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
31 size_t n_Ptor = (size_t)(data->n_Ptor);
32 size_t n_Ekin = (size_t)(data->n_Ekin);
33 data->step_2 = n_Ptor * n_Ekin;
34 data->step_1 = n_Ptor;
35
36 data->histogram = calloc(data->step_2 * (size_t)data->n_mu, sizeof(real));
37 return data->histogram == NULL;
38}
39
46 free(data->histogram);
47}
48
55 GPU_MAP_TO_DEVICE( data->histogram[0:data->n_mu*data->n_Ekin*data->n_Ptor] )
56}
57
64 GPU_UPDATE_FROM_DEVICE(
65 data->histogram[0:data->n_mu*data->n_Ekin*data->n_Ptor]
66 )
67}
68
79
80#ifdef GPU
81 size_t index;
82 real weight;
83#else
84 size_t index[NSIMD];
85 real weight[NSIMD];
86#endif
87
88 GPU_PARALLEL_LOOP_ALL_LEVELS
89 for(int i = 0; i < p_f->n_mrk; i++) {
90 if(p_f->running[i]) {
91 real Ekin, Ptor, Bnorm, psi, mu, xi, pnorm, ppar;
92
93 B_field_eval_psi(&psi, p_f->r[i], p_f->phi[i], p_f->z[i],
94 p_f->time[i], Bdata);
95
96 real B [] = {p_f->B_r[i], p_f->B_phi[i], p_f->B_z[i]};
97 Bnorm = math_normc(p_f->B_r[i], p_f->B_phi[i], p_f->B_z[i]);
98
99 real p [] = {p_f->p_r[i], p_f->p_phi[i], p_f->p_z[i]};
100 pnorm = math_normc(p_f->p_r[i], p_f->p_phi[i], p_f->p_z[i]);
101 ppar = math_dot(p, B) / Bnorm;
102 xi = ppar / pnorm;
103
104 mu = physlib_gc_mu(p_f->mass[i], pnorm, xi, Bnorm);
105 int i_mu = floor((mu - dist->min_mu)
106 / ((dist->max_mu - dist->min_mu)/dist->n_mu));
107 Ekin = physlib_Ekin_pnorm(p_f->mass[i], pnorm);
108
109 int i_Ekin = floor((Ekin - dist->min_Ekin)
110 / ((dist->max_Ekin - dist->min_Ekin) / dist->n_Ekin));
111 Ptor = phys_ptoroid_fo(
112 p_f->charge[i], p_f->r[i], p_f->p_phi[i], psi);
113
114 int i_Ptor = floor((Ptor - dist->min_Ptor)
115 / ((dist->max_Ptor - dist->min_Ptor)/dist->n_Ptor));
116
117 if(i_mu >= 0 && i_mu <= dist->n_mu - 1 &&
118 i_Ekin >= 0 && i_Ekin <= dist->n_Ekin - 1 &&
119 i_Ptor >= 0 && i_Ptor <= dist->n_Ptor - 1 ) {
120#ifdef GPU
121 index = dist_COM_index(
122 i_mu, i_Ekin, i_Ptor, dist->step_2, dist->step_1);
123 weight = p_f->weight[i] * (p_f->time[i] - p_i->time[i]);
124 GPU_ATOMIC
125 dist->histogram[index] += weight;
126#else
127 index[i] = dist_COM_index(
128 i_mu, i_Ekin, i_Ptor, dist->step_2, dist->step_1);
129 weight[i] = p_f->weight[i] * (p_f->time[i] - p_i->time[i]);
130#endif
131 }
132 }
133 }
134#ifndef GPU
135 for(int i = 0; i < p_f->n_mrk; i++) {
136 if(p_f->running[i] && index[i] >= 0 &&
137 index[i] < dist->step_2 * dist->n_mu) {
138 GPU_ATOMIC
139 dist->histogram[index[i]] += weight[i];
140 }
141 }
142#endif
143}
144
159 int i_mu[NSIMD];
160 int i_Ekin[NSIMD];
161 int i_Ptor[NSIMD];
162
163 int ok[NSIMD];
164 real weight[NSIMD];
165
166 #pragma omp simd
167 for(int i = 0; i < NSIMD; i++) {
168 if(p_f->running[i]) {
169 real Ekin, Ptor, B, psi;
170
171 B_field_eval_psi(&psi, p_f->r[i], p_f->phi[i], p_f->z[i],
172 p_f->time[i], Bdata);
173
174 B = math_normc(p_f->B_r[i], p_f->B_phi[i], p_f->B_z[i]);
175 i_mu[i] = floor((p_f->mu[i] - dist->min_mu)
176 / ((dist->max_mu - dist->min_mu)/dist->n_mu));
177
178 Ekin = physlib_Ekin_ppar(p_f->mass[i], p_f->mu[i], p_f->ppar[i], B);
179
180 i_Ekin[i] = floor((Ekin - dist->min_Ekin)
181 / ((dist->max_Ekin - dist->min_Ekin) / dist->n_Ekin));
182 Ptor = phys_ptoroid_gc(p_f->charge[i], p_f->r[i], p_f->ppar[i], psi,
183 B, p_f->B_phi[i]);
184
185 i_Ptor[i] = floor((Ptor - dist->min_Ptor)
186 / ((dist->max_Ptor - dist->min_Ptor)/dist->n_Ptor));
187
188 if(i_mu[i] >= 0 && i_mu[i] <= dist->n_mu - 1 &&
189 i_Ekin[i] >= 0 && i_Ekin[i] <= dist->n_Ekin - 1 &&
190 i_Ptor[i] >= 0 && i_Ptor[i] <= dist->n_Ptor - 1 ) {
191 ok[i] = 1;
192 weight[i] = p_f->weight[i] * (p_f->time[i] - p_i->time[i]);
193 }
194 else {
195 ok[i] = 0;
196 }
197 }
198 }
199
200 for(int i = 0; i < NSIMD; i++) {
201 if(p_f->running[i] && ok[i]) {
202 size_t index = dist_COM_index(i_mu[i], i_Ekin[i], i_Ptor[i],
203 dist->step_2, dist->step_1);
204 #pragma omp atomic
205 dist->histogram[index] += weight[i];
206 }
207 }
208}
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:102
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:77
void dist_COM_free(dist_COM_data *data)
Free allocated resources.
Definition dist_com.c:45
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_offload(dist_COM_data *data)
Offload data to the accelerator.
Definition dist_com.c:54
void dist_COM_onload(dist_COM_data *data)
Onload data back to the host.
Definition dist_com.c:63
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:157
int dist_COM_init(dist_COM_data *data)
Initializes distribution data.
Definition dist_com.c:29
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:32
#define math_normc(a1, a2, a3)
Calculate norm of 3D vector from its components a1, a2, a3.
Definition math.h:71
Header file for particle.c.
Methods to evaluate elementary physical quantities.
#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 particle.
Definition physlib.h:314
#define physlib_gc_mu(m, p, xi, B)
Evaluate guiding center magnetic moment [J/T] from momentum norm and pitch.
Definition physlib.h:182
Magnetic field simulation data.
Definition B_field.h:41
Histogram parameters on target.
Definition dist_com.h:16
real max_Ptor
Definition dist_com.h:27
real * histogram
Definition dist_com.h:32
size_t step_1
Definition dist_com.h:29
real min_Ptor
Definition dist_com.h:26
real min_Ekin
Definition dist_com.h:22
real max_Ekin
Definition dist_com.h:23
size_t step_2
Definition dist_com.h:30
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