1#ifndef AMREX_PARTICLEREDUCE_H_
2#define AMREX_PARTICLEREDUCE_H_
3#include <AMReX_Config.H>
19namespace particle_detail {
21template <
typename F,
typename T_ParticleType,
int NAR,
int NAI>
27 if constexpr ( ! T_ParticleType::is_soa_particle &&
30 }
else if constexpr (
IsCallable<
F,
decltype(p.getSuperParticle(i))>::value) {
31 return f(p.getSuperParticle(i));
78template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
83 return ReduceSum(pc, 0, pc.finestLevel(), std::forward<F>(f));
126template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
131 return ReduceSum(pc, lev, lev, std::forward<F>(f));
175template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
177ReduceSum (PC
const& pc,
int lev_min,
int lev_max,
F const& f)
188 using ReduceTuple =
typename decltype(reduce_data)::Type;
190 for (
int lev = lev_min; lev <= lev_max; ++lev)
192 const auto& plev = pc.GetParticles(lev);
193 for (
const auto& kv : plev)
195 const auto& tile = plev.at(kv.first);
196 const auto np = tile.numParticles();
197 const auto& ptd = tile.getConstParticleTileData();
198 reduce_op.
eval(np, reduce_data,
205 ReduceTuple hv = reduce_data.
value(reduce_op);
206 sm = amrex::get<0>(hv);
211 for (
int lev = lev_min; lev <= lev_max; ++lev)
213 const auto& plev = pc.GetParticles(lev);
216 for (
auto& kv : plev)
218 grid_tile_ids.push_back(kv.first);
219 ptile_ptrs.push_back(&(kv.second));
224#pragma omp parallel for if (!system::regtest_reduction) reduction(+:sm)
226 for (
int pmap_it = 0; pmap_it < static_cast<int>(ptile_ptrs.
size()); ++pmap_it)
228 const auto& tile = plev.at(grid_tile_ids[pmap_it]);
229 const auto np = tile.numParticles();
230 const auto& ptd = tile.getConstParticleTileData();
231 for (
int i = 0; i < np; ++i) {
280template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
285 return ReduceMax(pc, 0, pc.finestLevel(), std::forward<F>(f));
329template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
334 return ReduceMax(pc, lev, lev, std::forward<F>(f));
378template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
380ReduceMax (PC
const& pc,
int lev_min,
int lev_max,
F const& f)
384 constexpr value_type value_lowest = std::numeric_limits<value_type>::lowest();
385 value_type
r = value_lowest;
392 using ReduceTuple =
typename decltype(reduce_data)::Type;
394 for (
int lev = lev_min; lev <= lev_max; ++lev)
396 const auto& plev = pc.GetParticles(lev);
397 for (
const auto& kv : plev)
399 const auto& tile = plev.at(kv.first);
400 const auto np = tile.numParticles();
401 const auto& ptd = tile.getConstParticleTileData();
402 reduce_op.
eval(np, reduce_data,
409 ReduceTuple hv = reduce_data.
value(reduce_op);
410 r = amrex::get<0>(hv);
415 for (
int lev = lev_min; lev <= lev_max; ++lev)
417 const auto& plev = pc.GetParticles(lev);
420 for (
auto& kv : plev)
422 grid_tile_ids.push_back(kv.first);
423 ptile_ptrs.push_back(&(kv.second));
428#pragma omp parallel for if (!system::regtest_reduction) reduction(max:r)
430 for (
int pmap_it = 0; pmap_it < static_cast<int>(ptile_ptrs.
size()); ++pmap_it)
432 const auto& tile = plev.at(grid_tile_ids[pmap_it]);
433 const auto np = tile.numParticles();
434 const auto& ptd = tile.getConstParticleTileData();
435 for (
int i = 0; i < np; ++i) {
484template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
489 return ReduceMin(pc, 0, pc.finestLevel(), std::forward<F>(f));
532template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
537 return ReduceMin(pc, lev, lev, std::forward<F>(f));
581template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
583ReduceMin (PC
const& pc,
int lev_min,
int lev_max,
F const& f)
587 constexpr value_type value_max = std::numeric_limits<value_type>::max();
588 value_type
r = value_max;
595 using ReduceTuple =
typename decltype(reduce_data)::Type;
597 for (
int lev = lev_min; lev <= lev_max; ++lev)
599 const auto& plev = pc.GetParticles(lev);
600 for (
const auto& kv : plev)
602 const auto& tile = plev.at(kv.first);
603 const auto np = tile.numParticles();
604 const auto& ptd = tile.getConstParticleTileData();
605 reduce_op.
eval(np, reduce_data,
612 ReduceTuple hv = reduce_data.
value(reduce_op);
613 r = amrex::get<0>(hv);
618 for (
int lev = lev_min; lev <= lev_max; ++lev)
620 const auto& plev = pc.GetParticles(lev);
623 for (
auto& kv : plev)
625 grid_tile_ids.push_back(kv.first);
626 ptile_ptrs.push_back(&(kv.second));
631#pragma omp parallel for if (!system::regtest_reduction) reduction(min:r)
633 for (
int pmap_it = 0; pmap_it < static_cast<int>(ptile_ptrs.
size()); ++pmap_it)
635 const auto& tile = plev.at(grid_tile_ids[pmap_it]);
636 const auto np = tile.numParticles();
637 const auto& ptd = tile.getConstParticleTileData();
638 for (
int i = 0; i < np; ++i) {
687template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
734template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
782template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
793 using ReduceTuple =
typename decltype(reduce_data)::Type;
795 for (
int lev = lev_min; lev <= lev_max; ++lev)
797 const auto& plev = pc.GetParticles(lev);
798 for (
const auto& kv : plev)
800 const auto& tile = plev.at(kv.first);
801 const auto np = tile.numParticles();
802 const auto& ptd = tile.getConstParticleTileData();
803 reduce_op.
eval(np, reduce_data,
810 ReduceTuple hv = reduce_data.
value(reduce_op);
811 r = amrex::get<0>(hv);
816 for (
int lev = lev_min; lev <= lev_max; ++lev)
818 const auto& plev = pc.GetParticles(lev);
821 for (
auto& kv : plev)
823 grid_tile_ids.push_back(kv.first);
824 ptile_ptrs.push_back(&(kv.second));
829#pragma omp parallel for if (!system::regtest_reduction) reduction(&&:r)
831 for (
int pmap_it = 0; pmap_it < static_cast<int>(ptile_ptrs.
size()); ++pmap_it)
833 const auto& tile = plev.at(grid_tile_ids[pmap_it]);
834 const auto np = tile.numParticles();
835 const auto& ptd = tile.getConstParticleTileData();
836 for (
int i = 0; i < np; ++i) {
885template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
932template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
980template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
991 using ReduceTuple =
typename decltype(reduce_data)::Type;
993 for (
int lev = lev_min; lev <= lev_max; ++lev)
995 const auto& plev = pc.GetParticles(lev);
996 for (
const auto& kv : plev)
998 const auto& tile = plev.at(kv.first);
999 const auto np = tile.numParticles();
1000 const auto& ptd = tile.getConstParticleTileData();
1001 reduce_op.
eval(np, reduce_data,
1009 ReduceTuple hv = reduce_data.
value(reduce_op);
1010 r = amrex::get<0>(hv);
1015 for (
int lev = lev_min; lev <= lev_max; ++lev)
1017 const auto& plev = pc.GetParticles(lev);
1020 for (
auto& kv : plev)
1022 grid_tile_ids.push_back(kv.first);
1023 ptile_ptrs.push_back(&(kv.second));
1028#pragma omp parallel for if (!system::regtest_reduction) reduction(||:r)
1030 for (
int pmap_it = 0; pmap_it < static_cast<int>(ptile_ptrs.
size()); ++pmap_it)
1032 const auto& tile = plev.at(grid_tile_ids[pmap_it]);
1033 const auto np = tile.numParticles();
1034 const auto& ptd = tile.getConstParticleTileData();
1035 for (
int i = 0; i < np; ++i) {
1107template <
class RD,
class PC,
class F,
class ReduceOps,
1108 std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
1112 return ParticleReduce<RD>(pc, 0, pc.finestLevel(), std::forward<F>(f), reduce_ops);
1178template <
class RD,
class PC,
class F,
class ReduceOps,
1179 std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
1183 return ParticleReduce<RD>(pc, lev, lev, std::forward<F>(f), reduce_ops);
1250template <
class RD,
class PC,
class F,
class ReduceOps,
1251 std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
1255 RD reduce_data(reduce_ops);
1256 for (
int lev = lev_min; lev <= lev_max; ++lev) {
1257 const auto& plev = pc.GetParticles(lev);
1260 for (
auto& kv : plev)
1262 grid_tile_ids.push_back(kv.first);
1263 ptile_ptrs.push_back(&(kv.second));
1267#if !defined(AMREX_USE_GPU) && defined(AMREX_USE_OMP)
1268#pragma omp parallel for
1270 for (
int pmap_it = 0; pmap_it < static_cast<int>(ptile_ptrs.
size()); ++pmap_it)
1272 const auto& tile = plev.at(grid_tile_ids[pmap_it]);
1273 const auto np = tile.numParticles();
1274 const auto& ptd = tile.getConstParticleTileData();
1275 reduce_ops.
eval(np, reduce_data,
1282 return reduce_data.value(reduce_ops);
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:119
#define AMREX_GPU_DEVICE
Definition AMReX_GpuQualifiers.H:18
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
Definition AMReX_Reduce.H:249
Type value()
Definition AMReX_Reduce.H:281
Definition AMReX_Reduce.H:364
std::enable_if_t< IsFabArray< MF >::value > eval(MF const &mf, IntVect const &nghost, D &reduce_data, F &&f)
Definition AMReX_Reduce.H:433
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:28
Long size() const noexcept
Definition AMReX_Vector.H:53
bool inLaunchRegion() noexcept
Definition AMReX_GpuControl.H:92
__host__ __device__ auto call_f(F const &f, const PTDType< T_ParticleType, NAR, NAI > &p, const int i, Array4< T > const &fabarr, GpuArray< Real, 3 > const &plo, GpuArray< Real, 3 > const &dxi) noexcept
Definition AMReX_ParticleMesh.H:16
Definition AMReX_Amr.cpp:49
FAB::value_type ReduceMax(FabArray< FAB > const &fa, int nghost, F &&f)
Definition AMReX_FabArrayUtility.H:531
bool ReduceLogicalAnd(FabArray< FAB > const &fa, int nghost, F &&f)
Definition AMReX_FabArrayUtility.H:758
bool ReduceLogicalOr(FabArray< FAB > const &fa, int nghost, F &&f)
Definition AMReX_FabArrayUtility.H:905
RD::Type ParticleReduce(PC const &pc, F &&f, ReduceOps &reduce_ops)
A general reduction method for the particles in a ParticleContainer that can run on either CPUs or GP...
Definition AMReX_ParticleReduce.H:1110
FAB::value_type ReduceMin(FabArray< FAB > const &fa, int nghost, F &&f)
Definition AMReX_FabArrayUtility.H:305
FAB::value_type ReduceSum(FabArray< FAB > const &fa, int nghost, F &&f)
Definition AMReX_FabArrayUtility.H:16
Definition AMReX_ParticleTile.H:513
Test if a given type T is callable with arguments of type Args...
Definition AMReX_TypeTraits.H:209