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
68
69 GPU_PARALLEL_LOOP_ALL_LEVELS
70 for(int i = 0; i < p_f->n_mrk; i++) {
71 if(p_f->running[i]) {
72 real Ekin, Ptor, Bnorm, psi, mu, xi, pnorm, ppar;
73
74 B_field_eval_psi(&psi, p_f->r[i], p_f->phi[i], p_f->z[i],
75 p_f->time[i], Bdata);
76
77 real B [] = {p_f->B_r[i], p_f->B_phi[i], p_f->B_z[i]};
78 Bnorm = math_normc(p_f->B_r[i], p_f->B_phi[i], p_f->B_z[i]);
79
80 real p [] = {p_f->p_r[i], p_f->p_phi[i], p_f->p_z[i]};
81 pnorm = math_normc(p_f->p_r[i], p_f->p_phi[i], p_f->p_z[i]);
82 ppar = math_dot(p, B) / Bnorm;
83 xi = ppar / pnorm;
84
85 mu = physlib_gc_mu(p_f->mass[i], pnorm, xi, Bnorm);
86 int i_mu = floor((mu - dist->min_mu)
87 / ((dist->max_mu - dist->min_mu)/dist->n_mu));
88 Ekin = physlib_Ekin_pnorm(p_f->mass[i], pnorm);
89
90 int i_Ekin = floor((Ekin - dist->min_Ekin)
91 / ((dist->max_Ekin - dist->min_Ekin) / dist->n_Ekin));
92 Ptor = phys_ptoroid_fo(
93 p_f->charge[i], p_f->r[i], p_f->p_phi[i], psi);
94
95 int i_Ptor = floor((Ptor - dist->min_Ptor)
96 / ((dist->max_Ptor - dist->min_Ptor)/dist->n_Ptor));
97
98 if(i_mu >= 0 && i_mu <= dist->n_mu - 1 &&
99 i_Ekin >= 0 && i_Ekin <= dist->n_Ekin - 1 &&
100 i_Ptor >= 0 && i_Ptor <= dist->n_Ptor - 1 ) {
101 real weight = p_f->weight[i] * (p_f->time[i] - p_i->time[i]);
102 size_t index = dist_COM_index(
103 i_mu, i_Ekin, i_Ptor, dist->step_2, dist->step_1);
104 GPU_ATOMIC
105 dist->histogram[index] += weight;
106 }
107 }
108 }
109}
110
125 int i_mu[NSIMD];
126 int i_Ekin[NSIMD];
127 int i_Ptor[NSIMD];
128
129 int ok[NSIMD];
130 real weight[NSIMD];
131
132 #pragma omp simd
133 for(int i = 0; i < NSIMD; i++) {
134 if(p_f->running[i]) {
135 real Ekin, Ptor, B, psi;
136
137 B_field_eval_psi(&psi, p_f->r[i], p_f->phi[i], p_f->z[i],
138 p_f->time[i], Bdata);
139
140 B = math_normc(p_f->B_r[i], p_f->B_phi[i], p_f->B_z[i]);
141 i_mu[i] = floor((p_f->mu[i] - dist->min_mu)
142 / ((dist->max_mu - dist->min_mu)/dist->n_mu));
143
144 Ekin = physlib_Ekin_ppar(p_f->mass[i], p_f->mu[i], p_f->ppar[i], B);
145
146 i_Ekin[i] = floor((Ekin - dist->min_Ekin)
147 / ((dist->max_Ekin - dist->min_Ekin) / dist->n_Ekin));
148 Ptor = phys_ptoroid_gc(p_f->charge[i], p_f->r[i], p_f->ppar[i], psi,
149 B, p_f->B_phi[i]);
150
151 i_Ptor[i] = floor((Ptor - dist->min_Ptor)
152 / ((dist->max_Ptor - dist->min_Ptor)/dist->n_Ptor));
153
154 if(i_mu[i] >= 0 && i_mu[i] <= dist->n_mu - 1 &&
155 i_Ekin[i] >= 0 && i_Ekin[i] <= dist->n_Ekin - 1 &&
156 i_Ptor[i] >= 0 && i_Ptor[i] <= dist->n_Ptor - 1 ) {
157 ok[i] = 1;
158 weight[i] = p_f->weight[i] * (p_f->time[i] - p_i->time[i]);
159 }
160 else {
161 ok[i] = 0;
162 }
163 }
164 }
165
166 for(int i = 0; i < NSIMD; i++) {
167 if(p_f->running[i] && ok[i]) {
168 size_t index = dist_COM_index(i_mu[i], i_Ekin[i], i_Ptor[i],
169 dist->step_2, dist->step_1);
170 #pragma omp atomic
171 dist->histogram[index] += weight[i];
172 }
173 }
174}
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:66
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_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:123
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