subroutine ocean_lateral_mix_compute(grid, metrics, this, ms, &
res_fn_u, res_fn_v)
!! Dispatcher — runs the compute kernel for the active closure tag.
!! `LMIX_LEITH`/`LMIX_SMAGORINSKY` → harmonic `ah_face_*`;
!! `LMIX_LEITH_BIHARM` → biharmonic `nu4_face_*`; `LMIX_BIHARMONIC`
!! → scalar `nu_4` in the apply step (no per-face fill); `LMIX_NONE`
!! → no-op. The independent `smag_ah_active` switch separately
!! fills `nu4_face_*` from the strain rate. `this` is optional so
!! the driver can call unconditionally. `res_fn_u/v` (optional
!! VarMix resolution-function fields): when supplied AND
!! `resoln_scaled_visc`, scale the dynamic coefficients before the
!! clamps; absent ⇒ unscaled ⇒ bit-identical.
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(in) :: metrics
type(ocean_lateral_mix_t), intent(inout), optional :: this
type(multilayer_state_t), intent(in) :: ms
real(wp), intent(in), optional :: res_fn_u(grid%nx_total + 1, grid%ny_total)
real(wp), intent(in), optional :: res_fn_v(grid%nx_total, grid%ny_total + 1)
logical :: ran_closure
if (.not. present(this)) return
if (.not. this%is_init) return
! `ran_closure` tracks whether a flow-aware closure populated the
! HARMONIC `ah_face_*` field this step — only LMIX_LEITH/SMAGORINSKY
! do (the biharmonic closures fill `nu4_face_*` instead). It gates
! whether the live velocity-scale floor must first seed `ah_bg`.
ran_closure = .false.
! Forward the resolution-function fields straight through; Fortran
! 2008+ propagates `present()` across optional dummies, so an absent
! actual stays absent in the callee (kernels self-gate on present).
select case (this%closure)
case (LMIX_LEITH)
call ocean_lateral_mix_compute_leith(grid, metrics, this, ms, &
res_fn_u=res_fn_u, res_fn_v=res_fn_v)
ran_closure = .true.
case (LMIX_SMAGORINSKY)
call ocean_lateral_mix_compute_smag(grid, metrics, this, ms, &
res_fn_u=res_fn_u, res_fn_v=res_fn_v)
ran_closure = .true.
case (LMIX_LEITH_BIHARM)
call ocean_lateral_mix_compute_leith_biharm(grid, metrics, this, ms)
case (LMIX_BIHARMONIC)
! Constant biharmonic — driven by the scalar `nu_4` in the
! apply step; no flow-aware per-face fill required.
case default
! LMIX_NONE — scalar `nu_h` Laplacian, no flow-aware closure.
end select
! Live velocity-scale floor — max-combined into `ah_face_*`; seed the
! background first only when no harmonic closure populated the field.
if (this%kh_vel_scale_live > 0.0_wp) then
call ocean_lateral_mix_compute_vel_scale(grid, metrics, this, ms, &
seed_bg=.not. ran_closure)
end if
if (this%smag_ah_active) then
call ocean_lateral_mix_compute_smag_ah(grid, metrics, this, ms)
end if
end subroutine ocean_lateral_mix_compute