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) {
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 print_out(VERBOSE_IO, "\n1D plasma profiles (P_1DS)\n");
135 "Min rho = %1.2le, Max rho = %1.2le,"
136 " Number of rho grid points = %d,"
137 " Number of ion species = %d\n",
138 rhomin, rhomax, nrho, nion);
140 "Species Z/A charge [e]/mass [amu] Density [m^-3] at Min/Max rho"
141 " Temperature [eV] at Min/Max rho\n");
142 real T0, T1, n0, n1;
143 for(int i=0; i < nion; i++) {
144 plasma_1DS_eval_temp(&T0, rhomin, i+1, data);
145 plasma_1DS_eval_temp(&T1, rhomax, i+1, data);
146 plasma_1DS_eval_dens(&n0, rhomin, i+1, data);
147 plasma_1DS_eval_dens(&n1, rhomax, i+1, data);
149 " %3d /%3d %3d /%7.3f %1.2le/%1.2le "
150 " %1.2le/%1.2le \n",
151 data->znum[i], data->anum[i],
152 (int)round(data->charge[i+1]/CONST_E),
153 data->mass[i+1]/CONST_U,
154 n0, n1, T0 / CONST_E, T1 / CONST_E);
155 }
156
157 plasma_1DS_eval_temp(&T0, rhomin, 0, data);
158 plasma_1DS_eval_temp(&T1, rhomax, 0, data);
159 plasma_1DS_eval_dens(&n0, rhomin, 0, data);
160 plasma_1DS_eval_dens(&n1, rhomax, 0, data);
162 "[electrons] %3d /%7.3f %1.2le/%1.2le "
163 " %1.2le/%1.2le \n", -1, CONST_M_E/CONST_U,
164 n0, n1, T0 / CONST_E, T1 / CONST_E);
165 real quasineutrality = 0;
166 for(int k = 0; k < nrho; k++) {
167 real rho = rhomin + k * (rhomax - rhomin) / (nrho - 1);
168 real ele_qdens;
169 plasma_1DS_eval_dens(&ele_qdens, rho, 0, data);
170 real ion_qdens = 0;
171 for(int i=0; i < nion; i++) {
172 plasma_1DS_eval_dens(&n0, rho, i+1, data);
173 ion_qdens += n0;
174 }
175 quasineutrality = fmax( quasineutrality,
176 fabs( 1 - ion_qdens / ele_qdens ) );
177 }
178 print_out(VERBOSE_IO, "Quasi-neutrality is (electron / ion charge density)"
179 " %.2f\n", 1+quasineutrality);
180
181 return 0;
182}
183
190 free(data->mass);
191 free(data->charge);
192 free(data->anum);
193 free(data->znum);
194 for(int i = 0; i < data->n_species; i++) {
195 free(data->dens[i].c);
196 }
197 free(data->dens);
198}
199
206 GPU_MAP_TO_DEVICE(
207 data->mass[0:data->n_species], data->charge[0:data->n_species], \
208 data->anum[0:data->n_species-1], data->znum[0:data->n_species-1], \
209 data->temp[0:2], data->dens[0:data->n_species], \
210 data->temp[0].c[0:data->temp[0].n_x*NSIZE_COMP1D], \
211 data->temp[1].c[0:data->temp[1].n_x*NSIZE_COMP1D]
212 )
213 for (int i = 0; i < data->n_species; i++) {
214 GPU_MAP_TO_DEVICE( data->dens[i].c[0:data->dens[i].n_x*NSIZE_COMP1D] )
215 }
216}
217
228a5err plasma_1DS_eval_temp(real* temp, real rho, int species,
230 int interperr = 0;
231 interperr += interp1Dcomp_eval_f(temp, &plasma_data->temp[species>0], rho);
232
233 a5err err = 0;
234 if(interperr) {
236 }
237
238#if PLASMA_1DS_NONEG == PLASMA_1DS_LOG
239 *temp = exp(*temp);
240#elif PLASMA_1DS_NONEG == PLASMA_1DS_SQRT
241 *temp = (*temp) * (*temp);
242#endif
243 if(!err && *temp < 0){
245 }
246 return err;
247}
248
259a5err plasma_1DS_eval_dens(real* dens, real rho, int species,
261
262 int interperr = 0;
263 interperr += interp1Dcomp_eval_f(dens, &plasma_data->dens[species], rho);
264
265 a5err err = 0;
266 if(interperr) {
268 }
269
270#if PLASMA_1DS_NONEG == PLASMA_1DS_LOG
271 *dens = exp(*dens);
272#elif PLASMA_1DS_NONEG == PLASMA_1DS_SQRT
273 *dens = (*dens) * (*dens);
274#endif
275 if(!err && *dens < 0){
277 }
278 return err;
279}
280
296 int interperr = 0;
297
298 /* Evaluate electron temperature and density */
299 interperr += interp1Dcomp_eval_f(&temp[0], &plasma_data->temp[0], rho);
300 interperr += interp1Dcomp_eval_f(&dens[0], &plasma_data->dens[0], rho);
301
302 /* Evaluate ion temperature (same for all ions) and densities */
303 interperr += interp1Dcomp_eval_f(&temp[1], &plasma_data->temp[1], rho);
304 for(int i=1; i<plasma_data->n_species; i++) {
305 temp[i] = temp[1];
306 interperr += interp1Dcomp_eval_f(&dens[i], &plasma_data->dens[i], rho);
307 }
308
309 a5err err = 0;
310 if(interperr) {
312 }
313
314#if PLASMA_1DS_NONEG == PLASMA_1DS_LOG
315 for(int i=0; i<plasma_data->n_species; i++) {
316 dens[i] = exp(dens[i]);
317 temp[i] = exp(temp[i]);
318 }
319#elif PLASMA_1DS_NONEG == PLASMA_1DS_SQRT
320 for(int i=0; i<plasma_data->n_species; i++) {
321 dens[i] = dens[i]*dens[i];
322 temp[i] = temp[i]*temp[i];
323 }
324#endif
325 for(int i=0; i<plasma_data->n_species; i++) {
326 if(!err && (dens[i] < 0 || temp[i] < 0) ) {
327 err = error_raise( ERR_INPUT_EVALUATION, __LINE__,
329 }
330 }
331 return err;
332}
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:29
#define CONST_M_E
Electron mass [kg]
Definition consts.h:38
#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_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.
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:294
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)
Initialize 1DS plasma data and check inputs.
Definition plasma_1DS.c:43
a5err plasma_1DS_eval_dens(real *dens, real rho, int species, plasma_1DS_data *plasma_data)
Evaluate plasma density.
Definition plasma_1DS.c:259
void plasma_1DS_free(plasma_1DS_data *data)
Free allocated resources.
Definition plasma_1DS.c:189
a5err plasma_1DS_eval_temp(real *temp, real rho, int species, plasma_1DS_data *plasma_data)
Evaluate plasma temperature.
Definition plasma_1DS.c:228
void plasma_1DS_offload(plasma_1DS_data *data)
Offload data to the accelerator.
Definition plasma_1DS.c:205
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
Plasma simulation data.
Definition plasma.h:32