reset_vanished_layer_velocities Subroutine

private pure subroutine reset_vanished_layer_velocities(ms, vanish_tol)

Zero the per-layer face velocity at any face where BOTH adjacent centre-cell thicknesses are at or below vanish_tol (isopycnal_vanish_tol(angstrom_h) = max(angstrom_h, H_VANISHED)).

Both-sided rule (R1/R6): a face is reset only when BOTH neighbouring centre cells are vanished. A face with one massive side (h >> vanish_tol) is LEFT UNTOUCHED — that flux is legitimate (it may be re-wetting the thin layer at a grounding FRONT) and zeroing it would create a spurious vorticity dipole.

Idempotency (R6): faces zeroed here are already 0 when Phase-3 CFL truncation runs (apply_velocity_truncation); the composition is harmless.

Mirroring mask_layer_velocities: plain do concurrent, no !$acc annotations, pure, explicit dims before arrays.

Arguments

Type IntentOptional Attributes Name
type(multilayer_state_t), intent(inout) :: ms
real(kind=wp), intent(in) :: vanish_tol

Called by

proc~~reset_vanished_layer_velocities~~CalledByGraph proc~reset_vanished_layer_velocities reset_vanished_layer_velocities proc~ocean_dyn_step_split ocean_dyn_step_split proc~ocean_dyn_step_split->proc~reset_vanished_layer_velocities proc~run_stage_split run_stage_split proc~ocean_dyn_step_split->proc~run_stage_split proc~run_stage_split->proc~reset_vanished_layer_velocities 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 proc~driver_run driver_run proc~driver_run->proc~driver_run_ocean

Variables

Type Visibility Attributes Name Initial
integer, private :: i
integer, private :: j
integer, private :: k
integer, private :: nx_centre
integer, private :: nx_face
integer, private :: nx_vface
integer, private :: ny_centre
integer, private :: ny_face
integer, private :: ny_uface
integer, private :: nz

Source Code

   pure subroutine reset_vanished_layer_velocities(ms, vanish_tol)
      !! Zero the per-layer face velocity at any face where BOTH adjacent
      !! centre-cell thicknesses are at or below `vanish_tol`
      !! (`isopycnal_vanish_tol(angstrom_h)` = `max(angstrom_h, H_VANISHED)`).
      !!
      !! **Both-sided rule (R1/R6):** a face is reset only when BOTH
      !! neighbouring centre cells are vanished.  A face with one massive
      !! side (`h >> vanish_tol`) is LEFT UNTOUCHED — that flux is
      !! legitimate (it may be re-wetting the thin layer at a grounding
      !! FRONT) and zeroing it would create a spurious vorticity dipole.
      !!
      !! **Idempotency (R6):** faces zeroed here are already 0 when
      !! Phase-3 CFL truncation runs (`apply_velocity_truncation`);
      !! the composition is harmless.
      !!
      !! Mirroring `mask_layer_velocities`: plain `do concurrent`, no
      !! `!$acc` annotations, pure, explicit dims before arrays.
      type(multilayer_state_t), intent(inout) :: ms
      real(wp), intent(in) :: vanish_tol
      integer :: i, j, k, nz, nx_face, ny_uface, nx_vface, ny_face
      integer :: nx_centre, ny_centre

      nz = ms%nz_ml
      nx_centre = size(ms%h_layer, 1)
      ny_centre = size(ms%h_layer, 2)
      nx_face = size(ms%u_face_x_layer, 1)
      ny_uface = size(ms%u_face_x_layer, 2)
      nx_vface = size(ms%v_face_y_layer, 1)
      ny_face = size(ms%v_face_y_layer, 2)

      ! u-face at (i,j,k) straddles centres (i-1,j,k) and (i,j,k).
      ! Skip outermost columns (i=1 and i=nx_face) which are ghost/wall
      ! faces — their adjacent interior index would be out of range.
      ! Safe inner range: i=2..nx_face-1 (both i-1 and i are in 1..nx_centre).
      ! Both-sided-vanished test as an inner `if`, not a DC mask — masked
      ! headers fail tools/dc_audit.py --strict.
      do concurrent(k=1:nz, j=1:ny_uface, i=2:nx_face - 1)
         if (max(ms%h_layer(i - 1, j, k), ms%h_layer(i, j, k)) <= vanish_tol) then
            ms%u_face_x_layer(i, j, k) = 0.0_wp
         end if
      end do

      ! v-face at (i,j,k) straddles centres (i,j-1,k) and (i,j,k).
      ! Safe inner range: j=2..ny_face-1.
      do concurrent(k=1:nz, j=2:ny_face - 1, i=1:nx_vface)
         if (max(ms%h_layer(i, j - 1, k), ms%h_layer(i, j, k)) <= vanish_tol) then
            ms%v_face_y_layer(i, j, k) = 0.0_wp
         end if
      end do
   end subroutine reset_vanished_layer_velocities