Basilisk CFD
Adaptive Cartesian mesh PDE framework
Loading...
Searching...
No Matches
linear.h
Go to the documentation of this file.
1/** @file linear.h
2 */
3/* Linear quadtree implementation based on
4 *
5 * K. Aizawa, K. Motomura, S. Kimura, R. Kadowaki and J. Fan
6 * "Constant time neighbor finding in quadtrees"
7 * ISCCSP 2008, Malta, 12-14 March 2008.
8 * http://www.lcad.icmc.usp.br/~jbatista/procimg/quadtree_neighbours.pdf
9 *
10 * This uses a Z-grid ordering
11 */
12
13#define GRIDNAME "Linear quadtree"
14
15#include <stdio.h>
16#include <assert.h>
17
18#define _I (quad_x(point.i))
19#define _J (quad_y(point.i))
20
21typedef struct {
23 int i, level, depth;
24} Point;
25
26#define data(k,l) point.d[quad_neighbor(point.i, k, l)]
27
28/* the maximum level */
29static int quad_r;
30
31static int size (int l)
32{
33 return ((1 << (2*(l + 1))) - 1)/3;
34}
35
36int level (int p)
37{
38 p = 3*p + 1;
39 int l = 0;
40 while (p > 0) { p /= 4; l++; }
41 return l - 1;
42}
43
44int code (int p, int l)
45{
46 return (p - size (l - 1)) << 2*(quad_r - l);
47}
48
49int index (int code, int l)
50{
51 return size(l - 1) + (code >> 2*(quad_r - l));
52}
53
54int quad_x (int p)
55{
56 int n = code (p, level(p)), a = 0, m = 1, b = 1;
57 for (int i = 0; i < 2*quad_r - 1; i += 2, m *= 4, b *= 2)
58 a += ((m & n) != 0)*b;
59 return a;
60}
61
62int quad_y (int p)
63{
64 int n = code (p, level(p)), a = 0, m = 2, b = 1;
65 for (int i = 1; i < 2*quad_r; i += 2, m *= 4, b *= 2)
66 a += ((m & n) != 0)*b;
67 return a;
68}
69
70int repeat (int a)
71{
72 int s = 0;
73 for (int i = 0; i < quad_r; i++, a *= 4)
74 s += a;
75 return s;
76}
77
79
80#define quad(n, d) ((((n|quad_bottom)+(d&quad_left))&quad_left)|(((n|quad_left)+(d&quad_bottom))&quad_bottom))
81
82static int quad_id[3][3];
83
84int quad_neighbor (int p, int i, int j)
85{
86 int d = quad_id[i+1][j+1];
87 if (d == 0) return p;
88 int l = level (p);
89 int n = code (p, l);
90 d <<= (2*(quad_r - l));
91 return index (quad(n, d), l);
92}
93
94int quad_neighbor_finest (int p, int i, int j)
95{
96 int d = quad_id[i+1][j+1];
97 if (d == 0) return p;
98 int s = size (quad_r - 1);
99 int n = p - s;
100 return s + quad(n,d);
101}
102
103void * quadtree (int r, size_t s)
104{
105 quad_r = r;
106 void * q = malloc (s*size (r));
107 quad_left = repeat (1);
108 quad_bottom = repeat (2);
109 quad_id[0][2] = quad_top|quad_left;
110 quad_id[1][2] = quad_top;
112 quad_id[0][1] = quad_left; quad_id[1][1] = 0; quad_id[2][1] = quad_right;
115 return q;
116}
117
118void * init_grid (int n)
119{
120 int depth = 0;
121 while (n > 1) {
122 if (n % 2) {
123 fprintf (stderr, "quadtree: N must be a power-of-two\n");
124 exit (1);
125 }
126 n /= 2;
127 depth++;
128 }
129 void * q = quadtree (depth, sizeof (Data));
130 return q;
131}
132
133void free_grid (void * m)
134{
135 free (m);
136}
137
138#define STACKSIZE 20
139#define _push(c,d) \
140 { _s++; stack[_s].i = c; stack[_s].stage = d; }
141#define _pop(c,d) \
142 { c = stack[_s].i; d = stack[_s].stage; _s--; }
143
144#define foreach(grid) \
145{ \
146 struct { int i, stage; } stack[STACKSIZE]; int _s = -1; /* the stack */ \
147 Point point; \
148 point.d = grid; \
149 point.depth = quad_r; \
150 _push (0, 0); /* the root cell */ \
151 while (_s >= 0) { \
152 int stage; \
153 _pop (point.i, stage); \
154 if (!stage) { \
155 point.level = level (point.i); \
156 if (point.level < point.depth) { \
157 _push (point.i, 1); \
158 _push (4*point.i + 1, 0); \
159 } \
160 else { \
161 VARIABLES; \
162 /* do something */
163
164#define end_foreach() \
165 } \
166 } \
167 else { \
168 if (stage < 3) \
169 _push (point.i, stage + 1); \
170 _push (4*point.i + stage + 1, 0); \
171 } \
172 } \
173}
174
175#if 0
176int main (int argc, char * argv[])
177{
178 void * grid = init_grid (atoi (argv[1]));
179 foreach (grid) {
180 printf ("%d %d %d\n", I, J, point.level);
181 } end_foreach();
182 free_grid (grid);
183}
184#endif
185
186#if 0
187int main (int argc, char * argv[])
188{
189 int r = atoi(argv[1]);
190 void * q = quadtree (r, sizeof (double));
191 for (int p = size (r - 1); p < size (r); p++) {
192 int q = neighbor (p, quad_bottom | quad_left, r);
193 printf ("%d %d %d ( %d , %d ) | ( %d , %d ) ",
194 p, index (code (p, r), level (p), r), level (p),
195 x(p, r), y(p, r),
196 x(q, r), y(q, r));
197 printf ("\n");
198 }
199 return 0;
200}
201#endif
vector q[]
The primitive variables are the momentum , pressure , density , (face) specific volume ,...
Definition all-mach.h:44
const vector a
Definition all-mach.h:59
int main(int argc, char *argv[])
Definition bview.c:25
define l
define m((k)==0 &&(l)==0 &&(m)==0) macro2 foreach_point(double _x=0.
define neighbor(o, p, q)((Point)
Definition cartesian.h:146
free(list1)
int y
Definition common.h:76
int x
Definition common.h:76
Grid * grid
Definition common.h:32
#define p
Definition tree.h:320
Point point
Definition conserving.h:86
else return n
Definition curvature.h:101
scalar s
Definition embed-tree.h:56
*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 depth()
Definition cartesian.h:14
#define free_grid()
Definition grid.h:1404
#define init_grid(n)
Definition grid.h:1402
static int quad_r
Definition linear.h:29
int quad_y(int p)
Definition linear.h:62
int quad_x(int p)
Definition linear.h:54
int code(int p, int l)
Definition linear.h:44
int quad_neighbor(int p, int i, int j)
Definition linear.h:84
int repeat(int a)
Definition linear.h:70
static int quad_top
Definition linear.h:78
static int quad_id[3][3]
Definition linear.h:82
static int quad_right
Definition linear.h:78
int quad_neighbor_finest(int p, int i, int j)
Definition linear.h:94
void * quadtree(int r, size_t s)
Definition linear.h:103
#define quad(n, d)
Definition linear.h:80
#define end_foreach()
Definition linear.h:164
static int quad_bottom
Definition linear.h:78
static int quad_left
Definition linear.h:78
size_t size
size *double * b
int int int level
Definition linear.h:21
Data * d
Definition linear.h:22
int level
Definition linear.h:23
int depth
Definition linear.h:23
Array * index