ASCOT5
Loading...
Searching...
No Matches
plasma_1DS.c
Go to the documentation of this file.
1
5#include <stdlib.h>
6#include <math.h>
7#include <float.h>
8#include "../ascot5.h"
9#include "../print.h"
10#include "../error.h"
11#include "../consts.h"
12#include "../spline/interp.h"
13#include "plasma_1DS.h"
14
28#define PLASMA_1DS_NONEG 1
29
31#define PLASMA_1DS_LOG 1
32
34#define PLASMA_1DS_SQRT 2
35
43int plasma_1DS_init(plasma_1DS_data* data, int nrho, real rhomin, real rhomax,
44 int nion, int* anum, int* znum, real* mass, real* charge,
45 real* Te, real* Ti, real* ne, real* ni, real* vtor) {
46 int err = 0;
47 data->n_species = nion + 1;
48 data->anum = (int*) malloc( nion*sizeof(int) );
49 data->znum = (int*) malloc( nion*sizeof(int) );
50 data->mass = (real*) malloc( (nion+1)*sizeof(real) );
51 data->charge = (real*) malloc( (nion+1)*sizeof(real) );
52 for(int i = 0; i < data->n_species; i++) {
53 if(i < nion) {
54 data->znum[i] = znum[i];
55 data->anum[i] = anum[i];
56 }
57 data->mass[i] = mass[i];
58 data->charge[i] = charge[i];
59 }
60
61 real* Te_scaled = (real*) malloc( nrho*sizeof(real) );
62 real* Ti_scaled = (real*) malloc( nrho*sizeof(real) );
63 real* ne_scaled = (real*) malloc( nrho*sizeof(real) );
64 real* ni_scaled = (real*) malloc( nion*nrho*sizeof(real) );
65 for(int i=0; i < nrho; i++) {
66#if PLASMA_1DS_NONEG == PLASMA_1DS_LOG
67 Te_scaled[i] = log(Te[i]);
68 Ti_scaled[i] = log(Ti[i]);
69 ne_scaled[i] = log(ne[i]);
70 for(int j = 0; j < nion; j++) {
71 ni_scaled[j*nrho + i] = log(ni[j*nrho + i]);
72 }
73#elif PLASMA_1DS_NONEG == PLASMA_1DS_SQRT
74 Te_scaled[i] = sqrt(Te[i]);
75 Ti_scaled[i] = sqrt(Ti[i]);
76 ne_scaled[i] = sqrt(ne[i]);
77 for(int j = 0; j < nion; j++) {
78 ni_scaled[j*nrho + i] = sqrt(ni[j*nrho + i]);
79 }
80#endif
81 }
82 err = interp1Dcomp_setup(&data->temp[0], Te_scaled, nrho, NATURALBC,
83 rhomin, rhomax);
84 if(err) {
85 print_err("Error: Failed to initialize splines.\n");
86 free(Te_scaled);
87 free(Ti_scaled);
88 free(ne_scaled);
89 free(ni_scaled);
90 return 1;
91 }
92 err = interp1Dcomp_setup(&data->temp[1], Ti_scaled, nrho, NATURALBC,
93 rhomin, rhomax);
94 if(err) {
95 print_err("Error: Failed to initialize splines.\n");
96 free(Te_scaled);
97 free(Ti_scaled);
98 free(ne_scaled);
99 free(ni_scaled);
100 return 1;
101 }
102
103 data->dens = (interp1D_data*) malloc(data->n_species*sizeof(interp1D_data));
104 err = interp1Dcomp_setup(&data->dens[0], ne_scaled, nrho, NATURALBC,
105 rhomin, rhomax);
106 if(err) {
107 print_err("Error: Failed to initialize splines.\n");
108 free(Te_scaled);
109 free(Ti_scaled);
110 free(ne_scaled);
111 free(ni_scaled);
112 free(data->dens);
113 return 1;
114 }
115 for(int i = 0; i < nion; i++) {
116 err = interp1Dcomp_setup(&data->dens[i+1], &ni_scaled[i*nrho],
117 nrho, NATURALBC, rhomin, rhomax);
118 if(err) {
119 print_err("Error: Failed to initialize splines.\n");
120 free(Te_scaled);
121 free(Ti_scaled);
122 free(ne_scaled);
123 free(ni_scaled);
124 free(data->dens);
125 return 1;
126 }
127 }
128 free(Te_scaled);
129 free(Ti_scaled);
130 free(ne_scaled);
131 free(ni_scaled);
132
133 err = interp1Dcomp_setup(&data->vtor[0], vtor, nrho, NATURALBC,
134 rhomin, rhomax);
135
136 print_out(VERBOSE_IO, "\n1D plasma profiles (P_1DS)\n");
138 "Min rho = %1.2le, Max rho = %1.2le,"
139 " Number of rho grid points = %d,"
140 " Number of ion species = %d\n",
141 rhomin, rhomax, nrho, nion);
143 "Species Z/A charge [e]/mass [amu] Density [m^-3] at Min/Max rho"
144 " Temperature [eV] at Min/Max rho\n");
145 real T0, T1, n0, n1, vtor0, vtor1;
146 for(int i=0; i < nion; i++) {
147 plasma_1DS_eval_temp(&T0, rhomin, i+1, data);
148 plasma_1DS_eval_temp(&T1, rhomax, i+1, data);
149 plasma_1DS_eval_dens(&n0, rhomin, i+1, data);
150 plasma_1DS_eval_dens(&n1, rhomax, i+1, data);
152 " %3d /%3d %3d /%7.3f %1.2le/%1.2le "
153 " %1.2le/%1.2le \n",
154 data->znum[i], data->anum[i],
155 (int)round(data->charge[i+1]/CONST_E),
156 data->mass[i+1]/CONST_U,
157 n0, n1, T0 / CONST_E, T1 / CONST_E);
158 }
159
160 plasma_1DS_eval_temp(&T0, rhomin, 0, data);
161 plasma_1DS_eval_temp(&T1, rhomax, 0, data);
162 plasma_1DS_eval_dens(&n0, rhomin, 0, data);
163 plasma_1DS_eval_dens(&n1, rhomax, 0, data);
164 plasma_1DS_eval_flow(&vtor0, rhomin, 1.0/CONST_2PI, data);
165 plasma_1DS_eval_flow(&vtor1, rhomax, 1.0/CONST_2PI, data);
167 "[electrons] %3d /%7.3f %1.2le/%1.2le "
168 " %1.2le/%1.2le \n", -1, CONST_M_E/CONST_U,
169 n0, n1, T0 / CONST_E, T1 / CONST_E);
170 real quasineutrality = 0;
171 for(int k = 0; k < nrho; k++) {
172 real rho = rhomin + k * (rhomax - rhomin) / (nrho - 1);
173 real ele_qdens;
174 plasma_1DS_eval_dens(&ele_qdens, rho, 0, data);
175 real ion_qdens = 0;
176 for(int i=0; i < nion; i++) {
177 plasma_1DS_eval_dens(&n0, rho, i+1, data);
178 ion_qdens += n0;
179 }
180 quasineutrality = fmax( quasineutrality,
181 fabs( 1 - ion_qdens / ele_qdens ) );
182 }
183 print_out(VERBOSE_IO, "Quasi-neutrality is (electron / ion charge density)"
184 " %.2f\n", 1+quasineutrality);
185 print_out(VERBOSE_IO, "Toroidal rotation [rad/s] at Min/Max rho: "
186 "%1.2le/%1.2le\n", vtor0, vtor1);
187
188 return 0;
189}
190
197 free(data->mass);
198 free(data->charge);
199 free(data->anum);
200 free(data->znum);
201 for(int i = 0; i < data->n_species; i++) {
202 free(data->dens[i].c);
203 }
204 free(data->dens);
205}
206
213 GPU_MAP_TO_DEVICE(
214 data->mass[0:data->n_species], data->charge[0:data->n_species], \
215 data->anum[0:data->n_species-1], data->znum[0:data->n_species-1], \
216 data->vtor[0],\
217 data->temp[0:2], data->dens[0:data->n_species], \
218 data->temp[0].c[0:data->temp[0].n_x*NSIZE_COMP1D], \
219 data->temp[1].c[0:data->temp[1].n_x*NSIZE_COMP1D]
220 )
221 for (int i = 0; i < data->n_species; i++) {
222 GPU_MAP_TO_DEVICE( data->dens[i].c[0:data->dens[i].n_x*NSIZE_COMP1D] )
223 }
224}
225
236a5err plasma_1DS_eval_temp(real* temp, real rho, int species,
238 int interperr = 0;
239 interperr += interp1Dcomp_eval_f(temp, &plasma_data->temp[species>0], rho);
240
241 a5err err = 0;
242 if(interperr) {
244 }
245
246#if PLASMA_1DS_NONEG == PLASMA_1DS_LOG
247 *temp = exp(*temp);
248#elif PLASMA_1DS_NONEG == PLASMA_1DS_SQRT
249 *temp = (*temp) * (*temp);
250#endif
251 if(!err && *temp < 0){
253 }
254 return err;
255}
256
267a5err plasma_1DS_eval_dens(real* dens, real rho, int species,
269
270 int interperr = 0;
271 interperr += interp1Dcomp_eval_f(dens, &plasma_data->dens[species], rho);
272
273 a5err err = 0;
274 if(interperr) {
276 }
277
278#if PLASMA_1DS_NONEG == PLASMA_1DS_LOG
279 *dens = exp(*dens);
280#elif PLASMA_1DS_NONEG == PLASMA_1DS_SQRT
281 *dens = (*dens) * (*dens);
282#endif
283 if(!err && *dens < 0){
285 }
286 return err;
287}
288
304 int interperr = 0;
305
306 /* Evaluate electron temperature and density */
307 interperr += interp1Dcomp_eval_f(&temp[0], &plasma_data->temp[0], rho);
308 interperr += interp1Dcomp_eval_f(&dens[0], &plasma_data->dens[0], rho);
309
310 /* Evaluate ion temperature (same for all ions) and densities */
311 interperr += interp1Dcomp_eval_f(&temp[1], &plasma_data->temp[1], rho);
312 for(int i=1; i<plasma_data->n_species; i++) {
313 temp[i] = temp[1];
314 interperr += interp1Dcomp_eval_f(&dens[i], &plasma_data->dens[i], rho);
315 }
316
317 a5err err = 0;
318 if(interperr) {
320 }
321
322#if PLASMA_1DS_NONEG == PLASMA_1DS_LOG
323 for(int i=0; i<plasma_data->n_species; i++) {
324 dens[i] = exp(dens[i]);
325 temp[i] = exp(temp[i]);
326 }
327#elif PLASMA_1DS_NONEG == PLASMA_1DS_SQRT
328 for(int i=0; i<plasma_data->n_species; i++) {
329 dens[i] = dens[i]*dens[i];
330 temp[i] = temp[i]*temp[i];
331 }
332#endif
333 for(int i=0; i<plasma_data->n_species; i++) {
334 if(!err && (dens[i] < 0 || temp[i] < 0) ) {
335 err = error_raise( ERR_INPUT_EVALUATION, __LINE__,
337 }
338 }
339 return err;
340}
341
351 plasma_1DS_data* pls_data) {
352 a5err err = 0;
353 if(interp1Dcomp_eval_f(vflow, &pls_data->vtor[0], rho)) {
355 }
356 *vflow *= r;
357 return err;
358}
Main header file for ASCOT5.
double real
Definition ascot5.h:85
Header file containing physical and mathematical constants.
#define CONST_U
Atomic mass unit in kilograms [kg].
Definition consts.h:32
#define CONST_M_E
Electron mass [kg].
Definition consts.h:41
#define CONST_2PI
2*pi
Definition consts.h:14
#define CONST_E
Elementary charge [C].
Definition consts.h:35
Error module for ASCOT5.
unsigned long int a5err
Simulation error flag.
Definition error.h:17
@ EF_PLASMA_1DS
Definition error.h:41
@ 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.
@ 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.
Header file for math.c.
int plasma_1DS_init(plasma_1DS_data *data, int nrho, real rhomin, real rhomax, int nion, int *anum, int *znum, real *mass, real *charge, real *Te, real *Ti, real *ne, real *ni, real *vtor)
Initialize 1DS plasma data and check inputs.
Definition plasma_1DS.c:43
a5err plasma_1DS_eval_densandtemp(real *dens, real *temp, real rho, plasma_1DS_data *plasma_data)
Evaluate plasma density and temperature for all species.
Definition plasma_1DS.c:302
a5err plasma_1DS_eval_dens(real *dens, real rho, int species, plasma_1DS_data *plasma_data)
Evaluate plasma density.
Definition plasma_1DS.c:267
a5err plasma_1DS_eval_flow(real *vflow, real rho, real r, plasma_1DS_data *pls_data)
Evalate plasma flow along the field lines.
Definition plasma_1DS.c:350
void plasma_1DS_free(plasma_1DS_data *data)
Free allocated resources.
Definition plasma_1DS.c:196
a5err plasma_1DS_eval_temp(real *temp, real rho, int species, plasma_1DS_data *plasma_data)
Evaluate plasma temperature.
Definition plasma_1DS.c:236
void plasma_1DS_offload(plasma_1DS_data *data)
Offload data to the accelerator.
Definition plasma_1DS.c:212
Header file for plasma_1DS.c.
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
Cubic interpolation struct.
Definition interp.h:56
real * c
Definition interp.h:62
1D spline plasma parameters on the target
Definition plasma_1DS.h:15
interp1D_data * dens
Definition plasma_1DS.h:22
interp1D_data temp[2]
Definition plasma_1DS.h:21
interp1D_data vtor[0]
Definition plasma_1DS.h:23
Plasma simulation data.
Definition plasma.h:32