ASCOT5
Loading...
Searching...
No Matches
asigma_loc.c
Go to the documentation of this file.
1
9#include <stdio.h>
10#include <stdlib.h>
11#include "../ascot5.h"
12#include "../print.h"
13#include "../error.h"
14#include "../spline/interp.h"
15#include "../consts.h"
16#include "../math.h"
17#include "../physlib.h"
18#include "../suzuki.h"
19#include "../asigma.h"
20#include "asigma_loc.h"
21
29int asigma_loc_init(asigma_loc_data* data, int nreac,
30 int* z1, int* a1, int* z2, int* a2, int* reactype,
31 int* ne, real* emin, real* emax,
32 int* nn, real* nmin, real* nmax,
33 int* nT, real* Tmin, real* Tmax, real* sigma) {
34
35 int err = 0;
36 data->N_reac = nreac;
37 data->z_1 = (int*) malloc( nreac * sizeof(int) );
38 data->a_1 = (int*) malloc( nreac * sizeof(int) );
39 data->z_2 = (int*) malloc( nreac * sizeof(int) );
40 data->a_2 = (int*) malloc( nreac * sizeof(int) );
41 data->reac_type = (int*) malloc( nreac * sizeof(int) );
42 data->sigma = (interp1D_data*) malloc( nreac * sizeof(interp1D_data) );
43 data->sigmav = (interp2D_data*) malloc( nreac * sizeof(interp2D_data) );
44 data->BMSsigmav = (interp3D_data*) malloc( nreac * sizeof(interp3D_data) );
45 for(int i_reac = 0; i_reac < nreac; i_reac++) {
46 data->z_1[i_reac] = z1[i_reac];
47 data->a_1[i_reac] = a1[i_reac];
48 data->z_2[i_reac] = z2[i_reac];
49 data->a_2[i_reac] = a2[i_reac];
50 data->reac_type[i_reac] = reactype[i_reac];
51
52 /* Initialize spline struct according to dimensionality of
53 reaction data (and mark reaction availability) */
54 int dim = (ne[i_reac] > 1) + (nn[i_reac] > 1) + (nT[i_reac] > 1);
55 real* pos = sigma;
56 switch(dim) {
57 case 1:
58 err = interp1Dcomp_setup(&data->sigma[i_reac], pos,
59 ne[i_reac], NATURALBC,
60 emin[i_reac], emax[i_reac]);
61 pos += ne[i_reac];
62 break;
63 case 2:
64 err = interp2Dcomp_setup(&data->sigmav[i_reac], pos,
65 ne[i_reac], nT[i_reac],
67 emin[i_reac], emax[i_reac],
68 Tmin[i_reac], Tmax[i_reac]);
69 pos += ne[i_reac] * nT[i_reac];
70 break;
71 case 3:
72 err = interp3Dcomp_setup(&data->BMSsigmav[i_reac], pos,
73 ne[i_reac], nn[i_reac], nT[i_reac],
75 emin[i_reac], emax[i_reac],
76 nmin[i_reac], nmax[i_reac],
77 Tmin[i_reac], Tmax[i_reac]);
78 pos += ne[i_reac] * nn[i_reac] * nT[i_reac];
79 break;
80 default:
81 /* Unrecognized dimensionality. Produce error. */
82 print_err("Error: Unrecognized abscissa dimensionality\n");
83 err = 1;
84 break;
85 }
86 }
87
88 print_out(VERBOSE_IO, "\nFound data for %d atomic reactions:\n",
89 data->N_reac);
90 for(int i_reac = 0; i_reac < data->N_reac; i_reac++) {
92 "Reaction number / Total number of reactions = %d / %d\n"
93 " Reactant species Z_1 / A_1, Z_2 / A_2 = %d / %d, %d / %d\n"
94 " Min/Max energy = %1.2le / %1.2le\n"
95 " Min/Max density = %1.2le / %1.2le\n"
96 " Min/Max temperature = %1.2le / %1.2le\n"
97 " Number of energy grid points = %d\n"
98 " Number of density grid points = %d\n"
99 " Number of temperature grid points = %d\n",
100 i_reac+1, data->N_reac, data->z_1[i_reac], data->a_1[i_reac],
101 data->z_2[i_reac], data->a_2[i_reac], emin[i_reac], emax[i_reac],
102 nmin[i_reac], nmax[i_reac], Tmin[i_reac], Tmax[i_reac],
103 ne[i_reac], nn[i_reac], nT[i_reac]);
104 }
105
106 return err;
107}
108
115 for(int i_reac = 0; i_reac < data->N_reac; i_reac++) {
116 if(data->reac_type[i_reac] == sigma_CX) {
117 free(data->sigma[i_reac].c);
118 }
119 else if(data->reac_type[i_reac] == sigmav_CX) {
120 free(data->sigmav[i_reac].c);
121 }
122 else if(data->reac_type[i_reac] == sigmav_BMS) {
123 free(data->BMSsigmav[i_reac].c);
124 }
125 }
126 free(data->z_1);
127 free(data->a_1);
128 free(data->z_2);
129 free(data->a_2);
130 free(data->reac_type);
131 free(data->sigma);
132 free(data->sigmav);
133 free(data->BMSsigmav);
134}
135
142 // TODO: Implement
143}
144
167 real* sigma, int z_1, int a_1, int z_2, int a_2, real E_coll_per_amu,
168 int reac_type, int extrapolate, asigma_loc_data* asigma_data) {
169 a5err err = 0;
170
171 /* We look for a match of the reaction identifiers in asigma_data to
172 determine if the reaction of interest has been initialized */
173 int reac_found = -1, i_reac;
174 for(i_reac = 0; i_reac < asigma_data->N_reac; i_reac++) {
175 if(z_1 == asigma_data->z_1[i_reac] &&
176 a_1 == asigma_data->a_1[i_reac] &&
177 z_2 == asigma_data->z_2[i_reac] &&
178 a_2 == asigma_data->a_2[i_reac] &&
179 reac_type == asigma_data->reac_type[i_reac]) {
180 reac_found = i_reac;
181 }
182 }
183 i_reac = reac_found;
184
185 /* The cross-section is evaluated if reaction data was found,
186 is available, and its interpolation implemented. Otherwise,
187 the cross-section is set to zero to avoid further problems. */
188 if(reac_found < 0) {
189 /* Reaction not found. Raise error. */
191 } else {
192 if(asigma_data->reac_type[i_reac] == sigma_ioniz ||
193 asigma_data->reac_type[i_reac] == sigma_recomb ||
194 asigma_data->reac_type[i_reac] == sigma_CX) {
195 int interperr = 0;
196 interperr += interp1Dcomp_eval_f(sigma,
197 &asigma_data->sigma[i_reac],
198 E_coll_per_amu);
199 if(interperr) {
200 /* Energy is outside spline domain */
201 if(extrapolate) {
202 *sigma = 0.0;
203 } else {
204 err = error_raise( ERR_INPUT_EVALUATION, __LINE__,
206 }
207 }
208 } else {
209 /* Interpolation of cross-section not implemented. Raise error. */
211 }
212 }
213 return err;
214}
215
242 real* sigmav, int z_1, int a_1, real m_1, int z_2, int a_2,
243 real E, real T_e, real T_0, real n_i, int reac_type, int extrapolate,
245 a5err err = 0;
246
247 /* Convert Joule to eV */
248 E /= CONST_E;
249 T_e /= CONST_E;
250 T_0 /= CONST_E;
251
252 /* Find the matching reaction. Note that BMS data is same for all
253 * isotopes, so we don't compare anums */
254 int reac_found = -1, i_reac;
255 for(i_reac = 0; i_reac < asigma_data->N_reac; i_reac++) {
256 if(reac_type == sigmav_BMS &&
257 z_1 == asigma_data->z_1[i_reac] &&
258 z_2 == asigma_data->z_2[i_reac] &&
259 reac_type == asigma_data->reac_type[i_reac]) {
260 reac_found = i_reac;
261 } else if(z_1 == asigma_data->z_1[i_reac] &&
262 a_1 == asigma_data->a_1[i_reac] &&
263 z_2 == asigma_data->z_2[i_reac] &&
264 a_2 == asigma_data->a_2[i_reac] &&
265 reac_type == asigma_data->reac_type[i_reac]) {
266 reac_found = i_reac;
267 }
268 }
269 i_reac = reac_found;
270
271 if(reac_found < 0) {
272 /* Reaction not found. Raise error. */
274 } else {
275 /* Interpolation error means the data has to be extrapolated */
276 if(reac_type == sigmav_ioniz ||
277 reac_type == sigmav_recomb ||
278 reac_type == sigmav_CX) {
279 int interperr = interp2Dcomp_eval_f(
280 sigmav, &asigma_data->sigmav[i_reac], E, T_0);
281 if(interperr) {
282 if(extrapolate) {
283 *sigmav = 0.0;
284 } else {
285 err = error_raise( ERR_INPUT_EVALUATION, __LINE__,
287 }
288 }
289 } else if(reac_type == sigmav_BMS) {
290 int interperr = interp3Dcomp_eval_f(
291 sigmav, &asigma_data->BMSsigmav[i_reac], E/a_2,
292 z_2*n_i, T_e);
293 if(interperr) {
294 if(extrapolate) {
295 *sigmav = 0.0;
296 } else {
297 err = error_raise( ERR_INPUT_EVALUATION, __LINE__,
299 }
300 }
301 } else {
302 /* Interpolation of rate coefficient not implemented.
303 Raise error. */
305 }
306 }
307
308 return err;
309}
310
335 real* ratecoeff, int z_1, int a_1, real E, real mass, int nspec,
336 const int* znum, const int* anum, real T_0, real* n_0, int extrapolate,
338 a5err err = 0;
339
340 /* Convert Joule to eV */
341 E /= CONST_E;
342 T_0 /= CONST_E;
343 *ratecoeff = 0;
344 for(int i_spec = 0; i_spec < nspec; i_spec++) {
345
346 /* Find the matching reaction */
347 int reac_found = -1, i_reac;
348 for(i_reac = 0; i_reac < asigma_data->N_reac; i_reac++) {
349 if(asigma_data->z_1[i_reac] == z_1 &&
350 asigma_data->a_1[i_reac] == a_1 &&
351 asigma_data->z_2[i_reac] == znum[i_spec] &&
352 asigma_data->a_2[i_reac] == anum[i_spec] &&
353 asigma_data->reac_type[i_reac] == sigmav_CX) {
354 reac_found = i_reac;
355 }
356 }
357 i_reac = reac_found;
358
359 if(reac_found < 0) {
360 /* Reaction not found. Raise error. */
362 } else {
363 real sigmav;
364 int interperr = interp2Dcomp_eval_f(
365 &sigmav, &asigma_data->sigmav[i_reac], E, T_0);
366
367 /* Interpolation error means the data has to be extrapolated */
368 if(interperr) {
369 if(extrapolate) {
370 sigmav = 0.0;
371 } else {
372 err = error_raise( ERR_INPUT_EVALUATION, __LINE__,
374 }
375 }
376 *ratecoeff += sigmav*n_0[i_spec];
377 }
378 }
379
380 return err;
381}
382
407 real* ratecoeff, int z_1, int a_1, real E, real mass, int nion,
408 const int* znum, const int* anum, real T_e, real* n_i, int extrapolate,
410 a5err err = 0;
411
412 /* Convert Joule to eV */
413 real E_eV = E / CONST_E;
414 T_e /= CONST_E;
415
416 /* Find the matching reaction. Note that BMS data is same for all
417 * isotopes, so we don't compare anums */
418 int reac_found = -1; real n_e = 0; *ratecoeff = 0;
419 for(int i_spec = 0; i_spec < nion; i_spec++) {
420 n_e += znum[i_spec] * n_i[i_spec];
421 for(int i_reac = 0; i_reac < asigma_data->N_reac; i_reac++) {
422 if(asigma_data->z_1[i_reac] == z_1 &&
423 asigma_data->z_2[i_reac] == znum[i_spec] &&
424 asigma_data->reac_type[i_reac] == sigmav_BMS) {
425 reac_found = i_reac;
426 real sigmav;
427 int interperr = \
428 interp3Dcomp_eval_f(
429 &sigmav, &asigma_data->BMSsigmav[i_reac],
430 E_eV/a_1, znum[i_spec] * n_i[i_spec], T_e);
431
432 /* Interpolation error means the data has to be extrapolated */
433 if(interperr) {
434 if(extrapolate) {
435 sigmav = 0.0;
436 } else {
437 err = error_raise( ERR_INPUT_EVALUATION, __LINE__,
439 }
440 }
441 *ratecoeff += sigmav * ( znum[i_spec] * n_i[i_spec]);
442 }
443 }
444 }
445 *ratecoeff /= n_e;
446
447 if(reac_found < 0) {
448 /* Reaction not found. Try Suzuki before throwing error. */
449 T_e *= CONST_E;
450 real gamma = physlib_gamma_Ekin(mass, E);
451 real vnorm = physlib_vnorm_gamma(gamma);
452 if(suzuki_sigmav(ratecoeff, E/a_1, vnorm, n_e, T_e, nion, n_i, anum,
453 znum)) {
455 }
456 }
457
458 return err;
459}
Main header file for ASCOT5.
double real
Definition ascot5.h:85
Header file for asigma.c.
int asigma_loc_init(asigma_loc_data *data, int nreac, int *z1, int *a1, int *z2, int *a2, int *reactype, int *ne, real *emin, real *emax, int *nn, real *nmin, real *nmax, int *nT, real *Tmin, real *Tmax, real *sigma)
Initialize local file atomic data and check inputs.
Definition asigma_loc.c:29
void asigma_loc_free(asigma_loc_data *data)
Free allocated resources.
Definition asigma_loc.c:114
a5err asigma_loc_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, int extrapolate, asigma_loc_data *asigma_data)
Evaluate atomic reaction rate coefficient.
Definition asigma_loc.c:334
a5err asigma_loc_eval_sigma(real *sigma, int z_1, int a_1, int z_2, int a_2, real E_coll_per_amu, int reac_type, int extrapolate, asigma_loc_data *asigma_data)
Evaluate atomic reaction cross-section.
Definition asigma_loc.c:166
void asigma_loc_offload(asigma_loc_data *data)
Offload data to the accelerator.
Definition asigma_loc.c:141
a5err asigma_loc_eval_sigmav(real *sigmav, int z_1, int a_1, real m_1, int z_2, int a_2, real E, real T_e, real T_0, real n_i, int reac_type, int extrapolate, asigma_loc_data *asigma_data)
Evaluate atomic reaction rate coefficient.
Definition asigma_loc.c:241
a5err asigma_loc_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, int extrapolate, asigma_loc_data *asigma_data)
Evaluate beam stopping rate coefficient.
Definition asigma_loc.c:406
Header file for asigma_loc.c.
Header file containing physical and mathematical constants.
#define CONST_E
Elementary charge [C]
Definition consts.h:32
Error module for ASCOT5.
unsigned long int a5err
Simulation error flag.
Definition error.h:17
@ EF_ASIGMA_LOC
Definition error.h:52
@ ERR_INPUT_EVALUATION
Definition error.h:63
static DECLARE_TARGET_SIMD a5err error_raise(error_type type, int line, error_file file)
Raise a new error.
Definition error.h:86
Spline interpolation library.
DECLARE_TARGET_END a5err interp3Dcomp_eval_f(real *f, interp3D_data *str, real x, real y, real z)
Evaluate interpolated value of 3D scalar field.
int interp3Dcomp_setup(interp3D_data *str, real *f, int n_x, int n_y, int n_z, int bc_x, int bc_y, int bc_z, real x_min, real x_max, real y_min, real y_max, real z_min, real z_max)
Set up splines to interpolate 3D scalar data.
int interp2Dcomp_setup(interp2D_data *str, real *f, int n_x, int n_y, int bc_x, int bc_y, real x_min, real x_max, real y_min, real y_max)
Set up splines to interpolate 2D scalar data.
@ NATURALBC
Definition interp.h:37
a5err interp1Dcomp_eval_f(real *f, interp1D_data *str, real x)
Evaluate interpolated value of 1D scalar field.
int interp1Dcomp_setup(interp1D_data *str, real *f, int n_x, int bc_x, real x_min, real x_max)
Set up splines to interpolate 1D scalar data.
DECLARE_TARGET_END a5err interp2Dcomp_eval_f(real *f, interp2D_data *str, real x, real y)
Evaluate interpolated value of a 2D field.
Header file for math.c.
Methods to evaluate elementary physical quantities.
#define physlib_vnorm_gamma(gamma)
Evaluate velocity norm from Lorentz factor.
Definition physlib.h:33
#define physlib_gamma_Ekin(m, ekin)
Evaluate Lorentz factor from kinetic energy [J].
Definition physlib.h:103
Macros for printing console output.
#define print_out(v,...)
Print to standard output.
Definition print.h:31
@ VERBOSE_IO
Definition print.h:20
#define print_err(...)
Print to standard error.
Definition print.h:42
Atomic reaction simulation data.
Definition asigma.h:53
Local-files atomic reaction simulation data.
Definition asigma_loc.h:15
interp2D_data * sigmav
Definition asigma_loc.h:23
interp1D_data * sigma
Definition asigma_loc.h:22
interp3D_data * BMSsigmav
Definition asigma_loc.h:24
Cubic interpolation struct.
Definition interp.h:56
real * c
Definition interp.h:62
Bicubic interpolation struct.
Definition interp.h:68
real * c
Definition interp.h:79
Tricubic interpolation struct.
Definition interp.h:85
real * c
Definition interp.h:101
a5err suzuki_sigmav(real *sigmav, real EperAmu, real vnorm, real ne, real te, integer nion, real *ni, const int *anum, const int *znum)
Calculate beam-stopping cross-section according to Suzuki model.
Definition suzuki.c:139
Header file for suzuki.c.