21#include "hdf5io/hdf5_dist.h"
34 real vol,
int nsample,
size_t i0,
size_t i1,
size_t i2,
40 size_t i0,
size_t i1,
size_t i2,
real* density,
67 strcpy(sim->
qid, qid);
69 int mpi_rank = 0, mpi_root = 0;
72 "Tag %s\nBranch %s\n\n", GIT_VERSION, GIT_BRANCH);
80 "\nInitializing output failed.\n"
81 "See stderr for details.\n");
86 real m1, q1, m2, q2, mprod1, qprod1, mprod2, qprod2, Q;
89 &mprod1, &qprod1, &mprod2, &qprod2, &Q);
92 int i0coord, i1coord, i2coord, p1coord, p2coord;
93 if(prod1->
axes[0].
n) {
98 else if(prod1->
axes[3].
n) {
106 if(prod1->
axes[5].
n) {
109 prod_mom_space = PPARPPERP;
111 else if(prod1->
axes[10].
n) {
114 prod_mom_space = EKINXI;
121 #pragma omp parallel for
122 for(
size_t i0 = 0; i0 < afsi->
volshape[0]; i0++) {
132 for(
size_t i1 = 0; i1 < afsi->
volshape[1]; i1++) {
133 for(
size_t i2 = 0; i2 < afsi->
volshape[2]; i2++) {
136 real r = afsi->
r[spatial_index];
137 real z = afsi->
z[spatial_index];
138 real phi = afsi->
phi[spatial_index];
139 real vol = afsi->
vol[spatial_index];
147 real density1, density2;
149 sim, afsi, m1, m2, vol, n, i0, i1, i2,
150 r, phi, z, time, rho[0],
151 &density1, ppara1, pperp1, &density2, ppara2, pperp2);
152 if(density1 == 0 || density2 == 0) {
155 for(
size_t i = 0; i < n; i++) {
158 i, m1, m2, mprod1, mprod2, Q, prod_mom_space,
159 ppara1, pperp1, ppara2, pperp2, &vcom2,
160 prod1_p1, prod1_p2, prod2_p1, prod2_p2);
161 real E = 0.5 * ( m1 * m2 ) / ( m1 + m2 ) * vcom2;
163 real weight = density1 * density2 * sqrt(vcom2)
167 prod1_p1[i], prod1->
axes[p1coord].
n,
170 prod1_p2[i], prod1->
axes[p2coord].
n,
172 if( 0 <= ip1 && ip1 < prod1->axes[p1coord].n &&
173 0 <= ip2 && ip2 < prod1->axes[p2coord].n) {
174 size_t index = i0*prod1->
strides[i0coord]
179 prod1->
bins[index] += weight * afsi->
mult;
183 prod2_p1[i], prod2->
axes[p1coord].
n,
186 prod2_p2[i], prod2->
axes[p2coord].
n,
188 if( 0 <= ip1 && ip1 < prod2->axes[p1coord].n &&
189 0 <= ip2 && ip2 < prod2->axes[p2coord].n) {
190 size_t index = i0*prod2->
strides[i0coord]
195 prod2->
bins[index] += weight * afsi->
mult;
214 int c1 = (int)rint(q1 /
CONST_E);
215 int c2 = (int)rint(q2 /
CONST_E);
216 int cprod1 = (int)rint(qprod1 /
CONST_E);
217 int cprod2 = (int)rint(qprod2 /
CONST_E);
225 sprintf(path,
"/results/afsi_%s/reaction", sim->
qid);
226 hid_t reactiondata = H5Gcreate2(f, path, H5P_DEFAULT, H5P_DEFAULT,
228 if(reactiondata < 0) {
229 print_err(
"Failed to write reaction data.\n");
234 if(H5LTmake_dataset_double(reactiondata,
"m1", 1, &size, &m1)) {
235 print_err(
"Failed to write reaction data.\n");
238 if(H5LTmake_dataset_double(reactiondata,
"m2", 1, &size, &m2)) {
239 print_err(
"Failed to write reaction data.\n");
242 if(H5LTmake_dataset_double(reactiondata,
"mprod1", 1, &size, &mprod1)) {
243 print_err(
"Failed to write reaction data.\n");
246 if(H5LTmake_dataset_double(reactiondata,
"mprod2", 1, &size, &mprod2)) {
247 print_err(
"Failed to write reaction data.\n");
250 if(H5LTmake_dataset_double(reactiondata,
"q", 1, &size, &q)) {
251 print_err(
"Failed to write reaction data.\n");
254 if(H5LTmake_dataset_int(reactiondata,
"q1", 1, &size, &c1)) {
255 print_err(
"Failed to write reaction data.\n");
258 if(H5LTmake_dataset_int(reactiondata,
"q2", 1, &size, &c2)) {
259 print_err(
"Failed to write reaction data.\n");
262 if(H5LTmake_dataset_int(reactiondata,
"qprod1", 1, &size, &cprod1)) {
263 print_err(
"Failed to write reaction data.\n");
266 if(H5LTmake_dataset_int(reactiondata,
"qprod2", 1, &size, &cprod2)) {
267 print_err(
"Failed to write reaction data.\n");
270 if(H5Gclose(reactiondata)) {
271 print_err(
"Failed to write reaction data.\n");
275 sprintf(path,
"/results/afsi_%s/prod1dist5d", sim->
qid);
277 print_err(
"Warning: 5D distribution could not be written.\n");
279 sprintf(path,
"/results/afsi_%s/prod2dist5d", sim->
qid);
281 print_err(
"Warning: 5D distribution could not be written.\n");
284 print_err(
"Failed to close the file.\n");
318 real v1x = cos(rn1) * pperp1[i] / m1;
319 real v1y = sin(rn1) * pperp1[i] / m1;
320 real v1z = ppara1[i] / m1;
322 real v2x = cos(rn2) * pperp2[i] / m2;
323 real v2y = sin(rn2) * pperp2[i] / m2;
324 real v2z = ppara2[i] / m2;
326 *vcom2 = (v1x - v2x) * (v1x - v2x)
327 + (v1y - v2y) * (v1y - v2y)
328 + (v1z - v2z) * (v1z - v2z);
332 v_cm[0] = ( m1 * v1x + m2 * v2x ) / ( m1 + m2 );
333 v_cm[1] = ( m1 * v1y + m2 * v2y ) / ( m1 + m2 );
334 v_cm[2] = ( m1 * v1z + m2 * v2z ) / ( m1 + m2 );
338 + 0.5 * m1 * ( (v1x - v_cm[0])*(v1x - v_cm[0])
339 + (v1y - v_cm[1])*(v1y - v_cm[1])
340 + (v1z - v_cm[2])*(v1z - v_cm[2]) )
341 + 0.5 * m2 * ( (v2x - v_cm[0])*(v2x - v_cm[0])
342 + (v2y - v_cm[1])*(v2y - v_cm[1])
343 + (v2z - v_cm[2])*(v2z - v_cm[2]) );
349 real theta = acos( 2 * ( rn2 - 0.5 ) );
350 real vnorm = sqrt( 2.0 * ekin / ( mprod2 * ( 1.0 + mprod2 / mprod1 ) ) );
353 v2_cm[0] = vnorm * sin(theta) * cos(phi);
354 v2_cm[1] = vnorm * sin(theta) * sin(phi);
355 v2_cm[2] = vnorm * cos(theta);
358 real vprod1[3], vprod2[3];
359 vprod1[0] = -(mprod2/mprod1) * v2_cm[0] + v_cm[0];
360 vprod1[1] = -(mprod2/mprod1) * v2_cm[1] + v_cm[1];
361 vprod1[2] = -(mprod2/mprod1) * v2_cm[2] + v_cm[2];
362 vprod2[0] = v2_cm[0] + v_cm[0];
363 vprod2[1] = v2_cm[1] + v_cm[1];
364 vprod2[2] = v2_cm[2] + v_cm[2];
366 if(prodmomspace == PPARPPERP) {
367 prod1_p1[i] = vprod1[2] * mprod1;
368 prod1_p2[i] = sqrt(vprod1[0]*vprod1[0] + vprod1[1]*vprod1[1]) * mprod1;
369 prod2_p1[i] = vprod2[2] * mprod2;
370 prod2_p2[i] = sqrt(vprod2[0]*vprod2[0] + vprod2[1]*vprod2[1]) * mprod2;
374 prod1_p2[i] = vprod1[2] / vnorm1;
378 prod2_p2[i] = vprod2[2] / vnorm2;
401 int nsample,
size_t i0,
size_t i1,
size_t i2,
405 if(afsi->
type1 == 1) {
407 density1, ppara1, pperp1);
409 else if(afsi->
type1 == 2) {
411 time, rho, density1, ppara1, pperp1);
413 if(afsi->
type2 == 1) {
415 density2, ppara2, pperp2);
417 else if(afsi->
type2 == 2) {
419 time, rho, density2, ppara2, pperp2);
433 size_t i0,
size_t i1,
size_t i2,
436 size_t p1coord, p2coord;
437 if(hist->
axes[5].
n) {
440 mom_space = PPARPPERP;
442 else if(hist->
axes[10].
n) {
455 for(
size_t ip1 = 0; ip1 < hist->
axes[p1coord].
n; ip1++) {
456 for(
size_t ip2 = 0; ip2 < hist->
axes[p2coord].
n; ip2++) {
457 size_t index = i0*hist->
strides[0]
462 if(ip1 == 0 && ip2 == 0) {
463 cumdist[0] = hist->
bins[index];
465 cumdist[ip1*hist->
axes[p2coord].
n+ip2] =
466 cumdist[ip1*hist->
axes[p2coord].
n+ip2-1]
469 *density += hist->
bins[index] / vol;
476 for(
size_t i = 0; i < nsample; i++) {
478 r *= cumdist[hist->
axes[p1coord].
n*hist->
axes[p2coord].
n-1];
479 for(
size_t j = 0; j < hist->
axes[p1coord].
n*hist->
axes[p2coord].
n; j++) {
481 if(mom_space == PPARPPERP) {
482 ppara[i] = hist->
axes[5].
min + (j / hist->
axes[5].
n + 0.5)
484 pperp[i] = hist->
axes[6].
min + (j % hist->
axes[6].
n + 0.5)
493 real pnorm = sqrt(gamma * gamma - 1.0) * mass *
CONST_C;
494 ppara[i] = pitch * pnorm;
495 pperp[i] = sqrt( 1.0 - pitch*pitch ) * pnorm;
530 for(
int i = 0; i < nsample; i++) {
531 real r1, r2, r3, r4, E;
536 E = -ti * ( log(r1) + log(r2) * r3 * r3 );
539 pperp[i] = sqrt( ( 1 - r4*r4 ) * 2 * E * mass);
540 ppara[i] = r4 * sqrt(2 * E * mass);
a5err B_field_eval_rho(real rho[2], real psi, B_field_data *Bdata)
Evaluate normalized poloidal flux rho and its psi derivative.
a5err B_field_eval_psi(real *psi, real r, real phi, real z, real t, B_field_data *Bdata)
Evaluate poloidal flux psi.
void afsi_sample_reactant_momenta_2d(sim_data *sim, afsi_data *afsi, real mass1, real mass2, real vol, int nsample, size_t i0, size_t i1, size_t i2, real r, real phi, real z, real time, real rho, real *density1, real *ppara1, real *pperp1, real *density2, real *ppara2, real *pperp2)
Sample velocities from reactant distributions.
void afsi_sample_thermal_2d(sim_data *sim, int ispecies, real mass, int nsample, real r, real phi, real z, real time, real rho, real *density, real *pppara, real *ppperp)
Sample ppara and pperp from a thermal (Maxwellian) population.
void afsi_sample_beam_2d(histogram *hist, real mass, real vol, int nsample, size_t i0, size_t i1, size_t i2, real *density, real *ppara, real *pperp)
Sample ppara and pperp from a 5D distribution.
void afsi_run(sim_data *sim, afsi_data *afsi, int n, histogram *prod1, histogram *prod2)
Calculate fusion source from two arbitrary ion distributions.
void afsi_compute_product_momenta_2d(int i, real m1, real m2, real mprod1, real mprod2, real Q, int prodmomspace, real *ppara1, real *pperp1, real *ppara2, real *pperp2, real *vcom2, real *prod1_p1, real *prod1_p2, real *prod2_p1, real *prod2_p2)
Compute momenta of reaction products.
Main header file for ASCOT5.
void boschhale_reaction(Reaction reaction, real *m1, real *q1, real *m2, real *q2, real *mprod1, real *qprod1, real *mprod2, real *qprod2, real *Q)
Get masses and charges of particles participating in the reaction and the released energy.
real boschhale_sigma(Reaction reaction, real E)
Estimate cross-section for a given fusion reaction.
Header file for boschdale.c.
Header file containing physical and mathematical constants.
#define CONST_U
Atomic mass unit in kilograms [kg].
#define CONST_C
Speed of light [m/s].
#define CONST_E
Elementary charge [C].
herr_t hdf5_close(hid_t file_id)
Close access to given hdf5 file identifier. A negative value is returned on failure.
hid_t hdf5_open(const char *filename)
Open a hdf5 file for reading and writing. A negative value is returned on failure.
Header file for hdf5_helpers.h.
int hdf5_hist_write(hid_t f, char *path, histogram *hist)
Write a histogram object to HDF5 file.
Header file for hdf5_histogram.c.
int hdf5_interface_init_results(sim_data *sim, char *qid, char *run)
Initialize run group.
void hdf5_generate_qid(char *qid)
Generate an identification number for a run.
Header file for hdf5_interface.c.
#define math_bin_index(x, nx, xmin, xmax)
Find the bin index on a uniform grid.
#define math_norm(a)
Calculate norm of 3D vector a.
Methods to evaluate elementary physical quantities.
#define physlib_gamma_Ekin(m, ekin)
Evaluate Lorentz factor from kinetic energy [J].
#define physlib_Ekin_gamma(m, gamma)
Evaluate kinetic energy [J] from Lorentz factor.
#define physlib_gamma_vnorm(v)
Evaluate Lorentz factor from velocity norm.
a5err plasma_eval_temp(real *temp, real rho, real r, real phi, real z, real t, int species, plasma_data *pls_data)
Evaluate plasma temperature.
a5err plasma_eval_dens(real *dens, real rho, real r, real phi, real z, real t, int species, plasma_data *pls_data)
Evaluate plasma density.
Macros for printing console output.
#define print_out0(v, rank, root,...)
Print to standard output only for root process.
#define print_err(...)
Print to standard error.
Header file for random.c.
#define random_uniform(data)
#define random_init(data, seed)
void simulate_init(sim_data *sim)
Initialize simulation data struct.
Header file for simulate.c.
Wrapper around input data structures.
hist_axis axes[HIST_ALLDIM]
size_t strides[HIST_ALLDIM-1]