WarpX
Loading...
Searching...
No Matches
ParticleUtils.H
Go to the documentation of this file.
1/* Copyright 2019-2020 Neil Zaim, Yinjian Zhao
2 *
3 * This file is part of WarpX.
4 *
5 * License: BSD-3-Clause-LBNL
6 */
7#ifndef WARPX_PARTICLE_UTILS_H_
8#define WARPX_PARTICLE_UTILS_H_
9
11#include "Utils/WarpXConst.H"
12
13#include <AMReX_DenseBins.H>
14#include <AMReX_Geometry.H>
15#include <AMReX_Particles.H>
16#include <AMReX_Math.H>
17
18#include <AMReX_BaseFwd.H>
19
20namespace ParticleUtils {
21
22 // Define shortcuts for frequently-used type names
24 using ParticleTileDataType = typename ParticleTileType::ParticleTileDataType;
25
39 amrex::MFIter const & mfi,
41
54 void getCollisionEnergy ( amrex::ParticleReal const u2, double const m,
55 double const M, double& gamma, double& energy )
56 {
57 using std::sqrt;
58 using namespace amrex::literals;
59
60 gamma = sqrt(1.0_rt + u2 * PhysConst::inv_c2);
61 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))
65 }
66
80 amrex::ParticleReal const Vz )
81 {
82 using namespace amrex::literals;
83
84 // precompute repeatedly used quantities
85 const auto V2 = (Vx*Vx + Vy*Vy + Vz*Vz);
86 const auto gamma_V = 1.0_prt / std::sqrt(1.0_prt - V2 * PhysConst::inv_c2);
87 const auto gamma_u = std::sqrt(1.0_prt + (ux*ux + uy*uy + uz*uz)* PhysConst::inv_c2);
88
89 // copy velocity vector values
90 const auto vx = ux;
91 const auto vy = uy;
92 const auto vz = uz;
93
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;
98
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;
103
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;
108 }
109
122 amrex::ParticleReal const Ux, amrex::ParticleReal const Uy,
123 amrex::ParticleReal const Uz )
124 {
125 using namespace amrex::literals;
126
127 constexpr auto c2 = PhysConst::c2;
128
129 amrex::ParticleReal const Usq = Ux*Ux + Uy*Uy + Uz*Uz;
130 amrex::ParticleReal const U = std::sqrt(Usq);
131 if (U > 0._prt) {
132 amrex::ParticleReal const gamma = std::sqrt(1._prt + Usq/c2);
133 // A nice way of calculating (gamma - 1) when it is small
134 amrex::ParticleReal const gammam1 = Usq/c2/(gamma + 1.0_prt);
135 amrex::ParticleReal const Ux_hat = Ux/U;
136 amrex::ParticleReal const Uy_hat = Uy/U;
137 amrex::ParticleReal const Uz_hat = Uz/U;
138 amrex::ParticleReal const P0 = std::sqrt(1._prt + (ux*ux + uy*uy + uz*uz)/c2);
139 amrex::ParticleReal const udotn = ux*Ux_hat + uy*Uy_hat + uz*Uz_hat;
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;
143 }
144
145 }
146
159 amrex::ParticleReal const Ux, amrex::ParticleReal const Uy,
160 amrex::ParticleReal const Uz )
161 {
162 using namespace amrex::literals;
163
164 constexpr auto c2 = PhysConst::c2;
165
166 amrex::ParticleReal const Usq = Ux*Ux + Uy*Uy + Uz*Uz;
167 amrex::ParticleReal const U = std::sqrt(Usq);
168 if (U > 0._prt) {
169 amrex::ParticleReal const gamma = std::sqrt(1._prt + Usq/c2);
170 // A nice way of calculating (gamma - 1) when it is small
171 amrex::ParticleReal const gammam1 = Usq/c2/(gamma + 1.0_prt);
172 amrex::ParticleReal const Ux_hat = Ux/U;
173 amrex::ParticleReal const Uy_hat = Uy/U;
174 amrex::ParticleReal const Uz_hat = Uz/U;
175 amrex::ParticleReal const P0 = std::sqrt(px*px + py*py + pz*pz + mass*mass*c2);
176 amrex::ParticleReal const pdotn = px*Ux_hat + py*Uy_hat + pz*Uz_hat;
177 px = px + gammam1*pdotn*Ux_hat - Ux*P0/PhysConst::c;
178 py = py + gammam1*pdotn*Uy_hat - Uy*P0/PhysConst::c;
179 pz = pz + gammam1*pdotn*Uz_hat - Uz*P0/PhysConst::c;
180 }
181
182 }
183
196 amrex::ParticleReal& z, amrex::RandomEngine const& engine )
197 {
198 using namespace amrex::literals;
199
200 auto const phi = 2.0_prt * MathConst::pi * amrex::Random(engine);
201 auto const cos_theta = 2.0_prt * amrex::Random(engine) - 1.0_prt; // opposite sign of that in Higginson's paper
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);
205 z = cos_theta;
206 }
207
208
220 const amrex::ParticleReal vp,
221 amrex::RandomEngine const& engine )
222 {
223 amrex::ParticleReal x, y, z;
224 // generate random unit vector for the new velocity direction
225 getRandomVector(x, y, z, engine);
226
227 // scale new vector to have the desired magnitude
228 ux = x * vp;
229 uy = y * vp;
230 uz = z * vp;
231 }
232
233 /* \brief Determines whether the point is within the tilebox, inclusive of the boundaries.
234 * Note that this routine is needed since tilebox.contains excludes the boundaries.
235 * \param[in] tilebox The tilebox being checked
236 * \param[in] point The point being checked
237 * \result true if the point with within the boundary, otherwise false
238 */
240 bool containsInclusive (amrex::RealBox const& tilebox, amrex::XDim3 const point) {
241 const auto *const xlo = tilebox.lo();
242 const auto *const xhi = tilebox.hi();
243 return AMREX_D_TERM((xlo[0] <= point.x) && (point.x <= xhi[0]),
244 && (xlo[1] <= point.y) && (point.y <= xhi[1]),
245 && (xlo[2] <= point.z) && (point.z <= xhi[2]));
246 }
247
248 /* \brief Crops the position at the specified boundary if do_cropping is true, 1D version
249 * \param[in] x0 The initial particle position
250 * \param[in/out] x1 The final particle position, with the returned value being cropped
251 * \param[in] xmin The lower boundary of the domain in grid units
252 * \param[in] xmax The upper boundary of the domain in grid units
253 * \param[in] do_cropping Whether to crop at each of the boundaries
254 */
256 void crop_at_boundary(double & x1,
257 double xmin, double xmax, amrex::GpuArray<bool,2> const& do_cropping) {
258 if (do_cropping[0] && x1 < xmin) {
259 x1 = xmin;
260 }
261 else if (do_cropping[1] && x1 > xmax) {
262 x1 = xmax;
263 }
264 }
265
266 /* \brief Crops the position at the specified boundary if do_cropping is true, 2D version
267 * \param[in] x0, z0 The initial particle position
268 * \param[in/out] x1, z1 The final particle position, with the returned value being cropped
269 * \param[in] xmin The lower boundary of the domain in grid units
270 * \param[in] xmax The upper boundary of the domain in grid units
271 * \param[in] do_cropping Whether to crop at each of the boundaries
272 */
274 void crop_at_boundary(double x0, double z0,
275 double & x1, double & z1,
276 double xmin, double xmax, amrex::GpuArray<bool,2> const& do_cropping) {
277 if (do_cropping[0] && x1 < xmin) {
278 double const fx = ((x0 - x1) != 0. ? (x0 - xmin)/(x0 - x1) : 0.);
279 x1 = xmin;
280 z1 = z0 + fx*(z1 - z0);
281 }
282 else if (do_cropping[1] && x1 > xmax) {
283 double const fx = ((x0 - x1) != 0. ? (xmax - x0)/(x1 - x0) : 0.);
284 x1 = xmax;
285 z1 = z0 + fx*(z1 - z0);
286 }
287 }
288
289 /* \brief Crops the position at the specified boundary if do_cropping is true, 3D version
290 * \param[in] x0, y0, z0 The initial particle position
291 * \param[in/out] x1, y1, z1 The final particle position, with the returned value being cropped
292 * \param[in] xmin The lower boundary of the domain in grid units
293 * \param[in] xmax The upper boundary of the domain in grid units
294 * \param[in] do_cropping Whether to crop at each of the boundaries
295 */
297 void crop_at_boundary(double x0, double y0, double z0,
298 double & x1, double & y1, double & z1,
299 double xmin, double xmax, amrex::GpuArray<bool,2> const& do_cropping) {
300 if (do_cropping[0] && x1 < xmin) {
301 double const fx = ((x0 - x1) != 0. ? (x0 - xmin)/(x0 - x1) : 0.);
302 x1 = xmin;
303 y1 = y0 + fx*(y1 - y0);
304 z1 = z0 + fx*(z1 - z0);
305 }
306 else if (do_cropping[1] && x1 > xmax) {
307 double const fx = ((x0 - x1) != 0. ? (xmax - x0)/(x1 - x0) : 0.);
308 x1 = xmax;
309 y1 = y0 + fx*(y1 - y0);
310 z1 = z0 + fx*(z1 - z0);
311 }
312 }
313
314 /* \brief Check if the particle position is out of bounds at a boundary
315 * where orbit cropping is being performed.
316 * \param[in] xp, yp, zp The particle position
317 * \param[in] dinv 3D cell size inverse
318 * \param[in] xyzmin Physical lower bounds of domain
319 * \param[in] domain_double The domain boundary indicies cast to double values
320 * \param[in] do_cropping Whether to crop particle orbits at domain boundaries
321 * return whether position is out of bounds
322 */
324 bool is_out_of_bounds ([[maybe_unused]] double xp,
325 [[maybe_unused]] double yp,
326 [[maybe_unused]] double zp,
327 const amrex::XDim3 & dinv,
328 const amrex::XDim3 & xyzmin,
329 const amrex::GpuArray<amrex::GpuArray<double,2>, AMREX_SPACEDIM> & domain_double,
330 const amrex::GpuArray<amrex::GpuArray<bool,2>, AMREX_SPACEDIM> & do_cropping)
331 {
332
333 // Store logical particle position (in grid units) in temporary array
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;
349#endif
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;
353#endif
354
355 // Check if particle's position is out of bounds
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])) {
359 return true;
360 }
361 }
362 return false;
363
364 }
365
366 /* \brief Add or subtract a small percent of energy from a
367 * pair of particles such that momentum is not disturbed.
368 *
369 * This is done by treating it as an inelastic scattering event
370 * with potential U = deltaE and zero scattering angle
371 * deltaE > 0 ==> need to take energy away
372 * deltaE < 0 ==> need to add energy
373 *
374 * \param[in/out] uxp, uyp, uzp momenta of the particles
375 * \param[in] w weight of the particles
376 * \param[in] indices indices of particles, listed in cell order
377 * \param[in] cell_start start index of particles in the cell
378 * \param[in] cell_stop start index of particles in the next cell
379 * \param[in] mass mass of the particles
380 * \param[in] energy_fraction fraction of pair's relative energy to change
381 * \param[in/out] deltaE amount of energy to be distributed in this species
382 */
383 template <typename T_index>
385 bool ModifyEnergyPairwise (amrex::ParticleReal * const AMREX_RESTRICT uxp, //NOLINT(readability-non-const-parameter)
386 amrex::ParticleReal * const AMREX_RESTRICT uyp, //NOLINT(readability-non-const-parameter)
387 amrex::ParticleReal * const AMREX_RESTRICT uzp, //NOLINT(readability-non-const-parameter)
388 const amrex::ParticleReal * const AMREX_RESTRICT w,
389 T_index const * const AMREX_RESTRICT indices,
390 T_index const cell_start,
391 T_index const cell_stop,
392 amrex::ParticleReal const mass,
393 amrex::ParticleReal const energy_fraction,
394 amrex::ParticleReal & deltaE )
395 {
396 using namespace amrex::literals;
397
398 constexpr auto c2 = PhysConst::c2;
399
400 int const numCell = (cell_stop - cell_start);
401
402 if (numCell < 2) {
403 return true;
404 }
405
406 // Adjust particle's momentum to absorb deltaE.
407 // This loops over the particles, two at a time, distributing
408 // the energy until all of it has been distributed or failing if not.
409 // The loop is setup to switch between even first and odd first pairs
410 // each loop over the particles.
411 int loop_count = 0;
412 int const max_loop_count = 10;
413 int pair_offset = 0;
414 T_index i1 = cell_start + pair_offset;
415 bool correction_failed = false;
416 bool deltaE_is_zero = false;
417 while (!deltaE_is_zero) {
418
419 T_index i2 = i1 + 1;
420 if (i2 == cell_stop) {
421 // If i1 is the last particle, set the other particle, i2, to be the first particle
422 i2 = cell_start;
423 }
424
425 int const sign = (deltaE < 0.0_prt ? -1 : 1);
426
427 const amrex::ParticleReal ux1 = uxp[ indices[i1] ];
428 const amrex::ParticleReal uy1 = uyp[ indices[i1] ];
429 const amrex::ParticleReal uz1 = uzp[ indices[i1] ];
430 const amrex::ParticleReal ux2 = uxp[ indices[i2] ];
431 const amrex::ParticleReal uy2 = uyp[ indices[i2] ];
432 const amrex::ParticleReal uz2 = uzp[ indices[i2] ];
433 const amrex::ParticleReal wpmp1 = mass*w[ indices[i1] ];
434 const amrex::ParticleReal wpmp2 = mass*w[ indices[i2] ];
435
436 // For the calculations below, since it involves taking differences
437 // between similar numbers, which can lose precision, to achieve machine
438 // level accuracy on the energy conservation long double precision would
439 // be required. However, long double is implemented inconsistently across
440 // platforms, so standard precision is used here with the accordant loss
441 // of precision. For practical purposes however, the loss of precision is negligible.
442
443 const amrex::ParticleReal ux = ux1 - ux2;
444 const amrex::ParticleReal uy = uy1 - uy2;
445 const amrex::ParticleReal uz = uz1 - uz2;
446 const amrex::ParticleReal dbetasq = (ux*ux + uy*uy + uz*uz)/c2;
447 const amrex::ParticleReal gbsq1 = (ux1*ux1 + uy1*uy1 + uz1*uz1)/c2;
448 const amrex::ParticleReal gbsq2 = (ux2*ux2 + uy2*uy2 + uz2*uz2)/c2;
449 const amrex::ParticleReal gamma1 = std::sqrt(1.0_prt + gbsq1);
450 const amrex::ParticleReal gamma2 = std::sqrt(1.0_prt + gbsq2);
451 const amrex::ParticleReal E1 = wpmp1*gamma1*c2;
452 const amrex::ParticleReal E2 = wpmp2*gamma2*c2;
453 const amrex::ParticleReal Etot = E1 + E2;
454 const amrex::ParticleReal pxtot = wpmp1*ux1 + wpmp2*ux2;
455 const amrex::ParticleReal pytot = wpmp1*uy1 + wpmp2*uy2;
456 const amrex::ParticleReal pztot = wpmp1*uz1 + wpmp2*uz2;
457 const amrex::ParticleReal Ecm = std::sqrt(Etot*Etot - (pxtot*pxtot + pytot*pytot + pztot*pztot)*c2);
458 const amrex::ParticleReal Erel = Ecm - wpmp1*c2 - wpmp2*c2;
459
460 if (Erel > 0.0_prt) {
461
462 // Set the amount of energy change for this pair based on the
463 // relative energy in the center of momentum.
464 bool deltaE_finishes = false;
465 amrex::ParticleReal deltaEpair = static_cast<amrex::ParticleReal>(sign*energy_fraction)*Erel;
466 if (std::abs(deltaEpair) >= std::abs(deltaE)) {
467 deltaEpair = deltaE;
468 deltaE_finishes = true;
469 }
470
471 const amrex::ParticleReal A = Etot - deltaEpair;
472 const amrex::ParticleReal D = A*A + E2*E2 - E1*E1;
473 const amrex::ParticleReal p2dotu = wpmp2*(ux2*ux + uy2*uy + uz2*uz);
474 const amrex::ParticleReal ptdotu = pxtot*ux + pytot*uy + pztot*uz;
475
476 // Compute coefficients for quadratic equation for alpha.
477 const amrex::ParticleReal a = A*A*dbetasq - ptdotu*ptdotu;
478 const amrex::ParticleReal b = D*ptdotu - 2.0_prt*A*A*p2dotu;
479 const amrex::ParticleReal c = A*A*E2*E2 - D*D/4.0_prt;
480
481 const amrex::ParticleReal root = b*b - 4.0_prt*a*c;
482 if (root >= 0.0_prt && amrex::Math::abs(a) > 0.0_prt) {
483
484 // Update particle velocities.
485 const amrex::ParticleReal alpha = (-b + std::sqrt(root))/(2.0_prt*a);
486 const amrex::ParticleReal ratio1 = alpha/(wpmp1*c2);
487 const amrex::ParticleReal ratio2 = alpha/(wpmp2*c2);
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;
494
495 // Update energy violation.
496 if (deltaE_finishes) {
497 deltaE = 0.0_prt;
498 deltaE_is_zero = true;
499 }
500 else {
501 deltaE -= deltaEpair;
502 }
503
504 }
505
506 }
507
508 // Update particle 1 index.
509 if (i1 < cell_stop - 2) {
510 i1 = i2 + 1;
511 } else {
512 loop_count++;
513 if (loop_count >= max_loop_count) {
514 correction_failed = true;
515 break;
516 }
517
518 pair_offset = 1 - pair_offset; // 0, 1, 0, 1, ...
519 i1 = cell_start + pair_offset;
520 }
521 }
522
523 return correction_failed;
524 }
525
543
544 template <typename T_index>
546 void operator() (T_index index_array[], const amrex::ParticleReal bin_array[], const T_index start, const T_index n) const
547 {
548 // sort index_array into a max heap structure
549 for (T_index i = 1; i < n; i++)
550 {
551 auto j = i;
552 // move child through heap if it is less than its parent
553 while (j > 0 && bin_array[index_array[j+start]] < bin_array[index_array[(j - 1)/2 + start]]) {
554 // swap child and parent until branch is properly ordered
555 amrex::Swap(index_array[j+start], index_array[(j - 1)/2 + start]);
556 j = (j - 1) / 2;
557 }
558 }
559
560 for (T_index i = n - 1; i > 0; i--)
561 {
562 // swap value of first (now the smallest value) to the new end point
563 amrex::Swap(index_array[start], index_array[i+start]);
564
565 // remake the max heap
566 T_index j = 0, index;
567 while (j < i) {
568 index = 2 * j + 1;
569
570 // if left child is larger than right child, point index variable to right child
571 if (index + 1 < i && bin_array[index_array[index+start]] > bin_array[index_array[index+1+start]]) {
572 index++;
573 }
574 // if parent is larger than child, swap parent with child having lower value
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]);
577 }
578 j = index;
579 }
580 }
581 }
582 };
583}
584
585#endif // WARPX_PARTICLE_UTILS_H_
#define AMREX_FORCE_INLINE
#define AMREX_RESTRICT
#define AMREX_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
Real Random()
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