tradmp.F90 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. MODULE tradmp
  2. !!======================================================================
  3. !! *** MODULE tradmp ***
  4. !! Ocean physics: internal restoring trend on active tracers (T and S)
  5. !!======================================================================
  6. !! History : OPA ! 1991-03 (O. Marti, G. Madec) Original code
  7. !! ! 1992-06 (M. Imbard) doctor norme
  8. !! ! 1996-01 (G. Madec) statement function for e3
  9. !! ! 1997-05 (G. Madec) macro-tasked on jk-slab
  10. !! ! 1998-07 (M. Imbard, G. Madec) ORCA version
  11. !! 7.0 ! 2001-02 (M. Imbard) cofdis, Original code
  12. !! 8.1 ! 2001-02 (G. Madec, E. Durand) cleaning
  13. !! NEMO 1.0 ! 2002-08 (G. Madec, E. Durand) free form + modules
  14. !! 3.2 ! 2009-08 (G. Madec, C. Talandier) DOCTOR norm for namelist parameter
  15. !! 3.3 ! 2010-06 (C. Ethe, G. Madec) merge TRA-TRC
  16. !! 3.4 ! 2011-04 (G. Madec, C. Ethe) Merge of dtatem and dtasal + suppression of CPP keys
  17. !!----------------------------------------------------------------------
  18. !!----------------------------------------------------------------------
  19. !! tra_dmp_alloc : allocate tradmp arrays
  20. !! tra_dmp : update the tracer trend with the internal damping
  21. !! tra_dmp_init : initialization, namlist read, parameters control
  22. !!----------------------------------------------------------------------
  23. USE oce ! ocean: variables
  24. USE dom_oce ! ocean: domain variables
  25. USE c1d ! 1D vertical configuration
  26. USE trd_oce ! trends: ocean variables
  27. USE trdtra ! trends manager: tracers
  28. USE zdf_oce ! ocean: vertical physics
  29. USE phycst ! physical constants
  30. USE dtatsd ! data: temperature & salinity
  31. USE zdfmxl ! vertical physics: mixed layer depth
  32. USE in_out_manager ! I/O manager
  33. USE lib_mpp ! MPP library
  34. USE prtctl ! Print control
  35. USE wrk_nemo ! Memory allocation
  36. USE timing ! Timing
  37. USE iom
  38. IMPLICIT NONE
  39. PRIVATE
  40. PUBLIC tra_dmp ! routine called by step.F90
  41. PUBLIC tra_dmp_init ! routine called by opa.F90
  42. ! !!* Namelist namtra_dmp : T & S newtonian damping *
  43. ! nn_zdmp and cn_resto are public as they are used by C1D/dyndmp.F90
  44. LOGICAL , PUBLIC :: ln_tradmp !: internal damping flag
  45. INTEGER , PUBLIC :: nn_zdmp ! = 0/1/2 flag for damping in the mixed layer
  46. CHARACTER(LEN=200) , PUBLIC :: cn_resto ! name of netcdf file containing restoration coefficient field
  47. !
  48. REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: strdmp !: damping salinity trend (psu/s)
  49. REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: ttrdmp !: damping temperature trend (Celcius/s)
  50. REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: resto !: restoring coeff. on T and S (s-1)
  51. !! * Substitutions
  52. # include "domzgr_substitute.h90"
  53. # include "vectopt_loop_substitute.h90"
  54. !!----------------------------------------------------------------------
  55. !! NEMO/OPA 3.3 , NEMO Consortium (2010)
  56. !! $Id: tradmp.F90 4990 2014-12-15 16:42:49Z timgraham $
  57. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  58. !!----------------------------------------------------------------------
  59. CONTAINS
  60. INTEGER FUNCTION tra_dmp_alloc()
  61. !!----------------------------------------------------------------------
  62. !! *** FUNCTION tra_dmp_alloc ***
  63. !!----------------------------------------------------------------------
  64. ALLOCATE( strdmp(jpi,jpj,jpk) , ttrdmp(jpi,jpj,jpk), resto(jpi,jpj,jpk), STAT= tra_dmp_alloc )
  65. !
  66. IF( lk_mpp ) CALL mpp_sum ( tra_dmp_alloc )
  67. IF( tra_dmp_alloc > 0 ) CALL ctl_warn('tra_dmp_alloc: allocation of arrays failed')
  68. !
  69. END FUNCTION tra_dmp_alloc
  70. SUBROUTINE tra_dmp( kt )
  71. !!----------------------------------------------------------------------
  72. !! *** ROUTINE tra_dmp ***
  73. !!
  74. !! ** Purpose : Compute the tracer trend due to a newtonian damping
  75. !! of the tracer field towards given data field and add it to the
  76. !! general tracer trends.
  77. !!
  78. !! ** Method : Newtonian damping towards t_dta and s_dta computed
  79. !! and add to the general tracer trends:
  80. !! ta = ta + resto * (t_dta - tb)
  81. !! sa = sa + resto * (s_dta - sb)
  82. !! The trend is computed either throughout the water column
  83. !! (nlmdmp=0) or in area of weak vertical mixing (nlmdmp=1) or
  84. !! below the well mixed layer (nlmdmp=2)
  85. !!
  86. !! ** Action : - (ta,sa) tracer trends updated with the damping trend
  87. !!----------------------------------------------------------------------
  88. !
  89. INTEGER, INTENT(in) :: kt ! ocean time-step index
  90. !!
  91. INTEGER :: ji, jj, jk ! dummy loop indices
  92. REAL(wp) :: zta, zsa ! local scalars
  93. REAL(wp), POINTER, DIMENSION(:,:,:,:) :: zts_dta
  94. !!----------------------------------------------------------------------
  95. !
  96. IF( nn_timing == 1 ) CALL timing_start( 'tra_dmp')
  97. !
  98. CALL wrk_alloc( jpi, jpj, jpk, jpts, zts_dta )
  99. !
  100. ! !== input T-S data at kt ==!
  101. CALL dta_tsd( kt, zts_dta ) ! read and interpolates T-S data at kt
  102. !
  103. SELECT CASE ( nn_zdmp ) !== type of damping ==!
  104. !
  105. CASE( 0 ) !== newtonian damping throughout the water column ==!
  106. DO jk = 1, jpkm1
  107. DO jj = 2, jpjm1
  108. DO ji = fs_2, fs_jpim1 ! vector opt.
  109. zta = resto(ji,jj,jk) * ( zts_dta(ji,jj,jk,jp_tem) - tsb(ji,jj,jk,jp_tem) )
  110. zsa = resto(ji,jj,jk) * ( zts_dta(ji,jj,jk,jp_sal) - tsb(ji,jj,jk,jp_sal) )
  111. tsa(ji,jj,jk,jp_tem) = tsa(ji,jj,jk,jp_tem) + zta
  112. tsa(ji,jj,jk,jp_sal) = tsa(ji,jj,jk,jp_sal) + zsa
  113. strdmp(ji,jj,jk) = zsa ! save the trend (used in asmtrj)
  114. ttrdmp(ji,jj,jk) = zta
  115. END DO
  116. END DO
  117. END DO
  118. !
  119. CASE ( 1 ) !== no damping in the turbocline (avt > 5 cm2/s) ==!
  120. DO jk = 1, jpkm1
  121. DO jj = 2, jpjm1
  122. DO ji = fs_2, fs_jpim1 ! vector opt.
  123. IF( avt(ji,jj,jk) <= 5.e-4_wp ) THEN
  124. zta = resto(ji,jj,jk) * ( zts_dta(ji,jj,jk,jp_tem) - tsb(ji,jj,jk,jp_tem) )
  125. zsa = resto(ji,jj,jk) * ( zts_dta(ji,jj,jk,jp_sal) - tsb(ji,jj,jk,jp_sal) )
  126. ELSE
  127. zta = 0._wp
  128. zsa = 0._wp
  129. ENDIF
  130. tsa(ji,jj,jk,jp_tem) = tsa(ji,jj,jk,jp_tem) + zta
  131. tsa(ji,jj,jk,jp_sal) = tsa(ji,jj,jk,jp_sal) + zsa
  132. strdmp(ji,jj,jk) = zsa ! save the salinity trend (used in asmtrj)
  133. ttrdmp(ji,jj,jk) = zta
  134. END DO
  135. END DO
  136. END DO
  137. !
  138. CASE ( 2 ) !== no damping in the mixed layer ==!
  139. DO jk = 1, jpkm1
  140. DO jj = 2, jpjm1
  141. DO ji = fs_2, fs_jpim1 ! vector opt.
  142. IF( fsdept(ji,jj,jk) >= hmlp (ji,jj) ) THEN
  143. zta = resto(ji,jj,jk) * ( zts_dta(ji,jj,jk,jp_tem) - tsb(ji,jj,jk,jp_tem) )
  144. zsa = resto(ji,jj,jk) * ( zts_dta(ji,jj,jk,jp_sal) - tsb(ji,jj,jk,jp_sal) )
  145. ELSE
  146. zta = 0._wp
  147. zsa = 0._wp
  148. ENDIF
  149. tsa(ji,jj,jk,jp_tem) = tsa(ji,jj,jk,jp_tem) + zta
  150. tsa(ji,jj,jk,jp_sal) = tsa(ji,jj,jk,jp_sal) + zsa
  151. strdmp(ji,jj,jk) = zsa ! save the salinity trend (used in asmtrj)
  152. ttrdmp(ji,jj,jk) = zta
  153. END DO
  154. END DO
  155. END DO
  156. !
  157. END SELECT
  158. !
  159. IF( l_trdtra ) THEN ! trend diagnostic
  160. CALL trd_tra( kt, 'TRA', jp_tem, jptra_dmp, ttrdmp )
  161. CALL trd_tra( kt, 'TRA', jp_sal, jptra_dmp, strdmp )
  162. ENDIF
  163. ! ! Control print
  164. IF(ln_ctl) CALL prt_ctl( tab3d_1=tsa(:,:,:,jp_tem), clinfo1=' dmp - Ta: ', mask1=tmask, &
  165. & tab3d_2=tsa(:,:,:,jp_sal), clinfo2= ' Sa: ', mask2=tmask, clinfo3='tra' )
  166. !
  167. CALL wrk_dealloc( jpi, jpj, jpk, jpts, zts_dta )
  168. !
  169. IF( nn_timing == 1 ) CALL timing_stop( 'tra_dmp')
  170. !
  171. END SUBROUTINE tra_dmp
  172. SUBROUTINE tra_dmp_init
  173. !!----------------------------------------------------------------------
  174. !! *** ROUTINE tra_dmp_init ***
  175. !!
  176. !! ** Purpose : Initialization for the newtonian damping
  177. !!
  178. !! ** Method : read the namtra_dmp namelist and check the parameters
  179. !!----------------------------------------------------------------------
  180. NAMELIST/namtra_dmp/ ln_tradmp, nn_zdmp, cn_resto
  181. INTEGER :: ios ! Local integer for output status of namelist read
  182. INTEGER :: imask ! File handle
  183. !!
  184. !!----------------------------------------------------------------------
  185. !
  186. REWIND( numnam_ref ) ! Namelist namtra_dmp in reference namelist : T & S relaxation
  187. READ ( numnam_ref, namtra_dmp, IOSTAT = ios, ERR = 901)
  188. 901 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namtra_dmp in reference namelist', lwp )
  189. !
  190. REWIND( numnam_cfg ) ! Namelist namtra_dmp in configuration namelist : T & S relaxation
  191. READ ( numnam_cfg, namtra_dmp, IOSTAT = ios, ERR = 902 )
  192. 902 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namtra_dmp in configuration namelist', lwp )
  193. IF(lwm) WRITE ( numond, namtra_dmp )
  194. IF(lwp) THEN !Namelist print
  195. WRITE(numout,*)
  196. WRITE(numout,*) 'tra_dmp_init : T and S newtonian relaxation'
  197. WRITE(numout,*) '~~~~~~~'
  198. WRITE(numout,*) ' Namelist namtra_dmp : set relaxation parameters'
  199. WRITE(numout,*) ' Apply relaxation or not ln_tradmp = ', ln_tradmp
  200. WRITE(numout,*) ' mixed layer damping option nn_zdmp = ', nn_zdmp
  201. WRITE(numout,*) ' Damping file name cn_resto = ', cn_resto
  202. WRITE(numout,*)
  203. ENDIF
  204. IF( ln_tradmp) THEN
  205. !
  206. !Allocate arrays
  207. IF( tra_dmp_alloc() /= 0 ) CALL ctl_stop( 'STOP', 'tra_dmp_init: unable to allocate arrays' )
  208. !Check values of nn_zdmp
  209. SELECT CASE (nn_zdmp)
  210. CASE ( 0 ) ; IF(lwp) WRITE(numout,*) ' tracer damping as specified by mask'
  211. CASE ( 1 ) ; IF(lwp) WRITE(numout,*) ' no tracer damping in the turbocline'
  212. CASE ( 2 ) ; IF(lwp) WRITE(numout,*) ' no tracer damping in the mixed layer'
  213. END SELECT
  214. !TG: Initialisation of dtatsd - Would it be better to have dmpdta routine
  215. !so can damp to something other than intitial conditions files?
  216. IF( .NOT.ln_tsd_tradmp ) THEN
  217. CALL ctl_warn( 'tra_dmp_init: read T-S data not initialized, we force ln_tsd_tradmp=T' )
  218. CALL dta_tsd_init( ld_tradmp=ln_tradmp ) ! forces the initialisation of T-S data
  219. ENDIF
  220. !initialise arrays - Are these actually used anywhere else?
  221. strdmp(:,:,:) = 0._wp
  222. ttrdmp(:,:,:) = 0._wp
  223. !Read in mask from file
  224. CALL iom_open ( cn_resto, imask)
  225. CALL iom_get ( imask, jpdom_autoglo, 'resto', resto)
  226. CALL iom_close( imask )
  227. ENDIF
  228. END SUBROUTINE tra_dmp_init
  229. END MODULE tradmp