vmix_apply_nonlocal_tendencies Subroutine

public 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.

Arguments

Type IntentOptional 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

Called by

proc~~vmix_apply_nonlocal_tendencies~~CalledByGraph proc~vmix_apply_nonlocal_tendencies vmix_apply_nonlocal_tendencies proc~vmix_apply_in_stage vmix_apply_in_stage proc~vmix_apply_in_stage->proc~vmix_apply_nonlocal_tendencies proc~run_stage run_stage proc~run_stage->proc~vmix_apply_in_stage proc~run_stage_split run_stage_split proc~run_stage_split->proc~vmix_apply_in_stage proc~ocean_dyn_step ocean_dyn_step proc~ocean_dyn_step->proc~run_stage proc~ocean_dyn_step_split ocean_dyn_step_split proc~ocean_dyn_step_split->proc~run_stage_split proc~engine_step engine_step proc~engine_step->proc~ocean_dyn_step proc~engine_step->proc~ocean_dyn_step_split proc~driver_run_ocean driver_run_ocean proc~driver_run_ocean->proc~engine_step proc~rdb_ocean_step rdb_ocean_step proc~rdb_ocean_step->proc~engine_step

Variables

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

Source Code

   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