ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
ERF_PBLScaleAwareBlending.H
Go to the documentation of this file.
1 /**
2  * @file ERF_PBLScaleAwareBlending.H
3  * @brief GPU-inline blending functions for PBL diffusivity at grey-zone resolution.
4  *
5  * Provides scale-aware reduction of PBL vertical diffusivity (K_h) when the
6  * horizontal grid spacing falls between mesoscale and LES resolution.
7  *
8  * Designed as a standalone header callable from any PBL scheme (MRF, YSU,
9  * MYNN) without code duplication. All functions are AMREX_GPU_HOST_DEVICE
10  * AMREX_FORCE_INLINE free functions with no state.
11  *
12  * Usage in an MFIter loop after K_h is computed:
13  * K_h_eff = pbl_kh_blend_and_cap(K_h, dx, L_blend, C_s, c_max, SmnSmn, use_smag);
14  *
15  * K_h is a kinematic diffusivity [m^2/s], because that is the unit of the ceilings
16  * applied here. Schemes that carry rho*K in K_turb (all of the ERF PBL models do)
17  * must divide by rho on the way in and multiply by rho on the way out, or the cap
18  * ends up scaling like 1/rho instead of being a constant diffusivity.
19  *
20  * Gating: pbl_kh_blend_and_cap returns K_h unchanged when L_blend <= 0.
21  * Setting L_blend = 0 recovers original PBL behaviour exactly.
22  *
23  * References:
24  * Boutle, I.A. et al. (2014). Mon. Wea. Rev., 142, 1655.
25  * https://doi.org/10.1175/MWR-D-13-00229.1
26  * Smagorinsky, J. (1963). Mon. Wea. Rev., 91, 99.
27  * https://doi.org/10.1175/1520-0493(1963)091<0099:GCEWTP>2.3.CO;2
28  * Honnert, R. et al. (2011). J. Atmos. Sci., 68, 2742.
29  * https://doi.org/10.1175/JAS-D-11-025.1
30  * Beare, R.J. (2014). Bound.-Layer Meteor., 153, 345.
31  * https://doi.org/10.1007/s10546-013-9881-3
32  * Hong, S.-Y., & Pan, H.-L. (1996). Mon. Wea. Rev., 124, 2322.
33  * https://doi.org/10.1175/1520-0493(1996)124<2322:NBLVDI>2.0.CO;2
34  */
35 
36 #ifndef ERF_PBL_SCALE_AWARE_BLENDING_H
37 #define ERF_PBL_SCALE_AWARE_BLENDING_H
38 
39 #include <AMReX_REAL.H>
40 #include <AMReX_GpuQualifiers.H>
41 #include <cmath>
42 
43 /**
44  * @brief Boutle et al. (2014) blending factor.
45  *
46  * f = (dx/L_blend)^2 / (1 + (dx/L_blend)^2)
47  *
48  * Returns 1 when L_blend <= 0 (gate: no blending).
49  * Asymptotes to 1 as dx >> L_blend (mesoscale grid, full PBL K_h).
50  * Asymptotes to 0 as dx << L_blend (LES grid, no PBL K_h contribution).
51  *
52  * This is the weight on the parameterized (subgrid) part of the turbulence, so it
53  * must grow with dx: the coarser the grid, the less of the boundary layer overturning
54  * is resolved and the more the PBL scheme has to supply. It was previously written as
55  * 1/(1+(dx/L_blend)^2), which has both limits backwards -- it switched the PBL scheme
56  * off at mesoscale resolution and left it at full strength at LES resolution, on top of
57  * whatever the resolved motions were already doing (issue #3619).
58  *
59  * @param dx Horizontal grid spacing [m].
60  * @param L_blend Blending length scale [m]. Typical: 750 m. 0 = disabled.
61  */
62 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
64  amrex::Real L_blend) noexcept
65 {
66  if (L_blend <= 0.0) return 1.0;
67  const amrex::Real r = dx / L_blend;
68  return (r * r) / (1.0 + r * r);
69 }
70 
71 /**
72  * @brief Smagorinsky-Lilly K_h ceiling.
73  *
74  * K_h_max = (C_s * dx)^2 * sqrt(2 * SmnSmn)
75  *
76  * Used when strain rate SmnSmn is available (e.g. from SmnSmn_lev in ERF).
77  *
78  * @param dx Horizontal grid spacing [m].
79  * @param SmnSmn S_ij*S_ij strain rate squared [s^-2]. Must be >= 0.
80  * @param C_s Smagorinsky coefficient. Typical: 0.17.
81  */
82 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
84  amrex::Real SmnSmn,
85  amrex::Real C_s) noexcept
86 {
87  const amrex::Real Lmix = C_s * dx;
88  return Lmix * Lmix * std::sqrt(2.0 * amrex::max(SmnSmn, amrex::Real(0.0)));
89 }
90 
91 /**
92  * @brief Power-law K_h ceiling (fallback when SmnSmn not available).
93  *
94  * K_h_max = c_max * dx^(4/3)
95  *
96  * Derived from dimensional analysis of the inertial subrange.
97  * Reference: Honnert et al. (2011). https://doi.org/10.1175/JAS-D-11-025.1
98  *
99  * @param dx Horizontal grid spacing [m].
100  * @param c_max Coefficient [m^(2/3) s^-1]. Typical: 0.1.
101  */
102 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
104  amrex::Real c_max) noexcept
105 {
106  return c_max * std::pow(dx, amrex::Real(4.0) / amrex::Real(3.0));
107 }
108 
109 /**
110  * @brief Apply scale-aware blending and ceiling to a single K_h value.
111  *
112  * K_h_eff = min(K_h * f_blend(dx, L_blend), K_h_max)
113  *
114  * Gate: returns K_h unchanged when L_blend <= 0.
115  *
116  * Ceiling selection:
117  * use_smag = true and SmnSmn >= 0: Smagorinsky ceiling.
118  * otherwise: power-law ceiling.
119  *
120  * Callable from any PBL scheme (MRF, YSU, MYNN) without modification.
121  *
122  * @param K_h PBL vertical diffusivity [m^2/s] before blending.
123  * @param dx Horizontal grid spacing [m].
124  * @param L_blend Boutle blending length [m]. 0 = no blending (returns K_h).
125  * @param C_s Smagorinsky coefficient (used when use_smag=true).
126  * @param c_max Power-law coefficient [m^(2/3)/s] (used when use_smag=false).
127  * @param SmnSmn Strain rate squared [s^-2]. Use -1 when not available.
128  * @param use_smag Use Smagorinsky ceiling when SmnSmn >= 0.
129  * @return Blended and capped K_h [m^2/s].
130  */
131 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
133  amrex::Real dx,
134  amrex::Real L_blend,
135  amrex::Real C_s,
136  amrex::Real c_max,
137  amrex::Real SmnSmn,
138  bool use_smag) noexcept
139 {
140  if (L_blend <= 0.0) return K_h;
141 
142  const amrex::Real f = pbl_blend_factor(dx, L_blend);
143  const amrex::Real K_blend = K_h * f;
144 
145  amrex::Real K_max;
146  if (use_smag && SmnSmn >= 0.0) {
147  K_max = pbl_kh_ceiling_smag(dx, SmnSmn, C_s);
148  } else {
149  K_max = pbl_kh_ceiling_powerlaw(dx, c_max);
150  }
151  return amrex::min(K_blend, K_max);
152 }
153 
154 #endif // ERF_PBL_SCALE_AWARE_BLENDING_H
const Real dx
Definition: ERF_InitCustomPert_ABL.H:44
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real pbl_kh_blend_and_cap(amrex::Real K_h, amrex::Real dx, amrex::Real L_blend, amrex::Real C_s, amrex::Real c_max, amrex::Real SmnSmn, bool use_smag) noexcept
Apply scale-aware blending and ceiling to a single K_h value.
Definition: ERF_PBLScaleAwareBlending.H:132
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real pbl_blend_factor(amrex::Real dx, amrex::Real L_blend) noexcept
Boutle et al. (2014) blending factor.
Definition: ERF_PBLScaleAwareBlending.H:63
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real pbl_kh_ceiling_powerlaw(amrex::Real dx, amrex::Real c_max) noexcept
Power-law K_h ceiling (fallback when SmnSmn not available).
Definition: ERF_PBLScaleAwareBlending.H:103
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE amrex::Real pbl_kh_ceiling_smag(amrex::Real dx, amrex::Real SmnSmn, amrex::Real C_s) noexcept
Smagorinsky-Lilly K_h ceiling.
Definition: ERF_PBLScaleAwareBlending.H:83
amrex::Real Real
Definition: ERF_ShocInterface.H:19