ASCOT5
Loading...
Searching...
No Matches
ascot5_main.c
Go to the documentation of this file.
1
54#include <getopt.h>
55#include <math.h>
56#include <omp.h>
57#include <stdlib.h>
58#include <string.h>
59#include <time.h>
60#include "ascot5.h"
61#include "consts.h"
62#include "math.h"
63#include "wall.h"
64#include "diag.h"
65#include "B_field.h"
66#include "plasma.h"
67#include "print.h"
68#include "simulate.h"
69#include "particle.h"
70#include "endcond.h"
71#include "hdf5_interface.h"
72#include "offload.h"
73#include "gitver.h"
74#include "mpi_interface.h"
75
76#include "ascot5_main.h"
77
78#ifdef TRAP_FPE
79#include <fenv.h>
80#endif
81
82int read_arguments(int argc, char** argv, sim_offload_data* sim);
83
100int main(int argc, char** argv) {
101
102#ifdef TRAP_FPE
103 /* This will raise floating point exceptions */
104 feenableexcept(FE_DIVBYZERO| FE_INVALID | FE_OVERFLOW);
105 /*
106 * If you are hunting a specific exception, you can disable the exceptions
107 * in other parts of the code by surrounding it with: */
108 /*
109 * fedisableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
110 * --- your code here ---
111 * feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
112 *
113 * */
114#endif
115
116 /* Read and parse command line arguments */
118 if( read_arguments(argc, argv, &sim) ) {
119 abort();
120 return 1;
121 }
122
123 if(sim.mpi_size > 0) {
124 /* This is a pseudo-mpi run, where rank and size were set on the command
125 * line. Only set root equal to rank since there are no other processes
126 */
127 sim.mpi_root = sim.mpi_rank;
128 }
129 else {
130 /* Init MPI if used, or run serial */
131 int mpi_rank, mpi_size, mpi_root;
132 mpi_interface_init(argc, argv, &mpi_rank, &mpi_size, &mpi_root);
133 sim.mpi_rank = mpi_rank;
134 sim.mpi_size = mpi_size;
135 sim.mpi_root = mpi_root;
136 }
137
138 print_out0(VERBOSE_MINIMAL, sim.mpi_rank, sim.mpi_root, "ASCOT5_MAIN\n");
140 "Tag %s\nBranch %s\n\n", GIT_VERSION, GIT_BRANCH);
141 print_out(VERBOSE_NORMAL, "Initialized MPI, rank %d, size %d.\n",
142 sim.mpi_rank, sim.mpi_size);
143
144 /* Total number of markers to be simulated */
145 int n_tot;
146 /* Marker input struct */
148
149 /* Offload data arrays that are allocated when input is read */
150 real* B_offload_array;
151 real* E_offload_array;
152 real* plasma_offload_array;
153 real* neutral_offload_array;
154 real* wall_offload_array;
155 int* wall_int_offload_array;
156 real* boozer_offload_array;
157 real* mhd_offload_array;
158 real* asigma_offload_array;
159 real* diag_offload_array;
160
161 /* Read input from the HDF5 file */
168 &B_offload_array, &E_offload_array,
169 &plasma_offload_array, &neutral_offload_array,
170 &wall_offload_array, &wall_int_offload_array,
171 &boozer_offload_array, &mhd_offload_array,
172 &asigma_offload_array, NULL,
173 &p, &n_tot) ) {
175 "\nInput reading or initializing failed.\n"
176 "See stderr for details.\n");
178 abort();
179 return 1;
180 };
181
182 /* Initialize marker states array ps and free marker input p */
183 int n_proc; /* Number of markers allocated for this MPI process */
184 particle_state* ps;
185 if( prepare_markers(&sim, n_tot, p, &ps, &n_proc, B_offload_array) ) {
186 goto CLEANUP_FAILURE;
187 }
188
189 /* Combine input offload arrays to one */
190 offload_package offload_data;
191 real* offload_array;
192 int* int_offload_array;
194 &sim, &offload_data, &B_offload_array, &E_offload_array,
195 &plasma_offload_array, &neutral_offload_array, &wall_offload_array,
196 &wall_int_offload_array, &boozer_offload_array, &mhd_offload_array,
197 &asigma_offload_array, &offload_array, &int_offload_array) ) {
198 goto CLEANUP_FAILURE;
199 }
200
201 /* Initialize diagnostics offload data */
202 diag_init_offload(&sim.diag_offload_data, &diag_offload_array, n_tot);
204 "Initialized diagnostics, %.1f MB.\n",
206 / (1024.0*1024.0));
207
208 /* Write run group and inistate */
209 char qid[11];
211 if( write_rungroup(&sim, ps, n_tot, qid) ) {
212 goto CLEANUP_FAILURE;
213 }
214
215 /* Actual simulation is done here; the results are stored in
216 * diag_offload_array and pout contains end states from all processes.
217 * n_gathered is the number of markers in the output array, which is n_tot
218 * for most cases except when the simulation is run in condor-like manner,
219 * in which case it is equal to n_proc. */
220 int n_gathered;
221 particle_state* pout;
223 &sim, n_tot, n_proc, ps, &offload_data, offload_array,
224 int_offload_array, &n_gathered, &pout, diag_offload_array);
225
226 /* Free input data */
227 offload_free_offload(&offload_data, &offload_array, &int_offload_array);
228
229 /* Write output and clean */
230 if( write_output(&sim, pout, n_gathered, diag_offload_array) ) {
231 goto CLEANUP_FAILURE;
232 }
233 diag_free_offload(&sim.diag_offload_data, &diag_offload_array);
234
235 /* Display marker summary and free marker arrays */
236 if(sim.mpi_rank == sim.mpi_root) {
237 print_marker_summary(pout, n_tot);
238 }
239 free(pout);
240
241 print_out0(VERBOSE_MINIMAL, sim.mpi_rank, sim.mpi_root, "\nDone.\n");
243 return 0;
244
245/* GOTO this block to free resources in case simulation crashes */
246CLEANUP_FAILURE:
248 free(p);
249 free(ps);
250 free(pout);
251 free(offload_array);
252 free(int_offload_array);
253 free(diag_offload_array);
254 abort();
255 return 1;
256}
257
279 sim_offload_data* sim, int n_tot, input_particle* pin,
280 particle_state** pout, int* n_proc, real* B_offload_array) {
281
282 /* This sets up GC transformation order etc. so it must be called before
283 * initializing markers. */
285
286 /* Choose which markers are used in this MPI process. Simply put, markers
287 * are divided into mpi_size sequential blocks and the mpi_rank:th block
288 * is chosen for this simulation. */
289 int start_index;
290 mpi_my_particles(&start_index, n_proc, n_tot, sim->mpi_rank, sim->mpi_size);
291 pin += start_index;
292
293 /* Set up particlestates on host, needs magnetic field evaluation */
295 "\nInitializing marker states.\n");
296 B_field_data Bdata;
297 B_field_init(&Bdata, &sim->B_offload_data, B_offload_array);
298
299 *pout = (particle_state*) malloc(*n_proc * sizeof(particle_state));
300 for(int i = 0; i < *n_proc; i++) {
301 particle_input_to_state(&(pin[i]), &((*pout)[i]), &Bdata);
302 }
303
305 "Estimated memory usage %.1f MB.\n",
306 (sizeof(real) * (*n_proc)) / (1024.0*1024.0));
308 "Marker states initialized.\n");
309
310 /* We can now free the input markers */
311 free(pin-start_index);
312
313 return 0;
314}
315
316
342 sim_offload_data* sim, offload_package* offload_data,
343 real** B_offload_array, real** E_offload_array, real** plasma_offload_array,
344 real** neutral_offload_array, real** wall_offload_array,
345 int** wall_int_offload_array, real** boozer_offload_array,
346 real** mhd_offload_array, real** asigma_offload_array, real** offload_array,
347 int** int_offload_array) {
348
349 /* Pack offload data into single array and free individual offload arrays */
350 offload_init_offload(offload_data, offload_array, int_offload_array);
351
352 offload_pack(offload_data, offload_array, *B_offload_array,
354 int_offload_array, NULL, 0);
355 B_field_free_offload(&sim->B_offload_data, B_offload_array);
356
357 offload_pack(offload_data, offload_array, *E_offload_array,
359 int_offload_array, NULL, 0);
360 E_field_free_offload(&sim->E_offload_data, E_offload_array);
361
362 offload_pack(offload_data, offload_array, *plasma_offload_array,
364 int_offload_array, NULL, 0);
365 plasma_free_offload(&sim->plasma_offload_data, plasma_offload_array);
366
367 offload_pack(offload_data, offload_array, *neutral_offload_array,
369 int_offload_array, NULL, 0);
370 neutral_free_offload(&sim->neutral_offload_data, neutral_offload_array);
371
372 offload_pack(offload_data, offload_array, *wall_offload_array,
374 int_offload_array, *wall_int_offload_array,
376 wall_free_offload(&sim->wall_offload_data, wall_offload_array,
377 wall_int_offload_array);
378
379 offload_pack(offload_data, offload_array, *boozer_offload_array,
381 int_offload_array, NULL, 0);
382 boozer_free_offload(&sim->boozer_offload_data, boozer_offload_array);
383
384 offload_pack(offload_data, offload_array, *mhd_offload_array,
386 int_offload_array, NULL, 0);
387 mhd_free_offload(&sim->mhd_offload_data, mhd_offload_array);
388
389 offload_pack(offload_data, offload_array, *asigma_offload_array,
391 int_offload_array, NULL, 0);
392 asigma_free_offload(&sim->asigma_offload_data, asigma_offload_array);
393
394 return 0;
395}
396
397
409 char* qid) {
410
411 if(sim->mpi_rank == sim->mpi_root) {
412 /* Initialize results group in the output file */
414 "\nPreparing output.\n");
415 if( hdf5_interface_init_results(sim, qid, "run") ) {
417 "\nInitializing output failed.\n"
418 "See stderr for details.\n");
419 /* Free offload data and terminate */
420 return 1;
421 }
422 strcpy(sim->qid, qid);
423 }
424
425 /* Gather particle states so that we can write inistate */
426 int n_gather;
427 particle_state* ps_gather;
428 mpi_gather_particlestate(ps, &ps_gather, &n_gather, n_tot,
429 sim->mpi_rank, sim->mpi_size, sim->mpi_root);
430
431 if(sim->mpi_rank == sim->mpi_root) {
432 /* Write inistate */
434 sim->hdf5_out, "inistate", n_gather, ps_gather)) {
436 "\n"
437 "Writing inistate failed.\n"
438 "See stderr for details.\n"
439 "\n");
440 /* Free offload data and terminate */
441 return 1;
442 }
444 "\nInistate written.\n");
445 }
446 free(ps_gather);
447
448 return 0;
449}
450
451
470 sim_offload_data* sim, int n_tot, int n_proc, particle_state* pin,
471 offload_package* offload_data, real* offload_array, int* int_offload_array,
472 int* n_gather, particle_state** pout, real* diag_offload_array) {
473
474 /* Empty message buffer before proceeding to actual simulation */
475 fflush(stdout);
476
477 /* Actual marker simulation happens here. */
478 real t_sim_start = omp_get_wtime();
479 simulate(0, n_proc, pin, sim, offload_data,
480 offload_array, int_offload_array, diag_offload_array);
481
483 real t_sim_end = omp_get_wtime();
485 "Simulation finished in %lf s\n", t_sim_end-t_sim_start);
486
487 /* Gather output data */
488 mpi_gather_particlestate(pin, pout, n_gather, n_tot, sim->mpi_rank,
489 sim->mpi_size, sim->mpi_root);
490 free(pin);
491
492 mpi_gather_diag(&sim->diag_offload_data, diag_offload_array, n_tot,
493 sim->mpi_rank, sim->mpi_size, sim->mpi_root);
494 return 0;
495}
496
497
509 real* diag_offload_array){
510
511 if(sim->mpi_rank == sim->mpi_root) {
512 /* Write endstate */
514 sim->hdf5_out, "endstate", n_tot, ps)) {
516 "\nWriting endstate failed.\n"
517 "See stderr for details.\n");
518 return 1;
519 }
521 "Endstate written.\n");
522 }
523
524 /* Combine diagnostic data and write it to HDF5 file */
526 "\nCombining and writing diagnostics.\n");
527 int err_writediag = 0;
528
529 if(sim->mpi_rank == sim->mpi_root) {
530 err_writediag = hdf5_interface_write_diagnostics(sim,
531 diag_offload_array, sim->hdf5_out);
532 }
533 if(err_writediag) {
535 "\nWriting diagnostics failed.\n"
536 "See stderr for details.\n");
537 return 1;
538 }
539 else {
541 "Diagnostics written.\n");
542 }
543
544 return 0;
545}
546
547
572int read_arguments(int argc, char** argv, sim_offload_data* sim) {
573 struct option longopts[] = {
574 {"in", required_argument, 0, 1},
575 {"out", required_argument, 0, 2},
576 {"mpi_size", required_argument, 0, 3},
577 {"mpi_rank", required_argument, 0, 4},
578 {"d", required_argument, 0, 5},
579 {"options", required_argument, 0, 6},
580 {"bfield", required_argument, 0, 7},
581 {"efield", required_argument, 0, 8},
582 {"marker", required_argument, 0, 9},
583 {"wall", required_argument, 0, 10},
584 {"plasma", required_argument, 0, 11},
585 {"neutral", required_argument, 0, 12},
586 {"boozer", required_argument, 0, 13},
587 {"mhd", required_argument, 0, 14},
588 {"asigma", required_argument, 0, 15},
589 {0, 0, 0, 0}
590 };
591
592 /* Initialize default values */
593 sim->hdf5_in[0] = '\0';
594 sim->hdf5_out[0] = '\0';
595 sim->mpi_rank = 0;
596 sim->mpi_size = 0;
597 strcpy(sim->description, "No description.");
598 sim->qid_options[0] = '\0';
599 sim->qid_bfield[0] = '\0';
600 sim->qid_efield[0] = '\0';
601 sim->qid_marker[0] = '\0';
602 sim->qid_wall[0] = '\0';
603 sim->qid_plasma[0] = '\0';
604 sim->qid_neutral[0] = '\0';
605 sim->qid_boozer[0] = '\0';
606 sim->qid_mhd[0] = '\0';
607 sim->qid_asigma[0] = '\0';
608 sim->qid_nbi[0] = '\0';
609
610 /* Read user input */
611 int c;
612 int slen; /* String length */
613 while((c = getopt_long(argc, argv, "", longopts, NULL)) != -1) {
614 switch(c) {
615 case 1:
616 /* The .hdf5 filename can be specified with or without the
617 * trailing .h5 */
618 slen = strlen(optarg);
619 if ( slen > 3 && !strcmp(optarg+slen-3, ".h5") ) {
620 strcpy(sim->hdf5_in, optarg);
621 (sim->hdf5_in)[slen-3]='\0';
622 }
623 else {
624 strcpy(sim->hdf5_in, optarg);
625 }
626 break;
627 case 2:
628 /* The .hdf5 filename can be specified with or without the
629 * trailing .h5 */
630 slen = strlen(optarg);
631 if ( slen > 3 && !strcmp(optarg+slen-3, ".h5") ) {
632 strcpy(sim->hdf5_out, optarg);
633 (sim->hdf5_out)[slen-3]='\0';
634 }
635 else {
636 strcpy(sim->hdf5_out, optarg);
637 }
638 break;
639 case 3:
640 sim->mpi_size = atoi(optarg);
641 break;
642 case 4:
643 sim->mpi_rank = atoi(optarg);
644 break;
645 case 5:
646 strcpy(sim->description, optarg);
647 break;
648 case 6:
649 strcpy(sim->qid_options, optarg);
650 break;
651 case 7:
652 strcpy(sim->qid_bfield, optarg);
653 break;
654 case 8:
655 strcpy(sim->qid_efield, optarg);
656 break;
657 case 9:
658 strcpy(sim->qid_marker, optarg);
659 break;
660 case 10:
661 strcpy(sim->qid_wall, optarg);
662 break;
663 case 11:
664 strcpy(sim->qid_plasma, optarg);
665 break;
666 case 12:
667 strcpy(sim->qid_neutral, optarg);
668 break;
669 case 13:
670 strcpy(sim->qid_boozer, optarg);
671 break;
672 case 14:
673 strcpy(sim->qid_mhd, optarg);
674 break;
675 case 15:
676 strcpy(sim->qid_asigma, optarg);
677 break;
678 default:
679 // Unregonizable argument(s). Tell user how to run ascot5_main
681 "\nUnrecognized argument. The valid arguments are:\n");
683 "--in input file (default: ascot.h5)\n");
685 "--out output file (default: same as input)\n");
687 "--mpi_size number of independent processes\n");
689 "--mpi_rank rank of independent process\n");
691 "--d run description maximum of 250 characters\n");
692 return 1;
693 }
694 }
695
696 /* Default value for input file is ascot.h5, and for output same as input
697 * file. Adujust hdf5_in and hdf5_out accordingly. For output file, we don't
698 * add the .h5 extension here. */
699 if(sim->hdf5_in[0] == '\0' && sim->hdf5_out[0] == '\0') {
700 /* No input, use default values for both */
701 strcpy(sim->hdf5_in, "ascot.h5");
702 strcpy(sim->hdf5_out, "ascot.h5");
703 }
704 else if(sim->hdf5_in[0] == '\0' && sim->hdf5_out[0] != '\0') {
705 /* Output file is given but the input file is not */
706 strcpy(sim->hdf5_in, "ascot.h5");
707 strcat(sim->hdf5_out, ".h5");
708 }
709 else if(sim->hdf5_in[0] != '\0' && sim->hdf5_out[0] == '\0') {
710 /* Input file is given but the output is not */
711 strcat(sim->hdf5_in, ".h5");
712 strcpy(sim->hdf5_out, sim->hdf5_in);
713 }
714 else {
715 /* Both input and output files are given */
716 strcat(sim->hdf5_in, ".h5");
717 strcat(sim->hdf5_out, ".h5");
718 }
719 return 0;
720}
721
737
738 print_out(VERBOSE_MINIMAL, "\nSummary of results:\n");
739
740 /* Temporary arrays that are needed to store unique end conditions and
741 * errors. We can have at most n_tot different values. */
742 int* temp = (int*)malloc(n_tot*sizeof(int));
743 int* unique = (int*)malloc(n_tot*sizeof(int));
744 int* count = (int*)malloc((n_tot+1)*sizeof(int));
745
746 /* First we find out what the end conditions are */
747 for(int i=0; i<n_tot; i++) {
748 temp[i] = ps[i].endcond;
749 }
750 math_uniquecount(temp, unique, count, n_tot);
751 count[n_tot] = 0;/* This ensures the following while loops are terminated.*/
752
753 /* Print the end conditions, if marker has multiple end conditions, separate
754 * those with "and". */
755 int i = 0;
756 while(count[i] > 0) {
757 /* Initialize */
758 int endconds[32];
759 for(int j=0; j<32;j++) {
760 endconds[j] = 0;
761 }
762 char endcondstr[256];
763 endcondstr[0] = '\0';
764
765 /* Represent all end conditions with a single string and print it */
766 int j = 0;
767 endcond_parse(unique[i], endconds);
768 while(endconds[j]) {
769 if(j>0) {
770 strcat(endcondstr, " and ");
771 }
772 char temp[256];
773 endcond_parse2str(endconds[j], temp);
774 strcat(endcondstr, temp);
775 j++;
776 }
777 if(j == 0) {
778 sprintf(endcondstr, "Aborted");
779 }
780 print_out(VERBOSE_MINIMAL, "%9d markers had end condition %s\n",
781 count[i], endcondstr);
782 i++;
783 }
784
785 /* Empty line between end conditions and errors */
787
788 /* Find all errors */
789 for(int i=0; i<n_tot; i++) {
790 temp[i] = (int)(ps[i].err);
791 }
792 math_uniquecount(temp, unique, count, n_tot);
793
794 /* Go through each unique error and represent is a string */
795 i = 0;
796 while(count[i] > 0) {
797 if(unique[i] == 0) {
798 /* Value 0 indicates no error occurred so skip that */
799 i++;
800 continue;
801 }
802 char msg[256];
803 char line[256];
804 char file[256];
805 error_parse2str(unique[i], msg, line, file);
807 "%9d markers were aborted with an error message:\n"
808 " %s\n"
809 " at line %s in %s\n",
810 count[i], msg, line, file);
811 i++;
812 }
813
814 /* If count[0] equals to number of markers and their error field is zero,
815 * we have no markers that were aborted. */
816 if(count[0] == n_tot && unique[0] == 0) {
818 " No markers were aborted.\n");
819 }
820
821 /* Free temporary arrays */
822 free(temp);
823 free(unique);
824 free(count);
825}
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
void B_field_free_offload(B_field_offload_data *offload_data, real **offload_array)
Free offload array and reset parameters.
Definition B_field.c:105
Header file for B_field.c.
void E_field_free_offload(E_field_offload_data *offload_data, real **offload_array)
Free offload array and reset parameters.
Definition E_field.c:85
Main header file for ASCOT5.
double real
Definition ascot5.h:85
int write_rungroup(sim_offload_data *sim, particle_state *ps, int n_tot, char *qid)
Create and store run group and marker inistate.
int pack_offload_array(sim_offload_data *sim, offload_package *offload_data, real **B_offload_array, real **E_offload_array, real **plasma_offload_array, real **neutral_offload_array, real **wall_offload_array, int **wall_int_offload_array, real **boozer_offload_array, real **mhd_offload_array, real **asigma_offload_array, real **offload_array, int **int_offload_array)
Prepare offload array to be offloaded.
int prepare_markers(sim_offload_data *sim, int n_tot, input_particle *pin, particle_state **pout, int *n_proc, real *B_offload_array)
Prepare markers for offload.
int main(int argc, char **argv)
Main function for ascot5_main.
void print_marker_summary(particle_state *ps, int n_tot)
Writes a summary of what happened to the markers during simulation.
int read_arguments(int argc, char **argv, sim_offload_data *sim)
Read command line arguments and modify sim struct accordingly.
int offload_and_simulate(sim_offload_data *sim, int n_tot, int n_proc, particle_state *pin, offload_package *offload_data, real *offload_array, int *int_offload_array, int *n_gather, particle_state **pout, real *diag_offload_array)
Offload data to target, carry out the simulation, and return to host.
int write_output(sim_offload_data *sim, particle_state *ps, int n_tot, real *diag_offload_array)
Store simulation output data.
Functions to execute main program externally.
void asigma_free_offload(asigma_offload_data *offload_data, real **offload_array)
Free offload array and reset parameters.
Definition asigma.c:104
void boozer_free_offload(boozer_offload_data *offload_data, real **offload_array)
Free offload array.
Definition boozer.c:154
Header file containing physical and mathematical constants.
void diag_free_offload(diag_offload_data *data, real **offload_array)
Frees the offload array.
Definition diag.c:140
int diag_init_offload(diag_offload_data *data, real **offload_array, int Nmrk)
Initializes offload array from offload data.
Definition diag.c:40
Header file for diag.c.
void endcond_parse(int endcond, int *endconds)
Split endcond to an array of end conditions.
Definition endcond.c:538
void endcond_parse2str(int endcond, char *str)
Represent end condition in human-readable format.
Definition endcond.c:564
Header file for endcond.c.
void error_parse2str(a5err err, char *msg, char *line, char *file)
Convert error flag in string format.
Definition error.c:62
int hdf5_interface_init_results(sim_offload_data *sim, char *qid, char *run)
Initialize run group.
int hdf5_interface_read_input(sim_offload_data *sim, int input_active, real **B_offload_array, real **E_offload_array, real **plasma_offload_array, real **neutral_offload_array, real **wall_offload_array, int **wall_int_offload_array, real **boozer_offload_array, real **mhd_offload_array, real **asigma_offload_array, real **nbi_offload_array, input_particle **p, int *n_markers)
Read and initialize input data.
int hdf5_interface_write_state(char *fn, char *state, integer n, particle_state *p)
Write marker state to HDF5 output.
int hdf5_interface_write_diagnostics(sim_offload_data *sim, real *diag_offload_array, char *out)
Write diagnostics to HDF5 output.
void hdf5_generate_qid(char *qid)
Generate an identification number for a run.
Header file for hdf5_interface.c.
@ hdf5_input_marker
@ hdf5_input_plasma
@ hdf5_input_options
@ hdf5_input_wall
@ hdf5_input_neutral
@ hdf5_input_bfield
@ hdf5_input_efield
@ hdf5_input_boozer
@ hdf5_input_mhd
@ hdf5_input_asigma
void math_uniquecount(int *in, int *unique, int *count, int n)
Find unique numbers and their frequency in given array.
Definition math.c:276
Header file for math.c.
void mhd_free_offload(mhd_offload_data *offload_data, real **offload_array)
Free offload array and reset parameters.
Definition mhd.c:90
void mpi_my_particles(int *start_index, int *n, int n_tot, int mpi_rank, int mpi_size)
Divide markers to mpi processes.
void mpi_gather_diag(diag_offload_data *data, real *offload_array, int ntotal, int mpi_rank, int mpi_size, int mpi_root)
Gather all diagnostics to the root process.
void mpi_interface_finalize()
Finalize MPI.
void mpi_interface_init(int argc, char **argv, int *mpi_rank, int *mpi_size, int *mpi_root)
Initialize MPI.
void mpi_interface_barrier()
Wait until all processes have reached this routine.
void mpi_gather_particlestate(particle_state *ps, particle_state **ps_gather, int *n_gather, int n_tot, int mpi_rank, int mpi_size, int mpi_root)
Gather all particle states to the root process.
Header file for mpi_interface.c.
void neutral_free_offload(neutral_offload_data *offload_data, real **offload_array)
Free offload array and reset parameters.
Definition neutral.c:81
void offload_free_offload(offload_package *o, real **offload_array, int **int_offload_array)
Free offload array and set offload_package to clean state.
Definition offload.c:49
void offload_init_offload(offload_package *o, real **offload_array, int **int_offload_array)
Initialize offload package.
Definition offload.c:31
void offload_pack(offload_package *o, real **offload_array, real *pack_array, size_t pack_length, int **int_offload_array, int *int_pack_array, size_t int_pack_length)
Pack an offload array to package array.
Definition offload.c:78
Header file for offload.h.
void particle_input_to_state(input_particle *p, particle_state *ps, B_field_data *Bdata)
Converts input marker to a marker state.
Definition particle.c:550
Header file for particle.c.
void plasma_free_offload(plasma_offload_data *offload_data, real **offload_array)
Free offload array and reset parameters.
Definition plasma.c:102
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_IO
Definition print.h:20
@ VERBOSE_MINIMAL
Definition print.h:19
#define print_out0(v, rank, root,...)
Print to standard output only for root process.
Definition print.h:36
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
Header file for simulate.c.
Magnetic field simulation data.
Definition B_field.h:63
int offload_array_length
Definition asigma.h:57
int offload_array_length
Definition boozer.h:23
size_t offload_array_length
Definition diag.h:47
Wrapper for marker structs.
Definition particle.h:186
int offload_array_length
Definition mhd.h:45
Struct to keep track of the offload array length and unpack status.
Definition offload.h:11
General representation of a marker.
Definition particle.h:40
integer endcond
Definition particle.h:64
int offload_array_length
Definition plasma.h:45
Simulation offload struct.
Definition simulate.h:55
char qid_wall[256]
Definition simulate.h:134
char qid_options[256]
Definition simulate.h:130
char qid_boozer[256]
Definition simulate.h:137
B_field_offload_data B_offload_data
Definition simulate.h:57
char hdf5_in[256]
Definition simulate.h:120
plasma_offload_data plasma_offload_data
Definition simulate.h:59
char qid[256]
Definition simulate.h:122
neutral_offload_data neutral_offload_data
Definition simulate.h:60
mhd_offload_data mhd_offload_data
Definition simulate.h:63
char qid_nbi[256]
Definition simulate.h:140
char qid_marker[256]
Definition simulate.h:133
char qid_mhd[256]
Definition simulate.h:138
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
char qid_neutral[256]
Definition simulate.h:136
char qid_bfield[256]
Definition simulate.h:131
E_field_offload_data E_offload_data
Definition simulate.h:58
char qid_plasma[256]
Definition simulate.h:135
char qid_efield[256]
Definition simulate.h:132
char qid_asigma[256]
Definition simulate.h:139
char hdf5_out[256]
Definition simulate.h:121
char description[256]
Definition simulate.h:123
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
void wall_free_offload(wall_offload_data *offload_data, real **offload_array, int **int_offload_array)
Free offload array and reset parameters.
Definition wall.c:91
Header file for wall.c.