trcadv.F90 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. MODULE trcadv
  2. !!==============================================================================
  3. !! *** MODULE trcadv ***
  4. !! Ocean passive tracers: advection trend
  5. !!==============================================================================
  6. !! History : 2.0 ! 05-11 (G. Madec) Original code
  7. !! 3.0 ! 10-06 (C. Ethe) Adapted to passive tracers
  8. !!----------------------------------------------------------------------
  9. #if defined key_top
  10. !!----------------------------------------------------------------------
  11. !! 'key_top' TOP models
  12. !!----------------------------------------------------------------------
  13. !! trc_adv : compute ocean tracer advection trend
  14. !! trc_adv_ctl : control the different options of advection scheme
  15. !!----------------------------------------------------------------------
  16. USE oce_trc ! ocean dynamics and active tracers
  17. USE trc ! ocean passive tracers variables
  18. USE trcnam_trp ! passive tracers transport namelist variables
  19. USE traadv_cen2 ! 2nd order centered scheme (tra_adv_cen2 routine)
  20. USE traadv_tvd ! TVD scheme (tra_adv_tvd routine)
  21. USE traadv_muscl ! MUSCL scheme (tra_adv_muscl routine)
  22. USE traadv_muscl2 ! MUSCL2 scheme (tra_adv_muscl2 routine)
  23. USE traadv_ubs ! UBS scheme (tra_adv_ubs routine)
  24. USE traadv_qck ! QUICKEST scheme (tra_adv_qck routine)
  25. USE traadv_eiv ! eddy induced velocity (tra_adv_eiv routine)
  26. USE traadv_mle ! ML eddy induced velocity (tra_adv_mle routine)
  27. USE ldftra_oce ! lateral diffusion coefficient on tracers
  28. USE prtctl_trc ! Print control
  29. IMPLICIT NONE
  30. PRIVATE
  31. PUBLIC trc_adv ! routine called by step module
  32. PUBLIC trc_adv_alloc ! routine called by nemogcm module
  33. INTEGER :: nadv ! choice of the type of advection scheme
  34. REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:) :: r2dt ! vertical profile time-step, = 2 rdttra
  35. ! ! except at nitrrc000 (=rdttra) if neuler=0
  36. !! * Substitutions
  37. # include "domzgr_substitute.h90"
  38. # include "vectopt_loop_substitute.h90"
  39. !!----------------------------------------------------------------------
  40. !! NEMO/TOP 3.3 , NEMO Consortium (2010)
  41. !! $Id: trcadv.F90 4610 2014-03-31 13:19:34Z cetlod $
  42. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  43. !!----------------------------------------------------------------------
  44. CONTAINS
  45. INTEGER FUNCTION trc_adv_alloc()
  46. !!----------------------------------------------------------------------
  47. !! *** ROUTINE trc_adv_alloc ***
  48. !!----------------------------------------------------------------------
  49. ALLOCATE( r2dt(jpk), STAT=trc_adv_alloc )
  50. IF( trc_adv_alloc /= 0 ) CALL ctl_warn('trc_adv_alloc : failed to allocate array.')
  51. END FUNCTION trc_adv_alloc
  52. SUBROUTINE trc_adv( kt )
  53. !!----------------------------------------------------------------------
  54. !! *** ROUTINE trc_adv ***
  55. !!
  56. !! ** Purpose : compute the ocean tracer advection trend.
  57. !!
  58. !! ** Method : - Update the tracer with the advection term following nadv
  59. !!----------------------------------------------------------------------
  60. !!
  61. INTEGER, INTENT(in) :: kt ! ocean time-step index
  62. !
  63. INTEGER :: jk
  64. CHARACTER (len=22) :: charout
  65. REAL(wp), POINTER, DIMENSION(:,:,:) :: zun, zvn, zwn ! effective velocity
  66. !!----------------------------------------------------------------------
  67. !
  68. IF( nn_timing == 1 ) CALL timing_start('trc_adv')
  69. !
  70. CALL wrk_alloc( jpi, jpj, jpk, zun, zvn, zwn )
  71. !
  72. IF( kt == nittrc000 ) CALL trc_adv_ctl ! initialisation & control of options
  73. IF( ( neuler == 0 .AND. kt == nittrc000 ) .OR. ln_top_euler ) THEN ! at nittrc000
  74. r2dt(:) = rdttrc(:) ! = rdttrc (use or restarting with Euler time stepping)
  75. ELSEIF( kt <= nittrc000 + nn_dttrc ) THEN ! at nittrc000 or nittrc000+1
  76. r2dt(:) = 2. * rdttrc(:) ! = 2 rdttrc (leapfrog)
  77. ENDIF
  78. !
  79. IF( lk_offline ) THEN
  80. zun(:,:,:) = un(:,:,:) ! effective transport already in un/vn/wn
  81. zvn(:,:,:) = vn(:,:,:)
  82. zwn(:,:,:) = wn(:,:,:)
  83. ELSE
  84. ! ! effective transport
  85. DO jk = 1, jpkm1
  86. ! ! eulerian transport only
  87. zun(:,:,jk) = e2u (:,:) * fse3u(:,:,jk) * un(:,:,jk)
  88. zvn(:,:,jk) = e1v (:,:) * fse3v(:,:,jk) * vn(:,:,jk)
  89. zwn(:,:,jk) = e1e2t(:,:) * wn(:,:,jk)
  90. !
  91. END DO
  92. !
  93. IF( ln_vvl_ztilde .OR. ln_vvl_layer ) THEN
  94. zun(:,:,:) = zun(:,:,:) + un_td(:,:,:)
  95. zvn(:,:,:) = zvn(:,:,:) + vn_td(:,:,:)
  96. ENDIF
  97. !
  98. zun(:,:,jpk) = 0._wp ! no transport trough the bottom
  99. zvn(:,:,jpk) = 0._wp ! no transport trough the bottom
  100. zwn(:,:,jpk) = 0._wp ! no transport trough the bottom
  101. !
  102. IF( lk_traldf_eiv .AND. .NOT. ln_traldf_grif ) & ! add the eiv transport (if necessary)
  103. & CALL tra_adv_eiv( kt, nittrc000, zun, zvn, zwn, 'TRC' )
  104. !
  105. IF( ln_mle ) CALL tra_adv_mle( kt, nittrc000, zun, zvn, zwn, 'TRC' ) ! add the mle transport (if necessary)
  106. !
  107. ENDIF
  108. !
  109. SELECT CASE ( nadv ) !== compute advection trend and add it to general trend ==!
  110. CASE ( 1 ) ; CALL tra_adv_cen2 ( kt, nittrc000, 'TRC', zun, zvn, zwn, trb, trn, tra, jptra ) ! 2nd order centered
  111. CASE ( 2 ) ; CALL tra_adv_tvd ( kt, nittrc000, 'TRC', r2dt, zun, zvn, zwn, trb, trn, tra, jptra ) ! TVD
  112. CASE ( 3 ) ; CALL tra_adv_muscl ( kt, nittrc000, 'TRC', r2dt, zun, zvn, zwn, trb, tra, jptra, ln_trcadv_msc_ups ) ! MUSCL
  113. CASE ( 4 ) ; CALL tra_adv_muscl2( kt, nittrc000, 'TRC', r2dt, zun, zvn, zwn, trb, trn, tra, jptra ) ! MUSCL2
  114. CASE ( 5 ) ; CALL tra_adv_ubs ( kt, nittrc000, 'TRC', r2dt, zun, zvn, zwn, trb, trn, tra, jptra ) ! UBS
  115. CASE ( 6 ) ; CALL tra_adv_qck ( kt, nittrc000, 'TRC', r2dt, zun, zvn, zwn, trb, trn, tra, jptra ) ! QUICKEST
  116. !
  117. CASE (-1 ) !== esopa: test all possibility with control print ==!
  118. CALL tra_adv_cen2 ( kt, nittrc000, 'TRC', zun, zvn, zwn, trb, trn, tra, jptra )
  119. WRITE(charout, FMT="('adv1')") ; CALL prt_ctl_trc_info(charout)
  120. CALL prt_ctl_trc(tab4d=tra, mask=tmask, clinfo=ctrcnm,clinfo2='trd')
  121. CALL tra_adv_tvd ( kt, nittrc000, 'TRC', r2dt, zun, zvn, zwn, trb, trn, tra, jptra )
  122. WRITE(charout, FMT="('adv2')") ; CALL prt_ctl_trc_info(charout)
  123. CALL prt_ctl_trc(tab4d=tra, mask=tmask, clinfo=ctrcnm,clinfo2='trd')
  124. CALL tra_adv_muscl ( kt, nittrc000, 'TRC', r2dt, zun, zvn, zwn, trb, tra, jptra, ln_trcadv_msc_ups )
  125. WRITE(charout, FMT="('adv3')") ; CALL prt_ctl_trc_info(charout)
  126. CALL prt_ctl_trc(tab4d=tra, mask=tmask, clinfo=ctrcnm,clinfo2='trd')
  127. CALL tra_adv_muscl2( kt, nittrc000, 'TRC', r2dt, zun, zvn, zwn, trb, trn, tra, jptra )
  128. WRITE(charout, FMT="('adv4')") ; CALL prt_ctl_trc_info(charout)
  129. CALL prt_ctl_trc(tab4d=tra, mask=tmask, clinfo=ctrcnm,clinfo2='trd')
  130. CALL tra_adv_ubs ( kt, nittrc000, 'TRC', r2dt, zun, zvn, zwn, trb, trn, tra, jptra )
  131. WRITE(charout, FMT="('adv5')") ; CALL prt_ctl_trc_info(charout)
  132. CALL prt_ctl_trc(tab4d=tra, mask=tmask, clinfo=ctrcnm,clinfo2='trd')
  133. CALL tra_adv_qck ( kt, nittrc000, 'TRC', r2dt, zun, zvn, zwn, trb, trn, tra, jptra )
  134. WRITE(charout, FMT="('adv6')") ; CALL prt_ctl_trc_info(charout)
  135. CALL prt_ctl_trc(tab4d=tra, mask=tmask, clinfo=ctrcnm,clinfo2='trd')
  136. !
  137. END SELECT
  138. ! ! print mean trends (used for debugging)
  139. IF( ln_ctl ) THEN
  140. WRITE(charout, FMT="('adv ')") ; CALL prt_ctl_trc_info(charout)
  141. CALL prt_ctl_trc( tab4d=tra, mask=tmask, clinfo=ctrcnm, clinfo2='trd' )
  142. END IF
  143. !
  144. CALL wrk_dealloc( jpi, jpj, jpk, zun, zvn, zwn )
  145. !
  146. IF( nn_timing == 1 ) CALL timing_stop('trc_adv')
  147. !
  148. END SUBROUTINE trc_adv
  149. SUBROUTINE trc_adv_ctl
  150. !!---------------------------------------------------------------------
  151. !! *** ROUTINE trc_adv_ctl ***
  152. !!
  153. !! ** Purpose : Control the consistency between namelist options for
  154. !! passive tracer advection schemes and set nadv
  155. !!----------------------------------------------------------------------
  156. INTEGER :: ioptio
  157. !!----------------------------------------------------------------------
  158. ioptio = 0 ! Parameter control
  159. IF( ln_trcadv_cen2 ) ioptio = ioptio + 1
  160. IF( ln_trcadv_tvd ) ioptio = ioptio + 1
  161. IF( ln_trcadv_muscl ) ioptio = ioptio + 1
  162. IF( ln_trcadv_muscl2 ) ioptio = ioptio + 1
  163. IF( ln_trcadv_ubs ) ioptio = ioptio + 1
  164. IF( ln_trcadv_qck ) ioptio = ioptio + 1
  165. IF( lk_esopa ) ioptio = 1
  166. IF( ioptio /= 1 ) CALL ctl_stop( 'Choose ONE advection scheme in namelist namtrc_adv' )
  167. ! ! Set nadv
  168. IF( ln_trcadv_cen2 ) nadv = 1
  169. IF( ln_trcadv_tvd ) nadv = 2
  170. IF( ln_trcadv_muscl ) nadv = 3
  171. IF( ln_trcadv_muscl2 ) nadv = 4
  172. IF( ln_trcadv_ubs ) nadv = 5
  173. IF( ln_trcadv_qck ) nadv = 6
  174. IF( lk_esopa ) nadv = -1
  175. IF(lwp) THEN ! Print the choice
  176. WRITE(numout,*)
  177. IF( nadv == 1 ) WRITE(numout,*) ' 2nd order scheme is used'
  178. IF( nadv == 2 ) WRITE(numout,*) ' TVD scheme is used'
  179. IF( nadv == 3 ) WRITE(numout,*) ' MUSCL scheme is used'
  180. IF( nadv == 4 ) WRITE(numout,*) ' MUSCL2 scheme is used'
  181. IF( nadv == 5 ) WRITE(numout,*) ' UBS scheme is used'
  182. IF( nadv == 6 ) WRITE(numout,*) ' QUICKEST scheme is used'
  183. IF( nadv == -1 ) WRITE(numout,*) ' esopa test: use all advection scheme'
  184. ENDIF
  185. !
  186. END SUBROUTINE trc_adv_ctl
  187. #else
  188. !!----------------------------------------------------------------------
  189. !! Default option Empty module
  190. !!----------------------------------------------------------------------
  191. CONTAINS
  192. SUBROUTINE trc_adv( kt )
  193. INTEGER, INTENT(in) :: kt
  194. WRITE(*,*) 'trc_adv: You should not have seen this print! error?', kt
  195. END SUBROUTINE trc_adv
  196. #endif
  197. !!======================================================================
  198. END MODULE trcadv