7#ifndef WARPX_PARTICLE_UTILS_H_
8#define WARPX_PARTICLE_UTILS_H_
55 double const M,
double& gamma,
double& energy )
62 2.0_rt * m * M * u2 / (gamma + 1.0_rt)
63 / (M + m +
sqrt(m*m + M*M + 2.0_rt * m * M * gamma))
85 const auto V2 = (Vx*Vx + Vy*Vy + Vz*Vz);
87 const auto gamma_u = std::sqrt(1.0_prt + (ux*ux + uy*uy + uz*uz)*
PhysConst::inv_c2);
94 ux = vx * (1.0_prt + (gamma_V - 1.0_prt) * Vx*Vx/V2)
95 + vy * (gamma_V - 1.0_prt) * Vx*Vy/V2
96 +
vz * (gamma_V - 1.0_prt) * Vx*Vz/V2
97 - gamma_V * Vx * gamma_u;
99 uy = vy * (1.0_prt + (gamma_V - 1.0_prt) * Vy*Vy/V2)
100 + vx * (gamma_V - 1.0_prt) * Vx*Vy/V2
101 +
vz * (gamma_V - 1.0_prt) * Vy*Vz/V2
102 - gamma_V * Vy * gamma_u;
104 uz =
vz * (1.0_prt + (gamma_V - 1.0_prt) * Vz*Vz/V2)
105 + vx * (gamma_V - 1.0_prt) * Vx*Vz/V2
106 + vy * (gamma_V - 1.0_prt) * Vy*Vz/V2
107 - gamma_V * Vz * gamma_u;
140 ux = ux + gammam1*udotn*Ux_hat - Ux*P0;
141 uy = uy + gammam1*udotn*Uy_hat - Uy*P0;
142 uz = uz + gammam1*udotn*Uz_hat - Uz*P0;
201 auto const cos_theta = 2.0_prt *
amrex::Random(engine) - 1.0_prt;
202 auto const sin_theta = std::sqrt(1.0_prt - cos_theta*cos_theta);
203 x = sin_theta * std::cos(phi);
204 y = sin_theta * std::sin(phi);
241 const auto *
const xlo = tilebox.
lo();
242 const auto *
const xhi = tilebox.
hi();
244 && (xlo[1] <= point.
y) && (point.
y <= xhi[1]),
245 && (xlo[2] <= point.
z) && (point.
z <= xhi[2]));
258 if (do_cropping[0] && x1 < xmin) {
261 else if (do_cropping[1] && x1 > xmax) {
275 double & x1,
double & z1,
277 if (do_cropping[0] && x1 < xmin) {
278 double const fx = ((x0 - x1) != 0. ? (x0 - xmin)/(x0 - x1) : 0.);
280 z1 = z0 + fx*(z1 - z0);
282 else if (do_cropping[1] && x1 > xmax) {
283 double const fx = ((x0 - x1) != 0. ? (xmax - x0)/(x1 - x0) : 0.);
285 z1 = z0 + fx*(z1 - z0);
298 double & x1,
double & y1,
double & z1,
300 if (do_cropping[0] && x1 < xmin) {
301 double const fx = ((x0 - x1) != 0. ? (x0 - xmin)/(x0 - x1) : 0.);
303 y1 = y0 + fx*(y1 - y0);
304 z1 = z0 + fx*(z1 - z0);
306 else if (do_cropping[1] && x1 > xmax) {
307 double const fx = ((x0 - x1) != 0. ? (xmax - x0)/(x1 - x0) : 0.);
309 y1 = y0 + fx*(y1 - y0);
310 z1 = z0 + fx*(z1 - z0);
325 [[maybe_unused]]
double yp,
326 [[maybe_unused]]
double zp,
335#if defined(WARPX_DIM_3D)
336 xp_grid[0] = (xp - xyzmin.
x)*dinv.
x;
337 xp_grid[1] = (yp - xyzmin.
y)*dinv.
y;
338 xp_grid[2] = (zp - xyzmin.
z)*dinv.
z;
339#elif defined(WARPX_DIM_XZ)
340 xp_grid[0] = (xp - xyzmin.
x)*dinv.
x;
341 xp_grid[1] = (zp - xyzmin.
z)*dinv.
z;
342#elif defined(WARPX_DIM_1D_Z)
343 xp_grid[0] = (zp - xyzmin.
z)*dinv.
z;
344#elif defined(WARPX_DIM_RZ) || defined(WARPX_DIM_RCYLINDER)
345 const double rp = std::sqrt(xp*xp + yp*yp);
346 xp_grid[0] = (rp - xyzmin.
x)*dinv.
x;
347#if defined(WARPX_DIM_RZ)
348 xp_grid[1] = (zp - xyzmin.
z)*dinv.
z;
350#elif defined(WARPX_DIM_RSPHERE)
351 const double rp = std::sqrt(xp*xp + yp*yp + zp*zp);
352 xp_grid[0] = (rp - xyzmin.
x)*dinv.
x;
356 for (
int dim = 0; dim < AMREX_SPACEDIM; dim++) {
357 if ( (do_cropping[dim][0] && xp_grid[dim] <= domain_double[dim][0]) ||
358 (do_cropping[dim][1] && xp_grid[dim] >= domain_double[dim][1])) {
383 template <
typename T_index>
390 T_index
const cell_start,
391 T_index
const cell_stop,
400 int const numCell = (cell_stop - cell_start);
412 int const max_loop_count = 10;
414 T_index i1 = cell_start + pair_offset;
415 bool correction_failed =
false;
416 bool deltaE_is_zero =
false;
417 while (!deltaE_is_zero) {
420 if (i2 == cell_stop) {
425 int const sign = (deltaE < 0.0_prt ? -1 : 1);
457 const amrex::ParticleReal Ecm = std::sqrt(Etot*Etot - (pxtot*pxtot + pytot*pytot + pztot*pztot)*c2);
460 if (Erel > 0.0_prt) {
464 bool deltaE_finishes =
false;
466 if (std::abs(deltaEpair) >= std::abs(deltaE)) {
468 deltaE_finishes =
true;
482 if (root >= 0.0_prt && amrex::Math::abs(a) > 0.0_prt) {
488 uxp[ indices[i1] ] += ratio1*ux;
489 uyp[ indices[i1] ] += ratio1*uy;
490 uzp[ indices[i1] ] += ratio1*uz;
491 uxp[ indices[i2] ] -= ratio2*ux;
492 uyp[ indices[i2] ] -= ratio2*uy;
493 uzp[ indices[i2] ] -= ratio2*uz;
496 if (deltaE_finishes) {
498 deltaE_is_zero =
true;
501 deltaE -= deltaEpair;
509 if (i1 < cell_stop - 2) {
513 if (loop_count >= max_loop_count) {
514 correction_failed =
true;
518 pair_offset = 1 - pair_offset;
519 i1 = cell_start + pair_offset;
523 return correction_failed;
544 template <
typename T_index>
549 for (T_index i = 1; i < n; i++)
553 while (j > 0 && bin_array[index_array[j+start]] < bin_array[index_array[(j - 1)/2 + start]]) {
555 amrex::Swap(index_array[j+start], index_array[(j - 1)/2 + start]);
560 for (T_index i = n - 1; i > 0; i--)
563 amrex::Swap(index_array[start], index_array[i+start]);
566 T_index j = 0, index;
571 if (index + 1 < i && bin_array[index_array[index+start]] > bin_array[index_array[index+1+start]]) {
575 if (index < i && bin_array[index_array[j+start]] > bin_array[index_array[index+start]]) {
576 amrex::Swap(index_array[j+start], index_array[index+start]);
#define AMREX_FORCE_INLINE
#define AMREX_GPU_HOST_DEVICE
#define AMREX_D_TERM(a, b, c)
@ vz
Definition RigidInjectedParticleContainer.H:27
std::conditional_t< is_rtsoa_pc, ParticleTileRT< typename ParticleType::RealType, typename ParticleType::IntType >, ParticleTile< ParticleType, NArrayReal, NArrayInt, Allocator > > ParticleTileType
__host__ __device__ const Real * lo() const &noexcept
__host__ __device__ const Real * hi() const &noexcept
amrex_particle_real ParticleReal
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:157
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:120
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:54
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:77
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, const 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 &deltaE)
Definition ParticleUtils.H:385
typename WarpXParticleContainer::ParticleTileType ParticleTileType
Definition ParticleUtils.H:23
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
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_FORCE_INLINE bool is_out_of_bounds(double xp, double yp, double zp, const amrex::XDim3 &dinv, const amrex::XDim3 &xyzmin, const amrex::GpuArray< amrex::GpuArray< double, 2 >, 3 > &domain_double, const amrex::GpuArray< amrex::GpuArray< bool, 2 >, 3 > &do_cropping)
Definition ParticleUtils.H:324
AMREX_GPU_HOST_DEVICE AMREX_INLINE void getRandomVector(amrex::ParticleReal &x, amrex::ParticleReal &y, amrex::ParticleReal &z, amrex::RandomEngine const &engine)
Generate a random unit vector with isotropic distribution, following the method described in equation...
Definition ParticleUtils.H:195
AMREX_GPU_HOST_DEVICE AMREX_INLINE bool containsInclusive(amrex::RealBox const &tilebox, amrex::XDim3 const point)
Definition ParticleUtils.H:240
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void crop_at_boundary(double &x1, double xmin, double xmax, amrex::GpuArray< bool, 2 > const &do_cropping)
Definition ParticleUtils.H:256
typename ParticleTileType::ParticleTileDataType ParticleTileDataType
Definition ParticleUtils.H:24
constexpr auto c
vacuum speed of light [m/s]
Definition constant.H:160
constexpr auto c2
square of the vacuum speed of light [m^2/s^2]
Definition constant.H:221
constexpr auto inv_c2
inverse of the square of the vacuum speed of light [s^2/m^2]
Definition constant.H:227
constexpr auto q_e
elementary charge [C]
Definition constant.H:169
constexpr auto pi
ratio of a circle's circumference to its diameter
Definition constant.H:29
__host__ __device__ void Swap(T &t1, T &t2) noexcept
__host__ __device__ GpuComplex< T > sqrt(const GpuComplex< T > &a_z) noexcept
A GPU compartible sort of a index vector vector based on another GPU vector's values,...
Definition ParticleUtils.H:542
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void operator()(T_index index_array[], const amrex::ParticleReal bin_array[], const T_index start, const T_index n) const
Definition ParticleUtils.H:546