ASCOT5
Loading...
Searching...
No Matches
B_2DS.c
Go to the documentation of this file.
1
26#include <stdlib.h>
27#include <math.h>
28#include "../math.h"
29#include "../ascot5.h"
30#include "../error.h"
31#include "../print.h"
32#include "B_2DS.h"
33#include "../spline/interp.h"
34
56 int n_r, real r_min, real r_max,
57 int n_z, real z_min, real z_max,
59 real* psi, real* B_r, real* B_phi, real* B_z) {
60
61 int err = 0;
62 data->psi0 = psi0;
63 data->psi1 = psi1;
64 data->axis_r = axis_r;
65 data->axis_z = axis_z;
66
67 /* Set up the splines */
68 err = interp2Dcomp_setup(&data->psi, psi, n_r, n_z, NATURALBC, NATURALBC,
69 r_min, r_max, z_min, z_max);
70 if(err) {
71 print_err("Error: Failed to initialize splines.\n");
72 return 1;
73 }
74 err = interp2Dcomp_setup(&data->B_r, B_r, n_r, n_z, NATURALBC, NATURALBC,
75 r_min, r_max, z_min, z_max);
76 if(err) {
77 print_err("Error: Failed to initialize splines.\n");
78 return 1;
79 }
80 err = interp2Dcomp_setup(&data->B_phi, B_phi, n_r, n_z,
81 NATURALBC, NATURALBC, r_min, r_max, z_min, z_max);
82 if(err) {
83 print_err("Error: Failed to initialize splines.\n");
84 return 1;
85 }
86 err = interp2Dcomp_setup(&data->B_z, B_z, n_r, n_z, NATURALBC, NATURALBC,
87 r_min, r_max, z_min, z_max);
88 if(err) {
89 print_err("Error: Failed to initialize splines.\n");
90 return 1;
91 }
92
93 /* Evaluate psi and magnetic field on axis for checks */
94 real psival[1], Bval[3];
95 err = B_2DS_eval_psi(psival, data->axis_r, 0, data->axis_z, data);
96 err = B_2DS_eval_B(Bval, data->axis_r, 0, data->axis_z, data);
97 if(err) {
98 print_err("Error: Initialization failed.\n");
99 return err;
100 }
101
102 /* Print some sanity check on data */
104 "\n2D magnetic field (B_2DS)\n"
105 "Grid: nR = %4.d Rmin = %3.3f Rmax = %3.3f\n"
106 " nz = %4.d zmin = %3.3f zmax = %3.3f\n"
107 "Psi at magnetic axis (%1.3f m, %1.3f m)\n"
108 "%3.3f (evaluated)\n%3.3f (given)\n"
109 "Magnetic field on axis:\n"
110 "B_R = %3.3f B_phi = %3.3f B_z = %3.3f\n",
111 n_r, r_min, r_max,
112 n_z, z_min, z_max,
113 data->axis_r, data->axis_z,
114 psival[0], data->psi0,
115 Bval[0], Bval[1], Bval[2]);
116
117 return err;
118}
119
126 free(data->psi.c);
127 free(data->B_r.c);
128 free(data->B_phi.c);
129 free(data->B_z.c);
130}
131
138 GPU_MAP_TO_DEVICE(
139 data->psi, data->B_r, data->B_phi, data->B_z, \
140 data->psi.c[0:data->psi.n_x*data->psi.n_y*NSIZE_COMP2D], \
141 data->B_r.c[0:data->B_r.n_x*data->B_r.n_y*NSIZE_COMP2D], \
142 data->B_phi.c[0:data->B_phi.n_x *data->B_phi.n_y*NSIZE_COMP2D], \
143 data->B_z.c[0:data->B_z.n_x*data->B_z.n_y*NSIZE_COMP2D]
144 )
145}
146
158a5err B_2DS_eval_psi(real* psi, real r, real phi, real z, B_2DS_data* Bdata) {
159
160 int interperr = 0;
161 interperr += interp2Dcomp_eval_f(&psi[0], &Bdata->psi, r, z);
162
163 a5err err = 0;
164 if(interperr) {
165 err = error_raise( ERR_INPUT_EVALUATION, __LINE__, EF_B_2DS );
166 }
167 return err;
168}
169
182 B_2DS_data* Bdata) {
183
184 int interperr = 0;
185 real psi_dpsi_temp[6];
186
187 interperr += interp2Dcomp_eval_df(psi_dpsi_temp, &Bdata->psi, r, z);
188 psi_dpsi[0] = psi_dpsi_temp[0];
189 psi_dpsi[1] = psi_dpsi_temp[1];
190 psi_dpsi[2] = 0;
191 psi_dpsi[3] = psi_dpsi_temp[2];
192
193 a5err err = 0;
194 if(interperr) {
195 err = error_raise( ERR_INPUT_EVALUATION, __LINE__, EF_B_2DS );
196 }
197
198 return err;
199}
200
213 B_2DS_data* Bdata) {
214 int interperr = 0;
215 real psi_dpsi[6];
216
217 interperr += interp2Dcomp_eval_df(psi_dpsi, &Bdata->psi, r, z);
218
219 a5err err = 0;
220 if(interperr) {
221 err = error_raise( ERR_INPUT_EVALUATION, __LINE__, EF_B_2DS );
222 }
223
224 /* Check that the values seem valid */
225 real delta = Bdata->psi1 - Bdata->psi0;
226 if( !err && (psi_dpsi[0] - Bdata->psi0) / delta < 0 ) {
227 err = error_raise( ERR_INPUT_UNPHYSICAL, __LINE__, EF_B_2DS );
228 }
229
230 /* Normalize psi to get rho */
231 rho_drho[0] = sqrt((psi_dpsi[0] - Bdata->psi0) / delta);
232 rho_drho[1] = psi_dpsi[1] / (2*delta*rho_drho[0]);
233 rho_drho[2] = 0;
234 rho_drho[3] = psi_dpsi[2] / (2*delta*rho_drho[0]);
235
236 return err;
237}
238
250a5err B_2DS_eval_B(real B[3], real r, real phi, real z, B_2DS_data* Bdata) {
251 a5err err = 0;
252 int interperr = 0;
253
254 interperr += interp2Dcomp_eval_f(&B[0], &Bdata->B_r, r, z);
255 interperr += interp2Dcomp_eval_f(&B[1], &Bdata->B_phi, r, z);
256 interperr += interp2Dcomp_eval_f(&B[2], &Bdata->B_z, r, z);
257
258 /* Test for B field interpolation error */
259 if(interperr) {
260 err = error_raise( ERR_INPUT_EVALUATION, __LINE__, EF_B_2DS );
261 }
262
263 if(!err) {
264 real psi_dpsi[6];
265 interperr += interp2Dcomp_eval_df(psi_dpsi, &Bdata->psi, r, z);
266 B[0] = B[0] - psi_dpsi[2]/r;
267 B[2] = B[2] + psi_dpsi[1]/r;
268
269 /* Test for psi interpolation error */
270 if(interperr) {
271 err = error_raise( ERR_INPUT_EVALUATION, __LINE__, EF_B_2DS );
272 }
273 }
274
275 /* Check that magnetic field seems valid */
276 int check = 0;
277 check += ((B[0]*B[0] + B[1]*B[1] + B[2]*B[2]) == 0);
278 if(!err && check) {
279 err = error_raise( ERR_INPUT_UNPHYSICAL, __LINE__, EF_B_2DS );
280 }
281
282 return err;
283}
284
297 B_2DS_data* Bdata) {
298 a5err err = 0;
299 int interperr = 0;
300 real B_dB_temp[6];
301
302 interperr += interp2Dcomp_eval_df(B_dB_temp, &Bdata->B_r, r, z);
303
304 B_dB[0] = B_dB_temp[0];
305 B_dB[1] = B_dB_temp[1];
306 B_dB[2] = 0;
307 B_dB[3] = B_dB_temp[2];
308
309 interperr += interp2Dcomp_eval_df(B_dB_temp, &Bdata->B_phi, r, z);
310
311 B_dB[4] = B_dB_temp[0];
312 B_dB[5] = B_dB_temp[1];
313 B_dB[6] = 0;
314 B_dB[7] = B_dB_temp[2];
315
316 interperr += interp2Dcomp_eval_df(B_dB_temp, &Bdata->B_z, r, z);
317
318 B_dB[8] = B_dB_temp[0];
319 B_dB[9] = B_dB_temp[1];
320 B_dB[10] = 0;
321 B_dB[11] = B_dB_temp[2];
322
323 /* Test for B field interpolation error */
324 if(interperr) {
325 err = error_raise( ERR_INPUT_EVALUATION, __LINE__, EF_B_2DS );
326 }
327
328
329 real psi_dpsi[6];
330
331 if(!err) {
332 interperr += interp2Dcomp_eval_df(psi_dpsi, &Bdata->psi, r, z);
333
334 B_dB[0] = B_dB[0] - psi_dpsi[2]/r;
335 B_dB[1] = B_dB[1] + psi_dpsi[2]/(r*r)-psi_dpsi[5]/r;
336 B_dB[3] = B_dB[3] - psi_dpsi[4]/r;
337 B_dB[8] = B_dB[8] + psi_dpsi[1]/r;
338 B_dB[9] = B_dB[9] - psi_dpsi[1]/(r*r) + psi_dpsi[3]/r;
339 B_dB[11] = B_dB[11] + psi_dpsi[5]/r;
340
341 /* Test for psi interpolation error */
342 if(interperr) {
343 err = error_raise( ERR_INPUT_EVALUATION, __LINE__, EF_B_2DS );
344 }
345 }
346
347 /* Check that magnetic field seems valid */
348 int check = 0;
349 check += ((B_dB[0]*B_dB[0] + B_dB[4]*B_dB[4] + B_dB[8]*B_dB[8]) == 0);
350 if(!err && check) {
351 err = error_raise( ERR_INPUT_UNPHYSICAL, __LINE__, EF_B_2DS );
352 }
353
354 return err;
355}
356
366 a5err err = 0;
367 rz[0] = Bdata->axis_r;
368 rz[1] = Bdata->axis_z;
369 return err;
370}
a5err B_2DS_eval_psi(real *psi, real r, real phi, real z, B_2DS_data *Bdata)
Evaluate poloidal flux psi.
Definition B_2DS.c:158
int B_2DS_init(B_2DS_data *data, int n_r, real r_min, real r_max, int n_z, real z_min, real z_max, real axis_r, real axis_z, real psi0, real psi1, real *psi, real *B_r, real *B_phi, real *B_z)
Initialize magnetic field data.
Definition B_2DS.c:55
a5err B_2DS_eval_psi_dpsi(real psi_dpsi[4], real r, real phi, real z, B_2DS_data *Bdata)
Evaluate poloidal flux psi and its derivatives.
Definition B_2DS.c:181
a5err B_2DS_eval_rho_drho(real rho_drho[4], real r, real phi, real z, B_2DS_data *Bdata)
Evaluate normalized poloidal flux rho and its derivatives.
Definition B_2DS.c:212
a5err B_2DS_eval_B(real B[3], real r, real phi, real z, B_2DS_data *Bdata)
Evaluate magnetic field.
Definition B_2DS.c:250
void B_2DS_offload(B_2DS_data *data)
Offload data to the accelerator.
Definition B_2DS.c:137
void B_2DS_free(B_2DS_data *data)
Free allocated resources.
Definition B_2DS.c:125
a5err B_2DS_get_axis_rz(real rz[2], B_2DS_data *Bdata)
Return magnetic axis R-coordinate.
Definition B_2DS.c:365
a5err B_2DS_eval_B_dB(real B_dB[12], real r, real phi, real z, B_2DS_data *Bdata)
Evaluate magnetic field and its derivatives.
Definition B_2DS.c:296
Header file for B_2DS.c.
real axis_r
Definition B_3DS.c:61
real axis_z
Definition B_3DS.c:62
real psi0
Definition B_3DS.c:59
real psi1
Definition B_3DS.c:60
Main header file for ASCOT5.
double real
Definition ascot5.h:85
Error module for ASCOT5.
unsigned long int a5err
Simulation error flag.
Definition error.h:17
@ EF_B_2DS
Definition error.h:37
@ ERR_INPUT_EVALUATION
Definition error.h:63
@ ERR_INPUT_UNPHYSICAL
Definition error.h:65
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.
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
DECLARE_TARGET_END a5err interp2Dcomp_eval_df(real *f_df, interp2D_data *str, real x, real y)
Evaluate interpolated value and 1st and 2nd derivatives of 2D field.
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.
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
2D magnetic field parameters
Definition B_2DS.h:17
interp2D_data psi
Definition B_2DS.h:22
real psi1
Definition B_2DS.h:19
interp2D_data B_phi
Definition B_2DS.h:24
interp2D_data B_z
Definition B_2DS.h:25
interp2D_data B_r
Definition B_2DS.h:23
real psi0
Definition B_2DS.h:18
real axis_z
Definition B_2DS.h:21
real axis_r
Definition B_2DS.h:20
real * c
Definition interp.h:79