bdydyn3d.F90 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. MODULE bdydyn3d
  2. !!======================================================================
  3. !! *** MODULE bdydyn3d ***
  4. !! Unstructured Open Boundary Cond. : Flow relaxation scheme on baroclinic velocities
  5. !!======================================================================
  6. !! History : 3.4 ! 2011 (D. Storkey) new module as part of BDY rewrite
  7. !! 3.5 ! 2012 (S. Mocavero, I. Epicoco) Optimization of BDY communications
  8. !!----------------------------------------------------------------------
  9. #if defined key_bdy
  10. !!----------------------------------------------------------------------
  11. !! 'key_bdy' : Unstructured Open Boundary Condition
  12. !!----------------------------------------------------------------------
  13. !! bdy_dyn3d : apply open boundary conditions to baroclinic velocities
  14. !! bdy_dyn3d_frs : apply Flow Relaxation Scheme
  15. !!----------------------------------------------------------------------
  16. USE timing ! Timing
  17. USE oce ! ocean dynamics and tracers
  18. USE dom_oce ! ocean space and time domain
  19. USE bdy_oce ! ocean open boundary conditions
  20. USE bdylib ! for orlanski library routines
  21. USE lbclnk ! ocean lateral boundary conditions (or mpp link)
  22. USE in_out_manager !
  23. Use phycst
  24. IMPLICIT NONE
  25. PRIVATE
  26. PUBLIC bdy_dyn3d ! routine called by bdy_dyn
  27. PUBLIC bdy_dyn3d_dmp ! routine called by step
  28. !! * Substitutions
  29. # include "domzgr_substitute.h90"
  30. !!----------------------------------------------------------------------
  31. !! NEMO/OPA 3.3 , NEMO Consortium (2010)
  32. !! $Id: bdydyn3d.F90 2355 2015-05-20 07:11:50Z ufla $
  33. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  34. !!----------------------------------------------------------------------
  35. CONTAINS
  36. SUBROUTINE bdy_dyn3d( kt )
  37. !!----------------------------------------------------------------------
  38. !! *** SUBROUTINE bdy_dyn3d ***
  39. !!
  40. !! ** Purpose : - Apply open boundary conditions for baroclinic velocities
  41. !!
  42. !!----------------------------------------------------------------------
  43. INTEGER, INTENT( in ) :: kt ! Main time step counter
  44. !!
  45. INTEGER :: ib_bdy ! loop index
  46. !!
  47. DO ib_bdy=1, nb_bdy
  48. SELECT CASE( cn_dyn3d(ib_bdy) )
  49. CASE('none')
  50. CYCLE
  51. CASE('frs')
  52. CALL bdy_dyn3d_frs( idx_bdy(ib_bdy), dta_bdy(ib_bdy), kt, ib_bdy )
  53. CASE('specified')
  54. CALL bdy_dyn3d_spe( idx_bdy(ib_bdy), dta_bdy(ib_bdy), kt, ib_bdy )
  55. CASE('zero')
  56. CALL bdy_dyn3d_zro( idx_bdy(ib_bdy), dta_bdy(ib_bdy), kt, ib_bdy )
  57. CASE('orlanski')
  58. CALL bdy_dyn3d_orlanski( idx_bdy(ib_bdy), dta_bdy(ib_bdy), ib_bdy, ll_npo=.false. )
  59. CASE('orlanski_npo')
  60. CALL bdy_dyn3d_orlanski( idx_bdy(ib_bdy), dta_bdy(ib_bdy), ib_bdy, ll_npo=.true. )
  61. CASE DEFAULT
  62. CALL ctl_stop( 'bdy_dyn3d : unrecognised option for open boundaries for baroclinic velocities' )
  63. END SELECT
  64. ENDDO
  65. END SUBROUTINE bdy_dyn3d
  66. SUBROUTINE bdy_dyn3d_spe( idx, dta, kt , ib_bdy )
  67. !!----------------------------------------------------------------------
  68. !! *** SUBROUTINE bdy_dyn3d_spe ***
  69. !!
  70. !! ** Purpose : - Apply a specified value for baroclinic velocities
  71. !! at open boundaries.
  72. !!
  73. !!----------------------------------------------------------------------
  74. INTEGER :: kt
  75. TYPE(OBC_INDEX), INTENT(in) :: idx ! OBC indices
  76. TYPE(OBC_DATA), INTENT(in) :: dta ! OBC external data
  77. INTEGER, INTENT(in) :: ib_bdy ! BDY set index
  78. !!
  79. INTEGER :: jb, jk ! dummy loop indices
  80. INTEGER :: ii, ij, igrd ! local integers
  81. REAL(wp) :: zwgt ! boundary weight
  82. !!----------------------------------------------------------------------
  83. !
  84. IF( nn_timing == 1 ) CALL timing_start('bdy_dyn3d_spe')
  85. !
  86. igrd = 2 ! Relaxation of zonal velocity
  87. DO jb = 1, idx%nblenrim(igrd)
  88. DO jk = 1, jpkm1
  89. ii = idx%nbi(jb,igrd)
  90. ij = idx%nbj(jb,igrd)
  91. ua(ii,ij,jk) = dta%u3d(jb,jk) * umask(ii,ij,jk)
  92. END DO
  93. END DO
  94. !
  95. igrd = 3 ! Relaxation of meridional velocity
  96. DO jb = 1, idx%nblenrim(igrd)
  97. DO jk = 1, jpkm1
  98. ii = idx%nbi(jb,igrd)
  99. ij = idx%nbj(jb,igrd)
  100. va(ii,ij,jk) = dta%v3d(jb,jk) * vmask(ii,ij,jk)
  101. END DO
  102. END DO
  103. CALL lbc_bdy_lnk( ua, 'U', -1., ib_bdy ) ! Boundary points should be updated
  104. CALL lbc_bdy_lnk( va, 'V', -1., ib_bdy )
  105. !
  106. IF( kt .eq. nit000 ) CLOSE( unit = 102 )
  107. IF( nn_timing == 1 ) CALL timing_stop('bdy_dyn3d_spe')
  108. END SUBROUTINE bdy_dyn3d_spe
  109. SUBROUTINE bdy_dyn3d_zro( idx, dta, kt, ib_bdy )
  110. !!----------------------------------------------------------------------
  111. !! *** SUBROUTINE bdy_dyn3d_zro ***
  112. !!
  113. !! ** Purpose : - baroclinic velocities = 0. at open boundaries.
  114. !!
  115. !!----------------------------------------------------------------------
  116. INTEGER :: kt
  117. TYPE(OBC_INDEX), INTENT(in) :: idx ! OBC indices
  118. TYPE(OBC_DATA), INTENT(in) :: dta ! OBC external data
  119. INTEGER, INTENT(in) :: ib_bdy ! BDY set index
  120. !!
  121. INTEGER :: ib, ik ! dummy loop indices
  122. INTEGER :: ii, ij, igrd, zcoef ! local integers
  123. REAL(wp) :: zwgt ! boundary weight
  124. !!----------------------------------------------------------------------
  125. !
  126. IF( nn_timing == 1 ) CALL timing_start('bdy_dyn3d_zro')
  127. !
  128. igrd = 2 ! Everything is at T-points here
  129. DO ib = 1, idx%nblenrim(igrd)
  130. ii = idx%nbi(ib,igrd)
  131. ij = idx%nbj(ib,igrd)
  132. DO ik = 1, jpkm1
  133. ua(ii,ij,ik) = 0._wp
  134. END DO
  135. END DO
  136. igrd = 3 ! Everything is at T-points here
  137. DO ib = 1, idx%nblenrim(igrd)
  138. ii = idx%nbi(ib,igrd)
  139. ij = idx%nbj(ib,igrd)
  140. DO ik = 1, jpkm1
  141. va(ii,ij,ik) = 0._wp
  142. END DO
  143. END DO
  144. !
  145. CALL lbc_bdy_lnk( ua, 'U', -1., ib_bdy ) ; CALL lbc_bdy_lnk( va, 'V', -1.,ib_bdy ) ! Boundary points should be updated
  146. !
  147. IF( kt .eq. nit000 ) CLOSE( unit = 102 )
  148. IF( nn_timing == 1 ) CALL timing_stop('bdy_dyn3d_zro')
  149. END SUBROUTINE bdy_dyn3d_zro
  150. SUBROUTINE bdy_dyn3d_frs( idx, dta, kt, ib_bdy )
  151. !!----------------------------------------------------------------------
  152. !! *** SUBROUTINE bdy_dyn3d_frs ***
  153. !!
  154. !! ** Purpose : - Apply the Flow Relaxation Scheme for baroclinic velocities
  155. !! at open boundaries.
  156. !!
  157. !! References :- Engedahl H., 1995: Use of the flow relaxation scheme in
  158. !! a three-dimensional baroclinic ocean model with realistic
  159. !! topography. Tellus, 365-382.
  160. !!----------------------------------------------------------------------
  161. INTEGER :: kt
  162. TYPE(OBC_INDEX), INTENT(in) :: idx ! OBC indices
  163. TYPE(OBC_DATA), INTENT(in) :: dta ! OBC external data
  164. INTEGER, INTENT(in) :: ib_bdy ! BDY set index
  165. !!
  166. INTEGER :: jb, jk ! dummy loop indices
  167. INTEGER :: ii, ij, igrd ! local integers
  168. REAL(wp) :: zwgt ! boundary weight
  169. !!----------------------------------------------------------------------
  170. !
  171. IF( nn_timing == 1 ) CALL timing_start('bdy_dyn3d_frs')
  172. !
  173. igrd = 2 ! Relaxation of zonal velocity
  174. DO jb = 1, idx%nblen(igrd)
  175. DO jk = 1, jpkm1
  176. ii = idx%nbi(jb,igrd)
  177. ij = idx%nbj(jb,igrd)
  178. zwgt = idx%nbw(jb,igrd)
  179. ua(ii,ij,jk) = ( ua(ii,ij,jk) + zwgt * ( dta%u3d(jb,jk) - ua(ii,ij,jk) ) ) * umask(ii,ij,jk)
  180. END DO
  181. END DO
  182. !
  183. igrd = 3 ! Relaxation of meridional velocity
  184. DO jb = 1, idx%nblen(igrd)
  185. DO jk = 1, jpkm1
  186. ii = idx%nbi(jb,igrd)
  187. ij = idx%nbj(jb,igrd)
  188. zwgt = idx%nbw(jb,igrd)
  189. va(ii,ij,jk) = ( va(ii,ij,jk) + zwgt * ( dta%v3d(jb,jk) - va(ii,ij,jk) ) ) * vmask(ii,ij,jk)
  190. END DO
  191. END DO
  192. CALL lbc_bdy_lnk( ua, 'U', -1., ib_bdy ) ! Boundary points should be updated
  193. CALL lbc_bdy_lnk( va, 'V', -1., ib_bdy )
  194. !
  195. IF( kt .eq. nit000 ) CLOSE( unit = 102 )
  196. IF( nn_timing == 1 ) CALL timing_stop('bdy_dyn3d_frs')
  197. END SUBROUTINE bdy_dyn3d_frs
  198. SUBROUTINE bdy_dyn3d_orlanski( idx, dta, ib_bdy, ll_npo )
  199. !!----------------------------------------------------------------------
  200. !! *** SUBROUTINE bdy_dyn3d_orlanski ***
  201. !!
  202. !! - Apply Orlanski radiation to baroclinic velocities.
  203. !! - Wrapper routine for bdy_orlanski_3d
  204. !!
  205. !!
  206. !! References: Marchesiello, McWilliams and Shchepetkin, Ocean Modelling vol. 3 (2001)
  207. !!----------------------------------------------------------------------
  208. TYPE(OBC_INDEX), INTENT(in) :: idx ! OBC indices
  209. TYPE(OBC_DATA), INTENT(in) :: dta ! OBC external data
  210. INTEGER, INTENT(in) :: ib_bdy ! BDY set index
  211. LOGICAL, INTENT(in) :: ll_npo ! switch for NPO version
  212. INTEGER :: jb, igrd ! dummy loop indices
  213. !!----------------------------------------------------------------------
  214. IF( nn_timing == 1 ) CALL timing_start('bdy_dyn3d_orlanski')
  215. !
  216. !! Note that at this stage the ub and ua arrays contain the baroclinic velocities.
  217. !
  218. igrd = 2 ! Orlanski bc on u-velocity;
  219. !
  220. CALL bdy_orlanski_3d( idx, igrd, ub, ua, dta%u3d, ll_npo )
  221. igrd = 3 ! Orlanski bc on v-velocity
  222. !
  223. CALL bdy_orlanski_3d( idx, igrd, vb, va, dta%v3d, ll_npo )
  224. !
  225. CALL lbc_bdy_lnk( ua, 'U', -1., ib_bdy ) ! Boundary points should be updated
  226. CALL lbc_bdy_lnk( va, 'V', -1., ib_bdy )
  227. !
  228. IF( nn_timing == 1 ) CALL timing_stop('bdy_dyn3d_orlanski')
  229. !
  230. END SUBROUTINE bdy_dyn3d_orlanski
  231. SUBROUTINE bdy_dyn3d_dmp( kt )
  232. !!----------------------------------------------------------------------
  233. !! *** SUBROUTINE bdy_dyn3d_dmp ***
  234. !!
  235. !! ** Purpose : Apply damping for baroclinic velocities at open boundaries.
  236. !!
  237. !!----------------------------------------------------------------------
  238. INTEGER :: kt
  239. !!
  240. INTEGER :: jb, jk ! dummy loop indices
  241. INTEGER :: ii, ij, igrd ! local integers
  242. REAL(wp) :: zwgt ! boundary weight
  243. INTEGER :: ib_bdy ! loop index
  244. !!----------------------------------------------------------------------
  245. !
  246. IF( nn_timing == 1 ) CALL timing_start('bdy_dyn3d_dmp')
  247. !
  248. !-------------------------------------------------------
  249. DO ib_bdy=1, nb_bdy
  250. IF ( ln_dyn3d_dmp(ib_bdy) .and. cn_dyn3d(ib_bdy) /= 'none' ) THEN
  251. igrd = 2 ! Relaxation of zonal velocity
  252. DO jb = 1, idx_bdy(ib_bdy)%nblen(igrd)
  253. ii = idx_bdy(ib_bdy)%nbi(jb,igrd)
  254. ij = idx_bdy(ib_bdy)%nbj(jb,igrd)
  255. zwgt = idx_bdy(ib_bdy)%nbd(jb,igrd)
  256. DO jk = 1, jpkm1
  257. ua(ii,ij,jk) = ( ua(ii,ij,jk) + zwgt * ( dta_bdy(ib_bdy)%u3d(jb,jk) - &
  258. ub(ii,ij,jk) + ub_b(ii,ij)) ) * umask(ii,ij,jk)
  259. END DO
  260. END DO
  261. !
  262. igrd = 3 ! Relaxation of meridional velocity
  263. DO jb = 1, idx_bdy(ib_bdy)%nblen(igrd)
  264. ii = idx_bdy(ib_bdy)%nbi(jb,igrd)
  265. ij = idx_bdy(ib_bdy)%nbj(jb,igrd)
  266. zwgt = idx_bdy(ib_bdy)%nbd(jb,igrd)
  267. DO jk = 1, jpkm1
  268. va(ii,ij,jk) = ( va(ii,ij,jk) + zwgt * ( dta_bdy(ib_bdy)%v3d(jb,jk) - &
  269. vb(ii,ij,jk) + vb_b(ii,ij)) ) * vmask(ii,ij,jk)
  270. END DO
  271. END DO
  272. ENDIF
  273. ENDDO
  274. !
  275. CALL lbc_lnk( ua, 'U', -1. ) ; CALL lbc_lnk( va, 'V', -1. ) ! Boundary points should be updated
  276. !
  277. IF( nn_timing == 1 ) CALL timing_stop('bdy_dyn3d_dmp')
  278. END SUBROUTINE bdy_dyn3d_dmp
  279. #else
  280. !!----------------------------------------------------------------------
  281. !! Dummy module NO Unstruct Open Boundary Conditions
  282. !!----------------------------------------------------------------------
  283. CONTAINS
  284. SUBROUTINE bdy_dyn3d( kt ) ! Empty routine
  285. WRITE(*,*) 'bdy_dyn3d: You should not have seen this print! error?', kt
  286. END SUBROUTINE bdy_dyn3d
  287. SUBROUTINE bdy_dyn3d_dmp( kt ) ! Empty routine
  288. WRITE(*,*) 'bdy_dyn3d_dmp: You should not have seen this print! error?', kt
  289. END SUBROUTINE bdy_dyn3d_dmp
  290. #endif
  291. !!======================================================================
  292. END MODULE bdydyn3d