tranxt.F90 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. MODULE tranxt
  2. !!======================================================================
  3. !! *** MODULE tranxt ***
  4. !! Ocean active tracers: time stepping on temperature and salinity
  5. !!======================================================================
  6. !! History : OPA ! 1991-11 (G. Madec) Original code
  7. !! 7.0 ! 1993-03 (M. Guyon) symetrical conditions
  8. !! 8.0 ! 1996-02 (G. Madec & M. Imbard) opa release 8.0
  9. !! - ! 1996-04 (A. Weaver) Euler forward step
  10. !! 8.2 ! 1999-02 (G. Madec, N. Grima) semi-implicit pressure grad.
  11. !! NEMO 1.0 ! 2002-08 (G. Madec) F90: Free form and module
  12. !! - ! 2002-11 (C. Talandier, A-M Treguier) Open boundaries
  13. !! - ! 2005-04 (C. Deltel) Add Asselin trend in the ML budget
  14. !! 2.0 ! 2006-02 (L. Debreu, C. Mazauric) Agrif implementation
  15. !! 3.0 ! 2008-06 (G. Madec) time stepping always done in trazdf
  16. !! 3.1 ! 2009-02 (G. Madec, R. Benshila) re-introduce the vvl option
  17. !! 3.3 ! 2010-04 (M. Leclair, G. Madec) semi-implicit hpg with asselin filter + modified LF-RA
  18. !! - ! 2010-05 (C. Ethe, G. Madec) merge TRC-TRA
  19. !!----------------------------------------------------------------------
  20. !!----------------------------------------------------------------------
  21. !! tra_nxt : time stepping on tracers
  22. !! tra_nxt_fix : time stepping on tracers : fixed volume case
  23. !! tra_nxt_vvl : time stepping on tracers : variable volume case
  24. !!----------------------------------------------------------------------
  25. USE oce ! ocean dynamics and tracers variables
  26. USE dom_oce ! ocean space and time domain variables
  27. USE sbc_oce ! surface boundary condition: ocean
  28. USE sbcrnf ! river runoffs
  29. USE sbcisf ! ice shelf melting/freezing
  30. USE zdf_oce ! ocean vertical mixing
  31. USE domvvl ! variable volume
  32. USE dynspg_oce ! surface pressure gradient variables
  33. USE dynhpg ! hydrostatic pressure gradient
  34. USE trd_oce ! trends: ocean variables
  35. USE trdtra ! trends manager: tracers
  36. USE traqsr ! penetrative solar radiation (needed for nksr)
  37. USE phycst ! physical constant
  38. USE ldftra_oce ! lateral physics on tracers
  39. USE bdy_oce ! BDY open boundary condition variables
  40. USE bdytra ! open boundary condition (bdy_tra routine)
  41. !
  42. USE in_out_manager ! I/O manager
  43. USE lbclnk ! ocean lateral boundary conditions (or mpp link)
  44. USE prtctl ! Print control
  45. USE wrk_nemo ! Memory allocation
  46. USE timing ! Timing
  47. #if defined key_agrif
  48. USE agrif_opa_interp
  49. #endif
  50. IMPLICIT NONE
  51. PRIVATE
  52. PUBLIC tra_nxt ! routine called by step.F90
  53. PUBLIC tra_nxt_fix ! to be used in trcnxt
  54. PUBLIC tra_nxt_vvl ! to be used in trcnxt
  55. REAL(wp) :: rbcp ! Brown & Campana parameters for semi-implicit hpg
  56. !! * Substitutions
  57. # include "domzgr_substitute.h90"
  58. !!----------------------------------------------------------------------
  59. !! NEMO/OPA 3.3 , NEMO-Consortium (2010)
  60. !! $Id: tranxt.F90 5628 2015-07-22 20:26:35Z mathiot $
  61. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  62. !!----------------------------------------------------------------------
  63. CONTAINS
  64. SUBROUTINE tra_nxt( kt )
  65. !!----------------------------------------------------------------------
  66. !! *** ROUTINE tranxt ***
  67. !!
  68. !! ** Purpose : Apply the boundary condition on the after temperature
  69. !! and salinity fields, achieved the time stepping by adding
  70. !! the Asselin filter on now fields and swapping the fields.
  71. !!
  72. !! ** Method : At this stage of the computation, ta and sa are the
  73. !! after temperature and salinity as the time stepping has
  74. !! been performed in trazdf_imp or trazdf_exp module.
  75. !!
  76. !! - Apply lateral boundary conditions on (ta,sa)
  77. !! at the local domain boundaries through lbc_lnk call,
  78. !! at the one-way open boundaries (lk_bdy=T),
  79. !! at the AGRIF zoom boundaries (lk_agrif=T)
  80. !!
  81. !! - Update lateral boundary conditions on AGRIF children
  82. !! domains (lk_agrif=T)
  83. !!
  84. !! ** Action : - (tb,sb) and (tn,sn) ready for the next time step
  85. !! - (ta,sa) time averaged (t,s) (ln_dynhpg_imp = T)
  86. !!----------------------------------------------------------------------
  87. INTEGER, INTENT(in) :: kt ! ocean time-step index
  88. !!
  89. INTEGER :: jk, jn ! dummy loop indices
  90. REAL(wp) :: zfact ! local scalars
  91. REAL(wp), POINTER, DIMENSION(:,:,:) :: ztrdt, ztrds
  92. !!----------------------------------------------------------------------
  93. !
  94. IF( nn_timing == 1 ) CALL timing_start( 'tra_nxt')
  95. !
  96. IF( kt == nit000 ) THEN
  97. IF(lwp) WRITE(numout,*)
  98. IF(lwp) WRITE(numout,*) 'tra_nxt : achieve the time stepping by Asselin filter and array swap'
  99. IF(lwp) WRITE(numout,*) '~~~~~~~'
  100. !
  101. rbcp = 0.25_wp * (1._wp + atfp) * (1._wp + atfp) * ( 1._wp - atfp) ! Brown & Campana parameter for semi-implicit hpg
  102. ENDIF
  103. ! Update after tracer on domain lateral boundaries
  104. !
  105. #if defined key_agrif
  106. CALL Agrif_tra ! AGRIF zoom boundaries
  107. #endif
  108. !
  109. CALL lbc_lnk( tsa(:,:,:,jp_tem), 'T', 1._wp ) ! local domain boundaries (T-point, unchanged sign)
  110. CALL lbc_lnk( tsa(:,:,:,jp_sal), 'T', 1._wp )
  111. !
  112. #if defined key_bdy
  113. IF( lk_bdy ) CALL bdy_tra( kt ) ! BDY open boundaries
  114. #endif
  115. ! set time step size (Euler/Leapfrog)
  116. IF( neuler == 0 .AND. kt == nit000 ) THEN ; r2dtra(:) = rdttra(:) ! at nit000 (Euler)
  117. ELSEIF( kt <= nit000 + 1 ) THEN ; r2dtra(:) = 2._wp* rdttra(:) ! at nit000 or nit000+1 (Leapfrog)
  118. ENDIF
  119. ! trends computation initialisation
  120. IF( l_trdtra ) THEN
  121. CALL wrk_alloc( jpi, jpj, jpk, ztrdt, ztrds )
  122. ztrdt(:,:,jpk) = 0._wp
  123. ztrds(:,:,jpk) = 0._wp
  124. IF( ln_traldf_iso ) THEN ! diagnose the "pure" Kz diffusive trend
  125. CALL trd_tra( kt, 'TRA', jp_tem, jptra_zdfp, ztrdt )
  126. CALL trd_tra( kt, 'TRA', jp_sal, jptra_zdfp, ztrds )
  127. ENDIF
  128. ! total trend for the non-time-filtered variables.
  129. ! G Nurser 23 Mar 2017. Recalculate trend as Delta(e3t*T)/e3tn; e3tn cancel from tsn terms
  130. IF( lk_vvl ) THEN
  131. DO jk = 1, jpkm1
  132. zfact = 1.0 / rdttra(jk)
  133. ztrdt(:,:,jk) = ( tsa(:,:,jk,jp_tem)*fse3t_a(:,:,jk) / fse3t_n(:,:,jk) - tsn(:,:,jk,jp_tem)) * zfact
  134. ztrds(:,:,jk) = ( tsa(:,:,jk,jp_sal)*fse3t_a(:,:,jk) / fse3t_n(:,:,jk) - tsn(:,:,jk,jp_sal)) * zfact
  135. END DO
  136. ELSE
  137. DO jk = 1, jpkm1
  138. zfact = 1.0 / rdttra(jk)
  139. ztrdt(:,:,jk) = ( tsa(:,:,jk,jp_tem) - tsn(:,:,jk,jp_tem) ) * zfact
  140. ztrds(:,:,jk) = ( tsa(:,:,jk,jp_sal) - tsn(:,:,jk,jp_sal) ) * zfact
  141. END DO
  142. END IF
  143. CALL trd_tra( kt, 'TRA', jp_tem, jptra_tot, ztrdt )
  144. CALL trd_tra( kt, 'TRA', jp_sal, jptra_tot, ztrds )
  145. IF( .NOT.lk_vvl ) THEN
  146. ! Store now fields before applying the Asselin filter
  147. ! in order to calculate Asselin filter trend later.
  148. ztrdt(:,:,:) = tsn(:,:,:,jp_tem)
  149. ztrds(:,:,:) = tsn(:,:,:,jp_sal)
  150. END IF
  151. ENDIF
  152. IF( neuler == 0 .AND. kt == nit000 ) THEN ! Euler time-stepping at first time-step (only swap)
  153. DO jn = 1, jpts
  154. DO jk = 1, jpkm1
  155. tsn(:,:,jk,jn) = tsa(:,:,jk,jn)
  156. END DO
  157. END DO
  158. IF (l_trdtra.AND.lk_vvl) THEN ! Zero Asselin filter contribution must be explicitly written out since for vvl
  159. ! Asselin filter is output by tra_nxt_vvl that is not called on this time step
  160. ztrdt(:,:,:) = 0._wp
  161. ztrds(:,:,:) = 0._wp
  162. CALL trd_tra( kt, 'TRA', jp_tem, jptra_atf, ztrdt )
  163. CALL trd_tra( kt, 'TRA', jp_sal, jptra_atf, ztrds )
  164. END IF
  165. ELSE ! Leap-Frog + Asselin filter time stepping
  166. !
  167. IF( lk_vvl ) THEN ; CALL tra_nxt_vvl( kt, nit000, rdttra, 'TRA', tsb, tsn, tsa, &
  168. & sbc_tsc, sbc_tsc_b, jpts ) ! variable volume level (vvl)
  169. ELSE ; CALL tra_nxt_fix( kt, nit000, 'TRA', tsb, tsn, tsa, jpts ) ! fixed volume level
  170. ENDIF
  171. ENDIF
  172. !
  173. ! trends computation
  174. IF( l_trdtra.AND..NOT.lk_vvl) THEN ! trend of the Asselin filter (tb filtered - tb)/dt
  175. DO jk = 1, jpkm1
  176. zfact = 1._wp / r2dtra(jk)
  177. ztrdt(:,:,jk) = ( tsb(:,:,jk,jp_tem) - ztrdt(:,:,jk) ) * zfact
  178. ztrds(:,:,jk) = ( tsb(:,:,jk,jp_sal) - ztrds(:,:,jk) ) * zfact
  179. END DO
  180. CALL trd_tra( kt, 'TRA', jp_tem, jptra_atf, ztrdt )
  181. CALL trd_tra( kt, 'TRA', jp_sal, jptra_atf, ztrds )
  182. END IF
  183. IF( l_trdtra) CALL wrk_dealloc( jpi, jpj, jpk, ztrdt, ztrds )
  184. !
  185. ! ! control print
  186. IF(ln_ctl) CALL prt_ctl( tab3d_1=tsn(:,:,:,jp_tem), clinfo1=' nxt - Tn: ', mask1=tmask, &
  187. & tab3d_2=tsn(:,:,:,jp_sal), clinfo2= ' Sn: ', mask2=tmask )
  188. !
  189. IF( nn_timing == 1 ) CALL timing_stop('tra_nxt')
  190. !
  191. END SUBROUTINE tra_nxt
  192. SUBROUTINE tra_nxt_fix( kt, kit000, cdtype, ptb, ptn, pta, kjpt )
  193. !!----------------------------------------------------------------------
  194. !! *** ROUTINE tra_nxt_fix ***
  195. !!
  196. !! ** Purpose : fixed volume: apply the Asselin time filter and
  197. !! swap the tracer fields.
  198. !!
  199. !! ** Method : - Apply a Asselin time filter on now fields.
  200. !! - save in (ta,sa) an average over the three time levels
  201. !! which will be used to compute rdn and thus the semi-implicit
  202. !! hydrostatic pressure gradient (ln_dynhpg_imp = T)
  203. !! - swap tracer fields to prepare the next time_step.
  204. !! This can be summurized for tempearture as:
  205. !! ztm = tn + rbcp * [ta -2 tn + tb ] ln_dynhpg_imp = T
  206. !! ztm = 0 otherwise
  207. !! with rbcp=1/4 * (1-atfp^4) / (1-atfp)
  208. !! tb = tn + atfp*[ tb - 2 tn + ta ]
  209. !! tn = ta
  210. !! ta = ztm (NB: reset to 0 after eos_bn2 call)
  211. !!
  212. !! ** Action : - (tb,sb) and (tn,sn) ready for the next time step
  213. !! - (ta,sa) time averaged (t,s) (ln_dynhpg_imp = T)
  214. !!----------------------------------------------------------------------
  215. INTEGER , INTENT(in ) :: kt ! ocean time-step index
  216. INTEGER , INTENT(in ) :: kit000 ! first time step index
  217. CHARACTER(len=3), INTENT(in ) :: cdtype ! =TRA or TRC (tracer indicator)
  218. INTEGER , INTENT(in ) :: kjpt ! number of tracers
  219. REAL(wp) , INTENT(inout), DIMENSION(jpi,jpj,jpk,kjpt) :: ptb ! before tracer fields
  220. REAL(wp) , INTENT(inout), DIMENSION(jpi,jpj,jpk,kjpt) :: ptn ! now tracer fields
  221. REAL(wp) , INTENT(inout), DIMENSION(jpi,jpj,jpk,kjpt) :: pta ! tracer trend
  222. !
  223. INTEGER :: ji, jj, jk, jn ! dummy loop indices
  224. LOGICAL :: ll_tra_hpg ! local logical
  225. REAL(wp) :: ztn, ztd ! local scalars
  226. !!----------------------------------------------------------------------
  227. IF( kt == kit000 ) THEN
  228. IF(lwp) WRITE(numout,*)
  229. IF(lwp) WRITE(numout,*) 'tra_nxt_fix : time stepping', cdtype
  230. IF(lwp) WRITE(numout,*) '~~~~~~~~~~~'
  231. ENDIF
  232. !
  233. IF( cdtype == 'TRA' ) THEN ; ll_tra_hpg = ln_dynhpg_imp ! active tracers case and semi-implicit hpg
  234. ELSE ; ll_tra_hpg = .FALSE. ! passive tracers case or NO semi-implicit hpg
  235. ENDIF
  236. !
  237. DO jn = 1, kjpt
  238. !
  239. DO jk = 1, jpkm1
  240. DO jj = 1, jpj
  241. DO ji = 1, jpi
  242. ztn = ptn(ji,jj,jk,jn)
  243. ztd = pta(ji,jj,jk,jn) - 2. * ztn + ptb(ji,jj,jk,jn) ! time laplacian on tracers
  244. !
  245. ptb(ji,jj,jk,jn) = ztn + atfp * ztd ! ptb <-- filtered ptn
  246. ptn(ji,jj,jk,jn) = pta(ji,jj,jk,jn) ! ptn <-- pta
  247. !
  248. IF( ll_tra_hpg ) pta(ji,jj,jk,jn) = ztn + rbcp * ztd ! pta <-- Brown & Campana average
  249. END DO
  250. END DO
  251. END DO
  252. !
  253. END DO
  254. !
  255. END SUBROUTINE tra_nxt_fix
  256. SUBROUTINE tra_nxt_vvl( kt, kit000, p2dt, cdtype, ptb, ptn, pta, psbc_tc, psbc_tc_b, kjpt )
  257. !!----------------------------------------------------------------------
  258. !! *** ROUTINE tra_nxt_vvl ***
  259. !!
  260. !! ** Purpose : Time varying volume: apply the Asselin time filter
  261. !! and swap the tracer fields.
  262. !!
  263. !! ** Method : - Apply a thickness weighted Asselin time filter on now fields.
  264. !! - save in (ta,sa) a thickness weighted average over the three
  265. !! time levels which will be used to compute rdn and thus the semi-
  266. !! implicit hydrostatic pressure gradient (ln_dynhpg_imp = T)
  267. !! - swap tracer fields to prepare the next time_step.
  268. !! This can be summurized for tempearture as:
  269. !! ztm = ( e3t_n*tn + rbcp*[ e3t_b*tb - 2 e3t_n*tn + e3t_a*ta ] ) ln_dynhpg_imp = T
  270. !! /( e3t_n + rbcp*[ e3t_b - 2 e3t_n + e3t_a ] )
  271. !! ztm = 0 otherwise
  272. !! tb = ( e3t_n*tn + atfp*[ e3t_b*tb - 2 e3t_n*tn + e3t_a*ta ] )
  273. !! /( e3t_n + atfp*[ e3t_b - 2 e3t_n + e3t_a ] )
  274. !! tn = ta
  275. !! ta = zt (NB: reset to 0 after eos_bn2 call)
  276. !!
  277. !! ** Action : - (tb,sb) and (tn,sn) ready for the next time step
  278. !! - (ta,sa) time averaged (t,s) (ln_dynhpg_imp = T)
  279. !!----------------------------------------------------------------------
  280. INTEGER , INTENT(in ) :: kt ! ocean time-step index
  281. INTEGER , INTENT(in ) :: kit000 ! first time step index
  282. REAL(wp) , INTENT(in ), DIMENSION(jpk) :: p2dt ! time-step
  283. CHARACTER(len=3), INTENT(in ) :: cdtype ! =TRA or TRC (tracer indicator)
  284. INTEGER , INTENT(in ) :: kjpt ! number of tracers
  285. REAL(wp) , INTENT(inout), DIMENSION(jpi,jpj,jpk,kjpt) :: ptb ! before tracer fields
  286. REAL(wp) , INTENT(inout), DIMENSION(jpi,jpj,jpk,kjpt) :: ptn ! now tracer fields
  287. REAL(wp) , INTENT(inout), DIMENSION(jpi,jpj,jpk,kjpt) :: pta ! tracer trend
  288. REAL(wp) , INTENT(in ), DIMENSION(jpi,jpj,kjpt) :: psbc_tc ! surface tracer content
  289. REAL(wp) , INTENT(in ), DIMENSION(jpi,jpj,kjpt) :: psbc_tc_b ! before surface tracer content
  290. !!
  291. LOGICAL :: ll_tra_hpg, ll_traqsr, ll_rnf, ll_isf ! local logical
  292. INTEGER :: ji, jj, jk, jn ! dummy loop indices
  293. REAL(wp) :: zfact, zfact1, ztc_a , ztc_n , ztc_b , ztc_f , ztc_d ! local scalar
  294. REAL(wp) :: zfact2, ze3t_b, ze3t_n, ze3t_a, ze3t_f, ze3t_d ! - -
  295. REAL(wp), POINTER, DIMENSION(:,:,:,:) :: ztrd_atf
  296. !!----------------------------------------------------------------------
  297. !
  298. IF( kt == kit000 ) THEN
  299. IF(lwp) WRITE(numout,*)
  300. IF(lwp) WRITE(numout,*) 'tra_nxt_vvl : time stepping', cdtype
  301. IF(lwp) WRITE(numout,*) '~~~~~~~~~~~'
  302. ENDIF
  303. !
  304. IF( cdtype == 'TRA' ) THEN
  305. ll_tra_hpg = ln_dynhpg_imp ! active tracers case and semi-implicit hpg
  306. ll_traqsr = ln_traqsr ! active tracers case and solar penetration
  307. ll_rnf = ln_rnf ! active tracers case and river runoffs
  308. IF (nn_isf .GE. 1) THEN
  309. ll_isf = .TRUE. ! active tracers case and ice shelf melting/freezing
  310. ELSE
  311. ll_isf = .FALSE.
  312. END IF
  313. ELSE
  314. ll_tra_hpg = .FALSE. ! passive tracers case or NO semi-implicit hpg
  315. ll_traqsr = .FALSE. ! active tracers case and NO solar penetration
  316. ll_rnf = .FALSE. ! passive tracers or NO river runoffs
  317. ll_isf = .FALSE. ! passive tracers or NO ice shelf melting/freezing
  318. ENDIF
  319. !
  320. IF( ( l_trdtra .and. cdtype == 'TRA' ) .OR. ( l_trdtrc .and. cdtype == 'TRC' ) ) THEN
  321. CALL wrk_alloc( jpi, jpj, jpk, kjpt, ztrd_atf )
  322. ztrd_atf(:,:,:,:) = 0.0_wp
  323. ENDIF
  324. DO jn = 1, kjpt
  325. DO jk = 1, jpkm1
  326. zfact = 1._wp / p2dt(jk)
  327. zfact1 = atfp * p2dt(jk)
  328. zfact2 = zfact1 / rau0
  329. DO jj = 1, jpj
  330. DO ji = 1, jpi
  331. ze3t_b = fse3t_b(ji,jj,jk)
  332. ze3t_n = fse3t_n(ji,jj,jk)
  333. ze3t_a = fse3t_a(ji,jj,jk)
  334. ! ! tracer content at Before, now and after
  335. ztc_b = ptb(ji,jj,jk,jn) * ze3t_b
  336. ztc_n = ptn(ji,jj,jk,jn) * ze3t_n
  337. ztc_a = pta(ji,jj,jk,jn) * ze3t_a
  338. !
  339. ze3t_d = ze3t_a - 2. * ze3t_n + ze3t_b
  340. ztc_d = ztc_a - 2. * ztc_n + ztc_b
  341. !
  342. ze3t_f = ze3t_n + atfp * ze3t_d
  343. ztc_f = ztc_n + atfp * ztc_d
  344. !
  345. IF( jk == mikt(ji,jj) ) THEN ! first level
  346. ze3t_f = ze3t_f - zfact2 * ( (emp_b(ji,jj) - emp(ji,jj) ) &
  347. & - (rnf_b(ji,jj) - rnf(ji,jj) ) &
  348. & + (fwfisf_b(ji,jj) - fwfisf(ji,jj)) )
  349. ztc_f = ztc_f - zfact1 * ( psbc_tc(ji,jj,jn) - psbc_tc_b(ji,jj,jn) )
  350. ENDIF
  351. ! solar penetration (temperature only)
  352. IF( ll_traqsr .AND. jn == jp_tem .AND. jk <= nksr ) &
  353. & ztc_f = ztc_f - zfact1 * ( qsr_hc(ji,jj,jk) - qsr_hc_b(ji,jj,jk) )
  354. ! river runoff
  355. IF( ll_rnf .AND. jk <= nk_rnf(ji,jj) ) &
  356. & ztc_f = ztc_f - zfact1 * ( rnf_tsc(ji,jj,jn) - rnf_tsc_b(ji,jj,jn) ) &
  357. & * fse3t_n(ji,jj,jk) / h_rnf(ji,jj)
  358. ! ice shelf
  359. IF( ll_isf ) THEN
  360. ! level fully include in the Losch_2008 ice shelf boundary layer
  361. IF ( jk >= misfkt(ji,jj) .AND. jk < misfkb(ji,jj) ) &
  362. ztc_f = ztc_f - zfact1 * ( risf_tsc(ji,jj,jn) - risf_tsc_b(ji,jj,jn) ) &
  363. & * fse3t_n(ji,jj,jk) * r1_hisf_tbl (ji,jj)
  364. ! level partially include in Losch_2008 ice shelf boundary layer
  365. IF ( jk == misfkb(ji,jj) ) &
  366. ztc_f = ztc_f - zfact1 * ( risf_tsc(ji,jj,jn) - risf_tsc_b(ji,jj,jn) ) &
  367. & * fse3t_n(ji,jj,jk) * r1_hisf_tbl (ji,jj) * ralpha(ji,jj)
  368. END IF
  369. ze3t_f = 1.e0 / ze3t_f
  370. ptb(ji,jj,jk,jn) = ztc_f * ze3t_f ! ptb <-- ptn filtered
  371. ptn(ji,jj,jk,jn) = pta(ji,jj,jk,jn) ! ptn <-- pta
  372. !
  373. IF( ll_tra_hpg ) THEN ! semi-implicit hpg (T & S only)
  374. ze3t_d = 1.e0 / ( ze3t_n + rbcp * ze3t_d )
  375. pta(ji,jj,jk,jn) = ze3t_d * ( ztc_n + rbcp * ztc_d ) ! ta <-- Brown & Campana average
  376. ENDIF
  377. IF( ( l_trdtra .and. cdtype == 'TRA' ) .OR. ( l_trdtrc .and. cdtype == 'TRC' ) ) THEN
  378. ztrd_atf(ji,jj,jk,jn) = (ztc_f - ztc_n) * zfact/ze3t_n
  379. ENDIF
  380. END DO
  381. END DO
  382. END DO
  383. !
  384. END DO
  385. !
  386. IF( l_trdtra .and. cdtype == 'TRA' ) THEN
  387. CALL trd_tra( kt, cdtype, jp_tem, jptra_atf, ztrd_atf(:,:,:,jp_tem) )
  388. CALL trd_tra( kt, cdtype, jp_sal, jptra_atf, ztrd_atf(:,:,:,jp_sal) )
  389. CALL wrk_dealloc( jpi, jpj, jpk, kjpt, ztrd_atf )
  390. ENDIF
  391. IF( l_trdtrc .and. cdtype == 'TRC' ) THEN
  392. DO jn = 1, kjpt
  393. CALL trd_tra( kt, cdtype, jn, jptra_atf, ztrd_atf(:,:,:,jn) )
  394. END DO
  395. CALL wrk_dealloc( jpi, jpj, jpk, kjpt, ztrd_atf )
  396. ENDIF
  397. END SUBROUTINE tra_nxt_vvl
  398. !!======================================================================
  399. END MODULE tranxt