ocean_fold_wrap_visc_rem Subroutine

public subroutine ocean_fold_wrap_visc_rem(grid, bc, visc_rem_u, visc_rem_v, device_resident)

Fold the viscous-remnant pair: visc_rem_u (u-face) and visc_rem_v (v-face) — PR-1’s bt_work%visc_rem_u/v seam. UNLIKE ocean_fold_wrap_stress (its vector twin, tau_x/tau_y), visc_rem is a POSITIVE SCALAR (the fraction of a barotropic acceleration a layer still feels after one implicit-friction step, MOM6 vertvisc_remnant), not a flux/velocity component, so both face kernels are called with negate=.false.: the 180-degree fold still swaps which side of the seam the ghost value comes from, but the value itself does not change sign, and the v-face fold-line duplicate DOF is forced EQUAL (not opposite) across the seam. Call after the pair’s halo exchange + periodic wrap (MOM6’s pass_visc_rem group pass, run after every one of the three vertvisc_remnant calls). No-op when not folding.

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_bc_state_t), intent(in) :: bc
real(kind=wp), intent(inout) :: visc_rem_u(:,:,:)

u-face per-layer remnant, shape (nx_total+1, ny_total, nz).

real(kind=wp), intent(inout) :: visc_rem_v(:,:,:)

v-face per-layer remnant, shape (nx_total, ny_total+1, nz).

logical, intent(in), optional :: device_resident

px > 1 only: .false. for host-side calls.


Calls

proc~~ocean_fold_wrap_visc_rem~~CallsGraph proc~ocean_fold_wrap_visc_rem ocean_fold_wrap_visc_rem interface~fold_north_u_face fold_north_u_face proc~ocean_fold_wrap_visc_rem->interface~fold_north_u_face interface~fold_north_v_face fold_north_v_face proc~ocean_fold_wrap_visc_rem->interface~fold_north_v_face interface~ocean_fold_pack ocean_fold_pack proc~ocean_fold_wrap_visc_rem->interface~ocean_fold_pack interface~ocean_fold_unpack ocean_fold_unpack proc~ocean_fold_wrap_visc_rem->interface~ocean_fold_unpack proc~ocean_fold_begin ocean_fold_begin proc~ocean_fold_wrap_visc_rem->proc~ocean_fold_begin proc~ocean_fold_end ocean_fold_end proc~ocean_fold_wrap_visc_rem->proc~ocean_fold_end proc~ocean_fold_exchange ocean_fold_exchange proc~ocean_fold_wrap_visc_rem->proc~ocean_fold_exchange proc~ocean_fold_is_distributed ocean_fold_is_distributed proc~ocean_fold_wrap_visc_rem->proc~ocean_fold_is_distributed proc~fold_north_u_face_2d fold_north_u_face_2d interface~fold_north_u_face->proc~fold_north_u_face_2d proc~fold_north_u_face_3d fold_north_u_face_3d interface~fold_north_u_face->proc~fold_north_u_face_3d proc~fold_north_v_face_2d fold_north_v_face_2d interface~fold_north_v_face->proc~fold_north_v_face_2d proc~fold_north_v_face_3d fold_north_v_face_3d interface~fold_north_v_face->proc~fold_north_v_face_3d proc~ocean_fold_pack_2d ocean_fold_pack_2d interface~ocean_fold_pack->proc~ocean_fold_pack_2d proc~ocean_fold_pack_3d ocean_fold_pack_3d interface~ocean_fold_pack->proc~ocean_fold_pack_3d proc~ocean_fold_unpack_2d ocean_fold_unpack_2d interface~ocean_fold_unpack->proc~ocean_fold_unpack_2d proc~ocean_fold_unpack_3d ocean_fold_unpack_3d interface~ocean_fold_unpack->proc~ocean_fold_unpack_3d proc~grow_buffers grow_buffers proc~ocean_fold_begin->proc~grow_buffers to_string to_string proc~ocean_fold_begin->to_string warning warning proc~ocean_fold_begin->warning comm_irecv_real_sp_array_n comm_irecv_real_sp_array_n proc~ocean_fold_exchange->comm_irecv_real_sp_array_n comm_isend_real_sp_array_n comm_isend_real_sp_array_n proc~ocean_fold_exchange->comm_isend_real_sp_array_n proc~comm_env_compute_comm comm_env_compute_comm proc~ocean_fold_exchange->proc~comm_env_compute_comm waitall waitall proc~ocean_fold_exchange->waitall comm_world comm_world proc~comm_env_compute_comm->comm_world local local proc~fold_north_v_face_2d->local proc~fold_north_v_face_3d->local proc~ocean_fold_pack_2d->proc~ocean_fold_pack_3d proc~fold_stagger_family fold_stagger_family proc~ocean_fold_pack_3d->proc~fold_stagger_family proc~fold_stagger_nrows fold_stagger_nrows proc~ocean_fold_pack_3d->proc~fold_stagger_nrows proc~ocean_fold_unpack_2d->proc~ocean_fold_unpack_3d proc~ocean_fold_unpack_3d->proc~fold_stagger_family proc~ocean_fold_unpack_3d->proc~fold_stagger_nrows

