70 p_fo->
r = malloc(nmrk *
sizeof(p_fo->
r) );
71 p_fo->
phi = malloc(nmrk *
sizeof(p_fo->
phi) );
72 p_fo->
z = malloc(nmrk *
sizeof(p_fo->
z) );
73 p_fo->
p_r = malloc(nmrk *
sizeof(p_fo->
p_r) );
74 p_fo->
p_phi = malloc(nmrk *
sizeof(p_fo->
p_phi) );
75 p_fo->
p_z = malloc(nmrk *
sizeof(p_fo->
p_z) );
76 p_fo->
mass = malloc(nmrk *
sizeof(p_fo->
mass) );
78 p_fo->
time = malloc(nmrk *
sizeof(p_fo->
time) );
79 p_fo->
znum = malloc(nmrk *
sizeof(p_fo->
znum) );
80 p_fo->
anum = malloc(nmrk *
sizeof(p_fo->
anum) );
83 p_fo->
B_r = malloc(nmrk *
sizeof(p_fo->
B_r) );
84 p_fo->
B_phi = malloc(nmrk *
sizeof(p_fo->
B_phi) );
85 p_fo->
B_z = malloc(nmrk *
sizeof(p_fo->
B_z) );
100 p_fo->
rho = malloc(nmrk *
sizeof(p_fo->
rho) );
101 p_fo->
theta = malloc(nmrk *
sizeof(p_fo->
theta) );
103 p_fo->
id = malloc(nmrk *
sizeof(p_fo->
id) );
112 p_fo->
err = malloc(nmrk *
sizeof(p_fo->
err) );
113 p_fo->
index = malloc(nmrk *
sizeof(p_fo->
index));
128 p_gc->
r = malloc(nmrk *
sizeof(p_gc->
r) );
129 p_gc->
phi = malloc(nmrk *
sizeof(p_gc->
phi) );
130 p_gc->
z = malloc(nmrk *
sizeof(p_gc->
z) );
131 p_gc->
ppar = malloc(nmrk *
sizeof(p_gc->
ppar) );
132 p_gc->
mu = malloc(nmrk *
sizeof(p_gc->
mu) );
133 p_gc->
zeta = malloc(nmrk *
sizeof(p_gc->
zeta) );
134 p_gc->
mass = malloc(nmrk *
sizeof(p_gc->
mass) );
136 p_gc->
time = malloc(nmrk *
sizeof(p_gc->
time) );
139 p_gc->
B_r = malloc(nmrk *
sizeof(p_gc->
B_r) );
140 p_gc->
B_phi = malloc(nmrk *
sizeof(p_gc->
B_phi) );
141 p_gc->
B_z = malloc(nmrk *
sizeof(p_gc->
B_z) );
156 p_gc->
rho = malloc(nmrk *
sizeof(p_gc->
rho) );
157 p_gc->
theta = malloc(nmrk *
sizeof(p_gc->
theta) );
158 p_gc->
id = malloc(nmrk *
sizeof(p_gc->
id) );
165 p_gc->
err = malloc(nmrk *
sizeof(p_gc->
err) );
166 p_gc->
index = malloc(nmrk *
sizeof(p_gc->
index) );
276 p_ml->mileage[j] = 0;
279 p_ml->B_r_dphi[j] = 1;
283 p_ml->B_phi_dr[j] = 1;
284 p_ml->B_phi_dphi[j] = 1;
285 p_ml->B_phi_dz[j] = 1;
289 p_ml->B_z_dphi[j] = 1;
325 for(
int i = 0; i < p->
n_mrk; i++) {
331 if(p->
id[i] < 0 && q->
next < q->
n) {
368 q->
p[i_prt], i_prt, p, i, Bdata);
372 q->
p[i_prt]->
err = err;
386 #pragma omp simd reduction(+:n_running)
387 for(
int i = 0; i < p->
n_mrk; i++) {
424 for(
int i = 0; i < p->
n_mrk; i++) {
430 if(p->
id[i] < 0 && q->
next < q->
n) {
462 q->
p[i_prt], i_prt, p, i, Bdata);
466 q->
p[i_prt]->
err = err;
480 #pragma omp simd reduction(+:n_running)
481 for(
int i = 0; i < p->
n_mrk; i++) {
518 for(
int i = 0; i <
NSIMD; i++) {
524 if(p->id[i] < 0 && q->
next < q->
n) {
529 if(!p->running[i] && p->id[i] >= 0) {
556 q->
p[i_prt], i_prt, p, i, Bdata);
560 q->
p[i_prt]->
err = err;
574 #pragma omp simd reduction(+:n_running)
575 for(
int i = 0; i <
NSIMD; i++) {
576 n_running += p->running[i];
609 if(!err && p->p.r <= 0) {
612 if(!err && p->p.mass <= 0) {
615 if(!err && p->p.weight <= 0) {
618 if(!err && p->p.id <= 0) {
631 if(!err && p->p_gc.r <= 0) {
634 if(!err && fabs(p->p_gc.pitch) > 1) {
637 if(!err && p->p_gc.energy <= 0) {
640 if(!err && p->p_gc.mass <= 0) {
643 if(!err && p->p_gc.weight <= 0) {
646 if(!err && p->p_gc.id <= 0) {
659 if(!err && p->p_ml.r <= 0) {
662 if(!err && p->p_ml.weight <= 0) {
665 if(!err && p->p_ml.id <= 0) {
716 p_fo->
r[j] = p->
rprt;
718 p_fo->
z[j] = p->
zprt;
738 real B_dB[15], psi[1], rho[2];
752 p_fo->
rho[j] = rho[0];
754 p_fo->
B_r[j] = B_dB[0];
755 p_fo->
B_r_dr[j] = B_dB[1];
757 p_fo->
B_r_dz[j] = B_dB[3];
759 p_fo->
B_phi[j] = B_dB[4];
764 p_fo->
B_z[j] = B_dB[8];
765 p_fo->
B_z_dr[j] = B_dB[9];
767 p_fo->
B_z_dz[j] = B_dB[11];
800 p->
rprt = p_fo->
r[j];
802 p->
zprt = p_fo->
z[j];
821 real B_dB[15], psi[1], rho[2];
822 rho[0] = p_fo->
rho[j];
823 B_dB[0] = p_fo->
B_r[j];
824 B_dB[1] = p_fo->
B_r_dr[j];
826 B_dB[3] = p_fo->
B_r_dz[j];
827 B_dB[4] = p_fo->
B_phi[j];
831 B_dB[8] = p_fo->
B_z[j];
832 B_dB[9] = p_fo->
B_z_dr[j];
834 B_dB[11] = p_fo->
B_z_dz[j];
1003 p->
id = p_gc->
id[j];
1043 real pparprt, muprt, zetaprt;
1053 p->
phiprt, pparprt, muprt, zetaprt,
1110 p_ml->phi[j] = p->
phi;
1113 p_ml->pitch[j] = 2*(p->
ppar >= 0) - 1.0;
1114 p_ml->time[j] = p->
time;
1115 p_ml->weight[j] = p->
weight;
1116 p_ml->id[j] = p->
id;
1117 p_ml->cputime[j] = p->
cputime;
1118 p_ml->rho[j] = p->
rho;
1119 p_ml->theta[j] = p->
theta;
1120 p_ml->endcond[j] = p->
endcond;
1122 p_ml->mileage[j] = p->
mileage;
1124 p_ml->B_r[j] = p->
B_r;
1125 p_ml->B_r_dr[j] = p->
B_r_dr;
1127 p_ml->B_r_dz[j] = p->
B_r_dz;
1129 p_ml->B_phi[j] = p->
B_phi;
1134 p_ml->B_z[j] = p->
B_z;
1135 p_ml->B_z_dr[j] = p->
B_z_dr;
1137 p_ml->B_z_dz[j] = p->
B_z_dz;
1139 p_ml->running[j] = 1;
1141 p_ml->running[j] = 0;
1173 p->
rprt = p_ml->r[j];
1174 p->
phiprt = p_ml->phi[j];
1175 p->
zprt = p_ml->z[j];
1181 p->
phi = p_ml->phi[j];
1183 p->
ppar = p_ml->pitch[j];
1188 p->
time = p_ml->time[j];
1189 p->
weight = p_ml->weight[j];
1190 p->
id = p_ml->id[j];
1191 p->
cputime = p_ml->cputime[j];
1192 p->
rho = p_ml->rho[j];
1193 p->
theta = p_ml->theta[j];
1194 p->
endcond = p_ml->endcond[j];
1196 p->
mileage = p_ml->mileage[j];
1197 p->
err = p_ml->err[j];
1199 p->
B_r = p_ml->B_r[j];
1200 p->
B_r_dr = p_ml->B_r_dr[j];
1202 p->
B_r_dz = p_ml->B_r_dz[j];
1204 p->
B_phi = p_ml->B_phi[j];
1209 p->
B_z = p_ml->B_z[j];
1210 p->
B_z_dr = p_ml->B_z_dr[j];
1212 p->
B_z_dz = p_ml->B_z_dz[j];
1215 a5err simerr = p_ml->err[j];
1222 if(!simerr && err) {err = err;}
1242 if(err) {simerr = 1;}
1243 p_gc->
id[j] = p_fo->
id[j];
1246 real r, phi, z, ppar, mu, zeta, B_dB[15];
1248 real Rprt = p_fo->
r[j];
1250 real zprt = p_fo->
z[j];
1267 B_dB[0] = p_fo->
B_r[j];
1268 B_dB[1] = p_fo->
B_r_dr[j];
1270 B_dB[3] = p_fo->
B_r_dz[j];
1271 B_dB[4] = p_fo->
B_phi[j];
1275 B_dB[8] = p_fo->
B_z[j];
1276 B_dB[9] = p_fo->
B_z_dr[j];
1278 B_dB[11] = p_fo->
B_z_dz[j];
1283 Rprt, phiprt, zprt, pr , pphi, pz,
1284 &r, &phi, &z, &ppar, &mu, &zeta);
1289 real psi[1], rho[2];
1292 B_dB, r, phi, z, p_fo->
time[j], Bdata);
1296 psi, r, phi, z, p_fo->
time[j], Bdata);
1310 p_gc->
zeta[j] = zeta;
1311 p_gc->
ppar[j] = ppar;
1312 p_gc->
rho[j] = rho[0];
1316 p_gc->
theta[j] += atan2( (p_fo->
r[j]-axisrz[0]) * (p_gc->
z[j]-axisrz[1])
1317 - (p_fo->
z[j]-axisrz[1]) * (p_gc->
r[j]-axisrz[0]),
1318 (p_fo->
r[j]-axisrz[0]) * (p_gc->
r[j]-axisrz[0])
1319 + (p_fo->
z[j]-axisrz[1]) * (p_gc->
z[j]-axisrz[1]) );
1321 p_gc->
B_r[j] = B_dB[0];
1322 p_gc->
B_r_dr[j] = B_dB[1];
1324 p_gc->
B_r_dz[j] = B_dB[3];
1326 p_gc->
B_phi[j] = B_dB[4];
1331 p_gc->
B_z[j] = B_dB[8];
1332 p_gc->
B_z_dr[j] = B_dB[9];
1334 p_gc->
B_z_dz[j] = B_dB[11];
1336 if(!simerr) {err = err;}
1355 p2->
r[j] = p1->
r[i];
1357 p2->
z[j] = p1->
z[i];
1376 p2->
id[j] = p1->
id[i];
1408 p2->
r[j] = p1->
r[i];
1410 p2->
z[j] = p1->
z[i];
1412 p2->
mu[j] = p1->
mu[i];
1425 p2->
id[j] = p1->
id[i];
1458 p2->r[j] = p1->r[i];
1459 p2->phi[j] = p1->phi[i];
1460 p2->z[j] = p1->z[i];
1461 p2->pitch[j] = p1->pitch[i];
1463 p2->time[j] = p1->time[i];
1464 p2->mileage[j] = p1->mileage[i];
1465 p2->cputime[j] = p1->cputime[i];
1466 p2->rho[j] = p1->rho[i];
1467 p2->weight[j] = p1->weight[i];
1468 p2->theta[j] = p1->theta[i];
1470 p2->id[j] = p1->id[i];
1471 p2->running[j] = p1->running[i];
1472 p2->endcond[j] = p1->endcond[i];
1473 p2->walltile[j] = p1->walltile[i];
1475 p2->B_r[j] = p1->B_r[i];
1476 p2->B_phi[j] = p1->B_phi[i];
1477 p2->B_z[j] = p1->B_z[i];
1479 p2->B_r_dr[j] = p1->B_r_dr[i];
1480 p2->B_r_dphi[j] = p1->B_r_dphi[i];
1481 p2->B_r_dz[j] = p1->B_r_dz[i];
1483 p2->B_phi_dr[j] = p1->B_phi_dr[i];
1484 p2->B_phi_dphi[j] = p1->B_phi_dphi[i];
1485 p2->B_phi_dz[j] = p1->B_phi_dz[i];
1487 p2->B_z_dr[j] = p1->B_z_dr[i];
1488 p2->B_z_dphi[j] = p1->B_z_dphi[i];
1489 p2->B_z_dz[j] = p1->B_z_dz[i];
1528 real B_dB[15], r, phi, z, ppar, mu, zeta, psi[1], rho[2];
1536 &r, &phi, &z, &ppar, &mu, &zeta);
1538 if(!err && r <= 0) {
1541 if(!err && mu < 0) {
1566 ps->
B_phi = B_dB[4];
1596 real B_dB[15], psi[1], rho[2];
1610 ps->
B_phi = B_dB[4];
1625 real gamma, mu, ppar;
1638 if(!err && mu < 0) {
1658 ps->
theta = atan2(ps->
z-axisrz[1], ps->
r-axisrz[0]);
1667 real rprt, phiprt, zprt, pr, pphi, pz;
1669 real pparprt, muprt, zetaprt;
1673 &rprt, &phiprt, &zprt, &pparprt, &muprt, &zetaprt);
1679 phiprt, pparprt, muprt, zetaprt,
1682 if(!err && rprt <= 0) {
1712 real B_dB[15], psi[1], rho[2];
1741 ps->
theta = atan2(p->
z - axisrz[1], p->
r - axisrz[0]);
1756 ps->
B_phi = B_dB[4];
1825 GPU_UPDATE_FROM_DEVICE(
1915 GPU_UPDATE_FROM_DEVICE(
a5err B_field_eval_rho(real rho[2], real psi, B_field_data *Bdata)
Evaluate normalized poloidal flux rho and its psi derivative.
a5err B_field_eval_psi(real *psi, real r, real phi, real z, real t, B_field_data *Bdata)
Evaluate poloidal flux psi.
a5err B_field_eval_B_dB(real B_dB[15], real r, real phi, real z, real t, B_field_data *Bdata)
Evaluate magnetic field and its derivatives.
a5err B_field_get_axis_rz(real rz[2], B_field_data *Bdata, real phi)
Return magnetic axis Rz-coordinates.
Header file for B_field.c.
Header file for E_field.c.
Main header file for ASCOT5.
#define NSIMD
Number of particles simulated simultaneously in a particle group operations.
Header file containing physical and mathematical constants.
#define CONST_C
Speed of light [m/s].
#define CONST_C2
Speed of light squared [m^2/s^2].
unsigned long int a5err
Simulation error flag.
#define math_normc(a1, a2, a3)
Calculate norm of 3D vector from its components a1, a2, a3.
void particle_allocate_gc(particle_simd_gc *p_gc, int nmrk)
Allocates guiding center struct representing particle markers.
void particle_onload_gc(particle_simd_gc *p)
Onload guiding center particle struct from the GPU.
void particle_onload_fo(particle_simd_fo *p)
Onload particle struct from the GPU.
void particle_to_ml_dummy(particle_simd_ml *p_ml, int j)
Makes a dummy ML simulation marker.
void particle_gc_to_state(particle_simd_gc *p_gc, int j, particle_state *p, B_field_data *Bdata)
Convert GC to state.
a5err particle_input_gc_to_state(particle_gc *p, particle_state *ps, B_field_data *Bdata)
Convert an input guiding center marker to particle state.
void particle_copy_gc(particle_simd_gc *p1, int i, particle_simd_gc *p2, int j)
Copy GC struct.
a5err particle_state_to_gc(particle_state *p, int i, particle_simd_gc *p_gc, int j, B_field_data *Bdata)
Convert state into a GC SIMD marker.
a5err particle_state_to_fo(particle_state *p, int i, particle_simd_fo *p_fo, int j, B_field_data *Bdata)
Convert state into a FO SIMD marker.
void particle_fo_to_state(particle_simd_fo *p_fo, int j, particle_state *p, B_field_data *Bdata)
Convert FO to state.
void particle_to_fo_dummy(particle_simd_fo *p_fo, int j)
Makes a dummy FO simulation marker.
void particle_offload_gc(particle_simd_gc *p)
Offload guiding center particle struct to GPU.
int particle_fo_to_gc(particle_simd_fo *p_fo, int j, particle_simd_gc *p_gc, B_field_data *Bdata)
Convert FO struct into a GC struct.
a5err particle_input_ml_to_state(particle_ml *p, particle_state *ps, B_field_data *Bdata)
Convert an input field line marker to particle state.
void particle_input_to_state(input_particle *p, particle_state *ps, B_field_data *Bdata)
Converts input marker to a marker state.
void particle_to_gc_dummy(particle_simd_gc *p_gc, int j)
Makes a dummy GC simulation marker.
void particle_copy_ml(particle_simd_ml *p1, int i, particle_simd_ml *p2, int j)
Copy ML struct.
void particle_allocate_fo(particle_simd_fo *p_fo, int nmrk)
Allocates struct representing particle markers.
a5err particle_state_to_ml(particle_state *p, int i, particle_simd_ml *p_ml, int j, B_field_data *Bdata)
Convert state to a ML SIMD marker.
a5err particle_input_p_to_state(particle *p, particle_state *ps, B_field_data *Bdata)
Convert an input particle marker to particle state.
void particle_offload_fo(particle_simd_fo *p)
Offload particle struct to GPU.
int particle_cycle_ml(particle_queue *q, particle_simd_ml *p, B_field_data *Bdata, int *cycle)
Replace finished ML markers with new ones or dummies.
void particle_ml_to_state(particle_simd_ml *p_ml, int j, particle_state *p, B_field_data *Bdata)
Convert ML to state.
int particle_cycle_gc(particle_queue *q, particle_simd_gc *p, B_field_data *Bdata, int *cycle)
Replace finished GC markers with new ones or dummies.
int particle_cycle_fo(particle_queue *q, particle_simd_fo *p, B_field_data *Bdata, int *cycle)
Replace finished FO markers with new ones or dummies.
void particle_copy_fo(particle_simd_fo *p1, int i, particle_simd_fo *p2, int j)
Copy FO struct.
Header file for particle.c.
Methods to evaluate elementary physical quantities.
#define physlib_gc_ppar(p, xi)
Evaluate guiding center parallel momentum [kg m/s] from momentum norm and pitch.
#define physlib_gc_mu(m, p, xi, B)
Evaluate guiding center magnetic moment [J/T] from momentum norm and pitch.
Magnetic field simulation data.
Wrapper for marker structs.
Struct representing NSIMD particle markers.
Struct representing NSIMD guiding center markers.
Struct representing NSIMD field line markers.
General representation of a marker.