This subroutine sets the properties of flow at open boundary conditions.
184 type(ocean_OBC_type),
pointer :: OBC
187 type(Kelvin_OBC_CS),
pointer :: CS
188 type(ocean_grid_type),
intent(in) :: G
189 type(verticalGrid_type),
intent(in) :: GV
190 type(unit_scale_type),
intent(in) :: US
191 real,
dimension(SZI_(G),SZJ_(G),SZK_(G)),
intent(in) :: h
192 type(time_type),
intent(in) :: Time
195 real :: time_sec, cff
202 integer :: i, j, k, n, is, ie, js, je, isd, ied, jsd, jed, nz
203 integer :: IsdB, IedB, JsdB, JedB
204 real :: fac, x, y, x1, y1
205 real :: val1, val2, sina, cosa
206 type(OBC_segment_type),
pointer :: segment => null()
208 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
209 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
210 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
212 if (.not.
associated(obc))
call mom_error(fatal,
'Kelvin_initialization.F90: '// &
213 'Kelvin_set_OBC_data() was called but OBC type was not initialized!')
215 time_sec = time_type_to_real(time)
219 if (cs%mode == 0)
then
220 omega = 2.0 * pi / (12.42 * 3600.0)
221 val1 = us%m_to_Z * sin(omega * time_sec)
223 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))
225 plx = 4.0 * pi / g%len_lon
226 pmz = pi * cs%mode / cs%H0
227 lambda = pmz * cs%F_0 / n0
228 omega = cs%F_0 * plx / lambda
234 sina = sin(cs%coast_angle)
235 cosa = cos(cs%coast_angle)
236 do n=1,obc%number_of_segments
237 segment => obc%segment(n)
238 if (.not. segment%on_pe) cycle
240 if (segment%direction == obc_direction_e) cycle
241 if (segment%direction == obc_direction_n) cycle
244 segment%Velocity_nudging_timescale_in = 1.0/(0.3*86400)
246 if (segment%direction == obc_direction_w)
then
247 isdb = segment%HI%IsdB ; iedb = segment%HI%IedB
248 jsd = segment%HI%jsd ; jed = segment%HI%jed
249 jsdb = segment%HI%JsdB ; jedb = segment%HI%JedB
250 do j=jsd,jed ;
do i=isdb,iedb
251 x1 = 1000. * g%geoLonCu(i,j)
252 y1 = 1000. * g%geoLatCu(i,j)
253 x = (x1 - cs%coast_offset1) * cosa + y1 * sina
254 y = - (x1 - cs%coast_offset1) * sina + y1 * cosa
255 if (cs%mode == 0)
then
256 cff = sqrt(gv%g_Earth * 0.5 * (g%bathyT(i+1,j) + g%bathyT(i,j)))
257 val2 = fac * exp(- us%T_to_s*cs%F_0 * us%m_to_L*y / cff)
258 segment%eta(i,j) = val2 * cos(omega * time_sec)
259 segment%normal_vel_bt(i,j) = us%L_T_to_m_s * (val2 * (val1 * cff * cosa / &
260 (0.5 * (g%bathyT(i+1,j) + g%bathyT(i,j)))) )
263 segment%eta(i,j) = 0.0
264 segment%normal_vel_bt(i,j) = 0.0
265 if (segment%nudged)
then
267 segment%nudged_normal_vel(i,j,k) = fac * lambda / cs%F_0 * &
268 exp(- lambda * y) * cos(pi * cs%mode * (k - 0.5) / nz) * &
269 cos(omega * time_sec)
271 elseif (segment%specified)
then
273 segment%normal_vel(i,j,k) = fac * lambda / cs%F_0 * &
274 exp(- lambda * y) * cos(pi * cs%mode * (k - 0.5) / nz) * &
275 cos(omega * time_sec)
276 segment%normal_trans(i,j,k) = segment%normal_vel(i,j,k) * &
277 h(i+1,j,k) * g%dyCu(i,j)
282 if (
associated(segment%tangential_vel))
then
283 do j=jsdb+1,jedb-1 ;
do i=isdb,iedb
284 x1 = 1000. * g%geoLonBu(i,j)
285 y1 = 1000. * g%geoLatBu(i,j)
286 x = (x1 - cs%coast_offset1) * cosa + y1 * sina
287 y = - (x1 - cs%coast_offset1) * sina + y1 * cosa
288 if (cs%answers_2018)
then
290 if (cs%mode == 0)
then ;
do k=1,nz
291 segment%tangential_vel(i,j,k) = us%L_T_to_m_s * (val2 * (val1 * cff * sina / &
292 (0.25 * (g%bathyT(i+1,j) + g%bathyT(i,j) + g%bathyT(i+1,j+1) + g%bathyT(i,j+1))) ))
295 cff =sqrt(gv%g_Earth * 0.5 * (g%bathyT(i+1,j) + g%bathyT(i,j)))
296 val2 = fac * exp(- us%T_to_s*cs%F_0 * us%m_to_L*y / cff)
297 if (cs%mode == 0)
then ;
do k=1,nz
298 segment%tangential_vel(i,j,k) = us%L_T_to_m_s * (val1 * val2 * cff * sina) / &
299 ( 0.25*((g%bathyT(i,j) + g%bathyT(i+1,j+1)) + (g%bathyT(i+1,j) + g%bathyT(i,j+1))) )
306 isd = segment%HI%isd ; ied = segment%HI%ied
307 jsdb = segment%HI%JsdB ; jedb = segment%HI%JedB
308 do j=jsdb,jedb ;
do i=isd,ied
309 x1 = 1000. * g%geoLonCv(i,j)
310 y1 = 1000. * g%geoLatCv(i,j)
311 x = (x1 - cs%coast_offset1) * cosa + y1 * sina
312 y = - (x1 - cs%coast_offset1) * sina + y1 * cosa
313 if (cs%mode == 0)
then
314 cff = sqrt(gv%g_Earth * 0.5 * (g%bathyT(i,j+1) + g%bathyT(i,j)))
315 val2 = fac * exp(- 0.5 * (g%CoriolisBu(i,j) + g%CoriolisBu(i-1,j)) * us%m_to_L*y / cff)
316 segment%eta(i,j) = val2 * cos(omega * time_sec)
317 segment%normal_vel_bt(i,j) = us%L_T_to_m_s * (val1 * cff * sina / &
318 (0.5*(g%bathyT(i+1,j) + g%bathyT(i,j)))) * val2
321 segment%eta(i,j) = 0.0
322 segment%normal_vel_bt(i,j) = 0.0
323 if (segment%nudged)
then
325 segment%nudged_normal_vel(i,j,k) = fac * lambda / cs%F_0 * &
326 exp(- lambda * y) * cos(pi * cs%mode * (k - 0.5) / nz) * cosa
328 elseif (segment%specified)
then
330 segment%normal_vel(i,j,k) = fac * lambda / cs%F_0 * &
331 exp(- lambda * y) * cos(pi * cs%mode * (k - 0.5) / nz) * cosa
332 segment%normal_trans(i,j,k) = segment%normal_vel(i,j,k) * &
333 h(i,j+1,k) * g%dxCv(i,j)
338 if (
associated(segment%tangential_vel))
then
339 do j=jsdb,jedb ;
do i=isdb+1,iedb-1
340 x1 = 1000. * g%geoLonBu(i,j)
341 y1 = 1000. * g%geoLatBu(i,j)
342 x = (x1 - cs%coast_offset1) * cosa + y1 * sina
343 y = - (x1 - cs%coast_offset1) * sina + y1 * cosa
344 if (cs%answers_2018)
then
346 if (cs%mode == 0)
then ;
do k=1,nz
347 segment%tangential_vel(i,j,k) = us%L_T_to_m_s * (val2 * (val1 * cff * sina / &
348 (0.25*(g%bathyT(i+1,j) + g%bathyT(i,j) + g%bathyT(i+1,j+1) + g%bathyT(i,j+1)))))
351 cff = sqrt(gv%g_Earth * 0.5 * (g%bathyT(i,j+1) + g%bathyT(i,j)))
352 val2 = fac * exp(- 0.5 * (g%CoriolisBu(i,j) + g%CoriolisBu(i-1,j)) * us%m_to_L*y / cff)
353 if (cs%mode == 0)
then ;
do k=1,nz
354 segment%tangential_vel(i,j,k) = us%L_T_to_m_s * ((val1 * val2 * cff * sina) / &
355 ( 0.25*((g%bathyT(i,j) + g%bathyT(i+1,j+1)) + (g%bathyT(i+1,j) + g%bathyT(i,j+1))) ))