pure subroutine meke_advect(nx, ny, sdt, adv_fac, iareaT, i_mass, &
baro_hu, baro_hv, uflux, vflux, meke)
!! Upwind flux-form advection of E by the barotropic mass transport.
!! advFac = adv_fac/sdt
!! uflux(I) = baroHu(I)*advFac*E_upwind (E_{I-1} if baroHu>0 else E_I)
!! E += sdt*IareaT*I_mass*((uflux_{i-1}-uflux_i)+(vflux_{j-1}-vflux_j))
!! Conservative on a closed domain (interior faces only; the
!! divergence telescopes ⇒ Sum E*area*mass conserved). `adv_fac=0`
!! never reaches here (gated by the caller) ⇒ default bit-identity.
integer, intent(in) :: nx, ny
real(wp), intent(in) :: sdt, adv_fac
real(wp), intent(in) :: iareaT(nx, ny)
real(wp), intent(in) :: i_mass(nx, ny)
real(wp), intent(in) :: baro_hu(nx + 1, ny)
real(wp), intent(in) :: baro_hv(nx, ny + 1)
real(wp), intent(inout) :: uflux(nx + 1, ny)
real(wp), intent(inout) :: vflux(nx, ny + 1)
real(wp), intent(inout) :: meke(nx, ny)
integer :: i, j
real(wp) :: adv_per_t, bh, mke
adv_per_t = 0.0_wp
if (sdt > 0.0_wp) adv_per_t = adv_fac/sdt
! u-face upwind flux (array-edge faces carry zero ⇒ closed domain).
do concurrent(j=1:ny, i=1:nx + 1)
uflux(i, j) = 0.0_wp
end do
do concurrent(j=1:ny, i=2:nx) local(bh)
bh = baro_hu(i, j)
if (bh > 0.0_wp) then
uflux(i, j) = bh*adv_per_t*meke(i - 1, j)
else if (bh < 0.0_wp) then
uflux(i, j) = bh*adv_per_t*meke(i, j)
end if
end do
! v-face upwind flux.
do concurrent(j=1:ny + 1, i=1:nx)
vflux(i, j) = 0.0_wp
end do
do concurrent(j=2:ny, i=1:nx) local(bh)
bh = baro_hv(i, j)
if (bh > 0.0_wp) then
vflux(i, j) = bh*adv_per_t*meke(i, j - 1)
else if (bh < 0.0_wp) then
vflux(i, j) = bh*adv_per_t*meke(i, j)
end if
end do
! conservative divergence (uflux at face i is the LEFT face of cell i;
! face i+1 the RIGHT face). Inflow-left minus outflow-right.
do concurrent(j=1:ny, i=1:nx) local(mke)
mke = sdt*(iareaT(i, j)*i_mass(i, j))* &
((uflux(i, j) - uflux(i + 1, j)) + (vflux(i, j) - vflux(i, j + 1)))
meke(i, j) = meke(i, j) + mke
end do
end subroutine meke_advect