1 #ifndef AMREX_PARTICLEREDUCE_H_
2 #define AMREX_PARTICLEREDUCE_H_
3 #include <AMReX_Config.H>
15 #include <type_traits>
21 template <
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));
77 template <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));
125 template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
130 return ReduceSum(pc, lev, lev, std::forward<F>(
f));
174 template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
176 ReduceSum (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) {
277 template <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));
325 template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
330 return ReduceMax(pc, lev, lev, std::forward<F>(
f));
374 template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
376 ReduceMax (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) {
478 template <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));
526 template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
531 return ReduceMin(pc, lev, lev, std::forward<F>(
f));
575 template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
577 ReduceMin (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()));
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) {
679 template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
726 template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
774 template <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) {
875 template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
922 template <class PC, class F, std::enable_if_t<IsParticleContainer<PC>::value,
int> foo = 0>
970 template <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));
1015 #ifdef AMREX_USE_OMP
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) {
1094 template <
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);
1164 template <
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);
1235 template <
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
static int f(amrex::Real t, N_Vector y_data, N_Vector y_rhs, void *user_data)
Definition: AMReX_SundialsIntegrator.H:44
@ min
Definition: AMReX_ParallelReduce.H:18
@ max
Definition: AMReX_ParallelReduce.H:17
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_WriteBinaryParticleData.H:19
Definition: AMReX_ParticleTile.H:495
Test if a given type T is callable with arguments of type Args...
Definition: AMReX_TypeTraits.H:201