Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions src/core/MOM_dynamics_split_RK2.F90
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ module MOM_dynamics_split_RK2
use MOM_lateral_mixing_coeffs, only : VarMix_CS
use MOM_MEKE_types, only : MEKE_type
use MOM_open_boundary, only : ocean_OBC_type, radiation_open_bdry_conds
use MOM_open_boundary, only : OBC_segment_type, OBC_DIRECTION_E, OBC_DIRECTION_W
use MOM_open_boundary, only : OBC_DIRECTION_N, OBC_DIRECTION_S
use MOM_open_boundary, only : open_boundary_zero_normal_flow, open_boundary_query
use MOM_open_boundary, only : open_boundary_test_extern_h, update_OBC_ramp
use MOM_open_boundary, only : copy_thickness_reservoirs
Expand Down Expand Up @@ -419,6 +421,8 @@ subroutine step_MOM_dyn_split_RK2(u_inst, v_inst, h, tv, visc, Time_local, dt, f
integer :: i, j, k, is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz
integer :: cont_stencil, obc_stencil, vel_stencil
integer :: cor_stencil
integer :: n ! OBC segment loop index (OBC-exterior h fix)
type(OBC_segment_type), pointer :: segment => NULL() ! OBC segment (OBC-exterior h fix)

is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke
Isq = G%IscB ; Ieq = G%IecB ; Jsq = G%JscB ; Jeq = G%JecB
Expand Down Expand Up @@ -465,6 +469,39 @@ subroutine step_MOM_dyn_split_RK2(u_inst, v_inst, h, tv, visc, Time_local, dt, f
! Update OBC ramp value as function of time
call update_OBC_ramp(Time_local, CS%OBC, US)

! === OBC-exterior h fix (minimal): the OBC-exterior h halo is not reconstructed
! bit-for-bit across an exact restart, and vertvisc_coef reads it (zero-gradient
! projection across OBCs), seeding a last-bit velocity divergence. Rebuild it here with a
! single in-place zero-gradient fill over all segments: copy the first interior thickness
! into the exterior ghost cell. u-points (E/W) and v-points (N/S) only read same-row /
! same-column neighbours, never the diagonal corner, so no corner handling is needed.
if (associated(CS%OBC)) then
do n=1,CS%OBC%number_of_segments
segment => CS%OBC%segment(n)
if (.not. segment%on_pe) cycle
if (segment%is_E_or_W) then
I = segment%HI%IsdB
do k=1,nz ; do j=segment%HI%jsd,segment%HI%jed
if (segment%direction == OBC_DIRECTION_W) then
h(I,j,k) = h(I+1,j,k)
elseif (segment%direction == OBC_DIRECTION_E) then
h(I+1,j,k) = h(I,j,k)
endif
enddo ; enddo
elseif (segment%is_N_or_S) then
J = segment%HI%JsdB
do k=1,nz ; do i=segment%HI%isd,segment%HI%ied
if (segment%direction == OBC_DIRECTION_S) then
h(i,J,k) = h(i,J+1,k)
elseif (segment%direction == OBC_DIRECTION_N) then
h(i,J+1,k) = h(i,J,k)
endif
enddo ; enddo
endif
enddo
endif
! === end OBC-exterior h fix ===

do k=1,nz ; do j=G%jsd,G%jed ; do I=G%IsdB,G%IedB
u_old_rad_OBC(I,j,k) = u_av(I,j,k)
enddo ; enddo ; enddo
Expand Down
Loading