ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_NOAHMP.H
Go to the documentation of this file.
1 #ifndef NOAHMP_H
2 #define NOAHMP_H
3 
4 #include <string>
5 #include <vector>
6 #include <memory>
7 #include <limits>
8 
9 #include <AMReX_FArrayBox.H>
10 #include <AMReX_Geometry.H>
11 #include <AMReX_MultiFabUtil.H>
12 #include <AMReX_Vector.H>
13 #include <AMReX_MFIter.H>
14 
15 #include <ERF_NullSurf.H>
16 #include <ERF_Constants.H>
17 #include <ERF_IndexDefines.H>
18 #include <ERF_DataStruct.H>
19 
20 // External include from the noahmp library
21 #include <NoahmpIO.H>
22 
23 namespace LsmData_NOAHMP {
24  enum {
25  // 2D RRTMGP coupling vars
26  t_sfc = 0,
39  NumVars
40  };
41 }
42 
43 namespace LsmFlux_NOAHMP {
44  enum {
45  // 2D SurfaceLayer flux vars
46  t_flux = 0,
50  NumVars
51  };
52 }
53 
54 
55 namespace NoahmpInputComp {
56  enum {
57  u_phy = 0,
61  p8w,
63  glw,
65  NumComps
66  };
67 }
68 
69 namespace NoahmpOutputComp {
70  enum {
71  hfx = 0,
72  lh,
75  tsk,
81  NumComps
82  };
83 }
84 
85 class NOAHMP : public NullSurf {
86 
87  using FabPtr = std::shared_ptr<amrex::MultiFab>;
88 
89 public:
90  // Constructor
91  NOAHMP () {}
92 
93  // Destructor
94  virtual ~NOAHMP () = default;
95 
96  // Set thermo and grid properties
97  void
98  Define (SolverChoice& /*sc*/) override
99  {
100  // NOTE: We should parse constants from sc here if needed,
101  }
102 
103  // Initialize data structures
104  void
105  Init (const int& lev,
106  const amrex::MultiFab& cons_in,
107  const amrex::Geometry& geom,
108  const amrex::Real& dt) override;
109 
110  // Wrapper to do all the updating
111  void
112  Advance_With_State (const int& lev,
113  amrex::MultiFab& cons_in,
114  amrex::MultiFab& xvel_in,
115  amrex::MultiFab& yvel_in,
116  amrex::MultiFab* hfx3_out,
117  amrex::MultiFab* qfx3_out,
118  const amrex::Real& elapsed_time,
119  const amrex::Real& dt,
120  const int& nstep) override;
121 
122  void
123  Plot_Landfile (const int& nstep) override;
124 
125  // Get state vars from lsm class
126  amrex::MultiFab*
127  Lsm_Data_Ptr (const int& varIdx) override
128  {
129  int lsmIdx = LsmDataMap[varIdx];
130  AMREX_ALWAYS_ASSERT(lsmIdx < NOAHMP::m_lsm_data_size && lsmIdx>=0);
131  return lsm_fab_data[lsmIdx].get();
132  }
133 
134  // Get flux vars from lsm class
135  amrex::MultiFab*
136  Lsm_Flux_Ptr (const int& varIdx) override
137  {
138  int lsmIdx = LsmFluxMap[varIdx];
139  AMREX_ALWAYS_ASSERT(lsmIdx < NOAHMP::m_lsm_flux_size && lsmIdx>=0);
140  return lsm_fab_flux[lsmIdx].get();
141  }
142 
143  // Get lsm geometry
144  amrex::Geometry
145  Lsm_Geom ( ) override { return m_lsm_geom; }
146 
147  // Get number of vars lsm class contains
148  int
149  Lsm_Data_Size () override { return NOAHMP::m_lsm_data_size; }
150 
151  // Get number of fluxes lsm class contains
152  int
153  Lsm_Flux_Size () override { return NOAHMP::m_lsm_flux_size; }
154 
155  // Get variable names
156  std::string
157  Lsm_DataName (const int& varIdx) override
158  {
159  int lsmIdx = LsmDataMap[varIdx];
160  AMREX_ALWAYS_ASSERT(lsmIdx < NOAHMP::m_lsm_data_size && lsmIdx>=0);
161  return LsmDataName[lsmIdx];
162  }
163 
164  // Get variable index from name
165  int
166  Lsm_DataIndex (std::string varname) override
167  {
168  int varIdx = -1;
169  std::string lc_varname = amrex::toLower(varname);
170  for (int idx(0); idx<LsmData_NOAHMP::NumVars; ++idx) {
171  if (lc_varname == amrex::toLower(LsmDataName[idx])) {
172  varIdx = idx;
173  }
174  }
175  return varIdx;
176  }
177 
178  // Get flux variable names
179  std::string
180  Lsm_FluxName (const int& varIdx) override
181  {
182  int lsmIdx = LsmFluxMap[varIdx];
183  AMREX_ALWAYS_ASSERT(lsmIdx < NOAHMP::m_lsm_flux_size && lsmIdx>=0);
184  return LsmFluxName[lsmIdx];
185  }
186 
187  // Get flux variable index from name
188  int
189  Lsm_FluxIndex (std::string varname) override
190  {
191  int varIdx = -1;
192  std::string lc_varname = amrex::toLower(varname);
193  for (int idx(0); idx<LsmFlux_NOAHMP::NumVars; ++idx) {
194  if (lc_varname == amrex::toLower(LsmFluxName[idx])) {
195  varIdx = idx;
196  }
197  }
198  return varIdx;
199  }
200 
201  // Checkpoint/restore the NoahMP substep counter. Uses the class member
202  // m_itimestep (valid on every rank) rather than noahmpio_vect[0] (absent on
203  // land-free ranks).
204  int
205  Get_LSM_Step () const override
206  {
207  return m_itimestep;
208  }
209 
210  void
211  Set_LSM_Step (int step) override
212  {
213  m_itimestep = step;
214  for (auto& noahmpio : noahmpio_vect) {
215  noahmpio.itimestep = step;
216  }
217  }
218 
219  // Write/read the full NoahMP prognostic state (soil, snow incl. layers,
220  // canopy, aquifer, albedo history, ...) to/from a NetCDF restart directory
221  // so a restart reproduces a cold-start trajectory bitwise (issue #3255).
222  // Each local block writes its tile into the global-domain file collectively.
223  void
224  Write_Lsm_Restart (const std::string& dir) const override
225  {
226  for (const NoahmpIO_type& noahmpio : noahmpio_vect) {
227  const_cast<NoahmpIO_type&>(noahmpio).WriteRestart(dir);
228  }
229  }
230 
231  void
232  Read_Lsm_Restart (const std::string& dir) override
233  {
234  for (NoahmpIO_type& noahmpio : noahmpio_vect) {
235  noahmpio.ReadRestart(dir);
236  }
237  }
238 
239 private:
240  // number of lsm data variables
242 
243  // number of lsm flux variables
245 
246  // LsmData map (state indices -> LsmVar enum)
247  amrex::Vector<int> LsmDataMap;
248 
249  // LsmFlux map (state indices -> LsmFlux enum)
250  amrex::Vector<int> LsmFluxMap;
251 
252  // Lsm data names
253  amrex::Vector<std::string> LsmDataName;
254 
255  // Lsm flux names
256  amrex::Vector<std::string> LsmFluxName;
257 
258  // geometry for atmosphere
259  amrex::Geometry m_geom;
260 
261  // geometry for lsm
262  amrex::Geometry m_lsm_geom;
263 
264  // timestep
266 
267  // Authoritative NoahMP substep counter, kept on the class so the firing
268  // decision in Advance_With_State is identical on every rank (including
269  // land-free ranks, whose noahmpio_vect is empty).
270  int m_itimestep = 0;
271 
272  // NoahMP timestep (DTBL), broadcast to all ranks in Init so the firing
273  // decision is well-defined on land-free ranks too.
274  amrex::Real m_dtbl = std::numeric_limits<amrex::Real>::max();
275 
276  // domain klo-1 or lsm khi
277  int khi_lsm;
278 
279  // Number of grid points in z
280  int m_nz_lsm = 1;
281 
282  // Size of grid spacing in z
284 
285  // LSM data variables
286  amrex::Array<FabPtr, LsmData_NOAHMP::NumVars> lsm_fab_data;
287 
288  // LSM data variables
289  amrex::Array<FabPtr, LsmFlux_NOAHMP::NumVars> lsm_fab_flux;
290 
291  // Vector to store NoahmpIO objects at a level
292  NoahmpIO_vector noahmpio_vect;
293 
294  // Pinned memory buffers for host/device coupling to Noah-MP
295  amrex::Vector<std::unique_ptr<amrex::FArrayBox>> noahmp_input_tmp;
296  amrex::Vector<std::unique_ptr<amrex::FArrayBox>> noahmp_output_tmp;
297 
298  // Plot frequency
299  int m_plot_int_1 = -1;
300 };
301 #endif
constexpr amrex::Real one
Definition: ERF_Constants.H:9
AMREX_ALWAYS_ASSERT(bx.length()[2]==khi+1)
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE int idx(int i, int j, int k, int nx, int ny)
Definition: ERF_InitForEnsemble.cpp:287
amrex::Real Real
Definition: ERF_ShocInterface.H:19
Definition: ERF_NOAHMP.H:85
int Lsm_DataIndex(std::string varname) override
Definition: ERF_NOAHMP.H:166
std::string Lsm_DataName(const int &varIdx) override
Definition: ERF_NOAHMP.H:157
int khi_lsm
Definition: ERF_NOAHMP.H:277
NOAHMP()
Definition: ERF_NOAHMP.H:91
void Define(SolverChoice &) override
Definition: ERF_NOAHMP.H:98
std::string Lsm_FluxName(const int &varIdx) override
Definition: ERF_NOAHMP.H:180
int m_plot_int_1
Definition: ERF_NOAHMP.H:299
void Plot_Landfile(const int &nstep) override
Definition: ERF_NOAHMP.cpp:256
int Lsm_FluxIndex(std::string varname) override
Definition: ERF_NOAHMP.H:189
amrex::Array< FabPtr, LsmFlux_NOAHMP::NumVars > lsm_fab_flux
Definition: ERF_NOAHMP.H:289
int Get_LSM_Step() const override
Definition: ERF_NOAHMP.H:205
void Write_Lsm_Restart(const std::string &dir) const override
Definition: ERF_NOAHMP.H:224
amrex::Vector< std::string > LsmDataName
Definition: ERF_NOAHMP.H:253
std::shared_ptr< amrex::MultiFab > FabPtr
Definition: ERF_NOAHMP.H:87
amrex::Vector< int > LsmDataMap
Definition: ERF_NOAHMP.H:247
amrex::Vector< std::unique_ptr< amrex::FArrayBox > > noahmp_output_tmp
Definition: ERF_NOAHMP.H:296
amrex::Vector< std::unique_ptr< amrex::FArrayBox > > noahmp_input_tmp
Definition: ERF_NOAHMP.H:295
void Init(const int &lev, const amrex::MultiFab &cons_in, const amrex::Geometry &geom, const amrex::Real &dt) override
Definition: ERF_NOAHMP.cpp:19
int Lsm_Flux_Size() override
Definition: ERF_NOAHMP.H:153
int Lsm_Data_Size() override
Definition: ERF_NOAHMP.H:149
amrex::Geometry Lsm_Geom() override
Definition: ERF_NOAHMP.H:145
void Read_Lsm_Restart(const std::string &dir) override
Definition: ERF_NOAHMP.H:232
NoahmpIO_vector noahmpio_vect
Definition: ERF_NOAHMP.H:292
int m_lsm_data_size
Definition: ERF_NOAHMP.H:241
virtual ~NOAHMP()=default
amrex::Geometry m_lsm_geom
Definition: ERF_NOAHMP.H:262
int m_itimestep
Definition: ERF_NOAHMP.H:270
amrex::Array< FabPtr, LsmData_NOAHMP::NumVars > lsm_fab_data
Definition: ERF_NOAHMP.H:286
int m_nz_lsm
Definition: ERF_NOAHMP.H:280
int m_lsm_flux_size
Definition: ERF_NOAHMP.H:244
amrex::Real m_dtbl
Definition: ERF_NOAHMP.H:274
void Advance_With_State(const int &lev, amrex::MultiFab &cons_in, amrex::MultiFab &xvel_in, amrex::MultiFab &yvel_in, amrex::MultiFab *hfx3_out, amrex::MultiFab *qfx3_out, const amrex::Real &elapsed_time, const amrex::Real &dt, const int &nstep) override
Definition: ERF_NOAHMP.cpp:264
amrex::Vector< int > LsmFluxMap
Definition: ERF_NOAHMP.H:250
void Set_LSM_Step(int step) override
Definition: ERF_NOAHMP.H:211
amrex::MultiFab * Lsm_Data_Ptr(const int &varIdx) override
Definition: ERF_NOAHMP.H:127
amrex::Vector< std::string > LsmFluxName
Definition: ERF_NOAHMP.H:256
amrex::Geometry m_geom
Definition: ERF_NOAHMP.H:259
amrex::Real m_dz_lsm
Definition: ERF_NOAHMP.H:283
amrex::MultiFab * Lsm_Flux_Ptr(const int &varIdx) override
Definition: ERF_NOAHMP.H:136
amrex::Real m_dt
Definition: ERF_NOAHMP.H:265
Definition: ERF_NullSurf.H:8
Definition: ERF_NOAHMP.H:23
@ sw_flux_dn
Definition: ERF_NOAHMP.H:33
@ sfc_emis
Definition: ERF_NOAHMP.H:27
@ sfc_alb_dir_vis
Definition: ERF_NOAHMP.H:28
@ sw_flux_dn_dif_nir
Definition: ERF_NOAHMP.H:37
@ sfc_alb_dif_nir
Definition: ERF_NOAHMP.H:31
@ sw_flux_dn_dir_vis
Definition: ERF_NOAHMP.H:34
@ sw_flux_dn_dir_nir
Definition: ERF_NOAHMP.H:35
@ lw_flux_dn
Definition: ERF_NOAHMP.H:38
@ cos_zenith_angle
Definition: ERF_NOAHMP.H:32
@ t_sfc
Definition: ERF_NOAHMP.H:26
@ NumVars
Definition: ERF_NOAHMP.H:39
@ sw_flux_dn_dif_vis
Definition: ERF_NOAHMP.H:36
@ sfc_alb_dir_nir
Definition: ERF_NOAHMP.H:29
@ sfc_alb_dif_vis
Definition: ERF_NOAHMP.H:30
Definition: ERF_NOAHMP.H:43
@ t_flux
Definition: ERF_NOAHMP.H:46
@ tau13
Definition: ERF_NOAHMP.H:48
@ q_flux
Definition: ERF_NOAHMP.H:47
@ NumVars
Definition: ERF_NOAHMP.H:50
@ tau23
Definition: ERF_NOAHMP.H:49
Definition: ERF_NOAHMP.H:55
@ v_phy
Definition: ERF_NOAHMP.H:58
@ glw
Definition: ERF_NOAHMP.H:63
@ qv_curr
Definition: ERF_NOAHMP.H:60
@ u_phy
Definition: ERF_NOAHMP.H:57
@ coszen
Definition: ERF_NOAHMP.H:64
@ t_phy
Definition: ERF_NOAHMP.H:59
@ swdown
Definition: ERF_NOAHMP.H:62
@ p8w
Definition: ERF_NOAHMP.H:61
@ NumComps
Definition: ERF_NOAHMP.H:65
Definition: ERF_NOAHMP.H:69
@ hfx
Definition: ERF_NOAHMP.H:71
@ tau_ns
Definition: ERF_NOAHMP.H:74
@ tau_ew
Definition: ERF_NOAHMP.H:73
@ tsk
Definition: ERF_NOAHMP.H:75
@ albsfcdir_vis
Definition: ERF_NOAHMP.H:77
@ NumComps
Definition: ERF_NOAHMP.H:81
@ albsfcdif_nir
Definition: ERF_NOAHMP.H:80
@ emiss
Definition: ERF_NOAHMP.H:76
@ albsfcdif_vis
Definition: ERF_NOAHMP.H:79
@ albsfcdir_nir
Definition: ERF_NOAHMP.H:78
@ lh
Definition: ERF_NOAHMP.H:72
Definition: ERF_DataStruct.H:141