ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ERF_ABLMost.H
Go to the documentation of this file.
1 #ifndef ERF_ABLMOST_H
2 #define ERF_ABLMOST_H
3 
4 #include <AMReX_Geometry.H>
5 #include <AMReX_ParmParse.H>
6 #include <AMReX_FArrayBox.H>
7 #include <AMReX_MultiFab.H>
8 #include <AMReX_iMultiFab.H>
9 #include <AMReX_Interpolater.H>
10 
11 #include <ERF_IndexDefines.H>
12 #include <ERF_Constants.H>
13 #include <ERF_MOSTAverage.H>
14 #include <ERF_MOSTStress.H>
15 #include <ERF_TerrainMetrics.H>
16 #include <ERF_PBLHeight.H>
17 
18 /** Monin-Obukhov surface layer profile
19  *
20  * van der Laan, P., Kelly, M. C., & Sørensen, N. N. (2017). A new k-epsilon
21  * model consistent with Monin-Obukhov similarity theory. Wind Energy,
22  * 20(3), 479–489. https://doi.org/10.1002/we.2017
23  *
24  * Consistent with Dyer (1974) formulation from page 57, Chapter 2, Modeling
25  * the vertical ABL structure in Modelling of Atmospheric Flow Fields,
26  * Demetri P Lalas and Corrado F Ratto, January 1996,
27  * https://doi.org/10.1142/2975.
28  */
29 class ABLMost
30 {
31 
32 public:
33 
34  // Constructor
35  explicit ABLMost (const amrex::Vector<amrex::Geometry>& geom,
36  bool& use_exp_most, bool& use_rot_most,
37  std::string a_pp_prefix,
38  amrex::Vector<std::unique_ptr<amrex::MultiFab>>& Qv_prim,
39  amrex::Vector<std::unique_ptr<amrex::MultiFab>>& z_phys_nd,
40  const TerrainType& a_terrain_type,
41  amrex::Real start_bdy_time = 0.0,
42  amrex::Real bdy_time_interval = 0.0)
43  : m_geom(geom),
44  m_exp_most(use_exp_most),
45  m_rotate(use_rot_most),
46  m_start_bdy_time(start_bdy_time),
47  m_bdy_time_interval(bdy_time_interval),
48  m_ma(geom,(z_phys_nd[0]!=nullptr),a_pp_prefix,a_terrain_type)
49  {
50  // We have a moisture model if Qv_prim is a valid pointer
51  use_moisture = (Qv_prim[0].get());
52 
53  // Get roughness
54  amrex::ParmParse pp("erf");
55  pp.query("most.z0", z0_const);
56 
57  // Specify how to compute the flux
58  if (use_rot_most) {
60  } else {
61  std::string flux_string{"moeng"};
62  pp.query("most.flux_type", flux_string);
63  if (flux_string == "donelan") {
65  } else if (flux_string == "moeng") {
67  } else if (flux_string == "custom") {
69  } else {
70  amrex::Abort("Undefined MOST flux type!");
71  }
72  }
73 
74  // Include w* to handle free convection (Beljaars 1995, QJRMS)
75  pp.query("most.include_wstar", m_include_wstar);
76 
77  std::string pblh_string{"none"};
78  pp.query("most.pblh_calc", pblh_string);
79  if (pblh_string == "none") {
81  } else if (pblh_string == "MYNN25") {
83  } else if (pblh_string == "MYNNEDMF") {
85  } else if (pblh_string == "YSU") {
87  } else {
88  amrex::Abort("Undefined PBLH calc type!");
89  }
90 
91  // Get surface temperature
92  auto erf_st = pp.query("most.surf_temp", surf_temp);
93 
94  // Custom type user must specify the fluxes
97  pp.query("most.ustar", custom_ustar);
98  pp.query("most.tstar", custom_tstar);
99  pp.query("most.qstar", custom_qstar);
100  if (custom_qstar != 0) {
101  AMREX_ASSERT_WITH_MESSAGE(use_moisture, "Specified custom MOST qv flux without moisture model!");
102  }
103  amrex::Print() << "Using specified ustar, tstar, qstar for MOST = "
104  << custom_ustar << " "
105  << custom_tstar << " "
106  << custom_qstar << std::endl;
107 
108  // Specify surface temperature or surface flux
109  } else {
110  if (erf_st) {
112  pp.query("most.surf_heating_rate", surf_heating_rate); // [K/h]
113  surf_heating_rate = surf_heating_rate / 3600.0; // [K/s]
114  if (pp.query("most.surf_temp_flux", surf_temp_flux)) {
115  amrex::Abort("Can only specify one of surf_temp_flux or surf_heating_rate");
116  }
117  } else {
118  pp.query("most.surf_temp_flux", surf_temp_flux);
119  if (pp.query("most.surf_heating_rate", surf_heating_rate)) {
120  amrex::Abort("Can only specify one of surf_temp_flux or surf_heating_rate");
121  }
122  if (std::abs(surf_temp_flux) > std::numeric_limits<amrex::Real>::epsilon()) {
124  } else {
126  }
127  }
128  }
129 
130  // Make sure the inputs file doesn't try to use most.roughness_type
131  std::string bogus_input;
132  if (pp.query("most.roughness_type", bogus_input) > 0) {
133  amrex::Abort("most.roughness_type is deprecated; use most.roughness_type_land and/or most.roughness_type_sea");
134  }
135 
136  // Specify how to compute the surface flux over land (if there is any)
137  std::string rough_land_string{"constant"};
138  pp.query("most.roughness_type_land", rough_land_string);
139  if (rough_land_string == "constant") {
141  } else {
142  amrex::Abort("Undefined MOST roughness type for land!");
143  }
144 
145  // Specify how to compute the surface flux over sea (if there is any)
146  std::string rough_sea_string{"charnock"};
147  pp.query("most.roughness_type_sea", rough_sea_string);
148  if (rough_sea_string == "charnock") {
150  pp.query("most.charnock_constant",cnk_a);
151  pp.query("most.charnock_viscosity",cnk_visc);
152  if (cnk_a > 0) {
153  amrex::Print() << "If there is water, Charnock relation with C_a=" << cnk_a
154  << (cnk_visc? " and viscosity" : "")
155  << " will be used"
156  << std::endl;
157  } else {
158  amrex::Print() << "If there is water, Charnock relation with variable Charnock parameter (COARE3.0)"
159  << (cnk_visc? " and viscosity" : "")
160  << " will be used"
161  << std::endl;
162  }
163  } else if (rough_sea_string == "coare3.0") {
165  amrex::Print() << "If there is water, Charnock relation with variable Charnock parameter (COARE3.0)"
166  << (cnk_visc? " and viscosity" : "")
167  << " will be used"
168  << std::endl;
169  cnk_a = -1;
170  } else if (rough_sea_string == "donelan") {
172  } else if (rough_sea_string == "modified_charnock") {
174  pp.query("most.modified_charnock_depth",depth);
175  } else if (rough_sea_string == "wave_coupled") {
177  } else if (rough_sea_string == "constant") {
179  } else {
180  amrex::Abort("Undefined MOST roughness type for sea!");
181  }
182  } // constructor
183 
184  void
185  make_MOST_at_level (const int& lev,
186  int nlevs,
187  const amrex::Vector<amrex::MultiFab*>& mfv,
188  std::unique_ptr<amrex::MultiFab>& Theta_prim,
189  std::unique_ptr<amrex::MultiFab>& Qv_prim,
190  std::unique_ptr<amrex::MultiFab>& Qr_prim,
191  std::unique_ptr<amrex::MultiFab>& z_phys_nd,
192  amrex::MultiFab* Hwave,
193  amrex::MultiFab* Lwave,
194  amrex::MultiFab* eddyDiffs,
195  amrex::Vector<amrex::MultiFab*> lsm_data,
196  amrex::Vector<amrex::MultiFab*> lsm_flux,
197  amrex::Vector<std::unique_ptr<amrex::MultiFab>>& sst_lev,
198  amrex::Vector<std::unique_ptr<amrex::iMultiFab>>& lmask_lev)
199  {
200  // Update MOST Average
201  m_ma.make_MOSTAverage_at_level(lev, mfv, Theta_prim, Qv_prim, Qr_prim, z_phys_nd);
202 
203  // Get CC vars
204  amrex::MultiFab& mf = *(mfv[0]);
205 
206  // Get surface temperature
207  amrex::ParmParse pp("erf");
208  auto erf_st = pp.query("most.surf_temp", surf_temp);
209 
210  // Do we have a time-varying surface roughness that needs to be saved?
211  if (lev == 0)
212  {
213  const int nghost = 0; // ghost cells not included
214  int lmask_min = lmask_min_reduce(*lmask_lev[0].get(), nghost);
215  amrex::ParallelDescriptor::ReduceIntMin(lmask_min);
216 
217  m_var_z0 = (lmask_min < 1) & (rough_type_sea != RoughCalcType::CONSTANT);
218  if (m_var_z0) {
219  std::string rough_sea_string{"charnock"};
220  pp.query("most.roughness_type_sea", rough_sea_string);
221  amrex::Print() << "Variable sea roughness (type " << rough_sea_string << ")" << std::endl;
222  }
223  }
224 
225  if ( (lev == 0) || (lev > nlevs-1) ) {
226  m_Hwave_lev.resize(nlevs);
227  m_Lwave_lev.resize(nlevs);
228  m_eddyDiffs_lev.resize(nlevs);
229 
230  m_lsm_data_lev.resize(nlevs);
231  m_lsm_flux_lev.resize(nlevs);
232 
233  m_sst_lev.resize(nlevs);
234  m_lmask_lev.resize(nlevs);
235 
236  // Size the MOST params for all levels
237  z_0.resize(nlevs);
238  u_star.resize(nlevs);
239  w_star.resize(nlevs);
240  t_star.resize(nlevs);
241  q_star.resize(nlevs);
242  t_surf.resize(nlevs);
243  olen.resize(nlevs);
244  pblh.resize(nlevs);
245  }
246 
247 
248  // Get pointers to SST and LANDMASK data
249  int nt_tot_sst = sst_lev.size();
250  m_sst_lev[lev].resize(nt_tot_sst);
251  for (int nt(0); nt<nt_tot_sst; ++nt) {
252  m_sst_lev[lev][nt] = sst_lev[nt].get();
253  }
254  int nt_tot_lmask = lmask_lev.size();
255  m_lmask_lev[lev].resize(nt_tot_lmask);
256  for (int nt(0); nt<nt_tot_lmask; ++nt) {
257  m_lmask_lev[lev][nt] = lmask_lev[nt].get();
258  }
259 
260  // Get pointers to wave data
261  m_Hwave_lev[lev] = Hwave;
262  m_Lwave_lev[lev] = Lwave;
263  m_eddyDiffs_lev[lev] = eddyDiffs;
264 
265  // Get pointers to LSM data and Fluxes
266  int nvar = lsm_data.size();
267  m_lsm_data_lev[lev].resize(nvar);
268  m_lsm_flux_lev[lev].resize(nvar);
269  for (int n(0); n<nvar; ++n) {
270  m_lsm_data_lev[lev][n] = lsm_data[n];
271  m_lsm_flux_lev[lev][n] = lsm_flux[n];
272  }
273 
274  // Check if there is a user-specified roughness file to be read
275  std::string fname;
276  bool read_z0 = false;
277  if ( (flux_type == FluxCalcType::MOENG) ||
279  read_z0 = pp.query("most.roughness_file_name", fname);
280  }
281 
282  // Attributes for MFs and FABs
283  //--------------------------------------------------------
284  // Create a 2D ba, dm, & ghost cells
285  amrex::BoxArray ba = mf.boxArray();
286  amrex::BoxList bl2d = ba.boxList();
287  for (auto& b : bl2d) {
288  b.setRange(2,0);
289  }
290  amrex::BoxArray ba2d(std::move(bl2d));
291  const amrex::DistributionMapping& dm = mf.DistributionMap();
292  const int ncomp = 1;
293  amrex::IntVect ng = mf.nGrowVect(); ng[2]=0;
294 
295  // Z0 heights FAB
296  //--------------------------------------------------------
297  amrex::Arena* Arena_Used = amrex::The_Arena();
298 #ifdef AMREX_USE_GPU
299  Arena_Used = amrex::The_Pinned_Arena();
300 #endif
301  amrex::Box bx = amrex::grow(m_geom[lev].Domain(),ng);
302  bx.setSmall(2,0);
303  bx.setBig(2,0);
304  z_0[lev].resize(bx,1,Arena_Used);
305  z_0[lev].setVal<amrex::RunOn::Device>(z0_const);
306  if (read_z0) read_custom_roughness(lev,fname);
307 
308  // 2D MFs for U*, T*, T_surf
309  //--------------------------------------------------------
310  u_star[lev] = std::make_unique<amrex::MultiFab>(ba2d,dm,ncomp,ng);
311  u_star[lev]->setVal(1.E34);
312 
313  w_star[lev] = std::make_unique<amrex::MultiFab>(ba2d,dm,ncomp,ng);
314  w_star[lev]->setVal(1.E34);
315 
316  t_star[lev] = std::make_unique<amrex::MultiFab>(ba2d,dm,ncomp,ng);
317  t_star[lev]->setVal(0.0); // default to neutral
318 
319  q_star[lev] = std::make_unique<amrex::MultiFab>(ba2d,dm,ncomp,ng);
320  q_star[lev]->setVal(0.0); // default to dry
321 
322  olen[lev] = std::make_unique<amrex::MultiFab>(ba2d,dm,ncomp,ng);
323  olen[lev]->setVal(1.E34);
324 
325  pblh[lev] = std::make_unique<amrex::MultiFab>(ba2d,dm,ncomp,ng);
326  pblh[lev]->setVal(1.E34);
327 
328  t_surf[lev] = std::make_unique<amrex::MultiFab>(ba2d,dm,ncomp,ng);
329 
330  // TODO: Do we want lsm_data to have theta at 0 index always?
331  // Do we want an external enum struct for indexing?
332  if (m_sst_lev[lev][0] || m_lsm_data_lev[lev][0]) {
333  // Valid SST or LSM data; t_surf set before computing fluxes (avoids extended lambda capture)
335  } else if (erf_st) {
336  t_surf[lev]->setVal(surf_temp);
337  } else {
338  t_surf[lev]->setVal(0.0);
339  }
340  }
341 
342  void
343  update_fluxes (const int& lev,
344  const amrex::Real& time,
345  int max_iters = 25);
346 
347  template <typename FluxIter>
348  void
349  compute_fluxes (const int& lev,
350  const int& max_iters,
351  const FluxIter& most_flux,
352  bool is_land);
353 
354  void
355  impose_most_bcs (const int& lev,
356  const amrex::Vector<amrex::MultiFab*>& mfs,
357  amrex::MultiFab* xxmom_flux,
358  amrex::MultiFab* yymom_flux,
359  amrex::MultiFab* zzmom_flux,
360  amrex::MultiFab* xymom_flux, amrex::MultiFab* yxmom_flux,
361  amrex::MultiFab* xzmom_flux, amrex::MultiFab* zxmom_flux,
362  amrex::MultiFab* yzmom_flux, amrex::MultiFab* zymom_flux,
363  amrex::MultiFab* xheat_flux,
364  amrex::MultiFab* yheat_flux,
365  amrex::MultiFab* zheat_flux,
366  amrex::MultiFab* xqv_flux,
367  amrex::MultiFab* yqv_flux,
368  amrex::MultiFab* zqv_flux,
369  amrex::MultiFab* z_phys);
370 
371  template <typename FluxCalc>
372  void
373  compute_most_bcs (const int& lev,
374  const amrex::Vector<amrex::MultiFab*>& mfs,
375  amrex::MultiFab* xxmom_flux,
376  amrex::MultiFab* yymom_flux,
377  amrex::MultiFab* zzmom_flux,
378  amrex::MultiFab* xymom_flux, amrex::MultiFab* yxmom_flux,
379  amrex::MultiFab* xzmom_flux, amrex::MultiFab* zxmom_flux,
380  amrex::MultiFab* yzmom_flux, amrex::MultiFab* zymom_flux,
381  amrex::MultiFab* xheat_flux,
382  amrex::MultiFab* yheat_flux,
383  amrex::MultiFab* zheat_flux,
384  amrex::MultiFab* xqv_flux,
385  amrex::MultiFab* yqv_flux,
386  amrex::MultiFab* zqv_flux,
387  amrex::MultiFab* z_phys,
388  const FluxCalc& flux_comp);
389 
390  void
391  time_interp_sst (const int& lev,
392  const amrex::Real& time);
393 
394  void
395  get_lsm_tsurf (const int& lev);
396 
397  /* wrapper around compute_pblh */
398  void
399  update_pblh (const int& lev,
400  amrex::Vector<amrex::Vector<amrex::MultiFab>>& vars,
401  amrex::MultiFab* z_phys_cc,
402  const int RhoQv_comp,
403  const int RhoQc_comp,
404  const int RhoQr_comp);
405 
406  template <typename PBLHeightEstimator>
407  void
408  compute_pblh (const int& lev,
409  amrex::Vector<amrex::Vector<amrex::MultiFab>>& vars,
410  amrex::MultiFab* z_phys_cc,
411  const PBLHeightEstimator& est,
412  const int RhoQv_comp,
413  const int RhoQc_comp,
414  const int RhoQr_comp);
415 
416  void
417  read_custom_roughness (const int& lev,
418  const std::string& fname);
419 
420  void
421  update_surf_temp (const amrex::Real& time)
422  {
423  if (surf_heating_rate != 0) {
424  int nlevs = m_geom.size();
425  for (int lev = 0; lev < nlevs; lev++)
426  {
427  t_surf[lev]->setVal(surf_temp + surf_heating_rate*time);
428  amrex::Print() << "Surface temp at t=" << time
429  << ": "
430  << surf_temp + surf_heating_rate*time
431  << std::endl;
432  }
433  }
434  }
435 
436  void
437  update_mac_ptrs (const int& lev,
438  amrex::Vector<amrex::Vector<amrex::MultiFab>>& vars_old,
439  amrex::Vector<std::unique_ptr<amrex::MultiFab>>& Theta_prim,
440  amrex::Vector<std::unique_ptr<amrex::MultiFab>>& Qv_prim,
441  amrex::Vector<std::unique_ptr<amrex::MultiFab>>& Qr_prim)
442  { m_ma.update_field_ptrs(lev,vars_old,Theta_prim,Qv_prim,Qr_prim); }
443 
444  const amrex::MultiFab*
445  get_u_star (const int& lev) { return u_star[lev].get(); }
446 
447  const amrex::MultiFab*
448  get_w_star (const int& lev) { return w_star[lev].get(); }
449 
450  const amrex::MultiFab*
451  get_t_star (const int& lev) { return t_star[lev].get(); }
452 
453  const amrex::MultiFab*
454  get_q_star (const int& lev) { return q_star[lev].get(); }
455 
456  const amrex::MultiFab*
457  get_olen (const int& lev) { return olen[lev].get(); }
458 
459  const amrex::MultiFab*
460  get_pblh (const int& lev) { return pblh[lev].get(); }
461 
462  const amrex::MultiFab*
463  get_mac_avg (const int& lev, int comp) { return m_ma.get_average(lev,comp); }
464 
465  const amrex::MultiFab*
466  get_t_surf (const int& lev) { return t_surf[lev].get(); }
467 
468  amrex::Real
469  get_zref () { return m_ma.get_zref(); }
470 
471  amrex::FArrayBox*
472  get_z0 (const int& lev) { return &z_0[lev]; }
473 
475 
476  const amrex::iMultiFab*
477  get_lmask(const int& lev) { return m_lmask_lev[lev][0]; }
478 
479  int
480  lmask_min_reduce (amrex::iMultiFab& lmask, const int& nghost)
481  {
482  int lmask_min = amrex::ReduceMin(lmask, nghost,
483  [=] AMREX_GPU_HOST_DEVICE (amrex::Box const& bx, amrex::Array4<int const> const& lm_arr) -> int
484  {
485  int locmin = std::numeric_limits<int>::max();
486  const auto lo = lbound(bx);
487  const auto hi = ubound(bx);
488  for (int j = lo.y; j <= hi.y; ++j) {
489  for (int i = lo.x; i <= hi.x; ++i) {
490  locmin = std::min(locmin, lm_arr(i,j,0));
491  }
492  }
493  return locmin;
494  });
495 
496  return lmask_min;
497  }
498 
499  enum struct FluxCalcType {
500  MOENG = 0, ///< Moeng functional form
501  DONELAN, ///< Donelan functional form
502  CUSTOM, ///< Custom constant flux functional form
503  ROTATE ///< Terrain rotation flux functional form
504  };
505 
506  enum struct ThetaCalcType {
507  ADIABATIC = 0,
508  HEAT_FLUX, ///< Heat-flux specified
509  SURFACE_TEMPERATURE ///< Surface temperature specified
510  };
511 
512  enum struct RoughCalcType {
513  CONSTANT = 0, ///< Constant z0
514  CHARNOCK,
516  DONELAN,
518  };
519 
520  enum struct PBLHeightCalcType {
521  None, MYNN25, YSU
522  };
523 
529 
530 private:
531  // Set in constructor
532  amrex::Vector<amrex::Geometry> m_geom;
533  bool m_exp_most = false;
534  bool m_rotate = false;
535  amrex::Real m_start_bdy_time;
536  amrex::Real m_bdy_time_interval;
537 
538  bool m_include_wstar = false;
539  amrex::Real z0_const{0.1};
540  amrex::Real surf_temp;
541  amrex::Real surf_heating_rate{0};
542  amrex::Real surf_temp_flux{0};
543  amrex::Real custom_ustar{0};
544  amrex::Real custom_tstar{0};
545  amrex::Real custom_qstar{0};
546  amrex::Real cnk_a{0.0185};
547  bool cnk_visc{false};
548  amrex::Real depth{30.0};
549  amrex::Vector<amrex::FArrayBox> z_0;
550  bool m_var_z0{false};
551 
553 
555  amrex::Vector<std::unique_ptr<amrex::MultiFab>> u_star;
556  amrex::Vector<std::unique_ptr<amrex::MultiFab>> w_star;
557  amrex::Vector<std::unique_ptr<amrex::MultiFab>> t_star;
558  amrex::Vector<std::unique_ptr<amrex::MultiFab>> q_star;
559  amrex::Vector<std::unique_ptr<amrex::MultiFab>> olen;
560  amrex::Vector<std::unique_ptr<amrex::MultiFab>> pblh;
561  amrex::Vector<std::unique_ptr<amrex::MultiFab>> t_surf;
562 
563  amrex::Vector<amrex::Vector<amrex::MultiFab*>> m_sst_lev;
564  amrex::Vector<amrex::Vector<amrex::iMultiFab*>> m_lmask_lev;
565  amrex::Vector<amrex::Vector<amrex::MultiFab*>> m_lsm_data_lev;
566  amrex::Vector<amrex::Vector<amrex::MultiFab*>> m_lsm_flux_lev;
567  amrex::Vector<amrex::MultiFab*> m_Hwave_lev;
568  amrex::Vector<amrex::MultiFab*> m_Lwave_lev;
569  amrex::Vector<amrex::MultiFab*> m_eddyDiffs_lev;
570 };
571 
572 #endif /* ABLMOST_H */
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real pp(amrex::Real y)
Definition: ERF_MicrophysicsUtils.H:219
Definition: ERF_ABLMost.H:30
amrex::Real m_bdy_time_interval
Definition: ERF_ABLMost.H:536
amrex::Vector< amrex::MultiFab * > m_eddyDiffs_lev
Definition: ERF_ABLMost.H:569
amrex::Vector< std::unique_ptr< amrex::MultiFab > > q_star
Definition: ERF_ABLMost.H:558
const amrex::MultiFab * get_u_star(const int &lev)
Definition: ERF_ABLMost.H:445
amrex::Vector< std::unique_ptr< amrex::MultiFab > > olen
Definition: ERF_ABLMost.H:559
const amrex::MultiFab * get_t_star(const int &lev)
Definition: ERF_ABLMost.H:451
amrex::Vector< std::unique_ptr< amrex::MultiFab > > w_star
Definition: ERF_ABLMost.H:556
amrex::Vector< amrex::FArrayBox > z_0
Definition: ERF_ABLMost.H:549
amrex::Vector< amrex::Geometry > m_geom
Definition: ERF_ABLMost.H:532
amrex::Real custom_ustar
Definition: ERF_ABLMost.H:543
amrex::Vector< std::unique_ptr< amrex::MultiFab > > t_surf
Definition: ERF_ABLMost.H:561
amrex::Real custom_qstar
Definition: ERF_ABLMost.H:545
ABLMost(const amrex::Vector< amrex::Geometry > &geom, bool &use_exp_most, bool &use_rot_most, std::string a_pp_prefix, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &Qv_prim, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &z_phys_nd, const TerrainType &a_terrain_type, amrex::Real start_bdy_time=0.0, amrex::Real bdy_time_interval=0.0)
Definition: ERF_ABLMost.H:35
amrex::Real depth
Definition: ERF_ABLMost.H:548
amrex::Real surf_heating_rate
Definition: ERF_ABLMost.H:541
void compute_pblh(const int &lev, amrex::Vector< amrex::Vector< amrex::MultiFab >> &vars, amrex::MultiFab *z_phys_cc, const PBLHeightEstimator &est, const int RhoQv_comp, const int RhoQc_comp, const int RhoQr_comp)
amrex::Vector< amrex::Vector< amrex::MultiFab * > > m_lsm_flux_lev
Definition: ERF_ABLMost.H:566
MOSTAverage m_ma
Definition: ERF_ABLMost.H:554
ThetaCalcType
Definition: ERF_ABLMost.H:506
@ SURFACE_TEMPERATURE
Surface temperature specified.
@ HEAT_FLUX
Heat-flux specified.
const amrex::iMultiFab * get_lmask(const int &lev)
Definition: ERF_ABLMost.H:477
int lmask_min_reduce(amrex::iMultiFab &lmask, const int &nghost)
Definition: ERF_ABLMost.H:480
bool have_variable_sea_roughness()
Definition: ERF_ABLMost.H:474
bool cnk_visc
Definition: ERF_ABLMost.H:547
amrex::Real m_start_bdy_time
Definition: ERF_ABLMost.H:535
const amrex::MultiFab * get_q_star(const int &lev)
Definition: ERF_ABLMost.H:454
amrex::Vector< std::unique_ptr< amrex::MultiFab > > pblh
Definition: ERF_ABLMost.H:560
amrex::FArrayBox * get_z0(const int &lev)
Definition: ERF_ABLMost.H:472
void update_mac_ptrs(const int &lev, amrex::Vector< amrex::Vector< amrex::MultiFab >> &vars_old, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &Theta_prim, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &Qv_prim, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &Qr_prim)
Definition: ERF_ABLMost.H:437
amrex::Vector< amrex::MultiFab * > m_Hwave_lev
Definition: ERF_ABLMost.H:567
void read_custom_roughness(const int &lev, const std::string &fname)
Definition: ERF_ABLMost.cpp:592
amrex::Real surf_temp
Definition: ERF_ABLMost.H:540
amrex::Real cnk_a
Definition: ERF_ABLMost.H:546
ThetaCalcType theta_type
Definition: ERF_ABLMost.H:525
void compute_fluxes(const int &lev, const int &max_iters, const FluxIter &most_flux, bool is_land)
Definition: ERF_ABLMost.cpp:145
PBLHeightCalcType pblh_type
Definition: ERF_ABLMost.H:528
FluxCalcType
Definition: ERF_ABLMost.H:499
@ MOENG
Moeng functional form.
@ CUSTOM
Custom constant flux functional form.
@ ROTATE
Terrain rotation flux functional form.
@ DONELAN
Donelan functional form.
amrex::Vector< amrex::Vector< amrex::MultiFab * > > m_lsm_data_lev
Definition: ERF_ABLMost.H:565
amrex::Real surf_temp_flux
Definition: ERF_ABLMost.H:542
void update_pblh(const int &lev, amrex::Vector< amrex::Vector< amrex::MultiFab >> &vars, amrex::MultiFab *z_phys_cc, const int RhoQv_comp, const int RhoQc_comp, const int RhoQr_comp)
Definition: ERF_ABLMost.cpp:561
const amrex::MultiFab * get_w_star(const int &lev)
Definition: ERF_ABLMost.H:448
void impose_most_bcs(const int &lev, const amrex::Vector< amrex::MultiFab * > &mfs, amrex::MultiFab *xxmom_flux, amrex::MultiFab *yymom_flux, amrex::MultiFab *zzmom_flux, amrex::MultiFab *xymom_flux, amrex::MultiFab *yxmom_flux, amrex::MultiFab *xzmom_flux, amrex::MultiFab *zxmom_flux, amrex::MultiFab *yzmom_flux, amrex::MultiFab *zymom_flux, amrex::MultiFab *xheat_flux, amrex::MultiFab *yheat_flux, amrex::MultiFab *zheat_flux, amrex::MultiFab *xqv_flux, amrex::MultiFab *yqv_flux, amrex::MultiFab *zqv_flux, amrex::MultiFab *z_phys)
Definition: ERF_ABLMost.cpp:211
amrex::Vector< amrex::Vector< amrex::iMultiFab * > > m_lmask_lev
Definition: ERF_ABLMost.H:564
const amrex::MultiFab * get_pblh(const int &lev)
Definition: ERF_ABLMost.H:460
void time_interp_sst(const int &lev, const amrex::Real &time)
Definition: ERF_ABLMost.cpp:493
RoughCalcType rough_type_land
Definition: ERF_ABLMost.H:526
bool m_rotate
Definition: ERF_ABLMost.H:534
amrex::Vector< amrex::MultiFab * > m_Lwave_lev
Definition: ERF_ABLMost.H:568
bool m_var_z0
Definition: ERF_ABLMost.H:550
RoughCalcType rough_type_sea
Definition: ERF_ABLMost.H:527
bool use_moisture
Definition: ERF_ABLMost.H:552
void compute_most_bcs(const int &lev, const amrex::Vector< amrex::MultiFab * > &mfs, amrex::MultiFab *xxmom_flux, amrex::MultiFab *yymom_flux, amrex::MultiFab *zzmom_flux, amrex::MultiFab *xymom_flux, amrex::MultiFab *yxmom_flux, amrex::MultiFab *xzmom_flux, amrex::MultiFab *zxmom_flux, amrex::MultiFab *yzmom_flux, amrex::MultiFab *zymom_flux, amrex::MultiFab *xheat_flux, amrex::MultiFab *yheat_flux, amrex::MultiFab *zheat_flux, amrex::MultiFab *xqv_flux, amrex::MultiFab *yqv_flux, amrex::MultiFab *zqv_flux, amrex::MultiFab *z_phys, const FluxCalc &flux_comp)
bool m_include_wstar
Definition: ERF_ABLMost.H:538
bool m_exp_most
Definition: ERF_ABLMost.H:533
amrex::Vector< std::unique_ptr< amrex::MultiFab > > t_star
Definition: ERF_ABLMost.H:557
const amrex::MultiFab * get_t_surf(const int &lev)
Definition: ERF_ABLMost.H:466
amrex::Vector< std::unique_ptr< amrex::MultiFab > > u_star
Definition: ERF_ABLMost.H:555
PBLHeightCalcType
Definition: ERF_ABLMost.H:520
amrex::Real z0_const
Definition: ERF_ABLMost.H:539
FluxCalcType flux_type
Definition: ERF_ABLMost.H:524
void update_surf_temp(const amrex::Real &time)
Definition: ERF_ABLMost.H:421
amrex::Vector< amrex::Vector< amrex::MultiFab * > > m_sst_lev
Definition: ERF_ABLMost.H:563
void get_lsm_tsurf(const int &lev)
Definition: ERF_ABLMost.cpp:528
amrex::Real get_zref()
Definition: ERF_ABLMost.H:469
RoughCalcType
Definition: ERF_ABLMost.H:512
@ CONSTANT
Constant z0.
const amrex::MultiFab * get_olen(const int &lev)
Definition: ERF_ABLMost.H:457
const amrex::MultiFab * get_mac_avg(const int &lev, int comp)
Definition: ERF_ABLMost.H:463
void update_fluxes(const int &lev, const amrex::Real &time, int max_iters=25)
Definition: ERF_ABLMost.cpp:12
void make_MOST_at_level(const int &lev, int nlevs, const amrex::Vector< amrex::MultiFab * > &mfv, std::unique_ptr< amrex::MultiFab > &Theta_prim, std::unique_ptr< amrex::MultiFab > &Qv_prim, std::unique_ptr< amrex::MultiFab > &Qr_prim, std::unique_ptr< amrex::MultiFab > &z_phys_nd, amrex::MultiFab *Hwave, amrex::MultiFab *Lwave, amrex::MultiFab *eddyDiffs, amrex::Vector< amrex::MultiFab * > lsm_data, amrex::Vector< amrex::MultiFab * > lsm_flux, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &sst_lev, amrex::Vector< std::unique_ptr< amrex::iMultiFab >> &lmask_lev)
Definition: ERF_ABLMost.H:185
amrex::Real custom_tstar
Definition: ERF_ABLMost.H:544
Definition: ERF_MOSTAverage.H:13
amrex::Real get_zref() const
Definition: ERF_MOSTAverage.H:103
const amrex::MultiFab * get_average(const int &lev, const int &comp) const
Definition: ERF_MOSTAverage.H:100
void update_field_ptrs(const int &lev, amrex::Vector< amrex::Vector< amrex::MultiFab >> &vars_old, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &Theta_prim, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &Qv_prim, amrex::Vector< std::unique_ptr< amrex::MultiFab >> &Qr_prim)
Definition: ERF_MOSTAverage.cpp:244
void make_MOSTAverage_at_level(const int &lev, const amrex::Vector< amrex::MultiFab * > &vars_old, std::unique_ptr< amrex::MultiFab > &Theta_prim, std::unique_ptr< amrex::MultiFab > &Qv_prim, std::unique_ptr< amrex::MultiFab > &Qr_prim, std::unique_ptr< amrex::MultiFab > &z_phys_nd)
Definition: ERF_MOSTAverage.cpp:68