WarpX
Loading...
Searching...
No Matches
LinearBreitWheelerUtil.H
Go to the documentation of this file.
1/* Copyright 2023 Arianna Formenti
2 *
3 * This file is part of WarpX.
4 *
5 * License: BSD-3-Clause-LBNL
6 */
7
8#ifndef LINEAR_BREIT_WHEELER_UTIL_H
9#define LINEAR_BREIT_WHEELER_UTIL_H
10
11#include "Utils/ParticleUtils.H"
12#include "Utils/WarpXConst.H"
13
14#include <AMReX_Math.H>
15#include <AMReX_Random.H>
16#include <AMReX_REAL.H>
17
18#include <cmath>
19#include <limits>
20
21namespace {
44 void LinearBreitWheelerComputeProductMomenta (
45 const amrex::ParticleReal& u1x_in,
46 const amrex::ParticleReal& u1y_in,
47 const amrex::ParticleReal& u1z_in,
48 const amrex::ParticleReal& u2x_in,
49 const amrex::ParticleReal& u2y_in,
50 const amrex::ParticleReal& u2z_in,
51 amrex::ParticleReal& u1x_out,
52 amrex::ParticleReal& u1y_out,
53 amrex::ParticleReal& u1z_out,
54 amrex::ParticleReal& u2x_out,
55 amrex::ParticleReal& u2y_out,
56 amrex::ParticleReal& u2z_out,
57 const amrex::RandomEngine& engine )
58 {
59 using namespace amrex::literals;
60 using namespace amrex::Math;
61
65 constexpr auto one_half_pr = amrex::ParticleReal(1./2.);
66 constexpr auto one_pr = amrex::ParticleReal(1.);
67
68 // Compute momenta
69 const amrex::ParticleReal p1x_in = u1x_in * me;
70 const amrex::ParticleReal p1y_in = u1y_in * me;
71 const amrex::ParticleReal p1z_in = u1z_in * me;
72 const amrex::ParticleReal p2x_in = u2x_in * me;
73 const amrex::ParticleReal p2y_in = u2y_in * me;
74 const amrex::ParticleReal p2z_in = u2z_in * me;
75 const amrex::ParticleReal p1_in = std::sqrt(powi<2>(p1x_in)+powi<2>(p1y_in)+powi<2>(p1z_in));
76 const amrex::ParticleReal p2_in = std::sqrt(powi<2>(p2x_in)+powi<2>(p2y_in)+powi<2>(p2z_in));
77
78 // Compute cosine of the angle between the two photon momenta in the lab frame
79 const amrex::ParticleReal cos_ang = (p1x_in*p2x_in+p1y_in*p2y_in+p1z_in*p2z_in)/(p1_in*p2_in);
80
81 // Energy squared of each of the two colliding photons in the center of momentum frame,
82 // calculated using the Lorentz invariance of the total four-momentum norm
83 const amrex::ParticleReal E_star_sq = one_half_pr*c2*p1_in*p2_in*(one_pr - cos_ang);
84
85 // Square of the norm of the momentum of the products in the center of mass frame
86 // Formula obtained by inverting E^2 = p^2*c^2 + m^2*c^4 in the COM frame for each particle:
87 // p_star_sq = E_star_sq/c2 - me*me*c2;
88 // The expression below is specifically written in a form that avoids returning
89 // small negative numbers due to machine precision errors, for low-energy particles
90 const amrex::ParticleReal E_ratio = std::sqrt(E_star_sq)/(2._prt*me*c2);
91 const amrex::ParticleReal p_star_sq = me*me*c2 * ( powi<2>(2._prt*E_ratio) - 1._prt );
92
93 // Compute momentum of first product in the center of mass frame, assuming isotropic
94 // distribution
95 amrex::ParticleReal px_star, py_star, pz_star;
96 ParticleUtils::RandomizeVelocity(px_star, py_star, pz_star, std::sqrt(p_star_sq),
97 engine);
98
99 // Next step is to convert momenta to lab frame
100 amrex::ParticleReal p1x_out, p1y_out, p1z_out;
101 // Preliminary calculation: compute velocity of the center of momentum frame:
102 // v = (p1 + p2) / | p1 + p2 | * c
103 const amrex::ParticleReal vcx = (p1x_in+p2x_in) * PhysConst::c / (p1_in + p2_in);
104 const amrex::ParticleReal vcy = (p1y_in+p2y_in) * PhysConst::c / (p1_in + p2_in);
105 const amrex::ParticleReal vcz = (p1z_in+p2z_in) * PhysConst::c / (p1_in + p2_in);
106 const amrex::ParticleReal vc_sq = vcx*vcx + vcy*vcy + vcz*vcz;
107
108 // Convert momentum of first product to lab frame, using equation (13) of F. Perez et al.,
109 // Phys.Plasmas.19.083104 (2012) (which is a regular Lorentz transformation)
110 if ( vc_sq > std::numeric_limits<amrex::ParticleReal>::min() )
111 {
112 const amrex::ParticleReal gc = 1._prt / std::sqrt( 1._prt - vc_sq*inv_c2 );
113 const amrex::ParticleReal g_star = std::sqrt(1._prt + p_star_sq / (me*me*c2));
114 const amrex::ParticleReal vcDps = vcx*px_star + vcy*py_star + vcz*pz_star;
115 const amrex::ParticleReal factor0 = (gc-1._prt)/vc_sq;
116 const amrex::ParticleReal factor = factor0*vcDps + me*g_star*gc;
117 p1x_out = px_star + vcx * factor;
118 p1y_out = py_star + vcy * factor;
119 p1z_out = pz_star + vcz * factor;
120 }
121 else // If center of mass velocity is zero, we are already in the lab frame
122 {
123 p1x_out = px_star;
124 p1y_out = py_star;
125 p1z_out = pz_star;
126 }
127
128 // Compute momentum of electron/positron in lab frame, using total momentum conservation
129 const amrex::ParticleReal p2x_out = p1x_in + p2x_in - p1x_out;
130 const amrex::ParticleReal p2y_out = p1y_in + p2y_in - p1y_out;
131 const amrex::ParticleReal p2z_out = p1z_in + p2z_in - p1z_out;
132
133 // Compute the momentum of the product macroparticles
134 u1x_out = p1x_out/me;
135 u1y_out = p1y_out/me;
136 u1z_out = p1z_out/me;
137 u2x_out = p2x_out/me;
138 u2y_out = p2y_out/me;
139 u2z_out = p2z_out/me;
140 }
141}
142
143#endif // LINEAR_BREIT_WHEELER_UTIL_H
#define AMREX_INLINE
#define AMREX_GPU_HOST_DEVICE
amrex_particle_real ParticleReal
AMREX_GPU_HOST_DEVICE AMREX_INLINE void RandomizeVelocity(amrex::ParticleReal &ux, amrex::ParticleReal &uy, amrex::ParticleReal &uz, const amrex::ParticleReal vp, amrex::RandomEngine const &engine)
Function to perform scattering of a particle that results in a random velocity vector with given magn...
Definition ParticleUtils.H:217
constexpr auto c
vacuum speed of light [m/s]
Definition constant.H:153
constexpr auto c2
square of the vacuum speed of light [m^2/s^2]
Definition constant.H:214
constexpr auto inv_c2_v
inverse of the square of the vacuum speed of light [s^2/m^2] (variable template)
Definition constant.H:146
constexpr auto m_e
electron mass [kg]
Definition constant.H:165
constexpr auto c2_v
square of the vacuum speed of light [m^2/s^2] (variable template)
Definition constant.H:138
constexpr auto inv_c2
inverse of the square of the vacuum speed of light [s^2/m^2]
Definition constant.H:220
constexpr T powi(T x) noexcept