44 for(
int i = 0; i <
NSIMD; i++) {
49 real Brpz[3] = {p->B_r[i], p->B_phi[i], p->B_z[i]};
57 real vin, pin, vflow, gamma, ppar_flow, xiin, Xin_xyz[3];
58 Xin_xyz[0] = p->r[i] * cos(p->phi[i]);
59 Xin_xyz[1] = p->r[i] * sin(p->phi[i]);
63 &vflow, p->rho[i], p->r[i], p->phi[i], p->z[i], p->time[i],
67 ppar_flow = p->ppar[i] - gamma * vflow * p->mass[i];
68 pin =
physlib_gc_p(p->mass[i], p->mu[i], ppar_flow, Bnorm);
76 p->r[i], p->phi[i], p->z[i],
83 n_species, mb, qb, nb, Tb);
89 real K = 0, Dpara = 0, dDpara = 0, dQ = 0, nu = 0, DX = 0;
90 for(
int j = 0; j < n_species; j++) {
91 real vb = sqrt( 2 * Tb[j] / mb[j] );
97 qb[j], nb[j], vb, clogab[j],
100 qb[j], nb[j], vb, clogab[j],
103 qb[j], nb[j], vb, clogab[j],
106 qb[j], nb[j], vb, clogab[j],
111 qb[j], nb[j], vb, clogab[j], mufun[2]);
124 real dW[5] = {0, 0, 0, 0, 0};
138 real k1 = sqrt(2*DX);
141 real vout, xiout, Xout_xyz[3];
142 Xout_xyz[0] = Xin_xyz[0] + k1 * ( dW[0] - k2 * bhat[0] );
143 Xout_xyz[1] = Xin_xyz[1] + k1 * ( dW[1] - k2 * bhat[1] );
144 Xout_xyz[2] = Xin_xyz[2] + k1 * ( dW[2] - k2 * bhat[2] );
145 vout = vin + K*hin[i] + sqrt( 2 * Dpara ) * dW[3]
146 + 0.5 * dDpara * ( dW[3]*dW[3] - hin[i] );
147 xiout = xiin - xiin*nu*hin[i] + sqrt( ( 1 - xiin*xiin ) * nu )*dW[4]
148 - 0.5 * xiin * nu * ( dW[4]*dW[4] - hin[i] );
153 vout = 2 * cutoff - vout;
157 xiout = ( (xiout > 0) - (xiout < 0) )
158 * ( 2 - fabs( xiout ) );
165 real v0 = ( vin + fabs(K) * hin[i] + sqrt( 2*Dpara*hin[i] ) )
167 real verr = fabs( K*dQ ) / (2*tol*v0);
168 real xierr = fabs( xiin*nu*nu ) / (2*tol);
173 kappa_k = verr*hin[i]*hin[i];
176 kappa_k = xierr*hin[i]*hin[i];
180 real kappa_d0 = fabs( dW[3]*dW[3]*dW[3]
181 * dDpara*dDpara / sqrt( Dpara ) ) / (6*tol*v0);
182 real kappa_d1 = sqrt( 1 - xiin*xiin ) * nu * sqrt( nu )
183 * fabs( dW[4] + sqrt( hin[i]/3 ) ) * hin[i] / (2*tol);
194 Xout_xyz[0] = Xin_xyz[0];
195 Xout_xyz[1] = Xin_xyz[1];
196 Xout_xyz[2] = Xin_xyz[2];
205 real B_dB[15], psi[1], rho[2];
208 Xout_rpz[2], p->time[i] + hin[i],
213 Xout_rpz[2], p->time[i] + hin[i],
223 p->B_r_dr[i] = B_dB[1];
224 p->B_r_dphi[i] = B_dB[2];
225 p->B_r_dz[i] = B_dB[3];
227 p->B_phi[i] = B_dB[4];
228 p->B_phi_dr[i] = B_dB[5];
229 p->B_phi_dphi[i] = B_dB[6];
230 p->B_phi_dz[i] = B_dB[7];
233 p->B_z_dr[i] = B_dB[9];
234 p->B_z_dphi[i] = B_dB[10];
235 p->B_z_dz[i] = B_dB[11];
239 Bnorm =
math_normc(B_dB[0], B_dB[4], B_dB[8]);
241 p->r[i] = Xout_rpz[0];
242 p->z[i] = Xout_rpz[2];
252 real dppar = gamma * p->mass[i] * vflow;
261 p->theta[i] += atan2( (R0-axisrz[0]) * (p->z[i]-axisrz[1])
262 - (z0-axisrz[1]) * (p->r[i]-axisrz[0]),
263 (R0-axisrz[0]) * (p->r[i]-axisrz[0])
264 + (z0-axisrz[1]) * (p->z[i]-axisrz[1]) );
265 p->phi[i] += atan2( Xin_xyz[0] * Xout_xyz[1]
266 - Xin_xyz[1] * Xout_xyz[0],
267 Xin_xyz[0] * Xout_xyz[0]
268 + Xin_xyz[1] * Xout_xyz[1] );
273 if( kappa_k >= kappa_d0 && kappa_k >= kappa_d1 ) {
275 hout[i] = 0.8 * hin[i] / sqrt( kappa_k );
277 else if( kappa_d0 >= kappa_k && kappa_d0 >= kappa_d1 ) {
279 hout[i] = 0.9 * hin[i] * pow( kappa_d0, -2.0/3.0 );
283 hout[i] = 0.9 * hin[i] * pow( kappa_d1, -2.0/3.0 );
287 if( kappa_k > 1 || kappa_d0 > 1 || kappa_d1 > 1 ){
290 else if(hout[i] > 1.5*hin[i]) {
292 hout[i] = 1.5*hin[i];
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.
Main header file for ASCOT5.
#define NSIMD
Number of particles simulated simultaneously in a particle group operations.
#define MAX_SPECIES
Maximum number of plasma species.
Header file containing physical and mathematical constants.
unsigned long int a5err
Simulation error flag.
#define math_dot(a, b)
Calculate dot product a[3] dot b[3].
#define math_unit(a, b)
Calculate unit vector b from a 3D vector a.
#define math_xyz2rpz(xyz, rpz)
Convert cartesian coordinates xyz to cylindrical coordinates rpz.
#define math_vec_rpz2xyz(vrpz, vxyz, phi)
Transform vector from cylindrical to cartesian basis: vrpz -> vxyz, phi is the toroidal angle in radi...
#define math_normc(a1, a2, a3)
Calculate norm of 3D vector from its components a1, a2, a3.
#define math_norm(a)
Calculate norm of 3D vector a.
Header file for mccc package.
#define MCCC_CUTOFF
Defines minimum energy boundary condition.
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].
#define mccc_coefs_dDpara(ma, qa, va, qb, nb, vb, clogab, mu0, dmu0)
Evaluate derivative of non-relativistic parallel diffusion coefficient [m/s^2].
#define mccc_coefs_dQ(ma, qa, mb, qb, nb, vb, clogab, dmu0)
Evaluate derivative of non-relativistic drag coefficient [m/s^2].
#define mccc_coefs_K(va, Dpara, dDpara, Q)
Evaluate guiding center drag coefficient [m/s^2].
static void mccc_coefs_mufun(real mufun[3], real x, mccc_data *mdata)
Evaluate special functions needed by collision coefficients.
#define mccc_coefs_Dperp(ma, qa, va, qb, nb, vb, clogab, mu1)
Evaluate non-relativistic perpendicular diffusion coefficient [m^2/s^3].
#define mccc_coefs_nu(va, Dperp)
Evaluate pitch collision frequency [1/s].
#define mccc_coefs_DX(xi, Dpara, Dperp, gyrofreq)
Evaluate spatial diffusion coefficient [m^2/s].
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.
#define mccc_coefs_Q(ma, qa, mb, qb, nb, vb, clogab, mu0)
Evaluate non-relativistic drag coefficient [m/s^2].
void mccc_gc_milstein(particle_simd_gc *p, real *hin, real *hout, real tol, mccc_wienarr *w, B_field_data *Bdata, plasma_data *pdata, mccc_data *mdata, real *rnd)
Integrate collisions for one time-step.
a5err mccc_wiener_generate(mccc_wienarr *w, real t, int *windex, real *rand5)
Generates a new Wiener process at a given time instant.
header file for mccc_wiener.c
Header file for particle.c.
Methods to evaluate elementary physical quantities.
#define physlib_gamma_pnorm(m, p)
Evaluate Lorentz factor from momentum norm.
#define physlib_gc_xi(m, mu, ppar, B)
Evaluate guiding center pitch from parallel momentum and magnetic moment.
#define physlib_pnorm_vnorm(m, v)
Evaluate momentum norm [kg m/s] from velocity norm.
#define physlib_gamma_ppar(m, mu, ppar, B)
Evaluate Lorentz factor from parallel momentum.
#define physlib_vnorm_pnorm(m, p)
Evaluate velocity norm [m/s] from momentum norm.
#define phys_gyrofreq_pnorm(m, q, p, B)
Evaluate gyrofrequency [rad/s] from momentum norm.
#define physlib_gc_ppar(p, xi)
Evaluate guiding center parallel momentum [kg m/s] from momentum norm and pitch.
#define physlib_gc_p(m, mu, ppar, B)
Evaluate guiding center momentum norm [kg m/s] from parallel momentum and magnetic moment.
#define physlib_gc_mu(m, p, xi, B)
Evaluate guiding center magnetic moment [J/T] from momentum norm and pitch.
const real * plasma_get_species_mass(plasma_data *pls_data)
Get mass of all plasma species.
int plasma_get_n_species(plasma_data *pls_data)
Get the number of plasma species.
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.
const real * plasma_get_species_charge(plasma_data *pls_data)
Get charge of all plasma species.
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.
Header file for plasma.c.
Header file for random.c.
Magnetic field simulation data.
Parameters and data required to evaluate Coulomb collisions.
Struct for storing Wiener processes.
real wiener[MCCC_NDIM *MCCC_NSLOTS]
Struct representing NSIMD guiding center markers.