ASCOT5
Loading...
Searching...
No Matches
nbi.c
Go to the documentation of this file.
1
5#include <stdlib.h>
6#include <math.h>
7#include "print.h"
8#include "ascot5.h"
9#include "consts.h"
10#include "physlib.h"
11#include "math.h"
12#include "random.h"
13#include "nbi.h"
14
23int nbi_init_offload(nbi_offload_data* offload_data, real** offload_array) {
24 int err = 0;
25 print_out(VERBOSE_IO, "\nNBI input\n");
26 print_out(VERBOSE_IO, "Number of injectors %d:\n", offload_data->ninj);
27 for(int i=0; i<offload_data->ninj; i++) {
28 print_out(VERBOSE_IO, "\n Injector ID %d (%d beamlets) Power: %1.1e\n",
29 offload_data->id[i], offload_data->n_beamlet[i],
30 offload_data->power[i]);
32 " Anum %d Znum %d mass %1.1e amu energy %1.1e eV\n",
33 offload_data->anum[i], offload_data->znum[i],
34 offload_data->mass[i] / CONST_U,
35 offload_data->energy[i] / CONST_E);
37 " Energy fractions: %1.1e (Full) %1.1e (1/2) %1.1e (1/3)\n",
38 offload_data->efrac[0], offload_data->efrac[1],
39 offload_data->efrac[2]);
40
41 /* Even if halo fraction is zero, the divergences should be nonzero
42 to avoid division by zero during evaluation. Do this after the
43 input has been printed as to not confuse the user */
44 if(offload_data->div_halo_frac[i] == 0) {
45 offload_data->div_halo_h[i] = 1e-10;
46 offload_data->div_halo_v[i] = 1e-10;
47 }
48 }
49 return err;
50}
51
59void nbi_init(nbi_data* nbi, nbi_offload_data* offload_data,
60 real* offload_array) {
61 int idx = 0;
62 nbi->ninj = offload_data->ninj;
63 for(int i=0; i<nbi->ninj; i++) {
64 nbi->inj[i].anum = offload_data->anum[i];
65 nbi->inj[i].znum = offload_data->znum[i];
66 nbi->inj[i].mass = offload_data->mass[i];
67 nbi->inj[i].power = offload_data->power[i];
68 nbi->inj[i].energy = offload_data->energy[i];
69 nbi->inj[i].efrac[0] = offload_data->efrac[3*i+0];
70 nbi->inj[i].efrac[1] = offload_data->efrac[3*i+1];
71 nbi->inj[i].efrac[2] = offload_data->efrac[3*i+2];
72 nbi->inj[i].div_h = offload_data->div_h[i];
73 nbi->inj[i].div_v = offload_data->div_v[i];
74 nbi->inj[i].div_halo_frac = offload_data->div_halo_frac[i];
75 nbi->inj[i].div_halo_h = offload_data->div_halo_h[i];
76 nbi->inj[i].div_halo_v = offload_data->div_halo_v[i];
77 nbi->inj[i].id = offload_data->id[i];
78 nbi->inj[i].n_beamlet = offload_data->n_beamlet[i];
79
80 int n_beamlet = nbi->inj[i].n_beamlet;
81 nbi->inj[i].beamlet_x = &(offload_array[idx + 0*n_beamlet]);
82 nbi->inj[i].beamlet_y = &(offload_array[idx + 1*n_beamlet]);
83 nbi->inj[i].beamlet_z = &(offload_array[idx + 2*n_beamlet]);
84 nbi->inj[i].beamlet_dx = &(offload_array[idx + 3*n_beamlet]);
85 nbi->inj[i].beamlet_dy = &(offload_array[idx + 4*n_beamlet]);
86 nbi->inj[i].beamlet_dz = &(offload_array[idx + 5*n_beamlet]);
87 idx += 6 * n_beamlet;
88 }
89}
90
98 real** offload_array) {
99 for(int i=0; i<offload_data->ninj; i++) {
100 offload_data->n_beamlet[i] = 0;
101 }
102 offload_data->ninj = 0;
103 free(*offload_array);
104}
105
114void nbi_inject(real* xyz, real* vxyz, nbi_injector* inj, random_data* rng) {
115 /* Pick a random beamlet and initialize marker there */
116 int i_beamlet = floor(random_uniform(rng) * inj->n_beamlet);
117 xyz[0] = inj->beamlet_x[i_beamlet];
118 xyz[1] = inj->beamlet_y[i_beamlet];
119 xyz[2] = inj->beamlet_z[i_beamlet];
120
121 /* Pick marker energy based on the energy fractions */
122 real energy;
123 real r = random_uniform(rng);
124 if(r < inj->efrac[0]) {
125 energy = inj->energy;
126 } else if(r < inj->efrac[0] + inj->efrac[1]) {
127 energy = inj->energy / 2;
128 } else {
129 energy = inj->energy / 3;
130 }
131
132 /* Calculate vertical and horizontal normals for beam divergence */
133 real dir[3], normalv[3], normalh[3], tmp[3];
134 dir[0] = inj->beamlet_dx[i_beamlet];
135 dir[1] = inj->beamlet_dy[i_beamlet];
136 dir[2] = inj->beamlet_dz[i_beamlet];
137
138 real phi = atan2(dir[1], dir[0]);
139 real theta = acos(dir[2]);
140
141 normalv[0] = sin(theta+CONST_PI/2) * cos(phi);
142 normalv[1] = sin(theta+CONST_PI/2) * sin(phi);
143 normalv[2] = cos(theta+CONST_PI/2);
144
145 math_cross(dir, normalv, tmp);
146 math_unit(tmp, normalh);
147
148 /* Generate a random number on interval [0,1]. If the number is smaller
149 * than the halo fraction, this marker will be considered as part
150 * of the halo. The divergences are different for the core and halo.
151 * Additionally, two normally distributed random variables are generated:
152 * the divergences in horizontal and the vertical directions. */
153 real div_h, div_v;
154 if(random_uniform(rng) < inj->div_halo_frac) {
155 // Use halo divergences instead
156 div_h = inj->div_halo_h * random_normal(rng) / sqrt(2.0);
157 div_v = inj->div_halo_v * random_normal(rng) / sqrt(2.0);
158 } else {
159 div_h = inj->div_h * random_normal(rng) / sqrt(2.0);
160 div_v = inj->div_v * random_normal(rng) / sqrt(2.0);
161 }
162
163 /* Convert the divergence angle to an unit vector. The marker velocity
164 * vector points in the direction of v_beam + v_divergence. */
165 tmp[0] = cos(div_h) * ( cos(div_v) * dir[0] + sin(div_v) * normalv[0] )
166 + sin(div_h) * normalh[0];
167 tmp[1] = cos(div_h) * ( cos(div_v) * dir[1] + sin(div_v) * normalv[1] )
168 + sin(div_h) * normalh[1];
169 tmp[2] = cos(div_h) * ( cos(div_v) * dir[2] + sin(div_v) * normalv[2] )
170 + sin(div_h) * normalh[2];
171 math_unit(tmp, dir);
172
173 real gamma = physlib_gamma_Ekin(inj->mass, energy);
174 real absv = sqrt( 1.0 - 1.0 / (gamma * gamma) ) * CONST_C;
175 vxyz[0] = absv * dir[0];
176 vxyz[1] = absv * dir[1];
177 vxyz[2] = absv * dir[2];
178}
Main header file for ASCOT5.
double real
Definition ascot5.h:85
Header file containing physical and mathematical constants.
#define CONST_U
Atomic mass unit in kilograms [kg]
Definition consts.h:29
#define CONST_PI
pi
Definition consts.h:11
#define CONST_C
Speed of light [m/s]
Definition consts.h:23
#define CONST_E
Elementary charge [C]
Definition consts.h:32
Header file for math.c.
#define math_unit(a, b)
Calculate unit vector b from a 3D vector a.
Definition math.h:70
#define math_cross(a, b, c)
Calculate cross product for 3D vectors c = a x b.
Definition math.h:31
void nbi_free_offload(nbi_offload_data *offload_data, real **offload_array)
Free offload array.
Definition nbi.c:97
void nbi_init(nbi_data *nbi, nbi_offload_data *offload_data, real *offload_array)
Initialize NBI data struct on target.
Definition nbi.c:59
int nbi_init_offload(nbi_offload_data *offload_data, real **offload_array)
Load NBI data and prepare parameters for offload.
Definition nbi.c:23
void nbi_inject(real *xyz, real *vxyz, nbi_injector *inj, random_data *rng)
Sample injected marker's coordinates.
Definition nbi.c:114
Header file for nbi.c.
Methods to evaluate elementary physical quantities.
#define physlib_gamma_Ekin(m, ekin)
Evaluate Lorentz factor from kinetic energy [J].
Definition physlib.h:103
Macros for printing console output.
#define print_out(v,...)
Print to standard output.
Definition print.h:31
@ VERBOSE_IO
Definition print.h:20
Header file for random.c.
void * random_data
Definition random.h:87
#define random_uniform(data)
Definition random.h:96
#define random_normal(data)
Definition random.h:98
NBI data on target.
Definition nbi.h:61
int ninj
Definition nbi.h:62
nbi_injector inj[NBI_MAX_INJ]
Definition nbi.h:63
Structure for describing an NBI injector.
Definition nbi.h:15
real mass
Definition nbi.h:34
int id
Definition nbi.h:16
real efrac[3]
Definition nbi.h:26
real * beamlet_x
Definition nbi.h:18
int anum
Definition nbi.h:32
real * beamlet_dy
Definition nbi.h:22
real energy
Definition nbi.h:25
real div_halo_h
Definition nbi.h:30
real power
Definition nbi.h:24
real * beamlet_y
Definition nbi.h:19
int znum
Definition nbi.h:33
real * beamlet_dz
Definition nbi.h:23
real div_halo_frac
Definition nbi.h:29
real * beamlet_dx
Definition nbi.h:21
real * beamlet_z
Definition nbi.h:20
int n_beamlet
Definition nbi.h:17
real div_halo_v
Definition nbi.h:31
real div_v
Definition nbi.h:28
real div_h
Definition nbi.h:27
NBI parameters consisting of a bundle of injectors.
Definition nbi.h:40
real div_v[NBI_MAX_INJ]
Definition nbi.h:48
real div_halo_v[NBI_MAX_INJ]
Definition nbi.h:51
real div_halo_h[NBI_MAX_INJ]
Definition nbi.h:50
int znum[NBI_MAX_INJ]
Definition nbi.h:53
real div_h[NBI_MAX_INJ]
Definition nbi.h:47
int n_beamlet[NBI_MAX_INJ]
Definition nbi.h:43
real mass[NBI_MAX_INJ]
Definition nbi.h:54
int anum[NBI_MAX_INJ]
Definition nbi.h:52
real energy[NBI_MAX_INJ]
Definition nbi.h:45
int id[NBI_MAX_INJ]
Definition nbi.h:42
real div_halo_frac[NBI_MAX_INJ]
Definition nbi.h:49
real power[NBI_MAX_INJ]
Definition nbi.h:44
real efrac[NBI_MAX_INJ *3]
Definition nbi.h:46