forked from ascot4fusion/ascot5
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathasigma.c
232 lines (215 loc) · 7.67 KB
/
asigma.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/**
* @file asigma.c
* @brief Atomic reaction data interface
*
* This is an interface through which atomic reaction data is initialized
* and accessed. Reading, for example from local files, is done elsewhere.
*
* The name asigma is short for atomicsigma. The word sigma refers to
* cross-section, a fundamental type of reaction probability data. Note
* that the data is not necessarily in the form of pure cross-sections.
* It might be in some derivative form, such as rate coefficients.
*
* To add a new atomic reaction data instance, make sure the functions
* are implemented and called from this interface, and that asigma.h
* contains enum type for the new instance.
*
* The interface checks which instance given data corresponds to from the
* "type"-field in asigma_offload_data or asigma_data that is given
* as an argument, and calls the relevant function for that instance.
*/
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "ascot5.h"
#include "print.h"
#include "error.h"
#include "math.h"
#include "asigma.h"
#include "asigma/asigma_loc.h"
#include "consts.h"
/**
* @brief Load atomic reaction data and prepare parameters
*
* This function fills the relevant atomic sigma offload struct with parameters
* and allocates and fills the offload array. Sets offload array length in the
* offload struct.
*
* The offload data has to have a type when this function is called as it should
* be set when the offload data is constructed from inputs.
*
* This function is host only.
*
* @param offload_data pointer to offload data struct
* @param offload_array pointer to pointer to offload array
*
* @return zero if initialization succeeded
*/
int asigma_init_offload(asigma_offload_data* offload_data,
real** offload_array) {
int err = 0;
switch(offload_data->type) {
case asigma_type_loc:
err = asigma_loc_init_offload(&(offload_data->asigma_loc),
offload_array);
offload_data->offload_array_length =
offload_data->asigma_loc.offload_array_length;
break;
default:
/* Unrecognized input. Produce error. */
print_err("Error: Unrecognized atomic reaction data type.");
err = 1;
break;
}
if(!err) {
print_out(VERBOSE_IO, "Estimated memory usage %.1f MB\n",
offload_data->offload_array_length
* sizeof(real) / (1024.0*1024.0) );
}
return err;
}
/**
* @brief Free offload array and reset parameters
*
* This function deallocates the offload_array.
*
* This function is host only.
*
* @param offload_data pointer to offload data struct
* @param offload_array pointer to pointer to offload array
*/
void asigma_free_offload(asigma_offload_data* offload_data,
real** offload_array) {
switch(offload_data->type) {
case asigma_type_loc:
asigma_loc_free_offload(&(offload_data->asigma_loc), offload_array);
break;
}
}
/**
* @brief Initializes atomic reaction data struct on target
*
* This function copies some atomic reaction parameters from the offload
* struct to the struct on target and sets the atomic reaction data pointers
* to correct offsets in the offload array.
*
* @param asgm_data pointer to data struct on target
* @param offload_data pointer to offload data struct
* @param offload_array pointer to offload array
*
* @return zero if initialization succeeded
*/
int asigma_init(asigma_data* asgm_data,
asigma_offload_data* offload_data,
real* offload_array) {
int err = 0;
switch(offload_data->type) {
case asigma_type_loc:
asigma_loc_init(&(asgm_data->asigma_loc),
&(offload_data->asigma_loc), offload_array);
break;
default:
/* Unrecognized input. Produce error. */
print_err("Error: Unrecognized atomic reaction data type.");
err = 1;
break;
}
asgm_data->type = offload_data->type;
return err;
}
/**
* @brief Evaluate atomic reaction cross-section
*
* This function evaluates the cross-section (sigma) for the atomic reaction
* corresponding to the reaction identifiers given as parameters at the
* given mass-normalized collision energy.
*
* This is a SIMD function.
*
* @param sigma pointer to evaluated cross-section
* @param z_1 atomic number of fast particle
* @param a_1 atomic mass number of fast particle
* @param z_2 atomic number of bulk particle
* @param a_2 atomic mass number of bulk particle
* @param reac_type reaction type
* @param asigma_data pointer to atomic data struct
* @param E_coll_per_amu energy per amu corresponding to collision speed
*
* @return Non-zero a5err value if evaluation failed, zero otherwise
*/
a5err asigma_eval_sigma(
real* sigma, int z_1, int a_1, int z_2, int a_2, int reac_type,
asigma_data* asigma_data, real E_coll_per_amu, int* enable_atomic) {
a5err err = 0;
switch(asigma_data->type) {
case asigma_type_loc:
err = asigma_loc_eval_sigma(sigma,
z_1, a_1,
z_2, a_2,
reac_type,
&(asigma_data->asigma_loc),
E_coll_per_amu,
enable_atomic);
break;
default:
/* Unrecognized input. Produce error. */
err = error_raise( ERR_UNKNOWN_INPUT, __LINE__, EF_ASIGMA );
break;
}
if(err || sigma[0] < 0.0) {
/* In case of error or unphysical negative value, return zero value
to avoid further complications */
sigma[0] = 0.0;
}
return err;
}
/**
* @brief Evaluate atomic reaction rate coefficient
*
* This function evaluates the rate coefficient (<sigma*v>) for the atomic
* reaction corresponding to the reaction identifiers given as parameters
* at the given fast particle energy and bulk plasma conditions.
*
* This is a SIMD function.
*
* @param sigmav pointer to evaluated rate coefficient
* @param z_1 atomic number of fast particle
* @param a_1 atomic mass number of fast particle
* @param m_1 mass of fast particle
* @param z_2 atomic number of bulk particle
* @param a_2 atomic mass number of bulk particle
* @param reac_type reaction type
* @param asigma_data pointer to atomic data struct
* @param E energy of fast particle
* @param T_e electron temperature of bulk plasma
* @param T_i ion temperature of bulk plasma
* @param T_0 temperature of bulk neutrals
* @param n_i ion density of bulk plasma
* @param enable_atomic pointer to atomic enable and functionality flag
*
* @return Non-zero a5err value if evaluation failed, zero otherwise
*/
a5err asigma_eval_sigmav(
real* sigmav, int z_1, int a_1, real m_1, int z_2, int a_2, int reac_type,
asigma_data* asigma_data, real E, real T_e, real T_0, real n_i,
int* enable_atomic) {
a5err err = 0;
switch(asigma_data->type) {
case asigma_type_loc:
err = asigma_loc_eval_sigmav(
sigmav, z_1, a_1, m_1, z_2, a_2,
reac_type, &(asigma_data->asigma_loc),
E, T_e, T_0, n_i, enable_atomic);
break;
default:
/* Unrecognized input. Produce error. */
err = error_raise( ERR_UNKNOWN_INPUT, __LINE__, EF_ASIGMA );
break;
}
if(err || sigmav[0] < 0.0) {
/* In case of error or unphysical negative value, return zero value
to avoid further complications */
sigmav[0] = 0.0;
}
return err;
}