Skip to content

Commit a01cc39

Browse files
committed
+Use OBCs to set masks
Added the ability to take open boundary conditions into account when setting up the masks, by providing the new optional arguments OBC_dir_u and OBC_dir_v in calls to initialize_masks(). The new optional argument open_corner_OBCs to initialize_masks() can be used to specify that convex corners between OBC segments should be treated as open. These had to be handled via optional arguments because SIS2 also calls initialize_masks and it is under separate version control. By default all answers are bitwise identical, but there are new optional arguments to a publicly visible routine.
1 parent c926d7d commit a01cc39

File tree

2 files changed

+88
-10
lines changed

2 files changed

+88
-10
lines changed

src/initialization/MOM_fixed_initialization.F90

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,11 @@ subroutine MOM_initialize_fixed(G, US, OBC, PF)
9494
call open_boundary_impose_normal_slope(OBC, G, G%bathyT)
9595

9696
! This call sets masks that prohibit flow over any point interpreted as land
97-
call initialize_masks(G, PF, US)
97+
if (associated(OBC)) then
98+
call initialize_masks(G, PF, US, OBC_dir_u=OBC%segnum_u, OBC_dir_v=OBC%segnum_v)
99+
else
100+
call initialize_masks(G, PF, US)
101+
endif
98102

99103
! Make OBC mask consistent with land mask
100104
call open_boundary_impose_land_mask(OBC, G, G%areaCu, G%areaCv, US)

src/initialization/MOM_grid_initialize.F90

Lines changed: 83 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,16 +1182,33 @@ end function Adcroft_reciprocal
11821182
!! flow over any points which are shallower than Dmask and permit an
11831183
!! appropriate treatment of the boundary conditions. mask2dCu and mask2dCv
11841184
!! are 0.0 at any points adjacent to a land point. mask2dBu is 0.0 at
1185-
!! any land or boundary point. For points in the interior, mask2dCu,
1186-
!! mask2dCv, and mask2dBu are all 1.0.
1187-
subroutine initialize_masks(G, PF, US)
1185+
!! any land or boundary point. For points in the ocean interior or at open boundary
1186+
!! condition points, mask2dCu, mask2dCv, and mask2dBu are all 1.0.
1187+
subroutine initialize_masks(G, PF, US, OBC_dir_u, OBC_dir_v, open_corner_OBCs)
11881188
type(dyn_horgrid_type), intent(inout) :: G !< The dynamic horizontal grid type
11891189
type(param_file_type), intent(in) :: PF !< Parameter file structure
11901190
type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
1191+
integer, dimension(G%IsdB:G%IedB,G%jsd:G%jed), &
1192+
optional, intent(in) :: OBC_dir_u !< Trinary values that indicate whether there
1193+
!! is an open boundary condition at zonal velocity
1194+
!! faces and their orientation, with 0 for no OBC,
1195+
!! a positive value for an Eastern OBC and
1196+
!! a negative value for a Western OBC.
1197+
integer, dimension(G%isd:G%ied,G%JsdB:G%JedB), &
1198+
optional, intent(in) :: OBC_dir_v !< Trinary values that indicate whether there
1199+
!! is an open boundary condition at zonal velocity
1200+
!! faces and their orientation, with 0 for no OBC,
1201+
!! a positive value for a Northern OBC and
1202+
!! a negative value for a Southern OBC.
1203+
logical, optional, intent(in) :: open_corner_OBCs !< If present and true, the bay-like corner
1204+
!! between two orthogonal open boundary segments is open,
1205+
!! otherwise it is closed.
1206+
11911207
! Local variables
11921208
real :: Dmask ! The depth for masking in the same units as G%bathyT [Z ~> m].
11931209
real :: min_depth ! The minimum ocean depth in the same units as G%bathyT [Z ~> m].
11941210
real :: mask_depth ! The depth shallower than which to mask a point as land [Z ~> m].
1211+
logical :: open_corners ! If true, the bay-like corner between two orthogonal open boundary segments is open
11951212
character(len=40) :: mdl = "MOM_grid_init initialize_masks"
11961213
integer :: i, j
11971214

@@ -1212,6 +1229,8 @@ subroutine initialize_masks(G, PF, US)
12121229
Dmask = mask_depth
12131230
if (mask_depth == -9999.0*US%m_to_Z) Dmask = min_depth
12141231

1232+
open_corners = .false. ; if (present(open_corner_OBCs)) open_corners = open_corner_OBCs
1233+
12151234
G%mask2dCu(:,:) = 0.0 ; G%mask2dCv(:,:) = 0.0 ; G%mask2dBu(:,:) = 0.0
12161235

