44 int sign,
int ir,
int iz,
int itheta,
46 int dim1,
int dim1_from,
int dim1_to,
47 int dim2,
int dim2_from,
int dim2_to);
49 static void max_update (
double *x,
double cmp);
50 static double f_ad (
rz_array_t *dens,
double efield,
double dc,
double mc,
51 int ir,
int iz,
int itheta,
int dim);
53 static double psi (
double theta);
56 int ir,
int iz,
int itheta,
double (*f) (
double));
62 int r1,
int z1,
int *in_edge);
69 double gauss2_xyz (
double x,
double y,
double z);
105 rz_array_t *ez, *er, *etheta, *eabs, *charge, **dens, **d_dens, *photo;
110 debug (2,
"cdr_new_3d_a (%d, %d, %d, %d)\n", r0, z0, r1, z1);
153 grid->ntheta = ntheta;
172 rz_array_t *ez, *er, *etheta, *eabs, *charge, **dens, **d_dens, *photo;
219 grid->ntheta = host->ntheta;
223 set_leaf (grid, host->parent, NULL, NULL, host->level);
241 n =
cdr_new_3d_a (grid->r0, grid->z0, grid->r1, grid->z1, grid->ntheta);
242 n->level = grid->level;
258 int itheta, s, nr, nz, nspecs;
262 nr = grid->r1 - grid->r0 + 4;
263 nz = grid->z1 - grid->z0 + 4;
272 #pragma omp parallel private(s)
276 for (s = 0; s < nspecs; s++) {
278 n->
dens[s], n->r0 - 2, n->z0 - 2,
279 nr, nz, itheta, itheta);
318 debug (2,
"cdr_free\n");
334 free (grid->max_dens);
366 debug (3,
"cdr_calc_charge\n");
373 #pragma omp parallel private(r, z)
377 for (r = grid->r0 - 2; r < grid->r1 + 2; r++) {
378 for (z = grid->z0 - 2; z < grid->z1 + 2; z++) {
380 * s_charge) / grid->ntheta;
437 int r0_half, r1_half, z0_half, z1_half, itheta;
442 debug (2,
"cdr_create_coarser_a\n");
444 r0_half = grid->r0 >> 1;
445 r1_half = (grid->r1 + 1) >> 1;
447 z0_half = grid->z0 >> 1;
448 z1_half = (grid->z1 + 1) >> 1;
450 new_grid =
cdr_new_3d_a (r0_half, z0_half, r1_half, z1_half, grid->ntheta);
452 #pragma omp parallel private (r, z)
465 +
RZT (grid->
charge, 2 * r, 2 * z + 1, itheta))
466 +
cyl_q (r + 0.75) * (
RZT (grid->
charge, 2 * r + 1, 2 * z, itheta)
467 +
RZT (grid->
charge, 2 * r + 1, 2 * z + 1,
485 debug (2,
"cdr_add_coarser_grids_a\n");
489 for (i = 0; i <
n; i++) {
491 set_leaf (grid, NULL, NULL, prev_root, prev_root->level - 1);
493 prev_root->parent = grid;
513 debug (2,
"cdr_free_coarser_grids_a\n");
515 for (i = 0; i <
n; i++) {
516 assert (NULL == prev_root->next);
517 grid = prev_root->first_child;
522 prev_root->parent = NULL;
539 if (cdr->ntheta != 1)
544 if (cdr->ntheta != 1)
567 if (cdr->ntheta != 1)
568 cdr_set_periodic_r (cdr);
602 #pragma omp parallel private(ir, iz)
606 RZT(grid->
er, ir, iz, itheta) +=
607 ext_e_r (
er_r_at (ir, grid->level),
611 RZT(grid->
ez, ir, iz, itheta) +=
612 ext_e_z (
ez_r_at (ir, grid->level),
617 ext_e_theta (
r_at (ir, grid->level),
618 z_at (iz, grid->level),
645 #pragma omp parallel private(ir, iz)
649 RZT(grid->er, ir, iz, itheta) +=
653 RZT(grid->ez, ir, iz, itheta) +=
671 double er, ez, etheta;
675 #pragma omp for private(ir, iz, er, ez, etheta)
677 er = 0.5 * (
RZT (grid->
er, ir, iz, itheta)
678 +
RZT (grid->
er, ir - 1, iz, itheta));
679 ez = 0.5 * (
RZT (grid->
ez, ir, iz, itheta)
680 +
RZT (grid->
ez, ir, iz - 1, itheta));
681 if (grid->ntheta != 1) {
682 etheta = 0.5 * (
RZT (grid->
etheta, ir, iz, itheta)
683 +
RZT (grid->
etheta, ir, iz, itheta - 1));
687 RZT (grid->
eabs, ir, iz, itheta) = sqrt (er * er + ez * ez
705 int s, ir, iz, itheta;
709 #pragma omp for private(ir, iz, s)
713 *
RZTP (grid->dens[s], ir, iz, itheta) =
714 MYMAX(0, *
RZTP (grid->dens[s], ir, iz, itheta));
728 int r0, z0, r1, z1, ntheta;
737 ntheta = grid->ntheta;
775 int sign,
int ir,
int iz,
int itheta,
int dim0,
int inout,
776 int dim1,
int dim1_from,
int dim1_to,
777 int dim2,
int dim2_from,
int dim2_to)
782 rz_set_bnd (grid->dens[s], sign,
RZTP (grid->dens[s], ir, iz, itheta),
784 dim1, dim1_from, dim1_to,
785 dim2, dim2_from, dim2_to);
800 int s, itheta, itheta2, ntheta;
805 assert (0 == grid->r0);
807 ntheta = grid->ntheta;
811 itheta2 = (itheta + ntheta / 2) % ntheta;
816 grid->r0, grid->z0 - 2, itheta2),
818 grid->r0, grid->z0 - 2, itheta),
820 Z_INDX, 0, grid->z1 - grid->z0 + 4,
847 #define pij(p_, stride_) \
848 (((*(p_)) - *((p_) - (stride_))) / (*((p_) + (stride_)) - *(p_)))
853 int ir,
int iz,
int itheta,
int dim)
855 double sigma, psi_p, sigmasigma;
862 p =
RZTP (dens, ir, iz, itheta);
864 ishift = (efield > 0? 0: 1);
870 sigma = *(p + ishift * dens->
strides[dim]);
882 psi_p = (efield > 0)? -
psi (psi_p) : psi_p == 0? 1.0:
psi (1.0 / psi_p);
885 sigmasigma = (*p) - *(p + dens->
strides[dim]);
893 return efield * mc * (sigma + psi_p * sigmasigma) + dc * sigmasigma;
902 int ir, iz, itheta, s;
904 double gdr_inv, gdz_inv, d_iso0, d_iso;
915 gdr_inv = 1.0 /
dr[grid->level];
916 gdz_inv = 1.0 /
dz[grid->level];
930 dens = grid->
dens[s];
933 rmax = strides[1]; dim2 = strides[2]/strides[1];
948 dr[grid->level],
dz[grid->level],
962 if (theta < 0)
return 0;
963 if (theta < 0.4)
return theta;
964 if (theta < 4)
return (1 + 0.5 * theta) / 3.0;
973 int s, ir, iz, itheta, depth, is_3d;
975 double dr_min, dz_min, rdtheta_min, emax_r, emax_z, emax_theta, dmax, ddmax;
976 double tau_a, tau_d, tau_rt, tau_f, max_diff;
980 is_3d = (grid->ntheta == 1? 0: 1);
1015 RZT(grid->
dens[s], ir, iz, itheta)));
1023 assert (emax_r >= 0 && emax_z >= 0 && emax_theta >= 0 && dmax >= 0);
1026 tau_a =
nu_a / (emax_r / dr_min + emax_z / dz_min
1027 + is_3d * emax_theta / rdtheta_min);
1032 double dens_z1, dens_z0;
1044 tau_d =
nu_d / (max_diff / dr_min / dr_min
1045 + max_diff / dz_min / dz_min
1046 + is_3d * max_diff / rdtheta_min / rdtheta_min);
1058 tau_rt =
nu_rt / dmax;
1066 if (*x < cmp) *x = cmp;
1077 int ir, iz, itheta, s;
1084 assert (orig->r0 == dest->r0 && orig->z0 == dest->z0 &&
1085 orig->r1 == dest->r1 && orig->z1 == dest->z1 &&
1086 orig->ntheta == dest->ntheta);
1088 #pragma omp parallel
1090 #pragma omp for private(ir, iz, s)
1093 RZT (dest->
dens[s], ir, iz, itheta) =
1094 RZT (orig->
dens[s], ir, iz, itheta)
1095 + h *
RZT (orig->
d_dens[s], ir, iz, itheta);
1111 int ir, iz, itheta, s;
1122 #pragma omp parallel
1124 #pragma omp for private(ir, iz, s)
1127 RZT (dest->
dens[s], ir, iz, itheta) =
1128 RZT (dens_0->
dens[s], ir, iz, itheta)
1129 + 0.5 * h *
RZT (d_dens_1->
d_dens[s], ir, iz, itheta)
1130 + 0.5 * h *
RZT (d_dens_2->
d_dens[s], ir, iz, itheta);
1147 cdr_grid_t *c_dens_0, *c_d_dens_1, *c_d_dens_2, *c_dest;
1151 c_dens_0 = dens_0->first_child;
1152 c_d_dens_1 = d_dens_1->first_child;
1153 c_d_dens_2 = d_dens_2->first_child;
1158 c_dens_0 = c_dens_0->next;
1159 c_d_dens_1 = c_d_dens_1->next;
1160 c_d_dens_2 = c_d_dens_2->next;
1197 new_grid->first_child = new_child;
1199 prev->next = new_child;
1201 set_leaf (new_child, new_grid, NULL, NULL, new_grid->level + 1);
1269 static int count_min_timestep = 5;
1294 h =
MYMIN (h, courant_h);
1297 warning (
"Time step [h = %g] is rather small. If this is ok, reduce "
1298 "warn_time_step to remove this warning\n", h);
1300 if (0 == count_min_timestep--) {
1301 fatal (
"Too many warnings about small timesteps.\n");
1350 cdr_set_periodic_r (grid);
1386 int s, ir, iz, itheta;
1415 debug (2,
"->max_charge = %g, ->max_dens[0] = %g, ->max_dens[1] = %g\n",
1430 double (*f) (
double))
1436 for (i = 0; i < 3; i++) {
1437 x[
i] =
RZT (ar, ir - 1 + i, iz, itheta);
1438 x[
i] = f? f(x[i]): x[
i];
1441 level = grid->level;
1447 for (i = 0; i < 3; i++) {
1448 x[
i] =
RZT (ar, ir, iz - 1 + i, itheta);
1449 x[
i] = f? f(x[i]): x[
i];
1452 duz = (x[2] - 2 * x[1] + x[0]);
1454 return fabs(dur) + fabs(duz);
1466 int s_ref_level_eabs;
1467 double s_ref_threshold_eabs;
1472 const double epsilon_charge = 1e-8;
1478 double z, back_dens;
1479 z =
z_at (iz, grid->level);
1487 s_ref_level_eabs =
ref_level_eabs + (int) floor (log2 (back_dens));
1494 if (grid->level < s_ref_level_eabs &&
1495 RZT (grid->
eabs, ir, iz, itheta) > s_ref_threshold_eabs) {
1497 " at ir = %d, iz = %d, itheta = %d\n"
1498 "\t because too high EABS [eabs = %g]\n",
1500 RZT (grid->
eabs, ir, iz, itheta));
1511 " at ir = %d, iz = %d, itheta = %d\n"
1512 "\t because too high CHARGE curvature [curv / max_charge = %g]\n",
1523 curv =
curv_at (grid, grid->
dens[s], ir, iz, itheta, NULL);
1526 " at ir = %d, iz = %d, itheta = %d\n"
1527 "\t because too high DENS[%s] curvature [curv / max_dens = %g]\n",
1540 " at ir = %d, iz = %d, itheta = %d\n"
1541 "\t because too high DENS[%s] in leading edge [dens = %g]\n",
1543 RZT (grid->
dens[s], ir, iz, itheta));
1589 " needs refinement at ir = %d, iz = %d itheta = %d\n",
1593 if (ret && ! *in_edge)
return TRUE;
1615 for (ir = r0; ir < r1; ir ++) {
1616 for (iz = z1 - 1; iz >= z0; iz--) {
1618 if (ret && ! *in_edge)
return TRUE;
1640 for (ir = grid->r0; ir < grid->r1; ir +=
cdr_brick_dr) {
1642 int tainted, building, z0 = -1, z1 = -1;
1650 for (iz = grid->z0, building =
FALSE;
1664 assert (z0 >= 0 && z1 > 0);
1671 refine_in (grid, ir, z0, irmax, z1, in_edge);
1678 assert (z0 >= 0 && z1 > 0);
1679 if (!first_edge)
refine_in (grid, ir, z0, irmax, z1, in_edge);
1693 int nr0, nr1, nz0, nz1;
1700 child =
cdr_new_3d_a (nr0, nz0, nr1, nz1, grid->ntheta);
1707 debug (3,
"new child created {r0 = %d, z0 = %d, r1 = %d, z1 = %d, "
1708 "level = %d}\n", child->r0, child->z0, child->r1, child->z1,
1730 if (NULL != source) {
1731 #pragma omp parallel
1777 if (NULL != grid2) {
1790 cdr_match_r (child1, (child1 != child2)? child2: NULL);
1816 assert (to->level == fro->level);
1818 if (to->r1 == fro->r0) {
1819 x0 =
MYMAX (to->z0 - 2, fro->z0 - 2);
1820 x1 =
MYMIN (to->z1 + 2, fro->z1 + 2);
1821 if (x1 <= x0)
return FALSE;
1825 RZTP (fro->
dens[s], fro->r0, x0, 0),
1826 RZTP (to->
dens[s], to->r1 - 1, x0, 0),
1834 if (to->r0 == fro->r1) {
1835 x0 =
MYMAX (to->z0 - 2, fro->z0 - 2);
1836 x1 =
MYMIN (to->z1 + 2, fro->z1 + 2);
1837 if (x1 <= x0)
return FALSE;
1841 RZTP (fro->
dens[s], fro->r1 - 1, x0, 0),
1850 if (to->z1 == fro->z0) {
1851 x0 =
MYMAX (to->r0 - 2, fro->r0 - 2);
1852 x1 =
MYMIN (to->r1 + 2, fro->r1 + 2);
1853 if (x1 <= x0)
return FALSE;
1857 RZTP (fro->
dens[s], x0, fro->z0, 0),
1858 RZTP (to->
dens[s], x0, to->z1 - 1, 0),
1866 if (to->z0 == fro->z1) {
1867 x0 =
MYMAX (to->r0 - 2, fro->r0 - 2);
1868 x1 =
MYMIN (to->r1 + 2, fro->r1 + 2);
1869 if (x1 <= x0)
return FALSE;
1873 RZTP (fro->
dens[s], x0, fro->z1 - 1, 0),
1890 cdr_grid_t *top, *bottom, *left, *right, *parent;
1896 parent = grid->parent;
1897 if (NULL == parent) {
1898 assert (0 == grid->level);
1907 top =
cdr_guest (grid, grid->r0 - 2, grid->z1,
1908 grid->r1 + 2, grid->z1 + 2);
1909 bottom =
cdr_guest (grid, grid->r0 - 2, grid->z0 - 2,
1910 grid->r1 + 2, grid->z0);
1911 left =
cdr_guest (grid, grid->r0 - 2, grid->z0,
1912 grid->r0, grid->z1);
1913 right =
cdr_guest (grid, grid->r1, grid->z0,
1914 grid->r1 + 2, grid->z1);
1916 #pragma omp parallel
1929 assert (grid->r0 != 0);
1968 for (s = 0; s < nmappers; s++) {
1975 mapper->coarsen = NULL;
1978 mappers[s] = mapper;
1981 mappers[nmappers] = NULL;
2001 int ir,
int iz,
int itheta)
2015 int pr,
int pz,
int itheta)
2022 r_at (pr, cdr->level),
2023 z_at (pz, cdr->level),
2024 cdr->
dens[mapper->
extra], pr, pz, itheta);
2032 int ir,
int iz,
int itheta)
2039 r =
r_at (ir, cdr->level);
2040 z =
z_at (iz, cdr->level);
2052 int ir, iz, cr, cz, itheta, s;
2059 assert (parent->level == child->level - 1);
2061 #pragma omp parallel private(sum, ir, iz, cr, cz, s)
2068 for (cr = (ir << 1); cr <= (ir << 1) + 1; cr++)
2069 for (cz = (iz << 1); cz <= (iz << 1) + 1; cz++)
2071 *
RZT (child->
dens[s], cr, cz, itheta);
2072 RZT (parent->
dens[s], ir, iz, itheta) =
2073 0.25 * sum /
cyl_r_at (ir, parent->level);
2127 double (*f) (
double,
double,
double))
2130 double ctheta, stheta, x, y;
2134 #pragma omp parallel private(ir, iz, ctheta, stheta, x, y)
2142 x =
r_at(ir, cdr->level) * ctheta;
2143 y =
r_at(ir, cdr->level) * stheta;
2147 *
RZTP(cdr->
dens[species], ir, iz, itheta) =
2148 factor * f (x, y,
z_at(iz, cdr->level));
2151 *
RZTP(cdr->
dens[species], ir, iz, itheta) +=
2152 factor * f (x, y,
z_at(iz, cdr->level));
2155 *
RZTP(cdr->
dens[species], ir, iz, itheta) -=
2156 factor * f (x, y,
z_at(iz, cdr->level));
2166 double f_one(
double x,
double y,
double z)
2185 for (cnt = 0; cnt <
no_seed; cnt++)
2217 cdr_set_periodic_r (cdr);
2237 nt = grid->ntheta == 1? 1: grid->ntheta + 1;
2240 #pragma omp parallel sections private(fname)
2244 asprintf (&fname,
"%s/r.%s.tsv", prefix, name);
2245 rz_axis_dump (fname, grid->r0 - m, grid->r1 + m,
dr[grid->level]);
2250 asprintf (&fname,
"%s/z.%s.tsv", prefix, name);
2251 rz_axis_dump (fname, grid->z0 - m , grid->z1 + m,
dz[grid->level]);
2260 asprintf (&fname,
"%s/theta.%s.tsv", prefix, name);
2266 asprintf (&fname,
"%s/charge.%s.tsv", prefix, name);
2268 grid->r1 + m, grid->z1 + m, nt);
2273 asprintf (&fname,
"%s/er.%s.tsv", prefix, name);
2274 rz_dump_3d (grid->
er, fname,
"w", grid->r0 - m, grid->z0 - m,
2275 grid->r1 + m, grid->z1 + m, nt);
2280 asprintf (&fname,
"%s/ez.%s.tsv", prefix, name);
2281 rz_dump_3d (grid->
ez, fname,
"w", grid->r0 - m, grid->z0 - m,
2282 grid->r1 + m, grid->z1 + m, nt);
2287 asprintf (&fname,
"%s/etheta.%s.tsv", prefix, name);
2289 grid->r1 + m, grid->z1 + m, nt);
2295 asprintf (&fname,
"%s/eabs.%s.tsv", prefix, name);
2297 grid->r1 + m, grid->z1 + m, nt);
2304 asprintf (&fname,
"%s/photo.%s.tsv", prefix, name);
2306 grid->r1 + m, grid->z1 + m, nt);
2315 asprintf (&fname,
"%s/%s.%s.tsv", prefix,
spec_index[s]->name, name);
2316 rz_dump_3d (grid->
dens[s], fname,
"w", grid->r0 - m, grid->z0 - m,
2317 grid->r1 + m, grid->z1 + m, nt);
2321 asprintf (&fname,
"%s/d_%s.%s.tsv", prefix,
spec_index[s]->name, name);
2323 grid->r1 + m, grid->z1 + m, nt);
2361 FILE *infp,
double sim_time)
2366 char codes[] =
"abcdefghijklmnopqrstuvwxyz";
2371 asprintf (&cname,
"%s/tree.%s.dat", prefix, name);
2372 fp = fopen (cname,
"w");
2374 fatal (
"Could not open file %s/tree.%s.dat to write\n",
2378 fprintf (fp,
"time %g\n", sim_time);
2388 fprintf (fp,
"open %s %d %d %d %d %d %d %d\n", name, grid->r0, grid->z0,
2389 grid->r1, grid->z1, grid->level, grid->
ext_bound,
2396 for (i = 0; i < nchilds; i++) {
2399 assert (NULL != child);
2401 if (i >
sizeof(codes) - 2)
2402 asprintf (&cname,
"%s{%d}", name, i);
2404 asprintf (&cname,
"%s%c", name, codes[i]);
2406 cdr_dump_r (child, prefix, cname, fp, sim_time);
2410 fprintf (fp,
"close %s\n", name);
2427 char command[16], gridname[32], *fname;
2428 int r0, z0, r1, z1, level, ext_bound, margin, nt, s;
2433 debug (2,
"cdr_load_tree_r (prefix = \"%s\", name = \"%s\", ...)\n",
2439 asprintf (&fname,
"%s/tree.%s.dat", prefix, name);
2440 fp = fopen (fname,
"r");
2442 fatal (
"Could not open file %s/tree.%s.dat to read\n",
2451 fscanf (fp,
"%15s %15s", command, gridname);
2457 if (0 == strcmp (command,
"time")) {
2459 sscanf (gridname,
"%lf\n", &new_time);
2460 warning (
"Starting time [%f] was read from %s/tree.%s.dat\n",
2461 new_time, prefix, name);
2466 }
while (!open_close);
2468 if (0 == strcmp (command,
"open")) {
2469 debug (3,
"opening %s\n", gridname);
2471 fscanf (fp,
"%d %d %d %d %d %d %d\n",
2472 &r0, &z0, &r1, &z1, &level, &ext_bound, &margin);
2476 grid->level = level;
2480 asprintf (&fname,
"%s/%s.%s.tsv", prefix,
spec_index[s]->name, gridname);
2481 debug (3,
"Loading %s\n", fname);
2483 grid->r0 - margin, grid->z0 - margin,
2484 grid->r1 + margin, grid->z1 + margin, nt);
2491 assert (leaf->level == grid->level + 1);
2495 }
while (NULL != leaf);
2496 }
else if (0 == strcmp (command,
"close")) {
2497 debug (3,
"closing %s\n", gridname);
2516 asprintf (&fname,
"%s/frames.%s.tsv", prefix, name);
2517 fp = fopen (fname,
"w");
2521 warning (
"Unable to open %s\n", fname);
2536 level = grid->level;
2538 fprintf (fp,
"%g %g %g %g %d\n",