ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_ParticleData.H
Go to the documentation of this file.
1 #ifndef ERF_PARTICLE_DATA_H_
2 #define ERF_PARTICLE_DATA_H_
3 
4 #ifdef ERF_USE_PARTICLES
5 
6 #include <map>
7 #include <vector>
8 #include <list>
9 #include <string>
10 #include <iostream>
11 
12 #include <AMReX_ParmParse.H>
13 #include <AMReX_Print.H>
14 #include <AMReX_Vector.H>
15 #include <AMReX_Gpu.H>
16 
17 #include <ERFPC.H>
18 
19 /**
20  * Container holding many of the particle-related data and options
21  */
22 
23 typedef std::map<std::string, ERFPC*> ParticleSpeciesMap;
24 typedef std::vector<std::string> ParticlesNamesVector;
25 typedef std::list<std::string> ParticlesNamesList;
26 
27 class ParticleData
28 {
29  public:
30 
31  /*! Constructor */
32  ParticleData ()
33  {
34  BL_PROFILE("ParticleData::ParticleData()");
35 
36  amrex::ParmParse pp("particles");
37  m_disable_particle_op = false;
38  pp.query("disable_plt", m_disable_particle_op);
39 
40  m_particle_species.clear();
41  m_namelist.clear();
42  m_namelist_unalloc.clear();
43  }
44 
45  /*! Destructor */
46  ~ParticleData ()
47  {
48  BL_PROFILE("ParticleData::~ParticleData()");
49  for (ParticlesNamesVector::size_type i = 0; i < m_namelist.size(); i++) {
50  auto particles( m_particle_species[m_namelist[i]] );
51  delete particles;
52  }
53  m_particle_species.clear();
54  m_namelist.clear();
55  m_namelist_unalloc.clear();
56  }
57 
58  /*! Write particle info to plot files. Particles are stored with
59  * pos(2) = computational zeta; the on-disk plotfile holds the
60  * physical z, so convert in-place around the write. */
61  void writePlotFile ( const std::string& a_fname,
62  const amrex::Vector<std::unique_ptr<amrex::MultiFab>>& a_z_phys_nd ) const
63  {
64  BL_PROFILE("ParticleData::writePlotFile");
65  if (!m_disable_particle_op) {
66  for (ParticlesNamesVector::size_type i = 0; i < m_namelist.size(); i++) {
67  auto name( m_namelist[i] );
68  auto particles( m_particle_species.at(name) );
69  particles->ConvertZetaToZ(a_z_phys_nd);
70  particles->WritePlotFile(a_fname, name, particles->varNames());
71  particles->ConvertZToZeta(a_z_phys_nd);
72  }
73  }
74  }
75 
76  /*! Write checkpoint files */
77  void Checkpoint ( const std::string& a_fname ) const
78  {
79  BL_PROFILE("ParticleData::Checkpoint()");
80  for (ParticlesNamesVector::size_type i = 0; i < m_namelist.size(); i++) {
81  auto name( m_namelist[i] );
82  auto particles( m_particle_species.at(name) );
83  particles->Checkpoint( a_fname, name, true, particles->varNames() );
84  }
85  }
86 
87  /*! Get mesh plot quantities from each particle container */
88  void GetMeshPlotVarNames ( amrex::Vector<std::string>& a_names ) const
89  {
90  BL_PROFILE("ParticleData::GetMeshPlotVarNames()");
91  a_names.clear();
92  for (ParticlesNamesVector::size_type i = 0; i < m_namelist.size(); i++) {
93  auto name( m_namelist[i] );
94  auto particles( m_particle_species.at(name) );
95 
96  auto var_names = particles->meshPlotVarNames();
97  for (int n = 0; n < var_names.size(); n++) {
98  a_names.push_back( std::string(name+"_"+var_names[n]) );
99  }
100  }
101  }
102 
103  void GetMeshPlotVar ( const std::string& a_var_name,
104  amrex::MultiFab& a_mf,
105  const amrex::MultiFab& a_z_phys_nd,
106  const int a_lev )
107  {
108  BL_PROFILE("ParticleData::GetMeshPlotVar()");
109  for (ParticlesNamesVector::size_type i = 0; i < m_namelist.size(); i++) {
110  auto particle_name( m_namelist[i] );
111  auto particles( m_particle_species.at(particle_name) );
112 
113  auto particle_var_names = particles->meshPlotVarNames();
114 
115  for (int n = 0; n < particle_var_names.size(); n++) {
116 
117  std::string var_name = particle_name+"_"+particle_var_names[n];
118  if ( var_name == a_var_name ) {
119  particles->computeMeshVar(particle_var_names[n], a_mf, a_z_phys_nd, a_lev);
120  return;
121  }
122  }
123  }
124  amrex::Abort("Requested var_name not found in ParticleData::GetMeshPlotVar");
125  }
126 
127  /*! Redistribute/rebalance particles data */
128  inline void Redistribute ()
129  {
130  BL_PROFILE("ParticleData::Redistribute()");
131  for (ParticlesNamesVector::size_type i = 0; i < m_namelist.size(); i++) {
132  m_particle_species[m_namelist[i]]->Redistribute();
133  }
134  }
135 
136  /*! Redistribute after AMR regrid. */
137  inline void Redistribute (
138  const amrex::Vector<std::unique_ptr<amrex::MultiFab>>& /*a_z_phys_nd*/)
139  {
140  BL_PROFILE("ParticleData::Redistribute(z_phys_nd)");
141  for (ParticlesNamesVector::size_type i = 0; i < m_namelist.size(); i++) {
142  m_particle_species[m_namelist[i]]->Redistribute();
143  }
144  }
145 
146  /*! Get species of a given name */
147  inline bool HasSpecies ( const std::string& a_name )
148  {
149  BL_PROFILE("ParticleData::HasSpecies()");
150  ParticleSpeciesMap::iterator it (m_particle_species.find(a_name));
151  if (it == m_particle_species.end()) {
152  return false;
153  } else {
154  return true;
155  }
156  }
157 
158  /*! Get species of a given name */
159  inline ERFPC* GetSpecies ( const std::string& a_name )
160  {
161  BL_PROFILE("ParticleData::GetSpecies()");
162  ParticleSpeciesMap::iterator it (m_particle_species.find(a_name));
163  if (it == m_particle_species.end()) {
164  amrex::Print() << "ERROR: unable to find particle species with name \""
165  << a_name << "\"!";
166  return nullptr;
167  } else {
168  return it->second;
169  }
170  }
171 
172  /*! accessor */
173  inline ERFPC* operator[] ( const std::string& a_name )
174  {
175  BL_PROFILE("ParticleData::operator[]");
176  ParticleSpeciesMap::iterator it (m_particle_species.find(a_name));
177  if (it == m_particle_species.end()) {
178  amrex::Print() << "ERROR: unable to find particle species with name \""
179  << a_name << "\"!";
180  return nullptr;
181  } else {
182  return it->second;
183  }
184  }
185 
186  /*! Get species of a given name (const version) */
187  inline const ERFPC* GetSpecies ( const std::string& a_name ) const
188  {
189  BL_PROFILE("ParticleData::GetSpecies()");
190  ParticleSpeciesMap::const_iterator it (m_particle_species.find(a_name));
191  if (it == m_particle_species.end()) {
192  amrex::Print() << "ERROR: unable to find particle species with name \""
193  << a_name << "\"!";
194  return nullptr;
195  } else {
196  return it->second;
197  }
198  }
199 
200  /*! accessor */
201  inline const ERFPC* operator[] ( const std::string& a_name ) const
202  {
203  BL_PROFILE("ParticleData::operator[]");
204  ParticleSpeciesMap::const_iterator it (m_particle_species.find(a_name));
205  if (it == m_particle_species.end()) {
206  amrex::Print() << "ERROR: unable to find particle species with name \""
207  << a_name << "\"!";
208  return nullptr;
209  } else {
210  return it->second;
211  }
212  }
213 
214  /*! Add a particle species to this container */
215  inline void pushBack (const std::string& a_name,
216  ERFPC* const a_pc )
217  {
218  BL_PROFILE("ParticleData::pushBack()");
219  AMREX_ASSERT(!contains(a_name));
220  m_particle_species[a_name] = a_pc;
221  m_namelist.push_back(a_name);
222  }
223 
224  /*! Add a name; particle container will be initialized later */
225  inline void addName (const std::string& a_name )
226  {
227  BL_PROFILE("ParticleData::addName()");
228  m_namelist_unalloc.push_back(a_name);
229  }
230 
231  /*! Returns list of names of particle species */
232  inline const ParticlesNamesVector& getNames () const
233  {
234  BL_PROFILE("ParticleData::getNames()");
235  return m_namelist;
236  }
237 
238  /*! Returns list of names of particle species that are unallocated */
239  inline ParticlesNamesList& getNamesUnalloc ()
240  {
241  BL_PROFILE("ParticleData::getNamesUnalloc()");
242  return m_namelist_unalloc;
243  }
244 
245  /*! queries if container has species of a certain name */
246  inline bool contains ( const std::string& a_name ) const
247  {
248  BL_PROFILE("ParticleData::contains()");
249  ParticleSpeciesMap::const_iterator it (m_particle_species.find(a_name));
250  return (it != m_particle_species.end());
251  }
252 
253  /*! query if container is empty */
254  inline bool isEmpty () const
255  {
256  BL_PROFILE("ParticleData::isEmpty()");
257  return (m_particle_species.size() == 0);
258  }
259 
260 
261  private:
262 
263  /*! Vector of all particle species */
264  ParticleSpeciesMap m_particle_species;
265  /*! Vector of particle species names */
266  ParticlesNamesVector m_namelist;
267  /*! List with names of unallocated species */
268  ParticlesNamesList m_namelist_unalloc;
269 
270  /*! Disable particle output in plotfile? (because expensive) */
271  bool m_disable_particle_op;
272 };
273 
274 #endif
275 #endif
ParmParse pp("prob")