subroutine register_kappa_shear(cfg, schema)
!! `&ocean_kappa_shear` (JHL08 shear-driven interior mixing).
!! Exclusive `> 0` bounds (ri_crit, kappa_0, tol_err, prandtl_turb)
!! are left to the configure-time strict checks.
type(config_t), target, intent(in) :: cfg
type(nml_schema_t), intent(inout) :: schema
type(nml_group_t) :: g
logical, pointer :: pl
real(wp), pointer :: pr
integer, pointer :: pi
g%name = "ocean_kappa_shear"
g%doc = "JHL08 shear-driven interior turbulence (kappa-shear)."
pl => cfg%ocean%kshear%enable
call g%add(nml_logical("enable", pl, &
"Master switch (requires use_closure + thermodynamics)"))
pr => cfg%ocean%kshear%ri_crit
call g%add(nml_real("ri_crit", pr, "Critical Richardson number", &
units="nondim"))
pr => cfg%ocean%kshear%shearmix_rate
call g%add(nml_real("shearmix_rate", pr, "Shear source-rate coefficient"))
pr => cfg%ocean%kshear%fri_curvature
call g%add(nml_real("fri_curvature", pr, "Ri-function curvature in the shear source"))
pr => cfg%ocean%kshear%c_n
call g%add(nml_real("c_n", pr, "TKE decay-rate coefficient vs stratification N"))
pr => cfg%ocean%kshear%c_s
call g%add(nml_real("c_s", pr, "TKE decay-rate coefficient vs shear S"))
pr => cfg%ocean%kshear%lambda
call g%add(nml_real("lambda", pr, "Buoyancy mixing-length-scale coefficient"))
pr => cfg%ocean%kshear%lz_rescale
call g%add(nml_real("lz_rescale", pr, "Boundary-distance length-scale rescale factor"))
pr => cfg%ocean%kshear%kappa_0
call g%add(nml_real("kappa_0", pr, "Background diffusivity (pre-step kappa)", &
units="m^2/s"))
pr => cfg%ocean%kshear%kappa_seed
call g%add(nml_real("kappa_seed", pr, "Iteration seed diffusivity", units="m^2/s"))
pr => cfg%ocean%kshear%kappa_trunc
call g%add(nml_real("kappa_trunc", pr, "Diffusivity truncated to 0 below this", &
units="m^2/s"))
pr => cfg%ocean%kshear%tke_bg
call g%add(nml_real("tke_bg", pr, "Background TKE (Q denominator floor)", &
units="m^2/s^2"))
pr => cfg%ocean%kshear%tol_err
call g%add(nml_real("tol_err", pr, "Picard convergence tolerance"))
pi => cfg%ocean%kshear%max_inner_it
call g%add(nml_int("max_inner_it", pi, "Inner Picard iteration cap", min=1))
pi => cfg%ocean%kshear%max_substep_it
call g%add(nml_int("max_substep_it", pi, "Outer adaptive-substep iteration cap", min=1))
pr => cfg%ocean%kshear%src_max_chg
call g%add(nml_real("src_max_chg", pr, "Adaptive-dt source-change tolerance band"))
pr => cfg%ocean%kshear%prandtl_turb
call g%add(nml_real("prandtl_turb", pr, "Kv = prandtl_turb * Kd into the momentum solve"))
pr => cfg%ocean%kshear%vel_underflow
call g%add(nml_real("vel_underflow", pr, "Velocity snap-to-zero magnitude", &
units="m/s"))
pl => cfg%ocean%kshear%massless_merge
call g%add(nml_logical("massless_merge", pl, &
"Merge vanished (<H_VANISHED) layers onto the "// &
"massive sub-grid before the column solve "// &
"(default off; identity columns bypass)"))
pl => cfg%ocean%kshear%at_vertex
call g%add(nml_logical("at_vertex", pl, &
"Solve the JHL08 columns at C-grid corners "// &
"(vorticity points) from the native face "// &
"velocities, averaging corner Kd back to tracer "// &
"points (MOM6 VERTEX_SHEAR; v1 = Kd only)"))
pl => cfg%ocean%kshear%vertex_geometric_mean
call g%add(nml_logical("vertex_geometric_mean", pl, &
"Geometric (vs arithmetic) mean in the "// &
"corner->centre Kd average (MOM6 "// &
"VERTEX_SHEAR_GEOMETRIC_MEAN)"))
pr => cfg%ocean%kshear%vertex_geomean_kdmin
call g%add(nml_real("vertex_geomean_kdmin", pr, &
"Floor applied to each corner Kd before the "// &
"geometric mean (inert unless vertex_geometric_mean; "// &
"OM5 configs use 1e-9)", &
units="m^2/s", min=0.0_wp))
call schema%add_group(g)
end subroutine register_kappa_shear