ocean_vmix_config_t Derived Type

type, public :: ocean_vmix_config_t


Inherited by

type~~ocean_vmix_config_t~~InheritedByGraph type~ocean_vmix_config_t ocean_vmix_config_t type~ocean_config_t ocean_config_t type~ocean_config_t->type~ocean_vmix_config_t vmix type~config_t config_t type~config_t->type~ocean_config_t ocean type~ocean_handle_t ocean_handle_t type~ocean_handle_t->type~config_t cfg

Components

Type Visibility Attributes Name Initial
real(kind=wp), public :: bkgnd_delta = 222.0_wp

Bryan-Lewis transition half-width (m).

logical, public :: bkgnd_henyey = .false.

Henyey, Wright & Flatte (1986) JGR 91:8487 latitude-dependent internal-wave factor (constant-N0 simplification of Harrison & Hallberg 2008, JPO 38:1894), scaling the SCALAR background tracer diffusivities kt_bg/ks_bg and floored at bkgnd_kd_min. MUTUALLY EXCLUSIVE with bkgnd_profile (Bryan-Lewis) and requires a non-cartesian grid_config — both fail-loud at configure. Default off ⇒ bit-identical.

real(kind=wp), public :: bkgnd_henyey_max_lat = 95.0_wp

Latitude (degN) poleward of which the Henyey factor is reset to its minimum floor; compared against |latitude| so both hemispheres clamp. > 90 so inert for any real latitude out of the box.

real(kind=wp), public :: bkgnd_henyey_n0_2omega = 20.0_wp

Ratio of the assumed reference buoyancy frequency N0 to twice the planetary rotation rate (nondim).

real(kind=wp), public :: bkgnd_kd_deep = 1.3e-4_wp

Deep-asymptote background tracer diffusivity (m^2/s).

real(kind=wp), public :: bkgnd_kd_min = -1.0_wp

Minimum background tracer diffusivity (m^2/s) under the Henyey scaling — max(Kd_min, Kd*L(phi)). Negative = unset ⇒ resolved to 0.01*kt_bg (the reference KD_MIN default).

real(kind=wp), public :: bkgnd_kd_sfc = 1.0e-5_wp

Surface-asymptote background tracer diffusivity (m^2/s).

real(kind=wp), public :: bkgnd_prandtl = 1.0_wp

Background Prandtl number: Kv_bg = bkgnd_prandtl * Kd_bg.

logical, public :: bkgnd_profile = .false.

Enable the Bryan & Lewis (1979) depth-varying background diffusivity instead of the constant interior background. Default off (bit-identical).

real(kind=wp), public :: bkgnd_z0 = 2500.0_wp

Bryan-Lewis transition-centre depth (m, positive down).

character(len=8), public :: buoyancy_coeffs = "constant"

Where the vmix closures take their α (thermal expansion) and β (haline contraction) from — "constant" (DEFAULT) or "eos". Parsed by parse_buoyancy_coeffs (rdb_ocean_vmix.F90); keep the allowed= list and that routine’s case arms in lockstep.

  • "constant" — the scalar &ocean_ic_nml alpha_T / beta_S off the EOS handle, whatever the active EOS is. Historical behaviour ⇒ bit-identical for every shipped namelist. For eos = "linear" these ARE the true coefficients, so the setting is physically exact there.
  • "eos" — eos_buoyancy_coeffs evaluated per column / per interface from the ACTIVE equation of state (α = −∂ρ/∂T, β = +∂ρ/∂S, both analytic). Under eos = "linear" it returns those same handle members bit-for-bit, so the two settings are byte-identical there — the knob only bites under a NONLINEAR EOS (wright / roquet).

Routes THREE consumers: the KPP B_0 surface buoyancy flux in both passes of vmix_kpp_overlay_impl (and hence the non-local γ gate, which switches on B_0 < 0), and the double-diffusion density ratio R_ρ = α·ΔT / β·ΔS in vmix_split_ddiff_*_impl. Every OTHER α/β-like quantity on the ocean path already tracks the active EOS: EPBL, kappa-shear, tidal mixing, the isopycnal slopes and Redi go through eos_specvol_derivs, while PP81’s N², the convective trigger, the wave speed and MLE difference ms%rho_layer itself.

Why it matters: seawater’s thermal expansion collapses toward zero near the freezing point and roughly doubles by 1000 dbar, so under an ice shelf a constant α mis-sizes the melt-driven buoyancy flux that sets the boundary layer. validate_config WARNS (does not refuse) on cavity melt × nonlinear EOS × "constant".

logical, public :: direct_stress = .false.

When .true. the wind stress is distributed across the top hmix_stress metres rather than the surface-most layer.

integer, public :: dt_therm_ratio = 1

Thermodynamic + tracer-advection step runs at ratio · dt_dynamic. Default 1.

