79 amrex::ParticleReal& uz,
80 amrex::ParticleReal
const Vx, amrex::ParticleReal
const Vy,
81 amrex::ParticleReal
const Vz )
83 using namespace amrex::literals;
87 const auto V2 = (Vx*Vx + Vy*Vy + Vz*Vz);
88 const auto gamma_V = 1.0_prt / std::sqrt(1.0_prt - V2 / c2);
89 const auto gamma_u = std::sqrt(1.0_prt + (ux*ux + uy*uy + uz*uz) / c2);
96 ux = vx * (1.0_prt + (gamma_V - 1.0_prt) * Vx*Vx/V2)
97 + vy * (gamma_V - 1.0_prt) * Vx*Vy/V2
98 +
vz * (gamma_V - 1.0_prt) * Vx*Vz/V2
99 - gamma_V * Vx * gamma_u;
101 uy = vy * (1.0_prt + (gamma_V - 1.0_prt) * Vy*Vy/V2)
102 + vx * (gamma_V - 1.0_prt) * Vx*Vy/V2
103 +
vz * (gamma_V - 1.0_prt) * Vy*Vz/V2
104 - gamma_V * Vy * gamma_u;
106 uz =
vz * (1.0_prt + (gamma_V - 1.0_prt) * Vz*Vz/V2)
107 + vx * (gamma_V - 1.0_prt) * Vx*Vz/V2
108 + vy * (gamma_V - 1.0_prt) * Vy*Vz/V2
109 - gamma_V * Vz * gamma_u;
123 amrex::ParticleReal& uz,
124 amrex::ParticleReal
const Ux, amrex::ParticleReal
const Uy,
125 amrex::ParticleReal
const Uz )
127 using namespace amrex::literals;
131 amrex::ParticleReal
const Usq = Ux*Ux + Uy*Uy + Uz*Uz;
132 amrex::ParticleReal
const U = std::sqrt(Usq);
134 amrex::ParticleReal
const gamma = std::sqrt(1._prt + Usq/c2);
136 amrex::ParticleReal
const gammam1 = Usq/c2/(gamma + 1.0_prt);
137 amrex::ParticleReal
const Ux_hat = Ux/U;
138 amrex::ParticleReal
const Uy_hat = Uy/U;
139 amrex::ParticleReal
const Uz_hat = Uz/U;
140 amrex::ParticleReal
const P0 = std::sqrt(1._prt + (ux*ux + uy*uy + uz*uz)/c2);
141 amrex::ParticleReal
const udotn = ux*Ux_hat + uy*Uy_hat + uz*Uz_hat;
142 ux = ux + gammam1*udotn*Ux_hat - Ux*P0;
143 uy = uy + gammam1*udotn*Uy_hat - Uy*P0;
144 uz = uz + gammam1*udotn*Uz_hat - Uz*P0;
160 amrex::ParticleReal& pz, amrex::ParticleReal mass,
161 amrex::ParticleReal
const Ux, amrex::ParticleReal
const Uy,
162 amrex::ParticleReal
const Uz )
164 using namespace amrex::literals;
168 amrex::ParticleReal
const Usq = Ux*Ux + Uy*Uy + Uz*Uz;
169 amrex::ParticleReal
const U = std::sqrt(Usq);
171 amrex::ParticleReal
const gamma = std::sqrt(1._prt + Usq/c2);
173 amrex::ParticleReal
const gammam1 = Usq/c2/(gamma + 1.0_prt);
174 amrex::ParticleReal
const Ux_hat = Ux/U;
175 amrex::ParticleReal
const Uy_hat = Uy/U;
176 amrex::ParticleReal
const Uz_hat = Uz/U;
177 amrex::ParticleReal
const P0 = std::sqrt(px*px + py*py + pz*pz + mass*mass*c2);
178 amrex::ParticleReal
const pdotn = px*Ux_hat + py*Uy_hat + pz*Uz_hat;
277 T_index
const cell_start,
278 T_index
const cell_stop,
279 amrex::ParticleReal
const mass,
280 amrex::ParticleReal
const energy_fraction,
281 amrex::ParticleReal
const energy_fraction_max,
282 amrex::ParticleReal & deltaE )
284 using namespace amrex::literals;
288 int const numCell = (cell_stop - cell_start);
300 int const max_loop_count = 10;
301 amrex::ParticleReal Erel_cumm = 0.0_prt;
302 amrex::ParticleReal fmult_fact = 1.0_prt;
303 amrex::ParticleReal energy_frac_eff = 0.0_prt;
304 T_index i1 = cell_start;
305 bool correction_failed =
false;
306 bool deltaE_is_zero =
false;
307 while (!deltaE_is_zero && !correction_failed && loop_count <= max_loop_count) {
310 if (i2 == cell_stop) {
315 int const sign = (deltaE < 0.0 ? -1 : 1);
317 const amrex::ParticleReal ux1 = uxp[ indices[i1] ];
318 const amrex::ParticleReal uy1 = uyp[ indices[i1] ];
319 const amrex::ParticleReal uz1 = uzp[ indices[i1] ];
320 const amrex::ParticleReal ux2 = uxp[ indices[i2] ];
321 const amrex::ParticleReal uy2 = uyp[ indices[i2] ];
322 const amrex::ParticleReal uz2 = uzp[ indices[i2] ];
323 const amrex::ParticleReal wpmp1 = mass*w[ indices[i1] ];
324 const amrex::ParticleReal wpmp2 = mass*w[ indices[i2] ];
333 const amrex::ParticleReal ux = ux1 - ux2;
334 const amrex::ParticleReal uy = uy1 - uy2;
335 const amrex::ParticleReal uz = uz1 - uz2;
336 const amrex::ParticleReal dbetasq = (ux*ux + uy*uy + uz*uz)/c2;
337 const amrex::ParticleReal gbsq1 = (ux1*ux1 + uy1*uy1 + uz1*uz1)/c2;
338 const amrex::ParticleReal gbsq2 = (ux2*ux2 + uy2*uy2 + uz2*uz2)/c2;
339 const amrex::ParticleReal gamma1 = std::sqrt(1.0_prt + gbsq1);
340 const amrex::ParticleReal gamma2 = std::sqrt(1.0_prt + gbsq2);
341 const amrex::ParticleReal E1 = wpmp1*gamma1*c2;
342 const amrex::ParticleReal E2 = wpmp2*gamma2*c2;
343 const amrex::ParticleReal Etot = E1 + E2;
344 const amrex::ParticleReal pxtot = wpmp1*ux1 + wpmp2*ux2;
345 const amrex::ParticleReal pytot = wpmp1*uy1 + wpmp2*uy2;
346 const amrex::ParticleReal pztot = wpmp1*uz1 + wpmp2*uz2;
347 const amrex::ParticleReal Ecm = std::sqrt(Etot*Etot - (pxtot*pxtot + pytot*pytot + pztot*pztot)*c2);
348 const amrex::ParticleReal Erel = Ecm - wpmp1*c2 - wpmp2*c2;
349 if (Erel <= 0.0) {
continue; }
356 amrex::ParticleReal deltaEpair =
static_cast<amrex::ParticleReal
>(sign*energy_fraction*fmult_fact)*Erel;
357 if (std::abs(deltaEpair) >= std::abs(deltaE)) {
360 deltaE_is_zero =
true;
362 deltaE -= deltaEpair;
365 const amrex::ParticleReal A = Etot - deltaEpair;
366 const amrex::ParticleReal D = A*A + E2*E2 - E1*E1;
367 const amrex::ParticleReal p2dotu =
static_cast<amrex::ParticleReal
>(wpmp2*(ux2*ux + uy2*uy + uz2*uz));
368 const amrex::ParticleReal ptdotu = (pxtot*ux + pytot*uy + pztot*uz);
371 const amrex::ParticleReal a = A*A*dbetasq - ptdotu*ptdotu;
372 const amrex::ParticleReal b = D*ptdotu - 2.0_prt*A*A*p2dotu;
373 const amrex::ParticleReal c = A*A*E2*E2 - D*D/4.0_prt;
375 const amrex::ParticleReal root = b*b - 4.0_prt*a*c;
376 if (root < 0.0 || a == 0.0) {
continue; }
377 const amrex::ParticleReal
alpha = (-b + std::sqrt(root))/(2.0_prt*a);
380 const amrex::ParticleReal ratio1 =
alpha/(wpmp1*c2);
381 const amrex::ParticleReal ratio2 =
alpha/(wpmp2*c2);
382 uxp[ indices[i1] ] += ratio1*ux;
383 uyp[ indices[i1] ] += ratio1*uy;
384 uzp[ indices[i1] ] += ratio1*uz;
385 uxp[ indices[i2] ] -= ratio2*ux;
386 uyp[ indices[i2] ] -= ratio2*uy;
387 uzp[ indices[i2] ] -= ratio2*uz;
389 Erel_cumm += Erel - deltaEpair;
391 if (i1 < cell_stop - 2) {
399 if (i1 == cell_stop - 2) {
400 if ((numCell % 2) == 0) { i1 = cell_start + 1; }
401 if ((numCell % 2) != 0) { i1 = cell_start; }
403 if ((numCell % 2) == 0) { i1 = cell_start; }
404 if ((numCell % 2) != 0) { i1 = cell_start + 1; }
411 energy_frac_eff = std::abs(deltaE)/Erel_cumm;
412 if (energy_frac_eff > energy_fraction_max || loop_count > max_loop_count) {
413 correction_failed =
true;
415 }
else if (deltaE < 0.) {
418 fmult_fact = std::max(1._prt, energy_frac_eff/energy_fraction);
424 return correction_failed;
@ vz
Definition RigidInjectedParticleContainer.H:27
Definition ParticleUtils.cpp:24
AMREX_GPU_HOST_DEVICE AMREX_INLINE void doLorentzTransformWithP(amrex::ParticleReal &px, amrex::ParticleReal &py, amrex::ParticleReal &pz, amrex::ParticleReal mass, amrex::ParticleReal const Ux, amrex::ParticleReal const Uy, amrex::ParticleReal const Uz)
Perform a Lorentz transformation of the given momentum to a frame moving with gamma*velocity (Ux,...
Definition ParticleUtils.H:159
AMREX_GPU_HOST_DEVICE AMREX_INLINE void doLorentzTransformWithU(amrex::ParticleReal &ux, amrex::ParticleReal &uy, amrex::ParticleReal &uz, amrex::ParticleReal const Ux, amrex::ParticleReal const Uy, amrex::ParticleReal const Uz)
Perform a Lorentz transformation of the given velocity to a frame moving with gamma*velocity (Ux,...
Definition ParticleUtils.H:122
AMREX_GPU_HOST_DEVICE AMREX_INLINE void getCollisionEnergy(amrex::ParticleReal const u2, double const m, double const M, double &gamma, double &energy)
Return (relativistic) collision energy assuming the target (with mass M) is stationary and the projec...
Definition ParticleUtils.H:53
AMREX_GPU_HOST_DEVICE AMREX_INLINE void doLorentzTransform(amrex::ParticleReal &ux, amrex::ParticleReal &uy, amrex::ParticleReal &uz, amrex::ParticleReal const Vx, amrex::ParticleReal const Vy, amrex::ParticleReal const Vz)
Perform a Lorentz transformation of the given velocity to a frame moving with velocity (Vx,...
Definition ParticleUtils.H:78
typename WarpXParticleContainer::ParticleTileType ParticleTileType
Definition ParticleUtils.H:22
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:221
amrex::DenseBins< ParticleTileDataType > findParticlesInEachCell(amrex::Geometry const &geom_lev, amrex::MFIter const &mfi, ParticleTileType &ptile)
Find the particles and count the particles that are in each cell. More specifically this function ret...
Definition ParticleUtils.cpp:35
AMREX_GPU_HOST_DEVICE AMREX_INLINE bool ModifyEnergyPairwise(amrex::ParticleReal *const AMREX_RESTRICT uxp, amrex::ParticleReal *const AMREX_RESTRICT uyp, amrex::ParticleReal *const AMREX_RESTRICT uzp, amrex::ParticleReal *const AMREX_RESTRICT w, T_index const *const AMREX_RESTRICT indices, T_index const cell_start, T_index const cell_stop, amrex::ParticleReal const mass, amrex::ParticleReal const energy_fraction, amrex::ParticleReal const energy_fraction_max, amrex::ParticleReal &deltaE)
Definition ParticleUtils.H:272
AMREX_GPU_HOST_DEVICE AMREX_INLINE void getRandomVector(amrex::ParticleReal &x, amrex::ParticleReal &y, amrex::ParticleReal &z, amrex::RandomEngine const &engine)
Generate random unit vector in 3 dimensions https://mathworld.wolfram.com/SpherePointPicking....
Definition ParticleUtils.H:196
AMREX_GPU_HOST_DEVICE AMREX_INLINE bool containsInclusive(amrex::RealBox const &tilebox, amrex::XDim3 const point)
Definition ParticleUtils.H:243
typename ParticleTileType::ParticleTileDataType ParticleTileDataType
Definition ParticleUtils.H:23