WarpX
BinaryCollisionUtils.H
Go to the documentation of this file.
1 /* Copyright 2021 Neil Zaim
2  *
3  * This file is part of WarpX.
4  *
5  * License: BSD-3-Clause-LBNL
6  */
7 
8 #ifndef BINARY_COLLISION_UTILS_H_
9 #define BINARY_COLLISION_UTILS_H_
10 
11 #include <string>
12 
14 
15 #include <AMReX_Math.H>
16 
22  Undefined };
23 
24 enum struct NuclearFusionType {
30  Undefined };
31 
32 namespace BinaryCollisionUtils{
33 
34  NuclearFusionType get_nuclear_fusion_type (std::string collision_name,
35  MultiParticleContainer const * mypc);
36 
37  CollisionType get_collision_type (std::string collision_name,
38  MultiParticleContainer const * mypc);
39 
41 
49  const amrex::ParticleReal& u1x, const amrex::ParticleReal& u1y,
50  const amrex::ParticleReal& u1z, const amrex::ParticleReal& u2x,
51  const amrex::ParticleReal& u2y, const amrex::ParticleReal& u2z,
52  const amrex::ParticleReal& m1, const amrex::ParticleReal& m2,
53  amrex::ParticleReal& E_kin_COM, amrex::ParticleReal& v_rel_COM,
54  amrex::ParticleReal& lab_to_COM_lorentz_factor )
55  {
56  // General notations in this function:
57  // x_sq denotes the square of x
58  // x_star denotes the value of x in the center of mass frame
59 
60  using namespace amrex::literals;
61  using namespace amrex::Math;
62 
63  constexpr auto one_pr = amrex::ParticleReal(1.);
64  constexpr auto inv_four_pr = amrex::ParticleReal(1./4.);
65  constexpr double c_sq = PhysConst::c * PhysConst::c;
66  constexpr double inv_csq = 1.0 / c_sq;
67 
68  const amrex::ParticleReal m1_sq = m1*m1;
69  const amrex::ParticleReal m2_sq = m2*m2;
70 
71  // Compute Lorentz factor gamma in the lab frame
72  const double g1 = std::sqrt( 1.0 + static_cast<double>(u1x*u1x+u1y*u1y+u1z*u1z)*inv_csq );
73  const double g2 = std::sqrt( 1.0 + static_cast<double>(u2x*u2x+u2y*u2y+u2z*u2z)*inv_csq );
74 
75  // Compute momenta
76  const amrex::ParticleReal p1x = u1x * m1;
77  const amrex::ParticleReal p1y = u1y * m1;
78  const amrex::ParticleReal p1z = u1z * m1;
79  const amrex::ParticleReal p2x = u2x * m2;
80  const amrex::ParticleReal p2y = u2y * m2;
81  const amrex::ParticleReal p2z = u2z * m2;
82  // Square norm of the total (sum between the two particles) momenta in the lab frame
83  const auto p_total_sq = static_cast<double>(
84  powi<2>(p1x + p2x) + powi<2>(p1y + p2y) + powi<2>(p1z + p2z)
85  );
86 
87  // Total energy in the lab frame
88  // Note the use of `double` for energy since this calculation is
89  // prone to error with single precision.
90  const auto m1_dbl = static_cast<double>(m1);
91  const auto m2_dbl = static_cast<double>(m2);
92  const double E_lab = (m1_dbl * g1 + m2_dbl * g2) * c_sq;
93  // Total energy squared in the center of mass frame, calculated using the Lorentz invariance
94  // of the four-momentum norm
95  const double E_star_sq = E_lab*E_lab - c_sq*p_total_sq;
96 
97  // Kinetic energy in the center of mass frame
98  const double E_star = std::sqrt(E_star_sq);
99  E_kin_COM = static_cast<amrex::ParticleReal>(E_star - (m1_dbl + m2_dbl)*c_sq);
100 
101  // Square of the norm of the momentum of one of the particles in the center of mass frame
102  // Formula obtained by inverting E^2 = p^2*c^2 + m^2*c^4 in the COM frame for each particle
103  // The expression below is specifically written in a form that avoids returning
104  // small negative numbers due to machine precision errors, for low-energy particles
105  const auto E_ratio = static_cast<amrex::ParticleReal>(E_star/((m1 + m2)*c_sq));
106  const auto p_star_sq = static_cast<amrex::ParticleReal>(
107  m1*m2*c_sq * ( powi<2>(E_ratio) - one_pr )
108  + powi<2>(m1 - m2)*c_sq*inv_four_pr * powi<2>( E_ratio - 1._prt/E_ratio)
109  );
110 
111  // Lorentz factors in the center of mass frame
112  const auto g1_star = std::sqrt(one_pr + p_star_sq / static_cast<amrex::ParticleReal>(m1_sq*c_sq));
113  const auto g2_star = std::sqrt(one_pr + p_star_sq / static_cast<amrex::ParticleReal>(m2_sq*c_sq));
114 
115  // relative velocity in the center of mass frame
116  v_rel_COM = std::sqrt(p_star_sq) * (one_pr/(m1*g1_star) + one_pr/(m2*g2_star));
117 
118  // Cross sections and relative velocity are computed in the center of mass frame.
119  // On the other hand, the particle densities (weight over volume) in the lab frame are used.
120  // To take this disrepancy into account, it is needed to multiply the
121  // collision probability by the ratio between the Lorentz factors in the
122  // COM frame and the Lorentz factors in the lab frame (see
123  // Perez et al., Phys.Plasmas.19.083104 (2012)). The correction factor
124  // is calculated here.
125  lab_to_COM_lorentz_factor = g1_star*g2_star/static_cast<amrex::ParticleReal>(g1*g2);
126  }
127 }
128 
129 #endif // BINARY_COLLISION_UTILS_H_
#define AMREX_INLINE
#define AMREX_GPU_HOST_DEVICE
CollisionType
Definition: BinaryCollisionUtils.H:17
@ ProtonBoronToAlphasFusion
@ DeuteriumDeuteriumToProtonTritiumFusion
@ DeuteriumDeuteriumToNeutronHeliumFusion
@ DeuteriumTritiumToNeutronHeliumFusion
@ DeuteriumHeliumToProtonHeliumFusion
NuclearFusionType
Definition: BinaryCollisionUtils.H:24
@ DeuteriumDeuteriumToProtonTritium
@ DeuteriumDeuteriumToNeutronHelium
Definition: MultiParticleContainer.H:66
Definition: BinaryCollisionUtils.cpp:18
CollisionType get_collision_type(const std::string collision_name, MultiParticleContainer const *const mypc)
Definition: BinaryCollisionUtils.cpp:105
CollisionType nuclear_fusion_type_to_collision_type(const NuclearFusionType fusion_type)
Definition: BinaryCollisionUtils.cpp:119
AMREX_GPU_HOST_DEVICE AMREX_INLINE void get_collision_parameters(const amrex::ParticleReal &u1x, const amrex::ParticleReal &u1y, const amrex::ParticleReal &u1z, const amrex::ParticleReal &u2x, const amrex::ParticleReal &u2y, const amrex::ParticleReal &u2z, const amrex::ParticleReal &m1, const amrex::ParticleReal &m2, amrex::ParticleReal &E_kin_COM, amrex::ParticleReal &v_rel_COM, amrex::ParticleReal &lab_to_COM_lorentz_factor)
Return (relativistic) collision energy, collision speed and Lorentz factor for transforming between t...
Definition: BinaryCollisionUtils.H:48
NuclearFusionType get_nuclear_fusion_type(const std::string collision_name, MultiParticleContainer const *const mypc)
Definition: BinaryCollisionUtils.cpp:20
static constexpr auto c
vacuum speed of light [m/s]
Definition: constant.H:44