12171236
! Construct the h-point or T-point mask
@@ -1229,6 +1248,20 @@ subroutine initialize_masks(G, PF, US)
12291248
else
12301249
G%mask2dCu(I,j) = 1.0
12311250
endif
1251+
enddo ; enddo
1252+
1253+
if (present(OBC_dir_u)) then
1254+
do j=G%jsd,G%jed ; do I=G%isd,G%ied-1
1255+
if (OBC_dir_u(I,j) > 0) then
1256+
if (G%bathyT(i,j) > Dmask) G%mask2dCu(I,j) = 1.0
1257+
endif
1258+
if (OBC_dir_u(I,j) < 0) then
1259+
if (G%bathyT(i+1,j) > Dmask) G%mask2dCu(I,j) = 1.0
1260+
endif
1261+
enddo ; enddo
1262+
endif
1263+
1264+
do j=G%jsd,G%jed ; do I=G%isd,G%ied-1
12321265
! This mask may be revised later after the open boundary positions are specified.
12331266
G%OBCmaskCu(I,j) = G%mask2dCu(I,j)
12341267
enddo ; enddo
@@ -1239,19 +1272,60 @@ subroutine initialize_masks(G, PF, US)
12391272
else
12401273
G%mask2dCv(i,J) = 1.0
12411274
endif
1275+
enddo ; enddo
1276+
1277+
if (present(OBC_dir_v)) then
1278+
do J=G%jsd,G%jed-1 ; do i=G%isd,G%ied
1279+
if (OBC_dir_v(i,J) > 0) then
1280+
if (G%bathyT(i,j) > Dmask) G%mask2dCv(i,J) = 1.0
1281+
endif
1282+
if (OBC_dir_v(i,J) < 0) then
1283+
if (G%bathyT(i,j+1) > Dmask) G%mask2dCv(i,J) = 1.0
1284+
endif
1285+
enddo ; enddo
1286+
endif
1287+
1288+
do J=G%jsd,G%jed-1 ; do i=G%isd,G%ied
12421289
! This mask may be revised later after the open boundary positions are specified.
12431290
G%OBCmaskCv(i,J) = G%mask2dCv(i,J)
12441291
enddo ; enddo
12451292

1293+
! The mask at the vertex can be determined from the masks at the faces.
1294+
! This works at interior ocean points or at convex OBC points.
12461295
do J=G%jsd,G%jed-1 ; do I=G%isd,G%ied-1
1247-
if ((G%bathyT(i+1,j) <= Dmask) .or. (G%bathyT(i+1,j+1) <= Dmask) .or. &
1248-
(G%bathyT(i,j) <= Dmask) .or. (G%bathyT(i,j+1) <= Dmask)) then
1249-
G%mask2dBu(I,J) = 0.0
1250-
else
1251-
G%mask2dBu(I,J) = 1.0
1252-
endif
1296+
G%mask2dBu(I,J) = (G%mask2dCu(I,j) * G%mask2dCu(I,j+1)) * (G%mask2dCv(i,J) * G%mask2dCv(i+1,J))
12531297
enddo ; enddo
12541298

1299+
! This block resets masks at the vertices when there are OBCs. The right logic is that if there
1300+
! are 2 or more unmasked OBCs, this point should be open, but to recreate the previous answers,
1301+
if (present(OBC_dir_u)) then
1302+
do J=G%jsd,G%jed-1 ; do I=G%isd,G%ied-1
1303+
! These are conditions to set open vertex points on a straight north-south coastline
1304+
if ((G%mask2dCu(I,j) * OBC_dir_u(I,j)) * (G%mask2dCu(I,j+1) * OBC_dir_u(I,j+1)) > 0.) &
1305+
G%mask2dBu(I,J) = 1.0
1306+
enddo ; enddo
1307+
endif
1308+
if (present(OBC_dir_v)) then
1309+
do J=G%jsd,G%jed-1 ; do I=G%isd,G%ied-1
1310+
! These are conditions to set open vertex points on a straight east-west coastline
1311+
if ((G%mask2dCv(i,J) * OBC_dir_v(i,J)) * (G%mask2dCv(i+1,J) * OBC_dir_v(i+1,J)) > 0.) &
1312+
G%mask2dBu(I,J) = 1.0
1313+
enddo ; enddo
1314+
endif
1315+
if (open_corners .and. present(OBC_dir_u) .and. present(OBC_dir_v)) then
1316+
do J=G%jsd,G%jed-1 ; do I=G%isd,G%ied-1
1317+
! These are the 4 conditions to set an open point in a concave (bay-like) corner
1318+
if ((G%mask2dCu(I,j+1) * OBC_dir_u(I,j+1) < 0.) .and. (G%mask2dCv(i+1,J) * OBC_dir_v(i+1,J) < 0.)) &
1319+
G%mask2dBu(I,J) = 1.0 ! Southwestern corner
1320+
if ((G%mask2dCu(I,j+1) * OBC_dir_u(I,j+1) > 0.) .and. (G%mask2dCv(i,J) * OBC_dir_v(i,J) < 0.)) &
1321+
G%mask2dBu(I,J) = 1.0 ! Southeastern corner
1322+
if ((G%mask2dCu(I,j) * OBC_dir_u(I,j) < 0.) .and. (G%mask2dCv(i+1,J) * OBC_dir_v(i+1,J) > 0.)) &
1323+
G%mask2dBu(I,J) = 1.0 ! Northwestern corner
1324+
if ((G%mask2dCu(I,j) * OBC_dir_u(I,j) > 0.) .and. (G%mask2dCv(i,J) * OBC_dir_v(i,J) > 0.)) &
1325+
G%mask2dBu(I,J) = 1.0 ! Northeastern corner
1326+
enddo ; enddo
1327+
endif
1328+
12551329
call pass_var(G%mask2dBu, G%Domain, position=CORNER)
12561330
call pass_vector(G%mask2dCu, G%mask2dCv, G%Domain, To_All+Scalar_Pair, CGRID_NE)
12571331

0 commit comments

Comments
 (0)