bt_wide_copy_in_impl Subroutine

private subroutine bt_wide_copy_in_impl(this, grid, bt_eta, bt_H_ref, bt_ubt, bt_vbt, bt_ubt_prev, bt_vbt_prev, bt_rem_u, bt_rem_v, force_u, force_v)

Non-polymorphic copy_in body. Offset = bt_halo: w_X(iw, jw) = X(clamp(iw-off), clamp(jw-off)) over the FULL wide extent — the inner band is a direct offset copy; the outer bt_halo ring is a clamped-index (constant-extrapolation) fill. The ring fill matters: without it the ring carries stale end-of-fast-loop values from the previous stage (H_ref = 0, eta from t-1), which at a PHYSICAL (non-seam) edge is never refreshed by any exchange and free-runs an inconsistent zero-depth integration that blows up in O(25) outer steps. At an MPI seam the ring is immediately overwritten with true neighbour data by entry_exchange, so the clamped fill only governs physical edges — the same sane ghost-band construction the v1 normal-width path gets from its own ghosts. Scratch / accumulator arrays (w_eta_new, w_ke, w_eta_sum, …) do not need copy-in — the substep initialises them.

Arguments

Type IntentOptional Attributes Name
type(bt_wide_t), intent(inout) :: this
type(hgrid_t), intent(in) :: grid

Normal-width grid (provides nx_total, ny_total for loop bounds).

real(kind=wp), intent(in) :: bt_eta(grid%nx_total,grid%ny_total)

Barotropic SSH (cell centres, normal-width).

real(kind=wp), intent(in) :: bt_H_ref(grid%nx_total,grid%ny_total)

Reference column depth (cell centres, normal-width).

real(kind=wp), intent(in) :: bt_ubt(grid%nx_total+1,grid%ny_total)

BT u (east faces, normal-width).

real(kind=wp), intent(in) :: bt_vbt(grid%nx_total,grid%ny_total+1)

BT v (north faces, normal-width).

real(kind=wp), intent(in) :: bt_ubt_prev(grid%nx_total+1,grid%ny_total)

BEBT u^{n-1} snapshot (east faces, normal-width).

real(kind=wp), intent(in) :: bt_vbt_prev(grid%nx_total,grid%ny_total+1)

BEBT v^{n-1} snapshot (north faces, normal-width).

real(kind=wp), intent(in) :: bt_rem_u(grid%nx_total+1,grid%ny_total)

Multiplicative drag factor for u (east faces, normal-width).

real(kind=wp), intent(in) :: bt_rem_v(grid%nx_total,grid%ny_total+1)

Multiplicative drag factor for v (north faces, normal-width).

real(kind=wp), intent(in) :: force_u(grid%nx_total+1,grid%ny_total)

BT slow forcing for u (east faces, normal-width).

real(kind=wp), intent(in) :: force_v(grid%nx_total,grid%ny_total+1)

BT slow forcing for v (north faces, normal-width).


Calls

proc~~bt_wide_copy_in_impl~~CallsGraph proc~bt_wide_copy_in_impl bt_wide_copy_in_impl local local proc~bt_wide_copy_in_impl->local

Called by

proc~~bt_wide_copy_in_impl~~CalledByGraph proc~bt_wide_copy_in_impl bt_wide_copy_in_impl proc~bt_wide_copy_in bt_wide_t%bt_wide_copy_in proc~bt_wide_copy_in->proc~bt_wide_copy_in_impl proc~run_stage_split run_stage_split proc~run_stage_split->proc~bt_wide_copy_in 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_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 :: i_src
integer, private :: j
integer, private :: j_src
integer, private :: nx
integer, private :: ny
integer, private :: off

