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
37 size_t n_q = (size_t)(data->n_q);
38 size_t n_time = (size_t)(data->n_time);
39 size_t n_pperp = (size_t)(data->n_pperp);
40 size_t n_ppara = (size_t)(data->n_ppara);
41 size_t n_z = (size_t)(data->n_z);
42 size_t n_phi = (size_t)(data->n_phi);
43 data->step_6 = n_q * n_time * n_pperp * n_ppara * n_z * n_phi;
44 data->step_5 = n_q * n_time * n_pperp * n_ppara * n_z;
45 data->step_4 = n_q * n_time * n_pperp * n_ppara;
46 data->step_3 = n_q * n_time * n_pperp;
47 data->step_2 = n_q * n_time;
48 data->step_1 = n_q;
49
50 data->histogram = calloc(data->step_6 * (size_t)data->n_r, sizeof(real));
51 return data->histogram == NULL;
52}
53
60 free(data->histogram);
61}
62
69 GPU_MAP_TO_DEVICE(
70 data->histogram[0:data->n_r*data->n_phi*data->n_z*data->n_ppara*data->n_pperp*data->n_time*data->n_q]
71 )
72}
73
80 GPU_UPDATE_FROM_DEVICE(
81 data->histogram[0:data->n_r*data->n_phi*data->n_z*data->n_ppara*data->n_pperp*data->n_time*data->n_q]
82 )
83}
84
97 particle_simd_fo* p_i) {
98
99#ifdef GPU
100 size_t index;
101 real weight;
102#else
103 size_t index[NSIMD];
104 real weight[NSIMD];
105 int valid[NSIMD] = {0};
106#endif
107
108 GPU_PARALLEL_LOOP_ALL_LEVELS
109 for(int i = 0; i < p_f->n_mrk; i++) {
110 if(p_f->running[i]) {
111 real 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 real ppara = ( p_f->p_r[i] * p_f->B_r[i]
125 + p_f->p_phi[i] * p_f->B_phi[i]
126 + p_f->p_z[i] * p_f->B_z[i])
127 / sqrt( p_f->B_r[i] * p_f->B_r[i]
128 + p_f->B_phi[i]* p_f->B_phi[i]
129 + p_f->B_z[i] * p_f->B_z[i]);
130 int i_ppara = floor((ppara - dist->min_ppara)
131 / ((dist->max_ppara - dist->min_ppara) / dist->n_ppara));
132
133 real pperp = sqrt(
134 p_f->p_r[i] * p_f->p_r[i]
135 + p_f->p_phi[i] * p_f->p_phi[i]
136 + p_f->p_z[i] * p_f->p_z[i]
137 - ppara * ppara);
138 int i_pperp = floor((pperp - dist->min_pperp)
139 / ((dist->max_pperp - dist->min_pperp) / dist->n_pperp));
140
141 int i_time = floor((p_f->time[i] - dist->min_time)
142 / ((dist->max_time - dist->min_time) / dist->n_time));
143
144 int i_q = floor((p_f->charge[i]/CONST_E - dist->min_q)
145 / ((dist->max_q - dist->min_q) / dist->n_q));
146
147 if(i_r >= 0 && i_r <= dist->n_r - 1 &&
148 i_phi >= 0 && i_phi <= dist->n_phi - 1 &&
149 i_z >= 0 && i_z <= dist->n_z - 1 &&
150 i_ppara >= 0 && i_ppara <= dist->n_ppara - 1 &&
151 i_pperp >= 0 && i_pperp <= dist->n_pperp - 1 &&
152 i_time >= 0 && i_time <= dist->n_time - 1 &&
153 i_q >= 0 && i_q <= dist->n_q - 1 ) {
154#ifdef GPU
155 index = dist_5D_index(
156 i_r, i_phi, i_z, i_ppara, i_pperp, i_time,
157 i_q, dist->step_6, dist->step_5, dist->step_4,
158 dist->step_3, dist->step_2, dist->step_1);
159 weight = p_f->weight[i] * (p_f->time[i] - p_i->time[i]);
160 GPU_ATOMIC
161 dist->histogram[index] += weight;
162#else
163 index[i] = dist_5D_index(
164 i_r, i_phi, i_z, i_ppara, i_pperp, i_time,
165 i_q, dist->step_6, dist->step_5, dist->step_4,
166 dist->step_3, dist->step_2, dist->step_1);
167 weight[i] = p_f->weight[i] * (p_f->time[i] - p_i->time[i]);
168 valid[i] = 1;
169#endif
170 }
171 }
172 }
173
174#ifndef GPU
175 for(int i = 0; i < p_f->n_mrk; i++) {
176 if(p_f->running[i] && valid[i] == 1) {
177 GPU_ATOMIC
178 dist->histogram[index[i]] += weight[i];
179 }
180 }
181#endif
182}
183
196 particle_simd_gc* p_i) {
197
198 GPU_PARALLEL_LOOP_ALL_LEVELS
199 for(int i = 0; i < p_f->n_mrk; i++) {
200 if(p_f->running[i]) {
201 int i_r = floor((p_f->r[i] - dist->min_r)
202 / ((dist->max_r - dist->min_r)/dist->n_r));
203
204 real phi = fmod(p_f->phi[i], 2*CONST_PI);
205 if(phi < 0) {
206 phi = phi + 2*CONST_PI;
207 }
208 int i_phi = floor((phi - dist->min_phi)
209 / ((dist->max_phi - dist->min_phi)/dist->n_phi));
210
211 int i_z = floor((p_f->z[i] - dist->min_z)
212 / ((dist->max_z - dist->min_z) / dist->n_z));
213
214 int i_ppara = floor((p_f->ppar[i] - dist->min_ppara)
215 / ((dist->max_ppara - dist->min_ppara) / dist->n_ppara));
216
217 real pperp = sqrt(2 * sqrt( p_f->B_r[i] * p_f->B_r[i]
218 + p_f->B_phi[i] * p_f->B_phi[i]
219 + p_f->B_z[i] * p_f->B_z[i] )
220 * p_f->mu[i] * p_f->mass[i]);
221 int i_pperp = floor((pperp - dist->min_pperp)
222 / ((dist->max_pperp - dist->min_pperp) / dist->n_pperp));
223
224 int i_time = floor((p_f->time[i] - dist->min_time)
225 / ((dist->max_time - dist->min_time) / dist->n_time));
226
227 int i_q = floor((p_f->charge[i]/CONST_E - dist->min_q)
228 / ((dist->max_q - dist->min_q) / dist->n_q));
229
230 if(i_r >= 0 && i_r <= dist->n_r - 1 &&
231 i_phi >= 0 && i_phi <= dist->n_phi - 1 &&
232 i_z >= 0 && i_z <= dist->n_z - 1 &&
233 i_ppara >= 0 && i_ppara <= dist->n_ppara - 1 &&
234 i_pperp >= 0 && i_pperp <= dist->n_pperp - 1 &&
235 i_time >= 0 && i_time <= dist->n_time - 1 &&
236 i_q >= 0 && i_q <= dist->n_q - 1 ) {
237 real weight = p_f->weight[i] * (p_f->time[i] - p_i->time[i]);
238 size_t index = dist_5D_index(
239 i_r, i_phi, i_z, i_ppara, i_pperp, i_time,
240 i_q, dist->step_6, dist->step_5, dist->step_4,
241 dist->step_3, dist->step_2, dist->step_1);
242 GPU_ATOMIC
243 dist->histogram[index] += weight;
244 }
245 }
246 }
247}
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_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:195
void dist_5D_onload(dist_5D_data *data)
Onload data back to the host.
Definition dist_5D.c:79
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_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:96
void dist_5D_free(dist_5D_data *data)
Free allocated resources.
Definition dist_5D.c:59
int dist_5D_init(dist_5D_data *data)
Initializes distribution from offload data.
Definition dist_5D.c:35
void dist_5D_offload(dist_5D_data *data)
Offload data to the accelerator.
Definition dist_5D.c:68
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.
Definition dist_5D.h:15
real min_time
Definition dist_5D.h:37
real max_r
Definition dist_5D.h:18
real max_pperp
Definition dist_5D.h:34
size_t step_5
Definition dist_5D.h:48
real min_phi
Definition dist_5D.h:21
size_t step_3
Definition dist_5D.h:46
real max_phi
Definition dist_5D.h:22
real min_ppara
Definition dist_5D.h:29
size_t step_1
Definition dist_5D.h:44
real max_z
Definition dist_5D.h:26
real max_time
Definition dist_5D.h:38
size_t step_2
Definition dist_5D.h:45
int n_ppara
Definition dist_5D.h:28
size_t step_6
Definition dist_5D.h:49
int n_pperp
Definition dist_5D.h:32
real min_z
Definition dist_5D.h:25
real max_ppara
Definition dist_5D.h:30
real min_r
Definition dist_5D.h:17
real max_q
Definition dist_5D.h:42
real * histogram
Definition dist_5D.h:51
real min_pperp
Definition dist_5D.h:33
size_t step_4
Definition dist_5D.h:47
real min_q
Definition dist_5D.h:41
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