ASCOT5
Loading...
Searching...
No Matches
simulate_gc_fixed.c
Go to the documentation of this file.
1
5#include <stdio.h>
6#include <stdlib.h>
7#include <omp.h>
8#include <math.h>
9#include "../ascot5.h"
10#include "../endcond.h"
11#include "../math.h"
12#include "../consts.h"
13#include "../physlib.h"
14#include "../simulate.h"
15#include "../particle.h"
16#include "../wall.h"
17#include "../diag.h"
18#include "../B_field.h"
19#include "../E_field.h"
20#include "../plasma.h"
21#include "simulate_gc_fixed.h"
22#include "step/step_gc_rk4.h"
23#include "mccc/mccc.h"
24
25DECLARE_TARGET_SIMD_UNIFORM(sim)
27
47 int cycle[NSIMD] __memalign__; // Flag indigating whether a new marker was initialized
48 real hin[NSIMD] __memalign__; // Time step
49
50 real cputime, cputime_last; // Global cpu time: recent and previous record
51
52 particle_simd_gc p; // This array holds current states
53 particle_simd_gc p0; // This array stores previous states
54
55 /* Init dummy markers */
56 for(int i=0; i< NSIMD; i++) {
57 p.id[i] = -1;
58 p.running[i] = 0;
59 }
60
61 /* Initialize running particles */
62 int n_running = particle_cycle_gc(pq, &p, &sim->B_data, cycle);
63
64 /* Determine simulation time-step */
65 #pragma omp simd
66 for(int i = 0; i < NSIMD; i++) {
67 if(cycle[i] > 0) {
68 hin[i] = simulate_gc_fixed_inidt(sim, &p, i);
69 }
70 }
71
72 cputime_last = A5_WTIME;
73
74 /* MAIN SIMULATION LOOP
75 * - Store current state
76 * - Integrate motion due to background EM-field (orbit-following)
77 * - Integrate scattering due to Coulomb collisions
78 * - Advance time
79 * - Check for end condition(s)
80 * - Update diagnostics
81 */
82 while(n_running > 0) {
83
84 /* Store marker states */
85 #pragma omp simd
86 for(int i = 0; i < NSIMD; i++) {
87 particle_copy_gc(&p, i, &p0, i);
88 }
89
90 /*************************** Physics **********************************/
91
92 /* Set time-step negative if tracing backwards in time */
93 #pragma omp simd
94 for(int i = 0; i < NSIMD; i++) {
95 if(sim->reverse_time) {
96 hin[i] = -hin[i];
97 }
98 }
99
100 /* RK4 method for orbit-following */
101 if(sim->enable_orbfol) {
102 if(sim->enable_mhd) {
103 step_gc_rk4_mhd(&p, hin, &sim->B_data, &sim->E_data,
104 &sim->boozer_data, &sim->mhd_data);
105 }
106 else {
107 step_gc_rk4(&p, hin, &sim->B_data, &sim->E_data);
108 }
109 }
110
111 /* Switch sign of the time-step again if it was reverted earlier */
112 #pragma omp simd
113 for(int i = 0; i < NSIMD; i++) {
114 if(sim->reverse_time) {
115 hin[i] = -hin[i];
116 }
117 }
118
119 /* Euler-Maruyama method for collisions */
120 if(sim->enable_clmbcol) {
121 real rnd[5*NSIMD];
122 random_normal_simd(&sim->random_data, 5*NSIMD, rnd);
123 mccc_gc_euler(&p, hin, &sim->B_data, &sim->plasma_data,
124 &sim->mccc_data, rnd);
125 }
126
127 /**********************************************************************/
128
129
130 /* Update simulation and cpu times */
131 cputime = A5_WTIME;
132 #pragma omp simd
133 for(int i = 0; i < NSIMD; i++) {
134 if(p.running[i]) {
135 p.time[i] += ( 1.0 - 2.0 * ( sim->reverse_time > 0 ) ) * hin[i];
136 p.mileage[i] += hin[i];
137 p.cputime[i] += cputime - cputime_last;
138 }
139 }
140 cputime_last = cputime;
141
142 /* Check possible end conditions */
143 endcond_check_gc(&p, &p0, sim);
144
145 /* Update diagnostics */
146 diag_update_gc(&sim->diag_data, &sim->B_data, &p, &p0);
147
148 /* Update running particles */
149 n_running = particle_cycle_gc(pq, &p, &sim->B_data, cycle);
150
151 /* Determine simulation time-step */
152 #pragma omp simd
153 for(int i = 0; i < NSIMD; i++) {
154 if(cycle[i] > 0) {
155 hin[i] = simulate_gc_fixed_inidt(sim, &p, i);
156 }
157 }
158
159 }
160
161 /* All markers simulated! */
162
163}
164
179 real h;
180
181 /* Value defined directly by user */
182 if(sim->fix_usrdef_use) {
183 h = sim->fix_usrdef_val;
184 }
185 else {
186 /* Value calculated from gyrotime */
187 real Bnorm = math_normc(p->B_r[i], p->B_phi[i], p->B_z[i]);
188 real gyrotime = CONST_2PI /
189 phys_gyrofreq_ppar(p->mass[i], p->charge[i],
190 p->mu[i], p->ppar[i], Bnorm);
191 h = gyrotime/sim->fix_gyrodef_nstep;
192 }
193
194 return h;
195}
Header file for B_field.c.
Header file for E_field.c.
Main header file for ASCOT5.
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
#define __memalign__
Definition ascot5.h:76
Header file containing physical and mathematical constants.
#define CONST_2PI
2*pi
Definition consts.h:14
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_gc(particle_simd_gc *p_f, particle_simd_gc *p_i, sim_data *sim)
Check end conditions for GC markers.
Definition endcond.c:262
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_gc_euler(particle_simd_gc *p, real *h, B_field_data *Bdata, plasma_data *pdata, mccc_data *mdata, real *rnd)
Integrate collisions for one time-step.
void particle_copy_gc(particle_simd_gc *p1, int i, particle_simd_gc *p2, int j)
Copy GC struct.
Definition particle.c:1355
int particle_cycle_gc(particle_queue *q, particle_simd_gc *p, B_field_data *Bdata, int *cycle)
Replace finished GC markers with new ones or dummies.
Definition particle.c:367
Header file for particle.c.
Methods to evaluate elementary physical quantities.
#define phys_gyrofreq_ppar(m, q, mu, ppar, B)
Evaluate gyrofrequency [rad/s] from parallel momentum and magnetic moment.
Definition physlib.h:273
Header file for plasma.c.
#define random_normal_simd(data, n, r)
Definition random.h:102
Header file for simulate.c.
void simulate_gc_fixed(particle_queue *pq, sim_data *sim)
Simulates guiding centers using fixed time-step.
real simulate_gc_fixed_inidt(sim_data *sim, particle_simd_gc *p, int i)
Calculates time step value.
Header file for simulate_gc_fixed.c.
void step_gc_rk4_mhd(particle_simd_gc *p, real *h, B_field_data *Bdata, E_field_data *Edata, boozer_data *boozer, mhd_data *mhd)
Integrate a guiding center step with RK4 with MHD modes present.
void step_gc_rk4(particle_simd_gc *p, real *h, B_field_data *Bdata, E_field_data *Edata)
Integrate a guiding center step for a struct of markers with RK4.
Definition step_gc_rk4.c:33
Header file for step_gc_rk4.c.
Marker queue.
Definition particle.h:154
Struct representing NSIMD guiding center markers.
Definition particle.h:275
Simulation data struct.
Definition simulate.h:154
int enable_orbfol
Definition simulate.h:194
plasma_data plasma_data
Definition simulate.h:158
mhd_data mhd_data
Definition simulate.h:162
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
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
int enable_clmbcol
Definition simulate.h:195
diag_data diag_data
Definition simulate.h:165
Header file for wall.c.