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->n_mu * data->n_Ptor * data->n_Ekin,
37 sizeof(real) );
38 return data->histogram == NULL;
39}
40
47 free(data->histogram);
48}
49
56 GPU_MAP_TO_DEVICE( data->histogram[0:data->n_mu*data->n_Ekin*data->n_Ptor] )
57}
58
69
70 GPU_PARALLEL_LOOP_ALL_LEVELS
71 for(int i = 0; i < p_f->n_mrk; i++) {
72 if(p_f->running[i]) {
73 real Ekin, Ptor, Bnorm, psi, mu, xi, pnorm, ppar;
74
75 B_field_eval_psi(&psi, p_f->r[i], p_f->phi[i], p_f->z[i],
76 p_f->time[i], Bdata);
77
78 real B [] = {p_f->B_r[i], p_f->B_phi[i], p_f->B_z[i]};
79 Bnorm = math_normc(p_f->B_r[i], p_f->B_phi[i], p_f->B_z[i]);
80
81 real p [] = {p_f->p_r[i], p_f->p_phi[i], p_f->p_z[i]};
82 pnorm = math_normc(p_f->p_r[i], p_f->p_phi[i], p_f->p_z[i]);
83 ppar = math_dot(p, B) / Bnorm;
84 xi = ppar / pnorm;
85
86 mu = physlib_gc_mu(p_f->mass[i], pnorm, xi, Bnorm);
87 int i_mu = floor((mu - dist->min_mu)
88 / ((dist->max_mu - dist->min_mu)/dist->n_mu));
89 Ekin = physlib_Ekin_pnorm(p_f->mass[i], pnorm);
90
91 int i_Ekin = floor((Ekin - dist->min_Ekin)
92 / ((dist->max_Ekin - dist->min_Ekin) / dist->n_Ekin));
93 Ptor = phys_ptoroid_fo(
94 p_f->charge[i], p_f->r[i], p_f->p_phi[i], psi);
95
96 int i_Ptor = floor((Ptor - dist->min_Ptor)
97 / ((dist->max_Ptor - dist->min_Ptor)/dist->n_Ptor));
98
99 if(i_mu >= 0 && i_mu <= dist->n_mu - 1 &&
100 i_Ekin >= 0 && i_Ekin <= dist->n_Ekin - 1 &&
101 i_Ptor >= 0 && i_Ptor <= dist->n_Ptor - 1 ) {
102 real weight = p_f->weight[i] * (p_f->time[i] - p_i->time[i]);
103 size_t index = dist_COM_index(
104 i_mu, i_Ekin, i_Ptor, dist->step_2, dist->step_1);
105 GPU_ATOMIC
106 dist->histogram[index] += weight;
107 }
108 }
109 }
110}
111
126 int i_mu[NSIMD];
127 int i_Ekin[NSIMD];
128 int i_Ptor[NSIMD];
129
130 int ok[NSIMD];
131 real weight[NSIMD];
132
133 #pragma omp simd
134 for(int i = 0; i < NSIMD; i++) {
135 if(p_f->running[i]) {
136 real Ekin, Ptor, B, psi;
137
138 B_field_eval_psi(&psi, p_f->r[i], p_f->phi[i], p_f->z[i],
139 p_f->time[i], Bdata);
140
141 B = math_normc(p_f->B_r[i], p_f->B_phi[i], p_f->B_z[i]);
142 i_mu[i] = floor((p_f->mu[i] - dist->min_mu)
143 / ((dist->max_mu - dist->min_mu)/dist->n_mu));
144
145 Ekin = physlib_Ekin_ppar(p_f->mass[i], p_f->mu[i], p_f->ppar[i], B);
146
147 i_Ekin[i] = floor((Ekin - dist->min_Ekin)
148 / ((dist->max_Ekin - dist->min_Ekin) / dist->n_Ekin));
149 Ptor = phys_ptoroid_gc(p_f->charge[i], p_f->r[i], p_f->ppar[i], psi,
150 B, p_f->B_phi[i]);
151
152 i_Ptor[i] = floor((Ptor - dist->min_Ptor)
153 / ((dist->max_Ptor - dist->min_Ptor)/dist->n_Ptor));
154
155 if(i_mu[i] >= 0 && i_mu[i] <= dist->n_mu - 1 &&
156 i_Ekin[i] >= 0 && i_Ekin[i] <= dist->n_Ekin - 1 &&
157 i_Ptor[i] >= 0 && i_Ptor[i] <= dist->n_Ptor - 1 ) {
158 ok[i] = 1;
159 weight[i] = p_f->weight[i] * (p_f->time[i] - p_i->time[i]);
160 }
161 else {
162 ok[i] = 0;
163 }
164 }
165 }
166
167 for(int i = 0; i < NSIMD; i++) {
168 if(p_f->running[i] && ok[i]) {
169 size_t index = dist_COM_index(i_mu[i], i_Ekin[i], i_Ptor[i],
170 dist->step_2, dist->step_1);
171 #pragma omp atomic
172 dist->histogram[index] += weight[i];
173 }
174 }
175}
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:67
void dist_COM_free(dist_COM_data *data)
Free allocated resources.
Definition dist_com.c:46
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:55
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:124
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:28
#define math_normc(a1, a2, a3)
Calculate norm of 3D vector from its components a1, a2, a3.
Definition math.h:67
Header file for particle.c.
Methods to evaluate elementary physical quantities.
#define phys_ptoroid_fo(q, R, pphi, psi)
Evaluate toroidal canonical momentum for particle.
Definition physlib.h:280
#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 guiding center.
Definition physlib.h:287
#define physlib_gc_mu(m, p, xi, B)
Evaluate guiding center magnetic moment [J/T] from momentum norm and pitch.
Definition physlib.h:180
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