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));
77template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
82 return ReduceSum(pc, 0, pc.finestLevel(), std::forward<F>(f));
125template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
130 return ReduceSum(pc, lev, lev, std::forward<F>(f));
174template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
176ReduceSum (PC
const& pc,
int lev_min,
int lev_max,
F const& f)
179 using value_type =
decltype(
particle_detail::call_f(f,
typename PC::ParticleTileType::ConstParticleTileDataType(),
int()));
187 using ReduceTuple =
typename decltype(reduce_data)::Type;
189 for (
int lev = lev_min; lev <= lev_max; ++lev)
191 const auto& plev = pc.GetParticles(lev);
192 for (
const auto& kv : plev)
194 const auto& tile = plev.at(kv.first);
195 const auto np = tile.numParticles();
196 const auto& ptd = tile.getConstParticleTileData();
197 reduce_op.
eval(np, reduce_data,
204 ReduceTuple hv = reduce_data.
value(reduce_op);
205 sm = amrex::get<0>(hv);
210 for (
int lev = lev_min; lev <= lev_max; ++lev)
212 const auto& plev = pc.GetParticles(lev);
215 for (
auto& kv : plev)
217 grid_tile_ids.push_back(kv.first);
218 ptile_ptrs.push_back(&(kv.second));
221#pragma omp parallel for if (!system::regtest_reduction) reduction(+:sm)
223 for (
int pmap_it = 0; pmap_it < static_cast<int>(ptile_ptrs.
size()); ++pmap_it)
225 const auto& tile = plev.at(grid_tile_ids[pmap_it]);
226 const auto np = tile.numParticles();
227 const auto& ptd = tile.getConstParticleTileData();
228 for (
int i = 0; i < np; ++i) {
277template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
282 return ReduceMax(pc, 0, pc.finestLevel(), std::forward<F>(f));
325template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
330 return ReduceMax(pc, lev, lev, std::forward<F>(f));
374template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
376ReduceMax (PC
const& pc,
int lev_min,
int lev_max,
F const& f)
379 using value_type =
decltype(
particle_detail::call_f(f,
typename PC::ParticleTileType::ConstParticleTileDataType(),
int()));
380 constexpr value_type value_lowest = std::numeric_limits<value_type>::lowest();
381 value_type
r = value_lowest;
388 using ReduceTuple =
typename decltype(reduce_data)::Type;
390 for (
int lev = lev_min; lev <= lev_max; ++lev)
392 const auto& plev = pc.GetParticles(lev);
393 for (
const auto& kv : plev)
395 const auto& tile = plev.at(kv.first);
396 const auto np = tile.numParticles();
397 const auto& ptd = tile.getConstParticleTileData();
398 reduce_op.
eval(np, reduce_data,
405 ReduceTuple hv = reduce_data.
value(reduce_op);
406 r = amrex::get<0>(hv);
411 for (
int lev = lev_min; lev <= lev_max; ++lev)
413 const auto& plev = pc.GetParticles(lev);
416 for (
auto& kv : plev)
418 grid_tile_ids.push_back(kv.first);
419 ptile_ptrs.push_back(&(kv.second));
422#pragma omp parallel for if (!system::regtest_reduction) reduction(max:r)
424 for (
int pmap_it = 0; pmap_it < static_cast<int>(ptile_ptrs.
size()); ++pmap_it)
426 const auto& tile = plev.at(grid_tile_ids[pmap_it]);
427 const auto np = tile.numParticles();
428 const auto& ptd = tile.getConstParticleTileData();
429 for (
int i = 0; i < np; ++i) {
478template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
483 return ReduceMin(pc, 0, pc.finestLevel(), std::forward<F>(f));
526template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
531 return ReduceMin(pc, lev, lev, std::forward<F>(f));
575template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
577ReduceMin (PC
const& pc,
int lev_min,
int lev_max,
F const& f)
580 using value_type =
decltype(
particle_detail::call_f(f,
typename PC::ParticleTileType::ConstParticleTileDataType(),
int()));
581 constexpr value_type value_max = std::numeric_limits<value_type>::max();
582 value_type
r = value_max;
589 using ReduceTuple =
typename decltype(reduce_data)::Type;
591 for (
int lev = lev_min; lev <= lev_max; ++lev)
593 const auto& plev = pc.GetParticles(lev);
594 for (
const auto& kv : plev)
596 const auto& tile = plev.at(kv.first);
597 const auto np = tile.numParticles();
598 const auto& ptd = tile.getConstParticleTileData();
599 reduce_op.
eval(np, reduce_data,
606 ReduceTuple hv = reduce_data.
value(reduce_op);
607 r = amrex::get<0>(hv);
612 for (
int lev = lev_min; lev <= lev_max; ++lev)
614 const auto& plev = pc.GetParticles(lev);
617 for (
auto& kv : plev)
619 grid_tile_ids.push_back(kv.first);
620 ptile_ptrs.push_back(&(kv.second));
623#pragma omp parallel for if (!system::regtest_reduction) reduction(min:r)
625 for (
int pmap_it = 0; pmap_it < static_cast<int>(ptile_ptrs.
size()); ++pmap_it)
627 const auto& tile = plev.at(grid_tile_ids[pmap_it]);
628 const auto np = tile.numParticles();
629 const auto& ptd = tile.getConstParticleTileData();
630 for (
int i = 0; i < np; ++i) {
679template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
726template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
774template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
785 using ReduceTuple =
typename decltype(reduce_data)::Type;
787 for (
int lev = lev_min; lev <= lev_max; ++lev)
789 const auto& plev = pc.GetParticles(lev);
790 for (
const auto& kv : plev)
792 const auto& tile = plev.at(kv.first);
793 const auto np = tile.numParticles();
794 const auto& ptd = tile.getConstParticleTileData();
795 reduce_op.
eval(np, reduce_data,
802 ReduceTuple hv = reduce_data.
value(reduce_op);
803 r = amrex::get<0>(hv);
808 for (
int lev = lev_min; lev <= lev_max; ++lev)
810 const auto& plev = pc.GetParticles(lev);
813 for (
auto& kv : plev)
815 grid_tile_ids.push_back(kv.first);
816 ptile_ptrs.push_back(&(kv.second));
819#pragma omp parallel for if (!system::regtest_reduction) reduction(&&:r)
821 for (
int pmap_it = 0; pmap_it < static_cast<int>(ptile_ptrs.
size()); ++pmap_it)
823 const auto& tile = plev.at(grid_tile_ids[pmap_it]);
824 const auto np = tile.numParticles();
825 const auto& ptd = tile.getConstParticleTileData();
826 for (
int i = 0; i < np; ++i) {
875template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
922template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
970template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
981 using ReduceTuple =
typename decltype(reduce_data)::Type;
983 for (
int lev = lev_min; lev <= lev_max; ++lev)
985 const auto& plev = pc.GetParticles(lev);
986 for (
const auto& kv : plev)
988 const auto& tile = plev.at(kv.first);
989 const auto np = tile.numParticles();
990 const auto& ptd = tile.getConstParticleTileData();
991 reduce_op.
eval(np, reduce_data,
999 ReduceTuple hv = reduce_data.
value(reduce_op);
1000 r = amrex::get<0>(hv);
1005 for (
int lev = lev_min; lev <= lev_max; ++lev)
1007 const auto& plev = pc.GetParticles(lev);
1010 for (
auto& kv : plev)
1012 grid_tile_ids.push_back(kv.first);
1013 ptile_ptrs.push_back(&(kv.second));
1016#pragma omp parallel for if (!system::regtest_reduction) reduction(||:r)
1018 for (
int pmap_it = 0; pmap_it < static_cast<int>(ptile_ptrs.
size()); ++pmap_it)
1020 const auto& tile = plev.at(grid_tile_ids[pmap_it]);
1021 const auto np = tile.numParticles();
1022 const auto& ptd = tile.getConstParticleTileData();
1023 for (
int i = 0; i < np; ++i) {
1094template <
class RD,
class PC,
class F,
class ReduceOps,
1095 std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
1099 return ParticleReduce<RD>(pc, 0, pc.finestLevel(), std::forward<F>(f), reduce_ops);
1164template <
class RD,
class PC,
class F,
class ReduceOps,
1165 std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
1169 return ParticleReduce<RD>(pc, lev, lev, std::forward<F>(f), reduce_ops);
1235template <
class RD,
class PC,
class F,
class ReduceOps,
1236 std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
1240 RD reduce_data(reduce_ops);
1241 for (
int lev = lev_min; lev <= lev_max; ++lev) {
1242 const auto& plev = pc.GetParticles(lev);
1245 for (
auto& kv : plev)
1247 grid_tile_ids.push_back(kv.first);
1248 ptile_ptrs.push_back(&(kv.second));
1250#if !defined(AMREX_USE_GPU) && defined(AMREX_USE_OMP)
1251#pragma omp parallel for
1253 for (
int pmap_it = 0; pmap_it < static_cast<int>(ptile_ptrs.
size()); ++pmap_it)
1255 const auto& tile = plev.at(grid_tile_ids[pmap_it]);
1256 const auto np = tile.numParticles();
1257 const auto& ptd = tile.getConstParticleTileData();
1258 reduce_ops.
eval(np, reduce_data,
1265 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:441
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:27
Long size() const noexcept
Definition AMReX_Vector.H:50
bool inLaunchRegion() noexcept
Definition AMReX_GpuControl.H:86
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE auto call_f(F const &f, const PTDType< T_ParticleType, NAR, NAI > &p, const int i, Array4< T > const &fabarr, GpuArray< Real, AMREX_SPACEDIM > const &plo, GpuArray< Real, AMREX_SPACEDIM > 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:1097
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:501
Test if a given type T is callable with arguments of type Args...
Definition AMReX_TypeTraits.H:201