tidal_bay_initialization.F90

1! This file is part of MOM6, the Modular Ocean Model version 6.
2! See the LICENSE file for licensing information.
3! SPDX-License-Identifier: Apache-2.0
4
5!> Configures the model for the "tidal_bay" experiment.
6!! tidal_bay = Tidally resonant bay from Zygmunt Kowalik's class on tides.
8
9use mom_coms, only : reproducing_sum
11use mom_error_handler, only : mom_mesg, mom_error, fatal, warning, is_root_pe
12use mom_file_parser, only : get_param, log_version, param_file_type
13use mom_grid, only : ocean_grid_type
18use mom_time_manager, only : time_type, time_to_real
19
20implicit none ; private
21
22#include <MOM_memory.h>
23
26
27!> Control structure for tidal bay open boundaries.
28type, public :: tidal_bay_obc_cs ; private
29 real :: tide_flow = 3.0e6 !< Maximum tidal flux with the tidal bay configuration [L2 Z T-1 ~> m3 s-1]
30 real :: tide_period !< The period associated with the tidal bay configuration [T ~> s]
31 real :: tide_ssh_amp !< The magnitude of the sea surface height anomalies at the inflow
32 !! with the tidal bay configuration [Z ~> m]
33end type tidal_bay_obc_cs
34
35contains
36
37!> Add tidal bay to OBC registry.
38function register_tidal_bay_obc(param_file, CS, US)
39 type(param_file_type), intent(in) :: param_file !< parameter file.
40 type(tidal_bay_obc_cs), intent(inout) :: cs !< tidal bay control structure.
41 type(unit_scale_type), intent(in) :: us !< A dimensional unit scaling type
42 logical :: register_tidal_bay_obc
43 character(len=40) :: mdl = "tidal_bay_initialization" ! This module's name.
44
45 call get_param(param_file, mdl, "TIDAL_BAY_FLOW", cs%tide_flow, &
46 "Maximum total tidal volume flux.", &
47 units="m3 s-1", default=3.0e6, scale=us%m_s_to_L_T*us%m_to_L*us%m_to_Z)
48 call get_param(param_file, mdl, "TIDAL_BAY_PERIOD", cs%tide_period, &
49 "Period of the inflow in the tidal bay configuration.", &
50 units="s", default=12.0*3600.0, scale=us%s_to_T)
51 call get_param(param_file, mdl, "TIDAL_BAY_SSH_ANOM", cs%tide_ssh_amp, &
52 "Magnitude of the sea surface height anomalies at the inflow with the "//&
53 "tidal bay configuration.", &
54 units="m", default=0.1, scale=us%m_to_Z)
55
57
58end function register_tidal_bay_obc
59
60!> This subroutine sets the properties of flow at open boundary conditions.
61subroutine tidal_bay_set_obc_data(OBC, CS, G, GV, US, h, Time)
62 type(ocean_obc_type), pointer :: obc !< This open boundary condition type specifies
63 !! whether, where, and what open boundary
64 !! conditions are used.
65 type(tidal_bay_obc_cs), intent(in) :: cs !< tidal bay control structure.
66 type(ocean_grid_type), intent(in) :: g !< The ocean's grid structure.
67 type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure
68 type(unit_scale_type), intent(in) :: us !< A dimensional unit scaling type
69 real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< layer thickness [H ~> m or kg m-2]
70 type(time_type), intent(in) :: time !< model time.
71
72 ! The following variables are used to set up the transport in the tidal_bay example.
73 real :: time_sec ! Elapsed model time [T ~> s]
74 real :: cff_eta ! The sea surface height anomalies associated with the inflow [Z ~> m]
75 real :: my_flux ! The volume flux through the face [L2 Z T-1 ~> m3 s-1]
76 real :: total_area ! The total face area of the OBCs [L Z ~> m2]
77 real :: normal_vel ! The normal velocity through the inflow face [L T-1 ~> m s-1]
78 real :: pi ! The ratio of the circumference of a circle to its diameter [nondim]
79 real, allocatable :: my_area(:,:) ! The total OBC inflow area [L Z ~> m2]
80 integer :: turns ! Number of index quarter turns
81 integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz, n
82 integer :: isdb, iedb, jsdb, jedb
83 type(obc_segment_type), pointer :: segment => null()
84
85 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = gv%ke
86 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
87 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
88
89 pi = 4.0*atan(1.0)
90
91 turns = modulo(g%HI%turns, 4)
92
93 if (.not.associated(obc)) return
94
95 time_sec = time_to_real(time, scale=us%s_to_T)
96 cff_eta = cs%tide_ssh_amp * sin(2.0*pi*time_sec / cs%tide_period)
97
98 segment => obc%segment(1)
99
100 if (turns == 0) then
101 allocate(my_area(1:1,js:je), source=0.0)
102 do j=segment%HI%jsc,segment%HI%jec ; do i=segment%HI%IscB,segment%HI%IecB
103 if (obc%segnum_u(i,j) > 0) then ! (segment%direction == OBC_DIRECTION_E)
104 do k=1,nz
105 my_area(1,j) = my_area(1,j) + h(i,j,k)*(gv%H_to_m*us%m_to_Z)*g%dyCu(i,j)
106 enddo
107 endif
108 enddo ; enddo
109 elseif (turns == 1) then
110 allocate(my_area(is:ie,1:1), source=0.0)
111 do j=segment%HI%JscB,segment%HI%JecB ; do i=segment%HI%isc,segment%HI%iec
112 if (obc%segnum_v(i,j) > 0) then ! (segment%direction == OBC_DIRECTION_N)
113 do k=1,nz
114 my_area(i,1) = my_area(i,1) + h(i,j,k)*(gv%H_to_m*us%m_to_Z)*g%dxCv(i,j)
115 enddo
116 endif
117 enddo ; enddo
118 elseif (turns == 2) then
119 allocate(my_area(1:1,js:je), source=0.0)
120 do j=segment%HI%jsc,segment%HI%jec ; do i=segment%HI%IscB,segment%HI%IecB
121 if (obc%segnum_u(i,j) < 0) then ! (segment%direction == OBC_DIRECTION_W)
122 do k=1,nz
123 my_area(1,j) = my_area(1,j) + h(i+1,j,k)*(gv%H_to_m*us%m_to_Z)*g%dyCu(i,j)
124 enddo
125 endif
126 enddo ; enddo
127 elseif (turns == 3) then
128 allocate(my_area(is:ie,1:1), source=0.0)
129 do j=segment%HI%JscB,segment%HI%JecB ; do i=segment%HI%isc,segment%HI%iec
130 if (obc%segnum_v(i,j) < 0) then ! (segment%direction == OBC_DIRECTION_S)
131 do k=1,nz
132 my_area(i,1) = my_area(i,1) + h(i,j+1,k)*(gv%H_to_m*us%m_to_Z)*g%dxCv(i,j)
133 enddo
134 endif
135 enddo ; enddo
136 endif
137
138 total_area = reproducing_sum(my_area, unscale=us%Z_to_m*us%L_to_m)
139 my_flux = - cs%tide_flow * sin(2.0*pi*time_sec / cs%tide_period)
140 normal_vel = my_flux / total_area
141 if ((turns==2) .or. (turns==3)) normal_vel = -1.0 * normal_vel
142
143 do n = 1, obc%number_of_segments
144 segment => obc%segment(n)
145 if (.not. segment%on_pe) cycle
146
147 segment%normal_vel_bt(:,:) = normal_vel
148 segment%SSH(:,:) = cff_eta
149
150 enddo ! end segment loop
151
152end subroutine tidal_bay_set_obc_data
153