Block-Structured AMR Software Framework
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
AMReX_ParticleMesh.H
Go to the documentation of this file.
1#ifndef AMREX_PARTICLEMESH_H_
2#define AMREX_PARTICLEMESH_H_
3#include <AMReX_Config.H>
4
5#include <AMReX_TypeTraits.H>
6#include <AMReX_MultiFab.H>
8#include <type_traits>
9
10namespace amrex {
11
12namespace particle_detail {
13
14template <typename F, typename T, typename T_ParticleType, template<class, int, int> class PTDType, int NAR, int NAI>
16auto call_f (F const& f,
17 const PTDType<T_ParticleType, NAR, NAI>& p,
18 const int i, Array4<T> const& fabarr,
20 GpuArray<Real,AMREX_SPACEDIM> const& dxi) noexcept
21{
22 using PTDTypeT = std::remove_const_t<std::remove_reference_t<decltype(p)>>;
23 if constexpr ( ! T_ParticleType::is_soa_particle &&
24 IsCallable<F, typename PTDTypeT::ParticleRefType, decltype(fabarr), decltype(plo), decltype(dxi)>::value) {
25 return f(p.m_aos[i], fabarr, plo, dxi);
26 } else if constexpr ( ! T_ParticleType::is_soa_particle &&
27 IsCallable<F, typename PTDTypeT::ParticleRefType, decltype(fabarr)>::value) {
28 return f(p.m_aos[i], fabarr);
29 } else if constexpr (IsCallable<F, decltype(p.getSuperParticle(i)), decltype(fabarr), decltype(plo), decltype(dxi)>::value) {
30 return f(p.getSuperParticle(i), fabarr, plo, dxi);
31 } else if constexpr (IsCallable<F, decltype(p.getSuperParticle(i)), decltype(fabarr)>::value) {
32 return f(p.getSuperParticle(i), fabarr);
33 } else if constexpr (IsCallable<F, decltype(p), int, decltype(fabarr), decltype(plo), decltype(dxi)>::value) {
34 return f(p, i, fabarr, plo, dxi);
35 } else {
36 return f(p, i, fabarr);
37 }
38}
39}
40
41template <class PC, class MF, class F, std::enable_if_t<IsParticleContainer<PC>::value, int> foo = 0>
42void
43ParticleToMesh (PC const& pc, MF& mf, int lev, F const& f, bool zero_out_input=true)
44{
45 BL_PROFILE("amrex::ParticleToMesh");
46
47 if (zero_out_input) { mf.setVal(0.0); }
48
49 MF* mf_pointer;
50
51 if (pc.OnSameGrids(lev, mf) && zero_out_input)
52 {
53 mf_pointer = &mf;
54 } else {
55 mf_pointer = new MF(pc.ParticleBoxArray(lev),
56 pc.ParticleDistributionMap(lev),
57 mf.nComp(), mf.nGrowVect());
58 mf_pointer->setVal(0.0);
59 }
60
61 const auto plo = pc.Geom(lev).ProbLoArray();
62 const auto dxi = pc.Geom(lev).InvCellSizeArray();
63
64 using ParIter = typename PC::ParConstIterType;
65#ifdef AMREX_USE_GPU
67 {
68 for(ParIter pti(pc, lev); pti.isValid(); ++pti)
69 {
70 const auto& tile = pti.GetParticleTile();
71 const auto np = tile.numParticles();
72 const auto& ptd = tile.getConstParticleTileData();
73
74 auto& fab = (*mf_pointer)[pti];
75 auto fabarr = fab.array();
76
77 AMREX_FOR_1D( np, i,
78 {
79 particle_detail::call_f(f, ptd, i, fabarr, plo, dxi);
80 });
81 }
82 }
83 else
84#endif
85 {
86#ifdef AMREX_USE_OMP
87#pragma omp parallel if (Gpu::notInLaunchRegion())
88#endif
89 {
90 typename MF::FABType::value_type local_fab;
91 for(ParIter pti(pc, lev); pti.isValid(); ++pti)
92 {
93 const auto& tile = pti.GetParticleTile();
94 const auto np = tile.numParticles();
95 const auto& ptd = tile.getConstParticleTileData();
96
97 auto& fab = (*mf_pointer)[pti];
98
99 Box tile_box = pti.tilebox();
100 tile_box.grow(mf_pointer->nGrowVect());
101 local_fab.resize(tile_box,mf_pointer->nComp());
102 local_fab.template setVal<RunOn::Host>(0.0);
103 auto fabarr = local_fab.array();
104
105 AMREX_FOR_1D( np, i,
106 {
107 particle_detail::call_f(f, ptd, i, fabarr, plo, dxi);
108 });
109
110 fab.template atomicAdd<RunOn::Host>(local_fab, tile_box, tile_box,
111 0, 0, mf_pointer->nComp());
112 }
113 }
114 }
115
116 if (mf_pointer != &mf)
117 {
118 mf.ParallelAdd(*mf_pointer, 0, 0, mf_pointer->nComp(),
119 mf_pointer->nGrowVect(), IntVect(0), pc.Geom(lev).periodicity());
120 delete mf_pointer;
121 } else {
122 mf_pointer->SumBoundary(pc.Geom(lev).periodicity());
123 }
124}
125
126template <class PC, class MF, class F, std::enable_if_t<IsParticleContainer<PC>::value, int> foo = 0>
127void
128MeshToParticle (PC& pc, MF const& mf, int lev, F const& f)
129{
130 BL_PROFILE("amrex::MeshToParticle");
131
132 MF* mf_pointer = pc.OnSameGrids(lev, mf) ?
133 const_cast<MF*>(&mf) : new MF(pc.ParticleBoxArray(lev),
134 pc.ParticleDistributionMap(lev),
135 mf.nComp(), mf.nGrowVect());
136
137 if (mf_pointer != &mf) {mf_pointer->ParallelCopy(mf,0,0,mf.nComp(),mf.nGrowVect(),mf.nGrowVect()); }
138
139 const auto plo = pc.Geom(lev).ProbLoArray();
140 const auto dxi = pc.Geom(lev).InvCellSizeArray();
141
142 using ParIter = typename PC::ParIterType;
143#ifdef AMREX_USE_OMP
144#pragma omp parallel if (Gpu::notInLaunchRegion())
145#endif
146 for(ParIter pti(pc, lev); pti.isValid(); ++pti)
147 {
148 auto& tile = pti.GetParticleTile();
149 const auto np = tile.numParticles();
150 const auto& ptd = tile.getParticleTileData();
151
152 const auto& fab = (*mf_pointer)[pti];
153 auto fabarr = fab.array();
154
155 AMREX_FOR_1D( np, i,
156 {
157 particle_detail::call_f(f, ptd, i, fabarr, plo, dxi);
158 });
159 }
160
161 if (mf_pointer != &mf) { delete mf_pointer; }
162}
163
164}
165#endif
#define BL_PROFILE(a)
Definition AMReX_BLProfiler.H:551
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:119
#define AMREX_FOR_1D(...)
Definition AMReX_GpuLaunchMacrosC.nolint.H:97
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE BoxND< new_dim > resize() const noexcept
Returns a new BoxND of size new_dim by either shrinking or expanding this BoxND.
Definition AMReX_Box.H:831
AMREX_GPU_HOST_DEVICE BoxND & grow(int i) noexcept
Definition AMReX_Box.H:627
bool isValid() const noexcept
Is the iterator valid i.e. is it associated with a FAB?
Definition AMReX_MFIter.H:141
ParticleTileRef GetParticleTile() const
Definition AMReX_ParIter.H:84
Definition AMReX_ParIter.H:113
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
void MeshToParticle(PC &pc, MF const &mf, int lev, F const &f)
Definition AMReX_ParticleMesh.H:128
void ParticleToMesh(PC const &pc, const Vector< MultiFab * > &mf, int lev_min, int lev_max, F &&f, bool zero_out_input=true, bool vol_weight=true)
Definition AMReX_AmrParticles.H:156
Definition AMReX_Array4.H:61
Definition AMReX_Array.H:34
Test if a given type T is callable with arguments of type Args...
Definition AMReX_TypeTraits.H:201