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 */
59  void writePlotFile ( const std::string& a_fname ) const
60  {
61  BL_PROFILE("ParticleData::writePlotFile");
62  if (!m_disable_particle_op) {
63  for (ParticlesNamesVector::size_type i = 0; i < m_namelist.size(); i++) {
64  auto name( m_namelist[i] );
65  auto particles( m_particle_species.at(name) );
66  particles->WritePlotFile(a_fname, name, particles->varNames());
67  }
68  }
69  }
70 
71  /*! Write checkpoint files */
72  void Checkpoint ( const std::string& a_fname ) const
73  {
74  BL_PROFILE("ParticleData::Checkpoint()");
75  for (ParticlesNamesVector::size_type i = 0; i < m_namelist.size(); i++) {
76  auto name( m_namelist[i] );
77  auto particles( m_particle_species.at(name) );
78  particles->Checkpoint( a_fname, name, true, particles->varNames() );
79  }
80  }
81 
82  /*! Get mesh plot quantities from each particle container */
83  void GetMeshPlotVarNames ( amrex::Vector<std::string>& a_names ) const
84  {
85  BL_PROFILE("ParticleData::GetMeshPlotVarNames()");
86  a_names.clear();
87  for (ParticlesNamesVector::size_type i = 0; i < m_namelist.size(); i++) {
88  auto name( m_namelist[i] );
89  auto particles( m_particle_species.at(name) );
90 
91  auto var_names = particles->meshPlotVarNames();
92  for (int n = 0; n < var_names.size(); n++) {
93  a_names.push_back( std::string(name+"_"+var_names[n]) );
94  }
95  }
96  }
97 
98  void GetMeshPlotVar ( const std::string& a_var_name,
99  amrex::MultiFab& a_mf,
100  const amrex::MultiFab& a_z_phys_nd,
101  const int a_lev )
102  {
103  BL_PROFILE("ParticleData::GetMeshPlotVar()");
104  for (ParticlesNamesVector::size_type i = 0; i < m_namelist.size(); i++) {
105  auto particle_name( m_namelist[i] );
106  auto particles( m_particle_species.at(particle_name) );
107 
108  auto particle_var_names = particles->meshPlotVarNames();
109 
110  for (int n = 0; n < particle_var_names.size(); n++) {
111 
112  std::string var_name = particle_name+"_"+particle_var_names[n];
113  if ( var_name == a_var_name ) {
114  particles->computeMeshVar(particle_var_names[n], a_mf, a_z_phys_nd, a_lev);
115  return;
116  }
117  }
118  }
119  amrex::Abort("Requested var_name not found in ParticleData::GetMeshPlotVar");
120  }
121 
122  /*! Redistribute/rebalance particles data */
123  inline void Redistribute ()
124  {
125  BL_PROFILE("ParticleData::Redistribute()");
126  for (ParticlesNamesVector::size_type i = 0; i < m_namelist.size(); i++) {
127  m_particle_species[m_namelist[i]]->Redistribute();
128  }
129  }
130 
131  /*! Redistribute with terrain-aware k-index fix and level-boundary split/merge */
132  inline void Redistribute (
133  const amrex::Vector<std::unique_ptr<amrex::MultiFab>>& a_z_phys_nd)
134  {
135  BL_PROFILE("ParticleData::Redistribute(z_phys_nd)");
136  for (ParticlesNamesVector::size_type i = 0; i < m_namelist.size(); i++) {
137  auto* pc = m_particle_species[m_namelist[i]];
138  pc->FixKIndexAMR(a_z_phys_nd);
139  }
140  }
141 
142  /*! Get species of a given name */
143  inline bool HasSpecies ( const std::string& a_name )
144  {
145  BL_PROFILE("ParticleData::HasSpecies()");
146  ParticleSpeciesMap::iterator it (m_particle_species.find(a_name));
147  if (it == m_particle_species.end()) {
148  return false;
149  } else {
150  return true;
151  }
152  }
153 
154  /*! Get species of a given name */
155  inline ERFPC* GetSpecies ( const std::string& a_name )
156  {
157  BL_PROFILE("ParticleData::GetSpecies()");
158  ParticleSpeciesMap::iterator it (m_particle_species.find(a_name));
159  if (it == m_particle_species.end()) {
160  amrex::Print() << "ERROR: unable to find particle species with name \""
161  << a_name << "\"!";
162  return nullptr;
163  } else {
164  return it->second;
165  }
166  }
167 
168  /*! accessor */
169  inline ERFPC* operator[] ( const std::string& a_name )
170  {
171  BL_PROFILE("ParticleData::operator[]");
172  ParticleSpeciesMap::iterator it (m_particle_species.find(a_name));
173  if (it == m_particle_species.end()) {
174  amrex::Print() << "ERROR: unable to find particle species with name \""
175  << a_name << "\"!";
176  return nullptr;
177  } else {
178  return it->second;
179  }
180  }
181 
182  /*! Get species of a given name (const version) */
183  inline const ERFPC* GetSpecies ( const std::string& a_name ) const
184  {
185  BL_PROFILE("ParticleData::GetSpecies()");
186  ParticleSpeciesMap::const_iterator it (m_particle_species.find(a_name));
187  if (it == m_particle_species.end()) {
188  amrex::Print() << "ERROR: unable to find particle species with name \""
189  << a_name << "\"!";
190  return nullptr;
191  } else {
192  return it->second;
193  }
194  }
195 
196  /*! accessor */
197  inline const ERFPC* operator[] ( const std::string& a_name ) const
198  {
199  BL_PROFILE("ParticleData::operator[]");
200  ParticleSpeciesMap::const_iterator it (m_particle_species.find(a_name));
201  if (it == m_particle_species.end()) {
202  amrex::Print() << "ERROR: unable to find particle species with name \""
203  << a_name << "\"!";
204  return nullptr;
205  } else {
206  return it->second;
207  }
208  }
209 
210  /*! Add a particle species to this container */
211  inline void pushBack (const std::string& a_name,
212  ERFPC* const a_pc )
213  {
214  BL_PROFILE("ParticleData::pushBack()");
215  AMREX_ASSERT(!contains(a_name));
216  m_particle_species[a_name] = a_pc;
217  m_namelist.push_back(a_name);
218  }
219 
220  /*! Add a name; particle container will be initialized later */
221  inline void addName (const std::string& a_name )
222  {
223  BL_PROFILE("ParticleData::addName()");
224  m_namelist_unalloc.push_back(a_name);
225  }
226 
227  /*! Returns list of names of particle species */
228  inline const ParticlesNamesVector& getNames () const
229  {
230  BL_PROFILE("ParticleData::getNames()");
231  return m_namelist;
232  }
233 
234  /*! Returns list of names of particle species that are unallocated */
235  inline ParticlesNamesList& getNamesUnalloc ()
236  {
237  BL_PROFILE("ParticleData::getNamesUnalloc()");
238  return m_namelist_unalloc;
239  }
240 
241  /*! queries if container has species of a certain name */
242  inline bool contains ( const std::string& a_name ) const
243  {
244  BL_PROFILE("ParticleData::contains()");
245  ParticleSpeciesMap::const_iterator it (m_particle_species.find(a_name));
246  return (it != m_particle_species.end());
247  }
248 
249  /*! query if container is empty */
250  inline bool isEmpty () const
251  {
252  BL_PROFILE("ParticleData::isEmpty()");
253  return (m_particle_species.size() == 0);
254  }
255 
256 
257  private:
258 
259  /*! Vector of all particle species */
260  ParticleSpeciesMap m_particle_species;
261  /*! Vector of particle species names */
262  ParticlesNamesVector m_namelist;
263  /*! List with names of unallocated species */
264  ParticlesNamesList m_namelist_unalloc;
265 
266  /*! Disable particle output in plotfile? (because expensive) */
267  bool m_disable_particle_op;
268 };
269 
270 #endif
271 #endif
ParmParse pp("prob")