ASCOT5
Loading...
Searching...
No Matches
dist_com.c
Go to the documentation of this file.
1
5#include <stdio.h>
6#include <stdlib.h>
7#include <math.h>
8#include "../ascot5.h"
9#include "../consts.h"
10#include "../physlib.h"
11#include "../particle.h"
12#include "dist_com.h"
13
17size_t dist_COM_index(int i_mu, int i_Ekin, int i_Ptor, size_t step_2,
18 size_t step_1) {
19 return (size_t)(i_mu) * step_2
20 + (size_t)(i_Ekin) * step_1
21 + (size_t)(i_Ptor);
22}
23
30 offload_data->n_mu = 0;
31 offload_data->min_mu = 0;
32 offload_data->max_mu = 0;
33 offload_data->n_Ekin = 0;
34 offload_data->min_Ekin = 0;
35 offload_data->max_Ekin = 0;
36 offload_data->n_Ptor = 0;
37 offload_data->min_Ptor = 0;
38 offload_data->max_Ptor = 0;
39}
40
49 dist_COM_offload_data* offload_data, real* offload_array) {
50 dist_data->n_mu = offload_data->n_mu;
51 dist_data->min_mu = offload_data->min_mu;
52 dist_data->max_mu = offload_data->max_mu;
53
54 dist_data->n_Ekin = offload_data->n_Ekin;
55 dist_data->min_Ekin = offload_data->min_Ekin;
56 dist_data->max_Ekin = offload_data->max_Ekin;
57
58 dist_data->n_Ptor = offload_data->n_Ptor;
59 dist_data->min_Ptor = offload_data->min_Ptor;
60 dist_data->max_Ptor = offload_data->max_Ptor;
61
62 size_t n_Ptor = (size_t)(dist_data->n_Ptor);
63 size_t n_Ekin = (size_t)(dist_data->n_Ekin);
64 dist_data->step_2 = n_Ptor * n_Ekin;
65 dist_data->step_1 = n_Ptor;
66
67 dist_data->histogram = &offload_array[0];
68}
69
80
81 GPU_PARALLEL_LOOP_ALL_LEVELS
82 for(int i = 0; i < p_f->n_mrk; i++) {
83 if(p_f->running[i]) {
84 real Ekin, Ptor, Bnorm, psi, mu, xi, pnorm, ppar;
85
86 B_field_eval_psi(&psi, p_f->r[i], p_f->phi[i], p_f->z[i],
87 p_f->time[i], Bdata);
88
89 real B [] = {p_f->B_r[i], p_f->B_phi[i], p_f->B_z[i]};
90 Bnorm = math_normc(p_f->B_r[i], p_f->B_phi[i], p_f->B_z[i]);
91
92 real p [] = {p_f->p_r[i], p_f->p_phi[i], p_f->p_z[i]};
93 pnorm = math_normc(p_f->p_r[i], p_f->p_phi[i], p_f->p_z[i]);
94 ppar = math_dot(p, B) / Bnorm;
95 xi = ppar / pnorm;
96
97 mu = physlib_gc_mu(p_f->mass[i], pnorm, xi, Bnorm);
98 int i_mu = floor((mu - dist->min_mu)
99 / ((dist->max_mu - dist->min_mu)/dist->n_mu));
100 Ekin = physlib_Ekin_pnorm(p_f->mass[i], pnorm);
101
102 int i_Ekin = floor((Ekin - dist->min_Ekin)
103 / ((dist->max_Ekin - dist->min_Ekin) / dist->n_Ekin));
104 Ptor = phys_ptoroid_fo(
105 p_f->charge[i], p_f->r[i], p_f->p_phi[i], psi);
106
107 int i_Ptor = floor((Ptor - dist->min_Ptor)
108 / ((dist->max_Ptor - dist->min_Ptor)/dist->n_Ptor));
109
110 if(i_mu >= 0 && i_mu <= dist->n_mu - 1 &&
111 i_Ekin >= 0 && i_Ekin <= dist->n_Ekin - 1 &&
112 i_Ptor >= 0 && i_Ptor <= dist->n_Ptor - 1 ) {
113 real weight = p_f->weight[i] * (p_f->time[i] - p_i->time[i]);
114 size_t index = dist_COM_index(
115 i_mu, i_Ekin, i_Ptor, dist->step_2, dist->step_1);
116 GPU_ATOMIC
117 dist->histogram[index] += weight;
118 }
119 }
120 }
121}
122
137 int i_mu[NSIMD];
138 int i_Ekin[NSIMD];
139 int i_Ptor[NSIMD];
140
141 int ok[NSIMD];
142 real weight[NSIMD];
143
144 #pragma omp simd
145 for(int i = 0; i < NSIMD; i++) {
146 if(p_f->running[i]) {
147 real Ekin, Ptor, B, psi;
148
149 B_field_eval_psi(&psi, p_f->r[i], p_f->phi[i], p_f->z[i],
150 p_f->time[i], Bdata);
151
152 B = math_normc(p_f->B_r[i], p_f->B_phi[i], p_f->B_z[i]);
153 i_mu[i] = floor((p_f->mu[i] - dist->min_mu)
154 / ((dist->max_mu - dist->min_mu)/dist->n_mu));
155
156 Ekin = physlib_Ekin_ppar(p_f->mass[i], p_f->mu[i], p_f->ppar[i], B);
157
158 i_Ekin[i] = floor((Ekin - dist->min_Ekin)
159 / ((dist->max_Ekin - dist->min_Ekin) / dist->n_Ekin));
160 Ptor = phys_ptoroid_gc(p_f->charge[i], p_f->r[i], p_f->ppar[i], psi,
161 B, p_f->B_phi[i]);
162
163 i_Ptor[i] = floor((Ptor - dist->min_Ptor)
164 / ((dist->max_Ptor - dist->min_Ptor)/dist->n_Ptor));
165
166 if(i_mu[i] >= 0 && i_mu[i] <= dist->n_mu - 1 &&
167 i_Ekin[i] >= 0 && i_Ekin[i] <= dist->n_Ekin - 1 &&
168 i_Ptor[i] >= 0 && i_Ptor[i] <= dist->n_Ptor - 1 ) {
169 ok[i] = 1;
170 weight[i] = p_f->weight[i] * (p_f->time[i] - p_i->time[i]);
171 }
172 else {
173 ok[i] = 0;
174 }
175 }
176 }
177
178 for(int i = 0; i < NSIMD; i++) {
179 if(p_f->running[i] && ok[i]) {
180 size_t index = dist_COM_index(i_mu[i], i_Ekin[i], i_Ptor[i],
181 dist->step_2, dist->step_1);
182 #pragma omp atomic
183 dist->histogram[index] += weight[i];
184 }
185 }
186}
a5err B_field_eval_psi(real *psi, real r, real phi, real z, real t, B_field_data *Bdata)
Evaluate poloidal flux psi.
Definition B_field.c:201
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
Header file containing physical and mathematical constants.
void dist_COM_update_fo(dist_COM_data *dist, B_field_data *Bdata, particle_simd_fo *p_f, particle_simd_fo *p_i)
Update the histogram from full-orbit markers.
Definition dist_com.c:78
void dist_COM_free_offload(dist_COM_offload_data *offload_data)
Frees the offload data.
Definition dist_com.c:29
size_t dist_COM_index(int i_mu, int i_Ekin, int i_Ptor, size_t step_2, size_t step_1)
Internal function calculating the index in the histogram array.
Definition dist_com.c:17
void dist_COM_init(dist_COM_data *dist_data, dist_COM_offload_data *offload_data, real *offload_array)
Initializes distribution from offload data.
Definition dist_com.c:48
void dist_COM_update_gc(dist_COM_data *dist, B_field_data *Bdata, particle_simd_gc *p_f, particle_simd_gc *p_i)
Update the histogram from guiding center markers.
Definition dist_com.c:135
Header file for dist_com.c.
Header file for math.c.
#define math_dot(a, b)
Calculate dot product a[3] dot b[3].
Definition math.h:28
#define math_normc(a1, a2, a3)
Calculate norm of 3D vector from its components a1, a2, a3.
Definition math.h:67
Header file for particle.c.
Methods to evaluate elementary physical quantities.
#define phys_ptoroid_fo(q, R, pphi, psi)
Evaluate toroidal canonical momentum for particle.
Definition physlib.h:280
#define physlib_Ekin_ppar(m, mu, ppar, B)
Evaluate kinetic energy [J] from parallel momentum.
Definition physlib.h:128
#define physlib_Ekin_pnorm(m, p)
Evaluate kinetic energy [J] from momentum norm.
Definition physlib.h:115
#define phys_ptoroid_gc(q, R, ppar, psi, B, Bphi)
Evaluate toroidal canonical momentum for guiding center.
Definition physlib.h:287
#define physlib_gc_mu(m, p, xi, B)
Evaluate guiding center magnetic moment [J/T] from momentum norm and pitch.
Definition physlib.h:180
Magnetic field simulation data.
Definition B_field.h:63
Histogram parameters on target.
Definition dist_com.h:33
real max_Ptor
Definition dist_com.h:44
real * histogram
Definition dist_com.h:49
size_t step_1
Definition dist_com.h:46
real min_Ptor
Definition dist_com.h:43
real min_Ekin
Definition dist_com.h:39
real max_Ekin
Definition dist_com.h:40
size_t step_2
Definition dist_com.h:47
Histogram parameters that will be offloaded to target.
Definition dist_com.h:16
Struct representing NSIMD particle markers.
Definition particle.h:210
integer * running
Definition particle.h:252
Struct representing NSIMD guiding center markers.
Definition particle.h:275