ASCOT5
Loading...
Searching...
No Matches
dist_5D.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_5D.h"
12#include "../particle.h"
13
17size_t dist_5D_index(int i_r, int i_phi, int i_z, int i_ppara, int i_pperp,
18 int i_time, int i_q, size_t step_6, size_t step_5,
19 size_t step_4, size_t step_3, size_t step_2,
20 size_t step_1) {
21 return (size_t)(i_r) * step_6
22 + (size_t)(i_phi) * step_5
23 + (size_t)(i_z) * step_4
24 + (size_t)(i_ppara) * step_3
25 + (size_t)(i_pperp) * step_2
26 + (size_t)(i_time) * step_1
27 + (size_t)(i_q);
28}
29
36 offload_data->n_r = 0;
37 offload_data->min_r = 0;
38 offload_data->max_r = 0;
39 offload_data->n_phi = 0;
40 offload_data->min_phi = 0;
41 offload_data->max_phi = 0;
42 offload_data->n_z = 0;
43 offload_data->min_z = 0;
44 offload_data->max_z = 0;
45 offload_data->n_ppara = 0;
46 offload_data->min_ppara = 0;
47 offload_data->max_ppara = 0;
48 offload_data->n_pperp = 0;
49 offload_data->min_pperp = 0;
50 offload_data->max_pperp = 0;
51}
52
60void dist_5D_init(dist_5D_data* dist_data, dist_5D_offload_data* offload_data,
61 real* offload_array) {
62 dist_data->n_r = offload_data->n_r;
63 dist_data->min_r = offload_data->min_r;
64 dist_data->max_r = offload_data->max_r;
65
66 dist_data->n_phi = offload_data->n_phi;
67 dist_data->min_phi = offload_data->min_phi;
68 dist_data->max_phi = offload_data->max_phi;
69
70 dist_data->n_z = offload_data->n_z;
71 dist_data->min_z = offload_data->min_z;
72 dist_data->max_z = offload_data->max_z;
73
74 dist_data->n_ppara = offload_data->n_ppara;
75 dist_data->min_ppara = offload_data->min_ppara;
76 dist_data->max_ppara = offload_data->max_ppara;
77
78 dist_data->n_pperp = offload_data->n_pperp;
79 dist_data->min_pperp = offload_data->min_pperp;
80 dist_data->max_pperp = offload_data->max_pperp;
81
82 dist_data->n_time = offload_data->n_time;
83 dist_data->min_time = offload_data->min_time;
84 dist_data->max_time = offload_data->max_time;
85
86 dist_data->n_q = offload_data->n_q;
87 dist_data->min_q = offload_data->min_q;
88 dist_data->max_q = offload_data->max_q;
89
90 size_t n_q = (size_t)(dist_data->n_q);
91 size_t n_time = (size_t)(dist_data->n_time);
92 size_t n_pperp = (size_t)(dist_data->n_pperp);
93 size_t n_ppara = (size_t)(dist_data->n_ppara);
94 size_t n_z = (size_t)(dist_data->n_z);
95 size_t n_phi = (size_t)(dist_data->n_phi);
96 dist_data->step_6 = n_q * n_time * n_pperp * n_ppara * n_z * n_phi;
97 dist_data->step_5 = n_q * n_time * n_pperp * n_ppara * n_z;
98 dist_data->step_4 = n_q * n_time * n_pperp * n_ppara;
99 dist_data->step_3 = n_q * n_time * n_pperp;
100 dist_data->step_2 = n_q * n_time;
101 dist_data->step_1 = n_q;
102
103 dist_data->histogram = &offload_array[0];
104}
105
118 particle_simd_fo* p_i) {
119
120 GPU_PARALLEL_LOOP_ALL_LEVELS
121 for(int i = 0; i < p_f->n_mrk; i++) {
122 if(p_f->running[i]) {
123 real i_r = floor((p_f->r[i] - dist->min_r)
124 / ((dist->max_r - dist->min_r)/dist->n_r));
125
126 real phi = fmod(p_f->phi[i], 2*CONST_PI);
127 if(phi < 0) {
128 phi += 2*CONST_PI;
129 }
130 int i_phi = floor((phi - dist->min_phi)
131 / ((dist->max_phi - dist->min_phi)/dist->n_phi));
132
133 int i_z = floor((p_f->z[i] - dist->min_z)
134 / ((dist->max_z - dist->min_z) / dist->n_z));
135
136 real ppara = ( p_f->p_r[i] * p_f->B_r[i]
137 + p_f->p_phi[i] * p_f->B_phi[i]
138 + p_f->p_z[i] * p_f->B_z[i])
139 / sqrt( p_f->B_r[i] * p_f->B_r[i]
140 + p_f->B_phi[i]* p_f->B_phi[i]
141 + p_f->B_z[i] * p_f->B_z[i]);
142 int i_ppara = floor((ppara - dist->min_ppara)
143 / ((dist->max_ppara - dist->min_ppara) / dist->n_ppara));
144
145 real pperp = sqrt(
146 p_f->p_r[i] * p_f->p_r[i]
147 + p_f->p_phi[i] * p_f->p_phi[i]
148 + p_f->p_z[i] * p_f->p_z[i]
149 - ppara * ppara);
150 int i_pperp = floor((pperp - dist->min_pperp)
151 / ((dist->max_pperp - dist->min_pperp) / dist->n_pperp));
152
153 int i_time = floor((p_f->time[i] - dist->min_time)
154 / ((dist->max_time - dist->min_time) / dist->n_time));
155
156 int i_q = floor((p_f->charge[i]/CONST_E - dist->min_q)
157 / ((dist->max_q - dist->min_q) / dist->n_q));
158
159 if(i_r >= 0 && i_r <= dist->n_r - 1 &&
160 i_phi >= 0 && i_phi <= dist->n_phi - 1 &&
161 i_z >= 0 && i_z <= dist->n_z - 1 &&
162 i_ppara >= 0 && i_ppara <= dist->n_ppara - 1 &&
163 i_pperp >= 0 && i_pperp <= dist->n_pperp - 1 &&
164 i_time >= 0 && i_time <= dist->n_time - 1 &&
165 i_q >= 0 && i_q <= dist->n_q - 1 ) {
166 real weight = p_f->weight[i] * (p_f->time[i] - p_i->time[i]);
167
168 size_t index = dist_5D_index(
169 i_r, i_phi, i_z, i_ppara, i_pperp, i_time,
170 i_q, dist->step_6, dist->step_5, dist->step_4,
171 dist->step_3, dist->step_2, dist->step_1);
172 GPU_ATOMIC
173 dist->histogram[index] += weight;
174 }
175 }
176 }
177}
178
191 particle_simd_gc* p_i) {
192 real phi[NSIMD];
193 real pperp[NSIMD];
194
195 int i_r[NSIMD];
196 int i_phi[NSIMD];
197 int i_z[NSIMD];
198 int i_ppara[NSIMD];
199 int i_pperp[NSIMD];
200 int i_time[NSIMD];
201 int i_q[NSIMD];
202
203 int ok[NSIMD];
204 real weight[NSIMD];
205
206 #pragma omp simd
207 for(int i = 0; i < NSIMD; i++) {
208 if(p_f->running[i]) {
209 i_r[i] = floor((p_f->r[i] - dist->min_r)
210 / ((dist->max_r - dist->min_r)/dist->n_r));
211
212 phi[i] = fmod(p_f->phi[i], 2*CONST_PI);
213 if(phi[i] < 0) {
214 phi[i] = phi[i] + 2*CONST_PI;
215 }
216 i_phi[i] = floor((phi[i] - dist->min_phi)
217 / ((dist->max_phi - dist->min_phi)/dist->n_phi));
218
219 i_z[i] = floor((p_f->z[i] - dist->min_z)
220 / ((dist->max_z - dist->min_z) / dist->n_z));
221
222 i_ppara[i] = floor((p_f->ppar[i] - dist->min_ppara)
223 / ((dist->max_ppara - dist->min_ppara) / dist->n_ppara));
224
225 pperp[i] = sqrt(2 * sqrt( p_f->B_r[i] * p_f->B_r[i]
226 + p_f->B_phi[i] * p_f->B_phi[i]
227 + p_f->B_z[i] * p_f->B_z[i] )
228 * p_f->mu[i] * p_f->mass[i]);
229 i_pperp[i] = floor((pperp[i] - dist->min_pperp)
230 / ((dist->max_pperp - dist->min_pperp) / dist->n_pperp));
231
232 i_time[i] = floor((p_f->time[i] - dist->min_time)
233 / ((dist->max_time - dist->min_time) / dist->n_time));
234
235 i_q[i] = floor((p_f->charge[i]/CONST_E - dist->min_q)
236 / ((dist->max_q - dist->min_q) / dist->n_q));
237
238 if(i_r[i] >= 0 && i_r[i] <= dist->n_r - 1 &&
239 i_phi[i] >= 0 && i_phi[i] <= dist->n_phi - 1 &&
240 i_z[i] >= 0 && i_z[i] <= dist->n_z - 1 &&
241 i_ppara[i] >= 0 && i_ppara[i] <= dist->n_ppara - 1 &&
242 i_pperp[i] >= 0 && i_pperp[i] <= dist->n_pperp - 1 &&
243 i_time[i] >= 0 && i_time[i] <= dist->n_time - 1 &&
244 i_q[i] >= 0 && i_q[i] <= dist->n_q - 1 ) {
245 ok[i] = 1;
246 weight[i] = p_f->weight[i] * (p_f->time[i] - p_i->time[i]);
247 }
248 else {
249 ok[i] = 0;
250 }
251 }
252 }
253
254 for(int i = 0; i < NSIMD; i++) {
255 if(p_f->running[i] && ok[i]) {
256 size_t index = dist_5D_index(
257 i_r[i], i_phi[i], i_z[i], i_ppara[i], i_pperp[i], i_time[i],
258 i_q[i], dist->step_6, dist->step_5, dist->step_4,
259 dist->step_3, dist->step_2, dist->step_1);
260 #pragma omp atomic
261 dist->histogram[index] += weight[i];
262 }
263 }
264}
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_5D_update_gc(dist_5D_data *dist, particle_simd_gc *p_f, particle_simd_gc *p_i)
Update the histogram from guiding center markers.
Definition dist_5D.c:190
void dist_5D_init(dist_5D_data *dist_data, dist_5D_offload_data *offload_data, real *offload_array)
Initializes distribution from offload data.
Definition dist_5D.c:60
size_t dist_5D_index(int i_r, int i_phi, int i_z, int i_ppara, int i_pperp, int i_time, int i_q, size_t step_6, size_t step_5, size_t step_4, size_t step_3, size_t step_2, size_t step_1)
Function for calculating the index in the histogram array.
Definition dist_5D.c:17
void dist_5D_free_offload(dist_5D_offload_data *offload_data)
Frees the offload data.
Definition dist_5D.c:35
void dist_5D_update_fo(dist_5D_data *dist, particle_simd_fo *p_f, particle_simd_fo *p_i)
Update the histogram from full-orbit particles.
Definition dist_5D.c:117
Header file for dist_5D.c.
real fmod(real x, real y)
Compute the modulus of two real numbers.
Definition math.c:22
Header file for math.c.
Header file for particle.c.
Methods to evaluate elementary physical quantities.
Histogram parameters on target.
Definition dist_5D.h:48
real min_time
Definition dist_5D.h:70
real max_r
Definition dist_5D.h:51
real max_pperp
Definition dist_5D.h:67
size_t step_5
Definition dist_5D.h:81
real min_phi
Definition dist_5D.h:54
size_t step_3
Definition dist_5D.h:79
real max_phi
Definition dist_5D.h:55
real min_ppara
Definition dist_5D.h:62
size_t step_1
Definition dist_5D.h:77
real max_z
Definition dist_5D.h:59
real max_time
Definition dist_5D.h:71
size_t step_2
Definition dist_5D.h:78
int n_ppara
Definition dist_5D.h:61
size_t step_6
Definition dist_5D.h:82
int n_pperp
Definition dist_5D.h:65
real min_z
Definition dist_5D.h:58
real max_ppara
Definition dist_5D.h:63
real min_r
Definition dist_5D.h:50
real max_q
Definition dist_5D.h:75
real * histogram
Definition dist_5D.h:84
real min_pperp
Definition dist_5D.h:66
size_t step_4
Definition dist_5D.h:80
real min_q
Definition dist_5D.h:74
Histogram parameters that will be offloaded to target.
Definition dist_5D.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