Apply the KPP non-local (counter-gradient) tracer tendency
computed by vmix_apply_kpp_overlay. Updates
hT, hS from the divergence of gamma_t / gamma_s at
interfaces:
hT(k) += dt · (γ_T(k+1) - γ_T(k))
(interface k+1 sits above layer k, interface k below — the ROMS-style k=1-bed convention). γ at the bed (k=1) and free surface (k=nz+1) is identically zero, so the surface and bed layers see only the lower / upper neighbour’s γ.
No-op when γ is all zero (stabilizing flux or KPP disabled). Touches only the layers with index_salinity / index_temperature in the tracer registry — extra tracers are diffusive only under KPP.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(hgrid_t), | intent(in) | :: | grid | |||
| type(ocean_vmix_t), | intent(in) | :: | this | |||
| type(multilayer_state_t), | intent(inout) | :: | ms | |||
| real(kind=wp), | intent(in) | :: | dt |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| integer, | private | :: | i | ||||
| integer, | private | :: | it_S | ||||
| integer, | private | :: | it_T | ||||
| integer, | private | :: | it_ps | ||||
| integer, | private | :: | j | ||||
| integer, | private | :: | k | ||||
| integer, | private | :: | nx | ||||
| integer, | private | :: | ny | ||||
| integer, | private | :: | nz |
pure subroutine vmix_apply_nonlocal_tendencies(grid, this, ms, dt) !! Apply the KPP non-local (counter-gradient) tracer tendency !! computed by `vmix_apply_kpp_overlay`. Updates !! `hT`, `hS` from the divergence of `gamma_t` / `gamma_s` at !! interfaces: !! !! hT(k) += dt · (γ_T(k+1) - γ_T(k)) !! !! (interface k+1 sits above layer k, interface k below — the !! ROMS-style k=1-bed convention). γ at the bed (k=1) and !! free surface (k=nz+1) is identically zero, so the surface !! and bed layers see only the lower / upper neighbour's γ. !! !! No-op when γ is all zero (stabilizing flux or KPP !! disabled). Touches only the layers with index_salinity / !! index_temperature in the tracer registry — extra tracers !! are diffusive only under KPP. type(hgrid_t), intent(in) :: grid type(ocean_vmix_t), intent(in) :: this type(multilayer_state_t), intent(inout) :: ms real(wp), intent(in) :: dt integer :: i, j, k, nx, ny, nz, it_T, it_S, it_ps nx = grid%nx_total ny = grid%ny_total nz = ms%nz_ml it_T = ms%idx_temperature it_S = ms%idx_salinity it_ps = ms%idx_pseudo_salt if (it_T > 0) then do concurrent(k=1:nz, j=1:ny, i=1:nx) ms%tracers(it_T)%hTr(i, j, k) = ms%tracers(it_T)%hTr(i, j, k) + & dt*(this%gamma_t(i, j, k + 1) - & this%gamma_t(i, j, k)) end do end if if (it_S > 0) then do concurrent(k=1:nz, j=1:ny, i=1:nx) ms%tracers(it_S)%hTr(i, j, k) = ms%tracers(it_S)%hTr(i, j, k) + & dt*(this%gamma_s(i, j, k + 1) - & this%gamma_s(i, j, k)) end do end if ! Pseudo-salt mirror: identical gamma_s expression, identical dt ! (§5.4.2) — `it_ps` is a HOST scalar hoisted above, exactly like ! `it_T`/`it_S`, so this is legal inside `do concurrent`. if (it_ps > 0) then do concurrent(k=1:nz, j=1:ny, i=1:nx) ms%tracers(it_ps)%hTr(i, j, k) = ms%tracers(it_ps)%hTr(i, j, k) + & dt*(this%gamma_s(i, j, k + 1) - & this%gamma_s(i, j, k)) end do end if end subroutine vmix_apply_nonlocal_tendencies