ice_gather_flux_x_impl Subroutine

private pure subroutine ice_gather_flux_x_impl(uh, val, tr_flux_x_work, ncat, nx, ny)

Gather pass (race-free): tr_flux_x_work(I,c) = val(donor of I,c), donor by the sign of the FLUX. uh is exactly 0.0 at the array-edge faces I=1 and I=nx+1 (the flux kernel zeros them unconditionally), so the I=1 donor-by-sign branch (uh>=0) would read the out-of-bounds val(0,j,c) — guarded explicitly below (I==1/I==nx+1 fall back to the IN-BOUNDS neighbour; the value is never actually consumed by the update kernel there since uh==0 at both those faces makes them inert, but the gather must still avoid the invalid index). Reads val ONLY at a donor cell — never writes val — so this kernel has no race with any other iteration.

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: uh(nx+1,ny,ncat)
real(kind=wp), intent(in) :: val(nx,ny,ncat)
real(kind=wp), intent(out) :: tr_flux_x_work(nx+1,ny,ncat)
integer, intent(in) :: ncat
integer, intent(in) :: nx
integer, intent(in) :: ny

Called by

proc~~ice_gather_flux_x_impl~~CalledByGraph proc~ice_gather_flux_x_impl ice_gather_flux_x_impl proc~ice_pass_x ice_pass_x proc~ice_pass_x->proc~ice_gather_flux_x_impl proc~ice_transport_step ice_transport_step proc~ice_transport_step->proc~ice_pass_x proc~engine_step_ice engine_step_ice proc~engine_step_ice->proc~ice_transport_step proc~driver_run_ocean driver_run_ocean proc~driver_run_ocean->proc~engine_step_ice proc~rdb_ocean_step rdb_ocean_step proc~rdb_ocean_step->proc~engine_step_ice proc~driver_run driver_run proc~driver_run->proc~driver_run_ocean

Variables

Type Visibility Attributes Name Initial
integer, private :: c
integer, private :: i
integer, private :: j

Source Code

   pure subroutine ice_gather_flux_x_impl(uh, val, tr_flux_x_work, ncat, nx, ny)
      !! Gather pass (race-free): `tr_flux_x_work(I,c) = val(donor of
      !! I,c)`, donor by the sign of the FLUX.  `uh` is exactly 0.0 at
      !! the array-edge faces `I=1` and `I=nx+1` (the flux kernel zeros
      !! them unconditionally), so the `I=1` donor-by-sign branch
      !! (`uh>=0`) would read the out-of-bounds `val(0,j,c)` — guarded
      !! explicitly below (`I==1`/`I==nx+1` fall back to the IN-BOUNDS
      !! neighbour; the value is never actually consumed by the update
      !! kernel there since `uh==0` at both those faces makes them
      !! inert, but the gather must still avoid the invalid index).
      !! Reads `val` ONLY at a donor cell — never writes `val` — so this
      !! kernel has no race with any other iteration.
      integer, intent(in) :: ncat, nx, ny
      real(wp), intent(in) :: uh(nx + 1, ny, ncat)
      real(wp), intent(in) :: val(nx, ny, ncat)
      real(wp), intent(out) :: tr_flux_x_work(nx + 1, ny, ncat)
      integer :: i, j, c

      do concurrent(j=1:ny, i=1:nx + 1, c=1:ncat)
         if (i == 1) then
            tr_flux_x_work(i, j, c) = val(1, j, c)
         else if (i == nx + 1) then
            tr_flux_x_work(i, j, c) = val(nx, j, c)
         else if (uh(i, j, c) >= 0.0_wp) then
            tr_flux_x_work(i, j, c) = val(i - 1, j, c)
         else
            tr_flux_x_work(i, j, c) = val(i, j, c)
         end if
      end do
   end subroutine ice_gather_flux_x_impl