This subroutine sets the properties of flow at open boundary conditions.
173 type(ocean_OBC_type),
pointer :: OBC
176 type(Kelvin_OBC_CS),
pointer :: CS
177 type(ocean_grid_type),
intent(in) :: G
178 type(verticalGrid_type),
intent(in) :: GV
179 type(unit_scale_type),
intent(in) :: US
180 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
181 type(time_type),
intent(in) :: Time
184 real :: time_sec, cff
191 integer :: i, j, k, n, is, ie, js, je, isd, ied, jsd, jed, nz
192 integer :: IsdB, IedB, JsdB, JedB
193 real :: fac, x, y, x1, y1
194 real :: val1, val2, sina, cosa
195 type(OBC_segment_type),
pointer :: segment => null()
197 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
198 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
199 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
201 if (.not.
associated(obc))
call mom_error(fatal,
'Kelvin_initialization.F90: '// &
202 'Kelvin_set_OBC_data() was called but OBC type was not initialized!')
204 time_sec = time_type_to_real(time)
208 if (cs%mode == 0)
then
209 omega = 2.0 * pi / (12.42 * 3600.0)
210 val1 = us%m_to_Z * sin(omega * time_sec)
212 n0 = us%L_to_m*us%s_to_T * sqrt((cs%rho_range / cs%rho_0) * gv%g_Earth * (us%m_to_Z * cs%H0))
214 plx = 4.0 * pi / g%len_lon
215 pmz = pi * cs%mode / cs%H0
216 lambda = pmz * cs%F_0 / n0
217 omega = cs%F_0 * plx / lambda
223 sina = sin(cs%coast_angle)
224 cosa = cos(cs%coast_angle)
225 do n=1,obc%number_of_segments
226 segment => obc%segment(n)
227 if (.not. segment%on_pe) cycle
229 if (segment%direction == obc_direction_e) cycle
230 if (segment%direction == obc_direction_n) cycle
233 segment%Velocity_nudging_timescale_in = 1.0/(0.3*86400)
235 if (segment%direction == obc_direction_w)
then
236 isdb = segment%HI%IsdB ; iedb = segment%HI%IedB
237 jsd = segment%HI%jsd ; jed = segment%HI%jed
238 jsdb = segment%HI%JsdB ; jedb = segment%HI%JedB
239 do j=jsd,jed ;
do i=isdb,iedb
240 x1 = 1000. * g%geoLonCu(i,j)
241 y1 = 1000. * g%geoLatCu(i,j)
242 x = (x1 - cs%coast_offset1) * cosa + y1 * sina
243 y = - (x1 - cs%coast_offset1) * sina + y1 * cosa
244 if (cs%mode == 0)
then
246 cff = sqrt(gv%g_Earth * g%bathyT(i+1,j) )
247 val2 = fac * exp(- us%T_to_s*cs%F_0 * us%m_to_L*y / cff)
248 segment%eta(i,j) = val2 * cos(omega * time_sec)
249 segment%normal_vel_bt(i,j) = (val2 * (val1 * cff * cosa / &
250 (g%bathyT(i+1,j) )) )
251 if (segment%nudged)
then
253 segment%nudged_normal_vel(i,j,k) = (val2 * (val1 * cff * cosa / &
256 elseif (segment%specified)
then
258 segment%normal_vel(i,j,k) = (val2 * (val1 * cff * cosa / &
259 (g%bathyT(i+1,j) )) )
260 segment%normal_trans(i,j,k) = segment%normal_vel(i,j,k) * h(i+1,j,k) * g%dyCu(i,j)
265 segment%eta(i,j) = 0.0
266 segment%normal_vel_bt(i,j) = 0.0
267 if (segment%nudged)
then
269 segment%nudged_normal_vel(i,j,k) = us%m_s_to_L_T * fac * lambda / cs%F_0 * &
270 exp(- lambda * y) * cos(pi * cs%mode * (k - 0.5) / nz) * &
271 cos(omega * time_sec)
273 elseif (segment%specified)
then
275 segment%normal_vel(i,j,k) = us%m_s_to_L_T * fac * lambda / cs%F_0 * &
276 exp(- lambda * y) * cos(pi * cs%mode * (k - 0.5) / nz) * &
277 cos(omega * time_sec)
278 segment%normal_trans(i,j,k) = segment%normal_vel(i,j,k) * h(i+1,j,k) * g%dyCu(i,j)
283 if (
associated(segment%tangential_vel))
then
284 do j=jsdb+1,jedb-1 ;
do i=isdb,iedb
285 x1 = 1000. * g%geoLonBu(i,j)
286 y1 = 1000. * g%geoLatBu(i,j)
287 x = (x1 - cs%coast_offset1) * cosa + y1 * sina
288 y = - (x1 - cs%coast_offset1) * sina + y1 * cosa
289 cff =sqrt(gv%g_Earth * g%bathyT(i+1,j) )
290 val2 = fac * exp(- us%T_to_s*cs%F_0 * us%m_to_L*y / cff)
291 if (cs%mode == 0)
then ;
do k=1,nz
292 segment%tangential_vel(i,j,k) = (val1 * val2 * cff * sina) / &
293 ( 0.5*(g%bathyT(i+1,j+1) + g%bathyT(i+1,j) ) )
299 isd = segment%HI%isd ; ied = segment%HI%ied
300 jsdb = segment%HI%JsdB ; jedb = segment%HI%JedB
301 do j=jsdb,jedb ;
do i=isd,ied
302 x1 = 1000. * g%geoLonCv(i,j)
303 y1 = 1000. * g%geoLatCv(i,j)
304 x = (x1 - cs%coast_offset1) * cosa + y1 * sina
305 y = - (x1 - cs%coast_offset1) * sina + y1 * cosa
306 if (cs%mode == 0)
then
307 cff = sqrt(gv%g_Earth * g%bathyT(i,j+1) )
308 val2 = fac * exp(- 0.5 * (g%CoriolisBu(i,j) + g%CoriolisBu(i-1,j)) * us%m_to_L*y / cff)
309 segment%eta(i,j) = val2 * cos(omega * time_sec)
310 segment%normal_vel_bt(i,j) = us%L_T_to_m_s * (val1 * cff * sina / &
311 (g%bathyT(i,j+1) )) * val2
312 if (segment%nudged)
then
314 segment%nudged_normal_vel(i,j,k) = us%L_T_to_m_s * (val1 * cff * sina / &
315 (g%bathyT(i,j+1) )) * val2
317 elseif (segment%specified)
then
319 segment%normal_vel(i,j,k) = us%L_T_to_m_s * (val1 * cff * sina / &
320 (g%bathyT(i,j+1) )) * val2
321 segment%normal_trans(i,j,k) = segment%normal_vel(i,j,k) * h(i,j+1,k) * g%dxCv(i,j)
326 segment%eta(i,j) = 0.0
327 segment%normal_vel_bt(i,j) = 0.0
328 if (segment%nudged)
then
330 segment%nudged_normal_vel(i,j,k) = us%m_s_to_L_T*fac * lambda / cs%F_0 * &
331 exp(- lambda * y) * cos(pi * cs%mode * (k - 0.5) / nz) * cosa
333 elseif (segment%specified)
then
335 segment%normal_vel(i,j,k) = us%m_s_to_L_T*fac * lambda / cs%F_0 * &
336 exp(- lambda * y) * cos(pi * cs%mode * (k - 0.5) / nz) * cosa
337 segment%normal_trans(i,j,k) = segment%normal_vel(i,j,k) * h(i,j+1,k) * g%dxCv(i,j)
342 if (
associated(segment%tangential_vel))
then
343 do j=jsdb,jedb ;
do i=isdb+1,iedb-1
344 x1 = 1000. * g%geoLonBu(i,j)
345 y1 = 1000. * g%geoLatBu(i,j)
346 x = (x1 - cs%coast_offset1) * cosa + y1 * sina
347 y = - (x1 - cs%coast_offset1) * sina + y1 * cosa
348 cff = sqrt(gv%g_Earth * g%bathyT(i,j+1) )
349 val2 = fac * exp(- 0.5 * (g%CoriolisBu(i,j) + g%CoriolisBu(i-1,j)) * us%m_to_L*y / cff)
350 if (cs%mode == 0)
then ;
do k=1,nz
351 segment%tangential_vel(i,j,k) = ((val1 * val2 * cff * sina) / &
352 ( 0.5*((g%bathyT(i+1,j+1)) + g%bathyT(i,j+1))) )