@@ -156,6 +156,7 @@ module MOM_barotropic
156156
157157  real , allocatable  ::  frhatu1(:,:,:)  ! < Predictor step values of frhatu stored for diagnostics [nondim]
158158  real , allocatable  ::  frhatv1(:,:,:)  ! < Predictor step values of frhatv stored for diagnostics [nondim]
159+   real , allocatable  ::  IareaT_OBCmask(:,:)  ! < If non-zero, work on given points [L-2 ~> m-2].
159160
160161  type (BT_OBC_type) ::  BT_OBC ! < A structure with all of this modules fields
161162                              ! ! for applying open boundary conditions.
@@ -290,6 +291,8 @@ module MOM_barotropic
290291                             ! ! consistent with tidal self-attraction and loading
291292                             ! ! used within the barotropic solver
292293  logical  ::  wt_uv_bug =  .true.  ! < If true, recover a bug that wt_[uv] that is not normalized.
294+   logical  ::  exterior_OBC_bug =  .true.  ! < If true, recover a bug with boundary conditions
295+                              ! ! inside the domain.
293296  type (time_type), pointer  ::  Time  = > NULL () ! < A pointer to the ocean models clock.
294297  type (diag_ctrl), pointer  ::  diag = > NULL ()  ! < A structure that is used to regulate
295298                             ! ! the timing of diagnostic output.
@@ -1961,7 +1964,7 @@ subroutine btstep(U_in, V_in, eta_in, dt, bc_accel_u, bc_accel_v, forces, pbce,
19611964        enddo  ; enddo 
19621965        ! $OMP do
19631966        do  j= jsv-1 ,jev+1  ; do  i= isv-1 ,iev+1 
1964-           eta_pred(i,j) =  (eta_IC(i,j) +  n* eta_src(i,j)) +  CS% IareaT (i,j) *  &
1967+           eta_pred(i,j) =  (eta_IC(i,j) +  n* eta_src(i,j)) +  CS% IareaT_OBCmask (i,j) *  &
19651968                     ((uhbt_int(I-1 ,j) -  uhbt_int(I,j)) +  (vhbt_int(i,J-1 ) -  vhbt_int(i,J)))
19661969        enddo  ; enddo 
19671970      elseif  (use_BT_cont) then 
@@ -1975,13 +1978,13 @@ subroutine btstep(U_in, V_in, eta_in, dt, bc_accel_u, bc_accel_v, forces, pbce,
19751978        enddo  ; enddo 
19761979        ! $OMP do
19771980        do  j= jsv-1 ,jev+1  ; do  i= isv-1 ,iev+1 
1978-           eta_pred(i,j) =  (eta(i,j) +  eta_src(i,j)) +  (dtbt *  CS% IareaT (i,j)) *  &
1981+           eta_pred(i,j) =  (eta(i,j) +  eta_src(i,j)) +  (dtbt *  CS% IareaT_OBCmask (i,j)) *  &
19791982                     ((uhbt(I-1 ,j) -  uhbt(I,j)) +  (vhbt(i,J-1 ) -  vhbt(i,J)))
19801983        enddo  ; enddo 
19811984      else 
19821985        ! $OMP do
19831986        do  j= jsv-1 ,jev+1  ; do  i= isv-1 ,iev+1 
1984-           eta_pred(i,j) =  (eta(i,j) +  eta_src(i,j)) +  (dtbt *  CS% IareaT (i,j)) *  &
1987+           eta_pred(i,j) =  (eta(i,j) +  eta_src(i,j)) +  (dtbt *  CS% IareaT_OBCmask (i,j)) *  &
19851988              (((Datu(I-1 ,j)* ubt(I-1 ,j) +  uhbt0(I-1 ,j)) -  &
19861989                (Datu(I,j)* ubt(I,j) +  uhbt0(I,j))) +  &
19871990               ((Datv(i,J-1 )* vbt(i,J-1 ) +  vhbt0(i,J-1 )) -  &
@@ -2488,14 +2491,14 @@ subroutine btstep(U_in, V_in, eta_in, dt, bc_accel_u, bc_accel_v, forces, pbce,
24882491    if  (integral_BT_cont) then 
24892492      ! $OMP do
24902493      do  j= jsv,jev ; do  i= isv,iev
2491-         eta(i,j) =  (eta_IC(i,j) +  n* eta_src(i,j)) +  CS% IareaT (i,j) *  &
2494+         eta(i,j) =  (eta_IC(i,j) +  n* eta_src(i,j)) +  CS% IareaT_OBCmask (i,j) *  &
24922495                   ((uhbt_int(I-1 ,j) -  uhbt_int(I,j)) +  (vhbt_int(i,J-1 ) -  vhbt_int(i,J)))
24932496        eta_wtd(i,j) =  eta_wtd(i,j) +  eta(i,j) *  wt_eta(n)
24942497      enddo  ; enddo 
24952498    else 
24962499      ! $OMP do
24972500      do  j= jsv,jev ; do  i= isv,iev
2498-         eta(i,j) =  (eta(i,j) +  eta_src(i,j)) +  (dtbt *  CS% IareaT (i,j)) *  &
2501+         eta(i,j) =  (eta(i,j) +  eta_src(i,j)) +  (dtbt *  CS% IareaT_OBCmask (i,j)) *  &
24992502                   ((uhbt(I-1 ,j) -  uhbt(I,j)) +  (vhbt(i,J-1 ) -  vhbt(i,J)))
25002503        eta_wtd(i,j) =  eta_wtd(i,j) +  eta(i,j) *  wt_eta(n)
25012504      enddo  ; enddo 
@@ -3283,7 +3286,7 @@ subroutine set_up_BT_OBC(OBC, eta, SpV_avg, BT_OBC, BT_Domain, G, GV, US, CS, MS
32833286  type (ocean_grid_type),                 intent (inout ) ::  G      ! < The ocean's grid structure.
32843287  type (verticalGrid_type),               intent (in )    ::  GV     ! < The ocean's vertical grid structure.
32853288  type (unit_scale_type),                 intent (in )    ::  US     ! < A dimensional unit scaling type
3286-   type (barotropic_CS),                   intent (in )     ::  CS     ! < Barotropic control structure
3289+   type (barotropic_CS),                   intent (inout )  ::  CS     ! < Barotropic control structure
32873290  integer ,                               intent (in )    ::  halo   ! < The extra halo size to use here.
32883291  logical ,                               intent (in )    ::  use_BT_cont ! < If true, use the BT_cont_types to calculate
32893292                                                                 ! ! transports.
@@ -3339,6 +3342,7 @@ subroutine set_up_BT_OBC(OBC, eta, SpV_avg, BT_OBC, BT_Domain, G, GV, US, CS, MS
33393342    allocate (BT_OBC% vhbt(isdw:iedw,jsdw-1 :jedw), source= 0.0 )
33403343    allocate (BT_OBC% vbt_outer(isdw:iedw,jsdw-1 :jedw), source= 0.0 )
33413344    allocate (BT_OBC% SSH_outer_v(isdw:iedw,jsdw-1 :jedw), source= 0.0 )
3345+ 
33423346    BT_OBC% is_alloced =  .true. 
33433347    call  create_group_pass(BT_OBC% pass_uv, BT_OBC% ubt_outer, BT_OBC% vbt_outer, BT_Domain)
33443348    call  create_group_pass(BT_OBC% pass_uhvh, BT_OBC% uhbt, BT_OBC% vhbt, BT_Domain)
@@ -3481,6 +3485,7 @@ subroutine destroy_BT_OBC(BT_OBC)
34813485    deallocate (BT_OBC% vhbt)
34823486    deallocate (BT_OBC% vbt_outer)
34833487    deallocate (BT_OBC% SSH_outer_v)
3488+ 
34843489    BT_OBC% is_alloced =  .false. 
34853490  endif 
34863491end  subroutine  destroy_BT_OBC 
@@ -4473,7 +4478,7 @@ end subroutine bt_mass_source
44734478! ! barotropic calculation and initializes any barotropic fields that have not
44744479! ! already been initialized.
44754480subroutine  barotropic_init (u , v , h , Time , G , GV , US , param_file , diag , CS , & 
4476-                            restart_CS , calc_dtbt , BT_cont , SAL_CSp , HA_CSp )
4481+                            restart_CS , calc_dtbt , BT_cont , OBC ,  SAL_CSp , HA_CSp )
44774482  type (ocean_grid_type),   intent (inout ) ::  G    ! < The ocean's grid structure.
44784483  type (verticalGrid_type), intent (in )    ::  GV   ! < The ocean's vertical grid structure.
44794484  type (unit_scale_type),   intent (in )    ::  US   ! < A dimensional unit scaling type
@@ -4494,7 +4499,8 @@ subroutine barotropic_init(u, v, h, Time, G, GV, US, param_file, diag, CS, &
44944499  type (BT_cont_type),      pointer        ::  BT_cont    ! < A structure with elements that describe the
44954500                                                 ! ! effective open face areas as a function of
44964501                                                 ! ! barotropic flow.
4497-   type (SAL_CS), target , optional  ::  SAL_CSp      ! < A pointer to the control structure of the
4502+   type (ocean_OBC_type),    pointer        ::  OBC  ! < The open boundary condition structure.
4503+   type (SAL_CS), target ,    optional       ::  SAL_CSp  ! < A pointer to the control structure of the
44984504                                                 ! ! SAL module.
44994505  type (harmonic_analysis_CS), target , optional  ::  HA_CSp ! < A pointer to the control structure of the
45004506                                                 ! ! harmonic analysis module
@@ -4692,6 +4698,10 @@ subroutine barotropic_init(u, v, h, Time, G, GV, US, param_file, diag, CS, &
46924698                 " If true, recover a bug in barotropic solver that uses an unnormalized weight " // &
46934699                 " function for vertical averages of baroclinic velocity and forcing. Default " // &
46944700                 " of this flag is set by VISC_REM_BUG."  , default= visc_rem_bug)
4701+   call  get_param(param_file, mdl, " EXTERIOR_OBC_BUG"  , CS% exterior_OBC_bug, &
4702+                  " If true, recover a bug in barotropic solver and other routines when " // &
4703+                  " boundary contitions interior to the domain are used."  , &
4704+                  default= .true. , do_not_log= .true. )
46954705  call  get_param(param_file, mdl, " TIDES"  , use_tides, &
46964706                 " If true, apply tidal momentum forcing."  , default= .false. )
46974707  if  (use_tides .and.  present (HA_CSp)) CS% HA_CSp = > HA_CSp
@@ -4934,11 +4944,49 @@ subroutine barotropic_init(u, v, h, Time, G, GV, US, param_file, diag, CS, &
49344944  ALLOC_(CS% IdyCv(CS% isdw:CS% iedw,CS% jsdw-1 :CS% jedw)) ; CS% IdyCv(:,:) =  0.0 
49354945  ALLOC_(CS% dy_Cu(CS% isdw-1 :CS% iedw,CS% jsdw:CS% jedw)) ; CS% dy_Cu(:,:) =  0.0 
49364946  ALLOC_(CS% dx_Cv(CS% isdw:CS% iedw,CS% jsdw-1 :CS% jedw)) ; CS% dx_Cv(:,:) =  0.0 
4947+   allocate (CS% IareaT_OBCmask(isdw:iedw,jsdw:jedw), source= 0.0 )
49374948  do  j= G% jsd,G% jed ; do  i= G% isd,G% ied
49384949    CS% IareaT(i,j) =  G% IareaT(i,j)
49394950    CS% bathyT(i,j) =  G% bathyT(i,j)
4951+     CS% IareaT_OBCmask(i,j) =  CS% IareaT(i,j)
49404952  enddo  ; enddo 
49414953
4954+   !  Update IareaT_OBCmask so that nothing changes outside of the OBC (problem for interior OBCs only)
4955+   if  (associated (OBC) .and.  (CS% exterior_OBC_bug .eqv.  .false. )) then 
4956+     if  (OBC% specified_u_BCs_exist_globally .or.  OBC% open_u_BCs_exist_globally) then 
4957+       do  i= isd,ied
4958+         do  j= jsd,jed
4959+           if  (OBC% segnum_u(I-1 ,j) /=  OBC_NONE) then 
4960+             if  (OBC% segment(OBC% segnum_u(I-1 ,j))% direction == OBC_DIRECTION_E) then 
4961+               CS% IareaT_OBCmask(i,j) =  0.0 
4962+             endif 
4963+           endif 
4964+           if  (OBC% segnum_u(I,j) /=  OBC_NONE) then 
4965+             if  (OBC% segment(OBC% segnum_u(I,j))% direction == OBC_DIRECTION_W) then 
4966+               CS% IareaT_OBCmask(i,j) =  0.0 
4967+             endif 
4968+           endif 
4969+         enddo 
4970+       enddo 
4971+     endif 
4972+     if  (OBC% specified_v_BCs_exist_globally .or.  OBC% open_v_BCs_exist_globally) then 
4973+       do  j= jsd,jed
4974+         do  i= isd,ied
4975+           if  (OBC% segnum_v(i,J-1 ) /=  OBC_NONE) then 
4976+             if  (OBC% segment(OBC% segnum_v(i,J-1 ))% direction == OBC_DIRECTION_N) then 
4977+               CS% IareaT_OBCmask(i,j) =  0.0 
4978+             endif 
4979+           endif 
4980+           if  (OBC% segnum_v(i,J) /=  OBC_NONE) then 
4981+             if  (OBC% segment(OBC% segnum_v(i,J))% direction == OBC_DIRECTION_S) then 
4982+               CS% IareaT_OBCmask(i,j) =  0.0 
4983+             endif 
4984+           endif 
4985+         enddo 
4986+       enddo 
4987+     endif 
4988+   endif 
4989+ 
49424990  !  Note: G%IdxCu & G%IdyCv may be valid for a smaller extent than CS%IdxCu & CS%IdyCv, even without
49434991  !    wide halos.
49444992  do  j= G% jsd,G% jed ; do  I= G% IsdB,G% IedB
@@ -4949,6 +4997,7 @@ subroutine barotropic_init(u, v, h, Time, G, GV, US, param_file, diag, CS, &
49494997  enddo  ; enddo 
49504998  call  create_group_pass(pass_static_data, CS% IareaT, CS% BT_domain, To_All)
49514999  call  create_group_pass(pass_static_data, CS% bathyT, CS% BT_domain, To_All)
5000+   call  create_group_pass(pass_static_data, CS% IareaT_OBCmask, CS% BT_domain, To_All)
49525001  call  create_group_pass(pass_static_data, CS% IdxCu, CS% IdyCv, CS% BT_domain, To_All+ Scalar_Pair)
49535002  call  create_group_pass(pass_static_data, CS% dy_Cu, CS% dx_Cv, CS% BT_domain, To_All+ Scalar_Pair)
49545003  call  do_group_pass(pass_static_data, CS% BT_domain)
@@ -5302,6 +5351,7 @@ subroutine barotropic_end(CS)
53025351
53035352  if  (allocated (CS% frhatu1)) deallocate (CS% frhatu1)
53045353  if  (allocated (CS% frhatv1)) deallocate (CS% frhatv1)
5354+   if  (allocated (CS% IareaT_OBCmask)) deallocate (CS% IareaT_OBCmask)
53055355  call  deallocate_MOM_domain(CS% BT_domain)
53065356
53075357  !  Allocated in restart registration, prior to timestep initialization
0 commit comments