trazdf.F90 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. MODULE trazdf
  2. !!==============================================================================
  3. !! *** MODULE trazdf ***
  4. !! Ocean active tracers: vertical component of the tracer mixing trend
  5. !!==============================================================================
  6. !! History : 1.0 ! 2005-11 (G. Madec) Original code
  7. !! 3.0 ! 2008-01 (C. Ethe, G. Madec) merge TRC-TRA
  8. !!----------------------------------------------------------------------
  9. !!----------------------------------------------------------------------
  10. !! tra_zdf : Update the tracer trend with the vertical diffusion
  11. !! tra_zdf_init : initialisation of the computation
  12. !!----------------------------------------------------------------------
  13. USE oce ! ocean dynamics and tracers variables
  14. USE dom_oce ! ocean space and time domain variables
  15. USE domvvl ! variable volume
  16. USE phycst ! physical constant
  17. USE zdf_oce ! ocean vertical physics variables
  18. USE sbc_oce ! surface boundary condition: ocean
  19. USE dynspg_oce
  20. USE trazdf_exp ! vertical diffusion: explicit (tra_zdf_exp routine)
  21. USE trazdf_imp ! vertical diffusion: implicit (tra_zdf_imp routine)
  22. USE ldftra_oce ! ocean active tracers: lateral physics
  23. USE trd_oce ! trends: ocean variables
  24. USE trdtra ! trends manager: tracers
  25. !
  26. USE in_out_manager ! I/O manager
  27. USE prtctl ! Print control
  28. USE lbclnk ! ocean lateral boundary conditions (or mpp link)
  29. USE lib_mpp ! MPP library
  30. USE wrk_nemo ! Memory allocation
  31. USE timing ! Timing
  32. IMPLICIT NONE
  33. PRIVATE
  34. PUBLIC tra_zdf ! routine called by step.F90
  35. PUBLIC tra_zdf_init ! routine called by nemogcm.F90
  36. INTEGER :: nzdf = 0 ! type vertical diffusion algorithm used (defined from ln_zdf... namlist logicals)
  37. !! * Substitutions
  38. # include "domzgr_substitute.h90"
  39. # include "zdfddm_substitute.h90"
  40. # include "vectopt_loop_substitute.h90"
  41. !!----------------------------------------------------------------------
  42. !! NEMO/OPA 3.7 , NEMO Consortium (2014)
  43. !! $Id: trazdf.F90 4990 2014-12-15 16:42:49Z timgraham $
  44. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  45. !!----------------------------------------------------------------------
  46. CONTAINS
  47. SUBROUTINE tra_zdf( kt )
  48. !!----------------------------------------------------------------------
  49. !! *** ROUTINE tra_zdf ***
  50. !!
  51. !! ** Purpose : compute the vertical ocean tracer physics.
  52. !!---------------------------------------------------------------------
  53. INTEGER, INTENT( in ) :: kt ! ocean time-step index
  54. !!
  55. INTEGER :: jk ! Dummy loop indices
  56. REAL(wp), POINTER, DIMENSION(:,:,:) :: ztrdt, ztrds ! 3D workspace
  57. !!---------------------------------------------------------------------
  58. !
  59. IF( nn_timing == 1 ) CALL timing_start('tra_zdf')
  60. !
  61. IF( neuler == 0 .AND. kt == nit000 ) THEN ! at nit000
  62. r2dtra(:) = rdttra(:) ! = rdtra (restarting with Euler time stepping)
  63. ELSEIF( kt <= nit000 + 1) THEN ! at nit000 or nit000+1
  64. r2dtra(:) = 2. * rdttra(:) ! = 2 rdttra (leapfrog)
  65. ENDIF
  66. IF( l_trdtra ) THEN !* Save ta and sa trends
  67. CALL wrk_alloc( jpi, jpj, jpk, ztrdt, ztrds )
  68. ztrdt(:,:,:) = tsa(:,:,:,jp_tem)
  69. ztrds(:,:,:) = tsa(:,:,:,jp_sal)
  70. ENDIF
  71. SELECT CASE ( nzdf ) ! compute lateral mixing trend and add it to the general trend
  72. CASE ( 0 ) ; CALL tra_zdf_exp( kt, nit000, 'TRA', r2dtra, nn_zdfexp, tsb, tsa, jpts ) ! explicit scheme
  73. CASE ( 1 ) ; CALL tra_zdf_imp( kt, nit000, 'TRA', r2dtra, tsb, tsa, jpts ) ! implicit scheme
  74. CASE ( -1 ) ! esopa: test all possibility with control print
  75. CALL tra_zdf_exp( kt, nit000, 'TRA', r2dtra, nn_zdfexp, tsb, tsa, jpts )
  76. CALL prt_ctl( tab3d_1=tsa(:,:,:,jp_tem), clinfo1=' zdf0 - Ta: ', mask1=tmask, &
  77. & tab3d_2=tsa(:,:,:,jp_sal), clinfo2= ' Sa: ', mask2=tmask, clinfo3='tra' )
  78. CALL tra_zdf_imp( kt, nit000, 'TRA', r2dtra, tsb, tsa, jpts )
  79. CALL prt_ctl( tab3d_1=tsa(:,:,:,jp_tem), clinfo1=' zdf1 - Ta: ', mask1=tmask, &
  80. & tab3d_2=tsa(:,:,:,jp_sal), clinfo2= ' Sa: ', mask2=tmask, clinfo3='tra' )
  81. END SELECT
  82. ! DRAKKAR SSS control {
  83. ! JMM avoid negative salinities near river outlet ! Ugly fix
  84. ! JMM : restore negative salinities to small salinities:
  85. WHERE ( tsa(:,:,:,jp_sal) < 0._wp ) tsa(:,:,:,jp_sal) = 0.1_wp
  86. IF( l_trdtra ) THEN ! save the vertical diffusive trends for further diagnostics
  87. ! G Nurser 23 Mar 2017. Recalculate trend as Delta(e3t*T)/e3tn.
  88. IF( lk_vvl ) THEN
  89. DO jk = 1, jpkm1
  90. ztrdt(:,:,jk) = ( ( tsa(:,:,jk,jp_tem)*fse3t_a(:,:,jk) - tsb(:,:,jk,jp_tem)*fse3t_b(:,:,jk) ) &
  91. & / (fse3t_n(:,:,jk)*r2dtra(jk)) ) - ztrdt(:,:,jk)
  92. ztrds(:,:,jk) = ( ( tsa(:,:,jk,jp_sal)*fse3t_a(:,:,jk) - tsb(:,:,jk,jp_sal)*fse3t_b(:,:,jk) ) &
  93. & / (fse3t_n(:,:,jk)*r2dtra(jk)) ) - ztrds(:,:,jk)
  94. END DO
  95. ELSE
  96. DO jk = 1, jpkm1
  97. ztrdt(:,:,jk) = ( ( tsa(:,:,jk,jp_tem) - tsb(:,:,jk,jp_tem) ) / r2dtra(jk) ) - ztrdt(:,:,jk)
  98. ztrds(:,:,jk) = ( ( tsa(:,:,jk,jp_sal) - tsb(:,:,jk,jp_sal) ) / r2dtra(jk) ) - ztrds(:,:,jk)
  99. END DO
  100. END IF
  101. CALL lbc_lnk( ztrdt, 'T', 1. )
  102. CALL lbc_lnk( ztrds, 'T', 1. )
  103. CALL trd_tra( kt, 'TRA', jp_tem, jptra_zdf, ztrdt )
  104. CALL trd_tra( kt, 'TRA', jp_sal, jptra_zdf, ztrds )
  105. CALL wrk_dealloc( jpi, jpj, jpk, ztrdt, ztrds )
  106. ENDIF
  107. ! ! print mean trends (used for debugging)
  108. IF(ln_ctl) CALL prt_ctl( tab3d_1=tsa(:,:,:,jp_tem), clinfo1=' zdf - Ta: ', mask1=tmask, &
  109. & tab3d_2=tsa(:,:,:,jp_sal), clinfo2= ' Sa: ', mask2=tmask, clinfo3='tra' )
  110. !
  111. IF( nn_timing == 1 ) CALL timing_stop('tra_zdf')
  112. !
  113. END SUBROUTINE tra_zdf
  114. SUBROUTINE tra_zdf_init
  115. !!----------------------------------------------------------------------
  116. !! *** ROUTINE tra_zdf_init ***
  117. !!
  118. !! ** Purpose : Choose the vertical mixing scheme
  119. !!
  120. !! ** Method : Set nzdf from ln_zdfexp
  121. !! nzdf = 0 explicit (time-splitting) scheme (ln_zdfexp=T)
  122. !! = 1 implicit (euler backward) scheme (ln_zdfexp=F)
  123. !! NB: rotation of lateral mixing operator or TKE or KPP scheme,
  124. !! the implicit scheme is required.
  125. !!----------------------------------------------------------------------
  126. USE zdftke
  127. USE zdfgls
  128. USE zdfkpp
  129. !!----------------------------------------------------------------------
  130. ! Choice from ln_zdfexp already read in namelist in zdfini module
  131. IF( ln_zdfexp ) THEN ; nzdf = 0 ! use explicit scheme
  132. ELSE ; nzdf = 1 ! use implicit scheme
  133. ENDIF
  134. ! Force implicit schemes
  135. IF( lk_zdftke .OR. lk_zdfgls .OR. lk_zdfkpp ) nzdf = 1 ! TKE, GLS or KPP physics
  136. IF( ln_traldf_iso ) nzdf = 1 ! iso-neutral lateral physics
  137. IF( ln_traldf_hor .AND. ln_sco ) nzdf = 1 ! horizontal lateral physics in s-coordinate
  138. IF( ln_zdfexp .AND. nzdf == 1 ) CALL ctl_stop( 'tra_zdf : If using the rotation of lateral mixing operator', &
  139. & ' TKE or KPP scheme, the implicit scheme is required, set ln_zdfexp = .false.' )
  140. ! Test: esopa
  141. IF( lk_esopa ) nzdf = -1 ! All schemes used
  142. IF(lwp) THEN
  143. WRITE(numout,*)
  144. WRITE(numout,*) 'tra_zdf_init : vertical tracer physics scheme'
  145. WRITE(numout,*) '~~~~~~~~~~~'
  146. IF( nzdf == -1 ) WRITE(numout,*) ' ESOPA test All scheme used'
  147. IF( nzdf == 0 ) WRITE(numout,*) ' Explicit time-splitting scheme'
  148. IF( nzdf == 1 ) WRITE(numout,*) ' Implicit (euler backward) scheme'
  149. ENDIF
  150. !
  151. END SUBROUTINE tra_zdf_init
  152. !!==============================================================================
  153. END MODULE trazdf