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