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