22 int *r_bound_cond,
int *z_bound_cond,
63 static double inhom_e_term (
double r,
double z,
double b);
128 debug (2,
"pois_new_a (r0 = %d, z0 = %d, r1 = %d, z1 = %d)\n",
134 #ifdef F_PHI_SAME_AS_CHARGE
146 grid->ntheta = ntheta;
165 debug (3,
"pois_free (...)\n");
198 debug (3,
"pois_new_glob_a (%d, %d, %d, %d)\n", r0, r1, z0, z1);
203 r1 << level, z1 << level);
207 r1 >> level, z1 >> level);
222 debug (3,
"pois_init_tree_a (%d, %d, %d, %d)\n", r0, z0, r1, z1);
228 coarsest->level = level;
249 int stride = 0, ortho_stride = 0, icells, invert,
n;
251 double interp_array[3][3] = {{-4.0, 1.0, 18.0},
255 const double prefactor = 1 / 96.0;
256 REAL *bnd, *p, *lstart;
258 debug (3,
"pois_boundary_a (..., %d)\n", boundary);
260 parent = grid->parent;
264 icells = grid->r1 - grid->r0;
266 if (NULL != parent) {
272 icells = grid->z1 - grid->z0;
273 if (NULL != parent) {
284 debug (3,
"pois_boundary_a (...) -> [0.0] * %d\n", icells);
286 assert (grid->r1 != 0);
292 assert (NULL != parent);
296 lstart =
RZP (parent->
phi,
297 (grid->r1 >> 1) - 1 + rb,
298 (grid->z1 >> 1) - 1 + zb);
300 ortho_stride = -ortho_stride;
303 lstart =
RZP (parent->
phi, (grid->r0 >> 1) - rb, (grid->z0 >> 1) - zb);
307 for (p = lstart, n = 0; n < icells; p += stride, n += 2) {
310 double s = 0.0, s2 = 0.0;
312 for (i = -1; i <= 1; i++) {
313 for (j = -1; j <= 1; j++) {
314 s += *(p + i * stride + j * ortho_stride) * interp_array[i + 1][j + 1];
315 s2 += *(p - i * stride + j * ortho_stride) * interp_array[i + 1][j + 1];
319 bnd[
n] = prefactor * s;
320 if (n < icells - 1) bnd[n + 1] = prefactor * s2;
322 bnd[icells - n - 1] = prefactor * s;
323 if (n < icells - 1) bnd[icells - n - 2] = prefactor * s2;
335 double lambda,
double s)
338 int i, z_bound_cond, r_bound_cond;
339 double rmin, rmax, zmin, zmax;
341 debug (3,
"pois_solve_grid (..., lambda = %f, s = %f)\n", lambda, s);
343 for (i = 0; i < 4; i++) {
345 debug (3,
"boundaries[%d] = %p\n", i, boundaries[i]);
348 #ifndef F_PHI_SAME_AS_CHARGE
350 grid->
phi, grid->r0, grid->z0,
351 grid->r1 - grid->r0, grid->z1 - grid->z0);
354 rmin = grid->r0 *
dr[grid->level];
355 rmax = grid->r1 *
dr[grid->level];
356 zmin = grid->z0 *
dz[grid->level];
357 zmax = grid->z1 *
dz[grid->level];
359 debug (3,
"HSTCYL/HSTCRT in a grid %d x %d\n", grid->r1 - grid->r0,
360 grid->z1 - grid->z0);
362 get_bound_cond (grid, prob, &r_bound_cond, &z_bound_cond, lambda);
365 fish_hstcyl (rmin, rmax, grid->r1 - grid->r0,
367 zmin, zmax, grid->z1 - grid->z0,
370 RZP (grid->
phi, grid->r0, grid->z0),
373 fish_hstcrt (rmin, rmax, grid->r1 - grid->r0,
374 r_bound_cond, boundaries[BND_LEFT], boundaries[BND_RIGHT],
375 zmin, zmax, grid->z1 - grid->z0,
376 z_bound_cond, boundaries[BND_BOTTOM], boundaries[BND_TOP],
378 RZP (grid->
phi, grid->r0, grid->z0),
381 debug (3,
"Finished HSTCYL/HSTCRT in a grid %d x %d\n", grid->r1 - grid->r0,
382 grid->z1 - grid->z0);
397 for (i = 0; i < 4; i++) {
398 debug (3,
"boundaries[%d] = %p\n", i, boundaries[i]);
399 free (boundaries[i]);
401 debug (3,
" <- pos_solve_grid (...)\n");
413 int *r_bound_cond,
int *z_bound_cond,
double lambda)
415 static int right_inside[] = {FISH_UNS_DIR, FISH_NEU_DIR, FISH_DIR_DIR};
416 static int right_ext_neu[] = {FISH_UNS_NEU, FISH_NEU_NEU, FISH_DIR_NEU};
417 static int *right_ext_dir = right_inside;
418 static int fish_order[4] = { FISH_DIR_DIR, FISH_DIR_NEU,
419 FISH_NEU_DIR, FISH_NEU_NEU};
434 *z_bound_cond = fish_order[(bottom << 1) + top];
438 right_sel = right_ext_neu;
440 right_sel = right_ext_dir;
442 right_sel = right_inside;
447 right_sel[0]: right_sel[2];
450 right_sel[1]: right_sel[2]);
466 int left_neu,
int right_neu,
int bottom_neu,
471 debug (3,
"pois_set_phi_boundaries (...)\n");
474 for (i = grid->r0; i < grid->r1; i++) {
475 RZ (grid->
phi, i, grid->z0 - 1) =
RZ (grid->
phi, i, grid->z0);
478 for (i = grid->r0; i < grid->r1; i++) {
479 RZ (grid->
phi, i, grid->z0 - 1) =
480 2 * boundaries[
BND_BOTTOM][i - grid->r0] -
RZ (grid->
phi, i, grid->z0);
485 for (i = grid->r0; i < grid->r1; i++) {
486 RZ (grid->
phi, i, grid->z1) =
RZ (grid->
phi, i, grid->z1 - 1);
489 for (i = grid->r0; i < grid->r1; i++) {
490 RZ (grid->
phi, i, grid->z1) = 2 * boundaries[
BND_TOP][i - grid->r0]
491 -
RZ(grid->
phi, i, grid->z1 - 1);
496 for (i = grid->z0; i < grid->z1; i++) {
497 RZ (grid->
phi, grid->r0 - 1, i) =
RZ(grid->
phi, grid->r0, i);
500 for (i = grid->z0; i < grid->z1; i++) {
501 RZ(grid->
phi, grid->r0 - 1, i) = 2 * boundaries[
BND_LEFT][i - grid->z0]
502 -
RZ(grid->
phi, grid->r0, i);
507 for (i = grid->z0; i < grid->z1; i++) {
508 RZ (grid->
phi, grid->r1, i) =
RZ(grid->
phi, grid->r1 - 1, i);
511 for (i = grid->z0; i < grid->z1; i++) {
512 RZ(grid->
phi, grid->r1, i) = 2 * boundaries[
BND_RIGHT][i - grid->z0]
513 -
RZ(grid->
phi, grid->r1 - 1, i);
519 RZ(grid->
phi, grid->r1, grid->z0 - 1) =
RZ(grid->
phi, grid->r1 - 1,
521 RZ(grid->
phi, grid->r1, grid->z1) =
RZ(grid->
phi, grid->r1 - 1,
524 RZ(grid->
phi, grid->r1, grid->z0 - 1) =
525 RZ(grid->
phi, grid->r1 - 1, grid->z0 - 1)
526 +
RZ(grid->
phi, grid->r1, grid->z0)
527 - 0.5 * (
RZ(grid->
phi, grid->r1 - 2, grid->z0 - 1)
528 +
RZ(grid->
phi, grid->r1, grid->z0 + 1));
530 RZ(grid->
phi, grid->r1, grid->z1) =
531 RZ(grid->
phi, grid->r1 - 1, grid->z1)
532 +
RZ(grid->
phi, grid->r1, grid->z1 - 1)
533 - 0.5 * (
RZ(grid->
phi, grid->r1 - 2, grid->z1)
534 +
RZ(grid->
phi, grid->r1, grid->z1 - 2));
538 RZ(grid->
phi, grid->r0 - 1, grid->z0 - 1) =
RZ(grid->
phi, grid->r0,
540 RZ(grid->
phi, grid->r0 - 1, grid->z1) =
RZ(grid->
phi, grid->r0,
543 RZ(grid->
phi, grid->r0 - 1, grid->z0 - 1) =
544 RZ(grid->
phi, grid->r0, grid->z0 - 1)
545 +
RZ(grid->
phi, grid->r0 - 1, grid->z0)
546 - 0.5 * (
RZ(grid->
phi, grid->r0 + 1, grid->z0 - 1)
547 +
RZ(grid->
phi, grid->r0 - 1, grid->z0 + 1));
549 RZ(grid->
phi, grid->r0 - 1, grid->z1) =
550 RZ(grid->
phi, grid->r0, grid->z1)
551 +
RZ(grid->
phi, grid->r0 - 1, grid->z1 - 1)
552 - 0.5 * (
RZ(grid->
phi, grid->r0 + 1, grid->z1)
553 +
RZ(grid->
phi, grid->r0 - 1, grid->z1 - 2));
567 debug (3,
"pois_set_error(...)\n");
569 parent = grid->parent;
570 assert (NULL != parent);
578 pr * 2.0 + 1, pz * 2.0 + 1,
579 parent->
phi, pr, pz, 0);
580 for (i = 0; i < 2; i++)
581 for (j = 0; j < 2; j++) {
588 v =
interpol_apply (interpol, (
double) cr + 0.5, (
double) cz + 0.5);
592 RZ (grid->
error, cr, cz) = fabs (
RZ (grid->
phi, cr, cz) - v);
609 int zmin, zmax, rmin, rmax;
612 int cr0, cr1, cz0, cz1;
615 int tainted_line =
FALSE;
617 debug (3,
"pois_refine(...)\n");
622 cr0 = grid->r1; cr1 = grid->r0 - 1;
623 cz0 = grid->z1; cz1 = grid->z0 - 1;
633 for (iz = zmin; iz < zmax && all_ok; iz++) {
634 tainted_line =
FALSE;
635 for (ir = rmin; ir < rmax; ir++) {
638 if (ir < cr0) cr0 = ir;
639 if (ir > cr1) cr1 = ir;
643 if (iz < cz0) cz0 = iz;
644 if (iz > cz1) cz1 = iz;
645 }
else if (cr1 >= cr0 && cz1 >= cz0) {
646 all_ok = all_ok &&
refine_in (grid, cr0, cz0, cr1, cz1);
647 cr0 = grid->r1; cr1 = grid->r0 - 1;
648 cz0 = grid->z1; cz1 = grid->z0 - 1;
652 if (cr1 >= cr0 && cz1 >= cz0) {
653 all_ok = all_ok &&
refine_in (grid, cr0, cz0, cr1, cz1);
668 #define REFINE_IN_MAX_WARN_CNT 20;
679 int nr0, nr1, nz0, nz1;
687 if ((nr1 - nr0) > FISH_MAX_GRIDPOINTS ||
688 (nz1 - nz0) > FISH_MAX_GRIDPOINTS) {
690 warning (
"FISHPACK limit exceeded. Not refining grid "
695 warning (
"No more warnings about FISHPACK limit.\n");
705 debug (3,
"new child created {r0 = %d, z0 = %d, r1 = %d, z1 = %d, "
706 "level = %d}\n", child->r0, child->z0, child->r1, child->z1,
728 err =
RZ (grid->
error, ir, iz);
729 if (err > *Lmax) *Lmax = err;
735 *L2 = sqrt (*L2 / i);
750 fprintf (fp,
"%d %g %g %g %g %g\n", grid->level,
dr[grid->level],
751 dz[grid->level], L1, L2, Lmax);
785 assert (0 == cdr->level);
791 #pragma omp for schedule(dynamic)
862 #define POIS_SOLVE_R_MAX_WARN 50
867 int mode,
double es,
double threshold)
870 int succeeded =
FALSE;
876 debug(3,
"w2k[mode = %d] = %f\n", mode,
w2k[mode]);
880 if (pois->level >= prob->
max_level)
return;
890 warning (
"Poisson error threshold was too small: trying %g.\
891 Consider increasing pois_max_error\n",
893 if (warn_cnt >= 0) warn_cnt --;
913 int irmin, irmax, izmin, izmax;
915 irmin = ir > grid->r0 + 3? ir - 1: grid->r0;
916 irmax = ir < grid->r1 - 4? ir + 1: grid->r1 - 1;
917 izmin = iz > grid->z0 + 3? iz - 1: grid->z0;
918 izmax = iz < grid->z1 - 4? iz + 1: grid->z1 - 1;
920 for (i = irmin; i <= irmax && !r; i++)
921 for (j = izmin; j <= izmax; j++)
922 if (
RZ(grid->
error, i, j) > threshold) {
967 insqrt = (
SQ(z - b) +
SQ(r));
978 insqrt = (
SQ(z - b) +
SQ(r));
979 insqrt = insqrt * insqrt * insqrt;
1006 #define sum_reflections(total_, field_, r_, z_) \
1009 total_ = (field_ (r_, z_, pois_inhom_z) - \
1010 field_ (r_, z_, -pois_inhom_z)); \
1012 for (i__ = 2; i__ <= pois_inhom_reflections; i__ += 2) { \
1013 total_ += (field_ (r_, z_, pois_inhom_z + i__ * pois_inhom_L) + \
1014 field_ (r_, z_, pois_inhom_z - i__ * pois_inhom_L)); \
1016 total_ -= (field_ (r_, z_, -pois_inhom_z + i__ * pois_inhom_L) + \
1017 field_ (r_, z_, -pois_inhom_z - i__ * pois_inhom_L)); \
1119 RZ(grid->
phi, ir, iz) += q * res;
1135 int ir,
int iz,
int itheta)
1144 RZT (cdr->
er, ir, iz, itheta) =
ER_RZ (pois, ir, iz);
1150 int ir,
int iz,
int itheta)
1159 RZT (cdr->
ez, ir, iz, itheta) =
EZ_RZ (pois, ir, iz);
1165 int ir,
int iz,
int itheta)
1179 int ir,
int iz,
int itheta)
1183 int level_diff, er_ir, er_iz;
1188 level_diff = pois->level - cdr->level;
1190 er_iz = (iz << level_diff) + (1 << (level_diff - 1));
1191 er_ir = ((ir + 1) << level_diff) - 1;
1196 RZT (cdr->
er, ir, iz, itheta) = 0.5 * (
ER_RZ(pois, er_ir, er_iz) +
1197 ER_RZ(pois, er_ir, er_iz - 1));
1204 int ir,
int iz,
int itheta)
1208 int level_diff, ez_ir, ez_iz;
1213 level_diff = pois->level - cdr->level;
1215 ez_iz = ((iz + 1) << level_diff) - 1;
1216 ez_ir = (ir << level_diff) + (1 << (level_diff - 1));
1221 RZT(cdr->
ez, ir, iz, itheta) = 0.5 * (
EZ_RZ(pois, ez_ir, ez_iz) +
1222 EZ_RZ(pois, ez_ir - 1, ez_iz));
1229 int ir,
int iz,
int itheta)
1233 int level_diff, ez_ir, er_iz;
1238 level_diff = pois->level - cdr->level;
1240 er_iz = (iz << level_diff) + (1 << (level_diff - 1));
1241 ez_ir = (ir << level_diff) + (1 << (level_diff - 1));
1248 RZT (cdr->
etheta, ir, iz, itheta) = 0.25 *
1249 (
RZ (pois->
phi, ez_ir, er_iz)
1250 +
RZ (pois->
phi, ez_ir - 1, er_iz)
1251 +
RZ (pois->
phi, ez_ir, er_iz - 1)
1252 +
RZ (pois->
phi, ez_ir - 1, er_iz - 1));
1259 int pr,
int pz,
int itheta)
1271 if (pr < pois->r0 || pz < pois->z0
1272 || pr > pois->r1 - 1 || pz > pois->z1)
1276 er_r_at (pr - 1, pois->level),
1277 er_z_at (pz - 1, pois->level),
1278 ER_RZ (pois, pr - 1, pz - 1),
1279 ER_RZ (pois, pr - 1, pz),
1280 ER_RZ (pois, pr, pz - 1),
1281 ER_RZ (pois, pr, pz));
1289 int pr,
int pz,
int itheta)
1295 if (pr < pois->r0 || pz < pois->z0
1296 || pr > pois->r1 || pz > pois->z1 - 1)
1300 ez_r_at (pr - 1, pois->level),
1301 ez_z_at (pz - 1, pois->level),
1302 EZ_RZ (pois, pr - 1, pz - 1),
1303 EZ_RZ (pois, pr - 1, pz),
1304 EZ_RZ (pois, pr, pz - 1),
1305 EZ_RZ (pois, pr, pz));
1312 int pr,
int pz,
int itheta)
1318 if (pr < pois->r0 || pz < pois->z0
1319 || pr > pois->r1 - 1|| pz > pois->z1 - 1)
1323 r_at (pr, pois->level),
1324 z_at (pz, pois->level),
1325 pois->
phi, pr, pz, 0);
1332 interpol_t *interpol,
int ir,
int iz,
int itheta)
1342 level_diff = cdr->level - pois->level;
1348 if ((ir >> level_diff) >= pois->r1)
return;
1350 er_r =
er_r_at (ir, cdr->level);
1351 er_z =
er_z_at (iz, cdr->level);
1359 interpol_t *interpol,
int ir,
int iz,
int itheta)
1369 level_diff = cdr->level - pois->level;
1371 if ((iz >> level_diff) >= pois->z1)
return;
1373 ez_r =
ez_r_at (ir, cdr->level);
1374 ez_z =
ez_z_at (iz, cdr->level);
1382 interpol_t *interpol,
int ir,
int iz,
int itheta)
1384 double eth_r, eth_z;
1389 eth_r =
r_at (ir, cdr->level);
1390 eth_z =
z_at (iz, cdr->level);
1399 int ir,
int iz,
int itheta)
1413 int pr,
int pz,
int itheta)
1419 if (pr < cdr->r0 || pz < cdr->z0
1420 || pr > cdr->r1 - 1|| pz > cdr->z1 - 1)
1424 r_at (pr, cdr->level),
1425 z_at (pz, cdr->level),
1426 cdr->
charge, pr, pz, itheta);
1434 int ir,
int iz,
int itheta)
1441 r =
r_at (ir, pois->level);
1442 z =
z_at (iz, pois->level);
1454 int ir, iz, itheta, it, itn;
1464 fatal (
"In pois_phi_at: potential outside the grid");
1470 ir = (int) (r /
dr[grid->level]);
1471 iz = (int) (z /
dz[grid->level]);
1476 if (grid->ntheta > 1 && r > 0.0) {
1477 itheta = (int) (theta /
dtheta);
1484 for (it = 0; it < itn; it++) {
1486 r_at (ir, grid->level),
1487 z_at (iz, grid->level),
1488 grid->
phi, ir, iz, itheta + it);
1495 if (grid->ntheta > 1 && r > 0.0) {
1496 return (phi_it[0] * (theta -
theta_at (itheta)) +
1512 asprintf (&fname,
"%s/r.%s.tsv", prefix, name);
1513 rz_axis_dump (fname, grid->r0 - m, grid->r1 + m,
dr[grid->level]);
1516 asprintf (&fname,
"%s/z.%s.tsv", prefix, name);
1517 rz_axis_dump (fname, grid->z0 - m, grid->z1 + m,
dz[grid->level]);
1520 asprintf (&fname,
"%s/phi.%s.tsv", prefix, name);
1521 rz_dump (grid->
phi, fname,
"w", grid->r0 - m, grid->z0 - m,
1522 grid->r1 + m, grid->z1 + m);
1525 asprintf (&fname,
"%s/charge.%s.tsv", prefix, name);
1526 rz_dump (grid->
charge, fname,
"w", grid->r0 - m, grid->z0 - m,
1527 grid->r1 + m, grid->z1 + m);
1530 asprintf (&fname,
"%s/error.%s.tsv", prefix, name);
1531 rz_dump (grid->
error, fname,
"w", grid->r0 - m, grid->z0 - m,
1532 grid->r1 + m, grid->z1 + m);
1545 char codes[] =
"abcdefghijklmnopqrstuvwxyz";
1551 for (i = 0; i < nchilds; i++) {
1554 assert (NULL != child);
1556 if (i >
sizeof(codes) - 2)
1557 asprintf (&cname,
"%s{%d}", name, i);
1559 asprintf (&cname,
"%s%c", name, codes[i]);