traadv_cen2.F90 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. MODULE traadv_cen2
  2. !!======================================================================
  3. !! *** MODULE traadv_cen2 ***
  4. !! Ocean tracers: horizontal & vertical advective trend
  5. !!======================================================================
  6. !! History : OPA ! 2001-08 (G. Madec, E. Durand) v8.2 trahad+trazad=traadv
  7. !! NEMO 1.0 ! 2002-06 (G. Madec) F90: Free form and module
  8. !! - ! 2004-08 (C. Talandier) New trends organization
  9. !! - ! 2005-11 (V. Garnier) Surface pressure gradient organization
  10. !! 2.0 ! 2006-04 (R. Benshila, G. Madec) Step reorganization
  11. !! - ! 2006-07 (G. madec) add ups_orca_set routine
  12. !! 3.2 ! 2009-07 (G. Madec) add avmb, avtb in restart for cen2 advection
  13. !! 3.3 ! 2010-05 (C. Ethe, G. Madec) merge TRC-TRA + switch from velocity to transport
  14. !!----------------------------------------------------------------------
  15. !!----------------------------------------------------------------------
  16. !! tra_adv_cen2 : update the tracer trend with the advection trends using a 2nd order centered scheme
  17. !! ups_orca_set : allow mixed upstream/centered scheme in specific area (set for orca 2 and 4 only)
  18. !!----------------------------------------------------------------------
  19. USE oce, ONLY: tsn ! now ocean temperature and salinity
  20. USE dom_oce ! ocean space and time domain
  21. USE eosbn2 ! equation of state
  22. USE trd_oce ! trends: ocean variables
  23. USE trdtra ! trends manager: tracers
  24. USE closea ! closed sea
  25. USE sbcrnf ! river runoffs
  26. USE in_out_manager ! I/O manager
  27. USE iom ! IOM library
  28. USE diaptr ! poleward transport diagnostics
  29. USE zdf_oce ! ocean vertical physics
  30. USE trc_oce ! share passive tracers/Ocean variables
  31. USE lib_mpp ! MPP library
  32. USE wrk_nemo ! Memory Allocation
  33. USE timing ! Timing
  34. USE phycst
  35. IMPLICIT NONE
  36. PRIVATE
  37. PUBLIC tra_adv_cen2 ! routine called by traadv.F90
  38. REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:) :: upsmsk !: mixed upstream/centered scheme near some straits
  39. ! ! and in closed seas (orca 2 and 4 configurations)
  40. !! * Substitutions
  41. # include "domzgr_substitute.h90"
  42. # include "vectopt_loop_substitute.h90"
  43. !!----------------------------------------------------------------------
  44. !! NEMO/OPA 3.3 , NEMO Consortium (2010)
  45. !! $Id: traadv_cen2.F90 5540 2015-07-02 15:11:23Z jchanut $
  46. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  47. !!----------------------------------------------------------------------
  48. CONTAINS
  49. SUBROUTINE tra_adv_cen2( kt, kit000, cdtype, pun, pvn, pwn, &
  50. & ptb, ptn, pta, kjpt )
  51. !!----------------------------------------------------------------------
  52. !! *** ROUTINE tra_adv_cen2 ***
  53. !!
  54. !! ** Purpose : Compute the now trend due to the advection of tracers
  55. !! and add it to the general trend of passive tracer equations.
  56. !!
  57. !! ** Method : The advection is evaluated by a second order centered
  58. !! scheme using now fields (leap-frog scheme). In specific areas
  59. !! (vicinity of major river mouths, some straits, or where tn is
  60. !! approaching the freezing point) it is mixed with an upstream
  61. !! scheme for stability reasons.
  62. !! Part 0 : compute the upstream / centered flag
  63. !! (3D array, zind, defined at T-point (0<zind<1))
  64. !! Part I : horizontal advection
  65. !! * centered flux:
  66. !! zcenu = e2u*e3u un mi(ptn)
  67. !! zcenv = e1v*e3v vn mj(ptn)
  68. !! * upstream flux:
  69. !! zupsu = e2u*e3u un (ptb(i) or ptb(i-1) ) [un>0 or <0]
  70. !! zupsv = e1v*e3v vn (ptb(j) or ptb(j-1) ) [vn>0 or <0]
  71. !! * mixed upstream / centered horizontal advection scheme
  72. !! zcofi = max(zind(i+1), zind(i))
  73. !! zcofj = max(zind(j+1), zind(j))
  74. !! zwx = zcofi * zupsu + (1-zcofi) * zcenu
  75. !! zwy = zcofj * zupsv + (1-zcofj) * zcenv
  76. !! * horizontal advective trend (divergence of the fluxes)
  77. !! ztra = 1/(e1t*e2t*e3t) { di-1[zwx] + dj-1[zwy] }
  78. !! * Add this trend now to the general trend of tracer (ta,sa):
  79. !! pta = pta + ztra
  80. !! * trend diagnostic (l_trdtra=T or l_trctra=T): the trend is
  81. !! saved for diagnostics. The trends saved is expressed as
  82. !! Uh.gradh(T), i.e. save trend = ztra + ptn divn
  83. !!
  84. !! Part II : vertical advection
  85. !! For temperature (idem for salinity) the advective trend is com-
  86. !! puted as follows :
  87. !! ztra = 1/e3t dk+1[ zwz ]
  88. !! where the vertical advective flux, zwz, is given by :
  89. !! zwz = zcofk * zupst + (1-zcofk) * zcent
  90. !! with
  91. !! zupsv = upstream flux = wn * (ptb(k) or ptb(k-1) ) [wn>0 or <0]
  92. !! zcenu = centered flux = wn * mk(tn)
  93. !! The surface boundary condition is :
  94. !! variable volume (lk_vvl = T) : zero advective flux
  95. !! lin. free-surf (lk_vvl = F) : wn(:,:,1) * ptn(:,:,1)
  96. !! Add this trend now to the general trend of tracer (ta,sa):
  97. !! pta = pta + ztra
  98. !! Trend diagnostic (l_trdtra=T or l_trctra=T): the trend is
  99. !! saved for diagnostics. The trends saved is expressed as :
  100. !! save trend = w.gradz(T) = ztra - ptn divn.
  101. !!
  102. !! ** Action : - update pta with the now advective tracer trends
  103. !! - save trends if needed
  104. !!----------------------------------------------------------------------
  105. INTEGER , INTENT(in ) :: kt ! ocean time-step index
  106. INTEGER , INTENT(in ) :: kit000 ! first time step index
  107. CHARACTER(len=3) , INTENT(in ) :: cdtype ! =TRA or TRC (tracer indicator)
  108. INTEGER , INTENT(in ) :: kjpt ! number of tracers
  109. REAL(wp), DIMENSION(jpi,jpj,jpk ), INTENT(in ) :: pun, pvn, pwn ! 3 ocean velocity components
  110. REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(in ) :: ptb, ptn ! before and now tracer fields
  111. REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(inout) :: pta ! tracer trend
  112. !
  113. INTEGER :: ji, jj, jk, jn, ikt ! dummy loop indices
  114. INTEGER :: ierr ! local integer
  115. REAL(wp) :: zbtr, ztra ! local scalars
  116. REAL(wp) :: zfp_ui, zfp_vj, zfp_w, zcofi ! - -
  117. REAL(wp) :: zfm_ui, zfm_vj, zfm_w, zcofj, zcofk ! - -
  118. REAL(wp) :: zupsut, zcenut, zupst ! - -
  119. REAL(wp) :: zupsvt, zcenvt, zcent, zice ! - -
  120. REAL(wp), POINTER, DIMENSION(:,:) :: zfzp, zpres ! 2D workspace
  121. REAL(wp), POINTER, DIMENSION(:,:,:) :: zwx, zwy ! 3D -
  122. REAL(wp), POINTER, DIMENSION(:,:,:) :: zwz, zind ! - -
  123. !!----------------------------------------------------------------------
  124. !
  125. IF( nn_timing == 1 ) CALL timing_start('tra_adv_cen2')
  126. !
  127. CALL wrk_alloc( jpi, jpj, zpres, zfzp )
  128. CALL wrk_alloc( jpi, jpj, jpk, zwx, zwy, zwz, zind )
  129. !
  130. IF( kt == kit000 ) THEN
  131. IF(lwp) WRITE(numout,*)
  132. IF(lwp) WRITE(numout,*) 'tra_adv_cen2 : 2nd order centered advection scheme on ', cdtype
  133. IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~ '
  134. IF(lwp) WRITE(numout,*)
  135. !
  136. IF( .NOT. ALLOCATED( upsmsk ) ) THEN
  137. ALLOCATE( upsmsk(jpi,jpj), STAT=ierr )
  138. IF( ierr /= 0 ) CALL ctl_stop('STOP', 'tra_adv_cen2: unable to allocate array')
  139. ENDIF
  140. !
  141. upsmsk(:,:) = 0._wp ! not upstream by default
  142. !
  143. IF( cp_cfg == "orca" ) CALL ups_orca_set ! set mixed Upstream/centered scheme near some straits
  144. ! ! and in closed seas (orca2 and orca4 only)
  145. IF( jp_cfg == 2 .AND. .NOT. ln_rstart ) THEN ! Increase the background in the surface layers
  146. avmb(1) = 10. * avmb(1) ; avtb(1) = 10. * avtb(1)
  147. avmb(2) = 10. * avmb(2) ; avtb(2) = 10. * avtb(2)
  148. avmb(3) = 5. * avmb(3) ; avtb(3) = 5. * avtb(3)
  149. avmb(4) = 2.5 * avmb(4) ; avtb(4) = 2.5 * avtb(4)
  150. ENDIF
  151. ENDIF
  152. !
  153. ! Upstream / centered scheme indicator
  154. ! ------------------------------------
  155. !!gm not strickly exact : the freezing point should be computed at each ocean levels...
  156. !!gm not a big deal since cen2 is no more used in global ice-ocean simulations
  157. !!ch changes for ice shelf to retain standard behaviour elsewhere, even if not optimal
  158. DO jj = 1, jpj
  159. DO ji = 1, jpi
  160. ikt = mikt(ji,jj)
  161. IF (ikt > 1 ) THEN
  162. zpres(ji,jj) = grav * rau0 * fsdept(ji,jj,ikt) * 1.e-04
  163. ELSE
  164. zpres(ji,jj) = 0.0
  165. ENDIF
  166. END DO
  167. END DO
  168. CALL eos_fzp( tsn(:,:,1,jp_sal), zfzp(:,:), zpres(:,:) )
  169. DO jk = 1, jpk
  170. DO jj = 1, jpj
  171. DO ji = 1, jpi
  172. ! ! below ice covered area (if tn < "freezing"+0.1 )
  173. IF( tsn(ji,jj,jk,jp_tem) <= zfzp(ji,jj) + 0.1 ) THEN ; zice = 1._wp
  174. ELSE ; zice = 0._wp
  175. ENDIF
  176. zind(ji,jj,jk) = MAX ( &
  177. rnfmsk(ji,jj) * rnfmsk_z(jk), & ! near runoff mouths (& closed sea outflows)
  178. upsmsk(ji,jj) , & ! some of some straits
  179. zice & ! below ice covered area (if tn < "freezing"+0.1 )
  180. & ) * tmask(ji,jj,jk)
  181. END DO
  182. END DO
  183. END DO
  184. DO jn = 1, kjpt
  185. !
  186. ! I. Horizontal advection
  187. ! ====================
  188. !
  189. DO jk = 1, jpkm1
  190. ! ! Second order centered tracer flux at u- and v-points
  191. DO jj = 1, jpjm1
  192. !
  193. DO ji = 1, fs_jpim1 ! vector opt.
  194. ! upstream indicator
  195. zcofi = MAX( zind(ji+1,jj,jk), zind(ji,jj,jk) )
  196. zcofj = MAX( zind(ji,jj+1,jk), zind(ji,jj,jk) )
  197. !
  198. ! upstream scheme
  199. zfp_ui = pun(ji,jj,jk) + ABS( pun(ji,jj,jk) )
  200. zfm_ui = pun(ji,jj,jk) - ABS( pun(ji,jj,jk) )
  201. zfp_vj = pvn(ji,jj,jk) + ABS( pvn(ji,jj,jk) )
  202. zfm_vj = pvn(ji,jj,jk) - ABS( pvn(ji,jj,jk) )
  203. zupsut = zfp_ui * ptb(ji,jj,jk,jn) + zfm_ui * ptb(ji+1,jj ,jk,jn)
  204. zupsvt = zfp_vj * ptb(ji,jj,jk,jn) + zfm_vj * ptb(ji ,jj+1,jk,jn)
  205. ! centered scheme
  206. zcenut = pun(ji,jj,jk) * ( ptn(ji,jj,jk,jn) + ptn(ji+1,jj ,jk,jn) )
  207. zcenvt = pvn(ji,jj,jk) * ( ptn(ji,jj,jk,jn) + ptn(ji ,jj+1,jk,jn) )
  208. ! mixed centered / upstream scheme
  209. zwx(ji,jj,jk) = 0.5 * ( zcofi * zupsut + (1.-zcofi) * zcenut )
  210. zwy(ji,jj,jk) = 0.5 * ( zcofj * zupsvt + (1.-zcofj) * zcenvt )
  211. END DO
  212. END DO
  213. END DO
  214. ! II. Vertical advection
  215. ! ==================
  216. !
  217. ! ! Vertical advective fluxes
  218. zwz(:,:,jpk) = 0.e0 ! Bottom value : flux set to zero
  219. ! ! Surface value :
  220. IF( lk_vvl ) THEN ; zwz(:,:, 1 ) = 0.e0 ! volume variable
  221. ELSE
  222. DO jj = 1, jpj ! vector opt.
  223. DO ji = 1, jpi ! vector opt.
  224. ikt = mikt(ji,jj)
  225. zwz(ji,jj,ikt ) = pwn(ji,jj,ikt) * ptn(ji,jj,ikt,jn) ! linear free surface
  226. zwz(ji,jj,1:ikt-1) = 0.e0
  227. END DO
  228. END DO
  229. ENDIF
  230. !
  231. DO jk = 2, jpk ! Second order centered tracer flux at w-point
  232. DO jj = 2, jpjm1
  233. DO ji = fs_2, fs_jpim1 ! vector opt.
  234. ! upstream indicator
  235. zcofk = MAX( zind(ji,jj,jk-1), zind(ji,jj,jk) )
  236. ! mixed centered / upstream scheme
  237. zfp_w = pwn(ji,jj,jk) + ABS( pwn(ji,jj,jk) )
  238. zfm_w = pwn(ji,jj,jk) - ABS( pwn(ji,jj,jk) )
  239. zupst = zfp_w * ptb(ji,jj,jk,jn) + zfm_w * ptb(ji,jj,jk-1,jn)
  240. ! centered scheme
  241. zcent = pwn(ji,jj,jk) * ( ptn(ji,jj,jk,jn) + ptn(ji,jj,jk-1,jn) )
  242. ! mixed centered / upstream scheme
  243. zwz(ji,jj,jk) = 0.5 * ( zcofk * zupst + (1.-zcofk) * zcent )
  244. END DO
  245. END DO
  246. END DO
  247. ! II. Divergence of advective fluxes
  248. ! ----------------------------------
  249. DO jk = 1, jpkm1
  250. DO jj = 2, jpjm1
  251. DO ji = fs_2, fs_jpim1 ! vector opt.
  252. zbtr = 1. / ( e1t(ji,jj) * e2t(ji,jj) * fse3t(ji,jj,jk) )
  253. ! advective trends
  254. ztra = - zbtr * ( zwx(ji,jj,jk) - zwx(ji-1,jj ,jk ) &
  255. & + zwy(ji,jj,jk) - zwy(ji ,jj-1,jk ) &
  256. & + zwz(ji,jj,jk) - zwz(ji ,jj ,jk+1) )
  257. ! advective trends added to the general tracer trends
  258. pta(ji,jj,jk,jn) = pta(ji,jj,jk,jn) + ztra
  259. END DO
  260. END DO
  261. END DO
  262. ! ! trend diagnostics
  263. IF( ( cdtype == 'TRA' .AND. l_trdtra ) .OR. &
  264. &( cdtype == 'TRC' .AND. l_trdtrc ) ) THEN
  265. CALL trd_tra( kt, cdtype, jn, jptra_xad, zwx, pun, ptn(:,:,:,jn) )
  266. CALL trd_tra( kt, cdtype, jn, jptra_yad, zwy, pvn, ptn(:,:,:,jn) )
  267. CALL trd_tra( kt, cdtype, jn, jptra_zad, zwz, pwn, ptn(:,:,:,jn) )
  268. END IF
  269. ! ! "Poleward" heat and salt transports (contribution of upstream fluxes)
  270. IF( cdtype == 'TRA' .AND. ln_diaptr ) CALL dia_ptr_ohst_components( jn, 'adv', zwy(:,:,:) )
  271. !
  272. END DO
  273. ! --------------------------- required in restart file to ensure restartability)
  274. ! avmb, avtb will be read in zdfini in restart case as they are used in zdftke, kpp etc...
  275. IF( lrst_oce .AND. cdtype == 'TRA' ) THEN
  276. CALL iom_rstput( kt, nitrst, numrow, 'avmb', avmb )
  277. CALL iom_rstput( kt, nitrst, numrow, 'avtb', avtb )
  278. ENDIF
  279. !
  280. CALL wrk_dealloc( jpi, jpj, zpres, zfzp )
  281. CALL wrk_dealloc( jpi, jpj, jpk, zwx, zwy, zwz, zind )
  282. !
  283. IF( nn_timing == 1 ) CALL timing_stop('tra_adv_cen2')
  284. !
  285. END SUBROUTINE tra_adv_cen2
  286. SUBROUTINE ups_orca_set
  287. !!----------------------------------------------------------------------
  288. !! *** ROUTINE ups_orca_set ***
  289. !!
  290. !! ** Purpose : add a portion of upstream scheme in area where the
  291. !! centered scheme generates too strong overshoot
  292. !!
  293. !! ** Method : orca (R4 and R2) confiiguration setting. Set upsmsk
  294. !! array to nozero value in some straith.
  295. !!
  296. !! ** Action : - upsmsk set to 1 at some strait, 0 elsewhere for orca
  297. !!----------------------------------------------------------------------
  298. INTEGER :: ii0, ii1, ij0, ij1 ! temporary integers
  299. !!----------------------------------------------------------------------
  300. !
  301. IF( nn_timing == 1 ) CALL timing_start('ups_orca_set')
  302. !
  303. ! mixed upstream/centered scheme near river mouths
  304. ! ------------------------------------------------
  305. SELECT CASE ( jp_cfg )
  306. ! ! =======================
  307. CASE ( 4 ) ! ORCA_R4 configuration
  308. ! ! =======================
  309. ! ! Gibraltar Strait
  310. ii0 = 70 ; ii1 = 71
  311. ij0 = 52 ; ij1 = 53 ; upsmsk( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 0.50
  312. !
  313. ! ! =======================
  314. CASE ( 2 ) ! ORCA_R2 configuration
  315. ! ! =======================
  316. ! ! Gibraltar Strait
  317. ij0 = 102 ; ij1 = 102
  318. ii0 = 138 ; ii1 = 138 ; upsmsk( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 0.20
  319. ii0 = 139 ; ii1 = 139 ; upsmsk( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 0.40
  320. ii0 = 140 ; ii1 = 140 ; upsmsk( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 0.50
  321. ij0 = 101 ; ij1 = 102
  322. ii0 = 141 ; ii1 = 141 ; upsmsk( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 0.50
  323. ! ! Bab el Mandeb Strait
  324. ij0 = 87 ; ij1 = 88
  325. ii0 = 164 ; ii1 = 164 ; upsmsk( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 0.10
  326. ij0 = 88 ; ij1 = 88
  327. ii0 = 163 ; ii1 = 163 ; upsmsk( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 0.25
  328. ii0 = 162 ; ii1 = 162 ; upsmsk( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 0.40
  329. ii0 = 160 ; ii1 = 161 ; upsmsk( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 0.50
  330. ij0 = 89 ; ij1 = 89
  331. ii0 = 158 ; ii1 = 160 ; upsmsk( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 0.25
  332. ij0 = 90 ; ij1 = 90
  333. ii0 = 160 ; ii1 = 160 ; upsmsk( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 0.25
  334. ! ! Sound Strait
  335. ij0 = 116 ; ij1 = 116
  336. ii0 = 144 ; ii1 = 144 ; upsmsk( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 0.25
  337. ii0 = 145 ; ii1 = 147 ; upsmsk( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 0.50
  338. ii0 = 148 ; ii1 = 148 ; upsmsk( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) ) = 0.25
  339. !
  340. END SELECT
  341. ! mixed upstream/centered scheme over closed seas
  342. ! -----------------------------------------------
  343. CALL clo_ups( upsmsk(:,:) )
  344. !
  345. IF( nn_timing == 1 ) CALL timing_stop('ups_orca_set')
  346. !
  347. END SUBROUTINE ups_orca_set
  348. !!======================================================================
  349. END MODULE traadv_cen2