1#ifndef AMREX_PARTICLEUTIL_H_
2#define AMREX_PARTICLEUTIL_H_
3#include <AMReX_Config.H>
33template <
class Iterator>
34requires (IsParticleIterator<Iterator>::value)
52template <
class Iterator>
53requires (IsParticleIterator<Iterator>::value)
57 const auto& tile = pti.GetParticleTile();
58 const auto np = tile.numParticles();
59 const auto& ptd = tile.getConstParticleTileData();
60 const auto& geom = pti.Geom(pti.GetLevel());
62 const auto& domain = geom.Domain();
63 const auto& plo = geom.ProbLoArray();
64 const auto& dxi = geom.InvCellSizeArray();
66 Box box = pti.tilebox();
71 using ReduceTuple =
typename decltype(reduce_data)::Type;
73 reduce_op.
eval(np, reduce_data,
77 if (!p.id().is_valid()) {
return false; }
78 using AssignorType =
typename Iterator::CellAssignor;
79 AssignorType assignor;
80 IntVect iv = assignor(p, plo, dxi, domain);
83 int hv = amrex::get<0>(reduce_data.
value(reduce_op));
100requires (IsParticleContainer<PC>::value)
120requires (IsParticleContainer<PC>::value)
142requires (IsParticleContainer<PC>::value)
167requires (IsParticleContainer<PC>::value)
173 using ParIter =
typename PC::ParConstIterType;
175 for (
int lev = lev_min; lev <= lev_max; ++lev)
178#pragma omp parallel if (Gpu::notInLaunchRegion() && !system::regtest_reduction) reduction(+:num_wrong)
194 if (a_do_tiling ==
false) {
201 auto tiling_1d = [](
int i,
int lo,
int hi,
int tilesize,
202 int& ntile,
int& tileidx,
int& tlo,
int& thi) {
203 int ncells = hi-lo+1;
205 int ts_right = ncells/ntile;
206 int ts_left = ts_right+1;
207 int nleft = ncells - ntile*ts_right;
209 int nbndry = nleft*ts_left;
211 tileidx = ii / ts_left;
212 tlo = lo + tileidx * ts_left;
213 thi = tlo + ts_left - 1;
215 tileidx = nleft + (ii-nbndry) / ts_right;
216 tlo = lo + tileidx * ts_right + nleft;
217 thi = tlo + ts_right - 1;
222 IntVect ntiles, ivIndex, tilelo, tilehi;
228 AMREX_D_TERM(tiling_1d(iv0, sml[0], big[0], a_tile_size[0], ntiles[0], ivIndex[0], tilelo[0], tilehi[0]);,
229 tiling_1d(iv1, sml[1], big[1], a_tile_size[1], ntiles[1], ivIndex[1], tilelo[1], tilehi[1]);,
230 tiling_1d(iv2, sml[2], big[2], a_tile_size[2], ntiles[2], ivIndex[2], tilelo[2], tilehi[2]););
232 tbx =
Box(tilelo, tilehi);
234 return AMREX_D_TERM(ivIndex[0], + ntiles[0]*ivIndex[1], + ntiles[0]*ntiles[1]*ivIndex[2]);
241 if (a_do_tiling ==
false) {
247 auto tiling_1d = [](
int lo,
int hi,
int tilesize,
int& ntile) {
248 int ncells = hi-lo+1;
256 AMREX_D_TERM(tiling_1d(sml[0], big[0], a_tile_size[0], ntiles[0]);,
257 tiling_1d(sml[1], big[1], a_tile_size[1], ntiles[1]);,
258 tiling_1d(sml[2], big[2], a_tile_size[2], ntiles[2]););
260 return AMREX_D_TERM(ntiles[0], *=ntiles[1], *=ntiles[2]);
271 int* bin_type_array=
nullptr)
272 : m_off_bins_p(off_bins_p), m_dxi_p(dxi_p), m_plo_p(plo_p) ,
273 m_lo_p(lo_p) , m_hi_p(hi_p) , m_bin_type_array(bin_type_array) {}
275 template <
typename T>
280 int type = (m_bin_type_array) ? m_bin_type_array[i] : 0;
281 int offset = m_off_bins_p[type];
284 AMREX_ASSERT((p.pos(1)-m_plo_p[type][1])*m_dxi_p[type][1] - m_lo_p[type].
y >= 0.0);,
285 AMREX_ASSERT((p.pos(2)-m_plo_p[type][2])*m_dxi_p[type][2] - m_lo_p[type].
z >= 0.0));
287 auto iv =
IntVect(
AMREX_D_DECL(
static_cast<int>(amrex::Math::floor((p.pos(0)-m_plo_p[type][0])*m_dxi_p[type][0])) - m_lo_p[type].
x,
288 static_cast<int>(amrex::Math::floor((p.pos(1)-m_plo_p[type][1])*m_dxi_p[type][1])) - m_lo_p[type].
y,
289 static_cast<int>(amrex::Math::floor((p.pos(2)-m_plo_p[type][2])*m_dxi_p[type][2])) - m_lo_p[type].
z));
290 auto iv3 = iv.dim3();
291 int nx = m_hi_p[type].
x-m_lo_p[type].
x+1;
292 int ny = m_hi_p[type].
y-m_lo_p[type].
y+1;
293 int nz = m_hi_p[type].
z-m_lo_p[type].
z+1;
297 return static_cast<unsigned int>( (uiz * ny + uiy) * nx + uix +
offset );
301 const int* m_off_bins_p;
306 int* m_bin_type_array;
317 template <
typename ParticleType>
319 unsigned int operator() (
const ParticleType& p)
const noexcept
324 return static_cast<unsigned int>(tid);
348 AMREX_D_DECL(
int(amrex::Math::floor((p.pos(0)-plo[0])*dxi[0])),
349 int(amrex::Math::floor((p.pos(1)-plo[1])*dxi[1])),
350 int(amrex::Math::floor((p.pos(2)-plo[2])*dxi[2]))));
373 const Box& domain)
noexcept
376 iv += domain.smallEnd();
380template <
typename PTD>
385 const Box& domain)
noexcept
388 AMREX_D_DECL(
int(amrex::Math::floor((ptd.pos(0, i)-plo[0])*dxi[0])),
389 int(amrex::Math::floor((ptd.pos(1, i)-plo[1])*dxi[1])),
390 int(amrex::Math::floor((ptd.pos(2, i)-plo[2])*dxi[2]))));
391 iv += domain.smallEnd();
398 template <
typename P>
403 const Box& domain)
const noexcept
414 const Box& domain)
noexcept
416 if (!p.id().is_valid()) {
return -1; }
430 bool shifted =
false;
431 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim)
433 if (! is_per[idim]) {
continue; }
434 if (p.pos(idim) > rhi[idim]) {
435 while (p.pos(idim) > rhi[idim]) {
436 p.pos(idim) -=
static_cast<ParticleReal>(phi[idim] - plo[idim]);
439 if (p.pos(idim) < rlo[idim]) {
440 p.pos(idim) = rlo[idim];
444 else if (p.pos(idim) < rlo[idim]) {
445 while (p.pos(idim) < rlo[idim]) {
446 p.pos(idim) +=
static_cast<ParticleReal>(phi[idim] - plo[idim]);
449 if (p.pos(idim) > rhi[idim]) {
450 p.pos(idim) = rhi[idim];
454 AMREX_ASSERT( (p.pos(idim) >= rlo[idim] ) && ( p.pos(idim) <= rhi[idim] ));
472template <
typename PTile,
typename ParFunc>
476 const int np = ptile.numParticles();
477 if (np == 0) {
return 0; }
479 auto ptd = ptile.getParticleTileData();
481 const int num_left = Reduce::Sum<int>(np,
484 return int(is_left(ptd, i));
498 const int max_num_swaps = std::min(num_left, np - num_left);
499 if (max_num_swaps == 0) {
return num_left; }
503 int *
const p_index_left = index_left.
dataPtr();
504 int *
const p_index_right = index_right.
dataPtr();
520 Scan::PrefixSum<int>(np,
523 return int(!is_left(ptd, i));
527 if (!is_left(ptd, i)) {
529 if (dst < max_num_swaps) {
530 p_index_right[dst] = i;
533 int dst = num_left-1-(i-s);
534 if (dst < max_num_swaps) {
535 p_index_left[dst] = i;
562 int left_i = p_index_left[i];
563 int right_i = p_index_right[i];
564 if (right_i < left_i) {
589template <
typename PTile,
typename ParFunc>
593 const int np = ptile.numParticles();
594 if (np == 0) {
return; }
596 auto ptd = ptile.getParticleTileData();
598 const int max_num_swaps = std::min(num_left, np - num_left);
599 if (max_num_swaps == 0) {
return; }
603 int *
const p_index_left = index_left.
dataPtr();
604 int *
const p_index_right = index_right.
dataPtr();
606 Scan::PrefixSum<int>(np,
609 return int(!is_left(ptd, i));
613 if (!is_left(ptd, i)) {
615 if (dst < max_num_swaps) {
616 p_index_right[dst] = i;
619 int dst = num_left-1-(i-s);
620 if (dst < max_num_swaps) {
621 p_index_left[dst] = i;
630 int left_i = p_index_left[i];
631 int right_i = p_index_right[i];
632 if (right_i < left_i) {
641template <
typename PTile>
647 return ptd.id(i).is_valid();
649 ptile.resize(new_size);
652template <
typename PTile,
typename PLocator,
typename CellAssignor>
661 int lev,
int gid,
int tid,
662 int lev_min,
int lev_max,
IntVect nGrow,
bool remove_negative)
668 uint8_t *
const p_particle_stays = particle_stays.
dataPtr();
669 auto ptd = ptile.getParticleTileData();
680 if (!ptd.id(i).is_valid())
688 auto p_prime = ptd.getSuperParticle(i);
689 enforcePeriodic(p_prime, plo, phi, rlo, rhi, is_per);
690 auto tup_prime = ploc(p_prime, lev_min, lev_max, nGrow, assignor);
691 assigned_grid = amrex::get<0>(tup_prime);
692 assigned_tile = amrex::get<1>(tup_prime);
693 assigned_lev = amrex::get<2>(tup_prime);
694 if (assigned_grid >= 0)
696 AMREX_D_TERM(ptd.pos(0, i) = p_prime.pos(0);,
697 ptd.pos(1, i) = p_prime.pos(1);,
698 ptd.pos(2, i) = p_prime.pos(2););
700 else if (lev_min > 0)
703 p_prime.pos(1) = ptd.pos(1, i);,
704 p_prime.pos(2) = ptd.pos(2, i););
705 auto tup = ploc(p_prime, lev_min, lev_max, nGrow, assignor);
706 assigned_grid = amrex::get<0>(tup);
707 assigned_tile = amrex::get<1>(tup);
708 assigned_lev = amrex::get<2>(tup);
712 p_particle_stays[i] = uint8_t(
713 ((remove_negative ==
false) && (!ptd.id(i).is_valid())) ||
714 ((assigned_grid == gid) && (assigned_tile == tid) &&
715 (assigned_lev == lev) && (getPID(lev, gid, tid) == pid)));
720 return p_particle_stays[i];
724template <
class PC1,
class PC2>
726 if (pc1.numLevels() != pc2.numLevels()) {
return false;}
727 if (pc1.do_tiling != pc2.do_tiling) {
return false;}
728 if (pc1.tile_size != pc2.tile_size) {
return false;}
729 for (
int lev = 0; lev < pc1.numLevels(); ++lev) {
730 if (pc1.ParticleBoxArray(lev) != pc2.ParticleBoxArray(lev)) {
return false;}
731 if (pc1.ParticleDistributionMap(lev) != pc2.ParticleDistributionMap(lev)) {
return false;}
738 using Iter =
typename PC::ParIterType;
739 for (
int lev = 0; lev < pc.numLevels(); ++lev) {
740 for (Iter pti(pc, lev); pti.isValid(); ++pti) {
741 pc.DefineAndReturnParticleTile(lev, pti);
746IntVect computeRefFac (
const ParGDBBase* a_gdb,
int src_lev,
int lev);
748Vector<int> computeNeighborProcs (
const ParGDBBase* a_gdb,
int ngrow);
750Vector<int> computeNeighborProcs (
const ParGDBBase* a_gdb, IntVect ngrow);
753namespace particle_detail
756void clearEmptyEntries (C& c)
758 for (
auto c_it = c.begin(); c_it != c.end(); )
760 if (c_it->second.empty()) { c.erase(c_it++); }
767template <
class index_type,
typename F>
769 index_type nbins, F
const& f)
773#if defined(AMREX_USE_HIP)
776 static constexpr index_type gpu_block_size = 64;
777 static constexpr bool compressed_layout =
true;
781 static constexpr index_type gpu_block_size = 1024;
782 static constexpr bool compressed_layout =
false;
785 static constexpr index_type gpu_block_size_m1 = gpu_block_size - 1;
786 static constexpr index_type llist_guard = std::numeric_limits<index_type>::max();
789 nbins = (nbins + gpu_block_size_m1) / gpu_block_size * gpu_block_size;
796 index_type* pllist_start = llist_start.
dataPtr();
797 index_type* pllist_next = llist_next.
dataPtr();
798 index_type* pperm = perm.
dataPtr();
799 index_type* pglobal_idx = global_idx.
dataPtr();
804 pllist_next[i] = Gpu::Atomic::Exch(pllist_start + f(i), i);
807#if defined(AMREX_USE_CUDA) || defined(AMREX_USE_HIP)
808 amrex::launch<gpu_block_size>(nbins / gpu_block_size, Gpu::gpuStream(),
810 __shared__ index_type sdata[gpu_block_size];
811 __shared__ index_type global_idx_start;
812 __shared__ index_type idx_start;
814 index_type current_idx = 0;
816 if constexpr (compressed_layout) {
820 current_idx = pllist_start[threadIdx.x + gpu_block_size * blockIdx.x];
822 index_type num_particles_thread = 0;
823 while (current_idx != llist_guard) {
824 ++num_particles_thread;
825 current_idx = pllist_next[current_idx];
828 index_type num_particles_block =
829 Gpu::blockReduceSum<gpu_block_size>(num_particles_thread);
831 if (threadIdx.x == 0) {
832 global_idx_start = Gpu::Atomic::Add(pglobal_idx, num_particles_block);
836 current_idx = pllist_start[threadIdx.x + gpu_block_size * blockIdx.x];
839 sdata[threadIdx.x] = index_type(current_idx != llist_guard);
843 for (index_type i = 1; i<gpu_block_size; i*=2) {
845 if (threadIdx.x >= i) {
846 x = sdata[threadIdx.x - i];
849 if (threadIdx.x >= i) {
850 sdata[threadIdx.x] +=
x;
854 if (sdata[gpu_block_size_m1] == 0) {
857 if (threadIdx.x == gpu_block_size_m1) {
858 if constexpr (compressed_layout) {
859 idx_start = global_idx_start;
860 global_idx_start += sdata[gpu_block_size_m1];
862 idx_start = Gpu::Atomic::Add(pglobal_idx, sdata[gpu_block_size_m1]);
866 sdata[threadIdx.x] += idx_start;
867 if (current_idx != llist_guard) {
868 pperm[sdata[threadIdx.x] - 1] = current_idx;
869 current_idx = pllist_next[current_idx];
875 Abort(
"PermutationForDeposition only implemented for CUDA and HIP");
878 Gpu::Device::streamSynchronize();
881template <
class index_type,
class PTile>
888 const IntVect type_vect = idx_type - idx_type / 2 * 2;
901 const int ref_product =
AMREX_D_TERM(refine_vect[0], * refine_vect[1], * refine_vect[2]);
902 const IntVect ref_offset(
AMREX_D_DECL(1, refine_vect[0], refine_vect[0] * refine_vect[1]));
904 auto ptd = ptile.getConstParticleTileData();
905 PermutationForDeposition<index_type>(perm, nitems, bx.
numPts() * ref_product,
908 const auto p = ptd[idx];
910 IntVect iv = ((p.pos() - pos_offset) * dxi).round();
912 IntVect iv_coarse = iv / refine_vect;
913 IntVect iv_remainder = iv - iv_coarse * refine_vect;
917 return bx.
index(iv_coarse) + bx.
numPts() * (iv_remainder * ref_offset).sum();
923 int first_r_name = 0;
924 if constexpr (P::is_soa_particle) {
925 if (i < AMREX_SPACEDIM) {
926 constexpr int x_in_ascii = 120;
927 std::string
const name{char(x_in_ascii+i)};
930 first_r_name = AMREX_SPACEDIM;
932 std::string
const name{(
"real_comp" + std::to_string(i-first_r_name))};
938 std::string
const name{(
"int_comp" + std::to_string(i))};
952template <
class PTile,
class index_type>
953requires (!PTile::ParticleType::is_rtsoa_particle)
955ReorderParticles (PTile& ptile,
const index_type* permutations)
957 const size_t np = ptile.numParticles();
958 const size_t np_total = np + ptile.numNeighborParticles();
960#if defined(AMREX_USE_CUDA) && defined(_WIN32)
961 if (!PTile::ParticleType::is_soa_particle)
963 if constexpr (!PTile::ParticleType::is_soa_particle)
966 static_assert(
sizeof(
typename PTile::ParticleType)%4 == 0 &&
sizeof(uint32_t) == 4);
967 using tmp_t = std::conditional_t<
sizeof(
typename PTile::ParticleType)%8 == 0,
969 constexpr std::size_t nchunks =
sizeof(
typename PTile::ParticleType) /
sizeof(tmp_t);
971 auto* ptmp = tmp.
data();
972 auto* paos = (tmp_t*)(ptile.getParticleTileData().m_aos);
973 for (std::size_t ichunk = 0; ichunk < nchunks; ++ichunk) {
977 ptmp[i] = paos[permutations[i]*nchunks+ichunk];
981 paos[i*nchunks+ichunk] = ptmp[i];
984 Gpu::streamSynchronize();
986 typename PTile::SoA::IdCPU tmp_idcpu;
987 if constexpr (PTile::has_polymorphic_allocator) {
988 tmp_idcpu.setArena(ptile.GetStructOfArrays().GetIdCPUData().arena());
990 tmp_idcpu.resize(np_total);
991 auto src = ptile.GetStructOfArrays().GetIdCPUData().data();
992 uint64_t* dst = tmp_idcpu.data();
995 dst[i] = i < np ? src[permutations[i]] : src[i];
998 Gpu::streamSynchronize();
1000 ptile.GetStructOfArrays().GetIdCPUData().swap(tmp_idcpu);
1004 typename PTile::RealVector tmp_real;
1005 if (ptile.NumRealComps() > 0) {
1006 if constexpr (PTile::has_polymorphic_allocator) {
1007 tmp_real.setArena(ptile.GetStructOfArrays().GetRealData(0).arena());
1009 tmp_real.resize(np_total);
1011 for (
int comp = 0; comp < ptile.NumRealComps(); ++comp) {
1012 auto src = ptile.GetStructOfArrays().GetRealData(comp).data();
1016 dst[i] = i < np ? src[permutations[i]] : src[i];
1019 Gpu::streamSynchronize();
1021 ptile.GetStructOfArrays().GetRealData(comp).swap(tmp_real);
1025 typename PTile::IntVector tmp_int;
1026 if (ptile.NumIntComps() > 0) {
1027 if constexpr (PTile::has_polymorphic_allocator) {
1028 tmp_int.setArena(ptile.GetStructOfArrays().GetIntData(0).arena());
1030 tmp_int.resize(np_total);
1033 for (
int comp = 0; comp < ptile.NumIntComps(); ++comp) {
1034 auto src = ptile.GetStructOfArrays().GetIntData(comp).data();
1035 int* dst = tmp_int.data();
1038 dst[i] = i < np ? src[permutations[i]] : src[i];
1041 Gpu::streamSynchronize();
1043 ptile.GetStructOfArrays().GetIntData(comp).swap(tmp_int);
1056template <
class PTile,
class index_type>
1057requires (PTile::ParticleType::is_rtsoa_particle)
1059ReorderParticles (PTile& ptile,
const index_type* permutations)
1061 const size_t np = ptile.numParticles();
1065 auto src = ptile.GetIdCPUData().data();
1066 uint64_t* dst = tmp_idcpu.
data();
1069 dst[i] = src[permutations[i]];
1079 for (
int comp = 0; comp < ptile.NumRealComps(); ++comp) {
1080 auto src = ptile.GetRealData(comp).data();
1081 auto dst = tmp_real.
data();
1084 dst[i] = src[permutations[i]];
1095 for (
int comp = 0; comp < ptile.NumIntComps(); ++comp) {
1096 auto src = ptile.GetIntData(comp).data();
1097 auto dst = tmp_int.
data();
1100 dst[i] = src[permutations[i]];
1109 Gpu::streamSynchronize();
1112#ifdef AMREX_USE_HDF5_ASYNC
1113void async_vol_es_wait_particle();
1114void async_vol_es_wait_close_particle();
#define BL_PROFILE(a)
Definition AMReX_BLProfiler.H:551
#define AMREX_ASSERT(EX)
Definition AMReX_BLassert.H:38
#define AMREX_ALWAYS_ASSERT(EX)
Definition AMReX_BLassert.H:50
Integer-lattice boxes and helpers for defining index-space regions.
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:124
#define AMREX_HOST_DEVICE_FOR_1D(...)
Definition AMReX_GpuLaunchMacrosC.nolint.H:105
#define AMREX_GPU_DEVICE
Definition AMReX_GpuQualifiers.H:18
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
Array4< int const > offset
Definition AMReX_HypreMLABecLap.cpp:1129
Array4< int const > mask
Definition AMReX_InterpFaceRegister.cpp:93
#define AMREX_D_TERM(a, b, c)
Definition AMReX_SPACE.H:172
#define AMREX_D_DECL(a, b, c)
Definition AMReX_SPACE.H:171
__host__ __device__ BoxND & grow(int i) noexcept
Grow in all directions by i cells (negative shrinks).
Definition AMReX_Box.H:668
__host__ __device__ const IntVectND< dim > & bigEnd() const &noexcept
Return the inclusive upper bound of the box.
Definition AMReX_Box.H:136
__host__ __device__ Long numPts() const noexcept
Return the number of points contained in the BoxND.
Definition AMReX_Box.H:385
__host__ __device__ BoxND & convert(IndexTypeND< dim > typ) noexcept
Convert the BoxND from the current type into the argument type. This may change the BoxND coordinates...
Definition AMReX_Box.H:1008
__host__ __device__ bool contains(const IntVectND< dim > &p) const noexcept
Return true if argument is contained within BoxND.
Definition AMReX_Box.H:233
__host__ __device__ Long index(const IntVectND< dim > &v) const noexcept
Return offset of point from smallend; i.e. index(smallend) -> 0, bigend would return numPts()-1....
Definition AMReX_Box.H:1089
__host__ __device__ const IntVectND< dim > & smallEnd() const &noexcept
Return the inclusive lower bound of the box.
Definition AMReX_Box.H:124
const Real * CellSize() const noexcept
Returns the cellsize for each coordinate direction.
Definition AMReX_CoordSys.H:79
const Real * InvCellSize() const noexcept
Returns the inverse cellsize for each coordinate direction.
Definition AMReX_CoordSys.H:91
Rectangular problem domain geometry.
Definition AMReX_Geometry.H:75
void refine(IntVect const &rr)
Refine the Geometry by rr.
Definition AMReX_Geometry.H:429
const Real * ProbHi() const noexcept
Returns the hi end of the problem domain in each dimension.
Definition AMReX_Geometry.H:186
const Box & Domain() const noexcept
Returns our rectangular domain.
Definition AMReX_Geometry.H:216
const Real * ProbLo() const noexcept
Returns the lo end of the problem domain in each dimension.
Definition AMReX_Geometry.H:184
__host__ __device__ constexpr int min() const noexcept
minimum (no absolute values) value
Definition AMReX_IntVect.H:324
__host__ __device__ constexpr bool allGE(const IntVectND< dim > &rhs) const noexcept
Returns true if this is greater than or equal to argument for all components. NOTE: This is NOT a str...
Definition AMReX_IntVect.H:542
__host__ __device__ constexpr int max() const noexcept
maximum (no absolute values) value
Definition AMReX_IntVect.H:313
__host__ __device__ constexpr bool allLE(const IntVectND< dim > &rhs) const noexcept
Returns true if this is less than or equal to argument for all components. NOTE: This is NOT a strict...
Definition AMReX_IntVect.H:492
bool isValid() const noexcept
Is the iterator valid i.e. is it associated with a FAB?
Definition AMReX_MFIter.H:172
Dynamically allocated vector for trivially copyable data.
Definition AMReX_PODVector.H:308
void resize(size_type a_new_size, GrowthStrategy strategy=GrowthStrategy::Poisson)
Definition AMReX_PODVector.H:728
void free_async() noexcept
Definition AMReX_PODVector.H:853
T * dataPtr() noexcept
Definition AMReX_PODVector.H:670
T * data() noexcept
Definition AMReX_PODVector.H:666
Definition AMReX_ParIter.H:118
Definition AMReX_ParticleBufferMap.H:59
GetPID getPIDFunctor() const noexcept
Definition AMReX_ParticleBufferMap.H:195
Definition AMReX_Reduce.H:438
Type value()
Definition AMReX_Reduce.H:473
Definition AMReX_Reduce.H:597
void eval(MF const &mf, IntVect const &nghost, D &reduce_data, F &&f)
Definition AMReX_Reduce.H:731
amrex_real Real
Floating Point Type for Fields.
Definition AMReX_REAL.H:79
amrex_particle_real ParticleReal
Floating Point Type for Particles.
Definition AMReX_REAL.H:90
amrex_long Long
Definition AMReX_INT.H:30
void ParallelForOMP(T n, L const &f) noexcept
Performance-portable kernel launch function with optional OpenMP threading.
Definition AMReX_GpuLaunch.H:328
void Sum(Gpu::DeviceVector< T > &v, MPI_Comm comm)
Definition AMReX_GpuParallelReduce.H:34
__host__ __device__ constexpr const T & min(const T &a, const T &b) noexcept
Definition AMReX_Algorithm.H:31
__host__ __device__ constexpr const T & max(const T &a, const T &b) noexcept
Definition AMReX_Algorithm.H:53
MPI_Comm CommunicatorSub() noexcept
sub-communicator for current frame
Definition AMReX_ParallelContext.H:70
int MyProcSub() noexcept
my sub-rank in current frame
Definition AMReX_ParallelContext.H:76
static constexpr struct amrex::Scan::Type::Exclusive exclusive
static constexpr RetSum noRetSum
Definition AMReX_Scan.H:34
Definition AMReX_Amr.cpp:50
__host__ __device__ void ignore_unused(const Ts &...)
No-op helper that marks variables as intentionally unused.
Definition AMReX.H:259
__host__ __device__ void swapParticle(const ParticleTileData< T_ParticleType, NAR, NAI > &dst, const ParticleTileData< T_ParticleType, NAR, NAI > &src, int src_i, int dst_i) noexcept
A general single particle swapping routine that can run on the GPU.
Definition AMReX_ParticleTransformation.H:120
__host__ __device__ int getTileIndex(const IntVect &iv, const Box &box, const bool a_do_tiling, const IntVect &a_tile_size, Box &tbx)
Definition AMReX_ParticleUtil.H:191
void EnsureThreadSafeTiles(PC &pc)
Definition AMReX_ParticleUtil.H:737
std::string getDefaultCompNameInt(const int i)
Definition AMReX_ParticleUtil.H:937
int partitionParticlesByDest(PTile &ptile, const PLocator &ploc, CellAssignor const &assignor, const ParticleBufferMap &pmap, const GpuArray< Real, 3 > &plo, const GpuArray< Real, 3 > &phi, const GpuArray< ParticleReal, 3 > &rlo, const GpuArray< ParticleReal, 3 > &rhi, const GpuArray< int, 3 > &is_per, int lev, int gid, int tid, int lev_min, int lev_max, IntVect nGrow, bool remove_negative)
Definition AMReX_ParticleUtil.H:654
__host__ __device__ bool enforcePeriodic(P &p, amrex::GpuArray< amrex::Real, 3 > const &plo, amrex::GpuArray< amrex::Real, 3 > const &phi, amrex::GpuArray< amrex::ParticleReal, 3 > const &rlo, amrex::GpuArray< amrex::ParticleReal, 3 > const &rhi, amrex::GpuArray< int, 3 > const &is_per) noexcept
Definition AMReX_ParticleUtil.H:423
void ParallelFor(TypeList< CTOs... > ctos, std::array< int, sizeof...(CTOs)> const &runtime_options, T N, F &&f)
Definition AMReX_CTOParallelForImpl.H:202
void removeInvalidParticles(PTile &ptile)
Definition AMReX_ParticleUtil.H:643
__host__ __device__ int numTilesInBox(const Box &box, const bool a_do_tiling, const IntVect &a_tile_size)
Definition AMReX_ParticleUtil.H:239
BoxND< 3 > Box
Box is an alias for amrex::BoxND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:35
std::string getDefaultCompNameReal(const int i)
Definition AMReX_ParticleUtil.H:922
IntVectND< 3 > IntVect
IntVect is an alias for amrex::IntVectND instantiated with AMREX_SPACEDIM.
Definition AMReX_BaseFwd.H:38
__host__ __device__ int getParticleGrid(P const &p, amrex::Array4< int > const &mask, amrex::GpuArray< amrex::Real, 3 > const &plo, amrex::GpuArray< amrex::Real, 3 > const &dxi, const Box &domain) noexcept
Definition AMReX_ParticleUtil.H:411
int numParticlesOutOfRange(Iterator const &pti, int nGrow)
Returns the number of particles that are more than nGrow cells from the box correspond to the input i...
Definition AMReX_ParticleUtil.H:36
void PermutationForDeposition(Gpu::DeviceVector< index_type > &perm, index_type nitems, index_type nbins, F const &f)
Definition AMReX_ParticleUtil.H:768
bool SameIteratorsOK(const PC1 &pc1, const PC2 &pc2)
Definition AMReX_ParticleUtil.H:725
int partitionParticles(PTile &ptile, ParFunc const &is_left)
Reorders the ParticleTile into two partitions left [0, num_left-1] and right [num_left,...
Definition AMReX_ParticleUtil.H:474
void Abort(const std::string &msg)
Print a fatal-error message to stderr and abort execution.
Definition AMReX.cpp:241
const int[]
Definition AMReX_BLProfiler.cpp:1664
__host__ __device__ IntVect getParticleCell(P const &p, amrex::GpuArray< amrex::Real, 3 > const &plo, amrex::GpuArray< amrex::Real, 3 > const &dxi) noexcept
Returns the cell index for a given particle using the provided lower bounds and cell sizes.
Definition AMReX_ParticleUtil.H:343
A multidimensional array accessor.
Definition AMReX_Array4.H:288
Definition AMReX_ParticleUtil.H:265
BinMapper(const int *off_bins_p, const GpuArray< Real, 3 > *dxi_p, const GpuArray< Real, 3 > *plo_p, const Dim3 *lo_p, const Dim3 *hi_p, int *bin_type_array=nullptr)
Definition AMReX_ParticleUtil.H:266
__host__ __device__ unsigned int operator()(const T &ptd, int i) const
Definition AMReX_ParticleUtil.H:277
Definition AMReX_ParticleUtil.H:396
__host__ __device__ IntVect operator()(P const &p, amrex::GpuArray< amrex::Real, 3 > const &plo, amrex::GpuArray< amrex::Real, 3 > const &dxi, const Box &domain) const noexcept
Definition AMReX_ParticleUtil.H:400
A simple struct holding 3 int values for a 3D index.
Definition AMReX_Dim3.H:24
int x
Definition AMReX_Dim3.H:24
int z
Definition AMReX_Dim3.H:24
int y
Definition AMReX_Dim3.H:24
Definition AMReX_ParticleUtil.H:310
GpuArray< Real, 3 > plo
Definition AMReX_ParticleUtil.H:311
IntVect bin_size
Definition AMReX_ParticleUtil.H:314
__host__ __device__ unsigned int operator()(const ParticleType &p) const noexcept
Definition AMReX_ParticleUtil.H:319
GpuArray< Real, 3 > dxi
Definition AMReX_ParticleUtil.H:312
Box domain
Definition AMReX_ParticleUtil.H:313
Box box
Definition AMReX_ParticleUtil.H:315
Fixed-size array that can be used on GPU.
Definition AMReX_Array.H:52
Definition AMReX_GpuMemory.H:57
T * dataPtr()
Definition AMReX_GpuMemory.H:91