zdfric.F90 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. MODULE zdfric
  2. !!======================================================================
  3. !! *** MODULE zdfric ***
  4. !! Ocean physics: vertical mixing coefficient compute from the local
  5. !! Richardson number dependent formulation
  6. !!======================================================================
  7. !! History : OPA ! 1987-09 (P. Andrich) Original code
  8. !! 4.0 ! 1991-11 (G. Madec)
  9. !! 7.0 ! 1996-01 (G. Madec) complete rewriting of multitasking suppression of common work arrays
  10. !! 8.0 ! 1997-06 (G. Madec) complete rewriting of zdfmix
  11. !! NEMO 1.0 ! 2002-06 (G. Madec) F90: Free form and module
  12. !! 3.3 ! 2010-10 (C. Ethe, G. Madec) reorganisation of initialisation phase
  13. !! 3.3.1! 2011-09 (P. Oddo) Mixed layer depth parameterization
  14. !!----------------------------------------------------------------------
  15. #if defined key_zdfric || defined key_esopa
  16. !!----------------------------------------------------------------------
  17. !! 'key_zdfric' Kz = f(Ri)
  18. !!----------------------------------------------------------------------
  19. !! zdf_ric : update momentum and tracer Kz from the Richardson
  20. !! number computation
  21. !! zdf_ric_init : initialization, namelist read, & parameters control
  22. !!----------------------------------------------------------------------
  23. USE oce ! ocean dynamics and tracers variables
  24. USE dom_oce ! ocean space and time domain variables
  25. USE zdf_oce ! ocean vertical physics
  26. USE in_out_manager ! I/O manager
  27. USE lbclnk ! ocean lateral boundary condition (or mpp link)
  28. USE lib_mpp ! MPP library
  29. USE wrk_nemo ! work arrays
  30. USE timing ! Timing
  31. USE lib_fortran ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined)
  32. USE eosbn2, ONLY : nn_eos
  33. IMPLICIT NONE
  34. PRIVATE
  35. PUBLIC zdf_ric ! called by step.F90
  36. PUBLIC zdf_ric_init ! called by opa.F90
  37. LOGICAL, PUBLIC, PARAMETER :: lk_zdfric = .TRUE. !: Richardson vertical mixing flag
  38. ! !!* Namelist namzdf_ric : Richardson number dependent Kz *
  39. INTEGER :: nn_ric ! coefficient of the parameterization
  40. REAL(wp) :: rn_avmri ! maximum value of the vertical eddy viscosity
  41. REAL(wp) :: rn_alp ! coefficient of the parameterization
  42. REAL(wp) :: rn_ekmfc ! Ekman Factor Coeff
  43. REAL(wp) :: rn_mldmin ! minimum mixed layer (ML) depth
  44. REAL(wp) :: rn_mldmax ! maximum mixed layer depth
  45. REAL(wp) :: rn_wtmix ! Vertical eddy Diff. in the ML
  46. REAL(wp) :: rn_wvmix ! Vertical eddy Visc. in the ML
  47. LOGICAL :: ln_mldw ! Use or not the MLD parameters
  48. REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) :: tmric !: coef. for the horizontal mean at t-point
  49. !! * Substitutions
  50. # include "domzgr_substitute.h90"
  51. !!----------------------------------------------------------------------
  52. !! NEMO/OPA 4.0 , NEMO Consortium (2011)
  53. !! $Id: zdfric.F90 4624 2014-04-28 12:09:03Z acc $
  54. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  55. !!----------------------------------------------------------------------
  56. CONTAINS
  57. INTEGER FUNCTION zdf_ric_alloc()
  58. !!----------------------------------------------------------------------
  59. !! *** FUNCTION zdf_ric_alloc ***
  60. !!----------------------------------------------------------------------
  61. ALLOCATE( tmric(jpi,jpj,jpk) , STAT= zdf_ric_alloc )
  62. !
  63. IF( lk_mpp ) CALL mpp_sum ( zdf_ric_alloc )
  64. IF( zdf_ric_alloc /= 0 ) CALL ctl_warn('zdf_ric_alloc: failed to allocate arrays')
  65. END FUNCTION zdf_ric_alloc
  66. SUBROUTINE zdf_ric( kt )
  67. !!----------------------------------------------------------------------
  68. !! *** ROUTINE zdfric ***
  69. !!
  70. !! ** Purpose : Compute the before eddy viscosity and diffusivity as
  71. !! a function of the local richardson number.
  72. !!
  73. !! ** Method : Local richardson number dependent formulation of the
  74. !! vertical eddy viscosity and diffusivity coefficients.
  75. !! The eddy coefficients are given by:
  76. !! avm = avm0 + avmb
  77. !! avt = avm0 / (1 + rn_alp*ri)
  78. !! with ri = N^2 / dz(u)**2
  79. !! = e3w**2 * rn2/[ mi( dk(ub) )+mj( dk(vb) ) ]
  80. !! avm0= rn_avmri / (1 + rn_alp*ri)**nn_ric
  81. !! Where ri is the before local Richardson number,
  82. !! rn_avmri is the maximum value reaches by avm and avt
  83. !! avmb and avtb are the background (or minimum) values
  84. !! and rn_alp, nn_ric are adjustable parameters.
  85. !! Typical values used are : avm0=1.e-2 m2/s, avmb=1.e-6 m2/s
  86. !! avtb=1.e-7 m2/s, rn_alp=5. and nn_ric=2.
  87. !! a numerical threshold is impose on the vertical shear (1.e-20)
  88. !! As second step compute Ekman depth from wind stress forcing
  89. !! and apply namelist provided vertical coeff within this depth.
  90. !! The Ekman depth is:
  91. !! Ustar = SQRT(Taum/rho0)
  92. !! ekd= rn_ekmfc * Ustar / f0
  93. !! Large et al. (1994, eq.29) suggest rn_ekmfc=0.7; however, the derivation
  94. !! of the above equation indicates the value is somewhat arbitrary; therefore
  95. !! we allow the freedom to increase or decrease this value, if the
  96. !! Ekman depth estimate appears too shallow or too deep, respectively.
  97. !! Ekd is then limited by rn_mldmin and rn_mldmax provided in the
  98. !! namelist
  99. !! N.B. the mask are required for implicit scheme, and surface
  100. !! and bottom value already set in zdfini.F90
  101. !!
  102. !! References : Pacanowski & Philander 1981, JPO, 1441-1451.
  103. !! PFJ Lermusiaux 2001.
  104. !!----------------------------------------------------------------------
  105. USE phycst, ONLY: rsmall,rau0
  106. USE sbc_oce, ONLY: taum
  107. !!
  108. INTEGER, INTENT( in ) :: kt ! ocean time-step
  109. !!
  110. INTEGER :: ji, jj, jk ! dummy loop indices
  111. REAL(wp) :: zcoef, zdku, zdkv, zri, z05alp, zflageos ! temporary scalars
  112. REAL(wp) :: zrhos, zustar
  113. REAL(wp), POINTER, DIMENSION(:,:) :: zwx, ekm_dep
  114. !!----------------------------------------------------------------------
  115. !
  116. IF( nn_timing == 1 ) CALL timing_start('zdf_ric')
  117. !
  118. CALL wrk_alloc( jpi,jpj, zwx, ekm_dep )
  119. ! ! ===============
  120. DO jk = 2, jpkm1 ! Horizontal slab
  121. ! ! ===============
  122. ! Richardson number (put in zwx(ji,jj))
  123. ! -----------------
  124. DO jj = 2, jpjm1
  125. DO ji = 2, jpim1
  126. zcoef = 0.5 / fse3w(ji,jj,jk)
  127. ! ! shear of horizontal velocity
  128. zdku = zcoef * ( ub(ji-1,jj,jk-1) + ub(ji,jj,jk-1) &
  129. & -ub(ji-1,jj,jk ) - ub(ji,jj,jk ) )
  130. zdkv = zcoef * ( vb(ji,jj-1,jk-1) + vb(ji,jj,jk-1) &
  131. & -vb(ji,jj-1,jk ) - vb(ji,jj,jk ) )
  132. ! ! richardson number (minimum value set to zero)
  133. zri = rn2(ji,jj,jk) / ( zdku*zdku + zdkv*zdkv + 1.e-20 )
  134. zwx(ji,jj) = MAX( zri, 0.e0 )
  135. END DO
  136. END DO
  137. CALL lbc_lnk( zwx, 'W', 1. ) ! Boundary condition (sign unchanged)
  138. ! Vertical eddy viscosity and diffusivity coefficients
  139. ! -------------------------------------------------------
  140. z05alp = 0.5_wp * rn_alp
  141. DO jj = 1, jpjm1 ! Eddy viscosity coefficients (avm)
  142. DO ji = 1, jpim1
  143. avmu(ji,jj,jk) = umask(ji,jj,jk) * rn_avmri / ( 1. + z05alp*( zwx(ji+1,jj)+zwx(ji,jj) ) )**nn_ric
  144. avmv(ji,jj,jk) = vmask(ji,jj,jk) * rn_avmri / ( 1. + z05alp*( zwx(ji,jj+1)+zwx(ji,jj) ) )**nn_ric
  145. END DO
  146. END DO
  147. DO jj = 2, jpjm1 ! Eddy diffusivity coefficients (avt)
  148. DO ji = 2, jpim1
  149. avt(ji,jj,jk) = tmric(ji,jj,jk) / ( 1._wp + rn_alp * zwx(ji,jj) ) &
  150. & * ( avmu(ji,jj,jk) + avmu(ji-1,jj,jk) &
  151. & + avmv(ji,jj,jk) + avmv(ji,jj-1,jk) ) &
  152. & + avtb(jk) * tmask(ji,jj,jk)
  153. END DO
  154. END DO
  155. DO jj = 2, jpjm1 ! Add the background coefficient on eddy viscosity
  156. DO ji = 2, jpim1
  157. avmu(ji,jj,jk) = avmu(ji,jj,jk) + avmb(jk) * umask(ji,jj,jk)
  158. avmv(ji,jj,jk) = avmv(ji,jj,jk) + avmb(jk) * vmask(ji,jj,jk)
  159. END DO
  160. END DO
  161. ! ! ===============
  162. END DO ! End of slab
  163. ! ! ===============
  164. !
  165. IF( ln_mldw ) THEN
  166. ! Compute Ekman depth from wind stress forcing.
  167. ! -------------------------------------------------------
  168. !SF zflageos = ( 0.5 + SIGN( 0.5, nn_eos - 1. ) ) * rau0
  169. !SF DO jj = 1, jpj
  170. !SF DO ji = 1, jpi
  171. !SF zrhos = rhop(ji,jj,1) + zflageos * ( 1. - tmask(ji,jj,1) )
  172. !SF zustar = SQRT( taum(ji,jj) / ( zrhos + rsmall ) )
  173. !SF ekm_dep(ji,jj) = rn_ekmfc * zustar / ( ABS( ff(ji,jj) ) + rsmall )
  174. !SF ekm_dep(ji,jj) = MAX(ekm_dep(ji,jj),rn_mldmin) ! Minimun allowed
  175. !SF ekm_dep(ji,jj) = MIN(ekm_dep(ji,jj),rn_mldmax) ! Maximum allowed
  176. !SF END DO
  177. !SF END DO
  178. DO jj = 1, jpj
  179. DO ji = 1, jpi
  180. zustar = SQRT( taum(ji,jj) * r1_rau0 )
  181. ekm_dep(ji,jj) = rn_ekmfc * zustar / ( ABS( ff(ji,jj) ) + rsmall )
  182. ekm_dep(ji,jj) = MAX(ekm_dep(ji,jj),rn_mldmin) ! Minimun allowed
  183. ekm_dep(ji,jj) = MIN(ekm_dep(ji,jj),rn_mldmax) ! Maximum allowed
  184. END DO
  185. END DO
  186. ! In the first model level vertical diff/visc coeff.s
  187. ! are always equal to the namelist values rn_wtmix/rn_wvmix
  188. ! -------------------------------------------------------
  189. DO jj = 1, jpj
  190. DO ji = 1, jpi
  191. avmv(ji,jj,1) = MAX( avmv(ji,jj,1), rn_wvmix )
  192. avmu(ji,jj,1) = MAX( avmu(ji,jj,1), rn_wvmix )
  193. avt( ji,jj,1) = MAX( avt(ji,jj,1), rn_wtmix )
  194. END DO
  195. END DO
  196. ! Force the vertical mixing coef within the Ekman depth
  197. ! -------------------------------------------------------
  198. DO jk = 2, jpkm1
  199. DO jj = 1, jpj
  200. DO ji = 1, jpi
  201. IF( fsdept(ji,jj,jk) < ekm_dep(ji,jj) ) THEN
  202. avmv(ji,jj,jk) = MAX( avmv(ji,jj,jk), rn_wvmix )
  203. avmu(ji,jj,jk) = MAX( avmu(ji,jj,jk), rn_wvmix )
  204. avt( ji,jj,jk) = MAX( avt(ji,jj,jk), rn_wtmix )
  205. ENDIF
  206. END DO
  207. END DO
  208. END DO
  209. DO jk = 1, jpkm1
  210. DO jj = 1, jpj
  211. DO ji = 1, jpi
  212. avmv(ji,jj,jk) = avmv(ji,jj,jk) * vmask(ji,jj,jk)
  213. avmu(ji,jj,jk) = avmu(ji,jj,jk) * umask(ji,jj,jk)
  214. avt( ji,jj,jk) = avt( ji,jj,jk) * tmask(ji,jj,jk)
  215. END DO
  216. END DO
  217. END DO
  218. ENDIF
  219. CALL lbc_lnk( avt , 'W', 1. ) ! Boundary conditions (unchanged sign)
  220. CALL lbc_lnk( avmu, 'U', 1. ) ; CALL lbc_lnk( avmv, 'V', 1. )
  221. !
  222. CALL wrk_dealloc( jpi,jpj, zwx, ekm_dep )
  223. !
  224. IF( nn_timing == 1 ) CALL timing_stop('zdf_ric')
  225. !
  226. END SUBROUTINE zdf_ric
  227. SUBROUTINE zdf_ric_init
  228. !!----------------------------------------------------------------------
  229. !! *** ROUTINE zdfbfr_init ***
  230. !!
  231. !! ** Purpose : Initialization of the vertical eddy diffusivity and
  232. !! viscosity coef. for the Richardson number dependent formulation.
  233. !!
  234. !! ** Method : Read the namzdf_ric namelist and check the parameter values
  235. !!
  236. !! ** input : Namelist namzdf_ric
  237. !!
  238. !! ** Action : increase by 1 the nstop flag is setting problem encounter
  239. !!----------------------------------------------------------------------
  240. INTEGER :: ji, jj, jk ! dummy loop indices
  241. INTEGER :: ios ! Local integer output status for namelist read
  242. !!
  243. NAMELIST/namzdf_ric/ rn_avmri, rn_alp , nn_ric , rn_ekmfc, &
  244. & rn_mldmin, rn_mldmax, rn_wtmix, rn_wvmix, ln_mldw
  245. !!----------------------------------------------------------------------
  246. !
  247. REWIND( numnam_ref ) ! Namelist namzdf_ric in reference namelist : Vertical diffusion Kz depends on Richardson number
  248. READ ( numnam_ref, namzdf_ric, IOSTAT = ios, ERR = 901)
  249. 901 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namzdf_ric in reference namelist', lwp )
  250. REWIND( numnam_cfg ) ! Namelist namzdf_ric in configuration namelist : Vertical diffusion Kz depends on Richardson number
  251. READ ( numnam_cfg, namzdf_ric, IOSTAT = ios, ERR = 902 )
  252. 902 IF( ios /= 0 ) CALL ctl_nam ( ios , 'namzdf_ric in configuration namelist', lwp )
  253. IF(lwm) WRITE ( numond, namzdf_ric )
  254. !
  255. IF(lwp) THEN ! Control print
  256. WRITE(numout,*)
  257. WRITE(numout,*) 'zdf_ric : Ri depend vertical mixing scheme'
  258. WRITE(numout,*) '~~~~~~~'
  259. WRITE(numout,*) ' Namelist namzdf_ric : set Kz(Ri) parameters'
  260. WRITE(numout,*) ' maximum vertical viscosity rn_avmri = ', rn_avmri
  261. WRITE(numout,*) ' coefficient rn_alp = ', rn_alp
  262. WRITE(numout,*) ' coefficient nn_ric = ', nn_ric
  263. WRITE(numout,*) ' Ekman Factor Coeff rn_ekmfc = ', rn_ekmfc
  264. WRITE(numout,*) ' minimum mixed layer depth rn_mldmin = ', rn_mldmin
  265. WRITE(numout,*) ' maximum mixed layer depth rn_mldmax = ', rn_mldmax
  266. WRITE(numout,*) ' Vertical eddy Diff. in the ML rn_wtmix = ', rn_wtmix
  267. WRITE(numout,*) ' Vertical eddy Visc. in the ML rn_wvmix = ', rn_wvmix
  268. WRITE(numout,*) ' Use the MLD parameterization ln_mldw = ', ln_mldw
  269. ENDIF
  270. !
  271. ! ! allocate zdfric arrays
  272. IF( zdf_ric_alloc() /= 0 ) CALL ctl_stop( 'STOP', 'zdf_ric_init : unable to allocate arrays' )
  273. !
  274. DO jk = 1, jpk ! weighting mean array tmric for 4 T-points
  275. DO jj = 2, jpj ! which accounts for coastal boundary conditions
  276. DO ji = 2, jpi
  277. tmric(ji,jj,jk) = tmask(ji,jj,jk) &
  278. & / MAX( 1., umask(ji-1,jj ,jk) + umask(ji,jj,jk) &
  279. & + vmask(ji ,jj-1,jk) + vmask(ji,jj,jk) )
  280. END DO
  281. END DO
  282. END DO
  283. tmric(:,1,:) = 0._wp
  284. !
  285. DO jk = 1, jpk ! Initialization of vertical eddy coef. to the background value
  286. avt (:,:,jk) = avtb(jk) * tmask(:,:,jk)
  287. avmu(:,:,jk) = avmb(jk) * umask(:,:,jk)
  288. avmv(:,:,jk) = avmb(jk) * vmask(:,:,jk)
  289. END DO
  290. !
  291. END SUBROUTINE zdf_ric_init
  292. #else
  293. !!----------------------------------------------------------------------
  294. !! Dummy module : NO Richardson dependent vertical mixing
  295. !!----------------------------------------------------------------------
  296. LOGICAL, PUBLIC, PARAMETER :: lk_zdfric = .FALSE. !: Richardson mixing flag
  297. CONTAINS
  298. SUBROUTINE zdf_ric_init ! Dummy routine
  299. END SUBROUTINE zdf_ric_init
  300. SUBROUTINE zdf_ric( kt ) ! Dummy routine
  301. WRITE(*,*) 'zdf_ric: You should not have seen this print! error?', kt
  302. END SUBROUTINE zdf_ric
  303. #endif
  304. !!======================================================================
  305. END MODULE zdfric