pure subroutine drain_limit_y(nx, ny, nz, areaT, h_min, uhr_y, hprev, uhh_y)
!! Meridional analogue of drain_limit_x. Face j between cell (i,j-1)
!! and cell (i,j); positive donor = cell (i,j-1).
integer, intent(in) :: nx, ny, nz
real(wp), intent(in) :: areaT(nx, ny)
real(wp), intent(in) :: h_min
real(wp), intent(in) :: uhr_y(nx, ny + 1, nz)
real(wp), intent(in) :: hprev(nx, ny, nz)
real(wp), intent(inout) :: uhh_y(nx, ny + 1, nz)
integer :: i, j, k
real(wp) :: uhr, hup, hlos
do concurrent(k=1:nz, j=2:ny, i=1:nx) local(uhr, hup, hlos)
uhr = uhr_y(i, j, k)
if (uhr > 0.0_wp) then
hup = areaT(i, j - 1)*hprev(i, j - 1, k) - areaT(i, j - 1)*h_min
hlos = max(0.0_wp, -uhr_y(i, j - 1, k))
if (((hup - hlos) - uhr < 0.0_wp) .and. (0.5_wp*hup - uhr < 0.0_wp)) then
uhh_y(i, j, k) = max(0.0_wp, max(0.5_wp*hup, hup - hlos))
else
uhh_y(i, j, k) = uhr
end if
else if (uhr < 0.0_wp) then
hup = areaT(i, j)*hprev(i, j, k) - areaT(i, j)*h_min
hlos = max(0.0_wp, uhr_y(i, j + 1, k))
if (((hup - hlos) + uhr < 0.0_wp) .and. (0.5_wp*hup + uhr < 0.0_wp)) then
uhh_y(i, j, k) = -max(0.0_wp, max(0.5_wp*hup, hup - hlos))
else
uhh_y(i, j, k) = uhr
end if
else
uhh_y(i, j, k) = 0.0_wp
end if
end do
do concurrent(k=1:nz, i=1:nx)
uhh_y(i, 1, k) = 0.0_wp
uhh_y(i, ny + 1, k) = 0.0_wp
end do
end subroutine drain_limit_y