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 "../copytogpu.h"
23#include "simulate_fo_fixed.h"
24#include "step/step_fo_vpa.h"
25#include "mccc/mccc.h"
26#include "atomic.h"
27
28DECLARE_TARGET_SIMD_UNIFORM(sim)
30
50void simulate_fo_fixed(particle_queue* pq, sim_data* sim, int mrk_array_size) {
51 int cycle[mrk_array_size];// Indicates whether a new marker was initialized
52 real hin[mrk_array_size];// Time step
53
54 real cputime, cputime_last; // Global cpu time: recent and previous record
55
56 particle_simd_fo p; // This array holds current states
57 particle_simd_fo p0; // This array stores previous states
58 particle_allocate_fo(&p, mrk_array_size);
59 particle_allocate_fo(&p0, mrk_array_size);
60
61 /* Init dummy markers */
62 for(int i=0; i< mrk_array_size; i++) {
63 p.id[i] = -1;
64 p.running[i] = 0;
65 }
66
67 /* Initialize running particles */
68 int n_running = particle_cycle_fo(pq, &p, &sim->B_data, cycle);
69
70 /* Determine simulation time-step */
71 #pragma omp simd
72 for(int i = 0; i < mrk_array_size; i++) {
73 if(cycle[i] > 0) {
74 hin[i] = simulate_fo_fixed_inidt(sim, &p, i);
75
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 */
89 particle_simd_fo *p_ptr = &p;
90 particle_simd_fo *p0_ptr = &p0;
91 real rnd[3*mrk_array_size];
92
94 particle_offload_fo(p0_ptr);
95 GPU_MAP_TO_DEVICE(hin[0:mrk_array_size], rnd[0:3*mrk_array_size])
96 while(n_running > 0) {
97 /* Store marker states */
98 GPU_PARALLEL_LOOP_ALL_LEVELS
99 for(int i = 0; i < p.n_mrk; i++) {
100 particle_copy_fo(p_ptr, i, p0_ptr, i);
101 }
102 /*************************** Physics **********************************/
103
104 /* Set time-step negative if tracing backwards in time */
105 GPU_PARALLEL_LOOP_ALL_LEVELS
106 for(int i = 0; i < p.n_mrk; i++) {
107 if(sim->reverse_time) {
108 hin[i] = -hin[i];
109 }
110 }
111
112 /* Volume preserving algorithm for orbit-following */
113 if(sim->enable_orbfol) {
114 if(sim->enable_mhd) {
115 step_fo_vpa_mhd(&p, hin, &sim->B_data, &sim->E_data,
116 &sim->boozer_data, &sim->mhd_data);
117 }
118 else {
119 step_fo_vpa(p_ptr, hin, &sim->B_data, &sim->E_data);
120 }
121 }
122
123 /* Switch sign of the time-step again if it was reverted earlier */
124 GPU_PARALLEL_LOOP_ALL_LEVELS
125 for(int i = 0; i < p.n_mrk; i++) {
126 if(sim->reverse_time) {
127 hin[i] = -hin[i];
128 }
129 }
130
131 /* Euler-Maruyama for Coulomb collisions */
132 if(sim->enable_clmbcol) {
133 random_normal_simd(&sim->random_data, 3*p.n_mrk, rnd);
134 mccc_fo_euler(p_ptr, hin, &sim->plasma_data, &sim->mccc_data, rnd);
135 }
136 /* Atomic reactions */
137 if(sim->enable_atomic) {
138 atomic_fo(p_ptr, hin, &sim->plasma_data, &sim->neutral_data,
139 &sim->random_data, &sim->asigma_data);
140 }
141 /**********************************************************************/
142
143
144 /* Update simulation and cpu times */
145 cputime = A5_WTIME;
146 GPU_PARALLEL_LOOP_ALL_LEVELS
147 for(int i = 0; i < p.n_mrk; i++) {
148 if(p.running[i]){
149 p.time[i] += ( 1.0 - 2.0 * ( sim->reverse_time > 0 ) ) * hin[i];
150 p.mileage[i] += hin[i];
151 p.cputime[i] += cputime - cputime_last;
152 }
153 }
154 cputime_last = cputime;
155
156 /* Check possible end conditions */
157 endcond_check_fo(p_ptr, p0_ptr, sim);
158
159 /* Update diagnostics */
160 if(!(sim->record_mode)) {
161 /* Record particle coordinates */
162 diag_update_fo(&sim->diag_data, &sim->B_data, p_ptr, p0_ptr);
163 }
164 else {
165 /* Instead of particle coordinates we record guiding center */
166
167 // Dummy guiding centers
168 particle_simd_gc gc_f;
169 particle_simd_gc gc_i;
170
171 /* Particle to guiding center transformation */
172 #pragma omp simd
173 for(int i=0; i<p.n_mrk; i++) {
174 if(p.running[i]) {
175 particle_fo_to_gc(&p, i, &gc_f, &sim->B_data);
176 }
177 else {
178 gc_f.id[i] = p.id[i];
179 gc_f.running[i] = 0;
180 }
181 if(p0.running[i]) {
182 particle_fo_to_gc(&p0, i, &gc_i, &sim->B_data);
183 }
184 else {
185 gc_i.id[i] = p0.id[i];
186 gc_i.running[i] = 0;
187 }
188 }
189 diag_update_gc(&sim->diag_data, &sim->B_data, &gc_f, &gc_i);
190 }
191
192 /* Update running particles */
193#ifdef GPU
194 n_running = 0;
195 GPU_PARALLEL_LOOP_ALL_LEVELS_REDUCTION(n_running)
196 for(int i = 0; i < p.n_mrk; i++)
197 {
198 if(p_ptr->running[i] > 0) n_running++;
199 }
200#else
201 n_running = particle_cycle_fo(pq, &p, &sim->B_data, cycle);
202#endif
203#ifndef GPU
204 /* Determine simulation time-step for new particles */
205 GPU_PARALLEL_LOOP_ALL_LEVELS
206 for(int i = 0; i < p.n_mrk; i++) {
207 if(cycle[i] > 0) {
208 hin[i] = simulate_fo_fixed_inidt(sim, &p, i);
209 }
210 }
211#endif
212 }
213 /* All markers simulated! */
214#ifdef GPU
216 n_running = particle_cycle_fo(pq, &p, &sim->B_data, cycle);
217#endif
218}
219
234
235 real h;
236
237 /* Value defined directly by user */
238 if(sim->fix_usrdef_use) {
239 h = sim->fix_usrdef_val;
240 }
241 else {
242 /* Value calculated from gyrotime */
243 real Bnorm = math_normc( p->B_r[i], p->B_phi[i], p->B_z[i] );
244 real pnorm = math_normc( p->p_r[i], p->p_phi[i], p->p_z[i] );
245 real gyrotime = CONST_2PI/
246 phys_gyrofreq_pnorm(p->mass[i], p->charge[i], pnorm, Bnorm);
247 h = gyrotime/sim->fix_gyrodef_nstep;
248 }
249
250 return h;
251}
252
253
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 simulate_fo_fixed_copy_from_gpu(sim_data *sim, particle_simd_fo *p_ptr)
Copy data from GPU to CPU.
Definition copytogpu.c:157
Header file for copytogpu.c.
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:223
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:258
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.
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:154
int enable_orbfol
Definition simulate.h:194
int record_mode
Definition simulate.h:175
plasma_data plasma_data
Definition simulate.h:158
mhd_data mhd_data
Definition simulate.h:162
int enable_atomic
Definition simulate.h:197
real fix_usrdef_val
Definition simulate.h:179
E_field_data E_data
Definition simulate.h:157
int enable_mhd
Definition simulate.h:196
int fix_usrdef_use
Definition simulate.h:178
mccc_data mccc_data
Definition simulate.h:169
random_data random_data
Definition simulate.h:168
neutral_data neutral_data
Definition simulate.h:159
int fix_gyrodef_nstep
Definition simulate.h:180
boozer_data boozer_data
Definition simulate.h:161
B_field_data B_data
Definition simulate.h:156
int reverse_time
Definition simulate.h:206
asigma_data asigma_data
Definition simulate.h:163
int enable_clmbcol
Definition simulate.h:195
diag_data diag_data
Definition simulate.h:165
Header file for wall.c.