Streamer fluid modeling - An overview of ARCoS  1.0
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
mapper.c
Go to the documentation of this file.
1 
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <math.h>
12 
13 #include "cstream.h"
14 #include "grid.h"
15 #include "interpol2.h"
16 #include "mapper.h"
17 #include "proto.h"
18 #include "species.h"
19 
20 static void map_same (mapper_t **mappers,
21  grid_t *source, grid_t *target, int ntheta,
22  int r0, int z0, int r1, int z1);
23 static void map_interpol (mapper_t **mappers, grid_t *source, grid_t *target,
24  int ntheta, int r0, int z0, int r1, int z1,
25  int level_diff);
26 static void interpol_inner (mapper_t **mappers, grid_t *source, grid_t *target,
27  int pr, int pz, int ntheta,
28  interpol_t **interpols,
29  int *extend_r, int *extend_z);
30 static void map_coarsen (mapper_t **mappers, grid_t *source, grid_t *target,
31  int ntheta, int r0, int z0, int r1, int z1,
32  int level_diff);
33 
34 
40 void
41 map_grid (mapper_t **mappers, grid_t *source, grid_t *target, int ntheta,
42  int copy, int interpol, int coarsen, int s_buff, int t_buff)
43 {
44  int r0, z0, r1, z1, level_diff;
45  int br0, bz0, br1, bz1;
46  mapper_t **m;
47  int overlap;
48 
49  debug (3, "map_grid (source = " grid_printf_str
50  ",\n\t dest = " grid_printf_str
51  ",\n\t s_buff = %d, t_buff = %d)\n",
52  grid_printf_args (source), grid_printf_args (target),
53  s_buff, t_buff);
54 
55  overlap = grid_overlap (source, target, s_buff, t_buff,
56  &r0, &z0, &r1, &z1, &level_diff);
57 
58  if (!overlap) {
59  debug (3, " -> no overlap\n");
60  return;
61  }
62 
63  if (level_diff == 0 && copy) {
64  map_same (mappers, source, target, ntheta, r0, z0, r1, z1);
65  } else if (level_diff < 0 && interpol) {
66  /* When we interpolate electric fields, the stencil used in the coarse
67  grid does not map exactly to cells in the finer grid by the standard
68  rules. Hence may have to extend the range of fine-grid cells that
69  can be affected by a coarse grid.
70  But later we must be careful, because not all fine-grid cells can
71  be interpolated.
72  */
73  for (m = mappers; *m; m++) {
74  int max_shift;
75 
76  max_shift = MYMAX(abs((*m)->shift_r) << (-level_diff - 1),
77  abs((*m)->shift_z) << (-level_diff - 1));
78 
79  debug (3, "max_shift = %d, shift_r = %d, shift_z = %d\n",
80  max_shift, (*m)->shift_r, (*m)->shift_z);
81 
82  grid_overlap_with_shifts (source, target,
83  s_buff,
84  MYMAX (t_buff, max_shift),
85  &br0, &bz0, &br1, &bz1, &level_diff,
86  (*m)->shift_r, (*m)->shift_z);
87  if (br0 < r0) r0 = br0;
88  if (bz0 < z0) z0 = bz0;
89  if (br1 > r1) r1 = br1;
90  if (bz1 > z1) z1 = bz1;
91  }
92  map_interpol (mappers, source, target, ntheta, r0, z0, r1, z1,
93  -level_diff);
94  } else if (level_diff > 0 && coarsen) {
95  map_coarsen (mappers, source, target, ntheta, r0, z0, r1, z1, level_diff);
96  }
97 }
98 
99 
104 void
105 map_grid_r (mapper_t **mappers, grid_t *source, grid_t *target, int ntheta,
106  int copy, int interpol, int coarsen, int s_buff, int t_buff)
107 {
108  grid_t *child;
109 
110  debug (3, "map_grid_r (...)\n");
111 
112  map_grid (mappers, source, target, ntheta, copy, interpol, coarsen,
113  s_buff, t_buff);
114 
115  iter_childs (source, child) {
116  map_grid_r (mappers, child, target, ntheta, copy, interpol, coarsen,
117  s_buff, t_buff);
118  }
119 }
120 
125 void
126 map_trees_r (mapper_t **mappers, grid_t *source, grid_t *target, int ntheta,
127  int copy, int interpol, int coarsen, int s_buff, int t_buff)
128 {
129  grid_t *child;
130 
131  debug (3, "map_trees_r (...)\n");
132 
133  iter_childs (target, child) {
134  map_trees_r (mappers, source, child, ntheta, copy, interpol, coarsen,
135  s_buff, t_buff);
136  }
137 
138  map_grid_r (mappers, source, target, ntheta, copy, interpol, coarsen,
139  s_buff, t_buff);
140 }
141 
146 static void
147 map_same (mapper_t **mappers,
148  grid_t *source, grid_t *target, int ntheta,
149  int r0, int z0, int r1, int z1)
150 {
151  int ir, iz;
152  mapper_t **m;
153 
154  debug (3, "map_same (source = " grid_printf_str
155  ",\n\t dest = " grid_printf_str
156  ",\n\t r0 = %d, z0 = %d, r1 = %d, z1 = %d)\n",
157  grid_printf_args (source), grid_printf_args (target),
158  r0, z0, r1, z1);
159 
160  for (ir = r0; ir < r1; ir++) {
161  for (iz = z0; iz < z1; iz++) {
162  for (m = mappers; *m; m++) {
163  (*m)->copy (*m, source, target, ir, iz, ntheta);
164  }
165  }
166  }
167  debug (3, " < map_same (...)\n");
168 }
169 
174 #define MAX_MAPPERS 32
175 
177 static void
178 map_interpol (mapper_t **mappers, grid_t *source, grid_t *target, int ntheta,
179  int r0, int z0, int r1, int z1, int level_diff)
180 {
181  int pr, pz;
182  int i, extend_r, extend_z;
183  interpol_t *interpols[MAX_MAPPERS];
184  mapper_t **m;
185 
186  debug (3, "map_interpol (source = " grid_printf_str
187  ",\n\t dest = " grid_printf_str
188  ",\n\t r0 = %d, z0 = %d, r1 = %d, z1 = %d, level_diff = %d)\n",
189  grid_printf_args (source), grid_printf_args (target),
190  r0, z0, r1, z1, level_diff);
191 
192  for (m = mappers, i = 0; *m; m++, i++)
193  interpols[i] = interpol_new_a (dr[source->level], dz[source->level],
194  (*m)->interpol_method);
195 
196  /* The +- 1 are there because even when we are including the
197  boundaries to calculate the overlap, we have to let one buffer cell
198  for the 9-point interpolation. */
199  r0 = MYMAX (r0 >> level_diff, source->r0 - 1);
200 
201  /* Explanation of the formula used: r1 is the index of the first cell not
202  in the overlap
203  -> r1 - 1 is the last cell in the overlap
204  -> (r1 - 1) >> level_diff indexes the last cell in the coarser grid
205  that contains part of the overlap.
206  -> since the loop has to include the former index, we add one.
207  */
208  r1 = MYMIN (((r1 - 1) >> level_diff) + 1, source->r1 + 1);
209  z0 = MYMAX (z0 >> level_diff, source->z0 - 1);
210  z1 = MYMIN (((z1 - 1) >> level_diff) + 1, source->z1 + 1);
211 
212 
213  debug (4, "r0 = %d, z0 = %d, r1 = %d, z1 = %d\n",
214  r0, z0, r1, z1);
215 
216  /* assert (r0 < r1 && z0 < z1); */
217 
218  for (pr = r0, extend_r = TRUE; pr < r1; pr++) {
219  /* The 0 initialization is to shut up the compiler. */
220  int extend_r_in = 0;
221  for (pz = z0, extend_z = TRUE; pz < z1; pz++) {
222  debug (6, "pr = %d, pz = %d, extend_r = %d, extend_z = %d\n",
223  pr, pz, extend_r, extend_z);
224  extend_r_in = extend_r;
225 
226  interpol_inner (mappers, source, target, pr, pz, ntheta,
227  interpols, &extend_r_in, &extend_z);
228  }
229  extend_r = extend_r_in;
230  }
231 
232  for (m = mappers, i= 0; *m; m++, i++)
233  interpol_free (interpols[i]);
234 
235  debug (3, "< map_interpol (...)\n");
236 }
237 
250 static void
251 interpol_inner (mapper_t **mappers, grid_t *source, grid_t *target,
252  int pr, int pz, int ntheta,
253  interpol_t **interpols, int *extend_r, int *extend_z)
254 {
255  int level_diff;
256  int i, ir, iz;
257  int rmin, rmax, zmin, zmax;
258  int inside;
259 
260  mapper_t **m;
261 
262  level_diff = target->level - source->level;
263 
264  debug (6, "interpol_inner (source = " grid_printf_str ",\n\t\t target = "
265  grid_printf_str ",\n\t\t pr = %d, pz = %d, ntheta = %d)\n",
266  grid_printf_args (source), grid_printf_args (target), pr, pz, ntheta);
267 
268  for (m = mappers, i = 0; *m; m++, i++) {
269  int fine_shift_r, fine_shift_z;
270 
271  inside = (*m)->interpol_set (*m, source, interpols[i], pr, pz, ntheta);
272 
273  if (!inside) continue;
274 
275  fine_shift_r = (*m)->shift_r << (level_diff - 1);
276  fine_shift_z = (*m)->shift_z << (level_diff - 1);
277 
278  debug (6, "shift_r = %d, shift_z = %d\n", (*m)->shift_r, (*m)->shift_z);
279 
280  rmin = (pr << level_diff) + fine_shift_r;
281  /* (*m)->shift_z tells us if the grid is staggered. If it is not,
282  it doesn't make sense to extend it. */
283  if (*extend_r && (*m)->shift_z != 0) {
284  *extend_r = FALSE;
285  rmin--;
286  }
287 
288  zmin = (pz << level_diff) + fine_shift_z;
289  if (*extend_z && (*m)->shift_r != 0) {
290  *extend_z = FALSE;
291  zmin--;
292  }
293 
294  /* The 2 are there because there is no problem in writing in the
295  buffer margin of the target grid. */
296  rmin = MYMAX (target->r0 - 2, rmin);
297  rmax = MYMIN (target->r1 + 2, ((pr + 1) << level_diff) + fine_shift_r);
298  zmin = MYMAX (target->z0 - 2, zmin);
299  zmax = MYMIN (target->z1 + 2, ((pz + 1) << level_diff) + fine_shift_z);
300 
301 
302  debug(6, "\trmin = %d, rmax = %d, zmin = %d, zmax = %d\n",
303  rmin, rmax, zmin, zmax);
304 
305  for (ir = rmin; ir < rmax; ir++) {
306  for (iz = zmin; iz < zmax; iz++) {
307  (*m)->interpol (*m, source, target, interpols[i],
308  ir, iz, ntheta);
309  }
310  }
311  }
312 }
313 
315 static void
316 map_coarsen (mapper_t **mappers, grid_t *source, grid_t *target, int ntheta,
317  int r0, int z0, int r1, int z1, int level_diff)
318 {
319  int i, ir, iz;
320  int rmin, rmax, zmin, zmax;
321  mapper_t **m;
322 
323  debug (3, "map_coarsen (source = " grid_printf_str
324  ",\n\t dest = " grid_printf_str
325  ",\n\t r0 = %d, z0 = %d, r1 = %d, z1 = %d, level_diff = %d)\n",
326  grid_printf_args (source), grid_printf_args (target),
327  r0, z0, r1, z1, level_diff);
328 
329  rmin = MYMAX (r0 >> level_diff, target->r0 - 2);
330 
331  /* See above for an explanation for this formula. */
332  rmax = MYMIN (((r1 - 1) >> level_diff) + 1, target->r1 + 2);
333  zmin = MYMAX (z0 >> level_diff, target->z0 - 2);
334  zmax = MYMIN (((z1 - 1) >> level_diff) + 1, target->z1 + 2);
335 
336  for (iz = zmin; iz < zmax; iz++) {
337  for (ir = rmin; ir < rmax; ir++) {
338  for (m = mappers, i = 0; *m; m++, i++) {
339  (*m)->coarsen (*m, source, target, ir, iz, ntheta);
340  }
341  }
342  }
343  debug (3, "< map_coarsen (...)\n");
344 }
345