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  * Gating: pbl_kh_blend_and_cap returns K_h unchanged when L_blend <= 0.
16  * Setting L_blend = 0 recovers original PBL behaviour exactly.
17  *
18  * References:
19  * Boutle, I.A. et al. (2014). Mon. Wea. Rev., 142, 1655.
20  * https://doi.org/10.1175/MWR-D-13-00229.1
21  * Smagorinsky, J. (1963). Mon. Wea. Rev., 91, 99.
22  * https://doi.org/10.1175/1520-0493(1963)091<0099:GCEWTP>2.3.CO;2
23  * Honnert, R. et al. (2011). J. Atmos. Sci., 68, 2742.
24  * https://doi.org/10.1175/JAS-D-11-025.1
25  * Beare, R.J. (2014). Bound.-Layer Meteor., 153, 345.
26  * https://doi.org/10.1007/s10546-013-9881-3
27  * Hong, S.-Y., & Pan, H.-L. (1996). Mon. Wea. Rev., 124, 2322.
28  * https://doi.org/10.1175/1520-0493(1996)124<2322:NBLVDI>2.0.CO;2
29  */
30 
31 #ifndef ERF_PBL_SCALE_AWARE_BLENDING_H
32 #define ERF_PBL_SCALE_AWARE_BLENDING_H
33 
34 #include <AMReX_REAL.H>
35 #include <AMReX_GpuQualifiers.H>
36 #include <cmath>
37 
38 /**
39  * @brief Boutle et al. (2014) blending factor.
40  *
41  * f = 1 / (1 + (dx/L_blend)^2)
42  *
43  * Returns 1 when L_blend <= 0 (gate: no blending).
44  * Asymptotes to 1 as dx >> L_blend (mesoscale grid, full PBL K_h).
45  * Asymptotes to 0 as dx << L_blend (LES grid, no PBL K_h contribution).
46  *
47  * @param dx Horizontal grid spacing [m].
48  * @param L_blend Blending length scale [m]. Typical: 750 m. 0 = disabled.
49  */
50 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
52  amrex::Real L_blend) noexcept
53 {
54  if (L_blend <= 0.0) return 1.0;
55  const amrex::Real r = dx / L_blend;
56  return 1.0 / (1.0 + r * r);
57 }
58 
59 /**
60  * @brief Smagorinsky-Lilly K_h ceiling.
61  *
62  * K_h_max = (C_s * dx)^2 * sqrt(2 * SmnSmn)
63  *
64  * Used when strain rate SmnSmn is available (e.g. from SmnSmn_lev in ERF).
65  *
66  * @param dx Horizontal grid spacing [m].
67  * @param SmnSmn S_ij*S_ij strain rate squared [s^-2]. Must be >= 0.
68  * @param C_s Smagorinsky coefficient. Typical: 0.17.
69  */
70 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
72  amrex::Real SmnSmn,
73  amrex::Real C_s) noexcept
74 {
75  const amrex::Real Lmix = C_s * dx;
76  return Lmix * Lmix * std::sqrt(2.0 * amrex::max(SmnSmn, amrex::Real(0.0)));
77 }
78 
79 /**
80  * @brief Power-law K_h ceiling (fallback when SmnSmn not available).
81  *
82  * K_h_max = c_max * dx^(4/3)
83  *
84  * Derived from dimensional analysis of the inertial subrange.
85  * Reference: Honnert et al. (2011). https://doi.org/10.1175/JAS-D-11-025.1
86  *
87  * @param dx Horizontal grid spacing [m].
88  * @param c_max Coefficient [m^(2/3) s^-1]. Typical: 0.1.
89  */
90 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
92  amrex::Real c_max) noexcept
93 {
94  return c_max * std::pow(dx, amrex::Real(4.0) / amrex::Real(3.0));
95 }
96 
97 /**
98  * @brief Apply scale-aware blending and ceiling to a single K_h value.
99  *
100  * K_h_eff = min(K_h * f_blend(dx, L_blend), K_h_max)
101  *
102  * Gate: returns K_h unchanged when L_blend <= 0.
103  *
104  * Ceiling selection:
105  * use_smag = true and SmnSmn >= 0: Smagorinsky ceiling.
106  * otherwise: power-law ceiling.
107  *
108  * Callable from any PBL scheme (MRF, YSU, MYNN) without modification.
109  *
110  * @param K_h PBL vertical diffusivity [m^2/s] before blending.
111  * @param dx Horizontal grid spacing [m].
112  * @param L_blend Boutle blending length [m]. 0 = no blending (returns K_h).
113  * @param C_s Smagorinsky coefficient (used when use_smag=true).
114  * @param c_max Power-law coefficient [m^(2/3)/s] (used when use_smag=false).
115  * @param SmnSmn Strain rate squared [s^-2]. Use -1 when not available.
116  * @param use_smag Use Smagorinsky ceiling when SmnSmn >= 0.
117  * @return Blended and capped K_h [m^2/s].
118  */
119 AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE
121  amrex::Real dx,
122  amrex::Real L_blend,
123  amrex::Real C_s,
124  amrex::Real c_max,
125  amrex::Real SmnSmn,
126  bool use_smag) noexcept
127 {
128  if (L_blend <= 0.0) return K_h;
129 
130  const amrex::Real f = pbl_blend_factor(dx, L_blend);
131  const amrex::Real K_blend = K_h * f;
132 
133  amrex::Real K_max;
134  if (use_smag && SmnSmn >= 0.0) {
135  K_max = pbl_kh_ceiling_smag(dx, SmnSmn, C_s);
136  } else {
137  K_max = pbl_kh_ceiling_powerlaw(dx, c_max);
138  }
139  return amrex::min(K_blend, K_max);
140 }
141 
142 #endif // ERF_PBL_SCALE_AWARE_BLENDING_H
const Real dx
Definition: ERF_InitCustomPert_ABL.H:23
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:120
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:51
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:91
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:71
amrex::Real Real
Definition: ERF_ShocInterface.H:19