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