integer, public :: dt_tracer_advect_ratio = 1

Horizontal tracer advection runs every ratio · dt_dynamic via accumulated mass fluxes drained in one windowed advect. 1 (default) ⇒ every step, bit-identical. dt_therm_ratio must be an integer multiple of this (configure-time check).

logical, public :: harmonic_visc = .false.

When .true. vdiff uses the harmonic mean of adjacent layer thicknesses in the face-thickness denominator. Default .false. = arithmetic mean.

real(kind=wp), public :: hmix_fixed = 20.0_wp

Mixed-layer thickness (m) for the kv_ml_invz2 profile. Default 20 m.

real(kind=wp), public :: hmix_stress = 20.0_wp

Thickness (m) of the surface slab for direct_stress. Default 20 m.

real(kind=wp), public :: kd_max = huge(1.0_wp)

Ceiling on tracer diffusivity kt/ks (m^2/s). Default huge = no clip.

integer, public :: kd_smooth_iterations = 0

1-2-1 horizontal smoothing passes on kv/kt at interfaces. Default 0 = off.

real(kind=wp), public :: kpp_c_vt2 = 1.8_wp

KPP unresolved-turbulence coefficient for the V_t^2 term in the bulk-Ri denominator (LMD94 eq 23). 0 disables V_t^2.

real(kind=wp), public :: kpp_cs_nonlocal = 6.3_wp

KPP non-local (counter-gradient) transport coefficient C_s (LMD94 eq 20, limit value).

real(kind=wp), public :: kpp_ri_crit = 0.3_wp

Critical bulk Richardson number for the KPP BL-depth sweep (LMD94 §3; MOM6 KPP_BULK_RI default 0.3).

real(kind=wp), public :: kv_max = huge(1.0_wp)

Ceiling on momentum viscosity kv (m^2/s). Default huge = no clip.

real(kind=wp), public :: kv_ml_invz2 = 0.0_wp

Extra near-surface vertical viscosity (m²/s) with a 1/(z·hmix)² profile in the top hmix_fixed metres. Zero (default) = no change.

real(kind=wp), public :: pp81_alpha = 5.0_wp

PP81 Richardson-number scaling coefficient (paper value 5; implementations vary 4-10).

real(kind=wp), public :: pp81_kappa_bg = 1.0e-5_wp

PP81 background diffusivity (m^2/s). Also seeds vmix%kt_bg/vmix%ks_bg.

real(kind=wp), public :: pp81_nu0 = 1.0e-2_wp

PP81 Richardson-dependent viscosity scale (m^2/s).

real(kind=wp), public :: pp81_nu_bg = 1.0e-4_wp

PP81 background viscosity (m^2/s). Also seeds vmix%kv_bg (the assembly floor) — see vmix_seed_backgrounds.

real(kind=wp), public :: shear2_floor = 1.0e-10_wp

Floor on |du/dz|^2 + |dv/dz|^2 in the PP81 Ri denominator (1/s^2).

character(len=8), public :: tracer_recon = "ppm"

Face-reconstruction scheme for the WINDOWED horizontal tracer-advection drain (dt_tracer_advect_ratio > 1 path): ppm (default, CW-PPM, bit-identical) | weno5 | weno7 | weno9 (WENO-Z swept-average, rung-adaptive; reuses the coastal reconstruction ladder). Per-rung nghost minimum (weno5→3, weno7→4, weno9→5) is fail-loud at configure. This is the SEPARATE ocean knob — independent of the coastal tracer_recon.

logical, public :: use_closure = .true.

Master switch for the vmix (vertical-mixing) module. When .true. (default), the chosen interior closure (PP81) populates vmix%kv / vmix%kt from the local Richardson number and vdiff reads them. When .false., vdiff uses its scalar K_v_* defaults and vmix kernels never run.

logical, public :: use_kpp = .true.

KPP surface-boundary-layer overlay. Requires use_closure. Adds the cubic-profile kv overlay plus non-local γ_T/γ_S transport.

logical, public :: vmix_guard = .false.

Debug-gated negative/NaN diffusivity guard. Default off.


