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
64 if(sim->record_mode) {
65 particle_allocate_gc(&gc_f, mrk_array_size);
66 particle_allocate_gc(&gc_i, mrk_array_size);
69 }
70
71 /* Init dummy markers */
72 for(int i = 0; i < mrk_array_size; i++) {
73 p.id[i] = -1;
74 p.running[i] = 0;
75 }
76
77 /* Initialize running particles */
78 int n_running = particle_cycle_fo(pq, &p, &sim->B_data, cycle);
79
80 /* Determine simulation time-step */
81 GPU_PARALLEL_LOOP_ALL_LEVELS
82 for(int i = 0; i < mrk_array_size; i++) {
83 if(cycle[i] > 0) {
84 hin[i] = simulate_fo_fixed_inidt(sim, &p, i);
85 }
86 }
87
88 cputime_last = A5_WTIME;
89
90 /* MAIN SIMULATION LOOP
91 * - Store current state
92 * - Integrate motion due to background EM-field (orbit-following)
93 * - Integrate scattering due to Coulomb collisions
94 * - Advance time
95 * - Check for end condition(s)
96 * - Update diagnostics
97 */
100 real* rnd = (real*) malloc(3*mrk_array_size*sizeof(real));
101 GPU_MAP_TO_DEVICE(hin[0:mrk_array_size], rnd[0:3*mrk_array_size])
102 while(n_running > 0) {
103 /* Store marker states */
104 GPU_PARALLEL_LOOP_ALL_LEVELS
105 for(int i = 0; i < p.n_mrk; i++) {
106 particle_copy_fo(&p, i, &p0, i);
107 }
108 /*************************** Physics **********************************/
109
110 /* Set time-step negative if tracing backwards in time */
111 GPU_PARALLEL_LOOP_ALL_LEVELS
112 for(int i = 0; i < p.n_mrk; i++) {
113 if(sim->reverse_time) {
114 hin[i] = -hin[i];
115 }
116 }
117
118 /* Volume preserving algorithm for orbit-following */
119 if(sim->enable_orbfol) {
120 if(sim->enable_mhd) {
122 &p, hin, &sim->B_data, &sim->E_data, &sim->boozer_data,
123 &sim->mhd_data, sim->enable_aldforce);
124 }
125 else {
126 step_fo_vpa(&p, hin, &sim->B_data, &sim->E_data,
127 sim->enable_aldforce);
128 }
129 }
130
131 /* Switch sign of the time-step again if it was reverted earlier */
132 GPU_PARALLEL_LOOP_ALL_LEVELS
133 for(int i = 0; i < p.n_mrk; i++) {
134 if(sim->reverse_time) {
135 hin[i] = -hin[i];
136 }
137 }
138
139 /* Euler-Maruyama for Coulomb collisions */
140 if(sim->enable_clmbcol) {
141 random_normal_simd(sim->random_data, 3*p.n_mrk, rnd);
142 mccc_fo_euler(&p, hin, &sim->plasma_data, &sim->mccc_data, rnd);
143 }
144 /* Atomic reactions */
145 if(sim->enable_atomic) {
146 atomic_fo(&p, hin, &sim->plasma_data, &sim->neutral_data,
147 sim->random_data, &sim->asigma_data);
148 }
149 /**********************************************************************/
150
151
152 /* Update simulation and cpu times */
153 cputime = A5_WTIME;
154 GPU_PARALLEL_LOOP_ALL_LEVELS
155 for(int i = 0; i < p.n_mrk; i++) {
156 if(p.running[i]){
157 p.time[i] += ( 1.0 - 2.0 * ( sim->reverse_time > 0 ) ) * hin[i];
158 p.mileage[i] += hin[i];
159 p.cputime[i] += cputime - cputime_last;
160 }
161 }
162 cputime_last = cputime;
163
164 /* Check possible end conditions */
165 endcond_check_fo(&p, &p0, sim);
166
167 /* Update diagnostics */
168 if(!(sim->record_mode)) {
169 /* Record particle coordinates */
170 diag_update_fo(&sim->diag_data, &sim->B_data, &p, &p0);
171 }
172 else {
173 /* Instead of particle coordinates we record guiding center */
174
175 /* Particle to guiding center transformation */
176 for(int i=0; i<p.n_mrk; i++) {
177 if(p.running[i]) {
178 particle_fo_to_gc(&p, i, &gc_f, &sim->B_data);
179 }
180 else {
181 gc_f.id[i] = p.id[i];
182 gc_f.running[i] = 0;
183 }
184 if(p0.running[i]) {
185 particle_fo_to_gc(&p0, i, &gc_i, &sim->B_data);
186 }
187 else {
188 gc_i.id[i] = p0.id[i];
189 gc_i.running[i] = 0;
190 }
191 }
192 diag_update_gc(&sim->diag_data, &sim->B_data, &gc_f, &gc_i);
193 }
194
195 /* Update running particles */
196#ifdef GPU
197 n_running = 0;
198 GPU_PARALLEL_LOOP_ALL_LEVELS_REDUCTION(n_running)
199 for(int i = 0; i < p.n_mrk; i++)
200 {
201 if(p.running[i] > 0) n_running++;
202 }
203#else
204 n_running = particle_cycle_fo(pq, &p, &sim->B_data, cycle);
205#endif
206#ifndef GPU
207 /* Determine simulation time-step for new particles */
208 GPU_PARALLEL_LOOP_ALL_LEVELS
209 for(int i = 0; i < p.n_mrk; i++) {
210 if(cycle[i] > 0) {
211 hin[i] = simulate_fo_fixed_inidt(sim, &p, i);
212 }
213 }
214#endif
215 }
216 /* All markers simulated! */
217#ifdef GPU
218 GPU_MAP_FROM_DEVICE(sim[0:1])
220 n_running = particle_cycle_fo(pq, &p, &sim->B_data, cycle);
221#endif
222 free(cycle);
223 free(hin);
224 free(rnd);
225}
226
241
242 real h;
243
244 /* Value defined directly by user */
245 if(sim->fix_usrdef_use) {
246 h = sim->fix_usrdef_val;
247 }
248 else {
249 /* Value calculated from gyrotime */
250 real Bnorm = math_normc( p->B_r[i], p->B_phi[i], p->B_z[i] );
251 real pnorm = math_normc( p->p_r[i], p->p_phi[i], p->p_z[i] );
252 real gyrotime = CONST_2PI/
253 phys_gyrofreq_pnorm(p->mass[i], p->charge[i], pnorm, Bnorm);
254 h = gyrotime/sim->fix_gyrodef_nstep;
255 }
256
257 return h;
258}
259
260
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:182
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:217
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:71
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_allocate_gc(particle_simd_gc *p_gc, int nmrk)
Allocates guiding center struct representing particle markers.
Definition particle.c:126
void particle_onload_fo(particle_simd_fo *p)
Onload particle struct from the GPU.
Definition particle.c:1824
void particle_offload_gc(particle_simd_gc *p)
Offload guiding center particle struct to GPU.
Definition particle.c:1870
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:1237
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:1778
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:320
void particle_copy_fo(particle_simd_fo *p1, int i, particle_simd_fo *p2, int j)
Copy FO struct.
Definition particle.c:1354
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:261
Header file for plasma.c.
#define random_normal_simd(data, n, r)
Definition random.h:115
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(particle_simd_fo *p, real *h, B_field_data *Bdata, E_field_data *Edata, int aldforce)
Integrate a full orbit step for a struct of particles with VPA.
Definition step_fo_vpa.c:36
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, int aldforce)
Integrate a full orbit step with VPA and MHd modes present.
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
integer * running
Definition particle.h:320
integer * id
Definition particle.h:312
Simulation data struct.
Definition simulate.h:58
int enable_orbfol
Definition simulate.h:99
int record_mode
Definition simulate.h:80
plasma_data plasma_data
Definition simulate.h:62
mhd_data mhd_data
Definition simulate.h:66
int enable_atomic
Definition simulate.h:102
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
random_data * random_data
Definition simulate.h:74
mccc_data mccc_data
Definition simulate.h:75
neutral_data neutral_data
Definition simulate.h:63
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
asigma_data asigma_data
Definition simulate.h:67
int enable_clmbcol
Definition simulate.h:100
diag_data diag_data
Definition simulate.h:69
Header file for wall.c.