traadv.F90 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. MODULE traadv
  2. !!==============================================================================
  3. !! *** MODULE traadv ***
  4. !! Ocean active tracers: advection trend
  5. !!==============================================================================
  6. !! History : 2.0 ! 2005-11 (G. Madec) Original code
  7. !! 3.3 ! 2010-09 (C. Ethe, G. Madec) merge TRC-TRA + switch from velocity to transport
  8. !! 4.0 ! 2011-06 (G. Madec) Addition of Mixed Layer Eddy parameterisation
  9. !!----------------------------------------------------------------------
  10. !!----------------------------------------------------------------------
  11. !! tra_adv : compute ocean tracer advection trend
  12. !! tra_adv_ctl : control the different options of advection scheme
  13. !!----------------------------------------------------------------------
  14. USE oce ! ocean dynamics and active tracers
  15. USE dom_oce ! ocean space and time domain
  16. USE domvvl ! variable vertical scale factors
  17. USE traadv_cen2 ! 2nd order centered scheme (tra_adv_cen2 routine)
  18. USE traadv_tvd ! TVD scheme (tra_adv_tvd routine)
  19. USE traadv_muscl ! MUSCL scheme (tra_adv_muscl routine)
  20. USE traadv_muscl2 ! MUSCL2 scheme (tra_adv_muscl2 routine)
  21. USE traadv_ubs ! UBS scheme (tra_adv_ubs routine)
  22. USE traadv_qck ! QUICKEST scheme (tra_adv_qck routine)
  23. USE traadv_eiv ! eddy induced velocity (tra_adv_eiv routine)
  24. USE traadv_mle ! ML eddy induced velocity (tra_adv_mle routine)
  25. USE cla ! cross land advection (cla_traadv routine)
  26. USE ldftra_oce ! lateral diffusion coefficient on tracers
  27. USE trd_oce ! trends: ocean variables
  28. USE trdtra ! trends manager: tracers
  29. !
  30. USE in_out_manager ! I/O manager
  31. USE iom ! I/O module
  32. USE prtctl ! Print control
  33. USE lib_mpp ! MPP library
  34. USE wrk_nemo ! Memory Allocation
  35. USE timing ! Timing
  36. USE sbc_oce
  37. USE diaptr ! Poleward heat transport
  38. IMPLICIT NONE
  39. PRIVATE
  40. PUBLIC tra_adv ! routine called by step module
  41. PUBLIC tra_adv_init ! routine called by opa module
  42. ! !!* Namelist namtra_adv *
  43. LOGICAL :: ln_traadv_cen2 ! 2nd order centered scheme flag
  44. LOGICAL :: ln_traadv_tvd ! TVD scheme flag
  45. LOGICAL :: ln_traadv_tvd_zts ! TVD scheme flag with vertical sub time-stepping
  46. LOGICAL :: ln_traadv_muscl ! MUSCL scheme flag
  47. LOGICAL :: ln_traadv_muscl2 ! MUSCL2 scheme flag
  48. LOGICAL :: ln_traadv_ubs ! UBS scheme flag
  49. LOGICAL :: ln_traadv_qck ! QUICKEST scheme flag
  50. LOGICAL :: ln_traadv_msc_ups ! use upstream scheme within muscl
  51. INTEGER :: nadv ! choice of the type of advection scheme
  52. !! * Substitutions
  53. # include "domzgr_substitute.h90"
  54. # include "vectopt_loop_substitute.h90"
  55. !!----------------------------------------------------------------------
  56. !! NEMO/OPA 3.3 , NEMO Consortium (2010)
  57. !! $Id: traadv.F90 4990 2014-12-15 16:42:49Z timgraham $
  58. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  59. !!----------------------------------------------------------------------
  60. CONTAINS
  61. SUBROUTINE tra_adv( kt )
  62. !!----------------------------------------------------------------------
  63. !! *** ROUTINE tra_adv ***
  64. !!
  65. !! ** Purpose : compute the ocean tracer advection trend.
  66. !!
  67. !! ** Method : - Update (ua,va) with the advection term following nadv
  68. !!----------------------------------------------------------------------
  69. !
  70. INTEGER, INTENT( in ) :: kt ! ocean time-step index
  71. !
  72. INTEGER :: jk ! dummy loop index
  73. REAL(wp), POINTER, DIMENSION(:,:,:) :: zun, zvn, zwn
  74. REAL(wp), POINTER, DIMENSION(:,:,:) :: ztrdt, ztrds ! 3D workspace
  75. !!----------------------------------------------------------------------
  76. !
  77. IF( nn_timing == 1 ) CALL timing_start('tra_adv')
  78. !
  79. CALL wrk_alloc( jpi, jpj, jpk, zun, zvn, zwn )
  80. ! ! set time step
  81. IF( neuler == 0 .AND. kt == nit000 ) THEN ! at nit000
  82. r2dtra(:) = rdttra(:) ! = rdtra (restarting with Euler time stepping)
  83. ELSEIF( kt <= nit000 + 1) THEN ! at nit000 or nit000+1
  84. r2dtra(:) = 2._wp * rdttra(:) ! = 2 rdttra (leapfrog)
  85. ENDIF
  86. !
  87. IF( nn_cla == 1 .AND. cp_cfg == 'orca' .AND. jp_cfg == 2 ) CALL cla_traadv( kt ) !== Cross Land Advection ==! (hor. advection)
  88. !
  89. ! !== effective transport ==!
  90. DO jk = 1, jpkm1
  91. zun(:,:,jk) = e2u(:,:) * fse3u(:,:,jk) * un(:,:,jk) ! eulerian transport only
  92. zvn(:,:,jk) = e1v(:,:) * fse3v(:,:,jk) * vn(:,:,jk)
  93. zwn(:,:,jk) = e1t(:,:) * e2t(:,:) * wn(:,:,jk)
  94. END DO
  95. !
  96. IF( ln_vvl_ztilde .OR. ln_vvl_layer ) THEN
  97. zun(:,:,:) = zun(:,:,:) + un_td(:,:,:)
  98. zvn(:,:,:) = zvn(:,:,:) + vn_td(:,:,:)
  99. ENDIF
  100. !
  101. zun(:,:,jpk) = 0._wp ! no transport trough the bottom
  102. zvn(:,:,jpk) = 0._wp ! no transport trough the bottom
  103. zwn(:,:,jpk) = 0._wp ! no transport trough the bottom
  104. !
  105. IF( lk_traldf_eiv .AND. .NOT. ln_traldf_grif ) &
  106. & CALL tra_adv_eiv( kt, nit000, zun, zvn, zwn, 'TRA' ) ! add the eiv transport (if necessary)
  107. !
  108. IF( ln_mle ) CALL tra_adv_mle( kt, nit000, zun, zvn, zwn, 'TRA' ) ! add the mle transport (if necessary)
  109. !
  110. CALL iom_put( "uocetr_eff", zun ) ! output effective transport
  111. CALL iom_put( "vocetr_eff", zvn )
  112. CALL iom_put( "wocetr_eff", zwn )
  113. !
  114. IF( ln_diaptr ) CALL dia_ptr( zvn ) ! diagnose the effective MSF
  115. !
  116. IF( l_trdtra ) THEN !* Save ta and sa trends
  117. CALL wrk_alloc( jpi, jpj, jpk, ztrdt, ztrds )
  118. ztrdt(:,:,:) = tsa(:,:,:,jp_tem)
  119. ztrds(:,:,:) = tsa(:,:,:,jp_sal)
  120. ENDIF
  121. !
  122. SELECT CASE ( nadv ) !== compute advection trend and add it to general trend ==!
  123. CASE ( 1 ) ; CALL tra_adv_cen2 ( kt, nit000, 'TRA', zun, zvn, zwn, tsb, tsn, tsa, jpts ) ! 2nd order centered
  124. CASE ( 2 ) ; CALL tra_adv_tvd ( kt, nit000, 'TRA', r2dtra, zun, zvn, zwn, tsb, tsn, tsa, jpts ) ! TVD
  125. CASE ( 3 ) ; CALL tra_adv_muscl ( kt, nit000, 'TRA', r2dtra, zun, zvn, zwn, tsb, tsa, jpts, ln_traadv_msc_ups ) ! MUSCL
  126. CASE ( 4 ) ; CALL tra_adv_muscl2 ( kt, nit000, 'TRA', r2dtra, zun, zvn, zwn, tsb, tsn, tsa, jpts ) ! MUSCL2
  127. CASE ( 5 ) ; CALL tra_adv_ubs ( kt, nit000, 'TRA', r2dtra, zun, zvn, zwn, tsb, tsn, tsa, jpts ) ! UBS
  128. CASE ( 6 ) ; CALL tra_adv_qck ( kt, nit000, 'TRA', r2dtra, zun, zvn, zwn, tsb, tsn, tsa, jpts ) ! QUICKEST
  129. CASE ( 7 ) ; CALL tra_adv_tvd_zts( kt, nit000, 'TRA', r2dtra, zun, zvn, zwn, tsb, tsn, tsa, jpts ) ! TVD ZTS
  130. !
  131. CASE (-1 ) !== esopa: test all possibility with control print ==!
  132. CALL tra_adv_cen2 ( kt, nit000, 'TRA', zun, zvn, zwn, tsb, tsn, tsa, jpts )
  133. CALL prt_ctl( tab3d_1=tsa(:,:,:,jp_tem), clinfo1=' adv0 - Ta: ', mask1=tmask, &
  134. & tab3d_2=tsa(:,:,:,jp_sal), clinfo2= ' Sa: ', mask2=tmask, clinfo3='tra' )
  135. CALL tra_adv_tvd ( kt, nit000, 'TRA', r2dtra, zun, zvn, zwn, tsb, tsn, tsa, jpts )
  136. CALL prt_ctl( tab3d_1=tsa(:,:,:,jp_tem), clinfo1=' adv1 - Ta: ', mask1=tmask, &
  137. & tab3d_2=tsa(:,:,:,jp_sal), clinfo2= ' Sa: ', mask2=tmask, clinfo3='tra' )
  138. CALL tra_adv_muscl ( kt, nit000, 'TRA', r2dtra, zun, zvn, zwn, tsb, tsa, jpts, ln_traadv_msc_ups )
  139. CALL prt_ctl( tab3d_1=tsa(:,:,:,jp_tem), clinfo1=' adv3 - Ta: ', mask1=tmask, &
  140. & tab3d_2=tsa(:,:,:,jp_sal), clinfo2= ' Sa: ', mask2=tmask, clinfo3='tra' )
  141. CALL tra_adv_muscl2( kt, nit000, 'TRA', r2dtra, zun, zvn, zwn, tsb, tsn, tsa, jpts )
  142. CALL prt_ctl( tab3d_1=tsa(:,:,:,jp_tem), clinfo1=' adv4 - Ta: ', mask1=tmask, &
  143. & tab3d_2=tsa(:,:,:,jp_sal), clinfo2= ' Sa: ', mask2=tmask, clinfo3='tra' )
  144. CALL tra_adv_ubs ( kt, nit000, 'TRA', r2dtra, zun, zvn, zwn, tsb, tsn, tsa, jpts )
  145. CALL prt_ctl( tab3d_1=tsa(:,:,:,jp_tem), clinfo1=' adv5 - Ta: ', mask1=tmask, &
  146. & tab3d_2=tsa(:,:,:,jp_sal), clinfo2= ' Sa: ', mask2=tmask, clinfo3='tra' )
  147. CALL tra_adv_qck ( kt, nit000, 'TRA', r2dtra, zun, zvn, zwn, tsb, tsn, tsa, jpts )
  148. CALL prt_ctl( tab3d_1=tsa(:,:,:,jp_tem), clinfo1=' adv6 - Ta: ', mask1=tmask, &
  149. & tab3d_2=tsa(:,:,:,jp_sal), clinfo2= ' Sa: ', mask2=tmask, clinfo3='tra' )
  150. END SELECT
  151. !
  152. IF( l_trdtra ) THEN ! save the advective trends for further diagnostics
  153. DO jk = 1, jpkm1
  154. ztrdt(:,:,jk) = tsa(:,:,jk,jp_tem) - ztrdt(:,:,jk)
  155. ztrds(:,:,jk) = tsa(:,:,jk,jp_sal) - ztrds(:,:,jk)
  156. END DO
  157. CALL trd_tra( kt, 'TRA', jp_tem, jptra_totad, ztrdt )
  158. CALL trd_tra( kt, 'TRA', jp_sal, jptra_totad, ztrds )
  159. CALL wrk_dealloc( jpi, jpj, jpk, ztrdt, ztrds )
  160. ENDIF
  161. ! ! print mean trends (used for debugging)
  162. IF(ln_ctl) CALL prt_ctl( tab3d_1=tsa(:,:,:,jp_tem), clinfo1=' adv - Ta: ', mask1=tmask, &
  163. & tab3d_2=tsa(:,:,:,jp_sal), clinfo2= ' Sa: ', mask2=tmask, clinfo3='tra' )
  164. !
  165. IF( nn_timing == 1 ) CALL timing_stop( 'tra_adv' )
  166. !
  167. CALL wrk_dealloc( jpi, jpj, jpk, zun, zvn, zwn )
  168. !
  169. END SUBROUTINE tra_adv
  170. SUBROUTINE tra_adv_init
  171. !!---------------------------------------------------------------------
  172. !! *** ROUTINE tra_adv_init ***
  173. !!
  174. !! ** Purpose : Control the consistency between namelist options for
  175. !! tracer advection schemes and set nadv
  176. !!----------------------------------------------------------------------
  177. INTEGER :: ioptio
  178. INTEGER :: ios ! Local integer output status for namelist read
  179. !!
  180. NAMELIST/namtra_adv/ ln_traadv_cen2 , ln_traadv_tvd, &
  181. & ln_traadv_muscl, ln_traadv_muscl2, &
  182. & ln_traadv_ubs , ln_traadv_qck, &
  183. & ln_traadv_msc_ups, ln_traadv_tvd_zts
  184. !!----------------------------------------------------------------------
  185. REWIND( numnam_ref ) ! Namelist namtra_adv in reference namelist : Tracer advection scheme
  186. READ ( numnam_ref, namtra_adv, IOSTAT = ios, ERR = 901)
  187. 901 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namtra_adv in reference namelist', lwp )
  188. REWIND( numnam_cfg ) ! Namelist namtra_adv in configuration namelist : Tracer advection scheme
  189. READ ( numnam_cfg, namtra_adv, IOSTAT = ios, ERR = 902 )
  190. 902 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namtra_adv in configuration namelist', lwp )
  191. IF(lwm) WRITE ( numond, namtra_adv )
  192. IF(lwp) THEN ! Namelist print
  193. WRITE(numout,*)
  194. WRITE(numout,*) 'tra_adv_init : choice/control of the tracer advection scheme'
  195. WRITE(numout,*) '~~~~~~~~~~~'
  196. WRITE(numout,*) ' Namelist namtra_adv : chose a advection scheme for tracers'
  197. WRITE(numout,*) ' 2nd order advection scheme ln_traadv_cen2 = ', ln_traadv_cen2
  198. WRITE(numout,*) ' TVD advection scheme ln_traadv_tvd = ', ln_traadv_tvd
  199. WRITE(numout,*) ' MUSCL advection scheme ln_traadv_muscl = ', ln_traadv_muscl
  200. WRITE(numout,*) ' MUSCL2 advection scheme ln_traadv_muscl2 = ', ln_traadv_muscl2
  201. WRITE(numout,*) ' UBS advection scheme ln_traadv_ubs = ', ln_traadv_ubs
  202. WRITE(numout,*) ' QUICKEST advection scheme ln_traadv_qck = ', ln_traadv_qck
  203. WRITE(numout,*) ' upstream scheme within muscl ln_traadv_msc_ups = ', ln_traadv_msc_ups
  204. WRITE(numout,*) ' TVD advection scheme with zts ln_traadv_tvd_zts = ', ln_traadv_tvd_zts
  205. ENDIF
  206. ioptio = 0 ! Parameter control
  207. IF( ln_traadv_cen2 ) ioptio = ioptio + 1
  208. IF( ln_traadv_tvd ) ioptio = ioptio + 1
  209. IF( ln_traadv_muscl ) ioptio = ioptio + 1
  210. IF( ln_traadv_muscl2 ) ioptio = ioptio + 1
  211. IF( ln_traadv_ubs ) ioptio = ioptio + 1
  212. IF( ln_traadv_qck ) ioptio = ioptio + 1
  213. IF( ln_traadv_tvd_zts) ioptio = ioptio + 1
  214. IF( lk_esopa ) ioptio = 1
  215. IF( ( ln_traadv_muscl .OR. ln_traadv_muscl2 .OR. ln_traadv_ubs .OR. ln_traadv_qck .OR. ln_traadv_tvd_zts ) &
  216. .AND. ln_isfcav ) CALL ctl_stop( 'Only traadv_cen2 and traadv_tvd is compatible with ice shelf cavity')
  217. IF( ioptio /= 1 ) CALL ctl_stop( 'Choose ONE advection scheme in namelist namtra_adv' )
  218. ! ! Set nadv
  219. IF( ln_traadv_cen2 ) nadv = 1
  220. IF( ln_traadv_tvd ) nadv = 2
  221. IF( ln_traadv_muscl ) nadv = 3
  222. IF( ln_traadv_muscl2 ) nadv = 4
  223. IF( ln_traadv_ubs ) nadv = 5
  224. IF( ln_traadv_qck ) nadv = 6
  225. IF( ln_traadv_tvd_zts) nadv = 7
  226. IF( lk_esopa ) nadv = -1
  227. IF(lwp) THEN ! Print the choice
  228. WRITE(numout,*)
  229. IF( nadv == 1 ) WRITE(numout,*) ' 2nd order scheme is used'
  230. IF( nadv == 2 ) WRITE(numout,*) ' TVD scheme is used'
  231. IF( nadv == 3 ) WRITE(numout,*) ' MUSCL scheme is used'
  232. IF( nadv == 4 ) WRITE(numout,*) ' MUSCL2 scheme is used'
  233. IF( nadv == 5 ) WRITE(numout,*) ' UBS scheme is used'
  234. IF( nadv == 6 ) WRITE(numout,*) ' QUICKEST scheme is used'
  235. IF( nadv == 7 ) WRITE(numout,*) ' TVD ZTS scheme is used'
  236. IF( nadv == -1 ) WRITE(numout,*) ' esopa test: use all advection scheme'
  237. ENDIF
  238. !
  239. CALL tra_adv_mle_init ! initialisation of the Mixed Layer Eddy parametrisation (MLE)
  240. !
  241. END SUBROUTINE tra_adv_init
  242. !!======================================================================
  243. END MODULE traadv