4 #ifdef ERF_USE_PARTICLES
7 #include <AMReX_Particles.H>
10 struct ERFParticlesIntIdxAoS
18 struct ERFParticlesRealIdxAoS
25 struct ERFParticlesIntIdxSoA
32 struct ERFParticlesRealIdxSoA
44 namespace ERFParticleInitializations
47 const std::string init_box_uniform =
"box";
50 namespace ERFParticleNames
52 const std::string tracers =
"tracer_particles";
55 struct ERFParticlesAssignor
59 amrex::IntVect operator() (
P const&
p,
60 amrex::GpuArray<amrex::Real,AMREX_SPACEDIM>
const& plo,
61 amrex::GpuArray<amrex::Real,AMREX_SPACEDIM>
const& dxi,
62 const amrex::Box& domain )
const noexcept
65 AMREX_D_DECL(
int(amrex::Math::floor((
p.pos(0)-plo[0])*dxi[0])),
66 int(amrex::Math::floor((
p.pos(1)-plo[1])*dxi[1])),
67 p.idata(ERFParticlesIntIdxAoS::k) ) );
68 iv[0] += domain.smallEnd()[0];
69 iv[1] += domain.smallEnd()[1];
70 iv[2] = amrex::max(domain.smallEnd()[2],
71 amrex::min(iv[2], domain.bigEnd()[2]));
77 struct GetParticleBinERF
79 amrex::GpuArray<amrex::Real,AMREX_SPACEDIM> plo;
80 amrex::GpuArray<amrex::Real,AMREX_SPACEDIM> dxi;
82 amrex::IntVect bin_size;
87 unsigned int operator() (
const P&
p)
const noexcept
90 auto iv = ERFParticlesAssignor()(
p, plo, dxi, domain);
91 auto tid = amrex::getTileIndex(iv, box,
true, bin_size, tbx);
92 return static_cast<unsigned int>(tid);
97 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
98 void update_location_idata (
P& a_p,
99 amrex::GpuArray<amrex::Real,AMREX_SPACEDIM>
const& a_plo,
100 amrex::GpuArray<amrex::Real,AMREX_SPACEDIM>
const& a_dxi,
101 const amrex::Array4<amrex::Real const>& a_height_arr )
105 int ix = int(amrex::Math::floor((a_p.pos(0)-a_plo[0])*a_dxi[0]));
106 int iy = int(amrex::Math::floor((a_p.pos(1)-a_plo[1])*a_dxi[1]));
113 if (ix < a_height_arr.begin[0] || ix+1 >= a_height_arr.end[0] ||
114 iy < a_height_arr.begin[1] || iy+1 >= a_height_arr.end[1]) {
123 int klo = a_height_arr.begin[2];
124 int khi = a_height_arr.end[2] - 2;
125 if (
khi < klo) {
return; }
126 int kcur = a_p.idata(ERFParticlesIntIdxAoS::k);
127 if (kcur < klo || kcur >
khi) {
128 a_p.idata(ERFParticlesIntIdxAoS::k) = amrex::max(klo, amrex::min(kcur,
khi));
132 int iz = a_p.idata(ERFParticlesIntIdxAoS::k);
134 if (iz < klo || iz >
khi) {
138 auto zlo = a_height_arr(ix ,iy ,iz ) * (
one-lx) * (
one-ly) +
139 a_height_arr(ix+1,iy ,iz ) * lx * (
one-ly) +
140 a_height_arr(ix ,iy+1,iz ) * (
one-lx) * ly +
141 a_height_arr(ix+1,iy+1,iz ) * lx * ly;
142 auto zhi = a_height_arr(ix ,iy ,iz+1) * (
one-lx) * (
one-ly) +
143 a_height_arr(ix+1,iy ,iz+1) * lx * (
one-ly) +
144 a_height_arr(ix ,iy+1,iz+1) * (
one-lx) * ly +
145 a_height_arr(ix+1,iy+1,iz+1) * lx * ly;
147 if (a_p.pos(2) > zhi) {
148 a_p.idata(ERFParticlesIntIdxAoS::k) += 1;
149 }
else if (a_p.pos(2) <= zlo) {
150 a_p.idata(ERFParticlesIntIdxAoS::k) -= 1;
174 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
183 if (zlevels ==
nullptr || nz_lev0 <= 0) {
185 int k =
static_cast<int>(amrex::Math::floor((z - plo_z) * dxi_z));
186 return amrex::max(0, amrex::min(k, k_max));
193 int k =
static_cast<int>(amrex::Math::floor((z - plo_z) * dxi_z));
194 k = amrex::max(0, amrex::min(k, k_max));
198 auto fine_z = [=] AMREX_GPU_HOST_DEVICE (
int k_f) ->
amrex::Real {
199 int kc = k_f / ref_ratio;
200 int sub = k_f % ref_ratio;
202 kc = amrex::max(0, amrex::min(kc, nz_lev0));
203 if (kc >= nz_lev0) {
return zlevels[nz_lev0]; }
206 * (zlevels[kc+1] - zlevels[kc])
210 for (
int iter = 0; iter <= k_max; iter++) {
213 if (z >= z_hi && k < k_max) {
215 }
else if (z < z_lo && k > 0) {
224 class ERFPC :
public amrex::ParticleContainer< ERFParticlesRealIdxAoS::ncomps,
225 ERFParticlesIntIdxAoS::ncomps,
226 ERFParticlesRealIdxSoA::ncomps,
227 ERFParticlesIntIdxSoA::ncomps,
228 amrex::DefaultAllocator,
229 ERFParticlesAssignor >
234 ERFPC ( amrex::ParGDBBase* a_gdb,
235 const std::string& a_name =
"particles" )
236 :
amrex::ParticleContainer< ERFParticlesRealIdxAoS::ncomps,
237 ERFParticlesIntIdxAoS::ncomps,
238 ERFParticlesRealIdxSoA::ncomps,
239 ERFParticlesIntIdxSoA::ncomps,
240 amrex::DefaultAllocator,
241 ERFParticlesAssignor> (a_gdb)
243 BL_PROFILE(
"ERFPCPC::ERFPC()");
249 ERFPC (
const amrex::Geometry& a_geom,
250 const amrex::DistributionMapping& a_dmap,
251 const amrex::BoxArray& a_ba,
252 const std::string& a_name =
"particles" )
253 :
amrex::ParticleContainer< ERFParticlesRealIdxAoS::ncomps,
254 ERFParticlesIntIdxAoS::ncomps,
255 ERFParticlesRealIdxSoA::ncomps,
256 ERFParticlesIntIdxSoA::ncomps,
257 amrex::DefaultAllocator,
258 ERFParticlesAssignor> ( a_geom, a_dmap, a_ba )
260 BL_PROFILE(
"ERFPCPC::ERFPC()");
266 virtual void InitializeParticles (
const amrex::Real time,
const std::unique_ptr<amrex::MultiFab>& a_ptr =
nullptr);
269 virtual void EvolveParticles (
int,
271 amrex::Vector<amrex::Vector<amrex::MultiFab>>&,
272 const amrex::Vector<std::unique_ptr<amrex::MultiFab>>& );
275 virtual amrex::Vector<std::string> varNames ()
const
277 BL_PROFILE(
"ERFPCPC::varNames()");
278 return {AMREX_D_DECL(
"xvel",
"yvel",
"zvel"),
"mass",
"temperature"};
282 virtual amrex::Vector<std::string> meshPlotVarNames ()
const
284 BL_PROFILE(
"ERFPCPC::varNames()");
285 return {
"mass_density"};
289 virtual void AdvectWithFlow ( amrex::MultiFab*,
292 const std::unique_ptr<amrex::MultiFab>& );
295 virtual void AdvectWithGravity (
int,
297 const std::unique_ptr<amrex::MultiFab>& );
300 virtual void ComputeTemperature (
const amrex::MultiFab&,
303 const std::unique_ptr<amrex::MultiFab>& );
306 virtual void massDensity ( amrex::MultiFab&,
const int&,
const int& a_comp = 0)
const;
309 virtual void computeMeshVar(
const std::string& a_var_name,
310 amrex::MultiFab& a_mf,
311 const int a_lev)
const
313 if (a_var_name ==
"mass_density") {
314 massDensity( a_mf, a_lev );
321 inline void setAdvectWithFlow (
bool a_flag)
323 BL_PROFILE(
"ERFPCPC::setAdvectWithFlow()");
324 m_advect_w_flow = a_flag;
327 inline void setAdvectWithGravity (
bool a_flag)
329 BL_PROFILE(
"ERFPCPC::setAdvectWithGravity()");
330 m_advect_w_gravity = a_flag;
337 void initializeParticlesUniformDistributionInBox (
const std::unique_ptr<amrex::MultiFab>& a_ptr,
338 const amrex::RealBox& particle_box);
341 void FixKIndexAMR (
const amrex::Vector<std::unique_ptr<amrex::MultiFab>>& a_z_phys_nd);
344 void ExtractAndRouteOORParticles (
int a_lev,
345 const amrex::Vector<std::unique_ptr<amrex::MultiFab>>& a_z_phys_nd );
348 void CountParticlesPerLevelAndHalo (
int a_finest_level );
352 bool m_advect_w_flow;
353 bool m_advect_w_gravity;
355 amrex::RealBox m_particle_box;
359 std::string m_initialization_type;
364 bool m_initialized =
false;
366 bool m_stable_redistribute;
368 amrex::Gpu::DeviceVector<amrex::Real> m_zlevels_d;
371 virtual void readInputs ();
375 bool place_randomly_in_cells;
constexpr amrex::Real one
Definition: ERF_Constants.H:7
const int khi
Definition: ERF_InitCustomPert_Bubble.H:21
Real * p
Definition: ERF_InitCustomPert_SquallLine.H:61
amrex::Real Real
Definition: ERF_ShocInterface.H:19
@ P
Definition: ERF_IndexDefines.H:148
Definition: ERF_ConsoleIO.cpp:12