ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_LandSurface.H
Go to the documentation of this file.
1 #ifndef ERF_LANDSURFACE_H
2 #define ERF_LANDSURFACE_H
3 
4 #include <typeinfo>
5 
6 #include <AMReX_PlotFileUtil.H>
7 #include <AMReX_MultiFabUtil.H>
8 
9 #include <ERF_NullSurf.H>
10 #include <ERF_SLM.H>
11 
12 #if ERF_USE_NOAHMP
13 #include <ERF_NOAHMP.H>
14 #endif
15 
16 /**
17  * @brief Wrapper class for managing land surface models across AMR levels.
18  */
19 class LandSurface {
20 
21 public:
22 
23  LandSurface () { }
24 
25  ~LandSurface () = default;
26 
27  void
28  ReSize (const int& nlev) { m_lsm_model.resize(nlev); }
29 
30  template<class NewSurfModel>
31  void
33  {
34  for (int lev(0); lev<m_lsm_model.size(); ++lev) {
35  m_lsm_model[lev] = std::make_unique<NewSurfModel>();
36  }
37  }
38 
39  void
40  Define (const int& lev,
41  SolverChoice& sc)
42  {
43  m_lsm_model[lev]->Define(sc);
44  }
45 
46  void
47  Init (const int& lev,
48  const amrex::MultiFab& cons_in,
49  const amrex::Geometry& geom,
50  const amrex::Geometry& geom0,
51  amrex::Vector<amrex::BCRec>& domain_bcs_type,
52  amrex::IntVect& refRatio,
53  const amrex::Real& dt_advance,
54  amrex::Vector<amrex::Vector<std::string>>& nc_init_file)
55  {
56  m_lsm_model[lev]->Init(lev, cons_in, geom, geom0,
57  domain_bcs_type, refRatio,
58  dt_advance, nc_init_file);
59  }
60 
61  void
62  Advance (const int& lev,
63  amrex::MultiFab& cons_in,
64  amrex::MultiFab& xvel_in,
65  amrex::MultiFab& yvel_in,
66  amrex::MultiFab* hfx3_out,
67  amrex::MultiFab* qfx3_out,
68  const SurfacePrecipAccumulationSources& precip_sources,
69  const double& time_d,
70  const double& dt_advance_d,
71  const int& nstep,
72  const bool updated_lev0)
73  {
74  amrex::Real time = static_cast<amrex::Real>(time_d);
75  amrex::Real dt_advance = static_cast<amrex::Real>(dt_advance_d);
76  m_lsm_model[lev]->Advance_With_State(lev, cons_in, xvel_in, yvel_in,
77  hfx3_out, qfx3_out,
78  precip_sources,
79  time, dt_advance, nstep, updated_lev0);
80  }
81 
82  void
83  Advance (const int& lev, const double& dt_advance_d)
84  {
85  amrex::Real dt_advance = static_cast<amrex::Real>(dt_advance_d);
86  m_lsm_model[lev]->Advance(dt_advance);
87  }
88 
89  void
90  Plot(const int& lev, const int& nstep)
91  {
92  m_lsm_model[lev]->Plot_Landfile(nstep);
93  }
94 
95  void
96  Update_Micro_Vars_Lev (const int& lev, amrex::MultiFab& cons_in)
97  {
98  m_lsm_model[lev]->Update_Micro_Vars(cons_in);
99  }
100 
101  void
102  Update_State_Vars_Lev (const int& lev, amrex::MultiFab& cons_in)
103  {
104  m_lsm_model[lev]->Update_State_Vars(cons_in);
105  }
106 
107  amrex::MultiFab*
108  Get_Data_Ptr (const int& lev, const int& varIdx) { return m_lsm_model[lev]->Lsm_Data_Ptr(varIdx); }
109 
110  amrex::MultiFab*
111  Get_Data_Ptr (const int& lev, const std::string& varname)
112  {
113  std::string name = varname;
114  const int index = m_lsm_model[lev]->Lsm_DataIndex(name);
115  return (index >= 0) ? m_lsm_model[lev]->Lsm_Data_Ptr(index) : nullptr;
116  }
117 
118  bool
119  Has_Model () const { return !m_lsm_model.empty() && m_lsm_model[0] != nullptr; }
120 
121  amrex::MultiFab*
122  Get_Flux_Ptr (const int& lev, const int& varIdx) { return m_lsm_model[lev]->Lsm_Flux_Ptr(varIdx); }
123 
124  amrex::Geometry
125  Get_Lsm_Geom (const int& lev ) { return m_lsm_model[lev]->Lsm_Geom(); }
126 
127  int
128  Get_Data_Size () { return m_lsm_model[0]->Lsm_Data_Size(); }
129 
130  int
131  Get_Flux_Size () { return m_lsm_model[0]->Lsm_Flux_Size(); }
132 
133  std::string
134  Get_DataName (const int& varIdx) { return m_lsm_model[0]->Lsm_DataName(varIdx); }
135 
136  amrex::Vector<std::string>
138  {
139  amrex::Vector<std::string> names;
140  if (m_lsm_model.empty() || m_lsm_model[0] == nullptr) {
141  return names;
142  }
143  const int nvars = Get_Data_Size();
144  names.reserve(nvars);
145  for (int var = 0; var < nvars; ++var) {
146  names.push_back(Get_DataName(var));
147  }
148  return names;
149  }
150 
151  int
152  Get_DataIdx (const int& lev, std::string& varname) { return m_lsm_model[lev]->Lsm_DataIndex(varname); }
153 
154  void
155  Set_Lev0_Data_Ptr (const int& lev) {
156  // Ensure the same type of model for copy in place of flux data
157  if ( (lev > 0) && typeid(m_lsm_model[lev]) == typeid(m_lsm_model[0]) ) {
158  int ndata = this->Get_Data_Size();
159  for (int varIdx(0); varIdx<ndata; ++varIdx) {
160  amrex::MultiFab* Lev0_Data_Ptr = this->Get_Data_Ptr(0, varIdx);
161  m_lsm_model[lev]->Lsm_Set_Lev0_Data_Ptr(varIdx, Lev0_Data_Ptr);
162  }
163  } else {
164  amrex::Abort("Differing types of land surface models across levels is not supported!");
165  }
166  }
167 
168  std::string
169  Get_FluxName (const int& varIdx) { return m_lsm_model[0]->Lsm_FluxName(varIdx); }
170 
171  int
172  Get_FluxIdx (const int& lev, std::string& varname) { return m_lsm_model[lev]->Lsm_FluxIndex(varname); }
173 
174  void
175  Set_Lev0_Flux_Ptr (const int& lev) {
176  // Ensure the same type of model for copy in place of flux data
177  if ( (lev > 0) && typeid(m_lsm_model[lev]) == typeid(m_lsm_model[0]) ) {
178  int nflux = this->Get_Flux_Size();
179  for (int varIdx(0); varIdx<nflux; ++varIdx) {
180  amrex::MultiFab* Lev0_Flux_Ptr = this->Get_Flux_Ptr(0, varIdx);
181  m_lsm_model[lev]->Lsm_Set_Lev0_Flux_Ptr(varIdx, Lev0_Flux_Ptr);
182  }
183  } else {
184  amrex::Abort("Differing types of land surface models across levels is not supported!");
185  }
186  }
187 
188  bool
189  Get_LSM_Update_Status (const int& lev) { return m_lsm_model[lev]->Get_Update_Status(); }
190 
191  std::unordered_map<std::string,std::string>&
192  Get_WRFInputNames() { return m_lsm_model[0]->Lsm_WRFInputNames(); }
193 
194  // Scalar LSM step counter (e.g., NoahMP itimestep) for checkpoint/restart.
195  int
196  Get_LSM_Step (const int& lev) const { return m_lsm_model[lev]->Get_LSM_Step(); }
197 
198  void
199  Set_LSM_Step (const int& lev, int step) { m_lsm_model[lev]->Set_LSM_Step(step); }
200 
201  // Full LSM prognostic-state restart I/O (e.g., NoahMP soil/snow/canopy).
202  // Write is const (called from the const WriteCheckpointFile); it only
203  // serializes state, it does not mutate the ERF-side model wrapper.
204  void
205  Write_Lsm_Restart (const int& lev, const std::string& dir) const { m_lsm_model[lev]->Write_Lsm_Restart(dir); }
206 
207  void
208  Read_Lsm_Restart (const int& lev, const std::string& dir) { m_lsm_model[lev]->Read_Lsm_Restart(dir); }
209 
210  void
211  Plot_Lsm_Data (double time,
212  int finest_level,
213  const amrex::Vector<int> &level_steps,
214  const amrex::Vector<amrex::IntVect> &ref_ratio)
215  {
216  // Note we must use finest_level here rather than m_lsm_model.size(), which is
217  // (max_level+1) -- the models at levels that have not (yet) been created
218  // have been allocated but not Define'd or Init'ed, so their data pointers
219  // are still null
220  int nlev = finest_level + 1;
221  int nvar = this->Get_Data_Size();
222  amrex::Vector<std::string> varnames;
223 
224  // Only write if we have valid pointers
225  if (this->Get_Data_Ptr(0,0)) {
226  varnames.resize(nvar);
227  m_lsm_geom_lev.resize(nlev);
228  m_lsm_data_lev.resize(nlev);
229  std::string plotfilename = amrex::Concatenate(plot_file_lsm, level_steps[0], 5);
230  for (int lev(0); lev<nlev; ++lev) {
231  m_lsm_geom_lev[lev] = this->Get_Lsm_Geom(lev);
232 
233  amrex::MultiFab* mf_lsm = this->Get_Data_Ptr(lev,0);
234  amrex::IntVect ng(0,0,0);
235  amrex::BoxArray ba = mf_lsm->boxArray();
236  amrex::DistributionMapping dm = mf_lsm->DistributionMap();
237  m_lsm_data_lev[lev].define(ba, dm, nvar, ng);
238  for (int n(0); n<nvar; ++n) {
239  mf_lsm = this->Get_Data_Ptr(lev,n);
240  amrex::MultiFab::Copy(m_lsm_data_lev[lev],*(mf_lsm),0,n,1,0);
241  if (lev==0) varnames[n] = this->Get_DataName(n);
242  }
243  }
244  WriteMultiLevelPlotfile (plotfilename, nlev, GetVecOfConstPtrs(m_lsm_data_lev),
245  varnames, m_lsm_geom_lev, static_cast<amrex::Real>(time),
246  level_steps, ref_ratio);
247  m_lsm_geom_lev.clear();
248  m_lsm_data_lev.clear();
249  }
250  }
251 
252  template<class SurfModelType>
253  SurfModelType* get_model_lev(const int &lev) {
254  return static_cast<SurfModelType*>(m_lsm_model[lev].get());
255  }
256 
257 private:
258  // lsm model at each level
259  amrex::Vector<std::unique_ptr<NullSurf>> m_lsm_model;
260 
261  // plotfile prefix
262  std::string plot_file_lsm {"plt_lsm_"};
263 
264  // Vector of geometry
265  amrex::Vector<amrex::Geometry> m_lsm_geom_lev;
266 
267  // Vector of data pointers
268  amrex::Vector<amrex::MultiFab> m_lsm_data_lev;
269 };
270 #endif
@ nvars
Definition: ERF_DataStruct.H:153
std::string name
Definition: ERF_Plotfile2DCatalog.cpp:101
amrex::Real Real
Definition: ERF_ShocInterface.H:19
Wrapper class for managing land surface models across AMR levels.
Definition: ERF_LandSurface.H:19
amrex::Vector< amrex::Geometry > m_lsm_geom_lev
Definition: ERF_LandSurface.H:265
std::unordered_map< std::string, std::string > & Get_WRFInputNames()
Definition: ERF_LandSurface.H:192
void Init(const int &lev, const amrex::MultiFab &cons_in, const amrex::Geometry &geom, const amrex::Geometry &geom0, amrex::Vector< amrex::BCRec > &domain_bcs_type, amrex::IntVect &refRatio, const amrex::Real &dt_advance, amrex::Vector< amrex::Vector< std::string >> &nc_init_file)
Definition: ERF_LandSurface.H:47
amrex::MultiFab * Get_Data_Ptr(const int &lev, const std::string &varname)
Definition: ERF_LandSurface.H:111
int Get_Data_Size()
Definition: ERF_LandSurface.H:128
amrex::Geometry Get_Lsm_Geom(const int &lev)
Definition: ERF_LandSurface.H:125
~LandSurface()=default
SurfModelType * get_model_lev(const int &lev)
Definition: ERF_LandSurface.H:253
void Read_Lsm_Restart(const int &lev, const std::string &dir)
Definition: ERF_LandSurface.H:208
int Get_FluxIdx(const int &lev, std::string &varname)
Definition: ERF_LandSurface.H:172
void Plot(const int &lev, const int &nstep)
Definition: ERF_LandSurface.H:90
void Set_Lev0_Data_Ptr(const int &lev)
Definition: ERF_LandSurface.H:155
amrex::Vector< std::string > Get_DataNames()
Definition: ERF_LandSurface.H:137
void ReSize(const int &nlev)
Definition: ERF_LandSurface.H:28
amrex::Vector< amrex::MultiFab > m_lsm_data_lev
Definition: ERF_LandSurface.H:268
std::string Get_DataName(const int &varIdx)
Definition: ERF_LandSurface.H:134
void Plot_Lsm_Data(double time, int finest_level, const amrex::Vector< int > &level_steps, const amrex::Vector< amrex::IntVect > &ref_ratio)
Definition: ERF_LandSurface.H:211
int Get_LSM_Step(const int &lev) const
Definition: ERF_LandSurface.H:196
std::string Get_FluxName(const int &varIdx)
Definition: ERF_LandSurface.H:169
amrex::Vector< std::unique_ptr< NullSurf > > m_lsm_model
Definition: ERF_LandSurface.H:259
void Set_LSM_Step(const int &lev, int step)
Definition: ERF_LandSurface.H:199
void SetModel()
Definition: ERF_LandSurface.H:32
amrex::MultiFab * Get_Flux_Ptr(const int &lev, const int &varIdx)
Definition: ERF_LandSurface.H:122
void Advance(const int &lev, const double &dt_advance_d)
Definition: ERF_LandSurface.H:83
void Advance(const int &lev, amrex::MultiFab &cons_in, amrex::MultiFab &xvel_in, amrex::MultiFab &yvel_in, amrex::MultiFab *hfx3_out, amrex::MultiFab *qfx3_out, const SurfacePrecipAccumulationSources &precip_sources, const double &time_d, const double &dt_advance_d, const int &nstep, const bool updated_lev0)
Definition: ERF_LandSurface.H:62
bool Get_LSM_Update_Status(const int &lev)
Definition: ERF_LandSurface.H:189
LandSurface()
Definition: ERF_LandSurface.H:23
void Set_Lev0_Flux_Ptr(const int &lev)
Definition: ERF_LandSurface.H:175
void Update_State_Vars_Lev(const int &lev, amrex::MultiFab &cons_in)
Definition: ERF_LandSurface.H:102
int Get_DataIdx(const int &lev, std::string &varname)
Definition: ERF_LandSurface.H:152
void Define(const int &lev, SolverChoice &sc)
Definition: ERF_LandSurface.H:40
int Get_Flux_Size()
Definition: ERF_LandSurface.H:131
amrex::MultiFab * Get_Data_Ptr(const int &lev, const int &varIdx)
Definition: ERF_LandSurface.H:108
void Write_Lsm_Restart(const int &lev, const std::string &dir) const
Definition: ERF_LandSurface.H:205
bool Has_Model() const
Definition: ERF_LandSurface.H:119
std::string plot_file_lsm
Definition: ERF_LandSurface.H:262
void Update_Micro_Vars_Lev(const int &lev, amrex::MultiFab &cons_in)
Definition: ERF_LandSurface.H:96
@ ng
Definition: ERF_Morrison.H:49
Definition: ERF_DataStruct.H:634
Definition: ERF_SurfacePrecipitation.H:34