ASCOT5
Loading...
Searching...
No Matches
simulate.c
Go to the documentation of this file.
1
14#include <string.h>
15#include <unistd.h>
16#include "endcond.h"
17#include "offload.h"
18#include "particle.h"
19#include "plasma.h"
20#include "random.h"
21#include "simulate.h"
22#include "print.h"
27#include "simulate/mccc/mccc.h"
28#include "gctransform.h"
29#include "asigma.h"
30#include "copytogpu.h"
31
32void sim_monitor(char* filename, volatile int* n, volatile int* finished);
33
81 int id, int n_particles, particle_state* p, sim_offload_data* sim_offload,
82 offload_package* offload_data, real* offload_array, int* int_offload_array,
83 real* diag_offload_array) {
84
85 // Size = NSIMD on CPU and Size = Total number of particles on GPU
86 int n_queue_size;
87#ifdef GPU
88 n_queue_size = n_particles;
89#else
90 n_queue_size = NSIMD;
91#endif
92 /**************************************************************************/
93 /* 1. Input offload data is unpacked and initialized by calling */
94 /* respective init functions. */
95 /* */
96 /**************************************************************************/
97 sim_data sim;
98 sim_init(&sim, sim_offload);
99
100#ifdef GPU
101 if(sim_offload->sim_mode != 1) {
102 print_err("Only GO mode ported to GPU. Please set SIM_MODE=1.");
103 exit(1);
104 }
105 if(sim_offload->record_mode) {
106 print_err("RECORD_MODE=1 not ported to GPU. Please disable it.");
107 exit(1);
108 }
109 if(sim_offload->enable_atomic) {
110 print_err("Atomic not yet ported to GPU. Please set ENABLE_ATOMIC=0.");
111 exit(1);
112 }
113 if(sim_offload->enable_mhd) {
114 print_err("MHD not yet ported to GPU. Please set ENABLE_MHD=0.");
115 exit(1);
116 }
117 if(sim_offload->diag_offload_data.diagorb_collect) {
118 print_err(
119 "ENABLE_ORBITWRITE=1 not ported to GPU. Please disable it.");
120 exit(1);
121 }
122 if(sim_offload->diag_offload_data.diagtrcof_collect) {
123 print_err(
124 "ENABLE_TRANSCOEF=1 not ported to GPU. Please disable it.");
125 exit(1);
126 }
127#endif
128 real* ptr; int* ptrint;
129 offload_unpack(offload_data, offload_array,
131 NULL, 0, &ptr, &ptrint);
132 B_field_init(&sim.B_data, &sim_offload->B_offload_data, ptr);
133
134 offload_unpack(offload_data, offload_array,
136 NULL, 0, &ptr, &ptrint);
137 E_field_init(&sim.E_data, &sim_offload->E_offload_data, ptr);
138
139 offload_unpack(offload_data, offload_array,
141 NULL, 0, &ptr, &ptrint);
142 plasma_init(&sim.plasma_data, &sim_offload->plasma_offload_data, ptr);
143
144 offload_unpack(offload_data, offload_array,
146 NULL, 0, &ptr, &ptrint);
147 neutral_init(&sim.neutral_data, &sim_offload->neutral_offload_data, ptr);
148
149 offload_unpack(offload_data, offload_array,
151 int_offload_array,
153 &ptr, &ptrint);
154 wall_init(&sim.wall_data, &sim_offload->wall_offload_data, ptr, ptrint);
155
156 offload_unpack(offload_data, offload_array,
158 NULL, 0, &ptr, &ptrint);
159 boozer_init(&sim.boozer_data, &sim_offload->boozer_offload_data, ptr);
160
161 offload_unpack(offload_data, offload_array,
163 NULL, 0, &ptr, &ptrint);
164 mhd_init(&sim.mhd_data, &sim_offload->mhd_offload_data, ptr);
165
166 offload_unpack(offload_data, offload_array,
168 NULL, 0, &ptr, &ptrint);
169 asigma_init(&sim.asigma_data, &sim_offload->asigma_offload_data, ptr);
170
171 /* Offload complete. Reset struct so it can be reused. */
172 offload_data->unpack_pos = 0;
173 offload_data->int_unpack_pos = 0;
174
175 diag_init(&sim.diag_data, &sim_offload->diag_offload_data,
176 diag_offload_array);
178
179 /**************************************************************************/
180 /* 2. Meta data (e.g. random number generator) is initialized. */
181 /* */
182 /**************************************************************************/
183 random_init(&sim.random_data, 0);
184
185 /**************************************************************************/
186 /* 3. Markers are put into simulation queue. */
187 /* */
188 /**************************************************************************/
190
191 pq.n = 0;
192 for(int i = 0; i < n_particles; i++) {
193 pq.n++;
194 }
195
196 pq.p = (particle_state**) malloc(pq.n * sizeof(particle_state*));
197 pq.finished = 0;
198
199 pq.next = 0;
200 for(int i = 0; i < n_particles; i++) {
201 pq.p[pq.next++] = &p[i];
202
203 }
204 pq.next = 0;
205
206 print_out(VERBOSE_NORMAL, "Simulation begins; %d threads.\n",
207 omp_get_max_threads());
208
209 /**************************************************************************/
210 /* 4. Threads are spawned. One thread is dedicated for monitoring */
211 /* progress, if monitoring is active. */
212 /* */
213 /**************************************************************************/
214#ifndef GPU
215 omp_set_max_active_levels(2);
216#endif
217#if !defined(GPU) && VERBOSE > 1
218 #pragma omp parallel sections num_threads(2)
219 {
220 #pragma omp section
221#endif
222 {
223 /******************************************************************/
224 /* 5. Other threads execute marker simulation using the mode the */
225 /* user has chosen. */
226 /* */
227 /******************************************************************/
228 if(pq.n > 0 && (sim.sim_mode == simulate_mode_gc
229 || sim.sim_mode == simulate_mode_hybrid)) {
230 if(sim.enable_ada) {
231 OMP_PARALLEL_CPU_ONLY
232 simulate_gc_adaptive(&pq, &sim);
233 }
234 else {
235 OMP_PARALLEL_CPU_ONLY
236 simulate_gc_fixed(&pq, &sim);
237 }
238 }
239 else if(pq.n > 0 && sim.sim_mode == simulate_mode_fo) {
240 OMP_PARALLEL_CPU_ONLY
241 simulate_fo_fixed(&pq, &sim, n_queue_size);
242 }
243 else if(pq.n > 0 && sim.sim_mode == simulate_mode_ml) {
244 OMP_PARALLEL_CPU_ONLY
245 simulate_ml_adaptive(&pq, &sim);
246 }
247 }
248#if !defined(GPU) && VERBOSE > 1
249 #pragma omp section
250 {
251 /* Update progress until simulation is complete. */
252 /* Trim .h5 from filename and replace it with _<QID>.stdout */
253 if(id == 0) {
254 char filename[519], outfn[256];
255 strcpy(outfn, sim_offload->hdf5_out);
256 outfn[strlen(outfn)-3] = '\0';
257 sprintf(filename, "%s_%s.stdout", outfn, sim_offload->qid);
258 sim_monitor(filename, &pq.n, &pq.finished);
259 }
260 }
261 }
262#endif
263
264 /**************************************************************************/
265 /* 6. (If hybrid mode is active) Markers with hybrid end condition active */
266 /* are placed on a new queue, and they have their end condition */
267 /* deactivated and they are simulated with simulate_fo_fixed.c until */
268 /* they have met some other end condition. Threads are spawned and */
269 /* progress is monitored as previously. */
270 /* */
271 /**************************************************************************/
272 int n_new = 0;
273 if(sim.sim_mode == simulate_mode_hybrid) {
274
275 /* Determine the number markers that should be run
276 * in fo after previous gc simulation */
277 for(int i = 0; i < pq.n; i++) {
278 if(pq.p[i]->endcond == endcond_hybrid) {
279 /* Check that there was no wall between when moving from
280 gc to fo */
281 real w_coll;
282 int tile = wall_hit_wall(pq.p[i]->r, pq.p[i]->phi, pq.p[i]->z,
283 pq.p[i]->rprt, pq.p[i]->phiprt, pq.p[i]->zprt,
284 &sim.wall_data, &w_coll);
285 if(tile > 0) {
286 pq.p[i]->walltile = tile;
287 pq.p[i]->endcond |= endcond_wall;
288 }
289 else {
290 n_new++;
291 }
292 }
293 }
294 }
295 if(n_new > 0) {
296
297 /* Reset hybrid marker end condition */
298 for(int i = 0; i < pq.n; i++) {
299 if(pq.p[i]->endcond & endcond_hybrid) {
300 pq.p[i]->endcond ^= endcond_hybrid;
301 }
302 }
303 pq.next = 0;
304 pq.finished = 0;
305
306#if !defined(GPU) && VERBOSE > 1
307 #pragma omp parallel sections num_threads(2)
308 {
309 #pragma omp section
310#endif
311 {
312 OMP_PARALLEL_CPU_ONLY
313 simulate_fo_fixed(&pq, &sim, n_queue_size);
314 }
315#if !defined(GPU) && VERBOSE > 1
316 #pragma omp section
317 {
318 /* Trim .h5 from filename and replace it with _<qid>.stdout */
319 if(id == 0) {
320 char filename[519], outfn[256];
321 strcpy(outfn, sim_offload->hdf5_out);
322 outfn[strlen(outfn)-3] = '\0';
323 sprintf(filename, "%s_%s.stdout", outfn, sim_offload->qid);
324 sim_monitor(filename, &pq.n, &pq.finished);
325 }
326 }
327 }
328#endif
329 }
330
331 /**************************************************************************/
332 /* 7. Simulation data is deallocated. */
333 /**************************************************************************/
334 free(pq.p);
335 diag_free(&sim.diag_data);
336
337 print_out(VERBOSE_NORMAL, "Simulation complete.\n");
338}
339
355
365void sim_init(sim_data* sim, sim_offload_data* offload_data) {
366 sim->sim_mode = offload_data->sim_mode;
367 sim->enable_ada = offload_data->enable_ada;
368 sim->record_mode = offload_data->record_mode;
369
370 sim->fix_usrdef_use = offload_data->fix_usrdef_use;
371 sim->fix_usrdef_val = offload_data->fix_usrdef_val;
372 sim->fix_gyrodef_nstep = offload_data->fix_gyrodef_nstep;
373
374 sim->ada_tol_orbfol = offload_data->ada_tol_orbfol;
375 sim->ada_tol_clmbcol = offload_data->ada_tol_clmbcol;
376 sim->ada_max_drho = offload_data->ada_max_drho;
377 sim->ada_max_dphi = offload_data->ada_max_dphi;
378
379 sim->enable_orbfol = offload_data->enable_orbfol;
380 sim->enable_clmbcol = offload_data->enable_clmbcol;
381 sim->enable_mhd = offload_data->enable_mhd;
382 sim->enable_atomic = offload_data->enable_atomic;
383 sim->disable_gctransform = offload_data->disable_gctransform;
384 sim->disable_energyccoll = offload_data->disable_energyccoll;
385 sim->disable_pitchccoll = offload_data->disable_pitchccoll;
386 sim->disable_gcdiffccoll = offload_data->disable_gcdiffccoll;
387 sim->reverse_time = offload_data->reverse_time;
388
389 sim->endcond_active = offload_data->endcond_active;
390 sim->endcond_lim_simtime = offload_data->endcond_lim_simtime;
391 sim->endcond_max_mileage = offload_data->endcond_max_mileage;
392 sim->endcond_max_cputime = offload_data->endcond_max_cputime;
393 sim->endcond_min_rho = offload_data->endcond_min_rho;
394 sim->endcond_max_rho = offload_data->endcond_max_rho;
395 sim->endcond_min_ekin = offload_data->endcond_min_ekin;
396 sim->endcond_min_thermal = offload_data->endcond_min_thermal;
397 sim->endcond_max_tororb = offload_data->endcond_max_tororb;
398 sim->endcond_max_polorb = offload_data->endcond_max_polorb;
399 sim->endcond_torandpol = offload_data->endcond_torandpol;
400
403
404}
405
422void sim_monitor(char* filename, volatile int* n, volatile int* finished) {
423 /* Open a file for writing simulation progress */
424 FILE *f = fopen(filename, "w");
425 if (f == NULL) {
427 "Warning. %s could not be opened for progress updates.\n",
428 filename);
429 return;
430 }
431
432 real time_sim_started = A5_WTIME;
433 int stopflag = 1; /* Ensures progress is written one last time at 100% */
434 int n_temp, finished_temp; /* Use these to store volatile variables so that
435 their value does not change during one loop */
436 while(stopflag) {
437 n_temp = *n;
438 finished_temp = *finished;
439 real fracprog = ((real) finished_temp)/n_temp;
440 real timespent = (A5_WTIME)-time_sim_started;
441
442 if(n_temp == finished_temp) {
443 stopflag = 0;
444 }
445
446 if(fracprog == 0) {
447 fprintf(f, "No marker has finished simulation yet. "
448 "Time spent: %.2f h\n", timespent/3600);
449 }
450 else {
451 fprintf(f, "Progress: %d/%d, %.2f %%. Time spent: %.2f h, "
452 "estimated time to finish: %.2f h\n", finished_temp, n_temp,
453 100*fracprog, timespent/3600, (1/fracprog-1)*timespent/3600);
454 }
455 fflush(f);
456 //sleep(A5_PRINTPROGRESSINTERVAL);
457 }
458
459 fprintf(f, "Simulation finished.\n");
460 fclose(f);
461}
int B_field_init(B_field_data *Bdata, B_field_offload_data *offload_data, real *offload_array)
Initialize magnetic field data struct on target.
Definition B_field.c:143
int E_field_init(E_field_data *Edata, E_field_offload_data *offload_data, real *offload_array)
Initialize electric field data struct on target.
Definition E_field.c:116
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
void asigma_extrapolate(int extrapolate)
Toggle extrapolation when evaluating cross sections.
Definition asigma.c:45
int asigma_init(asigma_data *asigma_data, asigma_offload_data *offload_data, real *offload_array)
Initializes atomic reaction data struct on target.
Definition asigma.c:126
Header file for asigma.c.
void boozer_init(boozer_data *boozerdata, boozer_offload_data *offload_data, real *offload_array)
Initialize boozer data struct on target.
Definition boozer.c:108
void simulate_copy_to_gpu(sim_data *sim)
Copy data from CPU to GPU.
Definition copytogpu.c:14
Header file for copytogpu.c.
void diag_init(diag_data *data, diag_offload_data *offload_data, real *offload_array)
Initializes diagnostics from offload data.
Definition diag.c:152
void diag_free(diag_data *data)
Free diagnostics data.
Definition diag.c:204
Header file for endcond.c.
@ endcond_wall
Definition endcond.h:22
@ endcond_hybrid
Definition endcond.h:28
void gctransform_setorder(int order)
Set the order of the transformation.
Definition gctransform.c:62
Header file for gctransform.c.
void mccc_init(mccc_data *mdata, int include_energy, int include_pitch, int include_gcdiff)
Set collision operator data.
Definition mccc.c:17
Header file for mccc package.
int mhd_init(mhd_data *mhddata, mhd_offload_data *offload_data, real *offload_array)
Initialize MHD data struct on target.
Definition mhd.c:121
int neutral_init(neutral_data *ndata, neutral_offload_data *offload_data, real *offload_array)
Initialize neutral data struct on target.
Definition neutral.c:106
void offload_unpack(offload_package *o, real *offload_array, size_t pack_length, int *int_offload_array, size_t int_pack_length, real **ptr, int **intptr)
Unpack offload array from the package.
Definition offload.c:137
Header file for offload.h.
Header file for particle.c.
int plasma_init(plasma_data *pls_data, plasma_offload_data *offload_data, real *offload_array)
Initialize plasma data struct on target.
Definition plasma.c:135
Header file for plasma.c.
Macros for printing console output.
#define print_out(v,...)
Print to standard output.
Definition print.h:31
@ VERBOSE_NORMAL
Definition print.h:18
@ VERBOSE_DEBUG
Definition print.h:17
#define print_err(...)
Print to standard error.
Definition print.h:42
Header file for random.c.
#define random_init(data, seed)
Definition random.h:94
void simulate_init_offload(sim_offload_data *sim)
Initializes simulation settings.
Definition simulate.c:349
void simulate(int id, int n_particles, particle_state *p, sim_offload_data *sim_offload, offload_package *offload_data, real *offload_array, int *int_offload_array, real *diag_offload_array)
Execute marker simulation.
Definition simulate.c:80
void sim_init(sim_data *sim, sim_offload_data *offload_data)
Initialize simulation data struct on target.
Definition simulate.c:365
void sim_monitor(char *filename, volatile int *n, volatile int *finished)
Monitor simulation progress.
Definition simulate.c:422
Header file for simulate.c.
@ simulate_mode_fo
Definition simulate.h:34
@ simulate_mode_ml
Definition simulate.h:45
@ simulate_mode_gc
Definition simulate.h:37
@ simulate_mode_hybrid
Definition simulate.h:42
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 simulate_gc_adaptive(particle_queue *pq, sim_data *sim)
Simulates guiding centers using adaptive time-step.
Header file for simulate_gc_adaptive.c.
void simulate_gc_fixed(particle_queue *pq, sim_data *sim)
Simulates guiding centers using fixed time-step.
Header file for simulate_gc_fixed.c.
void simulate_ml_adaptive(particle_queue *pq, sim_data *sim)
Simulates magnetic field-lines using adaptive time-step.
Header file for simulate_ml_adaptive.c.
int offload_array_length
Definition asigma.h:57
int offload_array_length
Definition boozer.h:23
int diagtrcof_collect
Definition diag.h:28
int diagorb_collect
Definition diag.h:22
int offload_array_length
Definition mhd.h:45
Struct to keep track of the offload array length and unpack status.
Definition offload.h:11
size_t unpack_pos
Definition offload.h:14
size_t int_unpack_pos
Definition offload.h:18
Marker queue.
Definition particle.h:154
particle_state ** p
Definition particle.h:156
volatile int next
Definition particle.h:158
volatile int finished
Definition particle.h:159
General representation of a marker.
Definition particle.h:40
integer walltile
Definition particle.h:65
integer endcond
Definition particle.h:64
int offload_array_length
Definition plasma.h:45
Simulation data struct.
Definition simulate.h:154
int enable_orbfol
Definition simulate.h:194
real endcond_min_ekin
Definition simulate.h:215
int endcond_torandpol
Definition simulate.h:220
real endcond_max_rho
Definition simulate.h:214
int record_mode
Definition simulate.h:175
int sim_mode
Definition simulate.h:173
int disable_energyccoll
Definition simulate.h:200
real ada_max_drho
Definition simulate.h:188
real ada_tol_clmbcol
Definition simulate.h:186
plasma_data plasma_data
Definition simulate.h:158
mhd_data mhd_data
Definition simulate.h:162
real endcond_max_tororb
Definition simulate.h:218
int enable_atomic
Definition simulate.h:197
int disable_gcdiffccoll
Definition simulate.h:204
real endcond_min_thermal
Definition simulate.h:216
real endcond_max_mileage
Definition simulate.h:211
real fix_usrdef_val
Definition simulate.h:179
E_field_data E_data
Definition simulate.h:157
int disable_pitchccoll
Definition simulate.h:202
int enable_mhd
Definition simulate.h:196
int endcond_active
Definition simulate.h:209
int fix_usrdef_use
Definition simulate.h:178
mccc_data mccc_data
Definition simulate.h:169
real endcond_max_polorb
Definition simulate.h:219
random_data random_data
Definition simulate.h:168
neutral_data neutral_data
Definition simulate.h:159
int fix_gyrodef_nstep
Definition simulate.h:180
real endcond_max_cputime
Definition simulate.h:212
boozer_data boozer_data
Definition simulate.h:161
real endcond_min_rho
Definition simulate.h:213
real endcond_lim_simtime
Definition simulate.h:210
int enable_ada
Definition simulate.h:174
B_field_data B_data
Definition simulate.h:156
wall_data wall_data
Definition simulate.h:160
int reverse_time
Definition simulate.h:206
real ada_max_dphi
Definition simulate.h:190
asigma_data asigma_data
Definition simulate.h:163
int enable_clmbcol
Definition simulate.h:195
int disable_gctransform
Definition simulate.h:198
real ada_tol_orbfol
Definition simulate.h:184
diag_data diag_data
Definition simulate.h:165
Simulation offload struct.
Definition simulate.h:55
int disable_gcdiffccoll
Definition simulate.h:101
int fix_gyrodef_nstep
Definition simulate.h:76
B_field_offload_data B_offload_data
Definition simulate.h:57
real endcond_min_ekin
Definition simulate.h:112
real endcond_max_mileage
Definition simulate.h:108
plasma_offload_data plasma_offload_data
Definition simulate.h:59
char qid[256]
Definition simulate.h:122
int disable_pitchccoll
Definition simulate.h:99
real ada_tol_clmbcol
Definition simulate.h:82
neutral_offload_data neutral_offload_data
Definition simulate.h:60
mhd_offload_data mhd_offload_data
Definition simulate.h:63
int disable_gctransform
Definition simulate.h:95
real endcond_max_tororb
Definition simulate.h:115
asigma_offload_data asigma_offload_data
Definition simulate.h:64
boozer_offload_data boozer_offload_data
Definition simulate.h:62
wall_offload_data wall_offload_data
Definition simulate.h:61
real endcond_max_polorb
Definition simulate.h:116
real endcond_min_thermal
Definition simulate.h:113
real endcond_lim_simtime
Definition simulate.h:107
real ada_tol_orbfol
Definition simulate.h:80
E_field_offload_data E_offload_data
Definition simulate.h:58
real fix_usrdef_val
Definition simulate.h:75
char hdf5_out[256]
Definition simulate.h:121
int disable_energyccoll
Definition simulate.h:97
real endcond_max_cputime
Definition simulate.h:109
diag_offload_data diag_offload_data
Definition simulate.h:66
int offload_array_length
Definition wall.h:42
int int_offload_array_length
Definition wall.h:43
int wall_hit_wall(real r1, real phi1, real z1, real r2, real phi2, real z2, wall_data *w, real *w_coll)
Check if a given directed line segment intersects the wall.
Definition wall.c:163
int wall_init(wall_data *w, wall_offload_data *offload_data, real *offload_array, int *int_offload_array)
Initialize wall data struct on target.
Definition wall.c:119