Called by

proc~~ocean_fold_wrap_visc_rem~~CalledByGraph proc~ocean_fold_wrap_visc_rem ocean_fold_wrap_visc_rem proc~visc_rem_halo_refresh visc_rem_halo_refresh proc~visc_rem_halo_refresh->proc~ocean_fold_wrap_visc_rem proc~visc_rem_precompute visc_rem_precompute proc~visc_rem_precompute->proc~visc_rem_halo_refresh proc~vmix_apply_in_stage vmix_apply_in_stage proc~vmix_apply_in_stage->proc~visc_rem_halo_refresh proc~vmix_apply_in_stage->proc~visc_rem_precompute proc~run_stage run_stage proc~run_stage->proc~vmix_apply_in_stage proc~run_stage_split run_stage_split proc~run_stage_split->proc~visc_rem_precompute proc~run_stage_split->proc~vmix_apply_in_stage proc~ocean_dyn_step ocean_dyn_step proc~ocean_dyn_step->proc~run_stage 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 proc~engine_step->proc~ocean_dyn_step_split

Variables

Type Visibility Attributes Name Initial
integer, private :: nxu
integer, private :: nxv
integer, private :: nyu
integer, private :: nyv
integer, private :: nz

Source Code

   subroutine ocean_fold_wrap_visc_rem(grid, bc, visc_rem_u, visc_rem_v, device_resident)
      !! Fold the viscous-remnant pair: `visc_rem_u` (u-face) and
      !! `visc_rem_v` (v-face) — PR-1's `bt_work%visc_rem_u/v` seam.
      !! UNLIKE `ocean_fold_wrap_stress` (its vector twin, tau_x/tau_y),
      !! `visc_rem` is a POSITIVE SCALAR (the fraction of a barotropic
      !! acceleration a layer still feels after one implicit-friction
      !! step, MOM6 `vertvisc_remnant`), not a flux/velocity component,
      !! so both face kernels are called
      !! with `negate=.false.`: the 180-degree fold still swaps which side
      !! of the seam the ghost value comes from, but the value itself does
      !! not change sign, and the v-face fold-line duplicate DOF is forced
      !! EQUAL (not opposite) across the seam.  Call after the pair's halo
      !! exchange + periodic wrap (MOM6's `pass_visc_rem` group pass, run
      !! after every one of the three `vertvisc_remnant` calls).  No-op
      !! when not folding.
      type(hgrid_t), intent(in) :: grid
      type(ocean_bc_state_t), intent(in) :: bc
      real(wp), intent(inout) :: visc_rem_u(:, :, :)
         !! u-face per-layer remnant, shape (nx_total+1, ny_total, nz).
      real(wp), intent(inout) :: visc_rem_v(:, :, :)
         !! v-face per-layer remnant, shape (nx_total, ny_total+1, nz).
      logical, intent(in), optional :: device_resident
         !! px > 1 only: `.false.` for host-side calls.

      integer :: nxu, nyu, nxv, nyv, nz

      if (.not. bc%north_fold) return

      nxu = size(visc_rem_u, 1)
      nyu = size(visc_rem_u, 2)
      nxv = size(visc_rem_v, 1)
      nyv = size(visc_rem_v, 2)
      nz = size(visc_rem_u, 3)

      if (ocean_fold_is_distributed()) then
         call ocean_fold_begin(2*(grid%nghost + 1)*nz)
         call ocean_fold_pack(visc_rem_u, nxu, nyu, nz, FOLD_STAG_U, device_resident)
         call ocean_fold_pack(visc_rem_v, nxv, nyv, nz, FOLD_STAG_V, device_resident)
         call ocean_fold_exchange(device_resident)
         call ocean_fold_unpack(visc_rem_u, nxu, nyu, nz, FOLD_STAG_U, .false., device_resident)
         call ocean_fold_unpack(visc_rem_v, nxv, nyv, nz, FOLD_STAG_V, .false., device_resident)
         call ocean_fold_end()
         return
      end if

      call fold_north_u_face(visc_rem_u, nxu, nyu, nz, &
                             grid%nx_phys, grid%ny_phys, grid%nghost, negate=.false.)
      call fold_north_v_face(visc_rem_v, nxv, nyv, nz, &
                             grid%nx_phys, grid%ny_phys, grid%nghost, negate=.false.)
   end subroutine ocean_fold_wrap_visc_rem