drain_limit_x Subroutine

private pure subroutine drain_limit_x(nx, ny, nz, areaT, h_min, uhr_x, hprev, uhh_x)

MOM6 hup/hlos/min_h two-test limiter on the zonal face transport (volume units). Face i between cell (i-1) and cell (i). Positive flow (uhr_x(i) > 0), donor = cell (i-1): hup = areaT(i-1)·hprev(i-1) − areaT(i-1)·min_h hlos = max(0, −uhr_x(i-1)) (already-committed outflow via the donor’s OTHER (west) face) cap when (hup−hlos)−uhr < 0 AND 0.5·hup−uhr < 0. Negative flow mirror, donor = cell (i).

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: nx
integer, intent(in) :: ny
integer, intent(in) :: nz
real(kind=wp), intent(in) :: areaT(nx,ny)
real(kind=wp), intent(in) :: h_min
real(kind=wp), intent(in) :: uhr_x(nx+1,ny,nz)
real(kind=wp), intent(in) :: hprev(nx,ny,nz)
real(kind=wp), intent(inout) :: uhh_x(nx+1,ny,nz)

Calls

proc~~drain_limit_x~~CallsGraph proc~drain_limit_x drain_limit_x local local proc~drain_limit_x->local

Called by

proc~~drain_limit_x~~CalledByGraph proc~drain_limit_x drain_limit_x proc~continuity_tracer_drain continuity_tracer_drain proc~continuity_tracer_drain->proc~drain_limit_x proc~ocean_dyn_flush_tracer_window ocean_dyn_flush_tracer_window proc~ocean_dyn_flush_tracer_window->proc~continuity_tracer_drain proc~ocean_dyn_step ocean_dyn_step proc~ocean_dyn_step->proc~continuity_tracer_drain proc~ocean_dyn_step_split ocean_dyn_step_split proc~ocean_dyn_step_split->proc~continuity_tracer_drain proc~driver_run_ocean driver_run_ocean proc~driver_run_ocean->proc~ocean_dyn_flush_tracer_window proc~engine_step engine_step proc~driver_run_ocean->proc~engine_step proc~engine_step->proc~ocean_dyn_step proc~engine_step->proc~ocean_dyn_step_split proc~rdb_ocean_set_tracer rdb_ocean_set_tracer proc~rdb_ocean_set_tracer->proc~ocean_dyn_flush_tracer_window proc~driver_run driver_run proc~driver_run->proc~driver_run_ocean proc~rdb_ocean_step rdb_ocean_step proc~rdb_ocean_step->proc~engine_step

Variables

Type Visibility Attributes Name Initial
real(kind=wp), private :: hlos
real(kind=wp), private :: hup
integer, private :: i
integer, private :: j
integer, private :: k
real(kind=wp), private :: uhr

Source Code

   pure subroutine drain_limit_x(nx, ny, nz, areaT, h_min, uhr_x, hprev, uhh_x)
      !! MOM6 hup/hlos/min_h two-test limiter on the zonal face transport
      !! (volume units).  Face i between cell (i-1) and cell (i).
      !! Positive flow (uhr_x(i) > 0), donor = cell (i-1):
      !!   hup  = areaT(i-1)·hprev(i-1) − areaT(i-1)·min_h
      !!   hlos = max(0, −uhr_x(i-1))   (already-committed outflow via the
      !!          donor's OTHER (west) face)
      !!   cap when (hup−hlos)−uhr < 0 AND 0.5·hup−uhr < 0.
      !! Negative flow mirror, donor = cell (i).
      integer, intent(in) :: nx, ny, nz
      real(wp), intent(in) :: areaT(nx, ny)
      real(wp), intent(in) :: h_min
      real(wp), intent(in) :: uhr_x(nx + 1, ny, nz)
      real(wp), intent(in) :: hprev(nx, ny, nz)
      real(wp), intent(inout) :: uhh_x(nx + 1, ny, nz)
      integer :: i, j, k
      real(wp) :: uhr, hup, hlos
      ! Interior faces 2..nx (each has a left cell i-1 and right cell i).
      do concurrent(k=1:nz, j=1:ny, i=2:nx) local(uhr, hup, hlos)
         uhr = uhr_x(i, j, k)
         if (uhr > 0.0_wp) then
            hup = areaT(i - 1, j)*hprev(i - 1, j, k) - areaT(i - 1, j)*h_min
            hlos = max(0.0_wp, -uhr_x(i - 1, j, k))
            if (((hup - hlos) - uhr < 0.0_wp) .and. (0.5_wp*hup - uhr < 0.0_wp)) then
               uhh_x(i, j, k) = max(0.0_wp, max(0.5_wp*hup, hup - hlos))
            else
               uhh_x(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_x(i + 1, j, k))
            if (((hup - hlos) + uhr < 0.0_wp) .and. (0.5_wp*hup + uhr < 0.0_wp)) then
               uhh_x(i, j, k) = -max(0.0_wp, max(0.5_wp*hup, hup - hlos))
            else
               uhh_x(i, j, k) = uhr
            end if
         else
            uhh_x(i, j, k) = 0.0_wp
         end if
      end do
      ! Boundary faces 1 and nx+1: no interior donor on one side ⇒ no flux.
      do concurrent(k=1:nz, j=1:ny)
         uhh_x(1, j, k) = 0.0_wp
         uhh_x(nx + 1, j, k) = 0.0_wp
      end do
   end subroutine drain_limit_x