ASCOT5
Loading...
Searching...
No Matches
simulate_ml_adaptive.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 "../simulate.h"
11#include "../particle.h"
12#include "../wall.h"
13#include "../diag.h"
14#include "../B_field.h"
15#include "../E_field.h"
18#include "../endcond.h"
19#include "../math.h"
20#include "../consts.h"
21
22DECLARE_TARGET_SIMD_UNIFORM(sim)
24
25
26#define MAGNETIC_FIELD_LINE_INISTEP 1.0e-2
27#define DUMMY_STEP_VAL 100.0
54
55 real hin[NSIMD] __memalign__; // Current time step
56 real hout[NSIMD] __memalign__; // Suggestion for next time step, negative value indicates rejected step
57 real hnext[NSIMD] __memalign__; // Next time step
58 int cycle[NSIMD] __memalign__; // Flag indigating whether a new marker was initialized
59
60 real cputime, cputime_last; // Global cpu time: recent and previous record
61
62 real tol = sim->ada_tol_orbfol;
63 int i;
64
65 particle_simd_ml p; // This array holds current states
66 particle_simd_ml p0; // This array stores previous states
67
68 for(i=0; i< NSIMD; i++) {
69 p.id[i] = -1;
70 p.running[i] = 0;
71 }
72
73 /* Initialize running particles */
74 int n_running = particle_cycle_ml(pq, &p, &sim->B_data, cycle);
75
76 /* Determine simulation time-step */
77 #pragma omp simd
78 for(i = 0; i < NSIMD; i++) {
79 if(cycle[i] > 0) {
80 /* Determine initial time-step */
81 hin[i] = simulate_ml_adaptive_inidt(sim, &p, i);
82 }
83 }
84
85 cputime_last = A5_WTIME;
86
87 /* MAIN SIMULATION LOOP
88 * - Store current state
89 * - Integrate motion due to bacgkround EM-field (orbit-following)
90 * - Check whether time step was accepted
91 * - NO: revert to initial state and ignore the end of the loop
92 * (except CPU_TIME_MAX end condition if this is implemented)
93 * - YES: update particle time, clean redundant Wiener processes, and proceed
94 * - Check for end condition(s)
95 * - Update diagnostics
96 * - Check for end condition(s)
97 */
98 while(n_running > 0) {
99
100 /* Store marker states in case time step will be rejected */
101 #pragma omp simd
102 for(i = 0; i < NSIMD; i++) {
103 particle_copy_ml(&p, i, &p0, i);
104
105 hout[i] = DUMMY_STEP_VAL;
106 hnext[i] = DUMMY_STEP_VAL;
107 }
108
109 /*************************** Physics **********************************/
110
111 /* Cash-Karp method for orbit-following */
112 if(sim->enable_orbfol) {
113
114 /* Set time-step negative if tracing backwards in time */
115 #pragma omp simd
116 for(i = 0; i < NSIMD; i++) {
117 if(sim->reverse_time) {
118 hin[i] = -hin[i];
119 }
120 }
121
122 if(sim->enable_mhd) {
123 step_ml_cashkarp_mhd(&p, hin, hout, tol, &sim->B_data,
124 &sim->boozer_data, &sim->mhd_data);
125 }
126 else {
127 step_ml_cashkarp(&p, hin, hout, tol, &sim->B_data);
128 }
129
130 /* Check whether time step was rejected */
131 #pragma omp simd
132 for(i = 0; i < NSIMD; i++) {
133 /* Switch sign of the time-step again if it was reverted earlier */
134 if(sim->reverse_time) {
135 hout[i] = -hout[i];
136 hin[i] = -hin[i];
137 }
138
139 if(p.running[i] && hout[i] < 0){
140 p.running[i] = 0;
141 hnext[i] = hout[i];
142 }
143 }
144 }
145
146 /**********************************************************************/
147
148
149 cputime = A5_WTIME;
150 #pragma omp simd
151 for(i = 0; i < NSIMD; i++) {
152 if(!p.err[i]) {
153 /* Check other time step limitations */
154 if(hnext[i] > 0) {
155 real dphi = fabs(p0.phi[i]-p.phi[i]) / sim->ada_max_dphi;
156 real drho = fabs(p0.rho[i]-p.rho[i]) / sim->ada_max_drho;
157
158 if(dphi > 1 && dphi > drho) {
159 hnext[i] = -hin[i]/dphi;
160 }
161 else if(drho > 1 && drho > dphi) {
162 hnext[i] = -hin[i]/drho;
163 }
164 }
165
166 /* Retrieve marker states in case time step was rejected */
167 if(hnext[i] < 0){
168 particle_copy_ml(&p0, i, &p, i);
169 }
170
171 /* Update simulation and cpu times */
172 if(p.running[i]){
173
174 /* Advance time (if time step was accepted) and determine next time step */
175 if(hnext[i] < 0){
176 /* Time step was rejected, use the suggestion given by integrator */
177 hin[i] = -hnext[i];
178 }
179 else {
180 /* Mileage measures seconds but hin is in meters */
181 p.mileage[i] += hin[i] / CONST_C;
182
183 if(hnext[i] > hout[i]) {
184 /* Use time step suggested by the integrator */
185 hnext[i] = hout[i];
186 }
187 else if(hnext[i] == DUMMY_STEP_VAL) {
188 /* Time step is unchanged (happens when no physics are enabled) */
189 hnext[i] = hin[i];
190 }
191 hin[i] = hnext[i];
192 }
193
194 p.cputime[i] += cputime - cputime_last;
195 }
196 }
197 }
198 cputime_last = cputime;
199
200 /* Check possible end conditions */
201 endcond_check_ml(&p, &p0, sim);
202
203 /* Update diagnostics */
204 diag_update_ml(&sim->diag_data, &p, &p0);
205
206 /* Update running particles */
207 n_running = particle_cycle_ml(pq, &p, &sim->B_data, cycle);
208
209 /* Determine simulation time-step for new particles */
210 #pragma omp simd
211 for(i = 0; i < NSIMD; i++) {
212 if(cycle[i] > 0) {
213 hin[i] = simulate_ml_adaptive_inidt(sim, &p, i);
214 }
215 }
216 }
217
218 /* All markers simulated! */
219
220}
221
235
236 /* Value calculated from speed of light
237 * assuming initial time step is of the order of 1 cm / c*/
238 /* Define this with a compiler parameter */
239
241
242}
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_C
Speed of light [m/s]
Definition consts.h:23
void diag_update_ml(diag_data *data, particle_simd_ml *p_f, particle_simd_ml *p_i)
Collects diagnostics when marker represents a magnetic field line.
Definition diag.c:300
Header file for diag.c.
void endcond_check_ml(particle_simd_ml *p_f, particle_simd_ml *p_i, sim_data *sim)
Check end conditions for ML markers.
Definition endcond.c:435
Header file for endcond.c.
Header file for math.c.
void particle_copy_ml(particle_simd_ml *p1, int i, particle_simd_ml *p2, int j)
Copy ML struct.
Definition particle.c:1404
int particle_cycle_ml(particle_queue *q, particle_simd_ml *p, B_field_data *Bdata, int *cycle)
Replace finished ML markers with new ones or dummies.
Definition particle.c:461
Header file for particle.c.
Header file for simulate.c.
real simulate_ml_adaptive_inidt(sim_data *sim, particle_simd_ml *p, int i)
Calculates initial time step value.
void simulate_ml_adaptive(particle_queue *pq, sim_data *sim)
Simulates magnetic field-lines using adaptive time-step.
#define DUMMY_STEP_VAL
#define MAGNETIC_FIELD_LINE_INISTEP
Header file for simulate_ml_adaptive.c.
void step_ml_cashkarp_mhd(particle_simd_ml *p, real *h, real *hnext, real tol, B_field_data *Bdata, boozer_data *boozerdata, mhd_data *mhddata)
Integrate a magnetic field line step for a struct of markers.
void step_ml_cashkarp(particle_simd_ml *p, real *h, real *hnext, real tol, B_field_data *Bdata)
Integrate a magnetic field line step for a struct of markers.
Header file for step_ml_cashkarp.c.
Marker queue.
Definition particle.h:154
Struct representing NSIMD field line markers.
Definition particle.h:342
Simulation data struct.
Definition simulate.h:154
int enable_orbfol
Definition simulate.h:194
real ada_max_drho
Definition simulate.h:188
mhd_data mhd_data
Definition simulate.h:162
int enable_mhd
Definition simulate.h:196
boozer_data boozer_data
Definition simulate.h:161
B_field_data B_data
Definition simulate.h:156
int reverse_time
Definition simulate.h:206
real ada_max_dphi
Definition simulate.h:190
real ada_tol_orbfol
Definition simulate.h:184
diag_data diag_data
Definition simulate.h:165
Header file for wall.c.