ASCOT5
Loading...
Searching...
No Matches
simulate_gc_fixed.c
Go to the documentation of this file.
1
5#include <stdio.h>
6#include <stdlib.h>
7#include <omp.h>
8#include <math.h>
9#include "../ascot5.h"
10#include "../endcond.h"
11#include "../math.h"
12#include "../consts.h"
13#include "../physlib.h"
14#include "../simulate.h"
15#include "../particle.h"
16#include "../wall.h"
17#include "../diag.h"
18#include "../B_field.h"
19#include "../E_field.h"
20#include "../rfof.h"
21#include "../plasma.h"
22#include "simulate_gc_fixed.h"
23#include "step/step_gc_rk4.h"
24#include "mccc/mccc.h"
25
26DECLARE_TARGET_SIMD_UNIFORM(sim)
28
29#define DUMMY_TIMESTEP_VAL 1.0
30
50 int cycle[NSIMD] __memalign__; /* Flag indigating whether a new marker
51 was initialized */
52 real hin[NSIMD] __memalign__; /* Time step given as an input into the
53 integrators. Almost always default.*/
54 real hin_default[NSIMD] __memalign__; /* The default fixed time step. */
55 real hnext_recom[NSIMD] __memalign__; /* Next time step, only used to
56 store the value when RFOF has
57 rejected a time step. */
58 real hout_rfof[NSIMD] __memalign__; /* The time step that RFOF recommends.
59 Small positive means that resonance
60 is close, small negative means that
61 the step failed because the marker
62 overshot the resonance and that the
63 time step should be retaken with a
64 smaller time step given by the
65 negative of hout_rfof */
66
67
68 real cputime, cputime_last; // Global cpu time: recent and previous record
69
70 particle_simd_gc p; // This array holds current states
71 particle_simd_gc p0; // This array stores previous states
72
73 rfof_marker rfof_mrk; // RFOF specific data
74
75 /* Init dummy markers */
76 for(int i=0; i< NSIMD; i++) {
77 p.id[i] = -1;
78 p.running[i] = 0;
79 hout_rfof[i] = DUMMY_TIMESTEP_VAL;
80 hnext_recom[i] = DUMMY_TIMESTEP_VAL;
81 }
82
83 /* Initialize running particles */
84 int n_running = particle_cycle_gc(pq, &p, &sim->B_data, cycle);
85
86 if(sim->enable_icrh) {
87 rfof_set_up(&rfof_mrk, &sim->rfof_data);
88 }
89
90 /* Determine simulation time-step */
91 #pragma omp simd
92 for(int i = 0; i < NSIMD; i++) {
93 if(cycle[i] > 0) {
94 hin_default[i] = simulate_gc_fixed_inidt(sim, &p, i);
95 hin[i] = hin_default[i];
96 }
97 }
98
99 cputime_last = A5_WTIME;
100
101 /* MAIN SIMULATION LOOP
102 * - Store current state
103 * - Integrate motion due to background EM-field (orbit-following)
104 * - Integrate scattering due to Coulomb collisions
105 * - Perform ICRH kick with RFOF if in wave-particle resonance
106 * - Advance time
107 * - Check for end condition(s)
108 * - Update diagnostics
109 */
110 while(n_running > 0) {
111
112 /* Store marker states */
113 #pragma omp simd
114 for(int i = 0; i < NSIMD; i++) {
115 particle_copy_gc(&p, i, &p0, i);
116 }
117
118 /*************************** Physics **********************************/
119
120 /* Set time-step negative if tracing backwards in time */
121 #pragma omp simd
122 for(int i = 0; i < NSIMD; i++) {
123 if(sim->reverse_time) {
124 hin[i] = -hin[i];
125 }
126 }
127
128 /* RK4 method for orbit-following */
129 if(sim->enable_orbfol) {
130 if(sim->enable_mhd) {
132 &p, hin, &sim->B_data, &sim->E_data, &sim->boozer_data,
133 &sim->mhd_data, sim->enable_aldforce);
134 }
135 else {
136 step_gc_rk4(&p, hin, &sim->B_data, &sim->E_data,
137 sim->enable_aldforce);
138 }
139 }
140
141 /* Switch sign of the time-step again if it was reverted earlier */
142 #pragma omp simd
143 for(int i = 0; i < NSIMD; i++) {
144 if(sim->reverse_time) {
145 hin[i] = -hin[i];
146 }
147 }
148
149 /* Euler-Maruyama method for collisions */
150 if(sim->enable_clmbcol) {
151 real rnd[5*NSIMD];
152 random_normal_simd(&sim->random_data, 5*NSIMD, rnd);
153 mccc_gc_euler(&p, hin, &sim->B_data, &sim->plasma_data,
154 &sim->mccc_data, rnd);
155 }
156
157 /* Performs the ICRH kick if in resonance. */
158 if(sim->enable_icrh) {
159 rfof_resonance_check_and_kick_gc(
160 &p, hin, hout_rfof, &rfof_mrk, &sim->rfof_data, &sim->B_data);
161
162 /* Check whether time step was rejected */
163 #pragma omp simd
164 for(int i = 0; i < NSIMD; i++) {
165 if(p.running[i] && hout_rfof[i] < 0){
166 // Screwed up big time
167 p.running[i] = 0;
168 hnext_recom[i] = hout_rfof[i]; /* Use the smaller time-step
169 suggested by RFOF on the
170 next round. */
171 } else if(p.running[i]) {
172 // Everything went better than expected
173 hin[i] = hin_default[i]; // use the original fixed step
174 }
175 }
176 }
177
178 /**********************************************************************/
179
180
181 /* Update simulation and cpu times */
182 cputime = A5_WTIME;
183 #pragma omp simd
184 for(int i = 0; i < NSIMD; i++) {
185 if(hnext_recom[i] < 0) {
186 /* Screwed up big time (negative time-step only when RFOF
187 rejected) */
188 particle_copy_gc(&p0, i, &p, i);
189 hin[i] = -hnext_recom[i];
190 }
191 if(p.running[i]) {
192 if(hnext_recom[i] < 0) {
193 // unsuccessful step, only reset the recommendation
194 hnext_recom[i] = DUMMY_TIMESTEP_VAL;
195 } else {
196 // The step was successful
197 p.time[i] += ( 1.0 - 2.0 * ( sim->reverse_time > 0 ) ) * hin[i];
198 p.mileage[i] += hin[i];
199 p.cputime[i] += cputime - cputime_last;
200 }
201 }
202 }
203 cputime_last = cputime;
204
205 /* Check possible end conditions */
206 endcond_check_gc(&p, &p0, sim);
207
208 /* Update diagnostics */
209 diag_update_gc(&sim->diag_data, &sim->B_data, &p, &p0);
210
211 /* Update running particles */
212 n_running = particle_cycle_gc(pq, &p, &sim->B_data, cycle);
213
214 /* Determine simulation time-step */
215 #pragma omp simd
216 for(int i = 0; i < NSIMD; i++) {
217 if(cycle[i] > 0) {
218 hin[i] = simulate_gc_fixed_inidt(sim, &p, i);
219 if(sim->enable_icrh) {
220 /* Reset icrh (rfof) resonance memory matrix. */
221 rfof_clear_history(&rfof_mrk, i);
222 }
223 }
224 }
225
226 }
227
228 /* All markers simulated! */
229
230 /* Deallocate rfof structs */
231 if(sim->enable_icrh) {
232 rfof_tear_down(&rfof_mrk);
233 }
234}
235
250 real h;
251
252 /* Value defined directly by user */
253 if(sim->fix_usrdef_use) {
254 h = sim->fix_usrdef_val;
255 }
256 else {
257 /* Value calculated from gyrotime */
258 real Bnorm = math_normc(p->B_r[i], p->B_phi[i], p->B_z[i]);
259 real gyrotime = CONST_2PI /
260 phys_gyrofreq_ppar(p->mass[i], p->charge[i],
261 p->mu[i], p->ppar[i], Bnorm);
262 h = gyrotime/sim->fix_gyrodef_nstep;
263 }
264
265 return h;
266}
Header file for B_field.c.
Header file for E_field.c.
Main header file for ASCOT5.
double real
Definition ascot5.h:85
#define NSIMD
Number of particles simulated simultaneously in a particle group operations.
Definition ascot5.h:91
#define A5_WTIME
Wall time.
Definition ascot5.h:124
#define __memalign__
Definition ascot5.h:76
Header file containing physical and mathematical constants.
#define CONST_2PI
2*pi
Definition consts.h:14
void diag_update_gc(diag_data *data, B_field_data *Bdata, particle_simd_gc *p_f, particle_simd_gc *p_i)
Collects diagnostics when marker represents a guiding center.
Definition diag.c:194
Header file for diag.c.
void endcond_check_gc(particle_simd_gc *p_f, particle_simd_gc *p_i, sim_data *sim)
Check end conditions for GC markers.
Definition endcond.c:262
Header file for endcond.c.
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 mccc package.
void mccc_gc_euler(particle_simd_gc *p, real *h, B_field_data *Bdata, plasma_data *pdata, mccc_data *mdata, real *rnd)
Integrate collisions for one time-step.
void particle_copy_gc(particle_simd_gc *p1, int i, particle_simd_gc *p2, int j)
Copy GC struct.
Definition particle.c:1355
int particle_cycle_gc(particle_queue *q, particle_simd_gc *p, B_field_data *Bdata, int *cycle)
Replace finished GC markers with new ones or dummies.
Definition particle.c:367
Header file for particle.c.
Methods to evaluate elementary physical quantities.
#define phys_gyrofreq_ppar(m, q, mu, ppar, B)
Evaluate gyrofrequency [rad/s] from parallel momentum and magnetic moment.
Definition physlib.h:278
Header file for plasma.c.
#define random_normal_simd(data, n, r)
Definition random.h:102
Contains the functions to be called from the simulation loop when using ICRH.
Header file for simulate.c.
#define DUMMY_TIMESTEP_VAL
void simulate_gc_fixed(particle_queue *pq, sim_data *sim)
Simulates guiding centers using fixed time-step.
real simulate_gc_fixed_inidt(sim_data *sim, particle_simd_gc *p, int i)
Calculates time step value.
Header file for simulate_gc_fixed.c.
void step_gc_rk4(particle_simd_gc *p, real *h, B_field_data *Bdata, E_field_data *Edata, int aldforce)
Integrate a guiding center step for a struct of markers with RK4.
Definition step_gc_rk4.c:34
void step_gc_rk4_mhd(particle_simd_gc *p, real *h, B_field_data *Bdata, E_field_data *Edata, boozer_data *boozer, mhd_data *mhd, int aldforce)
Integrate a guiding center step with RK4 with MHD modes present.
Header file for step_gc_rk4.c.
Marker queue.
Definition particle.h:154
Struct representing NSIMD guiding center markers.
Definition particle.h:275
Reusable struct for storing marker specific data during the simulation loop.
Definition rfof.h:19
Simulation data struct.
Definition simulate.h:58
int enable_orbfol
Definition simulate.h:99
plasma_data plasma_data
Definition simulate.h:62
mhd_data mhd_data
Definition simulate.h:66
rfof_data rfof_data
Definition simulate.h:70
real fix_usrdef_val
Definition simulate.h:84
E_field_data E_data
Definition simulate.h:61
int enable_aldforce
Definition simulate.h:104
int enable_mhd
Definition simulate.h:101
int fix_usrdef_use
Definition simulate.h:83
mccc_data mccc_data
Definition simulate.h:75
random_data random_data
Definition simulate.h:74
int fix_gyrodef_nstep
Definition simulate.h:85
boozer_data boozer_data
Definition simulate.h:65
B_field_data B_data
Definition simulate.h:60
int reverse_time
Definition simulate.h:113
int enable_icrh
Definition simulate.h:103
int enable_clmbcol
Definition simulate.h:100
diag_data diag_data
Definition simulate.h:69
Header file for wall.c.