ASCOT5
Loading...
Searching...
No Matches
libascot.c
Go to the documentation of this file.
1
8#include <stdlib.h>
9#include <stdio.h>
10#include <string.h>
11#include <hdf5.h>
12#include <math.h>
13
14#include "ascot5.h"
15#include "gitver.h"
16#include "math.h"
17#include "simulate.h"
18#include "B_field.h"
19#include "E_field.h"
20#include "plasma.h"
21#include "wall.h"
22#include "neutral.h"
23#include "boozer.h"
24#include "mhd.h"
25#include "asigma.h"
26#include "consts.h"
27#include "physlib.h"
28#include "gitver.h"
29
31
32#include "hdf5_interface.h"
33#include "hdf5io/hdf5_helpers.h"
34#include "hdf5io/hdf5_bfield.h"
35#include "hdf5io/hdf5_efield.h"
36#include "hdf5io/hdf5_plasma.h"
37#include "hdf5io/hdf5_wall.h"
38#include "hdf5io/hdf5_neutral.h"
39#include "hdf5io/hdf5_boozer.h"
40#include "hdf5io/hdf5_mhd.h"
41
42
66 sim_data* sim, int Neval,
67 real* R, real* phi, real* z, real* t, real* BR, real* Bphi, real* Bz,
68 real* BR_dR, real* BR_dphi, real* BR_dz, real* Bphi_dR, real* Bphi_dphi,
69 real* Bphi_dz, real* Bz_dR, real* Bz_dphi, real* Bz_dz) {
70
71 #pragma omp parallel for
72 for(int k = 0; k < Neval; k++) {
73 real B[15];
74 if( B_field_eval_B_dB(B, R[k], phi[k], z[k], t[k], &sim->B_data) ) {
75 continue;
76 }
77 BR[k] = B[0];
78 Bphi[k] = B[4];
79 Bz[k] = B[8];
80 BR_dR[k] = B[1];
81 BR_dphi[k] = B[2];
82 BR_dz[k] = B[3];
83 Bphi_dR[k] = B[5];
84 Bphi_dphi[k] = B[6];
85 Bphi_dz[k] = B[7];
86 Bz_dR[k] = B[9];
87 Bz_dphi[k] = B[10];
88 Bz_dz[k] = B[11];
89 }
90}
91
109 sim_data* sim, int Neval,
110 real* R, real* phi, real* z, real* t, real* rho, real* drhodpsi, real* psi,
111 real* dpsidr, real* dpsidphi, real* dpsidz) {
112
113 #pragma omp parallel for
114 for(int k = 0; k < Neval; k++) {
115 real rhoval[2], psival[4];
116 if( B_field_eval_psi_dpsi(psival, R[k], phi[k], z[k], t[k],
117 &sim->B_data) ) {
118 continue;
119 }
120 psi[k] = psival[0];
121 dpsidr[k] = psival[1];
122 dpsidphi[k] = psival[2];
123 dpsidz[k] = psival[3];
124 if( B_field_eval_rho(rhoval, psival[0], &sim->B_data) ) {
125 continue;
126 }
127 rho[k] = rhoval[0];
128 drhodpsi[k] = rhoval[1];
129 }
130}
131
142 sim_data* sim, int Neval, real* phi, real* Raxis, real* zaxis) {
143
144 #pragma omp parallel for
145 for(int k = 0; k < Neval; k++) {
146 real axisrz[2];
147 if( B_field_get_axis_rz(axisrz, &sim->B_data, phi[k]) ) {
148 continue;
149 }
150 Raxis[k] = axisrz[0];
151 zaxis[k] = axisrz[1];
152 }
153}
154
174 sim_data* sim, int Neval,
175 real* rho, real* theta, real* phi, real t, int maxiter, real tol,
176 real* r, real* z) {
177
178 #pragma omp parallel for
179 for(int j=0; j<Neval; j++) {
180 real axisrz[2];
181 real rhodrho[4];
182 if( B_field_get_axis_rz(axisrz, &sim->B_data, phi[j]) ) {
183 continue;
184 }
185 if( B_field_eval_rho_drho(rhodrho, axisrz[0], phi[j], axisrz[1],
186 &sim->B_data)) {
187 continue;
188 }
189 if( rhodrho[0] > rho[j] ) {
190 /* Due to padding, rho might not be exactly zero on the axis so we
191 * return the axis position for small values of queried rho */
192 r[j] = axisrz[0];
193 z[j] = axisrz[1];
194 continue;
195 }
196
197 real costh = cos(theta[j]);
198 real sinth = sin(theta[j]);
199 /* Find the limit of the dataset (if it exists) so that we can use it
200 * as a boundary */
201 real maxdist = axisrz[0];
202 real b = 0.0;
203 while(b < maxdist) {
204 b += 0.01;
205 real rj = axisrz[0] + b * costh;
206 real zj = axisrz[1] + b * sinth;
207 if( B_field_eval_rho_drho(rhodrho, rj, phi[j], zj, &sim->B_data)) {
208 break;
209 }
210 if( rhodrho[0] - rho[j] > 0 ) {
211 break;
212 }
213 }
214
215 real a = 0.0;
216 for(int i=0; i<maxiter; i++) {
217 real c = 0.5*(a + b);
218 real rj = axisrz[0] + c * costh;
219 real zj = axisrz[1] + c * sinth;
220 if(rj < 0) {
221 b = c;
222 continue;
223 }
224 if( B_field_eval_rho_drho(rhodrho, rj, phi[j], zj, &sim->B_data) ) {
225 b = c;
226 continue;
227 }
228 if( fabs(rho[j] - rhodrho[0]) < tol ) {
229 r[j] = rj;
230 z[j] = zj;
231 break;
232 }
233 if( rho[j] < rhodrho[0]) {
234 b = c;
235 } else {
236 a = c;
237 }
238 }
239 }
240}
241
258 sim_data* sim, real psi[1],
259 real rz[2], real phi, real step, real tol, int maxiter, int ascent) {
260
261 if(ascent) {
262 step = -0.001 * step;
263 }
264
265 real time = 0.0;
266 real psidpsi[4], nextrz[2];
267 B_field_eval_psi_dpsi(psidpsi, rz[0], phi, rz[1], time, &sim->B_data);
268
269 int iter = 0;
270 while(1) {
271 if( B_field_eval_psi_dpsi(psidpsi, rz[0], phi, rz[1], time,
272 &sim->B_data) ) {
273 break;
274 }
275 nextrz[0] = rz[0] - step * psidpsi[1];
276 nextrz[1] = rz[1] - step * psidpsi[3];
277
278 // Check convergence
279 if(sqrt( (nextrz[0] - rz[0]) * (nextrz[0] - rz[0])
280 + (nextrz[1] - rz[1]) * (nextrz[1] - rz[1]) ) < tol) {
281 psi[0] = psidpsi[0];
282 rz[0] = nextrz[0];
283 rz[1] = nextrz[1];
284
285 // Add a bit of padding
287 psidpsi, rz[0], phi, rz[1], time, &sim->B_data);
288 psi[0] = psi[0] + (tol * psidpsi[1] + tol * psidpsi[3]);
289 break;
290 }
291
292 rz[0] = nextrz[0];
293 rz[1] = nextrz[1];
294 iter++;
295
296 if(iter == maxiter) {
297 break;
298 }
299 }
300}
301
302
321 sim_data* sim, real psi[1],
322 real rzphi[3], real phimin, real phimax, real step, real tol, int maxiter,
323 int ascent) {
324
325 if(ascent) {
326 step = -1 * step;
327 }
328
329 real time = 0.0;
330 real psidpsi[4], nextrzphi[3];
331 B_field_eval_psi_dpsi(psidpsi, rzphi[0], rzphi[2], rzphi[1], time,
332 &sim->B_data);
333
334 int iter = 0;
335 while(1) {
336 if( B_field_eval_psi_dpsi(psidpsi, rzphi[0], rzphi[2], rzphi[1], time,
337 &sim->B_data) ) {
338 break;
339 }
340 nextrzphi[0] = rzphi[0] - step * psidpsi[1]; // R
341 nextrzphi[1] = rzphi[1] - step * psidpsi[3]; // z
342 nextrzphi[2] = rzphi[2] - step/rzphi[0] * psidpsi[2]; /* phi. phidpsi[2]
343 is dimensionless,
344 must divide by R
345 because in
346 cylindrical
347 co-ordinates */
348
349 /* Check that phi remained inside the sector. If not, use the value on
350 the sector boundary. */
351 if (nextrzphi[2] > phimax) {nextrzphi[2] = phimax;}
352 if (nextrzphi[2] < phimin) {nextrzphi[2]=phimin;}
353
354 /* Check convergence (phi difference must be multiplied by R to get
355 the arc length which has dimensions of L) */
356 if(sqrt( (nextrzphi[0] - rzphi[0]) * (nextrzphi[0] - rzphi[0])
357 + (nextrzphi[1] - rzphi[1]) * (nextrzphi[1] - rzphi[1])
358 + rzphi[0]*(nextrzphi[2] - rzphi[2]) *
359 rzphi[0]*(nextrzphi[2] - rzphi[2])) < tol){
360 psi[0] = psidpsi[0];
361 rzphi[0] = nextrzphi[0];
362 rzphi[1] = nextrzphi[1];
363 rzphi[2] = nextrzphi[2];
364
365 // Add a bit of padding
367 psidpsi, rzphi[0], rzphi[2], rzphi[1], time, &sim->B_data);
368 psi[0] = psi[0]
369 + (tol * ( psidpsi[1] + psidpsi[2]/rzphi[0] + psidpsi[3] ));
370 break;
371 }
372
373 rzphi[0] = nextrzphi[0];
374 rzphi[1] = nextrzphi[1];
375 rzphi[2] = nextrzphi[2];
376 iter++;
377
378 if(iter == maxiter) {
379 break;
380 }
381 }
382}
383
384
399 sim_data* sim, int Neval, real* R, real* phi, real* z, real* t,
400 real* ER, real* Ephi, real* Ez) {
401
402 #pragma omp parallel for
403 for(int k = 0; k < Neval; k++) {
404 real E[3];
405 if( E_field_eval_E(E, R[k], phi[k], z[k], t[k],
406 &sim->E_data, &sim->B_data) ) {
407 continue;
408 }
409 ER[k] = E[0];
410 Ephi[k] = E[1];
411 Ez[k] = E[2];
412 }
413}
414
425
436 sim_data* sim, real* mass, real* charge, int* anum, int* znum) {
437
438 int n_species = plasma_get_n_species(&sim->plasma_data);
439 const real* m = plasma_get_species_mass(&sim->plasma_data);
441 const int* a = plasma_get_species_anum(&sim->plasma_data);
442 const int* z = plasma_get_species_znum(&sim->plasma_data);
443 mass[0] = CONST_M_E;
444 charge[0] = -CONST_E;
445 anum[0] = 0;
446 znum[0] = 0;
447 for(int i=1; i<n_species; i++) {
448 mass[i] = m[i];
449 charge[i] = q[i];
450 anum[i] = a[i-1];
451 znum[i] = z[i-1];
452 }
453}
454
468 sim_data* sim, int Neval, real* R, real* phi, real* z, real* t,
469 real* dens, real* temp) {
470
471 int n_species = plasma_get_n_species(&sim->plasma_data);
472
473 #pragma omp parallel for
474 for(int k = 0; k < Neval; k++) {
475 real psi[1], rho[2], n[MAX_SPECIES], T[MAX_SPECIES];
476 if( B_field_eval_psi(psi, R[k], phi[k], z[k], t[k], &sim->B_data) ) {
477 continue;
478 }
479 if( B_field_eval_rho(rho, psi[0], &sim->B_data) ) {
480 continue;
481 }
482 if( plasma_eval_densandtemp(n, T, rho[0], R[k], phi[k], z[k], t[k],
483 &sim->plasma_data) ) {
484 continue;
485 }
486 for(int i=0; i<n_species; i++) {
487 dens[k + i*Neval] = n[i];
488 temp[k + i*Neval] = T[i]/CONST_E;
489 }
490 }
491}
492
505 sim_data* sim, int Neval, real* R, real* phi, real* z, real* t, real* dens) {
506
507 #pragma omp parallel for
508 for(int k = 0; k < Neval; k++) {
509 real psi[1], rho[2], n0[1];
510 if( B_field_eval_psi(psi, R[k], phi[k], z[k], t[k], &sim->B_data) ) {
511 continue;
512 }
513 if( B_field_eval_rho(rho, psi[0], &sim->B_data) ) {
514 continue;
515 }
516 if( neutral_eval_n0(n0, rho[0], R[k], phi[k], z[k], t[k],
517 &sim->neutral_data) ) {
518 continue;
519 }
520 dens[k] = n0[0];
521 }
522}
523
548 sim_data* sim, int Neval,
549 real* R, real* phi, real* z, real* t, real* psi, real* theta, real* zeta,
550 real* dpsidr, real* dpsidphi, real* dpsidz, real* dthetadr,
551 real* dthetadphi, real* dthetadz, real* dzetadr, real* dzetadphi,
552 real* dzetadz, real* rho) {
553
554 #pragma omp parallel for
555 for(int k = 0; k < Neval; k++) {
556 int isinside;
557 real psithetazeta[12], rhoval[2];
558 if( boozer_eval_psithetazeta(psithetazeta, &isinside, R[k], phi[k],
559 z[k], &sim->B_data, &sim->boozer_data) ) {
560 continue;
561 }
562 if(!isinside) {
563 continue;
564 }
565 if( B_field_eval_rho(rhoval, psithetazeta[0], &sim->B_data) ) {
566 continue;
567 }
568 psi[k] = psithetazeta[0];
569 theta[k] = psithetazeta[4];
570 zeta[k] = psithetazeta[8];
571 dpsidr[k] = psithetazeta[1];
572 dpsidphi[k] = psithetazeta[2];
573 dpsidz[k] = psithetazeta[3];
574 dthetadr[k] = psithetazeta[5];
575 dthetadphi[k] = psithetazeta[6];
576 dthetadz[k] = psithetazeta[7];
577 dzetadr[k] = psithetazeta[9];
578 dzetadphi[k] = psithetazeta[10];
579 dzetadz[k] = psithetazeta[11];
580 rho[k] = rhoval[0];
581 }
582}
583
598 sim_data* sim, int Neval, real* R, real* phi, real* z, real* t,
599 real* qprof, real* jac, real* jacB2) {
600
601 #pragma omp parallel for
602 for(int k = 0; k < Neval; k++) {
603 int isinside;
604 real psithetazeta[12], B[15];
605 if( boozer_eval_psithetazeta(psithetazeta, &isinside, R[k], phi[k],
606 z[k], &sim->B_data, &sim->boozer_data) ) {
607 continue;
608 }
609 if(!isinside) {
610 continue;
611 }
612 if( B_field_eval_B_dB(B, R[k], phi[k], z[k], t[k], &sim->B_data) ) {
613 continue;
614 }
615
616 real bvec[] = {B[0], B[4], B[8]};
617 real gradpsi[] = {psithetazeta[1],
618 psithetazeta[2]/R[k],
619 psithetazeta[3]};
620 real gradtheta[] = {psithetazeta[5],
621 psithetazeta[6]/R[k],
622 psithetazeta[7]};
623 real gradzeta[] = {psithetazeta[9],
624 psithetazeta[10]/R[k],
625 psithetazeta[11]};
626
627 real veca[3], vecb[3];
628
629 math_cross(gradpsi, gradzeta, veca);
630 math_cross(gradpsi, gradtheta, vecb);
631 qprof[k] = (veca[1] - bvec[1]) / vecb[1];
632
633 math_cross(gradtheta, gradzeta, veca);
634 jac[k] = -1.0 / math_dot(veca, gradpsi);
635 jacB2[k] = jac[k]*math_norm(bvec)*math_norm(bvec);
636 }
637}
638
647
648 return mhd_get_n_modes(&sim->mhd_data);
649}
650
662 sim_data* sim, int* nmode, int* mmode, real* amplitude, real* omega,
663 real* phase) {
664
665 int n_modes = mhd_get_n_modes(&sim->mhd_data);
666 const int* n = mhd_get_nmode(&sim->mhd_data);
667 const int* m = mhd_get_mmode(&sim->mhd_data);
668 const real* a = mhd_get_amplitude(&sim->mhd_data);
669 const real* o = mhd_get_frequency(&sim->mhd_data);
670 const real* p = mhd_get_phase(&sim->mhd_data);
671 for(int i=0; i<n_modes; i++) {
672 nmode[i] = n[i];
673 mmode[i] = m[i];
674 amplitude[i] = a[i];
675 omega[i] = o[i];
676 phase[i] = p[i];
677 }
678}
679
702 sim_data* sim, int Neval,
703 real* R, real* phi, real* z, real* t, int includemode,
704 real* alpha, real* dadr, real* dadphi, real* dadz, real* dadt, real* Phi,
705 real* dPhidr, real* dPhidphi, real* dPhidz, real* dPhidt) {
706
707 #pragma omp parallel for
708 for(int k = 0; k < Neval; k++) {
709 real mhd_dmhd[10];
710 if( mhd_eval(mhd_dmhd, R[k], phi[k], z[k], t[k], includemode,
711 &sim->boozer_data, &sim->mhd_data, &sim->B_data) ) {
712 continue;
713 }
714 alpha[k] = mhd_dmhd[0];
715 dadr[k] = mhd_dmhd[2];
716 dadphi[k] = mhd_dmhd[3];
717 dadz[k] = mhd_dmhd[4];
718 dadt[k] = mhd_dmhd[1];
719 Phi[k] = mhd_dmhd[5];
720 dPhidr[k] = mhd_dmhd[7];
721 dPhidphi[k] = mhd_dmhd[8];
722 dPhidz[k] = mhd_dmhd[9];
723 dPhidt[k] = mhd_dmhd[6];
724 }
725}
726
746 sim_data* sim, int Neval,
747 real* R, real* phi, real* z, real* t, int includemode, real* mhd_br,
748 real* mhd_bphi, real* mhd_bz, real* mhd_er, real* mhd_ephi, real* mhd_ez,
749 real* mhd_phi) {
750
751 int onlypert = 1;
752 #pragma omp parallel for
753 for(int k = 0; k < Neval; k++) {
754 real pert_field[7];
755 if( mhd_perturbations(pert_field, R[k], phi[k], z[k], t[k], onlypert,
756 includemode, &sim->boozer_data, &sim->mhd_data,
757 &sim->B_data) ) {
758 continue;
759 }
760 mhd_br[k] = pert_field[0];
761 mhd_bphi[k] = pert_field[1];
762 mhd_bz[k] = pert_field[2];
763 mhd_er[k] = pert_field[3];
764 mhd_ephi[k] = pert_field[4];
765 mhd_ez[k] = pert_field[5];
766 mhd_phi[k] = pert_field[6];
767 }
768}
769
797 sim_data* sim, int Neval, real* R, real* phi, real* z, real* t,
798 int Nv, real* va, real ma, real qa, real* F, real* Dpara, real* Dperp,
799 real* K, real* nu, real* Q, real* dQ, real* dDpara, real* clog,
800 real* mu0, real* mu1, real* dmu0) {
801
802 /* Evaluate plasma parameters */
803 int n_species = plasma_get_n_species(&sim->plasma_data);
804 const real* qb = plasma_get_species_charge(&sim->plasma_data);
805 const real* mb = plasma_get_species_mass(&sim->plasma_data);
806
807 #pragma omp parallel for
808 for(int k=0; k<Neval; k++) {
809 real mufun[3] = {0., 0., 0.};
810
811 /* Evaluate rho as it is needed to evaluate plasma parameters */
812 real psi, rho[2];
813 if( B_field_eval_psi(&psi, R[k], phi[k], z[k], t[k], &sim->B_data) ) {
814 continue;
815 }
816 if( B_field_eval_rho(rho, psi, &sim->B_data) ) {
817 continue;
818 }
819
821 if( plasma_eval_densandtemp(nb, Tb, rho[0], R[k], phi[k], z[k], t[k],
822 &sim->plasma_data) ) {
823 continue;
824 }
825
826 /* Evaluate coefficients for different velocities */
827 for(int iv=0; iv<Nv; iv++) {
828
829 /* Loop through all plasma species */
830 for(int ib=0; ib<n_species; ib++) {
831
832 /* Coulomb logarithm */
833 real clogab[MAX_SPECIES];
834 mccc_coefs_clog(clogab, ma, qa, va[iv], n_species, mb, qb,
835 nb, Tb);
836
837 /* Special functions */
838 real vb = sqrt( 2 * Tb[ib] / mb[ib] );
839 real x = va[iv] / vb;
840 mccc_coefs_mufun(mufun, x, &sim->mccc_data);
841
842 /* Coefficients */
843 real Fb = mccc_coefs_F(ma, qa, mb[ib], qb[ib], nb[ib], vb,
844 clogab[ib], mufun[0]);
845 real Qb = mccc_coefs_Q(ma, qa, mb[ib], qb[ib], nb[ib], vb,
846 clogab[ib], mufun[0]);
847 real dQb = mccc_coefs_dQ(ma, qa, mb[ib], qb[ib], nb[ib], vb,
848 clogab[ib], mufun[2]);
849 real Dparab = mccc_coefs_Dpara(ma, qa, va[iv], qb[ib], nb[ib],
850 vb, clogab[ib], mufun[0]);
851 real Dperpb = mccc_coefs_Dperp(ma, qa, va[iv], qb[ib], nb[ib],
852 vb, clogab[ib], mufun[1]);
853 real dDparab = mccc_coefs_dDpara(ma, qa, va[iv], qb[ib], nb[ib],
854 vb, clogab[ib], mufun[0],
855 mufun[2]);
856 real Kb = mccc_coefs_K(va[iv], Dparab, dDparab, Qb);
857 real nub = mccc_coefs_nu(va[iv], Dperpb);
858
859 /* Store requested quantities */
860 int idx = ib*Nv*Neval + Nv * k + iv;
861 if(mu0 != NULL) { mu0[idx] = mufun[0]; }
862 if(mu1 != NULL) { mu1[idx] = mufun[1]; }
863 if(dmu0 != NULL) { dmu0[idx] = mufun[2]; }
864 if(clog != NULL) { clog[idx] = clogab[ib]; }
865 if(F != NULL) { F[idx] = Fb; }
866 if(Dpara != NULL) { Dpara[idx] = Dparab; }
867 if(Dperp != NULL) { Dperp[idx] = Dperpb; }
868 if(K != NULL) { K[idx] = Kb; }
869 if(nu != NULL) { nu[idx] = nub; }
870 if(Q != NULL) { Q[idx] = Qb; }
871 if(dQ != NULL) { dQ[idx] = dQb; }
872 if(dDpara != NULL) { dDpara[idx] = dDparab; }
873 }
874 }
875 }
876}
877
896 sim_data* sim,
897 int Neval, real* R, real* phi, real* z, real* t, int Nv, real* va,
898 int Aa, int Za, real ma, int reac_type, real* ratecoeff) {
899
900 const int* Zb = plasma_get_species_znum(&sim->plasma_data);
901 const int* Ab = plasma_get_species_anum(&sim->plasma_data);
902 int nion = plasma_get_n_species(&sim->plasma_data) - 1;
903 int nspec = neutral_get_n_species(&sim->neutral_data);
904
905 #pragma omp parallel for
906 for (int k=0; k < Neval; k++) {
907 real psi[1], rho[2], T0[1], n[MAX_SPECIES], T[MAX_SPECIES],
908 n0[MAX_SPECIES];
909 if( B_field_eval_psi(psi, R[k], phi[k], z[k], t[k], &sim->B_data) ) {
910 continue;
911 }
912 if( B_field_eval_rho(rho, psi[0], &sim->B_data) ) {
913 continue;
914 }
915 if( plasma_eval_densandtemp(n, T, rho[0], R[k], phi[k], z[k], t[k],
916 &sim->plasma_data) ) {
917 continue;
918 }
919 if( neutral_eval_t0(T0, rho[0], R[k], phi[k], z[k], t[k],
920 &sim->neutral_data) ) {
921 continue;
922 }
923 if( neutral_eval_n0(n0, rho[0], R[k], phi[k], z[k], t[k],
924 &sim->neutral_data) ) {
925 continue;
926 }
927 for (int j=0; j < Nv; j++) {
928 real E = (physlib_gamma_vnorm(va[j]) - 1.0) * ma * CONST_C*CONST_C;
929 real val;
930 switch (reac_type) {
931 case sigmav_CX:
932 if( asigma_eval_cx(
933 &val, Za, Aa, E, ma, nspec, Zb, Ab, T0[0], n0,
934 &sim->asigma_data) ) {
935 continue;
936 }
937 ratecoeff[Nv*k + j] = val;
938 break;
939 case sigmav_BMS:
940 if( asigma_eval_bms(
941 &val, Za, Aa, E, ma, nion, Zb, Ab, T[0], n,
942 &sim->asigma_data) ) {
943 continue;
944 }
945 ratecoeff[Nv*k + j] = val * n[0];
946 break;
947 default:
948 break;
949 }
950 }
951 }
952
953}
954
1001 sim_data* sim, real* B_offload_array, int Neval,
1002 real* R, real* phi, real* z, real* t, real mass, real q, real vpar,
1003 real* Eplus_real, real* Eminus_real, real* Eplus_imag, real* Eminus_imag,
1004 real* res_cond) {
1005
1006 #pragma omp parallel
1007 {
1008 /* The function that evaluates resonance condition takes an RFOF marker
1009 * as an input. However, only the R and vpar values are actually used.
1010 * Therefore, we initialize a dummy marker and adjust only the values of
1011 * R and vpar. */
1012 rfof_marker rfof_mrk;
1013 int dummy_int = 1;
1014 real dummy_real = -999.0; /*-999.0 to be on the safe side */
1015 rfof_set_up(&rfof_mrk, &sim->rfof_data);
1016
1017 #pragma omp for
1018 for(int k = 0; k < Neval; k++) {
1019 real B[3];
1020 if( B_field_eval_B(B, R[k], phi[k], z[k], t[k], &sim->B_data) ) {
1021 continue;
1022 }
1023 real B_magn = sqrt(B[0]*B[0] + B[1]*B[1] + B[2]*B[2]);
1024 real gyrofreq = q * B_magn / mass;
1025 rfof_set_marker_manually(&rfof_mrk, &dummy_int,
1026 &dummy_real, &(R[k]), &dummy_real, &dummy_real, &dummy_real,
1027 &dummy_real, &dummy_real, &dummy_real, &dummy_real, &dummy_real,
1028 &dummy_real, &vpar, &dummy_real, &gyrofreq, &dummy_real,
1029 &dummy_real, &dummy_int, &dummy_int);
1030
1031 int nharm; /* For storing return value which is not used */
1032 rfof_eval_resonance_function(
1033 &(res_cond[k]), &nharm, &rfof_mrk, &sim->rfof_data);
1034
1035 // TODO: this should return a non-zero value for failed evaluations
1036 rfof_eval_rf_wave(
1037 &(Eplus_real[k]), &(Eminus_real[k]), &(Eplus_imag[k]),
1038 &(Eminus_imag[k]), R[k], z[k], &sim->rfof_data);
1039 }
1040 rfof_tear_down(&rfof_mrk);
1041 }
1042}
a5err B_field_eval_psi_dpsi(real psi_dpsi[4], real r, real phi, real z, real t, B_field_data *Bdata)
Evaluate poloidal flux psi and its derivatives.
Definition B_field.c:166
a5err B_field_eval_rho(real rho[2], real psi, B_field_data *Bdata)
Evaluate normalized poloidal flux rho and its psi derivative.
Definition B_field.c:228
a5err B_field_eval_psi(real *psi, real r, real phi, real z, real t, B_field_data *Bdata)
Evaluate poloidal flux psi.
Definition B_field.c:102
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.
Definition B_field.c:449
a5err B_field_eval_rho_drho(real rho_drho[4], real r, real phi, real z, B_field_data *Bdata)
Evaluate normalized poloidal flux rho and its derivatives.
Definition B_field.c:312
a5err B_field_get_axis_rz(real rz[2], B_field_data *Bdata, real phi)
Return magnetic axis Rz-coordinates.
Definition B_field.c:501
a5err B_field_eval_B(real B[3], real r, real phi, real z, real t, B_field_data *Bdata)
Evaluate magnetic field.
Definition B_field.c:374
Header file for B_field.c.
a5err E_field_eval_E(real E[3], real r, real phi, real z, real t, E_field_data *Edata, B_field_data *Bdata)
Evaluate electric field.
Definition E_field.c:82
Header file for E_field.c.
Main header file for ASCOT5.
double real
Definition ascot5.h:85
#define MAX_SPECIES
Maximum number of plasma species.
Definition ascot5.h:95
a5err asigma_eval_cx(real *ratecoeff, int z_1, int a_1, real E, real mass, int nspec, const int *znum, const int *anum, real T_0, real *n_0, asigma_data *asigma_data)
Evaluate charge exchange rate coefficient.
Definition asigma.c:191
a5err asigma_eval_bms(real *ratecoeff, int z_1, int a_1, real E, real mass, int nion, const int *znum, const int *anum, real T_e, real *n_i, asigma_data *asigma_data)
Evaluate beam stopping rate coefficient.
Definition asigma.c:237
Header file for asigma.c.
a5err boozer_eval_psithetazeta(real psithetazeta[12], int *isinside, real r, real phi, real z, B_field_data *Bdata, boozer_data *boozerdata)
Evaluate Boozer coordinates and partial derivatives.
Definition boozer.c:124
Header file for boozer.c.
Header file containing physical and mathematical constants.
#define CONST_M_E
Electron mass [kg].
Definition consts.h:41
#define CONST_C
Speed of light [m/s].
Definition consts.h:23
#define CONST_E
Elementary charge [C].
Definition consts.h:35
Header file for hdf5_bfield.c.
Header file for hdf5_boozer.c.
Header file for hdf5_efielc.c.
Header file for hdf5_helpers.h.
Header file for hdf5_interface.c.
Header file for hdf5_mhd.c.
Header file for hdf5_neutral.c.
Header file for hdf5_plasma.c.
Header file for hdf5_wall.c.
@ R
Definition hist.h:18
void libascot_neutral_eval_density(sim_data *sim, int Neval, real *R, real *phi, real *z, real *t, real *dens)
Evaluate neutral density at given coordinates.
Definition libascot.c:504
void libascot_eval_rfof(sim_data *sim, real *B_offload_array, int Neval, real *R, real *phi, real *z, real *t, real mass, real q, real vpar, real *Eplus_real, real *Eminus_real, real *Eplus_imag, real *Eminus_imag, real *res_cond)
Evaluate ICRH electric field and the resonance condition.
Definition libascot.c:1000
void libascot_E_field_eval_E(sim_data *sim, int Neval, real *R, real *phi, real *z, real *t, real *ER, real *Ephi, real *Ez)
Evaluate electric field vector at given coordinates.
Definition libascot.c:398
void libascot_eval_collcoefs(sim_data *sim, int Neval, real *R, real *phi, real *z, real *t, int Nv, real *va, real ma, real qa, real *F, real *Dpara, real *Dperp, real *K, real *nu, real *Q, real *dQ, real *dDpara, real *clog, real *mu0, real *mu1, real *dmu0)
Evaluate collision coefficients.
Definition libascot.c:796
void libascot_boozer_eval_fun(sim_data *sim, int Neval, real *R, real *phi, real *z, real *t, real *qprof, real *jac, real *jacB2)
Evaluate boozer coordinates related quantities.
Definition libascot.c:597
void libascot_B_field_gradient_descent_3d(sim_data *sim, real psi[1], real rzphi[3], real phimin, real phimax, real step, real tol, int maxiter, int ascent)
Find one psi minimum using the gradient descent method for 3D field inside a sector (phimin < phi < p...
Definition libascot.c:320
void libascot_eval_ratecoeff(sim_data *sim, int Neval, real *R, real *phi, real *z, real *t, int Nv, real *va, int Aa, int Za, real ma, int reac_type, real *ratecoeff)
Evaluate atomic reaction rate coefficient.
Definition libascot.c:895
void libascot_mhd_eval_perturbation(sim_data *sim, int Neval, real *R, real *phi, real *z, real *t, int includemode, real *mhd_br, real *mhd_bphi, real *mhd_bz, real *mhd_er, real *mhd_ephi, real *mhd_ez, real *mhd_phi)
Evaluate MHD perturbation EM-field components.
Definition libascot.c:745
int libascot_plasma_get_n_species(sim_data *sim)
Get number of plasma species.
Definition libascot.c:422
void libascot_mhd_get_mode_specs(sim_data *sim, int *nmode, int *mmode, real *amplitude, real *omega, real *phase)
Get MHD mode amplitude, frequency, phase, and mode numbers.
Definition libascot.c:661
void libascot_plasma_eval_background(sim_data *sim, int Neval, real *R, real *phi, real *z, real *t, real *dens, real *temp)
Evaluate plasma density and temperature at given coordinates.
Definition libascot.c:467
void libascot_boozer_eval_psithetazeta(sim_data *sim, int Neval, real *R, real *phi, real *z, real *t, real *psi, real *theta, real *zeta, real *dpsidr, real *dpsidphi, real *dpsidz, real *dthetadr, real *dthetadphi, real *dthetadz, real *dzetadr, real *dzetadphi, real *dzetadz, real *rho)
Evaluate boozer coordinates and derivatives.
Definition libascot.c:547
int libascot_mhd_get_n_modes(sim_data *sim)
Get number of MHD modes.
Definition libascot.c:646
void libascot_B_field_gradient_descent(sim_data *sim, real psi[1], real rz[2], real phi, real step, real tol, int maxiter, int ascent)
Find psi on axis using the gradient descent method.
Definition libascot.c:257
void libascot_B_field_rhotheta2rz(sim_data *sim, int Neval, real *rho, real *theta, real *phi, real t, int maxiter, real tol, real *r, real *z)
Map (rho, theta, phi) to (R,z) coordinates.
Definition libascot.c:173
void libascot_B_field_eval_B_dB(sim_data *sim, int Neval, real *R, real *phi, real *z, real *t, real *BR, real *Bphi, real *Bz, real *BR_dR, real *BR_dphi, real *BR_dz, real *Bphi_dR, real *Bphi_dphi, real *Bphi_dz, real *Bz_dR, real *Bz_dphi, real *Bz_dz)
Evaluate magnetic field vector and derivatives at given coordinates.
Definition libascot.c:65
void libascot_B_field_get_axis(sim_data *sim, int Neval, real *phi, real *Raxis, real *zaxis)
Get magnetic axis at given coordinates.
Definition libascot.c:141
void libascot_plasma_get_species_mass_and_charge(sim_data *sim, real *mass, real *charge, int *anum, int *znum)
Get mass and charge of all plasma species.
Definition libascot.c:435
void libascot_mhd_eval(sim_data *sim, int Neval, real *R, real *phi, real *z, real *t, int includemode, real *alpha, real *dadr, real *dadphi, real *dadz, real *dadt, real *Phi, real *dPhidr, real *dPhidphi, real *dPhidz, real *dPhidt)
Evaluate MHD perturbation potentials.
Definition libascot.c:701
void libascot_B_field_eval_rho(sim_data *sim, int Neval, real *R, real *phi, real *z, real *t, real *rho, real *drhodpsi, real *psi, real *dpsidr, real *dpsidphi, real *dpsidz)
Evaluate normalized poloidal flux at given coordinates.
Definition libascot.c:108
Header file for math.c.
#define math_dot(a, b)
Calculate dot product a[3] dot b[3].
Definition math.h:32
#define math_cross(a, b, c)
Calculate cross product for 3D vectors c = a x b.
Definition math.h:35
#define math_norm(a)
Calculate norm of 3D vector a.
Definition math.h:68
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
#define mccc_coefs_dDpara(ma, qa, va, qb, nb, vb, clogab, mu0, dmu0)
Evaluate derivative of non-relativistic parallel diffusion coefficient [m/s^2].
Definition mccc_coefs.h:126
#define mccc_coefs_dQ(ma, qa, mb, qb, nb, vb, clogab, dmu0)
Evaluate derivative of non-relativistic drag coefficient [m/s^2].
Definition mccc_coefs.h:61
#define mccc_coefs_K(va, Dpara, dDpara, Q)
Evaluate guiding center drag coefficient [m/s^2].
Definition mccc_coefs.h:167
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_nu(va, Dperp)
Evaluate pitch collision frequency [1/s].
Definition mccc_coefs.h:180
#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
#define mccc_coefs_Q(ma, qa, mb, qb, nb, vb, clogab, mu0)
Evaluate non-relativistic drag coefficient [m/s^2].
Definition mccc_coefs.h:43
int mhd_get_n_modes(mhd_data *mhddata)
Return number of modes.
Definition mhd.c:183
const real * mhd_get_amplitude(mhd_data *mhddata)
Return mode amplitudes.
Definition mhd.c:243
const int * mhd_get_nmode(mhd_data *mhddata)
Return mode toroidal numbers.
Definition mhd.c:203
a5err mhd_perturbations(real pert_field[7], real r, real phi, real z, real t, int pertonly, int includemode, boozer_data *boozerdata, mhd_data *mhddata, B_field_data *Bdata)
Evaluate perturbed fields Btilde, Etilde and potential Phi explicitly.
Definition mhd.c:147
const int * mhd_get_mmode(mhd_data *mhddata)
Return mode poloidal numbers.
Definition mhd.c:223
const real * mhd_get_frequency(mhd_data *mhddata)
Return mode frequencies.
Definition mhd.c:263
a5err mhd_eval(real mhd_dmhd[10], real r, real phi, real z, real t, int includemode, boozer_data *boozerdata, mhd_data *mhddata, B_field_data *Bdata)
Evaluate the needed quantities from MHD mode for orbit following.
Definition mhd.c:91
const real * mhd_get_phase(mhd_data *mhddata)
Return mode phases.
Definition mhd.c:283
Header file for mhd.c.
int neutral_get_n_species(neutral_data *ndata)
Get the number of neutral species.
Definition neutral.c:151
a5err neutral_eval_n0(real *n0, real rho, real r, real phi, real z, real t, neutral_data *ndata)
Evaluate neutral density.
Definition neutral.c:73
a5err neutral_eval_t0(real *t0, real rho, real r, real phi, real z, real t, neutral_data *ndata)
Evaluate neutral temperature.
Definition neutral.c:115
Header file for neutral.c.
Methods to evaluate elementary physical quantities.
#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
const int * plasma_get_species_znum(plasma_data *pls_data)
Get charge number of ion species.
Definition plasma.c:372
int plasma_get_n_species(plasma_data *pls_data)
Get the number of plasma species.
Definition plasma.c:284
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
const int * plasma_get_species_anum(plasma_data *pls_data)
Get atomic mass number of ion species.
Definition plasma.c:400
Header file for plasma.c.
Header file for simulate.c.
Reusable struct for storing marker specific data during the simulation loop.
Definition rfof.h:19
Simulation data struct.
Definition simulate.h:58
plasma_data plasma_data
Definition simulate.h:62
mhd_data mhd_data
Definition simulate.h:66
rfof_data rfof_data
Definition simulate.h:70
E_field_data E_data
Definition simulate.h:61
mccc_data mccc_data
Definition simulate.h:75
neutral_data neutral_data
Definition simulate.h:63
boozer_data boozer_data
Definition simulate.h:65
B_field_data B_data
Definition simulate.h:60
asigma_data asigma_data
Definition simulate.h:67
Header file for wall.c.