Mellor-Yamada Level-2.5 Turbulence Closure
NeuralPOM implements the Mellor-Yamada level-2.5 turbulence closure model (Mellor & Yamada, 1982) to parameterize vertical mixing. This second-moment closure scheme solves two prognostic equations for turbulence quantities, from which the vertical eddy viscosity
Overview of the Mellor-Yamada Hierarchy
The Mellor-Yamada turbulence closure hierarchy classifies models by the level of complexity in the Reynolds stress equations:
| Level | Description | Prognostic Variables |
|---|---|---|
| Level-2 | Full algebraic equilibrium; no transport of turbulence | None |
| Level-2.5 | Turbulence kinetic energy and length scale prognostic | |
| Level-3 | Adds temperature variance equation | |
| Level-4 | Full Reynolds stress transport | All second moments |
Level-2.5 provides a good balance between physical fidelity (it captures the evolution of turbulence in non-equilibrium conditions) and computational cost (only two additional prognostic equations).
Prognostic Equations
Turbulent Kinetic Energy ( )
The quantity
Turbulence Length Scale Product ( )
The master length scale
where:
| Symbol | Description |
|---|---|
| Twice the turbulent kinetic energy ( | |
| Turbulence master length scale | |
| Vertical diffusivity for turbulence quantities ( | |
| Shear production | |
| Buoyancy production/destruction | |
| Dissipation rate ( | |
| Wall proximity function | |
| Empirical constant |
Production and Dissipation Terms
Shear Production
Shear production represents the conversion of mean kinetic energy to turbulence by the Reynolds stresses working against the mean shear:
In the code (profq), the shear production is computed at internal interfaces:
for k in range(1, kbm1):
du_sq = (u[s_i, s_j, k] - u[s_i, s_j, k-1] +
u[s_ip1, s_j, k] - u[s_ip1, s_j, k-1])**2
dv_sq = (v[s_i, s_j, k] - v[s_i, s_j, k-1] +
v[s_i, s_jp1, k] - v[s_i, s_jp1, k-1])**2
denom = (dzz[k-1] * dh[s_i, s_j])**2
kn[s_i, s_j, k] = km[s_i, s_j, k] * 0.25 * sef * (du_sq + dv_sq) / denomwhere sef = 1.0 is a scaling factor and dzz is the vertical layer spacing.
Buoyancy Production/Destruction
Buoyancy effects can either produce turbulence (in unstable stratification) or destroy it (in stable stratification):
where
The implementation includes a sound speed correction:
for k in range(1, kbm1):
drho = rho[:, :, k-1] - rho[:, :, k]
term1 = grav * drho / (dzz[k-1] * dh)
term2 = (grav**2) * 2.0 / (cc[:, :, k-1]**2 + cc[:, :, k]**2)
boygr[:, :, k] = term1 + term2Dissipation
The dissipation rate follows Kolmogorov scaling:
where
dtef = safe_sqrt(torch.abs(q2b)) * stf / (b1 * l + small)Enhancing dissipation near boundaries:
Wall Proximity Function
The wall proximity function accounts for the suppression of the turbulence length scale near solid boundaries (both surface and bottom). It is defined as:
where:
| Symbol | Description |
|---|---|
| von Karman constant | |
| Vertical position of the free surface | |
| Vertical position of the bottom | |
| Total water depth | |
| Turbulence length scale |
This forces
wall_term = (1.0 / torch.abs(z[k] - z_surf) + 1.0 / torch.abs(z[k] - z_bot)) * l[:, :, k] / (dh * kappa)Stability Functions and
The stability functions are algebraic expressions derived from the level-2.5 closure assumptions. They depend on the Richardson number through the quantity
The stability functions are:
These are computed in the code using the pre-defined coef1--coef5:
coef4 = 18.0 * a1 * a1 + 9.0 * a1 * a2
coef5 = 9.0 * a1 * a2
coef1 = a2 * (1.0 - 6.0 * a1 / b1)
coef2 = 3.0 * a2 * b2 + 18.0 * a1 * a2
coef3 = a1 * (1.0 - 3.0 * c1 - 6.0 * a1 / b1)
denom_sh = 1.0 - coef2 * gh
sh = coef1 / (denom_sh + 1e-20)
num_sm = coef3 + sh * coef4 * gh
denom_sm = 1.0 - coef5 * gh
sm = num_sm / (denom_sm + 1e-20)The quantity gh is clamped to a maximum value of 0.028 to prevent numerical instability:
gh = torch.clamp(gh, max=0.028)Vertical Eddy Viscosity and Diffusivity
The turbulence quantities determine the vertical mixing coefficients:
(with
The final values are time-smoothed (averaged with previous values):
kn_final = l_out * safe_sqrt(torch.abs(q2_in))
kq_out = (kn_final * 0.41 * sh + kq_in) * 0.5
km_out = (kn_final * sm + km_in) * 0.5
kh_out = (kn_final * sh + kh_in) * 0.5Boundary values of fsm.
Boundary Conditions
Surface Boundary Condition for
At the free surface, the TKE is proportional to the friction velocity
where
gg_list[0][s_i, s_j] = (15.8 * cbcnst)**(2.0/3.0) * utau2The surface friction velocity is:
Surface Length Scale
The surface value of the length scale is constrained by a surface roughness length
where surfl = 2.0e5 is an empirical constant. The length scale in the upper layer is limited:
l0[s_i, s_j] = surfl * utau2 / grav
l_out[:, :, 0] = kappa * l0Bottom Boundary Condition
At the bottom, the turbulence length scale goes to zero:
The bottom TKE is determined by bottom friction:
uf_bottom_val[s_i, s_j] = safe_sqrt(u_bot_val**2 + v_bot_val**2) * const1where const1 = (16.6**(2.0/3.0)) * sef.
Implementation: The advq and profq Subroutines
advq: Horizontal Advection and Diffusion
The advq subroutine advects and diffuses
Key steps in advq:
- Horizontal advection at interior U/V points
- Horizontal diffusion using the
aam(ambient horizontal viscosity) field - Vertical advection term:
- Time stepping: Leapfrog update with depth scaling
profq: Vertical Diffusion and Production
The profq subroutine is the core of the Mellor-Yamada 2.5 implementation. It performs a vertical implicit solve for
The sequence in profq:
1. Compute diffusion coefficients (a/c matrices) for Kq
2. Calculate buoyancy frequency (N^2) at interfaces
3. Determine length scale l = |q^2l| / |q^2|
4. Apply wall proximity correction to l
5. Calculate shear production (P_s)
6. Forward sweep for q^2 (Thomas algorithm)
7. Backward sweep for q^2
8. Forward sweep for q^2l (with wall-enhanced dissipation)
9. Backward sweep for q^2l
10. Clip negative values to small positive floor
11. Compute stability functions S_M, S_H from gh
12. Update K_M, K_H, K_qEmpirical Constants
The standard Mellor-Yamada constants used in NeuralPOM are:
| Symbol | Value | Description |
|---|---|---|
a1) | 0.92 | Turbulence closure constant |
b1) | 16.6 | Turbulence closure constant |
a2) | 0.74 | Turbulence closure constant |
b2) | 10.1 | Turbulence closure constant |
c1) | 0.08 | Turbulence closure constant |
e1) | 1.8 | Wall proximity constant |
e2) | 1.33 | Wall proximity constant |
| -- | (not directly used in level-2.5) | |
kappa) | 0.4 | von Karman constant |
cbcnst) | 100.0 | Surface boundary constant |
| Surface length scale constant | ||
| 1.0 | Shear energy factor |
These constants are defined at the beginning of profq:
a1=0.92; b1=16.6; a2=0.74; b2=10.1; c1=0.08
e1=1.8; e2=1.33; sef=1.0
cbcnst=100.0; surfl=2.0e5; shiw=0.0The G_H Limiter
To prevent unrealistically large mixing in strongly stratified conditions, the stability-related quantity
This is equivalent to a critical gradient Richardson number of approximately
gh[:, :, 1:kbm1] = (l_out[:, :, 1:kbm1]**2) * boygr[:, :, 1:kbm1] / (q2b_abs[:, :, 1:kbm1] + 1e-20)
gh = torch.clamp(gh, max=0.028)Background Vertical Mixing
A molecular background viscosity umol is added to the turbulent coefficients to prevent zero mixing and maintain numerical stability:
In the Thomas algorithm tridiagonal coefficients:
num = -dti2 * (km_u[s_i, s_j, k] + umol)A small floor value small is enforced on sqrt errors in the stability function computation:
uf_sl_new = torch.where(mask_small, torch.tensor(small), uf_sl)
vf_sl_new = torch.where(mask_small, 0.1 * dt_sl * small, vf_sl)References
- Mellor, G. L., & Yamada, T. (1982). Development of a turbulence closure model for geophysical fluid problems. Reviews of Geophysics, 20(4), 851--875.
- Mellor, G. L. (2004). Users guide for a three-dimensional, primitive equation, numerical ocean model. Princeton University.
- Burchard, H., & Bolding, K. (2001). Comparative analysis of four second-moment turbulence closure models for the oceanic mixed layer. Journal of Physical Oceanography, 31(8), 1943--1968.
