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 
197  // SQ = SQfac*SM, so its bound is tied to SHmax and SQfac; the default member
198  // initializer was evaluated before either could be overridden here.
200 
201  } else if (pbl_type == PBLType::YSU || pbl_type == PBLType::YSUNew) {
203  pp, "pbl_ysu_coriolis_freq", pbl_ysu_coriolis_freq, lev, max_level);
205  pp, "pbl_ysu_use_consistent_coriolis",
206  pbl_ysu_use_consistent_coriolis, lev, max_level);
208  pp, "pbl_ysu_force_over_water", pbl_ysu_force_over_water, lev,
209  max_level);
211  pp, "pbl_ysu_land_Ribcr", pbl_ysu_land_Ribcr, lev, max_level);
213  pp, "pbl_ysu_unst_Ribcr", pbl_ysu_unst_Ribcr, lev, max_level);
215  pp, "enable_ysu_liquid_theta", enable_ysu_liquid_theta, lev, max_level);
217  pp, "enable_ysu_countergradient", enable_ysu_countergradient, lev, max_level);
219  pp, "enable_ysu_terrain_pblh_floor", enable_ysu_terrain_pblh_floor, lev, max_level);
221  pp, "enable_ysu_sat_limiter", enable_ysu_sat_limiter, lev, max_level);
223  pp, "enable_ysu_topdown", enable_ysu_topdown, lev, max_level);
225  pp, "enable_ysu_entrainment", enable_ysu_entrainment, lev, max_level);
227  pp, "enable_ysu_cloud_pblh", enable_ysu_cloud_pblh, lev, max_level);
229  pp, "enable_mrf_unbounded_vpert", enable_mrf_unbounded_vpert, lev, max_level);
231  pp, "ysu_qcloud_threshold", ysu_qcloud_threshold, lev, max_level);
233  pp, "ysu_moistvars", ysu_moistvars, lev, max_level);
235  pp, "pbl_ysunew_highres_bounds", pbl_ysunew_highres_bounds, lev, max_level);
236  } else if (pbl_type == PBLType::MRF) {
238  pp, "pbl_mrf_coriolis_freq", pbl_mrf_coriolis_freq, lev, max_level);
240  pp, "pbl_mrf_Ribcr", pbl_mrf_Ribcr, lev, max_level);
242  pp, "pbl_mrf_const_b", pbl_mrf_const_b, lev, max_level);
243  query_one_or_per_level(pp, "pbl_mrf_sf", pbl_mrf_sf, lev, max_level);
245  pp, "mrf_moistvars", mrf_moistvars, lev, max_level);
247  pp, "enable_mrf_countergradient", enable_mrf_countergradient, lev, max_level);
249  pp, "enable_mrf_cloud_adjustment", enable_mrf_cloud_adjustment, lev, max_level);
251  pp, "pbl_mrf_highres_bounds", pbl_mrf_highres_bounds, lev, max_level);
253  pp, "enable_mrf_unbounded_vpert", enable_mrf_unbounded_vpert, lev, max_level);
255  pp, "pbl_mrf_use_zero_ri_extent", pbl_mrf_use_zero_ri_extent, lev, max_level);
256  // Scale-aware PBL-LES blending parameters.
258  pp, "pbl_blend_length", pbl_blend_length, lev, max_level);
260  pp, "pbl_blend_cs", pbl_blend_cs, lev, max_level);
262  pp, "pbl_blend_c_max", pbl_blend_c_max, lev, max_level);
264  pp, "pbl_blend_use_smag", pbl_blend_use_smag, lev, max_level);
265  } else if (pbl_type == PBLType::SHOC) {
266 #ifndef ERF_USE_SHOC
267  amrex::Abort("You set use_shoc to true but didn't build with SHOC; you must rebuild the executable");
268  }
269 #endif
270  if (uses_eamxx_shoc()) {
271 #ifndef ERF_USE_EAMXX_SHOC
272  amrex::Abort("PBLType::EAMXX_SHOC requested, but ERF was not built with ERF_ENABLE_EAMXX_SHOC=ON");
273 #endif
274  }
275 
277  std::string zlo_bc = "none";
278  amrex::ParmParse pp_bc("zlo");
279  pp_bc.get("type",zlo_bc);
280  if (amrex::toLower(zlo_bc) != "surface_layer") {
281  amrex::Abort("You must use the surface_layer BC at zlo with the selected PBL.");
282  }
283  }
284  }
285 
286  // Flags for QKE/TKE equation
287  if (pbl_type == PBLType::MYJ || pbl_type == PBLType::MYNN25 || pbl_type == PBLType::MYNNEDMF) {
288  // Add sources/sinks to QKE/TKE? (MYJ does this inline)
289  if (pbl_type == PBLType::MYNN25 || pbl_type == PBLType::MYNNEDMF) {
290  use_pbl_tke = true;
291  }
292  // Advect QKE/TKE?
293  query_one_or_per_level(pp, "advect_tke" , advect_tke , lev, max_level);
294  // Apply numerical diffusion to QKE/TKE?
295  query_one_or_per_level(pp, "diffuse_tke_3D", diffuse_tke_3D, lev, max_level);
296  }
297 
298  // There is a default value of 1e-6 but the user can override the value here,
299  // and in addition can add perturbational values. and in addition can add perturbational values.
300  pp.queryAdd("tke_min",tke_min);
301 
302  // LES constants...
303  query_one_or_per_level(pp, "Cs", Cs, lev, max_level);
304 
305  query_one_or_per_level(pp, "Pr_t", Pr_t, lev, max_level);
306  query_one_or_per_level(pp, "Sc_t", Sc_t, lev, max_level);
307 
308  // Compute relevant forms of diffusion parameters
309  Pr_t_inv = one / Pr_t;
310  Sc_t_inv = one / Sc_t;
311 
312  if (les_type == LESType::Deardorff) {
313  query_one_or_per_level(pp, "Ck", Ck, lev, max_level);
314  query_one_or_per_level(pp, "Ce", Ce, lev, max_level);
315  query_one_or_per_level(pp, "Ce_wall", Ce_wall, lev, max_level);
316  }
317 
318  // To quantify atmospheric stability for subgrid modeling
319  query_one_or_per_level(pp, "thermal_stratification", strat_type, lev, max_level);
320  if (strat_type == StratType::theta) {
321  amrex::Print() << "Thermal stratification based on gradient of potential temperature" << std::endl;
322  } else if (strat_type == StratType::thetav) {
323  amrex::Print() << "Thermal stratification based on gradient of virtual potential temperature" << std::endl;
324  } else if (strat_type == StratType::thetal) {
325  amrex::Print() << "Thermal stratification based on gradient of linearized liquid-water potential temperature" << std::endl;
326  }
327 
328  // k-eqn constants
329  query_one_or_per_level(pp, "Cmu0", Cmu0, lev, max_level);
330  query_one_or_per_level(pp, "Cb", Cb, lev, max_level);
331  query_one_or_per_level(pp, "Rt_crit", Rt_crit, lev, max_level);
332  query_one_or_per_level(pp, "Rt_min", Rt_min, lev, max_level);
333  query_one_or_per_level(pp, "max_geom_lscale", l_g_max, lev, max_level);
334  query_one_or_per_level(pp, "dirichlet_k", dirichlet_k, lev, max_level);
335 
336  // Common inputs (LES or RANS)
337  if (!query_one_or_per_level(pp, "sigma_k", sigma_k, lev, max_level) && rans_type == RANSType::kEqn) {
338  amrex::Print() << "Overriding default sigma_k for k-eqn RANS" << std::endl;
339  sigma_k = one;
340  };
341  query_one_or_per_level(pp, "theta_ref", theta_ref, lev, max_level);
342 
343  query_one_or_per_level(pp, "mix_isotropic", mix_isotropic, lev, max_level);
344  query_one_or_per_level(pp, "use_Ri_correction", use_Ri_correction, lev, max_level);
345  query_one_or_per_level(pp, "Ri_crit", Ri_crit, lev, max_level);
346 
347  // Set common flags
348  use_kturb =
349  ((les_type != LESType::None) || (rans_type != RANSType::None) ||
350  (pbl_type != PBLType::None));
351  use_keqn =
352  ((les_type == LESType::Deardorff) || (rans_type == RANSType::kEqn));
353  use_tke =
354  ((les_type == LESType::Deardorff) || (rans_type == RANSType::kEqn) ||
355  (pbl_type == PBLType::MYJ) || (pbl_type == PBLType::MYNN25) ||
356  (pbl_type == PBLType::MYNNEDMF) || uses_shoc_family());
357 
358  if (use_tke) {
359  query_one_or_per_level(pp, "init_tke_from_ustar", init_tke_from_ustar, lev, max_level);
360  }
361 
362  // Validate inputs
363  if (les_type == LESType::Smagorinsky) {
364  if (Cs == 0) {
365  amrex::Error("Need to specify Cs for Smagorsinky LES");
366  }
367  if (smag2d && mix_isotropic) {
368  amrex::Print() << "Turning off mix_isotropic for 2-D Smagorinsky" << std::endl;
369  mix_isotropic = false;
370  }
371  }
372  }
373 
374  /**
375  * @brief Validate turbulence options against physical boundary conditions.
376  * @param phys_bc_type Physical boundary-condition types.
377  */
378  void check_params (amrex::GpuArray<ERF_BC, AMREX_SPACEDIM*2>& phys_bc_type)
379  {
380  // BC compatibility
382  phys_bc_type[amrex::Orientation(amrex::Direction::z,amrex::Orientation::low)] != ERF_BC::surface_layer ) {
383  amrex::Abort("The selected PBL model requires MOST at lower boundary");
384  }
385  if ( (les_type == LESType::Deardorff) && (Ce_wall > 0) &&
386  (phys_bc_type[amrex::Orientation(amrex::Direction::z,amrex::Orientation::low)] != ERF_BC::surface_layer) &&
387  (phys_bc_type[amrex::Orientation(amrex::Direction::z,amrex::Orientation::low)] != ERF_BC::slip_wall) &&
388  (phys_bc_type[amrex::Orientation(amrex::Direction::z,amrex::Orientation::low)] != ERF_BC::no_slip_wall) )
389  {
390  amrex::Warning("Deardorff LES assumes wall at zlo when applying Ce_wall");
391  }
392  }
393 
394  /**
395  * @brief Print turbulence settings for one AMR level.
396  * @param lev AMR level index.
397  */
398  void display (int lev)
399  {
400  amrex::Print() << "Turbulence Settings at level " << lev << std::endl;
401 
402  if (
403  les_type == LESType::None && rans_type == RANSType::None &&
404  pbl_type == PBLType::None) {
405  amrex::Print() << " Using DNS model at level " << lev << std::endl;
406  } else if (les_type == LESType::Smagorinsky) {
407  if (smag2d) {
408  amrex::Print() << " Using 2D Smagorinsky LES model at level " << lev << std::endl;
409  } else {
410  amrex::Print() << " Using Smagorinsky LES model at level " << lev << std::endl;
411  }
412  if (use_Ri_correction) {
413  amrex::Print() << " Smagorinsky uses Richardson number correction with Ri_crit = "
414  << Ri_crit << std::endl;
415  }
416  } else if (les_type == LESType::Deardorff) {
417  amrex::Print() << " Using Deardorff LES model at level " << lev << std::endl;
418  } else if (rans_type == RANSType::kEqn) {
419  amrex::Print()
420  << " Using Axell & Liungman one-equation RANS k model at level " << lev
421  << std::endl;
422  } else if (pbl_type == PBLType::MYJ) {
423  amrex::Print() << " Using MYJ PBL model at level " << lev << std::endl;
424  } else if (pbl_type == PBLType::MYNN25) {
425  amrex::Print() << " Using MYNN2.5 PBL model at level " << lev << std::endl;
426  } else if (pbl_type == PBLType::MYNNEDMF) {
427  amrex::Print() << " Using MYNNEDMF PBL model at level " << lev << std::endl;
428  } else if (pbl_type == PBLType::YSU) {
429  amrex::Print() << " Using YSU PBL model at level " << lev << std::endl;
430  } else if (pbl_type == PBLType::YSUNew) {
431  amrex::Print() << " Using YSU PBL model at level " << lev << std::endl;
432  } else if (pbl_type == PBLType::MRF) {
433  amrex::Print() << " Using MRF PBL model at level " << lev << std::endl;
434  } else if (pbl_type == PBLType::EAMXX_SHOC) {
435  amrex::Print() << " Using EAMxx SHOC PBL model at level " << lev << std::endl;
436  } else if (pbl_type == PBLType::NATIVE_SHOC) {
437  amrex::Print() << " Using native SHOC PBL model at level " << lev << std::endl;
438  } else {
439  amrex::Error("Unknown turbulence model");
440  }
441 
442  if (les_type != LESType::None) {
443  if (les_type == LESType::Smagorinsky) {
444  amrex::Print() << " Cs : " << Cs << std::endl;
445  }
446  if (les_type == LESType::Deardorff) {
447  amrex::Print() << " Ce : " << Ce << std::endl;
448  amrex::Print() << " Ce at wall : " << Ce_wall << std::endl;
449  amrex::Print() << " Ck : " << Ck << std::endl;
450  amrex::Print() << " sigma_k : " << sigma_k << std::endl;
451 
452  // Sullivan et al 1994, Eqn 14
453  amrex::Real Cs_equiv = std::sqrt(Ck * std::sqrt(Ck / Ce));
454  amrex::Print() << " equivalent Cs : " << Cs_equiv
455  << std::endl;
456  }
457  amrex::Print() << " isotropic mixing : " << mix_isotropic
458  << std::endl;
459  }
460 
461  if (rans_type != RANSType::None) {
462  if (rans_type == RANSType::kEqn) {
463  amrex::Print() << "Cmu0 : " << Cmu0 << std::endl;
464  amrex::Print() << "sigma_k : " << sigma_k << std::endl;
465  amrex::Print() << "Cb : " << Cb << std::endl;
466  amrex::Print() << "Rt_crit : " << Rt_crit << std::endl;
467  amrex::Print() << "Rt_min : " << Rt_min << std::endl;
468  amrex::Print() << "max_geom_lscale : " << l_g_max << std::endl;
469  }
470  }
471 
472  if ((les_type == LESType::Deardorff) ||
473  (rans_type == RANSType::kEqn)) {
474  if (theta_ref > 0) {
475  amrex::Print() << " reference theta : " << theta_ref << std::endl;
476  } else {
477  amrex::Print() << " reference theta : n/a" << std::endl;
478  }
479  }
480 
481  if ((les_type != LESType::None) || (rans_type != RANSType::None)) {
482  amrex::Print() << " Pr_t : " << Pr_t << std::endl;
483  amrex::Print() << " Sc_t : " << Sc_t << std::endl;
484  }
485 
486  if (pbl_type == PBLType::MYNN25 || pbl_type == PBLType::MYNNEDMF) {
487  amrex::Print() << " pbl_mynn_A1 : " << pbl_mynn.A1 << std::endl;
488  amrex::Print() << " pbl_mynn_A2 : " << pbl_mynn.A2 << std::endl;
489  amrex::Print() << " pbl_mynn_B1 : " << pbl_mynn.B1 << std::endl;
490  amrex::Print() << " pbl_mynn_B2 : " << pbl_mynn.B2 << std::endl;
491  amrex::Print() << " pbl_mynn_C1 : " << pbl_mynn.C1 << std::endl;
492  amrex::Print() << " pbl_mynn_C2 : " << pbl_mynn.C2 << std::endl;
493  amrex::Print() << " pbl_mynn_C3 : " << pbl_mynn.C3 << std::endl;
494  amrex::Print() << " pbl_mynn_C4 : " << pbl_mynn.C4 << std::endl;
495  amrex::Print() << " pbl_mynn_C5 : " << pbl_mynn.C5 << std::endl;
496  } else if (pbl_type == PBLType::YSU || pbl_type == PBLType::YSUNew) {
497  amrex::Print() << " pbl_ysu_coriolis_freq : "
498  << pbl_ysu_coriolis_freq << std::endl;
499  amrex::Print() << " pbl_ysu_use_consistent_coriolis : "
500  << pbl_ysu_use_consistent_coriolis << std::endl;
501  amrex::Print() << " pbl_ysu_force_over_water : "
502  << pbl_ysu_force_over_water << std::endl;
503  amrex::Print() << " pbl_ysu_land_Ribcr : "
504  << pbl_ysu_land_Ribcr << std::endl;
505  amrex::Print() << " pbl_ysu_unst_Ribcr : "
506  << pbl_ysu_unst_Ribcr << std::endl;
507  amrex::Print() << " enable_ysu_liquid_theta : "
508  << enable_ysu_liquid_theta << std::endl;
509  amrex::Print() << " enable_ysu_countergradient : "
510  << enable_ysu_countergradient << std::endl;
511  amrex::Print() << " enable_ysu_terrain_pblh_floor : "
512  << enable_ysu_terrain_pblh_floor << std::endl;
513  amrex::Print() << " enable_ysu_sat_limiter : "
514  << enable_ysu_sat_limiter << std::endl;
515  amrex::Print() << " enable_ysu_topdown : "
516  << enable_ysu_topdown << std::endl;
517  amrex::Print() << " enable_ysu_entrainment : "
518  << enable_ysu_entrainment << std::endl;
519  amrex::Print() << " enable_ysu_cloud_pblh : "
520  << enable_ysu_cloud_pblh << std::endl;
521  amrex::Print() << " ysu_qcloud_threshold : "
522  << ysu_qcloud_threshold << std::endl;
523  amrex::Print() << " ysu_moistvars : "
524  << ysu_moistvars << std::endl;
525  amrex::Print() << " pbl_ysunew_highres_bounds : "
526  << pbl_ysunew_highres_bounds << std::endl;
527  amrex::Print() << " enable_mrf_unbounded_vpert : "
528  << enable_mrf_unbounded_vpert << std::endl;
529  } else if (pbl_type == PBLType::MRF) {
530  amrex::Print() << " pbl_mrf_coriolis_freq : " << pbl_mrf_coriolis_freq
531  << std::endl;
532  amrex::Print() << " pbl_mrf_Ribcr : " << pbl_mrf_Ribcr
533  << std::endl;
534  amrex::Print() << " pbl_mrf_const_b : " << pbl_mrf_const_b
535  << std::endl;
536  amrex::Print() << " pbl_mrf_sf : " << pbl_mrf_sf
537  << std::endl;
538  amrex::Print() << " mrf_moistvars : " << mrf_moistvars
539  << std::endl;
540  amrex::Print() << " enable_mrf_countergradient : " << enable_mrf_countergradient
541  << std::endl;
542  amrex::Print() << " enable_mrf_cloud_adjustment : " << enable_mrf_cloud_adjustment
543  << std::endl;
544  amrex::Print() << " pbl_mrf_highres_bounds : " << pbl_mrf_highres_bounds
545  << std::endl;
546  amrex::Print() << " enable_mrf_unbounded_vpert : " << enable_mrf_unbounded_vpert
547  << std::endl;
548  amrex::Print() << " pbl_mrf_use_zero_ri_extent : " << pbl_mrf_use_zero_ri_extent
549  << std::endl;
550  amrex::Print() << " pbl_blend_length : " << pbl_blend_length
551  << std::endl;
552  amrex::Print() << " pbl_blend_cs : " << pbl_blend_cs
553  << std::endl;
554  amrex::Print() << " pbl_blend_c_max : " << pbl_blend_c_max
555  << std::endl;
556  amrex::Print() << " pbl_blend_use_smag : " << pbl_blend_use_smag
557  << std::endl;
558  }
559  }
560 
561  // LES model
562  LESType les_type = LESType::None;
563 
564  // Turbulent Prandtl number
567 
568  // Turbulent Schmidt number
571 
572  // Smagorinsky
574  bool smag2d = false;
575 
576  // Deardorff
578  amrex::Real Ce_wall = zero; // if > 0, then set Ce to this at k=0
580 
581  // k-eqn RANS coefficients (Axell & Liungman 2001)
586  amrex::Real l_g_max = amrex::Real(30.0); // ~ kappa * (amrex::Real(0.1) * zi)
587 
588  // Deardorff or k-eqn RANS
589  // - diffusivity of tke is 1/sigma_k times the eddy viscosity
591  // - reference potential temperature used to quantify the stratification in
592  // a stable region
594  // - how to quantify stratification effects
596 
597  // Anisotropic length scales
598  bool mix_isotropic = true;
599 
600  bool use_Ri_correction = true;
602 
603  // RANS type
604  RANSType rans_type = RANSType::None;
605 
606  bool dirichlet_k = false;
607 
608  // PBL model
609  PBLType pbl_type = PBLType::None;
610 
611  /**
612  * @brief Query whether this level uses the EAMxx SHOC PBL scheme.
613  * @return True if PBLType::EAMXX_SHOC is selected.
614  */
615  bool uses_eamxx_shoc () const noexcept
616  {
617  return pbl_type == PBLType::EAMXX_SHOC;
618  }
619 
620  /**
621  * @brief Query whether this level uses the native SHOC PBL scheme.
622  * @return True if PBLType::NATIVE_SHOC is selected.
623  */
624  bool uses_native_shoc () const noexcept
625  {
626  return pbl_type == PBLType::NATIVE_SHOC;
627  }
628 
629  /**
630  * @brief Query whether this level uses any SHOC-family PBL scheme.
631  * @return True if native or EAMxx SHOC is selected.
632  */
633  bool uses_shoc_family () const noexcept
634  {
635  return uses_eamxx_shoc() || uses_native_shoc();
636  }
637 
638  /**
639  * @brief Query whether the selected PBL scheme requires surface-layer boundary conditions.
640  * @return True if the PBL scheme requires a lower surface-layer boundary.
641  */
642  bool pbl_requires_surface_layer () const noexcept
643  {
644  return (pbl_type == PBLType::MYNN25) ||
645  (pbl_type == PBLType::MYNNEDMF) ||
646  (pbl_type == PBLType::YSU) ||
647  (pbl_type == PBLType::YSUNew) ||
648  (pbl_type == PBLType::MRF) ||
650  }
651 
652  /**
653  * @brief Query whether the selected PBL scheme suppresses microphysics condensation.
654  * @return True when the PBL scheme owns condensation handling.
655  */
657  {
658  return uses_shoc_family();
659  }
660 
662  MYNNLevel2 pbl_mynn_level2; // limiting in the decaying turbulence regime
663 
664  // Common Flags
665  bool use_kturb = false; // Any turbulence modeling?
666  bool use_keqn =
667  false; // Any microscale turbulence modeling (LES, RANS) with TKE closure?
668  // Then need to populate SmnSmn_lev for production term.
669  bool use_pbl_tke =
670  false; // Any mesoscale turbulence modeling (PBL) with TKE closure?
671  bool use_tke = false; // Any TKE closure (meso or microscale)?
672 
673  // Initialize TKE/QKE with linear profiles whose surface values are a
674  // function of the friction velocity calculated by the surface layer scheme
675  // (e.g., as done in MYNN-EDMF)
676  bool init_tke_from_ustar = false;
677 
678  // This is the value of tke_min in WRF 4.5
680 
681  // Model coefficients - YSU
682  // TODO: Add parmparse for all of these above
684  amrex::Real(1.0e-4); // 1e-4 is hardcoded in WRF, we let the user specify or take the
685  // value from ERF coriolis forcing
687  false; // ignore input pbl_ysu_coriolis_freq, take value from ERF coriolis
688  // forcing instead
690  false; // Force YSU to act as if it is over water regardless of other inputs
691  // (for testing)
693  fourth; // Critical Bulk Richardson number of Land for stable conditions
695  zero; // Critical Bulk Richardson number for unstable conditions
697  true; // if true, use liquid-water virtual potential temperature in YSU stability
699  true; // if true, apply YSU-style HGAMT/HGAMQ/HGAMU/HGAMV countergradient correction
701  true; // if true, apply terrain-following floor on PBL height
703  false; // if true, apply saturation limiter to moisture countergradient
705  true; // if true, enable top-down mixing for cloud-topped boundary layers
707  true; // if true, enable entrainment layer parameterization
709  true; // if true, enable cloud-based PBL height detection
711  amrex::Real(1.0e-4); // Cloud liquid water threshold for YSUNew (kg/kg)
712  bool ysu_moistvars = false; // if true, adds turbulence to moisture
713  bool pbl_ysunew_highres_bounds = false; // if true, apply high-resolution grid-dependent diffusivity bounds
714  // Model coefficients - MRF
716  amrex::Real pbl_mrf_Ribcr = amrex::Real(0.5); // Critical Bulk Richardson number for MRF PBL model
717  amrex::Real pbl_mrf_const_b = amrex::Real(7.8); // Constant b in MRF PBL model, used to compute the PBL height
718  amrex::Real pbl_mrf_sf = amrex::Real(0.1); // MRF surface flux, used to compute the PBL height
719  // Scale-aware PBL-LES blending parameters.
720  // Boutle et al. (2014): https://doi.org/10.1175/MWR-D-13-00229.1
721  // Set pbl_blend_length = 0 to disable (default). Recovers original behaviour.
722  amrex::Real pbl_blend_length = amrex::Real(0.0); ///< Boutle blending length L [m]. 0 = off.
723  amrex::Real pbl_blend_cs = amrex::Real(0.17); ///< Smagorinsky coeff for K_h ceiling.
724  amrex::Real pbl_blend_c_max = amrex::Real(0.1); ///< Power-law ceiling coeff [m^(2/3)/s].
725  bool pbl_blend_use_smag = true; ///< Use Smagorinsky ceiling (else power-law).
726  bool mrf_moistvars = false; // if true, adds turbulence to moisture
727  bool enable_mrf_countergradient = false; // if true, apply WRF-style HGAMT/HGAMQ correction to PBL height
728  bool enable_mrf_cloud_adjustment = false; // if true, apply cloud-aware stability function adjustments in MRF scheme
729  bool pbl_mrf_highres_bounds = false; // if true, apply high-resolution grid-dependent diffusivity bounds instead of global forecast bounds
730  bool enable_mrf_unbounded_vpert = false; // if true, does not limit VPERT to GAMCRT
731  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
732  // MYNN2.5 PBL model
733  // TKE/QKE stuff
734  bool advect_tke = true; // if MYNN2.5 PBL is used default is turb transport in
735  // Z-direction only
736  bool diffuse_tke_3D = true; // if numerical diffusion is turned on
737 };
738 
739 /**
740  * @var TurbChoice::les_type
741  * @brief Selected LES closure.
742  * @var TurbChoice::Pr_t
743  * @brief Turbulent Prandtl number.
744  * @var TurbChoice::Pr_t_inv
745  * @brief Inverse turbulent Prandtl number.
746  * @var TurbChoice::Sc_t
747  * @brief Turbulent Schmidt number.
748  * @var TurbChoice::Sc_t_inv
749  * @brief Inverse turbulent Schmidt number.
750  * @var TurbChoice::Cs
751  * @brief Smagorinsky model coefficient.
752  * @var TurbChoice::smag2d
753  * @brief Whether the 2-D Smagorinsky formulation is used.
754  * @var TurbChoice::Ce
755  * @brief Deardorff dissipation coefficient.
756  * @var TurbChoice::Ce_wall
757  * @brief Wall value for the Deardorff dissipation coefficient.
758  * @var TurbChoice::Ck
759  * @brief Deardorff eddy-viscosity coefficient.
760  * @var TurbChoice::Cmu0
761  * @brief One-equation RANS Cmu0 coefficient.
762  * @var TurbChoice::Cb
763  * @brief One-equation RANS buoyancy coefficient.
764  * @var TurbChoice::Rt_crit
765  * @brief Critical turbulent Reynolds number.
766  * @var TurbChoice::Rt_min
767  * @brief Minimum turbulent Reynolds number.
768  * @var TurbChoice::l_g_max
769  * @brief Maximum geometric length scale.
770  * @var TurbChoice::sigma_k
771  * @brief TKE diffusivity coefficient denominator.
772  * @var TurbChoice::theta_ref
773  * @brief Reference potential temperature for stable stratification.
774  * @var TurbChoice::strat_type
775  * @brief Thermodynamic variable used for stability stratification.
776  * @var TurbChoice::mix_isotropic
777  * @brief Whether subgrid mixing uses isotropic length scales.
778  * @var TurbChoice::use_Ri_correction
779  * @brief Whether Richardson-number correction is applied.
780  * @var TurbChoice::Ri_crit
781  * @brief Critical Richardson number for stability correction.
782  * @var TurbChoice::rans_type
783  * @brief Selected RANS closure.
784  * @var TurbChoice::dirichlet_k
785  * @brief Whether TKE uses Dirichlet boundary treatment.
786  * @var TurbChoice::pbl_type
787  * @brief Selected PBL closure.
788  * @var TurbChoice::pbl_mynn
789  * @brief MYNN level-2.5 closure coefficients.
790  * @var TurbChoice::pbl_mynn_level2
791  * @brief MYNN level-2 closure coefficients for limiting.
792  * @var TurbChoice::use_kturb
793  * @brief Whether any turbulence model is active.
794  * @var TurbChoice::use_keqn
795  * @brief Whether a microscale TKE closure is active.
796  * @var TurbChoice::use_pbl_tke
797  * @brief Whether a mesoscale PBL TKE closure is active.
798  * @var TurbChoice::use_tke
799  * @brief Whether any TKE or QKE closure is active.
800  * @var TurbChoice::init_tke_from_ustar
801  * @brief Whether initial TKE/QKE profiles are based on surface friction velocity.
802  * @var TurbChoice::tke_min
803  * @brief Minimum TKE/QKE value.
804  * @var TurbChoice::pbl_ysu_coriolis_freq
805  * @brief Coriolis frequency used by YSU-family PBL schemes.
806  * @var TurbChoice::pbl_ysu_use_consistent_coriolis
807  * @brief Whether YSU uses the ERF Coriolis frequency.
808  * @var TurbChoice::pbl_ysu_force_over_water
809  * @brief Whether YSU is forced to use over-water behavior.
810  * @var TurbChoice::pbl_ysu_land_Ribcr
811  * @brief Critical bulk Richardson number over land for stable YSU conditions.
812  * @var TurbChoice::pbl_ysu_unst_Ribcr
813  * @brief Critical bulk Richardson number for unstable YSU conditions.
814  * @var TurbChoice::enable_ysu_liquid_theta
815  * @brief Whether YSU uses liquid-water virtual potential temperature for stability.
816  * @var TurbChoice::enable_ysu_countergradient
817  * @brief Whether YSU countergradient corrections are enabled.
818  * @var TurbChoice::enable_ysu_terrain_pblh_floor
819  * @brief Whether YSU applies a terrain-following PBL-height floor.
820  * @var TurbChoice::enable_ysu_sat_limiter
821  * @brief Whether YSU applies a saturation limiter to moisture countergradient terms.
822  * @var TurbChoice::enable_ysu_topdown
823  * @brief Whether YSU top-down mixing is enabled.
824  * @var TurbChoice::enable_ysu_entrainment
825  * @brief Whether YSU entrainment-layer parameterization is enabled.
826  * @var TurbChoice::enable_ysu_cloud_pblh
827  * @brief Whether YSU cloud-based PBL-height detection is enabled.
828  * @var TurbChoice::ysu_qcloud_threshold
829  * @brief Cloud liquid water threshold for YSUNew [kg/kg].
830  * @var TurbChoice::ysu_moistvars
831  * @brief Whether YSU applies turbulence to moisture variables.
832  * @var TurbChoice::pbl_ysunew_highres_bounds
833  * @brief Whether YSUNew applies high-resolution grid-dependent diffusivity bounds.
834  * @var TurbChoice::pbl_mrf_coriolis_freq
835  * @brief Coriolis frequency used by the MRF PBL scheme.
836  * @var TurbChoice::pbl_mrf_Ribcr
837  * @brief Critical bulk Richardson number for the MRF PBL scheme.
838  * @var TurbChoice::pbl_mrf_const_b
839  * @brief MRF constant used to compute PBL height.
840  * @var TurbChoice::pbl_mrf_sf
841  * @brief MRF surface flux value used to compute PBL height.
842  * @var TurbChoice::mrf_moistvars
843  * @brief Whether MRF applies turbulence to moisture variables.
844  * @var TurbChoice::enable_mrf_countergradient
845  * @brief Whether MRF countergradient corrections are enabled.
846  * @var TurbChoice::enable_mrf_cloud_adjustment
847  * @brief Whether MRF cloud-aware stability adjustments are enabled.
848  * @var TurbChoice::pbl_mrf_highres_bounds
849  * @brief Whether MRF applies high-resolution grid-dependent diffusivity bounds.
850  * @var TurbChoice::enable_mrf_unbounded_vpert
851  * @brief Whether MRF leaves VPERT unlimited by GAMCRT.
852  * @var TurbChoice::pbl_mrf_use_zero_ri_extent
853  * @brief Whether MRF uses the Ri=0 K-profile extent.
854  * @var TurbChoice::advect_tke
855  * @brief Whether TKE/QKE is advected.
856  * @var TurbChoice::diffuse_tke_3D
857  * @brief Whether three-dimensional numerical diffusion is applied to TKE/QKE.
858  */
859 #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")
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
@ T
Definition: ERF_IndexDefines.H:128
Coefficients and stability functions for the Level 2.5 MYNN closure.
Definition: ERF_MYNNStruct.H:14
amrex::Real SMmax
Definition: ERF_MYNNStruct.H:61
amrex::Real SHmax
Definition: ERF_MYNNStruct.H:63
amrex::Real SQfac
Definition: ERF_MYNNStruct.H:57
amrex::Real C4
Definition: ERF_MYNNStruct.H:53
amrex::Real C1
Definition: ERF_MYNNStruct.H:50
amrex::Real C3
Definition: ERF_MYNNStruct.H:52
amrex::Real C2
Definition: ERF_MYNNStruct.H:51
amrex::Real A2
Definition: ERF_MYNNStruct.H:47
amrex::Real SHmin
Definition: ERF_MYNNStruct.H:62
amrex::Real B1
Definition: ERF_MYNNStruct.H:48
amrex::Real B2
Definition: ERF_MYNNStruct.H:49
amrex::Real C5
Definition: ERF_MYNNStruct.H:54
amrex::Real SMmin
Definition: ERF_MYNNStruct.H:60
amrex::Real A1
Definition: ERF_MYNNStruct.H:46
bool diffuse_moistvars
Definition: ERF_MYNNStruct.H:70
amrex::Real SQmax
Definition: ERF_MYNNStruct.H:65
Coefficients and stability functions for the Level 2 MYNN closure.
Definition: ERF_MYNNStruct.H:76
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)
Initialize Level 2 closure coefficients from Level 2.5 coefficients.
Definition: ERF_MYNNStruct.H:88
Definition: ERF_TurbStruct.H:114
bool advect_tke
Whether TKE/QKE is advected.
Definition: ERF_TurbStruct.H:734
bool pbl_ysu_force_over_water
Whether YSU is forced to use over-water behavior.
Definition: ERF_TurbStruct.H:689
StratType strat_type
Thermodynamic variable used for stability stratification.
Definition: ERF_TurbStruct.H:595
amrex::Real Ce
Deardorff dissipation coefficient.
Definition: ERF_TurbStruct.H:577
bool enable_mrf_unbounded_vpert
Whether MRF leaves VPERT unlimited by GAMCRT.
Definition: ERF_TurbStruct.H:730
amrex::Real Sc_t
Turbulent Schmidt number.
Definition: ERF_TurbStruct.H:569
MYNNLevel2 pbl_mynn_level2
MYNN level-2 closure coefficients for limiting.
Definition: ERF_TurbStruct.H:662
bool diffuse_tke_3D
Whether three-dimensional numerical diffusion is applied to TKE/QKE.
Definition: ERF_TurbStruct.H:736
bool use_tke
Whether any TKE or QKE closure is active.
Definition: ERF_TurbStruct.H:671
amrex::Real sigma_k
TKE diffusivity coefficient denominator.
Definition: ERF_TurbStruct.H:590
bool use_Ri_correction
Whether Richardson-number correction is applied.
Definition: ERF_TurbStruct.H:600
bool pbl_ysu_use_consistent_coriolis
Whether YSU uses the ERF Coriolis frequency.
Definition: ERF_TurbStruct.H:686
amrex::Real pbl_blend_length
Boutle blending length L [m]. 0 = off.
Definition: ERF_TurbStruct.H:722
amrex::Real Ck
Deardorff eddy-viscosity coefficient.
Definition: ERF_TurbStruct.H:579
bool pbl_mrf_use_zero_ri_extent
Whether MRF uses the Ri=0 K-profile extent.
Definition: ERF_TurbStruct.H:731
amrex::Real Ce_wall
Wall value for the Deardorff dissipation coefficient.
Definition: ERF_TurbStruct.H:578
RANSType rans_type
Selected RANS closure.
Definition: ERF_TurbStruct.H:604
void check_params(amrex::GpuArray< ERF_BC, AMREX_SPACEDIM *2 > &phys_bc_type)
Validate turbulence options against physical boundary conditions.
Definition: ERF_TurbStruct.H:378
amrex::Real theta_ref
Reference potential temperature for stable stratification.
Definition: ERF_TurbStruct.H:593
amrex::Real Sc_t_inv
Inverse turbulent Schmidt number.
Definition: ERF_TurbStruct.H:570
amrex::Real l_g_max
Maximum geometric length scale.
Definition: ERF_TurbStruct.H:586
bool enable_mrf_cloud_adjustment
Whether MRF cloud-aware stability adjustments are enabled.
Definition: ERF_TurbStruct.H:728
bool use_keqn
Whether a microscale TKE closure is active.
Definition: ERF_TurbStruct.H:666
bool uses_eamxx_shoc() const noexcept
Query whether this level uses the EAMxx SHOC PBL scheme.
Definition: ERF_TurbStruct.H:615
bool enable_ysu_entrainment
Whether YSU entrainment-layer parameterization is enabled.
Definition: ERF_TurbStruct.H:706
bool enable_ysu_sat_limiter
Whether YSU applies a saturation limiter to moisture countergradient terms.
Definition: ERF_TurbStruct.H:702
bool enable_ysu_cloud_pblh
Whether YSU cloud-based PBL-height detection is enabled.
Definition: ERF_TurbStruct.H:708
amrex::Real pbl_mrf_const_b
MRF constant used to compute PBL height.
Definition: ERF_TurbStruct.H:717
bool mrf_moistvars
Whether MRF applies turbulence to moisture variables.
Definition: ERF_TurbStruct.H:726
amrex::Real pbl_blend_cs
Smagorinsky coeff for K_h ceiling.
Definition: ERF_TurbStruct.H:723
bool uses_shoc_family() const noexcept
Query whether this level uses any SHOC-family PBL scheme.
Definition: ERF_TurbStruct.H:633
amrex::Real ysu_qcloud_threshold
Cloud liquid water threshold for YSUNew [kg/kg].
Definition: ERF_TurbStruct.H:710
amrex::Real pbl_blend_c_max
Power-law ceiling coeff [m^(2/3)/s].
Definition: ERF_TurbStruct.H:724
bool init_tke_from_ustar
Whether initial TKE/QKE profiles are based on surface friction velocity.
Definition: ERF_TurbStruct.H:676
bool enable_mrf_countergradient
Whether MRF countergradient corrections are enabled.
Definition: ERF_TurbStruct.H:727
bool enable_ysu_countergradient
Whether YSU countergradient corrections are enabled.
Definition: ERF_TurbStruct.H:698
bool mix_isotropic
Whether subgrid mixing uses isotropic length scales.
Definition: ERF_TurbStruct.H:598
bool uses_native_shoc() const noexcept
Query whether this level uses the native SHOC PBL scheme.
Definition: ERF_TurbStruct.H:624
bool dirichlet_k
Whether TKE uses Dirichlet boundary treatment.
Definition: ERF_TurbStruct.H:606
LESType les_type
Selected LES closure.
Definition: ERF_TurbStruct.H:562
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:704
bool pbl_mrf_highres_bounds
Whether MRF applies high-resolution grid-dependent diffusivity bounds.
Definition: ERF_TurbStruct.H:729
amrex::Real Rt_min
Minimum turbulent Reynolds number.
Definition: ERF_TurbStruct.H:585
bool pbl_blend_use_smag
Use Smagorinsky ceiling (else power-law).
Definition: ERF_TurbStruct.H:725
MYNNLevel25 pbl_mynn
MYNN level-2.5 closure coefficients.
Definition: ERF_TurbStruct.H:661
amrex::Real pbl_ysu_land_Ribcr
Critical bulk Richardson number over land for stable YSU conditions.
Definition: ERF_TurbStruct.H:692
amrex::Real Cb
One-equation RANS buoyancy coefficient.
Definition: ERF_TurbStruct.H:583
amrex::Real Ri_crit
Critical Richardson number for stability correction.
Definition: ERF_TurbStruct.H:601
amrex::Real pbl_ysu_unst_Ribcr
Critical bulk Richardson number for unstable YSU conditions.
Definition: ERF_TurbStruct.H:694
amrex::Real Rt_crit
Critical turbulent Reynolds number.
Definition: ERF_TurbStruct.H:584
bool pbl_suppresses_microphysics_condensation() const noexcept
Query whether the selected PBL scheme suppresses microphysics condensation.
Definition: ERF_TurbStruct.H:656
amrex::Real pbl_mrf_Ribcr
Critical bulk Richardson number for the MRF PBL scheme.
Definition: ERF_TurbStruct.H:716
amrex::Real pbl_mrf_sf
MRF surface flux value used to compute PBL height.
Definition: ERF_TurbStruct.H:718
amrex::Real Cmu0
One-equation RANS Cmu0 coefficient.
Definition: ERF_TurbStruct.H:582
amrex::Real Cs
Smagorinsky model coefficient.
Definition: ERF_TurbStruct.H:573
amrex::Real Pr_t
Turbulent Prandtl number.
Definition: ERF_TurbStruct.H:565
amrex::Real pbl_mrf_coriolis_freq
Coriolis frequency used by the MRF PBL scheme.
Definition: ERF_TurbStruct.H:715
bool pbl_ysunew_highres_bounds
Whether YSUNew applies high-resolution grid-dependent diffusivity bounds.
Definition: ERF_TurbStruct.H:713
amrex::Real tke_min
Minimum TKE/QKE value.
Definition: ERF_TurbStruct.H:679
amrex::Real pbl_ysu_coriolis_freq
Coriolis frequency used by YSU-family PBL schemes.
Definition: ERF_TurbStruct.H:683
void display(int lev)
Print turbulence settings for one AMR level.
Definition: ERF_TurbStruct.H:398
bool use_kturb
Whether any turbulence model is active.
Definition: ERF_TurbStruct.H:665
bool ysu_moistvars
Whether YSU applies turbulence to moisture variables.
Definition: ERF_TurbStruct.H:712
PBLType pbl_type
Selected PBL closure.
Definition: ERF_TurbStruct.H:609
amrex::Real Pr_t_inv
Inverse turbulent Prandtl number.
Definition: ERF_TurbStruct.H:566
bool enable_ysu_terrain_pblh_floor
Whether YSU applies a terrain-following PBL-height floor.
Definition: ERF_TurbStruct.H:700
bool enable_ysu_liquid_theta
Whether YSU uses liquid-water virtual potential temperature for stability.
Definition: ERF_TurbStruct.H:696
bool smag2d
Whether the 2-D Smagorinsky formulation is used.
Definition: ERF_TurbStruct.H:574
bool pbl_requires_surface_layer() const noexcept
Query whether the selected PBL scheme requires surface-layer boundary conditions.
Definition: ERF_TurbStruct.H:642
bool use_pbl_tke
Whether a mesoscale PBL TKE closure is active.
Definition: ERF_TurbStruct.H:669