ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERFPC.H
Go to the documentation of this file.
1 #ifndef ERF_PC_H_
2 #define ERF_PC_H_
3 
4 #ifdef ERF_USE_PARTICLES
5 
6 #include <string>
7 #include <AMReX_Particles.H>
8 #include <ERF_Constants.H>
9 
10 struct ERFParticlesIntIdx
11 {
12  enum {
13  ncomps = 0
14  };
15 };
16 
17 struct ERFParticlesRealIdx
18 {
19  enum {
20  vx = 0,
21  vy,
22  vz,
23  mass,
24  temperature,
25  ncomps
26  };
27 };
28 
29 namespace ERFParticleInitializations
30 {
31  /* list of particle initializations */
32  const std::string init_box_uniform = "box";
33 }
34 
35 namespace ERFParticleNames
36 {
37  const std::string tracers = "tracer_particles";
38 }
39 
40 class ERFPC : public amrex::ParticleContainer< 0, // AoS real attributes
41  0, // AoS integer attributes
42  ERFParticlesRealIdx::ncomps, // SoA real attributes
43  ERFParticlesIntIdx::ncomps, // SoA integer attributes
44  amrex::DefaultAllocator >
45 {
46  public:
47 
48  /*! Constructor */
49  ERFPC ( amrex::ParGDBBase* a_gdb,
50  const std::string& a_name = "particles" )
51  : amrex::ParticleContainer< 0, // AoS real attributes
52  0, // AoS integer attributes
53  ERFParticlesRealIdx::ncomps, // SoA real attributes
54  ERFParticlesIntIdx::ncomps, // SoA integer attributes
55  amrex::DefaultAllocator> (a_gdb)
56  {
57  BL_PROFILE("ERFPCPC::ERFPC()");
58  m_name = a_name;
59  readInputs();
60  }
61 
62  /*! Constructor */
63  ERFPC ( const amrex::Geometry& a_geom,
64  const amrex::DistributionMapping& a_dmap,
65  const amrex::BoxArray& a_ba,
66  const std::string& a_name = "particles" )
67  : amrex::ParticleContainer< 0, // AoS real attributes
68  0, // AoS integer attributes
69  ERFParticlesRealIdx::ncomps, // SoA real attributes
70  ERFParticlesIntIdx::ncomps, // SoA integer attributes
71  amrex::DefaultAllocator> ( a_geom, a_dmap, a_ba )
72  {
73  BL_PROFILE("ERFPCPC::ERFPC()");
74  m_name = a_name;
75  readInputs();
76  }
77 
78  /*! Initialize particles in domain */
79  virtual void InitializeParticles (const amrex::Real time, const std::unique_ptr<amrex::MultiFab>& a_ptr = nullptr);
80 
81  /*! Evolve particles for one time step */
82  virtual void EvolveParticles ( int,
84  amrex::Vector<amrex::Vector<amrex::MultiFab>>&,
85  const amrex::Vector<std::unique_ptr<amrex::MultiFab>>& );
86 
87  /*! Get real-type particle attribute names */
88  virtual amrex::Vector<std::string> varNames () const
89  {
90  BL_PROFILE("ERFPCPC::varNames()");
91  return {AMREX_D_DECL("xvel","yvel","zvel"),"mass","temperature"};
92  }
93 
94  /*! Get real-type particle attribute names */
95  virtual amrex::Vector<std::string> meshPlotVarNames () const
96  {
97  BL_PROFILE("ERFPCPC::varNames()");
98  return {"mass_density"};
99  }
100 
101  /*! Uses midpoint method to advance particles using flow velocity. */
102  virtual void AdvectWithFlow ( amrex::MultiFab*,
103  int,
104  amrex::Real,
105  const std::unique_ptr<amrex::MultiFab>& );
106 
107  /*! Uses midpoint method to advance particles falling under gravity. */
108  virtual void AdvectWithGravity ( int,
109  amrex::Real,
110  const std::unique_ptr<amrex::MultiFab>& );
111 
112  /*! Interpolates flow temperature to particles */
113  virtual void ComputeTemperature ( const amrex::MultiFab&,
114  int,
115  amrex::Real,
116  const std::unique_ptr<amrex::MultiFab>& );
117 
118  /*! Compute mass density */
119  virtual void massDensity ( amrex::MultiFab&,
120  const amrex::MultiFab& a_z_phys_nd,
121  const int&, const int& a_comp = 0) const;
122 
123  /*! Compute mesh variable from particles */
124  virtual void computeMeshVar( const std::string& a_var_name,
125  amrex::MultiFab& a_mf,
126  const amrex::MultiFab& a_z_phys_nd,
127  const int a_lev) const
128  {
129  if (a_var_name == "mass_density") {
130  massDensity( a_mf, a_z_phys_nd, a_lev );
131  } else {
132  a_mf.setVal(0.0);
133  }
134  }
135 
136  /*! Specify if particles should advect with flow */
137  inline void setAdvectWithFlow (bool a_flag)
138  {
139  BL_PROFILE("ERFPCPC::setAdvectWithFlow()");
140  m_advect_w_flow = a_flag;
141  }
142  /*! Specify if particles fall under gravity */
143  inline void setAdvectWithGravity (bool a_flag)
144  {
145  BL_PROFILE("ERFPCPC::setAdvectWithGravity()");
146  m_advect_w_gravity = a_flag;
147  }
148 
149  // the following functions should ideally be private or protected, but need to be
150  // public due to CUDA extended lambda capture rules
151 
152  /*! \brief Helper for ParticleToMesh operations on terrain-following grids.
153  *
154  * Generic CIC deposition from particles to a MultiFab. The caller provides
155  * a device lambda `value_func(ptd, i)` that returns the per-particle scalar
156  * to deposit (e.g. mass, number, flux). Implementation in ERFPCParticleToMesh.H.
157  */
158  template<typename ValueFunc>
159  void ERFPCParticleToMesh(amrex::MultiFab& a_mf,
160  const amrex::MultiFab& a_z_phys_nd,
161  int a_lev, int a_comp,
162  ValueFunc&& value_func) const;
163 
164  /*! Default particle initialization */
165  void initializeParticlesUniformDistributionInBox (const std::unique_ptr<amrex::MultiFab>& a_ptr,
166  const amrex::RealBox& particle_box);
167 
168  /*! Replace pos(2) (zeta) with the corresponding physical z, in place,
169  * on every level. Used around plotfile writes so the on-disk
170  * particles are in physical coordinates. */
171  void ConvertZetaToZ (const amrex::Vector<std::unique_ptr<amrex::MultiFab>>& a_z_phys_nd);
172 
173  /*! Inverse of ConvertZetaToZ: replace pos(2) (physical z) with zeta. */
174  void ConvertZToZeta (const amrex::Vector<std::unique_ptr<amrex::MultiFab>>& a_z_phys_nd);
175 
176  /*! Route fine-level particles whose position is outside the level's
177  * BA down to coarser levels, so per-level Redistribute on the fine
178  * level does not assert. */
179  void ExtractAndRouteOORParticles ( int a_lev );
180 
181  /*! Diagnostic: count particles per level and halo (for AMR) */
182  void CountParticlesPerLevelAndHalo ( int a_finest_level );
183 
184  protected:
185 
186  bool m_advect_w_flow; /*!< advect with flow velocity */
187  bool m_advect_w_gravity; /*!< advect under gravitational force */
188 
189  amrex::RealBox m_particle_box; /*!< box within which to place particles */
190 
191  std::string m_name; /*!< name of this particle species */
192 
193  std::string m_initialization_type; /*!< initial particle distribution type */
194  int m_ppc_init; /*!< initial number of particles per cell */
195 
196  amrex::Real m_inject_start_time; /*!< particles will only be initialized/injected if time >= m_inject_start_time */
197 
198  bool m_initialized = false; /*!< have the particles been initialized */
199 
200  bool m_stable_redistribute; /*!< use stable redistribute for deterministic simulations */
201 
202  /*! read inputs from file */
203  virtual void readInputs ();
204 
205  private:
206 
207  bool place_randomly_in_cells; /*!< place particles at random positions? */
208 };
209 
210 #endif
211 #endif
amrex::Real Real
Definition: ERF_ShocInterface.H:19
Definition: ERF_ConsoleIO.cpp:12