ASCOT5
Loading...
Searching...
No Matches
dist_6D.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 "dist_6D.h"
12#include "../gctransform.h"
13
17size_t dist_6D_index(int i_r, int i_phi, int i_z, int i_pr, int i_pphi,
18 int i_pz, int i_time, int i_q, size_t step_7,
19 size_t step_6, size_t step_5, size_t step_4, size_t step_3,
20 size_t step_2, size_t step_1) {
21 return (size_t)(i_r) * step_7
22 + (size_t)(i_phi) * step_6
23 + (size_t)(i_z) * step_5
24 + (size_t)(i_pr) * step_4
25 + (size_t)(i_pphi) * step_3
26 + (size_t)(i_pz) * step_2
27 + (size_t)(i_time) * step_1
28 + (size_t)(i_q);
29}
30
35 offload_data->n_r = 0;
36 offload_data->min_r = 0;
37 offload_data->max_r = 0;
38 offload_data->n_phi = 0;
39 offload_data->min_phi = 0;
40 offload_data->max_phi = 0;
41 offload_data->n_z = 0;
42 offload_data->min_z = 0;
43 offload_data->max_z = 0;
44 offload_data->n_pr = 0;
45 offload_data->min_pr = 0;
46 offload_data->max_pr = 0;
47 offload_data->n_pphi = 0;
48 offload_data->min_pphi = 0;
49 offload_data->max_pphi = 0;
50 offload_data->n_pz = 0;
51 offload_data->min_pz = 0;
52 offload_data->max_pz = 0;
53}
54
58void dist_6D_init(dist_6D_data* dist_data, dist_6D_offload_data* offload_data,
59 real* offload_array) {
60 dist_data->n_r = offload_data->n_r;
61 dist_data->min_r = offload_data->min_r;
62 dist_data->max_r = offload_data->max_r;
63
64 dist_data->n_phi = offload_data->n_phi;
65 dist_data->min_phi = offload_data->min_phi;
66 dist_data->max_phi = offload_data->max_phi;
67
68 dist_data->n_z = offload_data->n_z;
69 dist_data->min_z = offload_data->min_z;
70 dist_data->max_z = offload_data->max_z;
71
72 dist_data->n_pr = offload_data->n_pr;
73 dist_data->min_pr = offload_data->min_pr;
74 dist_data->max_pr = offload_data->max_pr;
75
76 dist_data->n_pphi = offload_data->n_pphi;
77 dist_data->min_pphi = offload_data->min_pphi;
78 dist_data->max_pphi = offload_data->max_pphi;
79
80 dist_data->n_pz = offload_data->n_pz;
81 dist_data->min_pz = offload_data->min_pz;
82 dist_data->max_pz = offload_data->max_pz;
83
84 dist_data->n_time = offload_data->n_time;
85 dist_data->min_time = offload_data->min_time;
86 dist_data->max_time = offload_data->max_time;
87
88 dist_data->n_q = offload_data->n_q;
89 dist_data->min_q = offload_data->min_q;
90 dist_data->max_q = offload_data->max_q;
91
92 size_t n_q = (size_t)(dist_data->n_q);
93 size_t n_time = (size_t)(dist_data->n_time);
94 size_t n_pz = (size_t)(dist_data->n_pz);
95 size_t n_pphi = (size_t)(dist_data->n_pphi);
96 size_t n_pr = (size_t)(dist_data->n_pr);
97 size_t n_z = (size_t)(dist_data->n_z);
98 size_t n_phi = (size_t)(dist_data->n_phi);
99 dist_data->step_7 = n_q * n_time * n_pz * n_pphi * n_pr * n_z * n_phi;
100 dist_data->step_6 = n_q * n_time * n_pz * n_pphi * n_pr * n_z;
101 dist_data->step_5 = n_q * n_time * n_pz * n_pphi * n_pr;
102 dist_data->step_4 = n_q * n_time * n_pz * n_pphi;
103 dist_data->step_3 = n_q * n_time * n_pz;
104 dist_data->step_2 = n_q * n_time;
105 dist_data->step_1 = n_q;
106
107 dist_data->histogram = &offload_array[0];
108}
109
122 particle_simd_fo* p_i) {
123
124 GPU_PARALLEL_LOOP_ALL_LEVELS
125 for(int i = 0; i < p_f->n_mrk; i++) {
126 if(p_f->running[i]) {
127
128 int i_r = floor((p_f->r[i] - dist->min_r)
129 / ((dist->max_r - dist->min_r)/dist->n_r));
130
131 real phi = fmod(p_f->phi[i], 2*CONST_PI);
132 if(phi < 0) {
133 phi += 2*CONST_PI;
134 }
135 int i_phi = floor((phi - dist->min_phi)
136 / ((dist->max_phi - dist->min_phi)/dist->n_phi));
137
138 int i_z = floor((p_f->z[i] - dist->min_z)
139 / ((dist->max_z - dist->min_z) / dist->n_z));
140
141 int i_pr = floor((p_f->p_r[i] - dist->min_pr)
142 / ((dist->max_pr - dist->min_pr) / dist->n_pr));
143
144 int i_pphi = floor((p_f->p_phi[i] - dist->min_pphi)
145 / ((dist->max_pphi - dist->min_pphi) / dist->n_pphi));
146
147 int i_pz = floor((p_f->p_z[i] - dist->min_pz)
148 / ((dist->max_pz - dist->min_pz) / dist->n_pz));
149
150 int i_time = floor((p_f->time[i] - dist->min_time)
151 / ((dist->max_time - dist->min_time) / dist->n_time));
152
153 int i_q = floor((p_f->charge[i]/CONST_E - dist->min_q)
154 / ((dist->max_q - dist->min_q) / dist->n_q));
155
156 if(i_r >= 0 && i_r <= dist->n_r - 1 &&
157 i_phi >= 0 && i_phi <= dist->n_phi - 1 &&
158 i_z >= 0 && i_z <= dist->n_z - 1 &&
159 i_pr >= 0 && i_pr <= dist->n_pr - 1 &&
160 i_pphi >= 0 && i_pphi <= dist->n_pphi - 1 &&
161 i_pz >= 0 && i_pz <= dist->n_pz - 1 &&
162 i_time >= 0 && i_time <= dist->n_time - 1 &&
163 i_q >= 0 && i_q <= dist->n_q - 1 ) {
164 real weight = p_f->weight[i] * (p_f->time[i] - p_i->time[i]);
165 size_t index = dist_6D_index(
166 i_r, i_phi, i_z, i_pr, i_pphi, i_pz,
167 i_time, i_q, dist->step_7, dist->step_6, dist->step_5,
168 dist->step_4, dist->step_3, dist->step_2, dist->step_1);
169 GPU_ATOMIC
170 dist->histogram[index] += weight;
171 }
172 }
173 }
174}
175
188 particle_simd_gc* p_i) {
189 real phi[NSIMD];
190
191 int i_r[NSIMD];
192 int i_phi[NSIMD];
193 int i_z[NSIMD];
194 int i_pr[NSIMD];
195 int i_pphi[NSIMD];
196 int i_pz[NSIMD];
197 int i_time[NSIMD];
198 int i_q[NSIMD];
199
200 int ok[NSIMD];
201 real weight[NSIMD];
202
203 #pragma omp simd
204 for(int i = 0; i < NSIMD; i++) {
205 if(p_f->running[i]) {
206
207 real pr, pphi, pz;
208 real B_dB[12] = {
209 p_f->B_r[i], p_f->B_r_dr[i], p_f->B_r_dphi[i], p_f->B_r_dz[i],
210 p_f->B_phi[i], p_f->B_phi_dr[i], p_f->B_phi_dphi[i],
211 p_f->B_phi_dz[i],
212 p_f->B_z[i], p_f->B_z_dr[i], p_f->B_z_dphi[i], p_f->B_z_dz[i]};
213 gctransform_pparmuzeta2prpphipz(p_f->mass[i], p_f->charge[i], B_dB,
214 p_f->phi[i], p_f->ppar[i],
215 p_f->mu[i], p_f->zeta[i],
216 &pr, &pphi, &pz);
217
218 i_r[i] = floor((p_f->r[i] - dist->min_r)
219 / ((dist->max_r - dist->min_r)/dist->n_r));
220
221 phi[i] = fmod(p_f->phi[i], 2*CONST_PI);
222 if(phi[i] < 0) {
223 phi[i] = phi[i] + 2*CONST_PI;
224 }
225 i_phi[i] = floor((phi[i] - dist->min_phi)
226 / ((dist->max_phi - dist->min_phi)/dist->n_phi));
227
228 i_z[i] = floor((p_f->z[i] - dist->min_z)
229 / ((dist->max_z - dist->min_z) / dist->n_z));
230
231 i_pr[i] = floor((pr - dist->min_pr)
232 / ((dist->max_pr - dist->min_pr) / dist->n_pr));
233
234 i_pphi[i] = floor((pphi - dist->min_pphi)
235 / ((dist->max_pphi - dist->min_pphi) / dist->n_pphi));
236
237 i_pz[i] = floor((pz - dist->min_pz)
238 / ((dist->max_pz - dist->min_pz) / dist->n_pz));
239
240 i_time[i] = floor((p_f->time[i] - dist->min_time)
241 / ((dist->max_time - dist->min_time) / dist->n_time));
242
243 i_q[i] = floor((p_f->charge[i]/CONST_E - dist->min_q)
244 / ((dist->max_q - dist->min_q) / dist->n_q));
245
246 if(i_r[i] >= 0 && i_r[i] <= dist->n_r - 1 &&
247 i_phi[i] >= 0 && i_phi[i] <= dist->n_phi - 1 &&
248 i_z[i] >= 0 && i_z[i] <= dist->n_z - 1 &&
249 i_pr[i] >= 0 && i_pr[i] <= dist->n_pr - 1 &&
250 i_pphi[i] >= 0 && i_pphi[i] <= dist->n_pphi - 1 &&
251 i_pz[i] >= 0 && i_pz[i] <= dist->n_pz - 1 &&
252 i_time[i] >= 0 && i_time[i] <= dist->n_time - 1 &&
253 i_q[i] >= 0 && i_q[i] <= dist->n_q - 1 ) {
254 ok[i] = 1;
255 weight[i] = p_f->weight[i] * (p_f->time[i] - p_i->time[i]);
256 }
257 else {
258 ok[i] = 0;
259 }
260 }
261 }
262
263 for(int i = 0; i < NSIMD; i++) {
264 if(p_f->running[i] && ok[i]) {
265 size_t index = dist_6D_index(
266 i_r[i], i_phi[i], i_z[i], i_pr[i], i_pphi[i], i_pz[i],
267 i_time[i], i_q[i], dist->step_7, dist->step_6, dist->step_5,
268 dist->step_4, dist->step_3, dist->step_2, dist->step_1);
269 #pragma omp atomic
270 dist->histogram[index] += weight[i];
271 }
272 }
273}
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.
#define CONST_PI
pi
Definition consts.h:11
#define CONST_E
Elementary charge [C]
Definition consts.h:32
void dist_6D_update_fo(dist_6D_data *dist, particle_simd_fo *p_f, particle_simd_fo *p_i)
Update the histogram from full-orbit particles.
Definition dist_6D.c:121
void dist_6D_init(dist_6D_data *dist_data, dist_6D_offload_data *offload_data, real *offload_array)
Initializes distribution from offload data.
Definition dist_6D.c:58
void dist_6D_free_offload(dist_6D_offload_data *offload_data)
Frees the offload data.
Definition dist_6D.c:34
void dist_6D_update_gc(dist_6D_data *dist, particle_simd_gc *p_f, particle_simd_gc *p_i)
Update the histogram from guiding-center particles.
Definition dist_6D.c:187
size_t dist_6D_index(int i_r, int i_phi, int i_z, int i_pr, int i_pphi, int i_pz, int i_time, int i_q, size_t step_7, size_t step_6, size_t step_5, size_t step_4, size_t step_3, size_t step_2, size_t step_1)
Internal function calculating the index in the histogram array.
Definition dist_6D.c:17
Header file for dist_6D.c.
void gctransform_pparmuzeta2prpphipz(real mass, real charge, real *B_dB, real phi, real ppar, real mu, real zeta, real *pr, real *pphi, real *pz)
Transform particle ppar, mu, and zeta to momentum vector.
Header file for gctransform.c.
real fmod(real x, real y)
Compute the modulus of two real numbers.
Definition math.c:22
Header file for math.c.
Methods to evaluate elementary physical quantities.
Histogram parameters on target.
Definition dist_6D.h:52
real max_phi
Definition dist_6D.h:59
real min_phi
Definition dist_6D.h:58
size_t step_7
Definition dist_6D.h:91
real * histogram
Definition dist_6D.h:93
size_t step_3
Definition dist_6D.h:87
real min_pz
Definition dist_6D.h:74
real max_pz
Definition dist_6D.h:75
real min_time
Definition dist_6D.h:78
size_t step_5
Definition dist_6D.h:89
real min_q
Definition dist_6D.h:82
size_t step_4
Definition dist_6D.h:88
real max_pphi
Definition dist_6D.h:71
real max_time
Definition dist_6D.h:79
real min_pphi
Definition dist_6D.h:70
real min_pr
Definition dist_6D.h:66
real max_pr
Definition dist_6D.h:67
size_t step_6
Definition dist_6D.h:90
size_t step_1
Definition dist_6D.h:85
real max_z
Definition dist_6D.h:63
real min_r
Definition dist_6D.h:54
real max_r
Definition dist_6D.h:55
real max_q
Definition dist_6D.h:83
size_t step_2
Definition dist_6D.h:86
real min_z
Definition dist_6D.h:62
Histogram parameters that will be offloaded to target.
Definition dist_6D.h:15
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