26#include "step/step_gc_cashkarp.h"
30DECLARE_TARGET_SIMD_UNIFORM(sim)
33#define DUMMY_TIMESTEP_VAL 1.0
63 real* hout_orb = (
real*) malloc(mrk_array_size*
sizeof(
real));
64 real* hout_col = (
real*) malloc(mrk_array_size*
sizeof(
real));
65 real* hout_rfof = (
real*) malloc(mrk_array_size*
sizeof(
real));
66 real* hnext = (
real*) malloc(mrk_array_size*
sizeof(
real));
71 int* cycle = (
int*) malloc(mrk_array_size*
sizeof(
int));
76 real cputime, cputime_last;
85 for(
int i=0; i< mrk_array_size; i++) {
88 acceleration.
acc[i] = 1.0;
90 acceleration.
cross[i].crossed_once = 0;
101 for(
int i = 0; i < mrk_array_size; i++) {
126 real* rnd = (
real*) malloc(5*mrk_array_size*
sizeof(
real));
130 GPU_MAP_TO_DEVICE(hin[0:mrk_array_size],rnd[0:5*mrk_array_size],hout_orb[0:mrk_array_size],hout_col[0:mrk_array_size],hout_rfof[0:mrk_array_size],hnext[0:mrk_array_size],cycle[0:mrk_array_size])
132 while(n_running > 0) {
135 GPU_PARALLEL_LOOP_ALL_LEVELS
136 for(
int i = 0; i < p.
n_mrk; i++) {
147 GPU_PARALLEL_LOOP_ALL_LEVELS
148 for(
int i = 0; i < p.
n_mrk; i++) {
167 GPU_PARALLEL_LOOP_ALL_LEVELS
168 for(
int i = 0; i < p.
n_mrk; i++) {
172 hout_orb[i] = -hout_orb[i];
175 if(p.
running[i] && hout_orb[i] < 0){
177 hnext[i] = hout_orb[i];
186 hout_col, tol_col, wienarr, &sim->
B_data,
190 GPU_PARALLEL_LOOP_ALL_LEVELS
191 for(
int i = 0; i < p.
n_mrk; i++) {
192 if(p.
running[i] && hout_col[i] < 0){
194 hnext[i] = hout_col[i];
201 rfof_resonance_check_and_kick_gc(
205 GPU_PARALLEL_LOOP_ALL_LEVELS
206 for(
int i = 0; i < p.
n_mrk; i++) {
207 if(p.
running[i] && hout_rfof[i] < 0){
209 hnext[i] = hout_rfof[i];
217 GPU_PARALLEL_LOOP_ALL_LEVELS
218 for(
int i = 0; i < p.
n_mrk; i++) {
219 if(p.
id[i] > 0 && !p.
err[i]) {
225 if(dphi > 1 && dphi > drho) {
226 hnext[i] = -hin[i]/dphi;
228 else if(drho > 1 && drho > dphi) {
229 hnext[i] = -hin[i]/drho;
249 * hin[i] * acceleration.
acc[i];
252 acceleration.
orbittime[i] += hin[i] * acceleration.
acc[i];
255 if(hnext[i] > hout_orb[i]) {
258 hnext[i] = hout_orb[i];
260 if(hnext[i] > hout_col[i]) {
263 hnext[i] = hout_col[i];
265 if(hnext[i] > hout_rfof[i]) {
267 hnext[i] = hout_rfof[i];
269 if(hnext[i] == 1.0) {
281 p.
cputime[i] += cputime - cputime_last;
285 cputime_last = cputime;
301 GPU_PARALLEL_LOOP_ALL_LEVELS_REDUCTION(n_running)
302 for(
int i = 0; i < p.
n_mrk; i++)
304 if(p.
running[i] > 0) n_running++;
311 for(
int i = 0; i <p.
n_mrk; i++) {
314 acceleration.
acc[i] = 1.0;
316 acceleration.
cross[i].crossed_once = 0;
323 rfof_clear_history(&rfof_mrk, i);
332 GPU_MAP_FROM_DEVICE(sim[0:1])
346 rfof_tear_down(&rfof_mrk);
389 real colltime = 1/(100*nu);
390 if(h > colltime) {h=colltime;}
417 GPU_PARALLEL_LOOP_ALL_LEVELS
418 for(
int i = 0; i < p->
n_mrk; i++) {
420 int omp_crossed = ((p->
z[i] - rz[1]) * (p0->
z[i] - rz[1]) < 0) &&
422 if(omp_crossed && acc->
cross[i].crossed_twice) {
423 if( ((
float)acc->
cross[i].first_ppar - 0.5) * p->
ppar[i] > 0 ) {
429 acc->
cross[i].crossed_once = 1;
430 acc->
cross[i].crossed_twice = 0;
431 acc->
cross[i].first_ppar = p->
ppar[i] > 0;
434 else if(omp_crossed && acc->
cross[i].crossed_once) {
435 acc->
cross[i].crossed_twice = 1;
436 if( ((
float)acc->
cross[i].first_ppar - 0.5) * p->
ppar[i] > 0 ) {
438 acc->
cross[i].crossed_once = 1;
439 acc->
cross[i].crossed_twice = 0;
440 acc->
cross[i].first_ppar = p->
ppar[i] > 0;
444 else if(omp_crossed) {
445 acc->
cross[i].crossed_once = 1;
446 acc->
cross[i].first_ppar = p->
ppar[i] > 0;
462 acceleration->
acc = malloc(nmrk *
sizeof(acceleration->
acc) );
465 acceleration->
cross = malloc(nmrk *
sizeof(acceleration->
cross) );
475 acceleration->
acc [0:mrk_array_size],\
476 acceleration->
orbittime [0:mrk_array_size],\
477 acceleration->
collfreq [0:mrk_array_size],\
478 acceleration->
cross [0:mrk_array_size]
a5err B_field_get_axis_rz(real rz[2], B_field_data *Bdata, real phi)
Return magnetic axis Rz-coordinates.
Header file for B_field.c.
Header file for E_field.c.
Main header file for ASCOT5.
#define A5_WTIME
Wall time.
Header file for boozer.c.
Header file containing physical and mathematical constants.
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.
void endcond_check_gc(particle_simd_gc *p_f, particle_simd_gc *p_i, sim_data *sim)
Check end conditions for GC markers.
Header file for endcond.c.
#define math_normc(a1, a2, a3)
Calculate norm of 3D vector from its components a1, a2, a3.
Header file for mccc package.
void mccc_gc_milstein(particle_simd_gc *p, real *hin, real *acc, real *collfreq, real *hout, real tol, mccc_wienarr *w, B_field_data *Bdata, plasma_data *pdata, mccc_data *mdata, real *rnd)
Integrate collisions for one time-step.
void mccc_wiener_onload(mccc_wienarr *w, int mrk_array_size)
Onload data from the GPU.
a5err mccc_wiener_clean(mccc_wienarr *w, real t)
Removes Wiener processes from the array that are no longer required.
void mccc_wiener_offload(mccc_wienarr *w, int mrk_array_size)
Offload data to the accelerator.
void mccc_wiener_initialize(mccc_wienarr *w, real initime)
Initializes a struct that stores generated Wiener processes.
header file for mccc_wiener.c
void particle_allocate_gc(particle_simd_gc *p_gc, int nmrk)
Allocates guiding center struct representing particle markers.
void particle_onload_gc(particle_simd_gc *p)
Onload guiding center particle struct from the GPU.
void particle_copy_gc(particle_simd_gc *p1, int i, particle_simd_gc *p2, int j)
Copy GC struct.
void particle_offload_gc(particle_simd_gc *p)
Offload guiding center particle struct to GPU.
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.
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.
Header file for plasma.c.
#define random_normal_simd(data, n, r)
Contains the functions to be called from the simulation loop when using ICRH.
Header file for simulate.c.
void simulate_gc_adaptive(particle_queue *pq, sim_data *sim, int mrk_array_size)
Simulates guiding centers using adaptive time-step.
void recalculate_acceleration(Acceleration *acc, sim_data *sim, particle_simd_gc *p, particle_simd_gc *p0)
void acceleration_offload(Acceleration *acceleration, int mrk_array_size)
Offload acceleration struct to GPU.
real simulate_gc_adaptive_inidt(sim_data *sim, particle_simd_gc *p, int i)
Calculates time step value.
#define DUMMY_TIMESTEP_VAL
void acceleration_allocate(Acceleration *acceleration, int nmrk)
Allocates struct representing acceleration struc.
Header file for simulate_gc_adaptive.c.
void step_gc_cashkarp_mhd(particle_simd_gc *p, real *h, real *hnext, real tol, B_field_data *Bdata, E_field_data *Edata, boozer_data *boozer, mhd_data *mhd, int aldforce)
Integrate a guiding center step for a struct of markers with MHD.
void step_gc_cashkarp(particle_simd_gc *p, real *h, real *hnext, real tol, B_field_data *Bdata, E_field_data *Edata, int aldforce)
Integrate a guiding center step for a struct of markers.
Struct for storing Wiener processes.
Struct representing NSIMD guiding center markers.
Reusable struct for storing marker specific data during the simulation loop.
random_data * random_data