divcur.F90 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. MODULE divcur
  2. !!==============================================================================
  3. !! *** MODULE divcur ***
  4. !! Ocean diagnostic variable : horizontal divergence and relative vorticity
  5. !!==============================================================================
  6. !! History : OPA ! 1987-06 (P. Andrich, D. L Hostis) Original code
  7. !! 4.0 ! 1991-11 (G. Madec)
  8. !! 6.0 ! 1993-03 (M. Guyon) symetrical conditions
  9. !! 7.0 ! 1996-01 (G. Madec) s-coordinates
  10. !! 8.0 ! 1997-06 (G. Madec) lateral boundary cond., lbc
  11. !! 8.1 ! 1997-08 (J.M. Molines) Open boundaries
  12. !! 8.2 ! 2000-03 (G. Madec) no slip accurate
  13. !! NEMO 1.0 ! 2002-09 (G. Madec, E. Durand) Free form, F90
  14. !! - ! 2005-01 (J. Chanut) Unstructured open boundaries
  15. !! - ! 2003-08 (G. Madec) merged of cur and div, free form, F90
  16. !! - ! 2005-01 (J. Chanut, A. Sellar) unstructured open boundaries
  17. !! 3.3 ! 2010-09 (D.Storkey and E.O'Dea) bug fixes for BDY module
  18. !! - ! 2010-10 (R. Furner, G. Madec) runoff and cla added directly here
  19. !! 3.6 ! 2014-11 (P. Mathiot) isf added directly here
  20. !!----------------------------------------------------------------------
  21. !!----------------------------------------------------------------------
  22. !! div_cur : Compute the horizontal divergence and relative
  23. !! vorticity fields
  24. !!----------------------------------------------------------------------
  25. USE oce ! ocean dynamics and tracers
  26. USE dom_oce ! ocean space and time domain
  27. USE sbc_oce, ONLY : ln_rnf, nn_isf ! surface boundary condition: ocean
  28. USE sbcrnf ! river runoff
  29. USE sbcisf ! ice shelf
  30. USE cla ! cross land advection (cla_div routine)
  31. USE in_out_manager ! I/O manager
  32. USE lbclnk ! ocean lateral boundary conditions (or mpp link)
  33. USE lib_mpp ! MPP library
  34. USE wrk_nemo ! Memory Allocation
  35. USE timing ! Timing
  36. IMPLICIT NONE
  37. PRIVATE
  38. PUBLIC div_cur ! routine called by step.F90 and istate.F90
  39. !! * Substitutions
  40. # include "domzgr_substitute.h90"
  41. # include "vectopt_loop_substitute.h90"
  42. !!----------------------------------------------------------------------
  43. !! NEMO/OPA 3.3 , NEMO Consortium (2010)
  44. !! $Id: divcur.F90 5516 2015-06-30 12:41:44Z smasson $
  45. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  46. !!----------------------------------------------------------------------
  47. CONTAINS
  48. #if defined key_noslip_accurate
  49. !!----------------------------------------------------------------------
  50. !! 'key_noslip_accurate' 2nd order interior + 4th order at the coast
  51. !!----------------------------------------------------------------------
  52. SUBROUTINE div_cur( kt )
  53. !!----------------------------------------------------------------------
  54. !! *** ROUTINE div_cur ***
  55. !!
  56. !! ** Purpose : compute the horizontal divergence and the relative
  57. !! vorticity at before and now time-step
  58. !!
  59. !! ** Method : I. divergence :
  60. !! - save the divergence computed at the previous time-step
  61. !! (note that the Asselin filter has not been applied on hdivb)
  62. !! - compute the now divergence given by :
  63. !! hdivn = 1/(e1t*e2t*e3t) ( di[e2u*e3u un] + dj[e1v*e3v vn] )
  64. !! correct hdiv with runoff inflow (div_rnf), ice shelf melting (div_isf)
  65. !! and cross land flow (div_cla)
  66. !! II. vorticity :
  67. !! - save the curl computed at the previous time-step
  68. !! rotb = rotn
  69. !! (note that the Asselin time filter has not been applied to rotb)
  70. !! - compute the now curl in tensorial formalism:
  71. !! rotn = 1/(e1f*e2f) ( di[e2v vn] - dj[e1u un] )
  72. !! - Coastal boundary condition: 'key_noslip_accurate' defined,
  73. !! the no-slip boundary condition is computed using Schchepetkin
  74. !! and O'Brien (1996) scheme (i.e. 4th order at the coast).
  75. !! For example, along east coast, the one-sided finite difference
  76. !! approximation used for di[v] is:
  77. !! di[e2v vn] = 1/(e1f*e2f) * ( (e2v vn)(i) + (e2v vn)(i-1) + (e2v vn)(i-2) )
  78. !!
  79. !! ** Action : - update hdivb, hdivn, the before & now hor. divergence
  80. !! - update rotb , rotn , the before & now rel. vorticity
  81. !!----------------------------------------------------------------------
  82. INTEGER, INTENT(in) :: kt ! ocean time-step index
  83. !
  84. INTEGER :: ji, jj, jk, jl ! dummy loop indices
  85. INTEGER :: ii, ij, ijt, iju, ierr ! local integer
  86. REAL(wp) :: zraur, zdep ! local scalar
  87. REAL(wp), POINTER, DIMENSION(:,:) :: zwu ! specific 2D workspace
  88. REAL(wp), POINTER, DIMENSION(:,:) :: zwv ! specific 2D workspace
  89. !!----------------------------------------------------------------------
  90. !
  91. IF( nn_timing == 1 ) CALL timing_start('div_cur')
  92. !
  93. CALL wrk_alloc( jpi , jpj+2, zwu )
  94. CALL wrk_alloc( jpi+2, jpj , zwv )
  95. !
  96. IF( kt == nit000 ) THEN
  97. IF(lwp) WRITE(numout,*)
  98. IF(lwp) WRITE(numout,*) 'div_cur : horizontal velocity divergence and relative vorticity'
  99. IF(lwp) WRITE(numout,*) '~~~~~~~ NOT optimal for auto-tasking case'
  100. ENDIF
  101. ! ! ===============
  102. DO jk = 1, jpkm1 ! Horizontal slab
  103. ! ! ===============
  104. !
  105. hdivb(:,:,jk) = hdivn(:,:,jk) ! time swap of div arrays
  106. rotb (:,:,jk) = rotn (:,:,jk) ! time swap of rot arrays
  107. !
  108. ! ! --------
  109. ! Horizontal divergence ! div
  110. ! ! --------
  111. DO jj = 2, jpjm1
  112. DO ji = fs_2, fs_jpim1 ! vector opt.
  113. hdivn(ji,jj,jk) = &
  114. ( e2u(ji,jj)*fse3u(ji,jj,jk) * un(ji,jj,jk) - e2u(ji-1,jj )*fse3u(ji-1,jj ,jk) * un(ji-1,jj ,jk) &
  115. + e1v(ji,jj)*fse3v(ji,jj,jk) * vn(ji,jj,jk) - e1v(ji ,jj-1)*fse3v(ji ,jj-1,jk) * vn(ji ,jj-1,jk) ) &
  116. / ( e1t(ji,jj) * e2t(ji,jj) * fse3t(ji,jj,jk) )
  117. END DO
  118. END DO
  119. IF( .NOT. AGRIF_Root() ) THEN
  120. IF ((nbondi == 1).OR.(nbondi == 2)) hdivn(nlci-1 , : ,jk) = 0.e0 ! east
  121. IF ((nbondi == -1).OR.(nbondi == 2)) hdivn(2 , : ,jk) = 0.e0 ! west
  122. IF ((nbondj == 1).OR.(nbondj == 2)) hdivn(: ,nlcj-1 ,jk) = 0.e0 ! north
  123. IF ((nbondj == -1).OR.(nbondj == 2)) hdivn(: ,2 ,jk) = 0.e0 ! south
  124. ENDIF
  125. ! ! --------
  126. ! relative vorticity ! rot
  127. ! ! --------
  128. ! contravariant velocity (extended for lateral b.c.)
  129. ! inside the model domain
  130. DO jj = 1, jpj
  131. DO ji = 1, jpi
  132. zwu(ji,jj) = e1u(ji,jj) * un(ji,jj,jk)
  133. zwv(ji,jj) = e2v(ji,jj) * vn(ji,jj,jk)
  134. END DO
  135. END DO
  136. ! East-West boundary conditions
  137. IF( nperio == 1 .OR. nperio == 4 .OR. nperio == 6) THEN
  138. zwv( 0 ,:) = zwv(jpi-2,:)
  139. zwv( -1 ,:) = zwv(jpi-3,:)
  140. zwv(jpi+1,:) = zwv( 3 ,:)
  141. zwv(jpi+2,:) = zwv( 4 ,:)
  142. ELSE
  143. zwv( 0 ,:) = 0.e0
  144. zwv( -1 ,:) = 0.e0
  145. zwv(jpi+1,:) = 0.e0
  146. zwv(jpi+2,:) = 0.e0
  147. ENDIF
  148. ! North-South boundary conditions
  149. IF( nperio == 3 .OR. nperio == 4 ) THEN
  150. ! north fold ( Grid defined with a T-point pivot) ORCA 2 degre
  151. zwu(jpi,jpj+1) = 0.e0
  152. zwu(jpi,jpj+2) = 0.e0
  153. DO ji = 1, jpi-1
  154. iju = jpi - ji + 1
  155. zwu(ji,jpj+1) = - zwu(iju,jpj-3)
  156. zwu(ji,jpj+2) = - zwu(iju,jpj-4)
  157. END DO
  158. ELSEIF( nperio == 5 .OR. nperio == 6 ) THEN
  159. ! north fold ( Grid defined with a F-point pivot) ORCA 0.5 degre\
  160. zwu(jpi,jpj+1) = 0.e0
  161. zwu(jpi,jpj+2) = 0.e0
  162. DO ji = 1, jpi-1
  163. iju = jpi - ji
  164. zwu(ji,jpj ) = - zwu(iju,jpj-1)
  165. zwu(ji,jpj+1) = - zwu(iju,jpj-2)
  166. zwu(ji,jpj+2) = - zwu(iju,jpj-3)
  167. END DO
  168. DO ji = -1, jpi+2
  169. ijt = jpi - ji + 1
  170. zwv(ji,jpj) = - zwv(ijt,jpj-2)
  171. END DO
  172. DO ji = jpi/2+1, jpi+2
  173. ijt = jpi - ji + 1
  174. zwv(ji,jpjm1) = - zwv(ijt,jpjm1)
  175. END DO
  176. ELSE
  177. ! closed
  178. zwu(:,jpj+1) = 0.e0
  179. zwu(:,jpj+2) = 0.e0
  180. ENDIF
  181. ! relative vorticity (vertical component of the velocity curl)
  182. DO jj = 1, jpjm1
  183. DO ji = 1, fs_jpim1 ! vector opt.
  184. rotn(ji,jj,jk) = ( zwv(ji+1,jj ) - zwv(ji,jj) &
  185. & - zwu(ji ,jj+1) + zwu(ji,jj) ) * fmask(ji,jj,jk) / ( e1f(ji,jj)*e2f(ji,jj) )
  186. END DO
  187. END DO
  188. ! second order accurate scheme along straight coast
  189. DO jl = 1, npcoa(1,jk)
  190. ii = nicoa(jl,1,jk)
  191. ij = njcoa(jl,1,jk)
  192. rotn(ii,ij,jk) = 1. / ( e1f(ii,ij) * e2f(ii,ij) ) &
  193. * ( + 4. * zwv(ii+1,ij) - zwv(ii+2,ij) + 0.2 * zwv(ii+3,ij) )
  194. END DO
  195. DO jl = 1, npcoa(2,jk)
  196. ii = nicoa(jl,2,jk)
  197. ij = njcoa(jl,2,jk)
  198. rotn(ii,ij,jk) = 1./(e1f(ii,ij)*e2f(ii,ij)) &
  199. *(-4.*zwv(ii,ij)+zwv(ii-1,ij)-0.2*zwv(ii-2,ij))
  200. END DO
  201. DO jl = 1, npcoa(3,jk)
  202. ii = nicoa(jl,3,jk)
  203. ij = njcoa(jl,3,jk)
  204. rotn(ii,ij,jk) = -1. / ( e1f(ii,ij)*e2f(ii,ij) ) &
  205. * ( +4. * zwu(ii,ij+1) - zwu(ii,ij+2) + 0.2 * zwu(ii,ij+3) )
  206. END DO
  207. DO jl = 1, npcoa(4,jk)
  208. ii = nicoa(jl,4,jk)
  209. ij = njcoa(jl,4,jk)
  210. rotn(ii,ij,jk) = -1. / ( e1f(ii,ij)*e2f(ii,ij) ) &
  211. * ( -4. * zwu(ii,ij) + zwu(ii,ij-1) - 0.2 * zwu(ii,ij-2) )
  212. END DO
  213. ! ! ===============
  214. END DO ! End of slab
  215. ! ! ===============
  216. IF( ln_rnf ) CALL sbc_rnf_div( hdivn ) ! runoffs (update hdivn field)
  217. IF( ln_divisf .AND. (nn_isf /= 0) ) CALL sbc_isf_div( hdivn ) ! ice shelf (update hdivn field)
  218. IF( nn_cla == 1 ) CALL cla_div ( kt ) ! Cross Land Advection (Update Hor. divergence)
  219. ! 4. Lateral boundary conditions on hdivn and rotn
  220. ! ---------------------------------=======---======
  221. CALL lbc_lnk( hdivn, 'T', 1. ) ; CALL lbc_lnk( rotn , 'F', 1. ) ! lateral boundary cond. (no sign change)
  222. !
  223. CALL wrk_dealloc( jpi , jpj+2, zwu )
  224. CALL wrk_dealloc( jpi+2, jpj , zwv )
  225. !
  226. IF( nn_timing == 1 ) CALL timing_stop('div_cur')
  227. !
  228. END SUBROUTINE div_cur
  229. #else
  230. !!----------------------------------------------------------------------
  231. !! Default option 2nd order centered schemes
  232. !!----------------------------------------------------------------------
  233. SUBROUTINE div_cur( kt )
  234. !!----------------------------------------------------------------------
  235. !! *** ROUTINE div_cur ***
  236. !!
  237. !! ** Purpose : compute the horizontal divergence and the relative
  238. !! vorticity at before and now time-step
  239. !!
  240. !! ** Method : - Divergence:
  241. !! - save the divergence computed at the previous time-step
  242. !! (note that the Asselin filter has not been applied on hdivb)
  243. !! - compute the now divergence given by :
  244. !! hdivn = 1/(e1t*e2t*e3t) ( di[e2u*e3u un] + dj[e1v*e3v vn] )
  245. !! correct hdiv with runoff inflow (div_rnf) and cross land flow (div_cla)
  246. !! - Relavtive Vorticity :
  247. !! - save the curl computed at the previous time-step (rotb = rotn)
  248. !! (note that the Asselin time filter has not been applied to rotb)
  249. !! - compute the now curl in tensorial formalism:
  250. !! rotn = 1/(e1f*e2f) ( di[e2v vn] - dj[e1u un] )
  251. !! Note: Coastal boundary condition: lateral friction set through
  252. !! the value of fmask along the coast (see dommsk.F90) and shlat
  253. !! (namelist parameter)
  254. !!
  255. !! ** Action : - update hdivb, hdivn, the before & now hor. divergence
  256. !! - update rotb , rotn , the before & now rel. vorticity
  257. !!----------------------------------------------------------------------
  258. INTEGER, INTENT(in) :: kt ! ocean time-step index
  259. !
  260. INTEGER :: ji, jj, jk ! dummy loop indices
  261. REAL(wp) :: zraur, zdep ! local scalars
  262. !!----------------------------------------------------------------------
  263. !
  264. IF( nn_timing == 1 ) CALL timing_start('div_cur')
  265. !
  266. IF( kt == nit000 ) THEN
  267. IF(lwp) WRITE(numout,*)
  268. IF(lwp) WRITE(numout,*) 'div_cur : horizontal velocity divergence and'
  269. IF(lwp) WRITE(numout,*) '~~~~~~~ relative vorticity'
  270. ENDIF
  271. ! ! ===============
  272. DO jk = 1, jpkm1 ! Horizontal slab
  273. ! ! ===============
  274. !
  275. hdivb(:,:,jk) = hdivn(:,:,jk) ! time swap of div arrays
  276. rotb (:,:,jk) = rotn (:,:,jk) ! time swap of rot arrays
  277. !
  278. ! ! --------
  279. ! Horizontal divergence ! div
  280. ! ! --------
  281. DO jj = 2, jpjm1
  282. DO ji = fs_2, fs_jpim1 ! vector opt.
  283. hdivn(ji,jj,jk) = &
  284. ( e2u(ji,jj)*fse3u(ji,jj,jk) * un(ji,jj,jk) - e2u(ji-1,jj)*fse3u(ji-1,jj,jk) * un(ji-1,jj,jk) &
  285. + e1v(ji,jj)*fse3v(ji,jj,jk) * vn(ji,jj,jk) - e1v(ji,jj-1)*fse3v(ji,jj-1,jk) * vn(ji,jj-1,jk) ) &
  286. / ( e1t(ji,jj) * e2t(ji,jj) * fse3t(ji,jj,jk) )
  287. END DO
  288. END DO
  289. IF( .NOT. AGRIF_Root() ) THEN
  290. IF ((nbondi == 1).OR.(nbondi == 2)) hdivn(nlci-1 , : ,jk) = 0.e0 ! east
  291. IF ((nbondi == -1).OR.(nbondi == 2)) hdivn(2 , : ,jk) = 0.e0 ! west
  292. IF ((nbondj == 1).OR.(nbondj == 2)) hdivn(: ,nlcj-1 ,jk) = 0.e0 ! north
  293. IF ((nbondj == -1).OR.(nbondj == 2)) hdivn(: ,2 ,jk) = 0.e0 ! south
  294. ENDIF
  295. ! ! --------
  296. ! relative vorticity ! rot
  297. ! ! --------
  298. DO jj = 1, jpjm1
  299. DO ji = 1, fs_jpim1 ! vector opt.
  300. rotn(ji,jj,jk) = ( e2v(ji+1,jj ) * vn(ji+1,jj ,jk) - e2v(ji,jj) * vn(ji,jj,jk) &
  301. & - e1u(ji ,jj+1) * un(ji ,jj+1,jk) + e1u(ji,jj) * un(ji,jj,jk) ) &
  302. & * fmask(ji,jj,jk) / ( e1f(ji,jj) * e2f(ji,jj) )
  303. END DO
  304. END DO
  305. ! ! ===============
  306. END DO ! End of slab
  307. ! ! ===============
  308. IF( ln_rnf ) CALL sbc_rnf_div( hdivn ) ! runoffs (update hdivn field)
  309. IF( ln_divisf .AND. (nn_isf .GT. 0) ) CALL sbc_isf_div( hdivn ) ! ice shelf (update hdivn field)
  310. IF( nn_cla == 1 ) CALL cla_div ( kt ) ! Cross Land Advection (update hdivn field)
  311. !
  312. CALL lbc_lnk( hdivn, 'T', 1. ) ; CALL lbc_lnk( rotn , 'F', 1. ) ! lateral boundary cond. (no sign change)
  313. !
  314. IF( nn_timing == 1 ) CALL timing_stop('div_cur')
  315. !
  316. END SUBROUTINE div_cur
  317. #endif
  318. !!======================================================================
  319. END MODULE divcur