Turbulence
TKE-based turbulence closures, as well as droplet turbulent motion.
Droplets.bott1997term — Method
bott1997term(grid, k, constants)Buoyancy-flux term at level k following Bott (1997), in place of a directly computed dry/moist buoyancy frequency.
Droplets.bott_mixing_length! — Method
bott_mixing_length!(l, grid, tke, constants)Bott (1996) mixing length
Droplets.deardorff_mixing_length! — Method
deardorff_mixing_length!(l, grid, tke, constants)Deardorff (1980)-style mixing length.
Droplets.diffuse_fields! — Method
diffuse_fields!(grid, tke, K_h, K_m, K_e, constants, dt, turbdata)One implicit-diffusion timestep for the full prognostic state:
ThetalQtVarorThetaQvVar, with surface heat fluxtke.SHFand latent heat fluxtke.LHF- horizontal wind components
grid.wind.u/grid.wind.v, with surface momentum flux fromtke.u_starand an explicit Coriolis update afterward usingtke.geostrophic_u/tke.geostrophic_v - TKE
grid.states.e, with surface flux2.5 * tke.u_star^3, floored at 0
Diffusion is density-weighted (ρ_arg = grid.states.ρ) when tke.density_weighted_diffusion is true, else unweighted. Density grid.states.ρ is re-diagnosed after the thermodynamic update via ρ_calc_θ!.
Droplets.diffuse_thermo! — Method
diffuse_thermo!(::ThetaQvVar, grid, tke, K_h, dt, dz, nz, turbdata, theta_surf_flux, constants, ρ_arg)Implicitly diffuse θ and qv directly, then recompute qt_tmp and θl_tmp from the diffused θ/qv and the (unmodified) ql_tmp.
Droplets.diffuse_thermo! — Method
diffuse_thermo!(::ThetalQtVar, grid, tke, K_h, dt, dz, nz, turbdata, theta_surf_flux, constants, ρ_arg)Implicitly diffuse θl and qt (conserved under phase change), then reconstruct θ from the diffused θl and the pre-diffusion ql_tmp, and qv as qt_tmp - ql_tmp.
Droplets.edmfx_mixing_length! — Method
edmfx_mixing_length!(l, grid, tke, constants)adapted from ClimaAtmos's EDMF-X closure (ClimaAtmos.jl/src/prognostic_equations/edmfx_closures.jl, mixing_length; coefficients from Lopez-Gomez et al. 2020, https://doi.org/10.1029/2020MS002162).
Simplifications relative to the ClimaAtmos source (single-column, no EDMF updraft/ environment decomposition here):
- lW: simplified to neutral von Kármán scaling (κz), Blackadar (1962)-blended with a fixed asymptotic scale `tke.linf` so it doesn't grow unbounded with height; the Businger/Gryanik Monin-Obukhov stability correction was not ported.
- lTKE: the production-dissipation balance omits the EDMF exchange term (`ᶜtkeexch`), which has no counterpart outside EDMF's updraft/environment split.
- Turbulent Prandtl number fixed at 1 in the buoyancy-production term.
- Scales are combined with a hard minimum rather than ClimaAtmos's smooth minimum.
- Floored (not capped) at
dz, matching this codebase's existing convention.
Droplets.mixing_length! — Method
mixing_length!(scheme, l, grid, tke, constants)Dispatch on tke.mixing_length_scheme to fill l in place: DeardorffMixing → deardorff_mixing_length!, BottMixing → bott_mixing_length!, EDMFXMixing → edmfx_mixing_length!.
Droplets.my25_stability_functions — Method
my25_stability_functions(l, K_h, K_m, K_e, GH, GM, SM, SH, k, tke, grid, constants)Mellor-Yamada level-2.5 (1982) stability functions at level k, following Bott (1996,1997).
Droplets.saturation_specific_humidity — Method
saturation_specific_humidity(θ, P, q_vap, constants)Saturation specific humidity at temperature and pressure P
Droplets.tke_update! — Method
tke_update!(l, SM, SH, GM, GH, grid, tke, dt, constants, turbdata)Advance grid.states.e (TKE) one timestep at each level via a production/ dissipation update, implicit in the dissipation term
Droplets.turb_timestep! — Method
turb_timestep!(::DynOFF, grid, tke, constants, dt, dynamics, turbdata)Turbulence scheme disabled.
Droplets.turb_timestep! — Method
turb_timestep!(::DynON, grid, tke, constants, dt, dynamics, turbdata)Advance the TKE-closure turbulence scheme by one timestep. Computes the mixing length (tke.mixing_length_scheme) and Mellor-Yamada stability functions/eddy diffusivities (K_h, K_m, K_e) from the current TKE field, runs turbulent droplet diffusion, implicitly diffuses the prognostic fields (thermodynamic pair, wind, TKE) via diffuse_fields!, records the resulting vertical-transport TKE tendency, then updates TKE via production/dissipation with tke_update!.
Droplets.tke_settings — Type
tke_settings{FT}(; kwargs...)Configuration and tunable coefficients for the prognostic-TKE turbulence closure: surface forcing (u_star, SHF, LHF), geostrophic wind profiles (geostrophic_u, geostrophic_v), Mellor-Yamada/Galperin coefficients (c_n, vk, my_diss, GH_lims), mixing-length scheme coefficients for bott_mixing_length! (bott_α, bott_β) and edmfx_mixing_length! (c_m, c_d, c_b, l_inf), which mixing-length scheme and thermodynamic variable pair to dispatch on (mixing_length_scheme, thermo_variable), and knobs for the droplet-diffusion schemes in this file (average_e_l_3pt, droplet_diffusion_length_dz, tau_max) and for implicit_diffuse! (density_weighted_diffusion).
Droplets.S2_flow_deformation — Method
S2_flow_deformation(grid, k, constants, tke)Squared vertical wind shear |dU/dz|² at level k, used as the shear-production term in the Mellor-Yamada stability functions.
Droplets.calculate_buoyancy_frequency — Method
calculate_buoyancy_frequency(grid, k, constants; dry=false)Brunt-Väisälä (buoyancy) frequency squared, N², at level k. With dry=true, uses a centered difference of dry potential temperature θ; otherwise uses moist θl_tmp scaled by bott1997term (Bott 1997's liquid-water correction to the moist static stability).
Droplets.dθldz — Method
dθldz(θl_t, grid, k, constants)Centered (one-sided at the boundaries) vertical gradient of liquid-water potential temperature θl_t at level k.
Droplets.implicit_diffuse! — Method
implicit_diffuse!(ϕ, K_centers, dt, dz, nz, turbdata; sfc_flux=nothing, ρ=nothing)Advance the diffusion equation ∂ϕ/∂t = ∂/∂z(K ∂ϕ/∂z) (or the mass-weighted ∂/∂z(ρK ∂ϕ/∂z) form when ρ is given) by one implicit (Crank-Nicolson) timestep in place, via the Thomas algorithm. Both boundaries are no-flux unless sfc_flux is given.
Droplets.partmc_jump_diffusion! — Method
partmc_jump_diffusion!(::DynON, grid, droplets, K_centers, dt, dz, nz)partmc-inspired stochastic diffusion of cloud droplets (radius < 40 μm) between adjacent cells. ... Differences due to weighting handling, not sure if this should be used yet
Droplets.run_droplet_diffusion! — Method
run_droplet_diffusion!(scheme, onoff, l, droplets, grid, tke, dt, K_h, e_prev)Dispatch on dynamics.droplet_diffusion_scheme to the corresponding turbulent droplet transport implementation in this file: NoDropletDiffusion → no-op, OUDropletDiffusion → turbulent_droplet_diffusion!, WellMixedDropletDiffusion → turbulent_droplet_diffusion_wellmixed!, WeilDropletDiffusion → weil_turbulent_droplet_diffusion!, VisserDropletDiffusion → turbulent_droplet_diffusion_visser!. onoff is dynamics.turbulent_droplet_diffusion_on, an independent DynON/DynOFF master switch forwarded to whichever scheme is picked.
Droplets.stochastic_jump_diffusion! — Method
stochastic_jump_diffusion!(::DynON, grid, droplets, K_centers, dt, dz, nz)Discrete 1D Monte Carlo analogue of Eulerian K-diffusion: only cloud droplets (radius < 40 μm) individually jump to the cell above/below with probability proportional to the face diffusive flux K_face*dt/dz² (renormalized if the two probabilities would sum above 1), independent of each droplet's multiplicity ξ.
Droplets.turbulent_droplet_diffusion! — Method
turbulent_droplet_diffusion!(::DynOFF, l, droplets, grid, tke, dt)
turbulent_droplet_diffusion!(::DynON, l, droplets, grid, tke, dt)Stochastic sub-grid vertical transport of droplets via droplet specific w_prime (adapted from Abade & Grabowski 2018, restricted to depend on TKE alone, with the Gillespie (1996) two-normal weak-second-order integration scheme) Droplets at or above the diagnosed inversion (grid.states.qv < 0.008, rediagnosed every time step) have w_prime clamped to ≤ 0 to not coast in turbulence free zones
Droplets.turbulent_droplet_diffusion_visser! — Method
turbulent_droplet_diffusion_visser!(::DynOFF, droplets, grid, K_centers, dt)
turbulent_droplet_diffusion_visser!(::DynON, droplets, grid, K_centers, dt)Random-walk droplet transport directly from an eddy diffusivity profile K_centers (Visser 1997): each droplet is displaced by a deterministic drift dK/dz * dt plus Gaussian noise sqrt(2*K_half*dt),
Droplets.turbulent_droplet_diffusion_wellmixed! — Method
turbulent_droplet_diffusion_wellmixed!(::DynOFF, l, droplets, grid, tke, dt)
turbulent_droplet_diffusion_wellmixed!(::DynON, l, droplets, grid, tke, dt)Same Ornstein-Uhlenbeck droplet-transport parameterization as turbulent_droplet_diffusion! (tau = Ct*l*sqrt(Ce/e), capped at tke.tau_max), but with an added well-mixed drift term (2/3) ∂e/∂z (per Bahlali, Henry & Carissimo 2020) that turbulent_droplet_diffusion! omits, so a uniform droplet distribution stays uniform under a spatially varying e.