ASCOT5
Loading...
Searching...
No Matches
rfof.c
1
6#include <stdio.h>
7#include <string.h>
8#include <math.h>
9#include <stdlib.h>
10#include "physlib.h"
11#include "consts.h"
12#include "particle.h"
13#include "rfof.h"
14
18typedef struct rfof_output {
19 double dmu;
20 double dvpar;
22 double de;
23 double deCumulative;
25 double dpitch;
26 double maxAcc;
27 double RFdt;
29
30#ifdef RFOF
31void __ascot5_icrh_routines_MOD_call_initev_excl_marker_stuff(
32 const char* xml_filename, int **xml_filename_len, void** cptr_rfglobal,
33 void** cptr_rfof_input_params);
34void __ascot5_icrh_routines_MOD_call_initialise_res_mem(void** cptr_mem,
35 int* cptr_mem_shape_i, int* cptr_mem_shape_j, void** cptr_rfglobal,
36 void** cptr_rfof_input_param);
37void __ascot5_icrh_routines_MOD_call_initialise_diagnostics(
38 void** cptr_RFglobal, void** cptr_diagno);
39
40void __ascot5_icrh_routines_MOD_call_set_marker_pointers(void** cptr_marker,
41 int** id, real** weight, real** R, real** phi, real** z, real** psi,
42 real** charge, real** mass, real** Ekin, real** velocity, real** mu,
43 real** pphicanonical, real** vpar, real** vperp, real** gyrof, real** tauB,
44 real** vdriftRho, real** acc, int* isOrbitTimeAccelerated,
45 int* is_already_allocated);
46
47void __ascot5_icrh_routines_MOD_call_rf_kick(double*time, double*dtin,
48 int* mpi_rank, void** cptr_marker, void** cptr_mem, void** cptr_rfglobal,
49 void** cptr_rfdiagno, void** cptr_rfof_input, int* mem_shape_i,
50 int* mem_shape_j, int *err, rfof_output* out);
51
52void __ascot5_icrh_routines_MOD_call_reset_res_mem(void** rfof_mem_pointer,
53 int* mem_shape_i, int* mem_shape_j);
54
55void __ascot5_icrh_routines_MOD_call_deallocate_rfof_input_param(
56 void** cptr_rfof_input_param);
57void __ascot5_icrh_routines_MOD_call_deallocate_rfglobal(void** cptr_rfglobal);
58void __ascot5_icrh_routines_MOD_call_deallocate_res_mem(void** cptr_res_mem,
59 int* cptr_mem_shape_i, int* cptr_mem_shape_j);
60void __ascot5_icrh_routines_MOD_call_deallocate_diagnostics(void** cptr_diagno);
61void __ascot5_icrh_routines_MOD_deallocate_marker(void** cptr_rfof_marker);
62
63void __ascot5_icrh_routines_MOD_get_rf_wave_local_v2(real* R, real* z,
64 real* rho_tor, real* theta, void** cptr_rfglobal, real* e_plus_real,
65 real* e_minus_real, real* e_plus_imag, real* e_minus_imag);
66
67void __ascot5_icrh_routines_MOD_eval_resonance_function(void** cptr_marker,
68 void** cptr_rfglobal, real* omega_res, int* nharm);
69
70void __ascot5_icrh_routines_MOD_print_marker_stuff(void** marker_pointer);
71
72void __ascot5_icrh_routines_MOD_print_mem_stuff(void** mem_pointer);
73#endif
74
83void rfof_init(rfof_data* rfof_data) {
84#ifdef RFOF
85 const char xml_filename[128] = RFOF_CODEPARAM_XML;
86 int xml_filename_len = strlen(xml_filename);
87 int*xml_filename_len_ptr = &xml_filename_len;
88 __ascot5_icrh_routines_MOD_call_initev_excl_marker_stuff(xml_filename,
89 &xml_filename_len_ptr, &(rfof_data->rfglobal),
91#endif
92}
93
100void rfof_free(rfof_data* rfof) {
101#ifdef RFOF
102 __ascot5_icrh_routines_MOD_call_deallocate_rfof_input_param(
103 &rfof->rfof_input_params);
104 __ascot5_icrh_routines_MOD_call_deallocate_rfglobal(&rfof->rfglobal);
105#endif
106}
107
116void rfof_set_up(rfof_marker* rfof_mrk, rfof_data* rfof) {
117#ifdef RFOF
118 for(int i=0; i< NSIMD; i++) {
119 /* Initialize marker data with dummy values */
120 real dummy = -999.0, *ptr = &dummy; /* -999.0 should be used for real
121 dummy when dealing with RFOF */
122 int dummyint = 0, *iptr = &dummyint; /* -999 should be used for int
123 dummy with RFOF but in this
124 case it is irrelevant as iptr
125 only goes to RFOF marker id */
126 int is_accelerated = 0;
127 int is_already_allocated = 0;
128 __ascot5_icrh_routines_MOD_call_set_marker_pointers(
129 &(rfof_mrk->p[i]), &iptr, &ptr, &ptr, &ptr, &ptr, &ptr, &ptr, &ptr,
130 &ptr, &ptr, &ptr, &ptr, &ptr, &ptr, &ptr, &ptr, &ptr, &ptr,
131 &is_accelerated, &is_already_allocated);
132
133 /* Initialize resonance history */
134 __ascot5_icrh_routines_MOD_call_initialise_res_mem(
135 &rfof_mrk->history_array[i], &rfof_mrk->nrow[i],
136 &rfof_mrk->ncol[i], &rfof->rfglobal,
137 &rfof->rfof_input_params);
138
139 /* Initialize diagnostics */
140 __ascot5_icrh_routines_MOD_call_initialise_diagnostics(
141 &rfof->rfglobal, &(rfof_mrk->diag_array[i]));
142 }
143#endif
144}
145
153void rfof_tear_down(rfof_marker* rfof_mrk) {
154#ifdef RFOF
155 for(int i=0; i< NSIMD; i++) {
156 __ascot5_icrh_routines_MOD_call_deallocate_res_mem(
157 &rfof_mrk->history_array[i], &rfof_mrk->nrow[i],
158 &rfof_mrk->ncol[i]);
159 __ascot5_icrh_routines_MOD_call_deallocate_diagnostics(
160 &rfof_mrk->diag_array[i]);
161 __ascot5_icrh_routines_MOD_deallocate_marker(&rfof_mrk->p[i]);
162 }
163#endif
164}
165
177void rfof_clear_history(rfof_marker* rfof_mrk, int i) {
178#ifdef RFOF
179 __ascot5_icrh_routines_MOD_call_reset_res_mem(
180 &rfof_mrk->history_array[i], &rfof_mrk->nrow[i], &rfof_mrk->ncol[i]);
181#endif
182}
183
206void rfof_resonance_check_and_kick_gc(
207 particle_simd_gc* p, real* hin, real* hout, rfof_marker* rfof_mrk,
209#ifdef RFOF
210 for(int i=0; i<NSIMD; i++) {
211 if(p->id[i] > 0 && p->running[i]) {
212 /* Evaluate derived quantities needed by librfof */
213 /* NOTE: It is possible that the use of (multiple) physlib
214 functions to evalutate some quantity introduces some error which,
215 at least when cumulated, grows intolerable. */
216 real psi, B, Ekin, vnorm, P_phi, v_par, v_perp, gyrof,
217 tauB;
218 B_field_eval_psi(&psi, p->r[i], p->phi[i], p->z[i], p->time[i],
219 Bdata);
220 psi *= CONST_2PI; // librfof is COCOS 13
221 B = math_normc(p->B_r[i], p->B_phi[i], p->B_z[i]);
222 v_par = p->ppar[i]/p->mass[i];
223 Ekin = p->ppar[i]*p->ppar[i]/(2*p->mass[i]) + p->mu[i]*B;
224 vnorm = sqrt( (p->ppar[i]/p->mass[i])*(p->ppar[i]/p->mass[i]) + 2*p->mu[i]*B/p->mass[i] );
225 v_perp = sqrt( 2 * p->mu[i]*B/p->mass[i] );
226
227 P_phi = phys_ptoroid_gc(p->charge[i], p->r[i], p->ppar[i], psi, B,
228 p->B_phi[i]);
229 gyrof = phys_gyrofreq_ppar(p->mass[i], p->charge[i], p->mu[i],
230 p->ppar[i], B);
231 real q_safe = 1.0;
232 real majR = 1.65; // For now AUG
233 real minR = 0.6; // AUG
234 tauB = CONST_2PI*q_safe*p->r[i]/fabs(v_par)*sqrt(2*majR/minR);
235 real vdriftRho = 0; // Assuming this is not needed in librfof
236 real acceleration = 1.0;
237 int is_accelerated = 0;
238 int is_preallocated = 1;
239
240 int dummy_id = 1;
241 int* dummy_Id_ptr = &dummy_id;
242
243 real* weight_ptr = &(p->weight[i]);
244 real* r_ptr = &(p->r[i]);
245 real* phi_ptr = &(p->phi[i]);
246 real* z_ptr = &(p->z[i]);
247 real* charge_ptr = &(p->charge[i]);
248 real* mass_ptr = &(p->mass[i]);
249 real* mu_ptr = &(p->mu[i]);
250 real* Ekin_ptr = &Ekin;
251 real* psi_ptr = &psi;
252 real* speed_ptr = &vnorm;
253 real* P_phi_ptr = &P_phi;
254 real* v_par_ptr = &v_par;
255 real* v_perp_ptr = &v_perp;
256 real* gyrof_ptr = &gyrof;
257 real* tauB_ptr = &tauB;
258 real* vdriftRho_ptr = &vdriftRho;
259 real* acc_ptr = &acceleration;
260
261 /* Update the fields of RFOF marker */
262 __ascot5_icrh_routines_MOD_call_set_marker_pointers(
263 &(rfof_mrk->p[i]),
264 &(dummy_Id_ptr),
265 &(weight_ptr),
266 &(r_ptr),
267 &(phi_ptr),
268 &(z_ptr),
269 &(psi_ptr),
270 &(charge_ptr),
271 &(mass_ptr),
272 &(Ekin_ptr),
273 &(speed_ptr),
274 &(mu_ptr),
275 &(P_phi_ptr),
276 &(v_par_ptr),
277 &(v_perp_ptr),
278 &(gyrof_ptr),
279 &(tauB_ptr),
280 &(vdriftRho_ptr),
281 &(acc_ptr),
282 &is_accelerated,
283 &is_preallocated);
284
285 /* Contains the change in physical quantities and the suggested
286 * time-step after the kick */
287 rfof_output rfof_data_pack = {
288 .dmu = 0.0,
289 .dvpar = 0.0,
290 .de = 0.0,
291 .deCumulative = 0.0,
292 .dpitch = 0.0,
293 .maxAcc = 0.0,
294 .RFdt = 0.0,
295 };
296
297 int err = 0;
298 int mpi_rank = 0; // RFOF does not work with MPI yet
299
300
301 /* Ready to kick some ash (if in resonance) */
302 __ascot5_icrh_routines_MOD_call_rf_kick(
303 &(p->time[i]), &(hin[i]), &mpi_rank,
304 &(rfof_mrk->p[i]), &(rfof_mrk->history_array[i]),
305 &(rfof_data->rfglobal), &(rfof_mrk->diag_array[i]),
306 &(rfof_data->rfof_input_params), &(rfof_mrk->nrow[i]),
307 &(rfof_mrk->ncol[i]), &err, &rfof_data_pack);
308
309 /* Most marker phase-space coordinates are updated automatically
310 * via the pointers in rfof_mrk except ppar which we update here */
311 p->ppar[i] = p->ppar[i] + p->mass[i]*(rfof_data_pack.dvpar);
312
313
314 if (err == 7) {
315 /* Overshot the resonance. Mark the suggested time-step as
316 * negative to inform ASCOT to retry the time step */
317 hout[i] = -rfof_data_pack.RFdt;
318 } else {
319 /* Interaction was successful. The suggested time-step is
320 * a guess how long till the marker enters the resonance */
321 hout[i] = rfof_data_pack.RFdt;
322 }
323 }
324 }
325#endif
326}
327
357void rfof_set_marker_manually(rfof_marker* rfof_mrk, int* id,
358 real* weight, real* R, real* phi, real* z, real* psi, real* charge,
359 real* mass, real* Ekin, real* vnorm, real* mu, real* Pphi,
360 real* vpar, real* vperp, real* gyrof, real* vdriftRho, real* acc,
361 int* is_accelerated, int* is_already_allocated) {
362#ifdef RFOF
363 // TODO: Check if this is needed and implement properly.
364 real bigR = 2.0;
365 real tauB_target = CONST_2PI*(*charge)*(bigR)/(*vpar);
366 real* tauB = &tauB_target;
367 __ascot5_icrh_routines_MOD_call_set_marker_pointers(
368 &rfof_mrk->p[0], &id, &weight, &R, &phi, &z, &psi, &charge, &mass,
369 &Ekin, &vnorm, &mu, &Pphi, &vpar, &vperp, &gyrof, &tauB, &vdriftRho, &acc,
370 is_accelerated, is_already_allocated);
371#endif
372}
373
392void rfof_eval_rf_wave(
393 real* e_plus_real, real* e_minus_real, real* e_plus_imag,
394 real* e_minus_imag, real R, real z, rfof_data* rfof) {
395#ifdef RFOF
396 /* The current implementation assumes that the ICRH wave field is given in
397 R,z co-ordinates. It would be possible to give it in rho_tor,theta as
398 well. Information about the choice of co-ordinates is saved in the
399 rfglobal fortran struct in the fields rfglobal%coord_name_x1 and
400 rfglobal_coord_name_x2. */
401 real rho_tor = -999.0; //currently dummy (-999.0 is standard dummy in RFOF)
402 real theta = -999.0; //currently dummy
403 __ascot5_icrh_routines_MOD_get_rf_wave_local_v2(
404 &R, &z, &rho_tor, &theta, &rfof->rfglobal, e_plus_real, e_minus_real,
405 e_plus_imag, e_minus_imag);
406#endif
407}
408
423void rfof_eval_resonance_function(
424 real* omega_res, int* nharm, rfof_marker* rfof_mrk, rfof_data* rfof) {
425#ifdef RFOF
426 __ascot5_icrh_routines_MOD_eval_resonance_function(
427 &rfof_mrk->p[0], &rfof->rfglobal, omega_res, nharm);
428#endif
429}
a5err B_field_eval_psi(real *psi, real r, real phi, real z, real t, B_field_data *Bdata)
Evaluate poloidal flux psi.
Definition B_field.c:102
double real
Definition ascot5.h:85
#define NSIMD
Number of particles simulated simultaneously in a particle group operations.
Definition ascot5.h:91
#define RFOF_CODEPARAM_XML
Input filename where RFOF parameters are stored.
Definition ascot5.h:137
Header file containing physical and mathematical constants.
#define CONST_2PI
2*pi
Definition consts.h:14
@ R
Definition hist.h:18
Header file for math.c.
#define math_normc(a1, a2, a3)
Calculate norm of 3D vector from its components a1, a2, a3.
Definition math.h:70
Header file for particle.c.
Methods to evaluate elementary physical quantities.
#define phys_ptoroid_gc(q, R, ppar, psi, B, Bphi)
Evaluate toroidal canonical momentum for particle.
Definition physlib.h:314
#define phys_gyrofreq_ppar(m, q, mu, ppar, B)
Evaluate gyrofrequency [rad/s] from parallel momentum and magnetic moment.
Definition physlib.h:278
Contains the functions to be called from the simulation loop when using ICRH.
Magnetic field simulation data.
Definition B_field.h:41
Struct representing NSIMD guiding center markers.
Definition particle.h:275
RFOF simulation input data.
Definition rfof.h:35
void * rfof_input_params
Definition rfof.h:36
void * rfglobal
Definition rfof.h:38
Reusable struct for storing marker specific data during the simulation loop.
Definition rfof.h:19
void * diag_array[NSIMD]
Definition rfof.h:23
void * p[NSIMD]
Definition rfof.h:20
void * history_array[NSIMD]
Definition rfof.h:21
int nrow[NSIMD]
Definition rfof.h:25
int ncol[NSIMD]
Definition rfof.h:26
double deCumulative
Definition rfof.c:23
double dvpar
Definition rfof.c:20
double maxAcc
Definition rfof.c:26
double RFdt
Definition rfof.c:27
double de
Definition rfof.c:22
double dpitch
Definition rfof.c:25
double dmu
Definition rfof.c:19