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