ASCOT5
Loading...
Searching...
No Matches
simulate_fo_fixed.c
Go to the documentation of this file.
1
5#include <stdio.h>
6#include <stdlib.h>
7#include <time.h>
8#include <omp.h>
9#include <math.h>
10#include "../ascot5.h"
11#include "../physlib.h"
12#include "../simulate.h"
13#include "../particle.h"
14#include "../wall.h"
15#include "../diag.h"
16#include "../B_field.h"
17#include "../E_field.h"
18#include "../plasma.h"
19#include "../endcond.h"
20#include "../math.h"
21#include "../consts.h"
22#include "simulate_fo_fixed.h"
23#include "step/step_fo_vpa.h"
24#include "mccc/mccc.h"
25#include "atomic.h"
26
27DECLARE_TARGET_SIMD_UNIFORM(sim)
29
49void simulate_fo_fixed(particle_queue* pq, sim_data* sim, int mrk_array_size) {
50 // Indicates whether a new marker was initialized
51 int* cycle = (int*) malloc(mrk_array_size*sizeof(int));
52 // Time-step
53 real* hin = (real*) malloc(mrk_array_size*sizeof(real));
54
55 real cputime, cputime_last; // Global cpu time: recent and previous record
56
57 particle_simd_fo p; // This array holds current states
58 particle_simd_fo p0; // This array stores previous states
59 particle_allocate_fo(&p, mrk_array_size);
60 particle_allocate_fo(&p0, mrk_array_size);
61
62 /* Init dummy markers */
63 for(int i = 0; i < mrk_array_size; i++) {
64 p.id[i] = -1;
65 p.running[i] = 0;
66 }
67
68 /* Initialize running particles */
69 int n_running = particle_cycle_fo(pq, &p, &sim->B_data, cycle);
70
71 /* Determine simulation time-step */
72 #pragma omp simd
73 for(int i = 0; i < mrk_array_size; i++) {
74 if(cycle[i] > 0) {
75 hin[i] = simulate_fo_fixed_inidt(sim, &p, i);
76 }
77 }
78
79 cputime_last = A5_WTIME;
80
81 /* MAIN SIMULATION LOOP
82 * - Store current state
83 * - Integrate motion due to background EM-field (orbit-following)
84 * - Integrate scattering due to Coulomb collisions
85 * - Advance time
86 * - Check for end condition(s)
87 * - Update diagnostics
88 */
91 real* rnd = (real*) malloc(3*mrk_array_size*sizeof(real));
92 GPU_MAP_TO_DEVICE(hin[0:mrk_array_size], rnd[0:3*mrk_array_size])
93 while(n_running > 0) {
94 /* Store marker states */
95 GPU_PARALLEL_LOOP_ALL_LEVELS
96 for(int i = 0; i < p.n_mrk; i++) {
97 particle_copy_fo(&p, i, &p0, i);
98 }
99 /*************************** Physics **********************************/
100
101 /* Set time-step negative if tracing backwards in time */
102 GPU_PARALLEL_LOOP_ALL_LEVELS
103 for(int i = 0; i < p.n_mrk; i++) {
104 if(sim->reverse_time) {
105 hin[i] = -hin[i];
106 }
107 }
108
109 /* Volume preserving algorithm for orbit-following */
110 if(sim->enable_orbfol) {
111 if(sim->enable_mhd) {
112 step_fo_vpa_mhd(&p, hin, &sim->B_data, &sim->E_data,
113 &sim->boozer_data, &sim->mhd_data);
114 }
115 else {
116 step_fo_vpa(&p, hin, &sim->B_data, &sim->E_data);
117 }
118 }
119
120 /* Switch sign of the time-step again if it was reverted earlier */
121 GPU_PARALLEL_LOOP_ALL_LEVELS
122 for(int i = 0; i < p.n_mrk; i++) {
123 if(sim->reverse_time) {
124 hin[i] = -hin[i];
125 }
126 }
127
128 /* Euler-Maruyama for Coulomb collisions */
129 if(sim->enable_clmbcol) {
130 random_normal_simd(&sim->random_data, 3*p.n_mrk, rnd);
131 mccc_fo_euler(&p, hin, &sim->plasma_data, &sim->mccc_data, rnd);
132 }
133 /* Atomic reactions */
134 if(sim->enable_atomic) {
135 atomic_fo(&p, hin, &sim->plasma_data, &sim->neutral_data,
136 &sim->random_data, &sim->asigma_data);
137 }
138 /**********************************************************************/
139
140
141 /* Update simulation and cpu times */
142 cputime = A5_WTIME;
143 GPU_PARALLEL_LOOP_ALL_LEVELS
144 for(int i = 0; i < p.n_mrk; i++) {
145 if(p.running[i]){
146 p.time[i] += ( 1.0 - 2.0 * ( sim->reverse_time > 0 ) ) * hin[i];
147 p.mileage[i] += hin[i];
148 p.cputime[i] += cputime - cputime_last;
149 }
150 }
151 cputime_last = cputime;
152
153 /* Check possible end conditions */
154 endcond_check_fo(&p, &p0, sim);
155
156 /* Update diagnostics */
157 if(!(sim->record_mode)) {
158 /* Record particle coordinates */
159 diag_update_fo(&sim->diag_data, &sim->B_data, &p, &p0);
160 }
161 else {
162 /* Instead of particle coordinates we record guiding center */
163
164 // Dummy guiding centers
165 particle_simd_gc gc_f;
166 particle_simd_gc gc_i;
167
168 /* Particle to guiding center transformation */
169 #pragma omp simd
170 for(int i=0; i<p.n_mrk; i++) {
171 if(p.running[i]) {
172 particle_fo_to_gc(&p, i, &gc_f, &sim->B_data);
173 }
174 else {
175 gc_f.id[i] = p.id[i];
176 gc_f.running[i] = 0;
177 }
178 if(p0.running[i]) {
179 particle_fo_to_gc(&p0, i, &gc_i, &sim->B_data);
180 }
181 else {
182 gc_i.id[i] = p0.id[i];
183 gc_i.running[i] = 0;
184 }
185 }
186 diag_update_gc(&sim->diag_data, &sim->B_data, &gc_f, &gc_i);
187 }
188
189 /* Update running particles */
190#ifdef GPU
191 n_running = 0;
192 GPU_PARALLEL_LOOP_ALL_LEVELS_REDUCTION(n_running)
193 for(int i = 0; i < p.n_mrk; i++)
194 {
195 if(p.running[i] > 0) n_running++;
196 }
197#else
198 n_running = particle_cycle_fo(pq, &p, &sim->B_data, cycle);
199#endif
200#ifndef GPU
201 /* Determine simulation time-step for new particles */
202 GPU_PARALLEL_LOOP_ALL_LEVELS
203 for(int i = 0; i < p.n_mrk; i++) {
204 if(cycle[i] > 0) {
205 hin[i] = simulate_fo_fixed_inidt(sim, &p, i);
206 }
207 }
208#endif
209 }
210 /* All markers simulated! */
211#ifdef GPU
212 GPU_MAP_FROM_DEVICE(sim[0:1])
214 n_running = particle_cycle_fo(pq, &p, &sim->B_data, cycle);
215#endif
216 free(cycle);
217 free(hin);
218 free(rnd);
219}
220
235
236 real h;
237
238 /* Value defined directly by user */
239 if(sim->fix_usrdef_use) {
240 h = sim->fix_usrdef_val;
241 }
242 else {
243 /* Value calculated from gyrotime */
244 real Bnorm = math_normc( p->B_r[i], p->B_phi[i], p->B_z[i] );
245 real pnorm = math_normc( p->p_r[i], p->p_phi[i], p->p_z[i] );
246 real gyrotime = CONST_2PI/
247 phys_gyrofreq_pnorm(p->mass[i], p->charge[i], pnorm, Bnorm);
248 h = gyrotime/sim->fix_gyrodef_nstep;
249 }
250
251 return h;
252}
253
254
Header file for B_field.c.
Header file for E_field.c.
Main header file for ASCOT5.
double real
Definition ascot5.h:85
#define A5_WTIME
Wall time.
Definition ascot5.h:124
void atomic_fo(particle_simd_fo *p, real *h, plasma_data *p_data, neutral_data *n_data, random_data *r_data, asigma_data *asigmadata)
Determine if atomic reactions occur during time-step and change charge.
Definition atomic.c:56
Header file for atomic.c.
Header file containing physical and mathematical constants.
#define CONST_2PI
2*pi
Definition consts.h:14
void diag_update_fo(diag_data *data, B_field_data *Bdata, particle_simd_fo *p_f, particle_simd_fo *p_i)
Collects diagnostics when marker represents a particle.
Definition diag.c:144
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:179
Header file for diag.c.
void endcond_check_fo(particle_simd_fo *p_f, particle_simd_fo *p_i, sim_data *sim)
Check end conditions for FO markers.
Definition endcond.c:73
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:67
Header file for mccc package.
void mccc_fo_euler(particle_simd_fo *p, real *h, plasma_data *pdata, mccc_data *mdata, real *rnd)
Integrate collisions for one time-step.
void particle_onload_fo(particle_simd_fo *p)
Onload particle struct from the GPU.
Definition particle.c:1772
int particle_fo_to_gc(particle_simd_fo *p_fo, int j, particle_simd_gc *p_gc, B_field_data *Bdata)
Convert FO struct into a GC struct.
Definition particle.c:1185
void particle_allocate_fo(particle_simd_fo *p_fo, int nmrk)
Allocates struct representing particle markers.
Definition particle.c:69
void particle_offload_fo(particle_simd_fo *p)
Offload particle struct to GPU.
Definition particle.c:1726
int particle_cycle_fo(particle_queue *q, particle_simd_fo *p, B_field_data *Bdata, int *cycle)
Replace finished FO markers with new ones or dummies.
Definition particle.c:268
void particle_copy_fo(particle_simd_fo *p1, int i, particle_simd_fo *p2, int j)
Copy FO struct.
Definition particle.c:1302
Header file for particle.c.
Methods to evaluate elementary physical quantities.
#define phys_gyrofreq_pnorm(m, q, p, B)
Evaluate gyrofrequency [rad/s] from momentum norm.
Definition physlib.h:257
Header file for plasma.c.
#define random_normal_simd(data, n, r)
Definition random.h:102
Header file for simulate.c.
real simulate_fo_fixed_inidt(sim_data *sim, particle_simd_fo *p, int i)
Calculates time step value.
void simulate_fo_fixed(particle_queue *pq, sim_data *sim, int mrk_array_size)
Simulates particles using fixed time-step.
Header file for simulate_fo_fixed.c.
void step_fo_vpa_mhd(particle_simd_fo *p, real *h, B_field_data *Bdata, E_field_data *Edata, boozer_data *boozer, mhd_data *mhd)
Integrate a full orbit step with VPA and MHd modes present.
void step_fo_vpa(particle_simd_fo *p, real *h, B_field_data *Bdata, E_field_data *Edata)
Integrate a full orbit step for a struct of particles with VPA.
Definition step_fo_vpa.c:35
Header file for step_fo_vpa.c.
Marker queue.
Definition particle.h:154
Struct representing NSIMD particle markers.
Definition particle.h:210
integer * id
Definition particle.h:246
integer * running
Definition particle.h:252
Struct representing NSIMD guiding center markers.
Definition particle.h:275
Simulation data struct.
Definition simulate.h:57
int enable_orbfol
Definition simulate.h:97
int record_mode
Definition simulate.h:78
plasma_data plasma_data
Definition simulate.h:61
mhd_data mhd_data
Definition simulate.h:65
int enable_atomic
Definition simulate.h:100
real fix_usrdef_val
Definition simulate.h:82
E_field_data E_data
Definition simulate.h:60
int enable_mhd
Definition simulate.h:99
int fix_usrdef_use
Definition simulate.h:81
mccc_data mccc_data
Definition simulate.h:72
random_data random_data
Definition simulate.h:71
neutral_data neutral_data
Definition simulate.h:62
int fix_gyrodef_nstep
Definition simulate.h:83
boozer_data boozer_data
Definition simulate.h:64
B_field_data B_data
Definition simulate.h:59
int reverse_time
Definition simulate.h:109
asigma_data asigma_data
Definition simulate.h:66
int enable_clmbcol
Definition simulate.h:98
diag_data diag_data
Definition simulate.h:68
Header file for wall.c.