8#ifndef WARPX_TWO_PRODUCT_UTIL_H
9#define WARPX_TWO_PRODUCT_UTIL_H
52 void TwoProductComputeProductMomenta (
53 const amrex::ParticleReal& u1x_in,
54 const amrex::ParticleReal& u1y_in,
55 const amrex::ParticleReal& u1z_in,
56 const amrex::ParticleReal& m1_in,
57 const amrex::ParticleReal& u2x_in,
58 const amrex::ParticleReal& u2y_in,
59 const amrex::ParticleReal& u2z_in,
60 const amrex::ParticleReal& m2_in,
61 amrex::ParticleReal& u1x_out,
62 amrex::ParticleReal& u1y_out,
63 amrex::ParticleReal& u1z_out,
64 const amrex::ParticleReal& m1_out,
65 amrex::ParticleReal& u2x_out,
66 amrex::ParticleReal& u2y_out,
67 amrex::ParticleReal& u2z_out,
68 const amrex::ParticleReal& m2_out,
69 const amrex::ParticleReal& E_reaction,
70 const bool isotropic_scattering,
73 using namespace amrex::literals;
77 constexpr amrex::ParticleReal inv_csq = 1._prt / ( c_sq );
79 const amrex::ParticleReal E_rest_in = (m1_in + m2_in)*c_sq;
81 const amrex::ParticleReal E_rest_out = (m1_out + m2_out)*c_sq;
86 const amrex::ParticleReal p1x_in = (m1_in == 0) ? me*u1x_in : m1_in*u1x_in;
87 const amrex::ParticleReal p1y_in = (m1_in == 0) ? me*u1y_in : m1_in*u1y_in;
88 const amrex::ParticleReal p1z_in = (m1_in == 0) ? me*u1z_in : m1_in*u1z_in;
89 const amrex::ParticleReal p2x_in = (m2_in == 0) ? me*u2x_in : m2_in*u2x_in;
90 const amrex::ParticleReal p2y_in = (m2_in == 0) ? me*u2y_in : m2_in*u2y_in;
91 const amrex::ParticleReal p2z_in = (m2_in == 0) ? me*u2z_in : m2_in*u2z_in;
94 const amrex::ParticleReal p1t_in = std::sqrt(
95 m1_in*m1_in*c_sq + p1x_in*p1x_in + p1y_in*p1y_in + p1z_in*p1z_in);
96 const amrex::ParticleReal p2t_in = std::sqrt(
97 m2_in*m2_in*c_sq + p2x_in*p2x_in + p2y_in*p2y_in + p2z_in*p2z_in);
100 const amrex::ParticleReal p_total_sq =
powi<2>(p1x_in+p2x_in) +
105 const amrex::ParticleReal E_lab = (p1t_in + p2t_in) *
PhysConst::c;
108 const amrex::ParticleReal E_star_sq = E_lab*E_lab - c_sq*p_total_sq;
115 const amrex::ParticleReal E_star_f_sq =
powi<2>(std::sqrt(E_star_sq)
116 - E_rest_in + E_rest_out + E_reaction);
122 const amrex::ParticleReal E_ratio = std::sqrt(E_star_f_sq)/((m1_out + m2_out)*c_sq);
123 const amrex::ParticleReal p_star_f_sq = m1_out*m2_out*c_sq * (
powi<2>(E_ratio) - 1._prt )
124 +
powi<2>(m1_out - m2_out)*c_sq*0.25_prt *
powi<2>( E_ratio - 1._prt/E_ratio );
127 const amrex::ParticleReal pt = p1t_in + p2t_in;
128 const amrex::ParticleReal vcx = (p1x_in+p2x_in) *
PhysConst::c / pt;
129 const amrex::ParticleReal vcy = (p1y_in+p2y_in) *
PhysConst::c / pt;
130 const amrex::ParticleReal vcz = (p1z_in+p2z_in) *
PhysConst::c / pt;
131 const amrex::ParticleReal vc_sq = vcx*vcx + vcy*vcy + vcz*vcz;
132 const amrex::ParticleReal gc = 1._prt / std::sqrt( 1._prt - vc_sq*inv_csq );
135 amrex::ParticleReal px_star_out, py_star_out, pz_star_out;
136 if (isotropic_scattering) {
145 amrex::ParticleReal p1x_star_in, p1y_star_in, p1z_star_in;
146 if ( vc_sq > std::numeric_limits<amrex::ParticleReal>::min() )
150 const amrex::ParticleReal vcDps = vcx*p1x_in + vcy*p1y_in + vcz*p1z_in;
151 const amrex::ParticleReal factor0 = (gc-1._prt)/vc_sq;
152 const amrex::ParticleReal factor = factor0*vcDps - p1t_in*gc/
PhysConst::c;
153 p1x_star_in = p1x_in + vcx * factor;
154 p1y_star_in = p1y_in + vcy * factor;
155 p1z_star_in = p1z_in + vcz * factor;
159 p1x_star_in = p1x_in;
160 p1y_star_in = p1y_in;
161 p1z_star_in = p1z_in;
163 amrex::ParticleReal p1_star_in = std::sqrt(p1x_star_in*p1x_star_in + p1y_star_in*p1y_star_in + p1z_star_in*p1z_star_in);
167 amrex::ParticleReal scaling = std::sqrt(p_star_f_sq)/p1_star_in;
168 px_star_out = p1x_star_in * scaling;
169 py_star_out = p1y_star_in * scaling;
170 pz_star_out = p1z_star_in * scaling;
174 amrex::ParticleReal p1x_out, p1y_out, p1z_out;
177 if ( vc_sq > std::numeric_limits<amrex::ParticleReal>::min() )
179 const amrex::ParticleReal p1t_out = std::sqrt(m1_out*m1_out*c_sq + p_star_f_sq);
180 const amrex::ParticleReal vcDps = vcx*px_star_out + vcy*py_star_out + vcz*pz_star_out;
181 const amrex::ParticleReal factor0 = (gc-1._prt)/vc_sq;
182 const amrex::ParticleReal factor = factor0*vcDps + p1t_out*gc/
PhysConst::c;
183 p1x_out = px_star_out + vcx * factor;
184 p1y_out = py_star_out + vcy * factor;
185 p1z_out = pz_star_out + vcz * factor;
189 p1x_out = px_star_out;
190 p1y_out = py_star_out;
191 p1z_out = pz_star_out;
195 const amrex::ParticleReal p2x_out = p1x_in + p2x_in - p1x_out;
196 const amrex::ParticleReal p2y_out = p1y_in + p2y_in - p1y_out;
197 const amrex::ParticleReal p2z_out = p1z_in + p2z_in - p1z_out;
201 u1x_out = (m1_out == 0) ? p1x_out/me : p1x_out/m1_out;
202 u1y_out = (m1_out == 0) ? p1y_out/me : p1y_out/m1_out;
203 u1z_out = (m1_out == 0) ? p1z_out/me : p1z_out/m1_out;
204 u2x_out = (m2_out == 0) ? p2x_out/me : p2x_out/m2_out;
205 u2y_out = (m2_out == 0) ? p2y_out/me : p2y_out/m2_out;
206 u2z_out = (m2_out == 0) ? p2z_out/me : p2z_out/m2_out;
#define AMREX_GPU_HOST_DEVICE
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:218
constexpr auto c
vacuum speed of light [m/s]
Definition constant.H:149
constexpr auto m_e
electron mass [kg]
Definition constant.H:161
constexpr T powi(T x) noexcept