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
36 size_t n_q = (size_t)(data->n_q);
37 size_t n_time = (size_t)(data->n_time);
38 size_t n_pz = (size_t)(data->n_pz);
39 size_t n_pphi = (size_t)(data->n_pphi);
40 size_t n_pr = (size_t)(data->n_pr);
41 size_t n_z = (size_t)(data->n_z);
42 size_t n_phi = (size_t)(data->n_phi);
43 data->step_7 = n_q * n_time * n_pz * n_pphi * n_pr * n_z * n_phi;
44 data->step_6 = n_q * n_time * n_pz * n_pphi * n_pr * n_z;
45 data->step_5 = n_q * n_time * n_pz * n_pphi * n_pr;
46 data->step_4 = n_q * n_time * n_pz * n_pphi;
47 data->step_3 = n_q * n_time * n_pz;
48 data->step_2 = n_q * n_time;
49 data->step_1 = n_q;
50
51 data->histogram = calloc(data->step_7 * (size_t)data->n_r, sizeof(real));
52 return data->histogram == NULL;
53}
54
59 free(data->histogram);
60}
61
68 GPU_MAP_TO_DEVICE(
69 data->histogram[0:data->n_r*data->n_phi*data->n_z*data->n_pr*data->n_pphi*data->n_pz*data->n_time*data->n_q]
70 )
71}
72
79 GPU_UPDATE_FROM_DEVICE(
80 data->histogram[0:data->n_r*data->n_phi*data->n_z*data->n_pr*data->n_pphi*data->n_pz*data->n_time*data->n_q]
81 )
82}
83
96 particle_simd_fo* p_i) {
97
98#ifdef GPU
99 size_t index;
100 real weight;
101#else
102 size_t index[NSIMD];
103 real weight[NSIMD];
104 int valid[NSIMD] = {0};
105#endif
106
107 GPU_PARALLEL_LOOP_ALL_LEVELS
108 for(int i = 0; i < p_f->n_mrk; i++) {
109 if(p_f->running[i]) {
110
111 int i_r = floor((p_f->r[i] - dist->min_r)
112 / ((dist->max_r - dist->min_r)/dist->n_r));
113
114 real phi = fmod(p_f->phi[i], 2*CONST_PI);
115 if(phi < 0) {
116 phi += 2*CONST_PI;
117 }
118 int i_phi = floor((phi - dist->min_phi)
119 / ((dist->max_phi - dist->min_phi)/dist->n_phi));
120
121 int i_z = floor((p_f->z[i] - dist->min_z)
122 / ((dist->max_z - dist->min_z) / dist->n_z));
123
124 int i_pr = floor((p_f->p_r[i] - dist->min_pr)
125 / ((dist->max_pr - dist->min_pr) / dist->n_pr));
126
127 int i_pphi = floor((p_f->p_phi[i] - dist->min_pphi)
128 / ((dist->max_pphi - dist->min_pphi) / dist->n_pphi));
129
130 int i_pz = floor((p_f->p_z[i] - dist->min_pz)
131 / ((dist->max_pz - dist->min_pz) / dist->n_pz));
132
133 int i_time = floor((p_f->time[i] - dist->min_time)
134 / ((dist->max_time - dist->min_time) / dist->n_time));
135
136 int i_q = floor((p_f->charge[i]/CONST_E - dist->min_q)
137 / ((dist->max_q - dist->min_q) / dist->n_q));
138
139 if(i_r >= 0 && i_r <= dist->n_r - 1 &&
140 i_phi >= 0 && i_phi <= dist->n_phi - 1 &&
141 i_z >= 0 && i_z <= dist->n_z - 1 &&
142 i_pr >= 0 && i_pr <= dist->n_pr - 1 &&
143 i_pphi >= 0 && i_pphi <= dist->n_pphi - 1 &&
144 i_pz >= 0 && i_pz <= dist->n_pz - 1 &&
145 i_time >= 0 && i_time <= dist->n_time - 1 &&
146 i_q >= 0 && i_q <= dist->n_q - 1 ) {
147#ifdef GPU
148 index = dist_6D_index(
149 i_r, i_phi, i_z, i_pr, i_pphi, i_pz,
150 i_time, i_q, dist->step_7, dist->step_6, dist->step_5,
151 dist->step_4, dist->step_3, dist->step_2, dist->step_1);
152 weight = p_f->weight[i] * (p_f->time[i] - p_i->time[i]);
153 GPU_ATOMIC
154 dist->histogram[index] += weight;
155#else
156 index[i] = dist_6D_index(
157 i_r, i_phi, i_z, i_pr, i_pphi, i_pz,
158 i_time, i_q, dist->step_7, dist->step_6, dist->step_5,
159 dist->step_4, dist->step_3, dist->step_2, dist->step_1);
160 weight[i] = p_f->weight[i] * (p_f->time[i] - p_i->time[i]);
161 valid[i] = 1;
162#endif
163 }
164 }
165 }
166#ifndef GPU
167 for(int i = 0; i < p_f->n_mrk; i++) {
168 if(p_f->running[i] && valid[i] == 1) {
169 GPU_ATOMIC
170 dist->histogram[index[i]] += weight[i];
171 }
172 }
173#endif
174}
175
188 particle_simd_gc* p_i) {
189
190 GPU_PARALLEL_LOOP_ALL_LEVELS
191 for(int i = 0; i < p_f->n_mrk; i++) {
192 if(p_f->running[i]) {
193
194 real pr, pphi, pz;
195 real B_dB[12] = {
196 p_f->B_r[i], p_f->B_r_dr[i], p_f->B_r_dphi[i], p_f->B_r_dz[i],
197 p_f->B_phi[i], p_f->B_phi_dr[i], p_f->B_phi_dphi[i],
198 p_f->B_phi_dz[i],
199 p_f->B_z[i], p_f->B_z_dr[i], p_f->B_z_dphi[i], p_f->B_z_dz[i]};
200 gctransform_pparmuzeta2prpphipz(p_f->mass[i], p_f->charge[i], B_dB,
201 p_f->phi[i], p_f->ppar[i],
202 p_f->mu[i], p_f->zeta[i],
203 &pr, &pphi, &pz);
204
205 int i_r = floor((p_f->r[i] - dist->min_r)
206 / ((dist->max_r - dist->min_r)/dist->n_r));
207
208 real phi = fmod(p_f->phi[i], 2*CONST_PI);
209 if(phi < 0) {
210 phi = phi + 2*CONST_PI;
211 }
212 int i_phi = floor((phi - dist->min_phi)
213 / ((dist->max_phi - dist->min_phi)/dist->n_phi));
214
215 int i_z = floor((p_f->z[i] - dist->min_z)
216 / ((dist->max_z - dist->min_z) / dist->n_z));
217
218 int i_pr = floor((pr - dist->min_pr)
219 / ((dist->max_pr - dist->min_pr) / dist->n_pr));
220
221 int i_pphi = floor((pphi - dist->min_pphi)
222 / ((dist->max_pphi - dist->min_pphi) / dist->n_pphi));
223
224 int i_pz = floor((pz - dist->min_pz)
225 / ((dist->max_pz - dist->min_pz) / dist->n_pz));
226
227 int i_time = floor((p_f->time[i] - dist->min_time)
228 / ((dist->max_time - dist->min_time) / dist->n_time));
229
230 int i_q = floor((p_f->charge[i]/CONST_E - dist->min_q)
231 / ((dist->max_q - dist->min_q) / dist->n_q));
232
233 if(i_r >= 0 && i_r <= dist->n_r - 1 &&
234 i_phi >= 0 && i_phi <= dist->n_phi - 1 &&
235 i_z >= 0 && i_z <= dist->n_z - 1 &&
236 i_pr >= 0 && i_pr <= dist->n_pr - 1 &&
237 i_pphi >= 0 && i_pphi <= dist->n_pphi - 1 &&
238 i_pz >= 0 && i_pz <= dist->n_pz - 1 &&
239 i_time >= 0 && i_time <= dist->n_time - 1 &&
240 i_q >= 0 && i_q <= dist->n_q - 1 ) {
241 real weight = p_f->weight[i] * (p_f->time[i] - p_i->time[i]);
242 size_t index = dist_6D_index(
243 i_r, i_phi, i_z, i_pr, i_pphi, i_pz,
244 i_time, i_q, dist->step_7, dist->step_6, dist->step_5,
245 dist->step_4, dist->step_3, dist->step_2, dist->step_1);
246 GPU_ATOMIC
247 dist->histogram[index] += weight;
248 }
249 }
250 }
251}
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:35
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:95
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
void dist_6D_onload(dist_6D_data *data)
Onload data back to the host.
Definition dist_6D.c:78
int dist_6D_init(dist_6D_data *data)
Initializes distribution data.
Definition dist_6D.c:34
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
void dist_6D_free(dist_6D_data *data)
Free allocated resources.
Definition dist_6D.c:58
void dist_6D_offload(dist_6D_data *data)
Offload data to the accelerator.
Definition dist_6D.c:67
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:15
real max_phi
Definition dist_6D.h:22
real min_phi
Definition dist_6D.h:21
size_t step_7
Definition dist_6D.h:54
real * histogram
Definition dist_6D.h:56
size_t step_3
Definition dist_6D.h:50
real min_pz
Definition dist_6D.h:37
real max_pz
Definition dist_6D.h:38
real min_time
Definition dist_6D.h:41
size_t step_5
Definition dist_6D.h:52
real min_q
Definition dist_6D.h:45
size_t step_4
Definition dist_6D.h:51
real max_pphi
Definition dist_6D.h:34
real max_time
Definition dist_6D.h:42
real min_pphi
Definition dist_6D.h:33
real min_pr
Definition dist_6D.h:29
real max_pr
Definition dist_6D.h:30
size_t step_6
Definition dist_6D.h:53
size_t step_1
Definition dist_6D.h:48
real max_z
Definition dist_6D.h:26
real min_r
Definition dist_6D.h:17
real max_r
Definition dist_6D.h:18
real max_q
Definition dist_6D.h:46
size_t step_2
Definition dist_6D.h:49
real min_z
Definition dist_6D.h:25
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
integer * running
Definition particle.h:320
real * B_phi_dphi
Definition particle.h:299