1 #ifndef ERF_TURB_STRUCT_H_
2 #define ERF_TURB_STRUCT_H_
9 AMREX_ENUM(LESType, None, Smagorinsky, Smagorinsky2D, Deardorff);
19 AMREX_ENUM(PBLType, None, MYJ, MYNN25, MYNNEDMF, YSU, YSUNew, MRF, SHOC, EAMXX_SHOC, NATIVE_SHOC);
39 const amrex::ParmParse&
pp,
40 const char* query_string,
45 int count =
pp.countval(query_string);
48 }
else if (count == 1) {
50 return pp.query(query_string, query_var);
51 }
else if (count >= maxlev + 1) {
55 return pp.query(query_string, query_var, lev);
62 "For parmparse variable " +
pp.prefixedName(query_string) +
63 ": if specified, specify once total or at least once for each level");
81 const amrex::ParmParse&
pp,
82 const char* query_string,
87 int count =
pp.countval(query_string);
90 }
else if (count == 1) {
92 return pp.query_enum_case_insensitive(query_string, query_var);
93 }
else if (count >= maxlev + 1) {
97 return pp.query_enum_case_insensitive(query_string, query_var, lev);
104 "For parmparse variable " +
pp.prefixedName(query_string) +
105 ": if specified, specify once total or at least once for each level");
124 amrex::ParmParse
pp(pp_prefix);
130 if (
les_type == LESType::Smagorinsky2D) {
139 amrex::Error(
"Hybrid RANS-LES not implemented");
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;
157 amrex::Print() <<
"Selected a PBL model and an LES model: "
158 <<
"Using PBL for vertical transport, LES for horizontal"
161 if (
les_type == LESType::Smagorinsky) {
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) {
167 "It is not recommended to use Deardorff LES and a PBL model");
200 pp,
"pbl_ysu_use_consistent_coriolis",
231 }
else if (
pbl_type == PBLType::MRF) {
260 }
else if (
pbl_type == PBLType::SHOC) {
262 amrex::Abort(
"You set use_shoc to true but didn't build with SHOC; you must rebuild the executable");
266 #ifndef ERF_USE_EAMXX_SHOC
267 amrex::Abort(
"PBLType::EAMXX_SHOC requested, but ERF was not built with ERF_ENABLE_EAMXX_SHOC=ON");
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.");
307 if (
les_type == LESType::Deardorff) {
316 amrex::Print() <<
"Thermal stratification based on gradient of potential temperature" << std::endl;
318 amrex::Print() <<
"Thermal stratification based on gradient of virtual potential temperature" << std::endl;
320 amrex::Print() <<
"Thermal stratification based on gradient of linearized liquid-water potential temperature" << std::endl;
333 amrex::Print() <<
"Overriding default sigma_k for k-eqn RANS" << std::endl;
358 if (
les_type == LESType::Smagorinsky) {
360 amrex::Error(
"Need to specify Cs for Smagorsinky LES");
363 amrex::Print() <<
"Turning off mix_isotropic for 2-D Smagorinsky" << std::endl;
373 void check_params (amrex::GpuArray<ERF_BC, AMREX_SPACEDIM*2>& phys_bc_type)
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");
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) )
385 amrex::Warning(
"Deardorff LES assumes wall at zlo when applying Ce_wall");
395 amrex::Print() <<
"Turbulence Settings at level " << lev << std::endl;
400 amrex::Print() <<
" Using DNS model at level " << lev << std::endl;
401 }
else if (
les_type == LESType::Smagorinsky) {
403 amrex::Print() <<
" Using 2D Smagorinsky LES model at level " << lev << std::endl;
405 amrex::Print() <<
" Using Smagorinsky LES model at level " << lev << std::endl;
408 amrex::Print() <<
" Smagorinsky uses Richardson number correction with Ri_crit = "
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) {
415 <<
" Using Axell & Liungman one-equation RANS k model at level " << lev
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;
434 amrex::Error(
"Unknown turbulence model");
438 if (
les_type == LESType::Smagorinsky) {
439 amrex::Print() <<
" Cs : " <<
Cs << std::endl;
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;
449 amrex::Print() <<
" equivalent Cs : " << Cs_equiv
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;
467 if ((
les_type == LESType::Deardorff) ||
470 amrex::Print() <<
" reference theta : " <<
theta_ref << std::endl;
472 amrex::Print() <<
" reference theta : n/a" << std::endl;
477 amrex::Print() <<
" Pr_t : " <<
Pr_t << std::endl;
478 amrex::Print() <<
" Sc_t : " <<
Sc_t << std::endl;
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;
492 amrex::Print() <<
" pbl_ysu_coriolis_freq : "
494 amrex::Print() <<
" pbl_ysu_use_consistent_coriolis : "
496 amrex::Print() <<
" pbl_ysu_force_over_water : "
498 amrex::Print() <<
" pbl_ysu_land_Ribcr : "
500 amrex::Print() <<
" pbl_ysu_unst_Ribcr : "
502 amrex::Print() <<
" enable_ysu_liquid_theta : "
504 amrex::Print() <<
" enable_ysu_countergradient : "
506 amrex::Print() <<
" enable_ysu_terrain_pblh_floor : "
508 amrex::Print() <<
" enable_ysu_sat_limiter : "
510 amrex::Print() <<
" enable_ysu_topdown : "
512 amrex::Print() <<
" enable_ysu_entrainment : "
514 amrex::Print() <<
" enable_ysu_cloud_pblh : "
516 amrex::Print() <<
" ysu_qcloud_threshold : "
518 amrex::Print() <<
" ysu_moistvars : "
520 amrex::Print() <<
" pbl_ysunew_highres_bounds : "
522 amrex::Print() <<
" enable_mrf_unbounded_vpert : "
524 }
else if (
pbl_type == PBLType::MRF) {
531 amrex::Print() <<
" pbl_mrf_sf : " <<
pbl_mrf_sf
612 return pbl_type == PBLType::EAMXX_SHOC;
621 return pbl_type == PBLType::NATIVE_SHOC;
639 return (
pbl_type == PBLType::MYNN25) ||
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
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