subroutine ocean_fold_wrap_time_means(grid, bc, ms)
!! Fold the `pred_corr` step time-means u_av (u, −), v_av (v, −, +
!! fold-row projection) and h_av (T) — the stage-entry site that
!! mirrors the prognostic fold for the Coriolis / viscosity inputs.
!! Call after their periodic wrap. No-op when not folding or when
!! the means are not allocated (ssp_rk2). Device-only: unlike the
!! other dispatchers it takes no `device_resident` flag, because its
!! production caller (`run_stage_split`) always runs on the mapped state.
type(hgrid_t), intent(in) :: grid
type(ocean_bc_state_t), intent(in) :: bc
type(multilayer_state_t), intent(inout) :: ms
integer :: nxu, nyu, nxv, nyv, nxh, nyh, nz
if (.not. bc%north_fold) return
if (.not. allocated(ms%u_av_layer)) return
nxu = size(ms%u_av_layer, 1)
nyu = size(ms%u_av_layer, 2)
nxv = size(ms%v_av_layer, 1)
nyv = size(ms%v_av_layer, 2)
nxh = size(ms%h_av_layer, 1)
nyh = size(ms%h_av_layer, 2)
nz = size(ms%u_av_layer, 3)
if (ocean_fold_is_distributed()) then
call ocean_fold_begin(3*(grid%nghost + 1)*nz)
call ocean_fold_pack(ms%u_av_layer, nxu, nyu, nz, FOLD_STAG_U)
call ocean_fold_pack(ms%v_av_layer, nxv, nyv, nz, FOLD_STAG_V)
call ocean_fold_pack(ms%h_av_layer, nxh, nyh, nz, FOLD_STAG_T)
call ocean_fold_exchange()
call ocean_fold_unpack(ms%u_av_layer, nxu, nyu, nz, FOLD_STAG_U, .true.)
call ocean_fold_unpack(ms%v_av_layer, nxv, nyv, nz, FOLD_STAG_V, .true.)
call ocean_fold_unpack(ms%h_av_layer, nxh, nyh, nz, FOLD_STAG_T, .false.)
call ocean_fold_end()
return
end if
call fold_north_u_face(ms%u_av_layer, nxu, nyu, nz, &
grid%nx_phys, grid%ny_phys, grid%nghost)
call fold_north_v_face(ms%v_av_layer, nxv, nyv, nz, &
grid%nx_phys, grid%ny_phys, grid%nghost)
call fold_north_centre(ms%h_av_layer, nxh, nyh, nz, &
grid%nx_phys, grid%ny_phys, grid%nghost)
end subroutine ocean_fold_wrap_time_means