Source Code

   type :: ocean_vmix_config_t
      logical :: use_closure = .true.
         !! Master switch for the vmix (vertical-mixing) module.  When
         !! `.true.` (default), the chosen interior closure (PP81)
         !! populates `vmix%kv` / `vmix%kt` from the local Richardson
         !! number and vdiff reads them.  When `.false.`, vdiff uses
         !! its scalar `K_v_*` defaults and vmix kernels never run.
      logical :: use_kpp = .true.
         !! KPP surface-boundary-layer overlay.  Requires `use_closure`.
         !! Adds the cubic-profile kv overlay plus non-local γ_T/γ_S transport.
      logical :: direct_stress = .false.
         !! When `.true.` the wind stress is distributed across the top
         !! `hmix_stress` metres rather than the surface-most layer.
      real(wp) :: hmix_stress = 20.0_wp
         !! Thickness (m) of the surface slab for `direct_stress`.  Default 20 m.
      real(wp) :: kv_ml_invz2 = 0.0_wp
         !! Extra near-surface vertical viscosity (m²/s) with a `1/(z·hmix)²`
         !! profile in the top `hmix_fixed` metres.  Zero (default) = no change.
      real(wp) :: hmix_fixed = 20.0_wp
         !! Mixed-layer thickness (m) for the `kv_ml_invz2` profile.  Default 20 m.
      logical :: harmonic_visc = .false.
         !! When `.true.` vdiff uses the harmonic mean of adjacent layer
         !! thicknesses in the face-thickness denominator.  Default `.false.`
         !! = arithmetic mean.
      integer :: dt_therm_ratio = 1
         !! Thermodynamic + tracer-advection step runs at `ratio · dt_dynamic`.
         !! Default 1.
      integer :: dt_tracer_advect_ratio = 1
         !! Horizontal tracer advection runs every `ratio · dt_dynamic` via
         !! accumulated mass fluxes drained in one windowed advect.  1
         !! (default) ⇒ every step, bit-identical.  `dt_therm_ratio` must be
         !! an integer multiple of this (configure-time check).
      real(wp) :: kv_max = huge(1.0_wp)
         !! Ceiling on momentum viscosity kv (m^2/s).  Default `huge` = no clip.
      real(wp) :: kd_max = huge(1.0_wp)
         !! Ceiling on tracer diffusivity kt/ks (m^2/s).  Default `huge` = no clip.
      integer :: kd_smooth_iterations = 0
         !! 1-2-1 horizontal smoothing passes on kv/kt at interfaces.  Default 0 = off.
      logical :: vmix_guard = .false.
         !! Debug-gated negative/NaN diffusivity guard.  Default off.
      logical :: bkgnd_profile = .false.
         !! Enable the Bryan & Lewis (1979) depth-varying background
         !! diffusivity instead of the constant interior background.
         !! Default off (bit-identical).
      real(wp) :: bkgnd_kd_sfc = 1.0e-5_wp
         !! Surface-asymptote background tracer diffusivity (m^2/s).
      real(wp) :: bkgnd_kd_deep = 1.3e-4_wp
         !! Deep-asymptote background tracer diffusivity (m^2/s).
      real(wp) :: bkgnd_z0 = 2500.0_wp
         !! Bryan-Lewis transition-centre depth (m, positive down).
      real(wp) :: bkgnd_delta = 222.0_wp
         !! Bryan-Lewis transition half-width (m).
      real(wp) :: bkgnd_prandtl = 1.0_wp
         !! Background Prandtl number: Kv_bg = bkgnd_prandtl * Kd_bg.
      logical :: bkgnd_henyey = .false.
         !! Henyey, Wright & Flatte (1986) JGR 91:8487 latitude-dependent
         !! internal-wave factor (constant-`N0` simplification of Harrison &
         !! Hallberg 2008, JPO 38:1894), scaling the SCALAR background tracer
         !! diffusivities `kt_bg`/`ks_bg` and floored at `bkgnd_kd_min`.
         !! MUTUALLY EXCLUSIVE with `bkgnd_profile` (Bryan-Lewis) and
         !! requires a non-cartesian `grid_config` — both fail-loud at
         !! configure.  Default off ⇒ bit-identical.
      real(wp) :: bkgnd_kd_min = -1.0_wp
         !! Minimum background tracer diffusivity (m^2/s) under the Henyey
         !! scaling — `max(Kd_min, Kd*L(phi))`.  Negative = unset ⇒ resolved
         !! to 0.01*kt_bg (the reference `KD_MIN` default).
      real(wp) :: bkgnd_henyey_n0_2omega = 20.0_wp
         !! Ratio of the assumed reference buoyancy frequency N0 to twice
         !! the planetary rotation rate (nondim).
      real(wp) :: bkgnd_henyey_max_lat = 95.0_wp
         !! Latitude (degN) poleward of which the Henyey factor is reset to
         !! its minimum floor; compared against |latitude| so both
         !! hemispheres clamp.  > 90 so inert for any real latitude out of
         !! the box.
      character(len=8) :: tracer_recon = "ppm"
         !! Face-reconstruction scheme for the WINDOWED horizontal
         !! tracer-advection drain (`dt_tracer_advect_ratio > 1` path):
         !! ppm (default, CW-PPM, bit-identical) | weno5 | weno7 | weno9
         !! (WENO-Z swept-average, rung-adaptive; reuses the coastal
         !! reconstruction ladder).  Per-rung nghost minimum (weno5→3,
         !! weno7→4, weno9→5) is fail-loud at configure.  This is the
         !! SEPARATE ocean knob — independent of the coastal `tracer_recon`.

      ! ---- PP81 interior closure + KPP BL-depth constants ----
      ! Each default equals the current `ocean_vmix_t` field default
      ! (rdb_ocean_vmix.F90) so an nml that never mentions these keys is
      ! bit-identical.  `kpp_*` names (not bare `ri_crit`/`cs_nonlocal`/
      ! `c_vt2`) avoid a collision with `&ocean_kshear_nml ri_crit` (a
      ! DIFFERENT physical quantity, the JHL08 critical Ri).  These route
      ! to the OCEAN vmix slot — do not confuse with the similarly-named
      ! `&nonhydrostatic_nml kpp_*` keys, which are the live COASTAL path.
      real(wp) :: pp81_nu0 = 1.0e-2_wp
         !! PP81 Richardson-dependent viscosity scale (m^2/s).
      real(wp) :: pp81_nu_bg = 1.0e-4_wp
         !! PP81 background viscosity (m^2/s).  Also seeds `vmix%kv_bg`
         !! (the assembly floor) — see `vmix_seed_backgrounds`.
      real(wp) :: pp81_kappa_bg = 1.0e-5_wp
         !! PP81 background diffusivity (m^2/s).  Also seeds
         !! `vmix%kt_bg`/`vmix%ks_bg`.
      real(wp) :: pp81_alpha = 5.0_wp
         !! PP81 Richardson-number scaling coefficient (paper value 5;
         !! implementations vary 4-10).
      real(wp) :: shear2_floor = 1.0e-10_wp
         !! Floor on |du/dz|^2 + |dv/dz|^2 in the PP81 Ri denominator (1/s^2).
      real(wp) :: kpp_ri_crit = 0.3_wp
         !! Critical bulk Richardson number for the KPP BL-depth sweep
         !! (LMD94 §3; MOM6 KPP_BULK_RI default 0.3).
      real(wp) :: kpp_cs_nonlocal = 6.3_wp
         !! KPP non-local (counter-gradient) transport coefficient C_s
         !! (LMD94 eq 20, limit value).
      real(wp) :: kpp_c_vt2 = 1.8_wp
         !! KPP unresolved-turbulence coefficient for the V_t^2 term in
         !! the bulk-Ri denominator (LMD94 eq 23).  0 disables V_t^2.

      ! ---- Source of the thermal-expansion / haline-contraction pair ----
      character(len=8) :: buoyancy_coeffs = "constant"
         !! Where the vmix closures take their α (thermal expansion) and
         !! β (haline contraction) from — `"constant"` (DEFAULT) or
         !! `"eos"`.  Parsed by `parse_buoyancy_coeffs`
         !! (`rdb_ocean_vmix.F90`); keep the `allowed=` list and that
         !! routine's `case` arms in lockstep.
         !!
         !!   * `"constant"` — the scalar `&ocean_ic_nml alpha_T` /
         !!     `beta_S` off the EOS handle, whatever the active EOS is.
         !!     Historical behaviour ⇒ **bit-identical** for every shipped
         !!     namelist.  For `eos = "linear"` these ARE the true
         !!     coefficients, so the setting is physically exact there.
         !!   * `"eos"` — `eos_buoyancy_coeffs` evaluated per column /
         !!     per interface from the ACTIVE equation of state
         !!     (`α = −∂ρ/∂T`, `β = +∂ρ/∂S`, both analytic).  Under
         !!     `eos = "linear"` it returns those same handle members
         !!     bit-for-bit, so the two settings are byte-identical
         !!     there — the knob only bites under a NONLINEAR EOS
         !!     (`wright` / `roquet`).
         !!
         !! Routes THREE consumers: the KPP `B_0` surface buoyancy flux
         !! in both passes of `vmix_kpp_overlay_impl` (and hence the
         !! non-local γ gate, which switches on `B_0 < 0`), and the
         !! double-diffusion density ratio `R_ρ = α·ΔT / β·ΔS` in
         !! `vmix_split_ddiff_*_impl`.  Every OTHER α/β-like quantity on
         !! the ocean path already tracks the active EOS: EPBL,
         !! kappa-shear, tidal mixing, the isopycnal slopes and Redi go
         !! through `eos_specvol_derivs`, while PP81's N², the convective
         !! trigger, the wave speed and MLE difference `ms%rho_layer`
         !! itself.
         !!
         !! Why it matters: seawater's thermal expansion collapses toward
         !! zero near the freezing point and roughly doubles by 1000 dbar,
         !! so under an ice shelf a constant α mis-sizes the melt-driven
         !! buoyancy flux that sets the boundary layer.  `validate_config`
         !! WARNS (does not refuse) on cavity melt × nonlinear EOS ×
         !! `"constant"`.
   end type ocean_vmix_config_t