trabbl.F90 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620
  1. MODULE trabbl
  2. !!==============================================================================
  3. !! *** MODULE trabbl ***
  4. !! Ocean physics : advective and/or diffusive bottom boundary layer scheme
  5. !!==============================================================================
  6. !! History : OPA ! 1996-06 (L. Mortier) Original code
  7. !! 8.0 ! 1997-11 (G. Madec) Optimization
  8. !! NEMO 1.0 ! 2002-08 (G. Madec) free form + modules
  9. !! - ! 2004-01 (A. de Miranda, G. Madec, J.M. Molines ) add advective bbl
  10. !! 3.3 ! 2009-11 (G. Madec) merge trabbl and trabbl_adv + style + optimization
  11. !! - ! 2010-04 (G. Madec) Campin & Goosse advective bbl
  12. !! - ! 2010-06 (C. Ethe, G. Madec) merge TRA-TRC
  13. !! - ! 2010-11 (G. Madec) add mbk. arrays associated to the deepest ocean level
  14. !! - ! 2013-04 (F. Roquet, G. Madec) use of eosbn2 instead of local hard coded alpha and beta
  15. !!----------------------------------------------------------------------
  16. #if defined key_trabbl || defined key_esopa
  17. !!----------------------------------------------------------------------
  18. !! 'key_trabbl' or bottom boundary layer
  19. !!----------------------------------------------------------------------
  20. !! tra_bbl_alloc : allocate trabbl arrays
  21. !! tra_bbl : update the tracer trends due to the bottom boundary layer (advective and/or diffusive)
  22. !! tra_bbl_dif : generic routine to compute bbl diffusive trend
  23. !! tra_bbl_adv : generic routine to compute bbl advective trend
  24. !! bbl : computation of bbl diffu. flux coef. & transport in bottom boundary layer
  25. !! tra_bbl_init : initialization, namelist read, parameters control
  26. !!----------------------------------------------------------------------
  27. USE oce ! ocean dynamics and active tracers
  28. USE dom_oce ! ocean space and time domain
  29. USE phycst ! physical constant
  30. USE eosbn2 ! equation of state
  31. USE trd_oce ! trends: ocean variables
  32. USE trdtra ! trends: active tracers
  33. !
  34. USE iom ! IOM library
  35. USE in_out_manager ! I/O manager
  36. USE lbclnk ! ocean lateral boundary conditions
  37. USE prtctl ! Print control
  38. USE wrk_nemo ! Memory Allocation
  39. USE timing ! Timing
  40. USE lib_fortran ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined)
  41. IMPLICIT NONE
  42. PRIVATE
  43. PUBLIC tra_bbl ! routine called by step.F90
  44. PUBLIC tra_bbl_init ! routine called by opa.F90
  45. PUBLIC tra_bbl_dif ! routine called by trcbbl.F90
  46. PUBLIC tra_bbl_adv ! - - - -
  47. PUBLIC bbl ! routine called by trcbbl.F90 and dtadyn.F90
  48. LOGICAL, PUBLIC, PARAMETER :: lk_trabbl = .TRUE. !: bottom boundary layer flag
  49. ! !!* Namelist nambbl *
  50. INTEGER , PUBLIC :: nn_bbl_ldf !: =1 : diffusive bbl or not (=0)
  51. INTEGER , PUBLIC :: nn_bbl_adv !: =1/2 : advective bbl or not (=0)
  52. ! ! =1 : advective bbl using the bottom ocean velocity
  53. ! ! =2 : - - using utr_bbl proportional to grad(rho)
  54. REAL(wp), PUBLIC :: rn_ahtbbl !: along slope bbl diffusive coefficient [m2/s]
  55. REAL(wp), PUBLIC :: rn_gambbl !: lateral coeff. for bottom boundary layer scheme [s]
  56. LOGICAL , PUBLIC :: l_bbl !: flag to compute bbl diffu. flux coef and transport
  57. REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:), PUBLIC :: utr_bbl , vtr_bbl ! u- (v-) transport in the bottom boundary layer
  58. REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:), PUBLIC :: ahu_bbl , ahv_bbl ! masked diffusive bbl coeff. at u & v-pts
  59. INTEGER , ALLOCATABLE, SAVE, DIMENSION(:,:), PUBLIC :: mbku_d , mbkv_d ! vertical index of the "lower" bottom ocean U/V-level (PUBLIC for TAM)
  60. INTEGER , ALLOCATABLE, SAVE, DIMENSION(:,:), PUBLIC :: mgrhu , mgrhv ! = +/-1, sign of grad(H) in u-(v-)direction (PUBLIC for TAM)
  61. REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:) :: ahu_bbl_0, ahv_bbl_0 ! diffusive bbl flux coefficients at u and v-points
  62. REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:), PUBLIC :: e3u_bbl_0, e3v_bbl_0 ! thichness of the bbl (e3) at u and v-points (PUBLIC for TAM)
  63. !! * Substitutions
  64. # include "domzgr_substitute.h90"
  65. # include "vectopt_loop_substitute.h90"
  66. !!----------------------------------------------------------------------
  67. !! NEMO/OPA 3.3 , NEMO Consortium (2010)
  68. !! $Id: trabbl.F90 4990 2014-12-15 16:42:49Z timgraham $
  69. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  70. !!----------------------------------------------------------------------
  71. CONTAINS
  72. INTEGER FUNCTION tra_bbl_alloc()
  73. !!----------------------------------------------------------------------
  74. !! *** FUNCTION tra_bbl_alloc ***
  75. !!----------------------------------------------------------------------
  76. ALLOCATE( utr_bbl (jpi,jpj) , ahu_bbl (jpi,jpj) , mbku_d (jpi,jpj) , mgrhu(jpi,jpj) , &
  77. & vtr_bbl (jpi,jpj) , ahv_bbl (jpi,jpj) , mbkv_d (jpi,jpj) , mgrhv(jpi,jpj) , &
  78. & ahu_bbl_0(jpi,jpj) , ahv_bbl_0(jpi,jpj) , &
  79. & e3u_bbl_0(jpi,jpj) , e3v_bbl_0(jpi,jpj) , STAT=tra_bbl_alloc )
  80. !
  81. IF( lk_mpp ) CALL mpp_sum ( tra_bbl_alloc )
  82. IF( tra_bbl_alloc > 0 ) CALL ctl_warn('tra_bbl_alloc: allocation of arrays failed.')
  83. END FUNCTION tra_bbl_alloc
  84. SUBROUTINE tra_bbl( kt )
  85. !!----------------------------------------------------------------------
  86. !! *** ROUTINE bbl ***
  87. !!
  88. !! ** Purpose : Compute the before tracer (t & s) trend associated
  89. !! with the bottom boundary layer and add it to the general
  90. !! trend of tracer equations.
  91. !!
  92. !! ** Method : Depending on namtra_bbl namelist parameters the bbl
  93. !! diffusive and/or advective contribution to the tracer trend
  94. !! is added to the general tracer trend
  95. !!----------------------------------------------------------------------
  96. INTEGER, INTENT( in ) :: kt ! ocean time-step
  97. !
  98. REAL(wp), POINTER, DIMENSION(:,:,:) :: ztrdt, ztrds
  99. !!----------------------------------------------------------------------
  100. !
  101. IF( nn_timing == 1 ) CALL timing_start( 'tra_bbl')
  102. !
  103. IF( l_trdtra ) THEN !* Save ta and sa trends
  104. CALL wrk_alloc( jpi, jpj, jpk, ztrdt, ztrds )
  105. ztrdt(:,:,:) = tsa(:,:,:,jp_tem)
  106. ztrds(:,:,:) = tsa(:,:,:,jp_sal)
  107. ENDIF
  108. IF( l_bbl ) CALL bbl( kt, nit000, 'TRA' ) !* bbl coef. and transport (only if not already done in trcbbl)
  109. IF( nn_bbl_ldf == 1 ) THEN !* Diffusive bbl
  110. !
  111. CALL tra_bbl_dif( tsb, tsa, jpts )
  112. IF( ln_ctl ) &
  113. CALL prt_ctl( tab3d_1=tsa(:,:,:,jp_tem), clinfo1=' bbl_ldf - Ta: ', mask1=tmask, &
  114. & tab3d_2=tsa(:,:,:,jp_sal), clinfo2= ' Sa: ', mask2=tmask, clinfo3='tra' )
  115. ! lateral boundary conditions ; just need for outputs
  116. CALL lbc_lnk( ahu_bbl, 'U', 1. ) ; CALL lbc_lnk( ahv_bbl, 'V', 1. )
  117. CALL iom_put( "ahu_bbl", ahu_bbl ) ! bbl diffusive flux i-coef
  118. CALL iom_put( "ahv_bbl", ahv_bbl ) ! bbl diffusive flux j-coef
  119. !
  120. END IF
  121. IF( nn_bbl_adv /= 0 ) THEN !* Advective bbl
  122. !
  123. CALL tra_bbl_adv( tsb, tsa, jpts )
  124. IF(ln_ctl) &
  125. CALL prt_ctl( tab3d_1=tsa(:,:,:,jp_tem), clinfo1=' bbl_adv - Ta: ', mask1=tmask, &
  126. & tab3d_2=tsa(:,:,:,jp_sal), clinfo2= ' Sa: ', mask2=tmask, clinfo3='tra' )
  127. ! lateral boundary conditions ; just need for outputs
  128. CALL lbc_lnk( utr_bbl, 'U', 1. ) ; CALL lbc_lnk( vtr_bbl, 'V', 1. )
  129. CALL iom_put( "uoce_bbl", utr_bbl ) ! bbl i-transport
  130. CALL iom_put( "voce_bbl", vtr_bbl ) ! bbl j-transport
  131. !
  132. END IF
  133. IF( l_trdtra ) THEN ! save the horizontal diffusive trends for further diagnostics
  134. ztrdt(:,:,:) = tsa(:,:,:,jp_tem) - ztrdt(:,:,:)
  135. ztrds(:,:,:) = tsa(:,:,:,jp_sal) - ztrds(:,:,:)
  136. CALL trd_tra( kt, 'TRA', jp_tem, jptra_bbl, ztrdt )
  137. CALL trd_tra( kt, 'TRA', jp_sal, jptra_bbl, ztrds )
  138. CALL wrk_dealloc( jpi, jpj, jpk, ztrdt, ztrds )
  139. ENDIF
  140. !
  141. IF( nn_timing == 1 ) CALL timing_stop( 'tra_bbl')
  142. !
  143. END SUBROUTINE tra_bbl
  144. SUBROUTINE tra_bbl_dif( ptb, pta, kjpt )
  145. !!----------------------------------------------------------------------
  146. !! *** ROUTINE tra_bbl_dif ***
  147. !!
  148. !! ** Purpose : Computes the bottom boundary horizontal and vertical
  149. !! advection terms.
  150. !!
  151. !! ** Method : * diffusive bbl only (nn_bbl_ldf=1) :
  152. !! When the product grad( rho) * grad(h) < 0 (where grad is an
  153. !! along bottom slope gradient) an additional lateral 2nd order
  154. !! diffusion along the bottom slope is added to the general
  155. !! tracer trend, otherwise the additional trend is set to 0.
  156. !! A typical value of ahbt is 2000 m2/s (equivalent to
  157. !! a downslope velocity of 20 cm/s if the condition for slope
  158. !! convection is satified)
  159. !!
  160. !! ** Action : pta increased by the bbl diffusive trend
  161. !!
  162. !! References : Beckmann, A., and R. Doscher, 1997, J. Phys.Oceanogr., 581-591.
  163. !! Campin, J.-M., and H. Goosse, 1999, Tellus, 412-430.
  164. !!----------------------------------------------------------------------
  165. INTEGER , INTENT(in ) :: kjpt ! number of tracers
  166. REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(in ) :: ptb ! before and now tracer fields
  167. REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(inout) :: pta ! tracer trend
  168. !
  169. INTEGER :: ji, jj, jn ! dummy loop indices
  170. INTEGER :: ik ! local integers
  171. REAL(wp) :: zbtr ! local scalars
  172. REAL(wp), POINTER, DIMENSION(:,:) :: zptb
  173. !!----------------------------------------------------------------------
  174. !
  175. IF( nn_timing == 1 ) CALL timing_start('tra_bbl_dif')
  176. !
  177. CALL wrk_alloc( jpi, jpj, zptb )
  178. !
  179. DO jn = 1, kjpt ! tracer loop
  180. ! ! ===========
  181. DO jj = 1, jpj
  182. DO ji = 1, jpi
  183. ik = mbkt(ji,jj) ! bottom T-level index
  184. zptb(ji,jj) = ptb(ji,jj,ik,jn) ! bottom before T and S
  185. END DO
  186. END DO
  187. !
  188. DO jj = 2, jpjm1 ! Compute the trend
  189. DO ji = 2, jpim1
  190. ik = mbkt(ji,jj) ! bottom T-level index
  191. zbtr = r1_e12t(ji,jj) / fse3t(ji,jj,ik)
  192. pta(ji,jj,ik,jn) = pta(ji,jj,ik,jn) &
  193. & + ( ahu_bbl(ji ,jj ) * ( zptb(ji+1,jj ) - zptb(ji ,jj ) ) &
  194. & - ahu_bbl(ji-1,jj ) * ( zptb(ji ,jj ) - zptb(ji-1,jj ) ) &
  195. & + ahv_bbl(ji ,jj ) * ( zptb(ji ,jj+1) - zptb(ji ,jj ) ) &
  196. & - ahv_bbl(ji ,jj-1) * ( zptb(ji ,jj ) - zptb(ji ,jj-1) ) ) * zbtr
  197. END DO
  198. END DO
  199. ! ! ===========
  200. END DO ! end tracer
  201. ! ! ===========
  202. CALL wrk_dealloc( jpi, jpj, zptb )
  203. !
  204. IF( nn_timing == 1 ) CALL timing_stop('tra_bbl_dif')
  205. !
  206. END SUBROUTINE tra_bbl_dif
  207. SUBROUTINE tra_bbl_adv( ptb, pta, kjpt )
  208. !!----------------------------------------------------------------------
  209. !! *** ROUTINE trc_bbl ***
  210. !!
  211. !! ** Purpose : Compute the before passive tracer trend associated
  212. !! with the bottom boundary layer and add it to the general trend
  213. !! of tracer equations.
  214. !! ** Method : advective bbl (nn_bbl_adv = 1 or 2) :
  215. !! nn_bbl_adv = 1 use of the ocean near bottom velocity as bbl velocity
  216. !! nn_bbl_adv = 2 follow Campin and Goosse (1999) implentation i.e.
  217. !! transport proportional to the along-slope density gradient
  218. !!
  219. !! References : Beckmann, A., and R. Doscher, 1997, J. Phys.Oceanogr., 581-591.
  220. !! Campin, J.-M., and H. Goosse, 1999, Tellus, 412-430.
  221. !!----------------------------------------------------------------------
  222. INTEGER , INTENT(in ) :: kjpt ! number of tracers
  223. REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(in ) :: ptb ! before and now tracer fields
  224. REAL(wp), DIMENSION(jpi,jpj,jpk,kjpt), INTENT(inout) :: pta ! tracer trend
  225. !
  226. INTEGER :: ji, jj, jk, jn ! dummy loop indices
  227. INTEGER :: iis , iid , ijs , ijd ! local integers
  228. INTEGER :: ikus, ikud, ikvs, ikvd ! - -
  229. REAL(wp) :: zbtr, ztra ! local scalars
  230. REAL(wp) :: zu_bbl, zv_bbl ! - -
  231. !!----------------------------------------------------------------------
  232. !
  233. IF( nn_timing == 1 ) CALL timing_start( 'tra_bbl_adv')
  234. ! ! ===========
  235. DO jn = 1, kjpt ! tracer loop
  236. ! ! ===========
  237. DO jj = 1, jpjm1
  238. DO ji = 1, jpim1 ! CAUTION start from i=1 to update i=2 when cyclic east-west
  239. IF( utr_bbl(ji,jj) /= 0.e0 ) THEN ! non-zero i-direction bbl advection
  240. ! down-slope i/k-indices (deep) & up-slope i/k indices (shelf)
  241. iid = ji + MAX( 0, mgrhu(ji,jj) ) ; iis = ji + 1 - MAX( 0, mgrhu(ji,jj) )
  242. ikud = mbku_d(ji,jj) ; ikus = mbku(ji,jj)
  243. zu_bbl = ABS( utr_bbl(ji,jj) )
  244. !
  245. ! ! up -slope T-point (shelf bottom point)
  246. zbtr = r1_e12t(iis,jj) / fse3t(iis,jj,ikus)
  247. ztra = zu_bbl * ( ptb(iid,jj,ikus,jn) - ptb(iis,jj,ikus,jn) ) * zbtr
  248. pta(iis,jj,ikus,jn) = pta(iis,jj,ikus,jn) + ztra
  249. !
  250. DO jk = ikus, ikud-1 ! down-slope upper to down T-point (deep column)
  251. zbtr = r1_e12t(iid,jj) / fse3t(iid,jj,jk)
  252. ztra = zu_bbl * ( ptb(iid,jj,jk+1,jn) - ptb(iid,jj,jk,jn) ) * zbtr
  253. pta(iid,jj,jk,jn) = pta(iid,jj,jk,jn) + ztra
  254. END DO
  255. !
  256. zbtr = r1_e12t(iid,jj) / fse3t(iid,jj,ikud)
  257. ztra = zu_bbl * ( ptb(iis,jj,ikus,jn) - ptb(iid,jj,ikud,jn) ) * zbtr
  258. pta(iid,jj,ikud,jn) = pta(iid,jj,ikud,jn) + ztra
  259. ENDIF
  260. !
  261. IF( vtr_bbl(ji,jj) /= 0.e0 ) THEN ! non-zero j-direction bbl advection
  262. ! down-slope j/k-indices (deep) & up-slope j/k indices (shelf)
  263. ijd = jj + MAX( 0, mgrhv(ji,jj) ) ; ijs = jj + 1 - MAX( 0, mgrhv(ji,jj) )
  264. ikvd = mbkv_d(ji,jj) ; ikvs = mbkv(ji,jj)
  265. zv_bbl = ABS( vtr_bbl(ji,jj) )
  266. !
  267. ! up -slope T-point (shelf bottom point)
  268. zbtr = r1_e12t(ji,ijs) / fse3t(ji,ijs,ikvs)
  269. ztra = zv_bbl * ( ptb(ji,ijd,ikvs,jn) - ptb(ji,ijs,ikvs,jn) ) * zbtr
  270. pta(ji,ijs,ikvs,jn) = pta(ji,ijs,ikvs,jn) + ztra
  271. !
  272. DO jk = ikvs, ikvd-1 ! down-slope upper to down T-point (deep column)
  273. zbtr = r1_e12t(ji,ijd) / fse3t(ji,ijd,jk)
  274. ztra = zv_bbl * ( ptb(ji,ijd,jk+1,jn) - ptb(ji,ijd,jk,jn) ) * zbtr
  275. pta(ji,ijd,jk,jn) = pta(ji,ijd,jk,jn) + ztra
  276. END DO
  277. ! ! down-slope T-point (deep bottom point)
  278. zbtr = r1_e12t(ji,ijd) / fse3t(ji,ijd,ikvd)
  279. ztra = zv_bbl * ( ptb(ji,ijs,ikvs,jn) - ptb(ji,ijd,ikvd,jn) ) * zbtr
  280. pta(ji,ijd,ikvd,jn) = pta(ji,ijd,ikvd,jn) + ztra
  281. ENDIF
  282. END DO
  283. !
  284. END DO
  285. ! ! ===========
  286. END DO ! end tracer
  287. ! ! ===========
  288. !
  289. IF( nn_timing == 1 ) CALL timing_stop( 'tra_bbl_adv')
  290. !
  291. END SUBROUTINE tra_bbl_adv
  292. SUBROUTINE bbl( kt, kit000, cdtype )
  293. !!----------------------------------------------------------------------
  294. !! *** ROUTINE bbl ***
  295. !!
  296. !! ** Purpose : Computes the bottom boundary horizontal and vertical
  297. !! advection terms.
  298. !!
  299. !! ** Method : * diffusive bbl (nn_bbl_ldf=1) :
  300. !! When the product grad( rho) * grad(h) < 0 (where grad is an
  301. !! along bottom slope gradient) an additional lateral 2nd order
  302. !! diffusion along the bottom slope is added to the general
  303. !! tracer trend, otherwise the additional trend is set to 0.
  304. !! A typical value of ahbt is 2000 m2/s (equivalent to
  305. !! a downslope velocity of 20 cm/s if the condition for slope
  306. !! convection is satified)
  307. !! * advective bbl (nn_bbl_adv=1 or 2) :
  308. !! nn_bbl_adv = 1 use of the ocean velocity as bbl velocity
  309. !! nn_bbl_adv = 2 follow Campin and Goosse (1999) implentation
  310. !! i.e. transport proportional to the along-slope density gradient
  311. !!
  312. !! NB: the along slope density gradient is evaluated using the
  313. !! local density (i.e. referenced at a common local depth).
  314. !!
  315. !! References : Beckmann, A., and R. Doscher, 1997, J. Phys.Oceanogr., 581-591.
  316. !! Campin, J.-M., and H. Goosse, 1999, Tellus, 412-430.
  317. !!----------------------------------------------------------------------
  318. INTEGER , INTENT(in ) :: kt ! ocean time-step index
  319. INTEGER , INTENT(in ) :: kit000 ! first time step index
  320. CHARACTER(len=3), INTENT(in ) :: cdtype ! =TRA or TRC (tracer indicator)
  321. !!
  322. INTEGER :: ji, jj ! dummy loop indices
  323. INTEGER :: ik ! local integers
  324. INTEGER :: iis, iid, ikus, ikud ! - -
  325. INTEGER :: ijs, ijd, ikvs, ikvd ! - -
  326. REAL(wp) :: za, zb, zgdrho ! local scalars
  327. REAL(wp) :: zsign, zsigna, zgbbl ! - -
  328. REAL(wp), DIMENSION(jpi,jpj,jpts) :: zts, zab ! 3D workspace
  329. REAL(wp), DIMENSION(jpi,jpj) :: zub, zvb, zdep ! 2D workspace
  330. !!----------------------------------------------------------------------
  331. !
  332. IF( nn_timing == 1 ) CALL timing_start( 'bbl')
  333. !
  334. IF( kt == kit000 ) THEN
  335. IF(lwp) WRITE(numout,*)
  336. IF(lwp) WRITE(numout,*) 'trabbl:bbl : Compute bbl velocities and diffusive coefficients in ', cdtype
  337. IF(lwp) WRITE(numout,*) '~~~~~~~~~~'
  338. ENDIF
  339. ! !* bottom variables (T, S, alpha, beta, depth, velocity)
  340. DO jj = 1, jpj
  341. DO ji = 1, jpi
  342. ik = mbkt(ji,jj) ! bottom T-level index
  343. zts (ji,jj,jp_tem) = tsb(ji,jj,ik,jp_tem) ! bottom before T and S
  344. zts (ji,jj,jp_sal) = tsb(ji,jj,ik,jp_sal)
  345. !
  346. zdep(ji,jj) = fsdept(ji,jj,ik) ! bottom T-level reference depth
  347. zub (ji,jj) = un(ji,jj,mbku(ji,jj)) ! bottom velocity
  348. zvb (ji,jj) = vn(ji,jj,mbkv(ji,jj))
  349. END DO
  350. END DO
  351. !
  352. CALL eos_rab( zts, zdep, zab )
  353. !
  354. ! !-------------------!
  355. IF( nn_bbl_ldf == 1 ) THEN ! diffusive bbl !
  356. ! !-------------------!
  357. DO jj = 1, jpjm1 ! (criteria for non zero flux: grad(rho).grad(h) < 0 )
  358. DO ji = 1, fs_jpim1 ! vector opt.
  359. ! ! i-direction
  360. za = zab(ji+1,jj,jp_tem) + zab(ji,jj,jp_tem) ! 2*(alpha,beta) at u-point
  361. zb = zab(ji+1,jj,jp_sal) + zab(ji,jj,jp_sal)
  362. ! ! 2*masked bottom density gradient
  363. zgdrho = ( za * ( zts(ji+1,jj,jp_tem) - zts(ji,jj,jp_tem) ) &
  364. & - zb * ( zts(ji+1,jj,jp_sal) - zts(ji,jj,jp_sal) ) ) * umask(ji,jj,1)
  365. !
  366. zsign = SIGN( 0.5, -zgdrho * REAL( mgrhu(ji,jj) ) ) ! sign of ( i-gradient * i-slope )
  367. ahu_bbl(ji,jj) = ( 0.5 - zsign ) * ahu_bbl_0(ji,jj) ! masked diffusive flux coeff.
  368. !
  369. ! ! j-direction
  370. za = zab(ji,jj+1,jp_tem) + zab(ji,jj,jp_tem) ! 2*(alpha,beta) at v-point
  371. zb = zab(ji,jj+1,jp_sal) + zab(ji,jj,jp_sal)
  372. ! ! 2*masked bottom density gradient
  373. zgdrho = ( za * ( zts(ji,jj+1,jp_tem) - zts(ji,jj,jp_tem) ) &
  374. & - zb * ( zts(ji,jj+1,jp_sal) - zts(ji,jj,jp_sal) ) ) * vmask(ji,jj,1)
  375. !
  376. zsign = SIGN( 0.5, -zgdrho * REAL( mgrhv(ji,jj) ) ) ! sign of ( j-gradient * j-slope )
  377. ahv_bbl(ji,jj) = ( 0.5 - zsign ) * ahv_bbl_0(ji,jj)
  378. END DO
  379. END DO
  380. !
  381. ENDIF
  382. ! !-------------------!
  383. IF( nn_bbl_adv /= 0 ) THEN ! advective bbl !
  384. ! !-------------------!
  385. SELECT CASE ( nn_bbl_adv ) !* bbl transport type
  386. !
  387. CASE( 1 ) != use of upper velocity
  388. DO jj = 1, jpjm1 ! criteria: grad(rho).grad(h)<0 and grad(rho).grad(h)<0
  389. DO ji = 1, fs_jpim1 ! vector opt.
  390. ! ! i-direction
  391. za = zab(ji+1,jj,jp_tem) + zab(ji,jj,jp_tem) ! 2*(alpha,beta) at u-point
  392. zb = zab(ji+1,jj,jp_sal) + zab(ji,jj,jp_sal)
  393. ! ! 2*masked bottom density gradient
  394. zgdrho = ( za * ( zts(ji+1,jj,jp_tem) - zts(ji,jj,jp_tem) ) &
  395. - zb * ( zts(ji+1,jj,jp_sal) - zts(ji,jj,jp_sal) ) ) * umask(ji,jj,1)
  396. !
  397. zsign = SIGN( 0.5, - zgdrho * REAL( mgrhu(ji,jj) ) ) ! sign of i-gradient * i-slope
  398. zsigna= SIGN( 0.5, zub(ji,jj) * REAL( mgrhu(ji,jj) ) ) ! sign of u * i-slope
  399. !
  400. ! ! bbl velocity
  401. utr_bbl(ji,jj) = ( 0.5 + zsigna ) * ( 0.5 - zsign ) * e2u(ji,jj) * e3u_bbl_0(ji,jj) * zub(ji,jj)
  402. !
  403. ! ! j-direction
  404. za = zab(ji,jj+1,jp_tem) + zab(ji,jj,jp_tem) ! 2*(alpha,beta) at v-point
  405. zb = zab(ji,jj+1,jp_sal) + zab(ji,jj,jp_sal)
  406. ! ! 2*masked bottom density gradient
  407. zgdrho = ( za * ( zts(ji,jj+1,jp_tem) - zts(ji,jj,jp_tem) ) &
  408. & - zb * ( zts(ji,jj+1,jp_sal) - zts(ji,jj,jp_sal) ) ) * vmask(ji,jj,1)
  409. zsign = SIGN( 0.5, - zgdrho * REAL( mgrhv(ji,jj) ) ) ! sign of j-gradient * j-slope
  410. zsigna= SIGN( 0.5, zvb(ji,jj) * REAL( mgrhv(ji,jj) ) ) ! sign of u * i-slope
  411. !
  412. ! ! bbl transport
  413. vtr_bbl(ji,jj) = ( 0.5 + zsigna ) * ( 0.5 - zsign ) * e1v(ji,jj) * e3v_bbl_0(ji,jj) * zvb(ji,jj)
  414. END DO
  415. END DO
  416. !
  417. CASE( 2 ) != bbl velocity = F( delta rho )
  418. zgbbl = grav * rn_gambbl
  419. DO jj = 1, jpjm1 ! criteria: rho_up > rho_down
  420. DO ji = 1, fs_jpim1 ! vector opt.
  421. ! ! i-direction
  422. ! down-slope T-point i/k-index (deep) & up-slope T-point i/k-index (shelf)
  423. iid = ji + MAX( 0, mgrhu(ji,jj) )
  424. iis = ji + 1 - MAX( 0, mgrhu(ji,jj) )
  425. !
  426. ikud = mbku_d(ji,jj)
  427. ikus = mbku(ji,jj)
  428. !
  429. za = zab(ji+1,jj,jp_tem) + zab(ji,jj,jp_tem) ! 2*(alpha,beta) at u-point
  430. zb = zab(ji+1,jj,jp_sal) + zab(ji,jj,jp_sal)
  431. ! ! masked bottom density gradient
  432. zgdrho = 0.5 * ( za * ( zts(iid,jj,jp_tem) - zts(iis,jj,jp_tem) ) &
  433. & - zb * ( zts(iid,jj,jp_sal) - zts(iis,jj,jp_sal) ) ) * umask(ji,jj,1)
  434. zgdrho = MAX( 0.e0, zgdrho ) ! only if shelf is denser than deep
  435. !
  436. ! ! bbl transport (down-slope direction)
  437. utr_bbl(ji,jj) = e2u(ji,jj) * e3u_bbl_0(ji,jj) * zgbbl * zgdrho * REAL( mgrhu(ji,jj) )
  438. !
  439. ! ! j-direction
  440. ! down-slope T-point j/k-index (deep) & of the up -slope T-point j/k-index (shelf)
  441. ijd = jj + MAX( 0, mgrhv(ji,jj) )
  442. ijs = jj + 1 - MAX( 0, mgrhv(ji,jj) )
  443. !
  444. ikvd = mbkv_d(ji,jj)
  445. ikvs = mbkv(ji,jj)
  446. !
  447. za = zab(ji,jj+1,jp_tem) + zab(ji,jj,jp_tem) ! 2*(alpha,beta) at v-point
  448. zb = zab(ji,jj+1,jp_sal) + zab(ji,jj,jp_sal)
  449. ! ! masked bottom density gradient
  450. zgdrho = 0.5 * ( za * ( zts(ji,ijd,jp_tem) - zts(ji,ijs,jp_tem) ) &
  451. & - zb * ( zts(ji,ijd,jp_sal) - zts(ji,ijs,jp_sal) ) ) * vmask(ji,jj,1)
  452. zgdrho = MAX( 0.e0, zgdrho ) ! only if shelf is denser than deep
  453. !
  454. ! ! bbl transport (down-slope direction)
  455. vtr_bbl(ji,jj) = e1v(ji,jj) * e3v_bbl_0(ji,jj) * zgbbl * zgdrho * REAL( mgrhv(ji,jj) )
  456. END DO
  457. END DO
  458. END SELECT
  459. !
  460. ENDIF
  461. !
  462. IF( nn_timing == 1 ) CALL timing_stop( 'bbl')
  463. !
  464. END SUBROUTINE bbl
  465. SUBROUTINE tra_bbl_init
  466. !!----------------------------------------------------------------------
  467. !! *** ROUTINE tra_bbl_init ***
  468. !!
  469. !! ** Purpose : Initialization for the bottom boundary layer scheme.
  470. !!
  471. !! ** Method : Read the nambbl namelist and check the parameters
  472. !! called by nemo_init at the first timestep (kit000)
  473. !!----------------------------------------------------------------------
  474. INTEGER :: ji, jj ! dummy loop indices
  475. INTEGER :: ii0, ii1, ij0, ij1 ! local integer
  476. INTEGER :: ios ! - -
  477. REAL(wp), POINTER, DIMENSION(:,:) :: zmbk
  478. !!
  479. NAMELIST/nambbl/ nn_bbl_ldf, nn_bbl_adv, rn_ahtbbl, rn_gambbl
  480. !!----------------------------------------------------------------------
  481. !
  482. IF( nn_timing == 1 ) CALL timing_start( 'tra_bbl_init')
  483. !
  484. CALL wrk_alloc( jpi, jpj, zmbk )
  485. !
  486. REWIND( numnam_ref ) ! Namelist nambbl in reference namelist : Bottom boundary layer scheme
  487. READ ( numnam_ref, nambbl, IOSTAT = ios, ERR = 901)
  488. 901 IF( ios /= 0 ) CALL ctl_nam ( ios , 'nambbl in reference namelist', lwp )
  489. REWIND( numnam_cfg ) ! Namelist nambbl in configuration namelist : Bottom boundary layer scheme
  490. READ ( numnam_cfg, nambbl, IOSTAT = ios, ERR = 902 )
  491. 902 IF( ios /= 0 ) CALL ctl_nam ( ios , 'nambbl in configuration namelist', lwp )
  492. IF(lwm) WRITE ( numond, nambbl )
  493. !
  494. l_bbl = .TRUE. !* flag to compute bbl coef and transport
  495. !
  496. IF(lwp) THEN !* Parameter control and print
  497. WRITE(numout,*)
  498. WRITE(numout,*) 'tra_bbl_init : bottom boundary layer initialisation'
  499. WRITE(numout,*) '~~~~~~~~~~~~'
  500. WRITE(numout,*) ' Namelist nambbl : set bbl parameters'
  501. WRITE(numout,*) ' diffusive bbl (=1) or not (=0) nn_bbl_ldf = ', nn_bbl_ldf
  502. WRITE(numout,*) ' advective bbl (=1/2) or not (=0) nn_bbl_adv = ', nn_bbl_adv
  503. WRITE(numout,*) ' diffusive bbl coefficient rn_ahtbbl = ', rn_ahtbbl, ' m2/s'
  504. WRITE(numout,*) ' advective bbl coefficient rn_gambbl = ', rn_gambbl, ' s'
  505. ENDIF
  506. ! ! allocate trabbl arrays
  507. IF( tra_bbl_alloc() /= 0 ) CALL ctl_stop( 'STOP', 'tra_bbl_init : unable to allocate arrays' )
  508. IF( nn_bbl_adv == 1 ) WRITE(numout,*) ' * Advective BBL using upper velocity'
  509. IF( nn_bbl_adv == 2 ) WRITE(numout,*) ' * Advective BBL using velocity = F( delta rho)'
  510. ! !* vertical index of "deep" bottom u- and v-points
  511. DO jj = 1, jpjm1 ! (the "shelf" bottom k-indices are mbku and mbkv)
  512. DO ji = 1, jpim1
  513. mbku_d(ji,jj) = MAX( mbkt(ji+1,jj ) , mbkt(ji,jj) ) ! >= 1 as mbkt=1 over land
  514. mbkv_d(ji,jj) = MAX( mbkt(ji ,jj+1) , mbkt(ji,jj) )
  515. END DO
  516. END DO
  517. ! converte into REAL to use lbc_lnk ; impose a min value of 1 as a zero can be set in lbclnk
  518. zmbk(:,:) = REAL( mbku_d(:,:), wp ) ; CALL lbc_lnk(zmbk,'U',1.) ; mbku_d(:,:) = MAX( INT( zmbk(:,:) ), 1 )
  519. zmbk(:,:) = REAL( mbkv_d(:,:), wp ) ; CALL lbc_lnk(zmbk,'V',1.) ; mbkv_d(:,:) = MAX( INT( zmbk(:,:) ), 1 )
  520. !* sign of grad(H) at u- and v-points; zero if grad(H) = 0
  521. mgrhu(:,:) = 0 ; mgrhv(:,:) = 0
  522. DO jj = 1, jpjm1
  523. DO ji = 1, jpim1
  524. IF( gdept_0(ji+1,jj,mbkt(ji+1,jj)) - gdept_0(ji,jj,mbkt(ji,jj)) /= 0._wp ) THEN
  525. mgrhu(ji,jj) = INT( SIGN( 1.e0, gdept_0(ji+1,jj,mbkt(ji+1,jj)) - gdept_0(ji,jj,mbkt(ji,jj)) ) )
  526. ENDIF
  527. !
  528. IF( gdept_0(ji,jj+1,mbkt(ji,jj+1)) - gdept_0(ji,jj,mbkt(ji,jj)) /= 0._wp ) THEN
  529. mgrhv(ji,jj) = INT( SIGN( 1.e0, gdept_0(ji,jj+1,mbkt(ji,jj+1)) - gdept_0(ji,jj,mbkt(ji,jj)) ) )
  530. ENDIF
  531. END DO
  532. END DO
  533. DO jj = 1, jpjm1 !* bbl thickness at u- (v-) point
  534. DO ji = 1, jpim1 ! minimum of top & bottom e3u_0 (e3v_0)
  535. e3u_bbl_0(ji,jj) = MIN( e3u_0(ji,jj,mbkt(ji+1,jj )), e3u_0(ji,jj,mbkt(ji,jj)) )
  536. e3v_bbl_0(ji,jj) = MIN( e3v_0(ji,jj,mbkt(ji ,jj+1)), e3v_0(ji,jj,mbkt(ji,jj)) )
  537. END DO
  538. END DO
  539. CALL lbc_lnk( e3u_bbl_0, 'U', 1. ) ; CALL lbc_lnk( e3v_bbl_0, 'V', 1. ) ! lateral boundary conditions
  540. ! !* masked diffusive flux coefficients
  541. ahu_bbl_0(:,:) = rn_ahtbbl * e2u(:,:) * e3u_bbl_0(:,:) / e1u(:,:) * umask(:,:,1)
  542. ahv_bbl_0(:,:) = rn_ahtbbl * e1v(:,:) * e3v_bbl_0(:,:) / e2v(:,:) * vmask(:,:,1)
  543. IF( cp_cfg == "orca" ) THEN !* ORCA configuration : regional enhancement of ah_bbl
  544. !
  545. SELECT CASE ( jp_cfg )
  546. CASE ( 2 ) ! ORCA_R2
  547. ij0 = 102 ; ij1 = 102 ! Gibraltar enhancement of BBL
  548. ii0 = 139 ; ii1 = 140
  549. ahu_bbl_0(mi0(ii0):mi1(ii1),mj0(ij0):mj1(ij1)) = 4.e0*ahu_bbl_0(mi0(ii0):mi1(ii1),mj0(ij0):mj1(ij1))
  550. ahv_bbl_0(mi0(ii0):mi1(ii1),mj0(ij0):mj1(ij1)) = 4.e0*ahv_bbl_0(mi0(ii0):mi1(ii1),mj0(ij0):mj1(ij1))
  551. !
  552. ij0 = 88 ; ij1 = 88 ! Red Sea enhancement of BBL
  553. ii0 = 161 ; ii1 = 162
  554. ahu_bbl_0(mi0(ii0):mi1(ii1),mj0(ij0):mj1(ij1)) = 10.e0*ahu_bbl_0(mi0(ii0):mi1(ii1),mj0(ij0):mj1(ij1))
  555. ahv_bbl_0(mi0(ii0):mi1(ii1),mj0(ij0):mj1(ij1)) = 10.e0*ahv_bbl_0(mi0(ii0):mi1(ii1),mj0(ij0):mj1(ij1))
  556. !
  557. CASE ( 4 ) ! ORCA_R4
  558. ij0 = 52 ; ij1 = 52 ! Gibraltar enhancement of BBL
  559. ii0 = 70 ; ii1 = 71
  560. ahu_bbl_0(mi0(ii0):mi1(ii1),mj0(ij0):mj1(ij1)) = 4.e0*ahu_bbl_0(mi0(ii0):mi1(ii1),mj0(ij0):mj1(ij1))
  561. ahv_bbl_0(mi0(ii0):mi1(ii1),mj0(ij0):mj1(ij1)) = 4.e0*ahv_bbl_0(mi0(ii0):mi1(ii1),mj0(ij0):mj1(ij1))
  562. END SELECT
  563. !
  564. ENDIF
  565. !
  566. CALL wrk_dealloc( jpi, jpj, zmbk )
  567. !
  568. IF( nn_timing == 1 ) CALL timing_stop( 'tra_bbl_init')
  569. !
  570. END SUBROUTINE tra_bbl_init
  571. #else
  572. !!----------------------------------------------------------------------
  573. !! Dummy module : No bottom boundary layer scheme
  574. !!----------------------------------------------------------------------
  575. LOGICAL, PUBLIC, PARAMETER :: lk_trabbl = .FALSE. !: bbl flag
  576. CONTAINS
  577. SUBROUTINE tra_bbl_init ! Dummy routine
  578. END SUBROUTINE tra_bbl_init
  579. SUBROUTINE tra_bbl( kt ) ! Dummy routine
  580. WRITE(*,*) 'tra_bbl: You should not have seen this print! error?', kt
  581. END SUBROUTINE tra_bbl
  582. #endif
  583. !!======================================================================
  584. END MODULE trabbl