Source Code

   subroutine bt_wide_copy_in_impl(this, grid, &
                                   bt_eta, bt_H_ref, bt_ubt, bt_vbt, &
                                   bt_ubt_prev, bt_vbt_prev, &
                                   bt_rem_u, bt_rem_v, &
                                   force_u, force_v)
      !! Non-polymorphic copy_in body.  Offset = bt_halo:
      !! w_X(iw, jw) = X(clamp(iw-off), clamp(jw-off)) over the FULL wide
      !! extent — the inner band is a direct offset copy; the outer bt_halo
      !! ring is a clamped-index (constant-extrapolation) fill.  The ring
      !! fill matters: without it the ring carries stale end-of-fast-loop
      !! values from the previous stage (H_ref = 0, eta from t-1), which at
      !! a PHYSICAL (non-seam) edge is never refreshed by any exchange and
      !! free-runs an inconsistent zero-depth integration that blows up in
      !! O(25) outer steps.  At an MPI seam the ring is immediately
      !! overwritten with true neighbour data by `entry_exchange`, so the
      !! clamped fill only governs physical edges — the same sane ghost-band
      !! construction the v1 normal-width path gets from its own ghosts.
      !! Scratch / accumulator arrays (w_eta_new, w_ke, w_eta_sum, …) do not
      !! need copy-in — the substep initialises them.
      type(bt_wide_t), intent(inout) :: this
      type(hgrid_t), intent(in) :: grid
         !! Normal-width grid (provides nx_total, ny_total for loop bounds).
      real(wp), intent(in) :: bt_eta(grid%nx_total, grid%ny_total)
         !! Barotropic SSH (cell centres, normal-width).
      real(wp), intent(in) :: bt_H_ref(grid%nx_total, grid%ny_total)
         !! Reference column depth (cell centres, normal-width).
      real(wp), intent(in) :: bt_ubt(grid%nx_total + 1, grid%ny_total)
         !! BT u (east faces, normal-width).
      real(wp), intent(in) :: bt_vbt(grid%nx_total, grid%ny_total + 1)
         !! BT v (north faces, normal-width).
      real(wp), intent(in) :: bt_ubt_prev(grid%nx_total + 1, grid%ny_total)
         !! BEBT u^{n-1} snapshot (east faces, normal-width).
      real(wp), intent(in) :: bt_vbt_prev(grid%nx_total, grid%ny_total + 1)
         !! BEBT v^{n-1} snapshot (north faces, normal-width).
      real(wp), intent(in) :: bt_rem_u(grid%nx_total + 1, grid%ny_total)
         !! Multiplicative drag factor for u (east faces, normal-width).
      real(wp), intent(in) :: bt_rem_v(grid%nx_total, grid%ny_total + 1)
         !! Multiplicative drag factor for v (north faces, normal-width).
      real(wp), intent(in) :: force_u(grid%nx_total + 1, grid%ny_total)
         !! BT slow forcing for u (east faces, normal-width).
      real(wp), intent(in) :: force_v(grid%nx_total, grid%ny_total + 1)
         !! BT slow forcing for v (north faces, normal-width).

      integer :: i, j, nx, ny, off
      integer :: i_src, j_src
      off = this%bt_halo
      nx = grid%nx_total
      ny = grid%ny_total

      ! Centre arrays: full wide extent (nx + 2*off, ny + 2*off), clamped
      ! source indices (constant extrapolation into the outer ring).
      do concurrent(j=1:ny + 2*off, i=1:nx + 2*off) local(i_src, j_src)
         i_src = min(max(i - off, 1), nx)
         j_src = min(max(j - off, 1), ny)
         this%w_eta(i, j) = bt_eta(i_src, j_src)
         this%w_H_ref(i, j) = bt_H_ref(i_src, j_src)
      end do
      ! East-face arrays: wide extent (nx + 2*off + 1, ny + 2*off).
      do concurrent(j=1:ny + 2*off, i=1:nx + 2*off + 1) local(i_src, j_src)
         i_src = min(max(i - off, 1), nx + 1)
         j_src = min(max(j - off, 1), ny)
         this%w_ubt(i, j) = bt_ubt(i_src, j_src)
         this%w_ubt_prev(i, j) = bt_ubt_prev(i_src, j_src)
         this%w_rem_u(i, j) = bt_rem_u(i_src, j_src)
         this%w_force_u(i, j) = force_u(i_src, j_src)
      end do
      ! North-face arrays: wide extent (nx + 2*off, ny + 2*off + 1).
      do concurrent(j=1:ny + 2*off + 1, i=1:nx + 2*off) local(i_src, j_src)
         i_src = min(max(i - off, 1), nx)
         j_src = min(max(j - off, 1), ny + 1)
         this%w_vbt(i, j) = bt_vbt(i_src, j_src)
         this%w_vbt_prev(i, j) = bt_vbt_prev(i_src, j_src)
         this%w_rem_v(i, j) = bt_rem_v(i_src, j_src)
         this%w_force_v(i, j) = force_v(i_src, j_src)
      end do
   end subroutine bt_wide_copy_in_impl