ASCOT5
Loading...
Searching...
No Matches
mccc_fo_euler.c
Go to the documentation of this file.
1
5#include <math.h>
6#include "../../ascot5.h"
7#include "../../consts.h"
8#include "../../math.h"
9#include "../../error.h"
10#include "../../physlib.h"
11#include "../../particle.h"
12#include "../../plasma.h"
13#include "../../random.h"
14#include "mccc_coefs.h"
15#include "mccc.h"
16
28 mccc_data* mdata, real* rnd) {
29
30 /* Get plasma information before going to the SIMD loop */
31 int n_species = plasma_get_n_species(pdata);
32 const real* qb = plasma_get_species_charge(pdata);
33 const real* mb = plasma_get_species_mass(pdata);
34
35 GPU_DATA_IS_MAPPED(h[0:p->n_mrk], rnd[0:3*p->n_mrk])
36 GPU_PARALLEL_LOOP_ALL_LEVELS
37 for(int i = 0; i < p->n_mrk; i++) {
38 if(p->running[i]) {
39 a5err errflag = 0;
40
41 /* These are needed twice to transform velocity to cartesian and *
42 * back to cylindrical coordinates. Position does not change */
43 real sinphi = sin(p->phi[i]);
44 real cosphi = cos(p->phi[i]);
45
46 real bnorm = math_normc(p->B_r[i], p->B_phi[i], p->B_z[i]);
47 real pnorm = sqrt( p->p_r[i] * p->p_r[i] + p->p_phi[i] * p->p_phi[i]
48 + p->p_z[i] * p->p_z[i] );
49 real gamma = physlib_gamma_pnorm(p->mass[i], pnorm);
50
51 real vflow;
52 if(!errflag) {
53 errflag = plasma_eval_flow(
54 &vflow, p->rho[i], p->r[i], p->phi[i], p->z[i], p->time[i],
55 pdata);
56 }
57
58 real vin_xyz[3];
59 vin_xyz[0] = ( p->p_r[i] / ( gamma * p->mass[i] )
60 - vflow * p->B_r[i] / bnorm ) * cosphi
61 - ( p->p_phi[i] / ( gamma * p->mass[i] )
62 - vflow * p->B_phi[i] / bnorm) * sinphi;
63 vin_xyz[1] = ( p->p_r[i] / ( gamma * p->mass[i] )
64 - vflow * p->B_r[i] / bnorm ) * sinphi
65 + ( p->p_phi[i] / ( gamma * p->mass[i] )
66 - vflow * p->B_phi[i] / bnorm) * cosphi;
67 vin_xyz[2] = p->p_z[i] / ( gamma * p->mass[i] )
68 - vflow * p->B_z[i] / bnorm;
69 real vin = math_norm(vin_xyz);
70
71 /* Evaluate plasma density and temperature */
73 if(!errflag) {
74 errflag = plasma_eval_densandtemp(nb, Tb, p->rho[i],
75 p->r[i], p->phi[i], p->z[i],
76 p->time[i], pdata);
77 }
78
79 /* Coulomb logarithm */
80 real clogab[MAX_SPECIES];
81 mccc_coefs_clog(clogab, p->mass[i], p->charge[i], vin,
82 n_species, mb, qb, nb, Tb);
83
84 /* Evaluate collision coefficients and sum them for each *
85 * species */
86 real F = 0, Dpara = 0, Dperp = 0;
87 GPU_SEQUENTIAL_LOOP
88 for(int j = 0; j < n_species; j++) {
89 real vb = sqrt( 2 * Tb[j] / mb[j] );
90 real x = vin / vb;
91 real mufun[3];
92 mccc_coefs_mufun(mufun, x, mdata);
93
94 F += mccc_coefs_F(p->mass[i], p->charge[i], mb[j], qb[j],
95 nb[j], vb, clogab[j], mufun[0]);
96 Dpara += mccc_coefs_Dpara(p->mass[i], p->charge[i], vin, qb[j],
97 nb[j], vb, clogab[j], mufun[0]);
98 Dperp += mccc_coefs_Dperp(p->mass[i], p->charge[i], vin, qb[j],
99 nb[j], vb, clogab[j], mufun[1]);
100 }
101
102 /* Evaluate collisions */
103 real sdt = sqrt(h[i]);
104 real dW[3];
105 dW[0] = sdt * rnd[0*p->n_mrk + i];
106 dW[1] = sdt * rnd[1*p->n_mrk + i];
107 dW[2] = sdt * rnd[2*p->n_mrk + i];
108
109 real vhat[3];
110 math_unit(vin_xyz, vhat);
111
112 real t1 = math_dot(vhat, dW);
113 real k1 = F*h[i];
114 real k2 = sqrt(2*Dpara)*t1;
115 real k3 = sqrt(2*Dperp);
116
117 real vout_xyz[3];
118 vout_xyz[0] = vin_xyz[0] + k1*vhat[0] + k2*vhat[0]
119 + k3*(dW[0] - t1*vhat[0]);
120 vout_xyz[1] = vin_xyz[1] + k1*vhat[1] + k2*vhat[1]
121 + k3*(dW[1] - t1*vhat[1]);
122 vout_xyz[2] = vin_xyz[2] + k1*vhat[2] + k2*vhat[2]
123 + k3*(dW[2] - t1*vhat[2]);
124
125 /* Transform back to cylindrical coordinates. */
126 real vout_rpz[3];
127 math_vec_xyz2rpz(vout_xyz, vout_rpz, p->phi[i]);
128 vout_rpz[0] += vflow * p->B_r[i] / bnorm;
129 vout_rpz[1] += vflow * p->B_phi[i] / bnorm;
130 vout_rpz[2] += vflow * p->B_z[i] / bnorm;
131 real vnorm = math_norm(vout_rpz);
132 gamma = physlib_gamma_vnorm(vnorm);
133 if(!errflag) {
134 p->p_r[i] = vout_rpz[0] * gamma * p->mass[i];
135 p->p_phi[i] = vout_rpz[1] * gamma * p->mass[i];
136 p->p_z[i] = vout_rpz[2] * gamma * p->mass[i];
137 }
138
139 /* Error handling */
140 if(errflag) {
141 p->err[i] = errflag;
142 p->running[i] = 0;
143 }
144 }
145 }
146}
Main header file for ASCOT5.
double real
Definition ascot5.h:85
#define MAX_SPECIES
Maximum number of plasma species.
Definition ascot5.h:95
Header file containing physical and mathematical constants.
Error module for ASCOT5.
unsigned long int a5err
Simulation error flag.
Definition error.h:17
Header file for math.c.
#define math_dot(a, b)
Calculate dot product a[3] dot b[3].
Definition math.h:31
#define math_vec_xyz2rpz(vxyz, vrpz, phi)
Transform vector from cartesian to cylindrical basis: vxyz -> vrpz, phi is the toroidal angle in radi...
Definition math.h:93
#define math_unit(a, b)
Calculate unit vector b from a 3D vector a.
Definition math.h:73
#define math_normc(a1, a2, a3)
Calculate norm of 3D vector from its components a1, a2, a3.
Definition math.h:70
#define math_norm(a)
Calculate norm of 3D vector a.
Definition math.h:67
Header file for mccc package.
Routines to evaluate coefficients needed to evaluate collisions.
#define mccc_coefs_Dpara(ma, qa, va, qb, nb, vb, clogab, mu0)
Evaluate non-relativistic parallel diffusion coefficient [m^2/s^3].
Definition mccc_coefs.h:103
static void mccc_coefs_mufun(real mufun[3], real x, mccc_data *mdata)
Evaluate special functions needed by collision coefficients.
Definition mccc_coefs.h:275
#define mccc_coefs_Dperp(ma, qa, va, qb, nb, vb, clogab, mu1)
Evaluate non-relativistic perpendicular diffusion coefficient [m^2/s^3].
Definition mccc_coefs.h:150
#define mccc_coefs_F(ma, qa, mb, qb, nb, vb, clogab, mu0)
Evaluate non-relativistic friction coefficient [m/s^2].
Definition mccc_coefs.h:80
static DECLARE_TARGET_END void mccc_coefs_clog(real *clogab, real ma, real qa, real va, int nspec, const real *mb, const real *qb, const real *nb, const real *Tb)
Evaluate Coulomb logarithm.
Definition mccc_coefs.h:228
void mccc_fo_euler(particle_simd_fo *p, real *h, plasma_data *pdata, mccc_data *mdata, real *rnd)
Integrate collisions for one time-step.
Header file for particle.c.
Methods to evaluate elementary physical quantities.
#define physlib_gamma_pnorm(m, p)
Evaluate Lorentz factor from momentum norm.
Definition physlib.h:46
#define physlib_gamma_vnorm(v)
Evaluate Lorentz factor from velocity norm.
Definition physlib.h:21
const real * plasma_get_species_mass(plasma_data *pls_data)
Get mass of all plasma species.
Definition plasma.c:314
int plasma_get_n_species(plasma_data *pls_data)
Get the number of plasma species.
Definition plasma.c:284
a5err plasma_eval_flow(real *vflow, real rho, real r, real phi, real z, real t, plasma_data *pls_data)
Evalate plasma flow along the field lines.
Definition plasma.c:236
const real * plasma_get_species_charge(plasma_data *pls_data)
Get charge of all plasma species.
Definition plasma.c:344
a5err plasma_eval_densandtemp(real *dens, real *temp, real rho, real r, real phi, real z, real t, plasma_data *pls_data)
Evaluate plasma density and temperature for all species.
Definition plasma.c:186
Header file for plasma.c.
Header file for random.c.
Parameters and data required to evaluate Coulomb collisions.
Definition mccc.h:27
Struct representing NSIMD particle markers.
Definition particle.h:210
integer * running
Definition particle.h:252
Plasma simulation data.
Definition plasma.h:32