Basilisk CFD
Adaptive Cartesian mesh PDE framework
Loading...
Searching...
No Matches
foreach_cell.h
Go to the documentation of this file.
1/** @file foreach_cell.h
2 */
3/* ===============================================================
4 * Tree traversal
5 * recursive() below is for reference only. The macro
6 * for (int _i = 0; _i < _N; _i++) /* foreach_cell */ is a stack-based implementation of
8 * version and 60% slower than simple array traversal.
9 *
11 * http://www.codeproject.com/Articles/418776/How-to-replace-recursive-functions-using-stack-and
12 *
13 * =============================================================== */
14
15#define _BOTTOM (2*point.j - GHOSTS)
16#define _TOP (_BOTTOM + 1)
17#define _LEFT (2*point.i - GHOSTS)
18#define _RIGHT (_LEFT + 1)
19#define _BACK (2*point.k - GHOSTS)
20#define _FRONT (_BACK + 1)
21
22#if 0
24{
25 if (point.level == grid->depth) {
26 /* do something */
27 }
28 else {
29 Point p1 = point; p1.level = point.level + 1;
30 p1.i = _LEFT; p1.j = _TOP; recursive (p1);
31 p1.i = _RIGHT; p1.j = _TOP; recursive (p1);
32 p1.i = _LEFT; p1.j = _BOTTOM; recursive (p1);
33 p1.i = _RIGHT; p1.j = _BOTTOM; recursive (p1);
34 }
35}
36#endif
37
38#define STACKSIZE 20
39#if dimension == 1
40#define _push(b,c,d,e,f) \
41 { _s++; stack[_s].l = b; \
42 stack[_s].i = c; \
43 stack[_s].stage = f; }
44#define _pop() \
45 { point.level = stack[_s].l; \
46 point.i = stack[_s].i; \
47 stage = stack[_s].stage; _s--; }
48#elif dimension == 2
49#define _push(b,c,d,e,f) \
50 { _s++; stack[_s].l = b; \
51 stack[_s].i = c; stack[_s].j = d; \
52 stack[_s].stage = f; }
53#define _pop() \
54 { point.level = stack[_s].l; \
55 point.i = stack[_s].i; point.j = stack[_s].j; \
56 stage = stack[_s].stage; _s--; }
57#else // dimension == 3
58#define _push(b,c,d,e,f) \
59 { _s++; stack[_s].l = b; \
60 stack[_s].i = c; stack[_s].j = d; stack[_s].k = e; \
61 stack[_s].stage = f; }
62#define _pop() \
63 { point.level = stack[_s].l; \
64 point.i = stack[_s].i; point.j = stack[_s].j; point.k = stack[_s].k; \
65 stage = stack[_s].stage; _s--; }
66#endif
67
69{
70 {
71 int ig = 0, jg = 0; NOT_UNUSED(ig); NOT_UNUSED(jg);
72 Point point = {0};
73#if dimension == 1
74 struct { int l, i, stage; } stack[STACKSIZE];
75#elif dimension == 2
76 struct { int l, i, j, stage; } stack[STACKSIZE];
77#else // dimension == 3
78 int kg = 0; NOT_UNUSED(kg);
79 struct { int l, i, j, k, stage; } stack[STACKSIZE];
80#endif
81 int _s = -1;
82 _push (root.level, root.i, root.j, root.k, 0);
83 while (_s >= 0) {
84 int stage;
85 _pop();
86 if (!allocated (0,0,0))
87 continue;
88 switch (stage) {
89 case 0: {
90
91 {...}
92
93 if (point.level < grid->depth) {
94 _push (point.level, point.i, point.j, point.k, 1);
95 _push (point.level + 1, _LEFT, _BOTTOM, _BACK, 0);
96 }
97 break;
98 }
99#if dimension == 1
100 case 1: _push (point.level + 1, _RIGHT, _BOTTOM, _BACK, 0); break;
101#elif dimension == 2
102 case 1: _push (point.level, point.i, point.j, point.k, 2);
103 _push (point.level + 1, _LEFT, _TOP, _BACK, 0); break;
104 case 2: _push (point.level, point.i, point.j, point.k, 3);
105 _push (point.level + 1, _RIGHT, _BOTTOM, _BACK, 0); break;
106 case 3: _push (point.level + 1, _RIGHT, _TOP, _BACK, 0); break;
107#elif dimension == 3
108 case 1: _push (point.level, point.i, point.j, point.k, 2);
109 _push (point.level + 1, _LEFT, _BOTTOM, _FRONT, 0); break;
110 case 2: _push (point.level, point.i, point.j, point.k, 3);
111 _push (point.level + 1, _LEFT, _TOP, _BACK, 0); break;
112 case 3: _push (point.level, point.i, point.j, point.k, 4);
113 _push (point.level + 1, _LEFT, _TOP, _FRONT, 0); break;
114 case 4: _push (point.level, point.i, point.j, point.k, 5);
115 _push (point.level + 1, _RIGHT, _BOTTOM, _BACK, 0); break;
116 case 5: _push (point.level, point.i, point.j, point.k, 6);
117 _push (point.level + 1, _RIGHT, _BOTTOM, _FRONT, 0); break;
118 case 6: _push (point.level, point.i, point.j, point.k, 7);
119 _push (point.level + 1, _RIGHT, _TOP, _BACK, 0); break;
120 case 7: _push (point.level + 1, _RIGHT, _TOP, _FRONT, 0); break;
121#endif
122 }
123 }
124 }
125}
126
127macro2 for (int _i = 0; _i < _N; _i++) /* foreach_cell */
128{
129 {
130#if dimension == 1
131 Point root = {GHOSTS,0};
132#elif dimension == 2
133 Point root = {GHOSTS,GHOSTS,0};
134#else // dimension == 3
136#endif
138 {...}
139 }
140}
141
143 {
144 Point root = {0};
145 for (root.i = GHOSTS*Period.x; root.i <= GHOSTS*(2 - Period.x); root.i++)
146#if dimension >= 2
147 for (root.j = GHOSTS*Period.y; root.j <= GHOSTS*(2 - Period.y); root.j++)
148#endif
149#if dimension >= 3
150 for (root.k = GHOSTS*Period.z; root.k <= GHOSTS*(2 - Period.z); root.k++)
151#endif
153 {...}
154 }
155}
156
158{
159 {
160 int ig = 0, jg = 0; NOT_UNUSED(ig); NOT_UNUSED(jg);
161 Point point = {0};
162#if dimension == 1
163 struct { int l, i, stage; } stack[STACKSIZE];
164#elif dimension == 2
165 struct { int l, i, j, stage; } stack[STACKSIZE];
166#else // dimension == 3
167 int kg = 0; NOT_UNUSED(kg);
168 struct { int l, i, j, k, stage; } stack[STACKSIZE];
169#endif
170 int _s = -1;
171 _push (0, root.i, root.j, root.k, 0); /* the root cell */
172 while (_s >= 0) {
173 int stage;
174 _pop();
175 if (!allocated (0,0,0))
176 continue;
177 switch (stage) {
178 case 0: {
179 if (point.level == grid->depth) {
180 _push (point.level, point.i, point.j, point.k, 8);
181 }
182 else {
183 _push (point.level, point.i, point.j, point.k, 1);
184 if (condition)
185 _push (point.level + 1, _LEFT, _BOTTOM, _BACK, 0);
186 }
187 break;
188 }
189#if dimension == 1
190 case 1:
191 _push (point.level, point.i, point.j, point.k, 2);
192 if (condition)
193 _push (point.level + 1, _RIGHT, _BOTTOM, _BACK, 0);
194 break;
195#elif dimension == 2
196 case 1:
197 _push (point.level, point.i, point.j, point.k, 2);
198 if (condition)
199 _push (point.level + 1, _LEFT, _TOP, _BACK, 0);
200 break;
201 case 2:
202 _push (point.level, point.i, point.j, point.k, 3);
203 if (condition)
204 _push (point.level + 1, _RIGHT, _BOTTOM, _BACK, 0);
205 break;
206 case 3:
207 _push (point.level, point.i, point.j, point.k, 4);
208 if (condition)
209 _push (point.level + 1, _RIGHT, _TOP, _BACK, 0);
210 break;
211#elif dimension == 3
212 case 1:
213 _push (point.level, point.i, point.j, point.k, 2);
214 if (condition)
215 _push (point.level + 1, _LEFT, _BOTTOM, _FRONT, 0);
216 break;
217 case 2:
218 _push (point.level, point.i, point.j, point.k, 3);
219 if (condition)
220 _push (point.level + 1, _LEFT, _TOP, _BACK, 0);
221 break;
222 case 3:
223 _push (point.level, point.i, point.j, point.k, 4);
224 if (condition)
225 _push (point.level + 1, _LEFT, _TOP, _FRONT, 0);
226 break;
227 case 4:
228 _push (point.level, point.i, point.j, point.k, 5);
229 if (condition)
230 _push (point.level + 1, _RIGHT, _BOTTOM, _BACK, 0);
231 break;
232 case 5:
233 _push (point.level, point.i, point.j, point.k, 6);
234 if (condition)
235 _push (point.level + 1, _RIGHT, _BOTTOM, _FRONT, 0);
236 break;
237 case 6:
238 _push (point.level, point.i, point.j, point.k, 7);
239 if (condition)
240 _push (point.level + 1, _RIGHT, _TOP, _BACK, 0);
241 break;
242 case 7:
243 _push (point.level, point.i, point.j, point.k, 8);
244 if (condition)
245 _push (point.level + 1, _RIGHT, _TOP, _FRONT, 0);
246 break;
247#endif
248 default:
249 {...}
250
251 }
252 }
253 }
254}
255
257{
258 {
259#if dimension == 1
260 Point root = {GHOSTS,0};
261#elif dimension == 2
262 Point root = {GHOSTS,GHOSTS,0};
263#else // dimension == 3
265#endif
267 {...}
268 }
269}
270
272{
273 {
274 Point root = {0};
275 for (root.i = 0; root.i <= 2*GHOSTS; root.i++)
276#if dimension >= 2
277 for (root.j = 0; root.j <= 2*GHOSTS; root.j++)
278#endif
279#if dimension >= 3
280 for (root.k = 0; root.k <= 2*GHOSTS; root.k++)
281#endif
283 {...}
284 }
285}
286
287macro2 for (int _i = 0; _i < _N; _i++) /* foreach_leaf */
288{
289 for (int _i = 0; _i < _N; _i++) /* foreach_cell */
290 if (is_leaf (cell)) {
291 if (is_active(cell) && is_local(cell))
292 {...}
293 continue;
294 }
295}
296
297#if dimension == 1
299{
300 if (!d.x) d.x = 1;
301 for (int ox = 0; ox < d.x; ox++) {
304 {...}
305 }
306}
307#elif dimension == 2
309{
310 if (!d.x) d.x = 1;
311 if (!d.y) d.y = 1;
312 for (int ox = 0; ox < d.x; ox++)
313 for (int oy = 0; oy < d.y; oy++) {
316 {...}
317 }
318}
319#elif dimension == 3
321{
322 if (!d.x) d.x = 1;
323 if (!d.y) d.y = 1;
324 if (!d.z) d.z = 1;
325 for (int ox = 0; ox < d.x; ox++)
326 for (int oy = 0; oy < d.y; oy++)
327 for (int oz = 0; oz < d.z; oz++) {
330 {...}
331 }
332}
333#endif // dimension == 3
const vector a
Definition all-mach.h:59
#define dimension
Definition bitree.h:3
define k
define l
#define GHOSTS
Definition cartesian.h:13
int x
Definition common.h:76
ivec Dimensions
Definition common.h:173
struct @0 Period
Grid * grid
Definition common.h:32
Point point
Definition conserving.h:86
*cs[i, 0, 0] a *[i -1, 0, 0] j
Definition embed.h:88
double d[2]
Definition embed.h:383
scalar int i
Definition embed.h:74
#define _pop()
#define _BACK
#define _push(b, c, d, e, f)
#define _TOP
#define STACKSIZE
#define _BOTTOM
macro2 foreach_cell_all()
macro2 foreach_cell_post_root(bool condition, Point root)
#define _RIGHT
macro2 foreach_cell_restore(ivec d=Dimensions, int rootlevel=0)
macro2 foreach_cell_post_all(bool condition)
macro2 foreach_cell_post(bool condition)
#define _FRONT
#define _LEFT
is a stack based implementation of * recursive(). It is about 12% slower than the recursive *version and 60% slower than simple array traversal. **This article was useful
Definition foreach_cell.h:7
int stack
Definition include.c:991
define is_active() cell(true) @define is_leaf(cell)(point.level
def _i
Definition stencils.h:405
int depth
Definition common.h:29
Definition linear.h:21
int level
Definition linear.h:23
int i
Definition linear.h:23
Definition common.h:139
def allocated(k, l, n)(mem_allocated(((Tree *) grid) -> L[point.level]->m, point.i+k, point.j+l)) @ @def NEIGHBOR(k, l, n)(((((Tree *) grid) ->L[point.level]->m) ->b[point.i+k][point.j+l])) @ @def PARENT(k, l, n)(((((Tree *) grid) ->L[point.level-1]->m) ->b[(point.i+2)/2+k][(point.j+2)/2+l])) @ @def allocated_child(k, l, n)(level< depth() &&mem_allocated(((Tree *) grid) ->L[point.level+1]->m, 2 *point.i- 2+k, 2 *point.j- 2+l)) @ @def CHILD(k, l, n)(((((Tree *) grid) ->L[point.level+1]->m) ->b[2 *point.i- 2+k][2 *point.j- 2+l])) @ @define CELL(m)(*((Cell *)(m))) @define depth()(grid->depth) @define aparent(k, l, n) CELL(PARENT(k, l, n)) @define child(k, l, n) CELL(CHILD(k, l, n)) @define cell CELL(NEIGHBOR(0, 0, 0)) @define neighbor(k, l, n) CELL(NEIGHBOR(k, l, n)) @def neighborp(l, m, n)(Point)
Definition tree.h:253