ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_TurbStruct.H
Go to the documentation of this file.
1 #ifndef ERF_TURB_STRUCT_H_
2 #define ERF_TURB_STRUCT_H_
3 
4 #include <ERF_MYNNStruct.H>
5 
6 /**
7  * @brief Large-eddy simulation closure type.
8  */
9 AMREX_ENUM(LESType, None, Smagorinsky, Smagorinsky2D, Deardorff);
10 
11 /**
12  * @brief Reynolds-averaged turbulence closure type.
13  */
14 AMREX_ENUM(RANSType, None, kEqn);
15 
16 /**
17  * @brief Planetary boundary-layer closure type.
18  */
19 AMREX_ENUM(PBLType, None, MYJ, MYNN25, MYNNEDMF, YSU, YSUNew, MRF, SHOC, EAMXX_SHOC, NATIVE_SHOC);
20 
21 /**
22  * @brief Thermodynamic variable used for stability stratification.
23  */
24 AMREX_ENUM(StratType, theta, thetav, thetal);
25 
26 /**
27  * @brief Query a scalar or per-level input value.
28  * @tparam T Value type accepted by ParmParse::query.
29  * @param pp ParmParse object to query.
30  * @param query_string Input key to query.
31  * @param query_var Destination value for the requested level.
32  * @param lev AMR level index.
33  * @param maxlev Maximum AMR level configured for the run.
34  * @return ParmParse query result, or zero if the key is absent.
35  */
36 template <typename T>
37 int
39  const amrex::ParmParse& pp,
40  const char* query_string,
41  T& query_var,
42  const int lev,
43  const int maxlev)
44 {
45  int count = pp.countval(query_string);
46  if (count == 0) {
47  return 0; // nothing to do
48  } else if (count == 1) {
49  // In this case, we assume the same value is used at every level
50  return pp.query(query_string, query_var);
51  } else if (count >= maxlev + 1) {
52  // In this case, there may be more values than levels so we
53  // will just read the number of values we need and ignore the
54  // extra levels
55  return pp.query(query_string, query_var, lev);
56  } else {
57  // In this case, there is more than one value AND there
58  // are more levels than values; as an example, if max_level = 2
59  // but count = 2 so we have three levels but only two values --
60  // it is not clear how to interpret this so we abort
61  amrex::Error(
62  "For parmparse variable " + pp.prefixedName(query_string) +
63  ": if specified, specify once total or at least once for each level");
64  return 0; // avoid compiler warning
65  }
66 }
67 
68 /**
69  * @brief Query a scalar or per-level enum input value using case-insensitive matching.
70  * @tparam T Enum type accepted by ParmParse::query_enum_case_insensitive.
71  * @param pp ParmParse object to query.
72  * @param query_string Input key to query.
73  * @param query_var Destination enum value for the requested level.
74  * @param lev AMR level index.
75  * @param maxlev Maximum AMR level configured for the run.
76  * @return ParmParse query result, or zero if the key is absent.
77  */
78 template <typename T>
79 int
81  const amrex::ParmParse& pp,
82  const char* query_string,
83  T& query_var,
84  const int lev,
85  const int maxlev)
86 {
87  int count = pp.countval(query_string);
88  if (count == 0) {
89  return 0; // nothing to do
90  } else if (count == 1) {
91  // In this case, we assume the same value is used at every level
92  return pp.query_enum_case_insensitive(query_string, query_var);
93  } else if (count >= maxlev + 1) {
94  // In this case, there may be more values than levels so we
95  // will just read the number of values we need and ignore the
96  // extra levels
97  return pp.query_enum_case_insensitive(query_string, query_var, lev);
98  } else {
99  // In this case, there is more than one value AND there
100  // are more levels than values; as an example, if max_level = 2
101  // but count = 2 so we have three levels but only two values --
102  // it is not clear how to interpret this so we abort
103  amrex::Error(
104  "For parmparse variable " + pp.prefixedName(query_string) +
105  ": if specified, specify once total or at least once for each level");
106  return 0; // avoid compiler warning
107  }
108 }
109 
110 /**
111  * Container holding quantities related to turbulence parametrizations
112  */
114 {
115 public:
116  /**
117  * @brief Read turbulence options for one AMR level from the input parameter database.
118  * @param lev AMR level index.
119  * @param max_level Maximum AMR level configured for the run.
120  * @param pp_prefix ParmParse prefix for the ERF input namespace.
121  */
122  void init_params (int lev, int max_level, std::string pp_prefix)
123  {
124  amrex::ParmParse pp(pp_prefix);
125 
126  // Which LES closure?
127  query_one_or_per_level(pp, "les_type", les_type, lev, max_level);
128 
129  // Handle 2-D Smag
130  if (les_type == LESType::Smagorinsky2D) {
131  les_type = LESType::Smagorinsky;
132  smag2d = true;
133  }
134 
135  // Which RANS closure?
136  query_one_or_per_level(pp, "rans_type", rans_type, lev, max_level);
137 
138  if ((rans_type != RANSType::None) && (les_type != LESType::None)) {
139  amrex::Error("Hybrid RANS-LES not implemented");
140  }
141 
142  // Which PBL Closure
143  query_one_or_per_level_enum_case_insensitive(pp, "pbl_type", pbl_type, lev, max_level);
144  if (pbl_type == PBLType::SHOC) {
145  static bool warned_legacy_shoc = false;
146  if (!warned_legacy_shoc) {
147  amrex::Warning("erf.pbl_type = SHOC is deprecated; use erf.pbl_type = EAMXX_SHOC");
148  warned_legacy_shoc = true;
149  }
150  pbl_type = PBLType::EAMXX_SHOC;
151  }
152 
153  // Do some more stuff for PBL Modeling
154  if (pbl_type != PBLType::None) {
155  // Check for compatibility between PBL, LES, Molec Transport
156  if (les_type != LESType::None) {
157  amrex::Print() << "Selected a PBL model and an LES model: "
158  << "Using PBL for vertical transport, LES for horizontal"
159  << std::endl;
160  }
161  if (les_type == LESType::Smagorinsky) {
162  if (!smag2d)
163  amrex::Error("If using Smagorinsky with a PBL model, the 2-D "
164  "formulation should be used");
165  } else if (les_type == LESType::Deardorff) {
166  amrex::Error(
167  "It is not recommended to use Deardorff LES and a PBL model");
168  }
169 
170  if (pbl_type == PBLType::MYNN25 || pbl_type == PBLType::MYNNEDMF) {
171  query_one_or_per_level(pp, "pbl_mynn_A1", pbl_mynn.A1, lev, max_level);
172  query_one_or_per_level(pp, "pbl_mynn_A2", pbl_mynn.A2, lev, max_level);
173  query_one_or_per_level(pp, "pbl_mynn_B1", pbl_mynn.B1, lev, max_level);
174  query_one_or_per_level(pp, "pbl_mynn_B2", pbl_mynn.B2, lev, max_level);
175  query_one_or_per_level(pp, "pbl_mynn_C1", pbl_mynn.C1, lev, max_level);
176  query_one_or_per_level(pp, "pbl_mynn_C2", pbl_mynn.C2, lev, max_level);
177  query_one_or_per_level(pp, "pbl_mynn_C3", pbl_mynn.C3, lev, max_level);
178  query_one_or_per_level(pp, "pbl_mynn_C4", pbl_mynn.C4, lev, max_level);
179  query_one_or_per_level(pp, "pbl_mynn_C5", pbl_mynn.C5, lev, max_level);
184  pp, "pbl_mynn_diffuse_moistvars", pbl_mynn.diffuse_moistvars, lev,
185  max_level);
187  pp, "pbl_mynn_SMmin", pbl_mynn.SMmin, lev, max_level);
189  pp, "pbl_mynn_SMmax", pbl_mynn.SMmax, lev, max_level);
191  pp, "pbl_mynn_SHmin", pbl_mynn.SHmin, lev, max_level);
193  pp, "pbl_mynn_SHmax", pbl_mynn.SHmax, lev, max_level);
195  pp, "pbl_mynn_SQfactor", pbl_mynn.SQfac, lev, max_level);
196  } else if (pbl_type == PBLType::YSU || pbl_type == PBLType::YSUNew) {
198  pp, "pbl_ysu_coriolis_freq", pbl_ysu_coriolis_freq, lev, max_level);
200  pp, "pbl_ysu_use_consistent_coriolis",
201  pbl_ysu_use_consistent_coriolis, lev, max_level);
203  pp, "pbl_ysu_force_over_water", pbl_ysu_force_over_water, lev,
204  max_level);
206  pp, "pbl_ysu_land_Ribcr", pbl_ysu_land_Ribcr, lev, max_level);
208  pp, "pbl_ysu_unst_Ribcr", pbl_ysu_unst_Ribcr, lev, max_level);
210  pp, "enable_ysu_liquid_theta", enable_ysu_liquid_theta, lev, max_level);
212  pp, "enable_ysu_countergradient", enable_ysu_countergradient, lev, max_level);
214  pp, "enable_ysu_terrain_pblh_floor", enable_ysu_terrain_pblh_floor, lev, max_level);
216  pp, "enable_ysu_sat_limiter", enable_ysu_sat_limiter, lev, max_level);
218  pp, "enable_ysu_topdown", enable_ysu_topdown, lev, max_level);
220  pp, "enable_ysu_entrainment", enable_ysu_entrainment, lev, max_level);
222  pp, "enable_ysu_cloud_pblh", enable_ysu_cloud_pblh, lev, max_level);
224  pp, "enable_mrf_unbounded_vpert", enable_mrf_unbounded_vpert, lev, max_level);
226  pp, "ysu_qcloud_threshold", ysu_qcloud_threshold, lev, max_level);
228  pp, "ysu_moistvars", ysu_moistvars, lev, max_level);
230  pp, "pbl_ysunew_highres_bounds", pbl_ysunew_highres_bounds, lev, max_level);
231  } else if (pbl_type == PBLType::MRF) {
233  pp, "pbl_mrf_coriolis_freq", pbl_mrf_coriolis_freq, lev, max_level);
235  pp, "pbl_mrf_Ribcr", pbl_mrf_Ribcr, lev, max_level);
237  pp, "pbl_mrf_const_b", pbl_mrf_const_b, lev, max_level);
238  query_one_or_per_level(pp, "pbl_mrf_sf", pbl_mrf_sf, lev, max_level);
240  pp, "mrf_moistvars", mrf_moistvars, lev, max_level);
242  pp, "enable_mrf_countergradient", enable_mrf_countergradient, lev, max_level);
244  pp, "enable_mrf_cloud_adjustment", enable_mrf_cloud_adjustment, lev, max_level);
246  pp, "pbl_mrf_highres_bounds", pbl_mrf_highres_bounds, lev, max_level);
248  pp, "enable_mrf_unbounded_vpert", enable_mrf_unbounded_vpert, lev, max_level);
250  pp, "pbl_mrf_use_zero_ri_extent", pbl_mrf_use_zero_ri_extent, lev, max_level);
251  // Scale-aware PBL-LES blending parameters.
253  pp, "pbl_blend_length", pbl_blend_length, lev, max_level);
255  pp, "pbl_blend_cs", pbl_blend_cs, lev, max_level);
257  pp, "pbl_blend_c_max", pbl_blend_c_max, lev, max_level);
259  pp, "pbl_blend_use_smag", pbl_blend_use_smag, lev, max_level);
260  } else if (pbl_type == PBLType::SHOC) {
261 #ifndef ERF_USE_SHOC
262  amrex::Abort("You set use_shoc to true but didn't build with SHOC; you must rebuild the executable");
263  }
264 #endif
265  if (uses_eamxx_shoc()) {
266 #ifndef ERF_USE_EAMXX_SHOC
267  amrex::Abort("PBLType::EAMXX_SHOC requested, but ERF was not built with ERF_ENABLE_EAMXX_SHOC=ON");
268 #endif
269  }
270 
272  std::string zlo_bc = "none";
273  amrex::ParmParse pp_bc("zlo");
274  pp_bc.get("type",zlo_bc);
275  if (amrex::toLower(zlo_bc) != "surface_layer") {
276  amrex::Abort("You must use the surface_layer BC at zlo with the selected PBL.");
277  }
278  }
279  }
280 
281  // Flags for QKE/TKE equation
282  if (pbl_type == PBLType::MYJ || pbl_type == PBLType::MYNN25 || pbl_type == PBLType::MYNNEDMF) {
283  // Add sources/sinks to QKE/TKE? (MYJ does this inline)
284  if (pbl_type == PBLType::MYNN25 || pbl_type == PBLType::MYNNEDMF) {
285  use_pbl_tke = true;
286  }
287  // Advect QKE/TKE?
288  query_one_or_per_level(pp, "advect_tke" , advect_tke , lev, max_level);
289  // Apply numerical diffusion to QKE/TKE?
290  query_one_or_per_level(pp, "diffuse_tke_3D", diffuse_tke_3D, lev, max_level);
291  }
292 
293  // There is a default value of 1e-6 but the user can override the value here,
294  // and in addition can add perturbational values. and in addition can add perturbational values.
295  pp.query("tke_min",tke_min);
296 
297  // LES constants...
298  query_one_or_per_level(pp, "Cs", Cs, lev, max_level);
299 
300  query_one_or_per_level(pp, "Pr_t", Pr_t, lev, max_level);
301  query_one_or_per_level(pp, "Sc_t", Sc_t, lev, max_level);
302 
303  // Compute relevant forms of diffusion parameters
304  Pr_t_inv = one / Pr_t;
305  Sc_t_inv = one / Sc_t;
306 
307  if (les_type == LESType::Deardorff) {
308  query_one_or_per_level(pp, "Ck", Ck, lev, max_level);
309  query_one_or_per_level(pp, "Ce", Ce, lev, max_level);
310  query_one_or_per_level(pp, "Ce_wall", Ce_wall, lev, max_level);
311  }
312 
313  // To quantify atmospheric stability for subgrid modeling
314  query_one_or_per_level(pp, "thermal_stratification", strat_type, lev, max_level);
315  if (strat_type == StratType::theta) {
316  amrex::Print() << "Thermal stratification based on gradient of potential temperature" << std::endl;
317  } else if (strat_type == StratType::thetav) {
318  amrex::Print() << "Thermal stratification based on gradient of virtual potential temperature" << std::endl;
319  } else if (strat_type == StratType::thetal) {
320  amrex::Print() << "Thermal stratification based on gradient of linearized liquid-water potential temperature" << std::endl;
321  }
322 
323  // k-eqn constants
324  query_one_or_per_level(pp, "Cmu0", Cmu0, lev, max_level);
325  query_one_or_per_level(pp, "Cb", Cb, lev, max_level);
326  query_one_or_per_level(pp, "Rt_crit", Rt_crit, lev, max_level);
327  query_one_or_per_level(pp, "Rt_min", Rt_min, lev, max_level);
328  query_one_or_per_level(pp, "max_geom_lscale", l_g_max, lev, max_level);
329  query_one_or_per_level(pp, "dirichlet_k", dirichlet_k, lev, max_level);
330 
331  // Common inputs (LES or RANS)
332  if (!query_one_or_per_level(pp, "sigma_k", sigma_k, lev, max_level) && rans_type == RANSType::kEqn) {
333  amrex::Print() << "Overriding default sigma_k for k-eqn RANS" << std::endl;
334  sigma_k = one;
335  };
336  query_one_or_per_level(pp, "theta_ref", theta_ref, lev, max_level);
337 
338  query_one_or_per_level(pp, "mix_isotropic", mix_isotropic, lev, max_level);
339  query_one_or_per_level(pp, "use_Ri_correction", use_Ri_correction, lev, max_level);
340  query_one_or_per_level(pp, "Ri_crit", Ri_crit, lev, max_level);
341 
342  // Set common flags
343  use_kturb =
344  ((les_type != LESType::None) || (rans_type != RANSType::None) ||
345  (pbl_type != PBLType::None));
346  use_keqn =
347  ((les_type == LESType::Deardorff) || (rans_type == RANSType::kEqn));
348  use_tke =
349  ((les_type == LESType::Deardorff) || (rans_type == RANSType::kEqn) ||
350  (pbl_type == PBLType::MYJ) || (pbl_type == PBLType::MYNN25) ||
351  (pbl_type == PBLType::MYNNEDMF) || uses_shoc_family());
352 
353  if (use_tke) {
354  query_one_or_per_level(pp, "init_tke_from_ustar", init_tke_from_ustar, lev, max_level);
355  }
356 
357  // Validate inputs
358  if (les_type == LESType::Smagorinsky) {
359  if (Cs == 0) {
360  amrex::Error("Need to specify Cs for Smagorsinky LES");
361  }
362  if (smag2d && mix_isotropic) {
363  amrex::Print() << "Turning off mix_isotropic for 2-D Smagorinsky" << std::endl;
364  mix_isotropic = false;
365  }
366  }
367  }
368 
369  /**
370  * @brief Validate turbulence options against physical boundary conditions.
371  * @param phys_bc_type Physical boundary-condition types.
372  */
373  void check_params (amrex::GpuArray<ERF_BC, AMREX_SPACEDIM*2>& phys_bc_type)
374  {
375  // BC compatibility
377  phys_bc_type[amrex::Orientation(amrex::Direction::z,amrex::Orientation::low)] != ERF_BC::surface_layer ) {
378  amrex::Abort("The selected PBL model requires MOST at lower boundary");
379  }
380  if ( (les_type == LESType::Deardorff) && (Ce_wall > 0) &&
381  (phys_bc_type[amrex::Orientation(amrex::Direction::z,amrex::Orientation::low)] != ERF_BC::surface_layer) &&
382  (phys_bc_type[amrex::Orientation(amrex::Direction::z,amrex::Orientation::low)] != ERF_BC::slip_wall) &&
383  (phys_bc_type[amrex::Orientation(amrex::Direction::z,amrex::Orientation::low)] != ERF_BC::no_slip_wall) )
384  {
385  amrex::Warning("Deardorff LES assumes wall at zlo when applying Ce_wall");
386  }
387  }
388 
389  /**
390  * @brief Print turbulence settings for one AMR level.
391  * @param lev AMR level index.
392  */
393  void display (int lev)
394  {
395  amrex::Print() << "Turbulence Settings at level " << lev << std::endl;
396 
397  if (
398  les_type == LESType::None && rans_type == RANSType::None &&
399  pbl_type == PBLType::None) {
400  amrex::Print() << " Using DNS model at level " << lev << std::endl;
401  } else if (les_type == LESType::Smagorinsky) {
402  if (smag2d) {
403  amrex::Print() << " Using 2D Smagorinsky LES model at level " << lev << std::endl;
404  } else {
405  amrex::Print() << " Using Smagorinsky LES model at level " << lev << std::endl;
406  }
407  if (use_Ri_correction) {
408  amrex::Print() << " Smagorinsky uses Richardson number correction with Ri_crit = "
409  << Ri_crit << std::endl;
410  }
411  } else if (les_type == LESType::Deardorff) {
412  amrex::Print() << " Using Deardorff LES model at level " << lev << std::endl;
413  } else if (rans_type == RANSType::kEqn) {
414  amrex::Print()
415  << " Using Axell & Liungman one-equation RANS k model at level " << lev
416  << std::endl;
417  } else if (pbl_type == PBLType::MYJ) {
418  amrex::Print() << " Using MYJ PBL model at level " << lev << std::endl;
419  } else if (pbl_type == PBLType::MYNN25) {
420  amrex::Print() << " Using MYNN2.5 PBL model at level " << lev << std::endl;
421  } else if (pbl_type == PBLType::MYNNEDMF) {
422  amrex::Print() << " Using MYNNEDMF PBL model at level " << lev << std::endl;
423  } else if (pbl_type == PBLType::YSU) {
424  amrex::Print() << " Using YSU PBL model at level " << lev << std::endl;
425  } else if (pbl_type == PBLType::YSUNew) {
426  amrex::Print() << " Using YSU PBL model at level " << lev << std::endl;
427  } else if (pbl_type == PBLType::MRF) {
428  amrex::Print() << " Using MRF PBL model at level " << lev << std::endl;
429  } else if (pbl_type == PBLType::EAMXX_SHOC) {
430  amrex::Print() << " Using EAMxx SHOC PBL model at level " << lev << std::endl;
431  } else if (pbl_type == PBLType::NATIVE_SHOC) {
432  amrex::Print() << " Using native SHOC PBL model at level " << lev << std::endl;
433  } else {
434  amrex::Error("Unknown turbulence model");
435  }
436 
437  if (les_type != LESType::None) {
438  if (les_type == LESType::Smagorinsky) {
439  amrex::Print() << " Cs : " << Cs << std::endl;
440  }
441  if (les_type == LESType::Deardorff) {
442  amrex::Print() << " Ce : " << Ce << std::endl;
443  amrex::Print() << " Ce at wall : " << Ce_wall << std::endl;
444  amrex::Print() << " Ck : " << Ck << std::endl;
445  amrex::Print() << " sigma_k : " << sigma_k << std::endl;
446 
447  // Sullivan et al 1994, Eqn 14
448  amrex::Real Cs_equiv = std::sqrt(Ck * std::sqrt(Ck / Ce));
449  amrex::Print() << " equivalent Cs : " << Cs_equiv
450  << std::endl;
451  }
452  amrex::Print() << " isotropic mixing : " << mix_isotropic
453  << std::endl;
454  }
455 
456  if (rans_type != RANSType::None) {
457  if (rans_type == RANSType::kEqn) {
458  amrex::Print() << "Cmu0 : " << Cmu0 << std::endl;
459  amrex::Print() << "sigma_k : " << sigma_k << std::endl;
460  amrex::Print() << "Cb : " << Cb << std::endl;
461  amrex::Print() << "Rt_crit : " << Rt_crit << std::endl;
462  amrex::Print() << "Rt_min : " << Rt_min << std::endl;
463  amrex::Print() << "max_geom_lscale : " << l_g_max << std::endl;
464  }
465  }
466 
467  if ((les_type == LESType::Deardorff) ||
468  (rans_type == RANSType::kEqn)) {
469  if (theta_ref > 0) {
470  amrex::Print() << " reference theta : " << theta_ref << std::endl;
471  } else {
472  amrex::Print() << " reference theta : n/a" << std::endl;
473  }
474  }
475 
476  if ((les_type != LESType::None) || (rans_type != RANSType::None)) {
477  amrex::Print() << " Pr_t : " << Pr_t << std::endl;
478  amrex::Print() << " Sc_t : " << Sc_t << std::endl;
479  }
480 
481  if (pbl_type == PBLType::MYNN25 || pbl_type == PBLType::MYNNEDMF) {
482  amrex::Print() << " pbl_mynn_A1 : " << pbl_mynn.A1 << std::endl;
483  amrex::Print() << " pbl_mynn_A2 : " << pbl_mynn.A2 << std::endl;
484  amrex::Print() << " pbl_mynn_B1 : " << pbl_mynn.B1 << std::endl;
485  amrex::Print() << " pbl_mynn_B2 : " << pbl_mynn.B2 << std::endl;
486  amrex::Print() << " pbl_mynn_C1 : " << pbl_mynn.C1 << std::endl;
487  amrex::Print() << " pbl_mynn_C2 : " << pbl_mynn.C2 << std::endl;
488  amrex::Print() << " pbl_mynn_C3 : " << pbl_mynn.C3 << std::endl;
489  amrex::Print() << " pbl_mynn_C4 : " << pbl_mynn.C4 << std::endl;
490  amrex::Print() << " pbl_mynn_C5 : " << pbl_mynn.C5 << std::endl;
491  } else if (pbl_type == PBLType::YSU || pbl_type == PBLType::YSUNew) {
492  amrex::Print() << " pbl_ysu_coriolis_freq : "
493  << pbl_ysu_coriolis_freq << std::endl;
494  amrex::Print() << " pbl_ysu_use_consistent_coriolis : "
495  << pbl_ysu_use_consistent_coriolis << std::endl;
496  amrex::Print() << " pbl_ysu_force_over_water : "
497  << pbl_ysu_force_over_water << std::endl;
498  amrex::Print() << " pbl_ysu_land_Ribcr : "
499  << pbl_ysu_land_Ribcr << std::endl;
500  amrex::Print() << " pbl_ysu_unst_Ribcr : "
501  << pbl_ysu_unst_Ribcr << std::endl;
502  amrex::Print() << " enable_ysu_liquid_theta : "
503  << enable_ysu_liquid_theta << std::endl;
504  amrex::Print() << " enable_ysu_countergradient : "
505  << enable_ysu_countergradient << std::endl;
506  amrex::Print() << " enable_ysu_terrain_pblh_floor : "
507  << enable_ysu_terrain_pblh_floor << std::endl;
508  amrex::Print() << " enable_ysu_sat_limiter : "
509  << enable_ysu_sat_limiter << std::endl;
510  amrex::Print() << " enable_ysu_topdown : "
511  << enable_ysu_topdown << std::endl;
512  amrex::Print() << " enable_ysu_entrainment : "
513  << enable_ysu_entrainment << std::endl;
514  amrex::Print() << " enable_ysu_cloud_pblh : "
515  << enable_ysu_cloud_pblh << std::endl;
516  amrex::Print() << " ysu_qcloud_threshold : "
517  << ysu_qcloud_threshold << std::endl;
518  amrex::Print() << " ysu_moistvars : "
519  << ysu_moistvars << std::endl;
520  amrex::Print() << " pbl_ysunew_highres_bounds : "
521  << pbl_ysunew_highres_bounds << std::endl;
522  amrex::Print() << " enable_mrf_unbounded_vpert : "
523  << enable_mrf_unbounded_vpert << std::endl;
524  } else if (pbl_type == PBLType::MRF) {
525  amrex::Print() << " pbl_mrf_coriolis_freq : " << pbl_mrf_coriolis_freq
526  << std::endl;
527  amrex::Print() << " pbl_mrf_Ribcr : " << pbl_mrf_Ribcr
528  << std::endl;
529  amrex::Print() << " pbl_mrf_const_b : " << pbl_mrf_const_b
530  << std::endl;
531  amrex::Print() << " pbl_mrf_sf : " << pbl_mrf_sf
532  << std::endl;
533  amrex::Print() << " mrf_moistvars : " << mrf_moistvars
534  << std::endl;
535  amrex::Print() << " enable_mrf_countergradient : " << enable_mrf_countergradient
536  << std::endl;
537  amrex::Print() << " enable_mrf_cloud_adjustment : " << enable_mrf_cloud_adjustment
538  << std::endl;
539  amrex::Print() << " pbl_mrf_highres_bounds : " << pbl_mrf_highres_bounds
540  << std::endl;
541  amrex::Print() << " enable_mrf_unbounded_vpert : " << enable_mrf_unbounded_vpert
542  << std::endl;
543  amrex::Print() << " pbl_mrf_use_zero_ri_extent : " << pbl_mrf_use_zero_ri_extent
544  << std::endl;
545  amrex::Print() << " pbl_blend_length : " << pbl_blend_length
546  << std::endl;
547  amrex::Print() << " pbl_blend_cs : " << pbl_blend_cs
548  << std::endl;
549  amrex::Print() << " pbl_blend_c_max : " << pbl_blend_c_max
550  << std::endl;
551  amrex::Print() << " pbl_blend_use_smag : " << pbl_blend_use_smag
552  << std::endl;
553  }
554  }
555 
556  // LES model
557  LESType les_type = LESType::None;
558 
559  // Turbulent Prandtl number
562 
563  // Turbulent Schmidt number
566 
567  // Smagorinsky
569  bool smag2d = false;
570 
571  // Deardorff
573  amrex::Real Ce_wall = zero; // if > 0, then set Ce to this at k=0
575 
576  // k-eqn RANS coefficients (Axell & Liungman 2001)
581  amrex::Real l_g_max = amrex::Real(30.0); // ~ kappa * (amrex::Real(0.1) * zi)
582 
583  // Deardorff or k-eqn RANS
584  // - diffusivity of tke is 1/sigma_k times the eddy viscosity
586  // - reference potential temperature used to quantify the stratification in
587  // a stable region
589  // - how to quantify stratification effects
591 
592  // Anisotropic length scales
593  bool mix_isotropic = true;
594 
595  bool use_Ri_correction = true;
597 
598  // RANS type
599  RANSType rans_type = RANSType::None;
600 
601  bool dirichlet_k = false;
602 
603  // PBL model
604  PBLType pbl_type = PBLType::None;
605 
606  /**
607  * @brief Query whether this level uses the EAMxx SHOC PBL scheme.
608  * @return True if PBLType::EAMXX_SHOC is selected.
609  */
610  bool uses_eamxx_shoc () const noexcept
611  {
612  return pbl_type == PBLType::EAMXX_SHOC;
613  }
614 
615  /**
616  * @brief Query whether this level uses the native SHOC PBL scheme.
617  * @return True if PBLType::NATIVE_SHOC is selected.
618  */
619  bool uses_native_shoc () const noexcept
620  {
621  return pbl_type == PBLType::NATIVE_SHOC;
622  }
623 
624  /**
625  * @brief Query whether this level uses any SHOC-family PBL scheme.
626  * @return True if native or EAMxx SHOC is selected.
627  */
628  bool uses_shoc_family () const noexcept
629  {
630  return uses_eamxx_shoc() || uses_native_shoc();
631  }
632 
633  /**
634  * @brief Query whether the selected PBL scheme requires surface-layer boundary conditions.
635  * @return True if the PBL scheme requires a lower surface-layer boundary.
636  */
637  bool pbl_requires_surface_layer () const noexcept
638  {
639  return (pbl_type == PBLType::MYNN25) ||
640  (pbl_type == PBLType::MYNNEDMF) ||
641  (pbl_type == PBLType::YSU) ||
642  (pbl_type == PBLType::YSUNew) ||
643  (pbl_type == PBLType::MRF) ||
645  }
646 
647  /**
648  * @brief Query whether the selected PBL scheme suppresses microphysics condensation.
649  * @return True when the PBL scheme owns condensation handling.
650  */
652  {
653  return uses_shoc_family();
654  }
655 
657  MYNNLevel2 pbl_mynn_level2; // limiting in the decaying turbulence regime
658 
659  // Common Flags
660  bool use_kturb = false; // Any turbulence modeling?
661  bool use_keqn =
662  false; // Any microscale turbulence modeling (LES, RANS) with TKE closure?
663  // Then need to populate SmnSmn_lev for production term.
664  bool use_pbl_tke =
665  false; // Any mesoscale turbulence modeling (PBL) with TKE closure?
666  bool use_tke = false; // Any TKE closure (meso or microscale)?
667 
668  // Initialize TKE/QKE with linear profiles whose surface values are a
669  // function of the friction velocity calculated by the surface layer scheme
670  // (e.g., as done in MYNN-EDMF)
671  bool init_tke_from_ustar = false;
672 
673  // This is the value of tke_min in WRF 4.5
675 
676  // Model coefficients - YSU
677  // TODO: Add parmparse for all of these above
679  amrex::Real(1.0e-4); // 1e-4 is hardcoded in WRF, we let the user specify or take the
680  // value from ERF coriolis forcing
682  false; // ignore input pbl_ysu_coriolis_freq, take value from ERF coriolis
683  // forcing instead
685  false; // Force YSU to act as if it is over water regardless of other inputs
686  // (for testing)
688  fourth; // Critical Bulk Richardson number of Land for stable conditions
690  zero; // Critical Bulk Richardson number for unstable conditions
692  true; // if true, use liquid-water virtual potential temperature in YSU stability
694  true; // if true, apply YSU-style HGAMT/HGAMQ/HGAMU/HGAMV countergradient correction
696  true; // if true, apply terrain-following floor on PBL height
698  false; // if true, apply saturation limiter to moisture countergradient
700  true; // if true, enable top-down mixing for cloud-topped boundary layers
702  true; // if true, enable entrainment layer parameterization
704  true; // if true, enable cloud-based PBL height detection
706  amrex::Real(1.0e-4); // Cloud liquid water threshold for YSUNew (kg/kg)
707  bool ysu_moistvars = false; // if true, adds turbulence to moisture
708  bool pbl_ysunew_highres_bounds = false; // if true, apply high-resolution grid-dependent diffusivity bounds
709  // Model coefficients - MRF
711  amrex::Real pbl_mrf_Ribcr = amrex::Real(0.5); // Critical Bulk Richardson number for MRF PBL model
712  amrex::Real pbl_mrf_const_b = amrex::Real(7.8); // Constant b in MRF PBL model, used to compute the PBL height
713  amrex::Real pbl_mrf_sf = amrex::Real(0.1); // MRF surface flux, used to compute the PBL height
714  // Scale-aware PBL-LES blending parameters.
715  // Boutle et al. (2014): https://doi.org/10.1175/MWR-D-13-00229.1
716  // Set pbl_blend_length = 0 to disable (default). Recovers original behaviour.
717  amrex::Real pbl_blend_length = amrex::Real(0.0); ///< Boutle blending length L [m]. 0 = off.
718  amrex::Real pbl_blend_cs = amrex::Real(0.17); ///< Smagorinsky coeff for K_h ceiling.
719  amrex::Real pbl_blend_c_max = amrex::Real(0.1); ///< Power-law ceiling coeff [m^(2/3)/s].
720  bool pbl_blend_use_smag = true; ///< Use Smagorinsky ceiling (else power-law).
721  bool mrf_moistvars = false; // if true, adds turbulence to moisture
722  bool enable_mrf_countergradient = false; // if true, apply WRF-style HGAMT/HGAMQ correction to PBL height
723  bool enable_mrf_cloud_adjustment = false; // if true, apply cloud-aware stability function adjustments in MRF scheme
724  bool pbl_mrf_highres_bounds = false; // if true, apply high-resolution grid-dependent diffusivity bounds instead of global forecast bounds
725  bool enable_mrf_unbounded_vpert = false; // if true, does not limit VPERT to GAMCRT
726  bool pbl_mrf_use_zero_ri_extent = false; // if true, use Ri=0 (pbli_zero_arr) for K-profile extent; default false uses Ri=0.5 corrector (pbli_arr) for WRF compatibility
727  // MYNN2.5 PBL model
728  // TKE/QKE stuff
729  bool advect_tke = true; // if MYNN2.5 PBL is used default is turb transport in
730  // Z-direction only
731  bool diffuse_tke_3D = true; // if numerical diffusion is turned on
732 };
733 
734 /**
735  * @var TurbChoice::les_type
736  * @brief Selected LES closure.
737  * @var TurbChoice::Pr_t
738  * @brief Turbulent Prandtl number.
739  * @var TurbChoice::Pr_t_inv
740  * @brief Inverse turbulent Prandtl number.
741  * @var TurbChoice::Sc_t
742  * @brief Turbulent Schmidt number.
743  * @var TurbChoice::Sc_t_inv
744  * @brief Inverse turbulent Schmidt number.
745  * @var TurbChoice::Cs
746  * @brief Smagorinsky model coefficient.
747  * @var TurbChoice::smag2d
748  * @brief Whether the 2-D Smagorinsky formulation is used.
749  * @var TurbChoice::Ce
750  * @brief Deardorff dissipation coefficient.
751  * @var TurbChoice::Ce_wall
752  * @brief Wall value for the Deardorff dissipation coefficient.
753  * @var TurbChoice::Ck
754  * @brief Deardorff eddy-viscosity coefficient.
755  * @var TurbChoice::Cmu0
756  * @brief One-equation RANS Cmu0 coefficient.
757  * @var TurbChoice::Cb
758  * @brief One-equation RANS buoyancy coefficient.
759  * @var TurbChoice::Rt_crit
760  * @brief Critical turbulent Reynolds number.
761  * @var TurbChoice::Rt_min
762  * @brief Minimum turbulent Reynolds number.
763  * @var TurbChoice::l_g_max
764  * @brief Maximum geometric length scale.
765  * @var TurbChoice::sigma_k
766  * @brief TKE diffusivity coefficient denominator.
767  * @var TurbChoice::theta_ref
768  * @brief Reference potential temperature for stable stratification.
769  * @var TurbChoice::strat_type
770  * @brief Thermodynamic variable used for stability stratification.
771  * @var TurbChoice::mix_isotropic
772  * @brief Whether subgrid mixing uses isotropic length scales.
773  * @var TurbChoice::use_Ri_correction
774  * @brief Whether Richardson-number correction is applied.
775  * @var TurbChoice::Ri_crit
776  * @brief Critical Richardson number for stability correction.
777  * @var TurbChoice::rans_type
778  * @brief Selected RANS closure.
779  * @var TurbChoice::dirichlet_k
780  * @brief Whether TKE uses Dirichlet boundary treatment.
781  * @var TurbChoice::pbl_type
782  * @brief Selected PBL closure.
783  * @var TurbChoice::pbl_mynn
784  * @brief MYNN level-2.5 closure coefficients.
785  * @var TurbChoice::pbl_mynn_level2
786  * @brief MYNN level-2 closure coefficients for limiting.
787  * @var TurbChoice::use_kturb
788  * @brief Whether any turbulence model is active.
789  * @var TurbChoice::use_keqn
790  * @brief Whether a microscale TKE closure is active.
791  * @var TurbChoice::use_pbl_tke
792  * @brief Whether a mesoscale PBL TKE closure is active.
793  * @var TurbChoice::use_tke
794  * @brief Whether any TKE or QKE closure is active.
795  * @var TurbChoice::init_tke_from_ustar
796  * @brief Whether initial TKE/QKE profiles are based on surface friction velocity.
797  * @var TurbChoice::tke_min
798  * @brief Minimum TKE/QKE value.
799  * @var TurbChoice::pbl_ysu_coriolis_freq
800  * @brief Coriolis frequency used by YSU-family PBL schemes.
801  * @var TurbChoice::pbl_ysu_use_consistent_coriolis
802  * @brief Whether YSU uses the ERF Coriolis frequency.
803  * @var TurbChoice::pbl_ysu_force_over_water
804  * @brief Whether YSU is forced to use over-water behavior.
805  * @var TurbChoice::pbl_ysu_land_Ribcr
806  * @brief Critical bulk Richardson number over land for stable YSU conditions.
807  * @var TurbChoice::pbl_ysu_unst_Ribcr
808  * @brief Critical bulk Richardson number for unstable YSU conditions.
809  * @var TurbChoice::enable_ysu_liquid_theta
810  * @brief Whether YSU uses liquid-water virtual potential temperature for stability.
811  * @var TurbChoice::enable_ysu_countergradient
812  * @brief Whether YSU countergradient corrections are enabled.
813  * @var TurbChoice::enable_ysu_terrain_pblh_floor
814  * @brief Whether YSU applies a terrain-following PBL-height floor.
815  * @var TurbChoice::enable_ysu_sat_limiter
816  * @brief Whether YSU applies a saturation limiter to moisture countergradient terms.
817  * @var TurbChoice::enable_ysu_topdown
818  * @brief Whether YSU top-down mixing is enabled.
819  * @var TurbChoice::enable_ysu_entrainment
820  * @brief Whether YSU entrainment-layer parameterization is enabled.
821  * @var TurbChoice::enable_ysu_cloud_pblh
822  * @brief Whether YSU cloud-based PBL-height detection is enabled.
823  * @var TurbChoice::ysu_qcloud_threshold
824  * @brief Cloud liquid water threshold for YSUNew [kg/kg].
825  * @var TurbChoice::ysu_moistvars
826  * @brief Whether YSU applies turbulence to moisture variables.
827  * @var TurbChoice::pbl_ysunew_highres_bounds
828  * @brief Whether YSUNew applies high-resolution grid-dependent diffusivity bounds.
829  * @var TurbChoice::pbl_mrf_coriolis_freq
830  * @brief Coriolis frequency used by the MRF PBL scheme.
831  * @var TurbChoice::pbl_mrf_Ribcr
832  * @brief Critical bulk Richardson number for the MRF PBL scheme.
833  * @var TurbChoice::pbl_mrf_const_b
834  * @brief MRF constant used to compute PBL height.
835  * @var TurbChoice::pbl_mrf_sf
836  * @brief MRF surface flux value used to compute PBL height.
837  * @var TurbChoice::mrf_moistvars
838  * @brief Whether MRF applies turbulence to moisture variables.
839  * @var TurbChoice::enable_mrf_countergradient
840  * @brief Whether MRF countergradient corrections are enabled.
841  * @var TurbChoice::enable_mrf_cloud_adjustment
842  * @brief Whether MRF cloud-aware stability adjustments are enabled.
843  * @var TurbChoice::pbl_mrf_highres_bounds
844  * @brief Whether MRF applies high-resolution grid-dependent diffusivity bounds.
845  * @var TurbChoice::enable_mrf_unbounded_vpert
846  * @brief Whether MRF leaves VPERT unlimited by GAMCRT.
847  * @var TurbChoice::pbl_mrf_use_zero_ri_extent
848  * @brief Whether MRF uses the Ri=0 K-profile extent.
849  * @var TurbChoice::advect_tke
850  * @brief Whether TKE/QKE is advected.
851  * @var TurbChoice::diffuse_tke_3D
852  * @brief Whether three-dimensional numerical diffusion is applied to TKE/QKE.
853  */
854 #endif
constexpr amrex::Real three
Definition: ERF_Constants.H:11
constexpr amrex::Real one
Definition: ERF_Constants.H:9
constexpr amrex::Real fourth
Definition: ERF_Constants.H:14
constexpr amrex::Real zero
Definition: ERF_Constants.H:8
@ no_slip_wall
@ surface_layer
ParmParse pp("prob")
Real T
Definition: ERF_InitCustomPert_Bubble.H:106
amrex::Real Real
Definition: ERF_ShocInterface.H:19
AMREX_ENUM(LESType, None, Smagorinsky, Smagorinsky2D, Deardorff)
Large-eddy simulation closure type.
int query_one_or_per_level_enum_case_insensitive(const amrex::ParmParse &pp, const char *query_string, T &query_var, const int lev, const int maxlev)
Query a scalar or per-level enum input value using case-insensitive matching.
Definition: ERF_TurbStruct.H:80
int query_one_or_per_level(const amrex::ParmParse &pp, const char *query_string, T &query_var, const int lev, const int maxlev)
Query a scalar or per-level input value.
Definition: ERF_TurbStruct.H:38
@ theta
Definition: ERF_SLM.H:20
Definition: ERF_MYNNStruct.H:11
amrex::Real SMmax
Definition: ERF_MYNNStruct.H:58
amrex::Real SHmax
Definition: ERF_MYNNStruct.H:60
amrex::Real SQfac
Definition: ERF_MYNNStruct.H:54
amrex::Real C4
Definition: ERF_MYNNStruct.H:50
amrex::Real C1
Definition: ERF_MYNNStruct.H:47
amrex::Real C3
Definition: ERF_MYNNStruct.H:49
amrex::Real C2
Definition: ERF_MYNNStruct.H:48
amrex::Real A2
Definition: ERF_MYNNStruct.H:44
amrex::Real SHmin
Definition: ERF_MYNNStruct.H:59
amrex::Real B1
Definition: ERF_MYNNStruct.H:45
amrex::Real B2
Definition: ERF_MYNNStruct.H:46
amrex::Real C5
Definition: ERF_MYNNStruct.H:51
amrex::Real SMmin
Definition: ERF_MYNNStruct.H:57
amrex::Real A1
Definition: ERF_MYNNStruct.H:43
bool diffuse_moistvars
Definition: ERF_MYNNStruct.H:67
Definition: ERF_MYNNStruct.H:70
void init_coeffs(amrex::Real A1_lvl25, amrex::Real A2_lvl25, amrex::Real B1, amrex::Real B2, amrex::Real C1, amrex::Real C2, amrex::Real C3, amrex::Real, amrex::Real C5)
Definition: ERF_MYNNStruct.H:71
Definition: ERF_TurbStruct.H:114
bool advect_tke
Whether TKE/QKE is advected.
Definition: ERF_TurbStruct.H:729
bool pbl_ysu_force_over_water
Whether YSU is forced to use over-water behavior.
Definition: ERF_TurbStruct.H:684
StratType strat_type
Thermodynamic variable used for stability stratification.
Definition: ERF_TurbStruct.H:590
amrex::Real Ce
Deardorff dissipation coefficient.
Definition: ERF_TurbStruct.H:572
bool enable_mrf_unbounded_vpert
Whether MRF leaves VPERT unlimited by GAMCRT.
Definition: ERF_TurbStruct.H:725
amrex::Real Sc_t
Turbulent Schmidt number.
Definition: ERF_TurbStruct.H:564
MYNNLevel2 pbl_mynn_level2
MYNN level-2 closure coefficients for limiting.
Definition: ERF_TurbStruct.H:657
bool diffuse_tke_3D
Whether three-dimensional numerical diffusion is applied to TKE/QKE.
Definition: ERF_TurbStruct.H:731
bool use_tke
Whether any TKE or QKE closure is active.
Definition: ERF_TurbStruct.H:666
amrex::Real sigma_k
TKE diffusivity coefficient denominator.
Definition: ERF_TurbStruct.H:585
bool use_Ri_correction
Whether Richardson-number correction is applied.
Definition: ERF_TurbStruct.H:595
bool pbl_ysu_use_consistent_coriolis
Whether YSU uses the ERF Coriolis frequency.
Definition: ERF_TurbStruct.H:681
amrex::Real pbl_blend_length
Boutle blending length L [m]. 0 = off.
Definition: ERF_TurbStruct.H:717
amrex::Real Ck
Deardorff eddy-viscosity coefficient.
Definition: ERF_TurbStruct.H:574
bool pbl_mrf_use_zero_ri_extent
Whether MRF uses the Ri=0 K-profile extent.
Definition: ERF_TurbStruct.H:726
amrex::Real Ce_wall
Wall value for the Deardorff dissipation coefficient.
Definition: ERF_TurbStruct.H:573
RANSType rans_type
Selected RANS closure.
Definition: ERF_TurbStruct.H:599
void check_params(amrex::GpuArray< ERF_BC, AMREX_SPACEDIM *2 > &phys_bc_type)
Validate turbulence options against physical boundary conditions.
Definition: ERF_TurbStruct.H:373
amrex::Real theta_ref
Reference potential temperature for stable stratification.
Definition: ERF_TurbStruct.H:588
amrex::Real Sc_t_inv
Inverse turbulent Schmidt number.
Definition: ERF_TurbStruct.H:565
amrex::Real l_g_max
Maximum geometric length scale.
Definition: ERF_TurbStruct.H:581
bool enable_mrf_cloud_adjustment
Whether MRF cloud-aware stability adjustments are enabled.
Definition: ERF_TurbStruct.H:723
bool use_keqn
Whether a microscale TKE closure is active.
Definition: ERF_TurbStruct.H:661
bool uses_eamxx_shoc() const noexcept
Query whether this level uses the EAMxx SHOC PBL scheme.
Definition: ERF_TurbStruct.H:610
bool enable_ysu_entrainment
Whether YSU entrainment-layer parameterization is enabled.
Definition: ERF_TurbStruct.H:701
bool enable_ysu_sat_limiter
Whether YSU applies a saturation limiter to moisture countergradient terms.
Definition: ERF_TurbStruct.H:697
bool enable_ysu_cloud_pblh
Whether YSU cloud-based PBL-height detection is enabled.
Definition: ERF_TurbStruct.H:703
amrex::Real pbl_mrf_const_b
MRF constant used to compute PBL height.
Definition: ERF_TurbStruct.H:712
bool mrf_moistvars
Whether MRF applies turbulence to moisture variables.
Definition: ERF_TurbStruct.H:721
amrex::Real pbl_blend_cs
Smagorinsky coeff for K_h ceiling.
Definition: ERF_TurbStruct.H:718
bool uses_shoc_family() const noexcept
Query whether this level uses any SHOC-family PBL scheme.
Definition: ERF_TurbStruct.H:628
amrex::Real ysu_qcloud_threshold
Cloud liquid water threshold for YSUNew [kg/kg].
Definition: ERF_TurbStruct.H:705
amrex::Real pbl_blend_c_max
Power-law ceiling coeff [m^(2/3)/s].
Definition: ERF_TurbStruct.H:719
bool init_tke_from_ustar
Whether initial TKE/QKE profiles are based on surface friction velocity.
Definition: ERF_TurbStruct.H:671
bool enable_mrf_countergradient
Whether MRF countergradient corrections are enabled.
Definition: ERF_TurbStruct.H:722
bool enable_ysu_countergradient
Whether YSU countergradient corrections are enabled.
Definition: ERF_TurbStruct.H:693
bool mix_isotropic
Whether subgrid mixing uses isotropic length scales.
Definition: ERF_TurbStruct.H:593
bool uses_native_shoc() const noexcept
Query whether this level uses the native SHOC PBL scheme.
Definition: ERF_TurbStruct.H:619
bool dirichlet_k
Whether TKE uses Dirichlet boundary treatment.
Definition: ERF_TurbStruct.H:601
LESType les_type
Selected LES closure.
Definition: ERF_TurbStruct.H:557
void init_params(int lev, int max_level, std::string pp_prefix)
Read turbulence options for one AMR level from the input parameter database.
Definition: ERF_TurbStruct.H:122
bool enable_ysu_topdown
Whether YSU top-down mixing is enabled.
Definition: ERF_TurbStruct.H:699
bool pbl_mrf_highres_bounds
Whether MRF applies high-resolution grid-dependent diffusivity bounds.
Definition: ERF_TurbStruct.H:724
amrex::Real Rt_min
Minimum turbulent Reynolds number.
Definition: ERF_TurbStruct.H:580
bool pbl_blend_use_smag
Use Smagorinsky ceiling (else power-law).
Definition: ERF_TurbStruct.H:720
MYNNLevel25 pbl_mynn
MYNN level-2.5 closure coefficients.
Definition: ERF_TurbStruct.H:656
amrex::Real pbl_ysu_land_Ribcr
Critical bulk Richardson number over land for stable YSU conditions.
Definition: ERF_TurbStruct.H:687
amrex::Real Cb
One-equation RANS buoyancy coefficient.
Definition: ERF_TurbStruct.H:578
amrex::Real Ri_crit
Critical Richardson number for stability correction.
Definition: ERF_TurbStruct.H:596
amrex::Real pbl_ysu_unst_Ribcr
Critical bulk Richardson number for unstable YSU conditions.
Definition: ERF_TurbStruct.H:689
amrex::Real Rt_crit
Critical turbulent Reynolds number.
Definition: ERF_TurbStruct.H:579
bool pbl_suppresses_microphysics_condensation() const noexcept
Query whether the selected PBL scheme suppresses microphysics condensation.
Definition: ERF_TurbStruct.H:651
amrex::Real pbl_mrf_Ribcr
Critical bulk Richardson number for the MRF PBL scheme.
Definition: ERF_TurbStruct.H:711
amrex::Real pbl_mrf_sf
MRF surface flux value used to compute PBL height.
Definition: ERF_TurbStruct.H:713
amrex::Real Cmu0
One-equation RANS Cmu0 coefficient.
Definition: ERF_TurbStruct.H:577
amrex::Real Cs
Smagorinsky model coefficient.
Definition: ERF_TurbStruct.H:568
amrex::Real Pr_t
Turbulent Prandtl number.
Definition: ERF_TurbStruct.H:560
amrex::Real pbl_mrf_coriolis_freq
Coriolis frequency used by the MRF PBL scheme.
Definition: ERF_TurbStruct.H:710
bool pbl_ysunew_highres_bounds
Whether YSUNew applies high-resolution grid-dependent diffusivity bounds.
Definition: ERF_TurbStruct.H:708
amrex::Real tke_min
Minimum TKE/QKE value.
Definition: ERF_TurbStruct.H:674
amrex::Real pbl_ysu_coriolis_freq
Coriolis frequency used by YSU-family PBL schemes.
Definition: ERF_TurbStruct.H:678
void display(int lev)
Print turbulence settings for one AMR level.
Definition: ERF_TurbStruct.H:393
bool use_kturb
Whether any turbulence model is active.
Definition: ERF_TurbStruct.H:660
bool ysu_moistvars
Whether YSU applies turbulence to moisture variables.
Definition: ERF_TurbStruct.H:707
PBLType pbl_type
Selected PBL closure.
Definition: ERF_TurbStruct.H:604
amrex::Real Pr_t_inv
Inverse turbulent Prandtl number.
Definition: ERF_TurbStruct.H:561
bool enable_ysu_terrain_pblh_floor
Whether YSU applies a terrain-following PBL-height floor.
Definition: ERF_TurbStruct.H:695
bool enable_ysu_liquid_theta
Whether YSU uses liquid-water virtual potential temperature for stability.
Definition: ERF_TurbStruct.H:691
bool smag2d
Whether the 2-D Smagorinsky formulation is used.
Definition: ERF_TurbStruct.H:569
bool pbl_requires_surface_layer() const noexcept
Query whether the selected PBL scheme requires surface-layer boundary conditions.
Definition: ERF_TurbStruct.H:637
bool use_pbl_tke
Whether a mesoscale PBL TKE closure is active.
Definition: ERF_TurbStruct.H:664