New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
zdftke.F90 in branches/2017/dev_r7881_HPC09_ZDF/NEMOGCM/NEMO/OPA_SRC/ZDF – NEMO

source: branches/2017/dev_r7881_HPC09_ZDF/NEMOGCM/NEMO/OPA_SRC/ZDF/zdftke.F90 @ 8093

Last change on this file since 8093 was 8093, checked in by gm, 7 years ago

#1880 (HPC-09) - step-6: prepare some forthcoming evolutions (ZDF modules mainly)

  • Property svn:keywords set to Id
File size: 43.0 KB
Line 
1MODULE zdftke
2   !!======================================================================
3   !!                       ***  MODULE  zdftke  ***
4   !! Ocean physics:  vertical mixing coefficient computed from the tke
5   !!                 turbulent closure parameterization
6   !!=====================================================================
7   !! History :  OPA  !  1991-03  (b. blanke)  Original code
8   !!            7.0  !  1991-11  (G. Madec)   bug fix
9   !!            7.1  !  1992-10  (G. Madec)   new mixing length and eav
10   !!            7.2  !  1993-03  (M. Guyon)   symetrical conditions
11   !!            7.3  !  1994-08  (G. Madec, M. Imbard)  nn_pdl flag
12   !!            7.5  !  1996-01  (G. Madec)   s-coordinates
13   !!            8.0  !  1997-07  (G. Madec)   lbc
14   !!            8.1  !  1999-01  (E. Stretta) new option for the mixing length
15   !!  NEMO      1.0  !  2002-06  (G. Madec) add tke_init routine
16   !!             -   !  2004-10  (C. Ethe )  1D configuration
17   !!            2.0  !  2006-07  (S. Masson)  distributed restart using iom
18   !!            3.0  !  2008-05  (C. Ethe,  G.Madec) : update TKE physics:
19   !!                 !           - tke penetration (wind steering)
20   !!                 !           - suface condition for tke & mixing length
21   !!                 !           - Langmuir cells
22   !!             -   !  2008-05  (J.-M. Molines, G. Madec)  2D form of avtb
23   !!             -   !  2008-06  (G. Madec)  style + DOCTOR name for namelist parameters
24   !!             -   !  2008-12  (G. Reffray) stable discretization of the production term
25   !!            3.2  !  2009-06  (G. Madec, S. Masson) TKE restart compatible with key_cpl
26   !!                 !                                + cleaning of the parameters + bugs correction
27   !!            3.3  !  2010-10  (C. Ethe, G. Madec) reorganisation of initialisation phase
28   !!            3.6  !  2014-11  (P. Mathiot) add ice shelf capability
29   !!            4.0  !  2017-04  (G. Madec)  remove CPP ddm key & avm at t-point only
30   !!----------------------------------------------------------------------
31
32   !!----------------------------------------------------------------------
33   !!   zdf_tke       : update momentum and tracer Kz from a tke scheme
34   !!   tke_tke       : tke time stepping: update tke at now time step (en)
35   !!   tke_avn       : compute mixing length scale and deduce avm and avt
36   !!   zdf_tke_init  : initialization, namelist read, and parameters control
37   !!   tke_rst       : read/write tke restart in ocean restart file
38   !!----------------------------------------------------------------------
39   USE oce            ! ocean: dynamics and active tracers variables
40   USE phycst         ! physical constants
41   USE dom_oce        ! domain: ocean
42   USE domvvl         ! domain: variable volume layer
43   USE sbc_oce        ! surface boundary condition: ocean
44   USE zdf_oce        ! vertical physics: ocean variables
45!!gm new
46   USE zdfdrg         ! vertical physics: top/bottom drag coef.
47!!gm
48   USE zdfmxl         ! vertical physics: mixed layer
49#if defined key_agrif
50   USE agrif_opa_interp
51   USE agrif_opa_update
52#endif
53   !
54   USE in_out_manager ! I/O manager
55   USE iom            ! I/O manager library
56   USE lib_mpp        ! MPP library
57   USE lbclnk         ! ocean lateral boundary conditions (or mpp link)
58   USE prtctl         ! Print control
59   USE wrk_nemo       ! work arrays
60   USE timing         ! Timing
61   USE lib_fortran    ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 
62
63   IMPLICIT NONE
64   PRIVATE
65
66   PUBLIC   zdf_tke        ! routine called in step module
67   PUBLIC   zdf_tke_init   ! routine called in opa module
68   PUBLIC   tke_rst        ! routine called in step module
69
70   !                      !!** Namelist  namzdf_tke  **
71   LOGICAL  ::   ln_mxl0   ! mixing length scale surface value as function of wind stress or not
72   INTEGER  ::   nn_mxl    ! type of mixing length (=0/1/2/3)
73   REAL(wp) ::   rn_mxl0   ! surface  min value of mixing length (kappa*z_o=0.4*0.1 m)  [m]
74   INTEGER  ::   nn_pdl    ! Prandtl number or not (ratio avt/avm) (=0/1)
75   REAL(wp) ::   rn_ediff  ! coefficient for avt: avt=rn_ediff*mxl*sqrt(e)
76   REAL(wp) ::   rn_ediss  ! coefficient of the Kolmogoroff dissipation
77   REAL(wp) ::   rn_ebb    ! coefficient of the surface input of tke
78   REAL(wp) ::   rn_emin   ! minimum value of tke           [m2/s2]
79   REAL(wp) ::   rn_emin0  ! surface minimum value of tke   [m2/s2]
80   REAL(wp) ::   rn_bshear ! background shear (>0) currently a numerical threshold (do not change it)
81   INTEGER  ::   nn_etau   ! type of depth penetration of surface tke (=0/1/2/3)
82   INTEGER  ::   nn_htau   ! type of tke profile of penetration (=0/1)
83   REAL(wp) ::   rn_efr    ! fraction of TKE surface value which penetrates in the ocean
84   LOGICAL  ::   ln_lc     ! Langmuir cells (LC) as a source term of TKE or not
85   REAL(wp) ::   rn_lc     ! coef to compute vertical velocity of Langmuir cells
86
87   REAL(wp) ::   ri_cri    ! critic Richardson number (deduced from rn_ediff and rn_ediss values)
88   REAL(wp) ::   rmxl_min  ! minimum mixing length value (deduced from rn_ediff and rn_emin values)  [m]
89   REAL(wp) ::   rhftau_add = 1.e-3_wp     ! add offset   applied to HF part of taum  (nn_etau=3)
90   REAL(wp) ::   rhftau_scl = 1.0_wp       ! scale factor applied to HF part of taum  (nn_etau=3)
91
92   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   htau    ! depth of tke penetration (nn_htau)
93   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   dissl   ! now mixing lenght of dissipation
94   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   apdlr   ! now mixing lenght of dissipation
95
96   !! * Substitutions
97#  include "vectopt_loop_substitute.h90"
98   !!----------------------------------------------------------------------
99   !! NEMO/OPA 3.7 , NEMO Consortium (2015)
100   !! $Id$
101   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
102   !!----------------------------------------------------------------------
103CONTAINS
104
105   INTEGER FUNCTION zdf_tke_alloc()
106      !!----------------------------------------------------------------------
107      !!                ***  FUNCTION zdf_tke_alloc  ***
108      !!----------------------------------------------------------------------
109      ALLOCATE( htau(jpi,jpj) , dissl(jpi,jpj,jpk) , apdlr(jpi,jpj,jpk) ,   STAT= zdf_tke_alloc )
110         !
111      IF( lk_mpp             )   CALL mpp_sum ( zdf_tke_alloc )
112      IF( zdf_tke_alloc /= 0 )   CALL ctl_warn('zdf_tke_alloc: failed to allocate arrays')
113      !
114   END FUNCTION zdf_tke_alloc
115
116
117   SUBROUTINE zdf_tke( kt, p_sh2, p_avm, p_avt )
118      !!----------------------------------------------------------------------
119      !!                   ***  ROUTINE zdf_tke  ***
120      !!
121      !! ** Purpose :   Compute the vertical eddy viscosity and diffusivity
122      !!              coefficients using a turbulent closure scheme (TKE).
123      !!
124      !! ** Method  :   The time evolution of the turbulent kinetic energy (tke)
125      !!              is computed from a prognostic equation :
126      !!         d(en)/dt = avm (d(u)/dz)**2             ! shear production
127      !!                  + d( avm d(en)/dz )/dz         ! diffusion of tke
128      !!                  + avt N^2                      ! stratif. destruc.
129      !!                  - rn_ediss / emxl en**(2/3)    ! Kolmogoroff dissipation
130      !!      with the boundary conditions:
131      !!         surface: en = max( rn_emin0, rn_ebb * taum )
132      !!         bottom : en = rn_emin
133      !!      The associated critical Richardson number is: ri_cri = 2/(2+rn_ediss/rn_ediff)
134      !!
135      !!        The now Turbulent kinetic energy is computed using the following
136      !!      time stepping: implicit for vertical diffusion term, linearized semi
137      !!      implicit for kolmogoroff dissipation term, and explicit forward for
138      !!      both buoyancy and shear production terms. Therefore a tridiagonal
139      !!      linear system is solved. Note that buoyancy and shear terms are
140      !!      discretized in a energy conserving form (Bruchard 2002).
141      !!
142      !!        The dissipative and mixing length scale are computed from en and
143      !!      the stratification (see tke_avn)
144      !!
145      !!        The now vertical eddy vicosity and diffusivity coefficients are
146      !!      given by:
147      !!              avm = max( avtb, rn_ediff * zmxlm * en^1/2 )
148      !!              avt = max( avmb, pdl * avm                 ) 
149      !!              eav = max( avmb, avm )
150      !!      where pdl, the inverse of the Prandtl number is 1 if nn_pdl=0 and
151      !!      given by an empirical funtion of the localRichardson number if nn_pdl=1
152      !!
153      !! ** Action  :   compute en (now turbulent kinetic energy)
154      !!                update avt, avm (before vertical eddy coef.)
155      !!
156      !! References : Gaspar et al., JGR, 1990,
157      !!              Blanke and Delecluse, JPO, 1991
158      !!              Mellor and Blumberg, JPO 2004
159      !!              Axell, JGR, 2002
160      !!              Bruchard OM 2002
161      !!----------------------------------------------------------------------
162      INTEGER                    , INTENT(in   ) ::   kt             ! ocean time step
163      REAL(wp), DIMENSION(:,:,:), INTENT(in   ) ::   p_sh2          ! shear production term
164      REAL(wp), DIMENSION(:,:,:) , INTENT(inout) ::   p_avm, p_avt   !  momentum and tracer Kz (w-points)
165      !!----------------------------------------------------------------------
166      !
167#if defined key_agrif 
168      ! interpolation parent grid => child grid for avm_k ( ex : at west border: update column 1 and 2)
169      IF( .NOT.Agrif_Root() )   CALL Agrif_Tke
170#endif
171      !
172      CALL tke_tke( gdepw_n, e3t_n, e3w_n, p_sh2, p_avm, p_avt )   ! now tke (en)
173      !
174      CALL tke_avn( gdepw_n, e3t_n, e3w_n,        p_avm, p_avt )   ! now avt, avm, dissl
175      !
176#if defined key_agrif
177      ! Update child grid f => parent grid
178      IF( .NOT.Agrif_Root() )   CALL Agrif_Update_Tke( kt )      ! children only
179#endif     
180      !
181  END SUBROUTINE zdf_tke
182
183
184   SUBROUTINE tke_tke( pdepw, p_e3t, p_e3w, p_sh2    &
185      &                            , p_avm, p_avt )
186      !!----------------------------------------------------------------------
187      !!                   ***  ROUTINE tke_tke  ***
188      !!
189      !! ** Purpose :   Compute the now Turbulente Kinetic Energy (TKE)
190      !!
191      !! ** Method  : - TKE surface boundary condition
192      !!              - source term due to Langmuir cells (Axell JGR 2002) (ln_lc=T)
193      !!              - source term due to shear (= Kz dz[Ub] * dz[Un] )
194      !!              - Now TKE : resolution of the TKE equation by inverting
195      !!                a tridiagonal linear system by a "methode de chasse"
196      !!              - increase TKE due to surface and internal wave breaking
197      !!
198      !! ** Action  : - en : now turbulent kinetic energy)
199      !! ---------------------------------------------------------------------
200      REAL(wp), DIMENSION(:,:,:) , INTENT(in   ) ::   pdepw          ! depth of w-points
201      REAL(wp), DIMENSION(:,:,:) , INTENT(in   ) ::   p_e3t, p_e3w   ! level thickness (t- & w-points)
202      REAL(wp), DIMENSION(:,:,:) , INTENT(in   ) ::   p_sh2          ! shear production term
203      REAL(wp), DIMENSION(:,:,:) , INTENT(in   ) ::   p_avm, p_avt   ! vertical eddy viscosity & diffusivity (w-points)
204      !
205      INTEGER ::   ji, jj, jk              ! dummy loop arguments
206!!bfr      REAL(wp) ::   zebot, zmshu, zmskv      ! local scalars
207      REAL(wp) ::   zrhoa  = 1.22            ! Air density kg/m3
208      REAL(wp) ::   zcdrag = 1.5e-3          ! drag coefficient
209      REAL(wp) ::   zbbrau, zri              ! local scalars
210      REAL(wp) ::   zfact1, zfact2, zfact3   !   -         -
211      REAL(wp) ::   ztx2  , zty2  , zcof     !   -         -
212      REAL(wp) ::   ztau  , zdif             !   -         -
213      REAL(wp) ::   zus   , zwlc  , zind     !   -         -
214      REAL(wp) ::   zzd_up, zzd_lw           !   -         -
215      INTEGER , DIMENSION(jpi,jpj)     ::   imlc
216      REAL(wp), DIMENSION(jpi,jpj)     ::   zhlc
217      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zpelc, zdiag, zd_up, zd_lw
218      !!--------------------------------------------------------------------
219      !
220      IF( nn_timing == 1 )  CALL timing_start('tke_tke')
221      !
222      zbbrau = rn_ebb / rau0       ! Local constant initialisation
223      zfact1 = -.5_wp * rdt 
224      zfact2 = 1.5_wp * rdt * rn_ediss
225      zfact3 = 0.5_wp       * rn_ediss
226      !
227      !
228      !                     !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
229      !                     !  Surface boundary condition on tke
230      !                     !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
231      IF ( ln_isfcav ) THEN
232         DO jj = 2, jpjm1            ! en(mikt(ji,jj))   = rn_emin
233            DO ji = fs_2, fs_jpim1   ! vector opt.
234               en(ji,jj,mikt(ji,jj)) = rn_emin * tmask(ji,jj,1)
235            END DO
236         END DO
237      END IF
238      DO jj = 2, jpjm1            ! en(1)   = rn_ebb taum / rau0  (min value rn_emin0)
239         DO ji = fs_2, fs_jpim1   ! vector opt.
240            en(ji,jj,1) = MAX( rn_emin0, zbbrau * taum(ji,jj) ) * tmask(ji,jj,1)
241         END DO
242      END DO
243     
244!!bfr   - start commented area
245      !                     !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
246      !                     !  Bottom boundary condition on tke
247      !                     !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
248      !
249      !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
250      ! Tests to date have found the bottom boundary condition on tke to have very little effect.
251      ! The condition is coded here for completion but commented out until there is proof that the
252      ! computational cost is justified
253      !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
254      !                     en(bot)   = (rn_ebb0/rau0)*0.5*sqrt(u_botfr^2+v_botfr^2) (min value rn_emin)
255!!gm old
256!!    DO jj = 2, jpjm1
257!!       DO ji = fs_2, fs_jpim1   ! vector opt.
258!!          ztx2 = bfrua(ji-1,jj) * ub(ji-1,jj,mbku(ji-1,jj)) + &
259!!                 bfrua(ji  ,jj) * ub(ji  ,jj,mbku(ji  ,jj) )
260!!          zty2 = bfrva(ji,jj  ) * vb(ji,jj  ,mbkv(ji,jj  )) + &
261!!                 bfrva(ji,jj-1) * vb(ji,jj-1,mbkv(ji,jj-1) )
262!!          zebot = 0.001875_wp * SQRT( ztx2 * ztx2 + zty2 * zty2 )   !  where 0.001875 = (rn_ebb0/rau0) * 0.5 = 3.75*0.5/1000.
263!!          en(ji,jj,mbkt(ji,jj)+1) = MAX( zebot, rn_emin ) * ssmask(ji,jj)
264!!       END DO
265!!    END DO
266!!gm new
267!!
268!!    ====>>>>  add below an wet-only calculation of u and v at t-point like in zdfsh2:
269!!                   zmsku = ( 2. - umask(ji-1,jj,mbkt(ji,jj)) * umask(ji,jj,mbkt(ji,jj)) )
270!!                   zmskv = ( 2. - vmask(ji,jj-1,mbkt(ji,jj)) * vmask(ji,jj,mbkt(ji,jj)) )
271!!
272!!
273!!    DO jj = 2, jpjm1
274!!       DO ji = fs_2, fs_jpim1   ! vector opt.
275!!          zmsku = ( 2. - umask(ji-1,jj,mbkt(ji,jj)) * umask(ji,jj,mbkt(ji,jj)) )
276!!          zmskv = ( 2. - vmask(ji,jj-1,mbkt(ji,jj)) * vmask(ji,jj,mbkt(ji,jj)) )
277!!          !                             ! where 0.001875 = (rn_ebb0/rau0) * 0.5 = 3.75*0.5/1000. (CAUTION CdU<0)
278!!          zebot = - 0.001875_wp * rCdU_bot(ji,jj) * SQRT(  ( zmsku*( ub(ji,jj,mbkt(ji,jj))+ub(ji-1,jj,mbkt(ji,jj)) ) )**2
279!!             &                                           + ( zmskv*( vb(ji,jj,mbkt(ji,jj))+vb(ji,jj-1,mbkt(ji,jj)) ) )**2  )
280!!          en(ji,jj,mbkt(ji,jj)+1) = MAX( zebot, rn_emin ) * ssmask(ji,jj)
281!!       END DO
282!!    END DO
283!!    IF( ln_isfcav ) THEN       !top friction
284!!       DO jj = 2, jpjm1
285!!          DO ji = fs_2, fs_jpim1   ! vector opt.
286!!             zmsku = ( 2. - umask(ji-1,jj,mikt(ji,jj)) * umask(ji,jj,mikt(ji,jj)) )
287!!             zmskv = ( 2. - vmask(ji,jj-1,mikt(ji,jj)) * vmask(ji,jj,mikt(ji,jj)) )
288!!             !                             ! where 0.001875 = (rn_ebb0/rau0) * 0.5 = 3.75*0.5/1000.  (CAUTION CdU<0)
289!!             zebot = - 0.001875_wp * rCdU_top(ji,jj) * SQRT(  ( zmsku*( ub(ji,jj,mikt(ji,jj))+ub(ji-1,jj,mikt(ji,jj)) ) )**2
290!!                &                                           + ( zmskv*( vb(ji,jj,mikt(ji,jj))+vb(ji,jj-1,mikt(ji,jj)) ) )**2  )
291!!             en(ji,jj,mikt(ji,jj)+1) = MAX( zebot, rn_emin ) * (1._wp - tmask(ji,jj,1))   ! masked at ocean surface
292!!          END DO
293!!       END DO
294!!    ENDIF
295!!
296!!bfr   - end commented area
297      !
298      !                     !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
299      IF( ln_lc ) THEN      !  Langmuir circulation source term added to tke   !   (Axell JGR 2002)
300         !                  !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
301         !
302         !                        !* total energy produce by LC : cumulative sum over jk
303         zpelc(:,:,1) =  MAX( rn2b(:,:,1), 0._wp ) * pdepw(:,:,1) * p_e3w(:,:,1)
304         DO jk = 2, jpk
305            zpelc(:,:,jk)  = zpelc(:,:,jk-1) + MAX( rn2b(:,:,jk), 0._wp ) * pdepw(:,:,jk) * p_e3w(:,:,jk)
306         END DO
307         !                        !* finite Langmuir Circulation depth
308         zcof = 0.5 * 0.016 * 0.016 / ( zrhoa * zcdrag )
309         imlc(:,:) = mbkt(:,:) + 1       ! Initialization to the number of w ocean point (=2 over land)
310         DO jk = jpkm1, 2, -1
311            DO jj = 1, jpj               ! Last w-level at which zpelc>=0.5*us*us
312               DO ji = 1, jpi            !      with us=0.016*wind(starting from jpk-1)
313                  zus  = zcof * taum(ji,jj)
314                  IF( zpelc(ji,jj,jk) > zus )   imlc(ji,jj) = jk
315               END DO
316            END DO
317         END DO
318         !                               ! finite LC depth
319         DO jj = 1, jpj 
320            DO ji = 1, jpi
321               zhlc(ji,jj) = pdepw(ji,jj,imlc(ji,jj))
322            END DO
323         END DO
324         zcof = 0.016 / SQRT( zrhoa * zcdrag )
325         DO jk = 2, jpkm1         !* TKE Langmuir circulation source term added to en
326            DO jj = 2, jpjm1
327               DO ji = fs_2, fs_jpim1   ! vector opt.
328                  zus  = zcof * SQRT( taum(ji,jj) )           ! Stokes drift
329                  !                                           ! vertical velocity due to LC
330                  zind = 0.5 - SIGN( 0.5, pdepw(ji,jj,jk) - zhlc(ji,jj) )
331                  zwlc = zind * rn_lc * zus * SIN( rpi * pdepw(ji,jj,jk) / zhlc(ji,jj) )
332                  !                                           ! TKE Langmuir circulation source term
333                  en(ji,jj,jk) = en(ji,jj,jk) + rdt * MAX(0.,1._wp - 2.*fr_i(ji,jj) ) * ( zwlc * zwlc * zwlc )   &
334                     &                              / zhlc(ji,jj) * wmask(ji,jj,jk) * tmask(ji,jj,1)
335               END DO
336            END DO
337         END DO
338         !
339      ENDIF
340      !
341      !                     !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
342      !                     !  Now Turbulent kinetic energy (output in en)
343      !                     !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
344      !                     ! Resolution of a tridiagonal linear system by a "methode de chasse"
345      !                     ! computation from level 2 to jpkm1  (e(1) already computed and e(jpk)=0 ).
346      !                     ! zdiag : diagonal zd_up : upper diagonal zd_lw : lower diagonal
347      !
348      IF( nn_pdl == 1 ) THEN      !* Prandtl number = F( Ri )
349         DO jk = 2, jpkm1
350            DO jj = 2, jpjm1
351               DO ji = 2, jpim1
352                  !                             ! local Richardson number
353                  zri = MAX( rn2b(ji,jj,jk), 0._wp ) * p_avm(ji,jj,jk) / ( p_sh2(ji,jj,jk) + rn_bshear )
354                  !                             ! inverse of Prandtl number
355                  apdlr(ji,jj,jk) = MAX(  0.1_wp,  ri_cri / MAX( ri_cri , zri )  )
356               END DO
357            END DO
358         END DO
359      ENDIF
360      !         
361      DO jk = 2, jpkm1           !* Matrix and right hand side in en
362         DO jj = 2, jpjm1
363            DO ji = fs_2, fs_jpim1   ! vector opt.
364               zcof   = zfact1 * tmask(ji,jj,jk)
365               !                                   ! A minimum of 2.e-5 m2/s is imposed on TKE vertical
366               !                                   ! eddy coefficient (ensure numerical stability)
367               zzd_up = zcof * MAX(  p_avm(ji,jj,jk+1) + p_avm(ji,jj,jk  ) , 2.e-5_wp  )   &  ! upper diagonal
368                  &          /    (  p_e3t(ji,jj,jk  ) * p_e3w(ji,jj,jk  )  )
369               zzd_lw = zcof * MAX(  p_avm(ji,jj,jk  ) + p_avm(ji,jj,jk-1) , 2.e-5_wp  )   &  ! lower diagonal
370                  &          /    (  p_e3t(ji,jj,jk-1) * p_e3w(ji,jj,jk  )  )
371               !
372               zd_up(ji,jj,jk) = zzd_up            ! Matrix (zdiag, zd_up, zd_lw)
373               zd_lw(ji,jj,jk) = zzd_lw
374               zdiag(ji,jj,jk) = 1._wp - zzd_lw - zzd_up + zfact2 * dissl(ji,jj,jk) * wmask(ji,jj,jk)
375               !
376               !                                   ! right hand side in en
377               en(ji,jj,jk) = en(ji,jj,jk) + rdt * (  p_sh2(ji,jj,jk)                          &   ! shear
378                  &                                 - p_avt(ji,jj,jk) * rn2(ji,jj,jk)          &   ! stratification
379                  &                                 + zfact3 * dissl(ji,jj,jk) * en(ji,jj,jk)  &   ! dissipation
380                  &                                ) * wmask(ji,jj,jk)
381            END DO
382         END DO
383      END DO
384      !                          !* Matrix inversion from level 2 (tke prescribed at level 1)
385      DO jk = 3, jpkm1                             ! First recurrence : Dk = Dk - Lk * Uk-1 / Dk-1
386         DO jj = 2, jpjm1
387            DO ji = fs_2, fs_jpim1    ! vector opt.
388               zdiag(ji,jj,jk) = zdiag(ji,jj,jk) - zd_lw(ji,jj,jk) * zd_up(ji,jj,jk-1) / zdiag(ji,jj,jk-1)
389            END DO
390         END DO
391      END DO
392      DO jj = 2, jpjm1                             ! Second recurrence : Lk = RHSk - Lk / Dk-1 * Lk-1
393         DO ji = fs_2, fs_jpim1   ! vector opt.
394            zd_lw(ji,jj,2) = en(ji,jj,2) - zd_lw(ji,jj,2) * en(ji,jj,1)    ! Surface boudary conditions on tke
395         END DO
396      END DO
397      DO jk = 3, jpkm1
398         DO jj = 2, jpjm1
399            DO ji = fs_2, fs_jpim1    ! vector opt.
400               zd_lw(ji,jj,jk) = en(ji,jj,jk) - zd_lw(ji,jj,jk) / zdiag(ji,jj,jk-1) *zd_lw(ji,jj,jk-1)
401            END DO
402         END DO
403      END DO
404      DO jj = 2, jpjm1                             ! thrid recurrence : Ek = ( Lk - Uk * Ek+1 ) / Dk
405         DO ji = fs_2, fs_jpim1   ! vector opt.
406            en(ji,jj,jpkm1) = zd_lw(ji,jj,jpkm1) / zdiag(ji,jj,jpkm1)
407         END DO
408      END DO
409      DO jk = jpk-2, 2, -1
410         DO jj = 2, jpjm1
411            DO ji = fs_2, fs_jpim1    ! vector opt.
412               en(ji,jj,jk) = ( zd_lw(ji,jj,jk) - zd_up(ji,jj,jk) * en(ji,jj,jk+1) ) / zdiag(ji,jj,jk)
413            END DO
414         END DO
415      END DO
416      DO jk = 2, jpkm1                             ! set the minimum value of tke
417         DO jj = 2, jpjm1
418            DO ji = fs_2, fs_jpim1   ! vector opt.
419               en(ji,jj,jk) = MAX( en(ji,jj,jk), rn_emin ) * wmask(ji,jj,jk)
420            END DO
421         END DO
422      END DO
423
424      !                            !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
425      !                            !  TKE due to surface and internal wave breaking
426      !                            !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
427!!gm BUG : in the exp  remove the depth of ssh !!!
428     
429     
430      IF( nn_etau == 1 ) THEN           !* penetration below the mixed layer (rn_efr fraction)
431         DO jk = 2, jpkm1
432            DO jj = 2, jpjm1
433               DO ji = fs_2, fs_jpim1   ! vector opt.
434                  en(ji,jj,jk) = en(ji,jj,jk) + rn_efr * en(ji,jj,1) * EXP( -pdepw(ji,jj,jk) / htau(ji,jj) )   &
435                     &                                 * MAX(0.,1._wp - 2.*fr_i(ji,jj) )  * wmask(ji,jj,jk) * tmask(ji,jj,1)
436               END DO
437            END DO
438         END DO
439      ELSEIF( nn_etau == 2 ) THEN       !* act only at the base of the mixed layer (jk=nmln)  (rn_efr fraction)
440         DO jj = 2, jpjm1
441            DO ji = fs_2, fs_jpim1   ! vector opt.
442               jk = nmln(ji,jj)
443               en(ji,jj,jk) = en(ji,jj,jk) + rn_efr * en(ji,jj,1) * EXP( -pdepw(ji,jj,jk) / htau(ji,jj) )   &
444                  &                                 * MAX(0.,1._wp - 2.*fr_i(ji,jj) )  * wmask(ji,jj,jk) * tmask(ji,jj,1)
445            END DO
446         END DO
447      ELSEIF( nn_etau == 3 ) THEN       !* penetration belox the mixed layer (HF variability)
448         DO jk = 2, jpkm1
449            DO jj = 2, jpjm1
450               DO ji = fs_2, fs_jpim1   ! vector opt.
451                  ztx2 = utau(ji-1,jj  ) + utau(ji,jj)
452                  zty2 = vtau(ji  ,jj-1) + vtau(ji,jj)
453                  ztau = 0.5_wp * SQRT( ztx2 * ztx2 + zty2 * zty2 ) * tmask(ji,jj,1)    ! module of the mean stress
454                  zdif = taum(ji,jj) - ztau                            ! mean of modulus - modulus of the mean
455                  zdif = rhftau_scl * MAX( 0._wp, zdif + rhftau_add )  ! apply some modifications...
456                  en(ji,jj,jk) = en(ji,jj,jk) + zbbrau * zdif * EXP( -pdepw(ji,jj,jk) / htau(ji,jj) )   &
457                     &                        * MAX(0.,1._wp - 2.*fr_i(ji,jj) ) * wmask(ji,jj,jk) * tmask(ji,jj,1)
458               END DO
459            END DO
460         END DO
461      ENDIF
462      !
463      IF( nn_timing == 1 )  CALL timing_stop('tke_tke')
464      !
465   END SUBROUTINE tke_tke
466
467
468   SUBROUTINE tke_avn( pdepw, p_e3t, p_e3w, p_avm, p_avt )
469      !!----------------------------------------------------------------------
470      !!                   ***  ROUTINE tke_avn  ***
471      !!
472      !! ** Purpose :   Compute the vertical eddy viscosity and diffusivity
473      !!
474      !! ** Method  :   At this stage, en, the now TKE, is known (computed in
475      !!              the tke_tke routine). First, the now mixing lenth is
476      !!      computed from en and the strafification (N^2), then the mixings
477      !!      coefficients are computed.
478      !!              - Mixing length : a first evaluation of the mixing lengh
479      !!      scales is:
480      !!                      mxl = sqrt(2*en) / N 
481      !!      where N is the brunt-vaisala frequency, with a minimum value set
482      !!      to rmxl_min (rn_mxl0) in the interior (surface) ocean.
483      !!        The mixing and dissipative length scale are bound as follow :
484      !!         nn_mxl=0 : mxl bounded by the distance to surface and bottom.
485      !!                        zmxld = zmxlm = mxl
486      !!         nn_mxl=1 : mxl bounded by the e3w and zmxld = zmxlm = mxl
487      !!         nn_mxl=2 : mxl bounded such that the vertical derivative of mxl is
488      !!                    less than 1 (|d/dz(mxl)|<1) and zmxld = zmxlm = mxl
489      !!         nn_mxl=3 : mxl is bounded from the surface to the bottom usings
490      !!                    |d/dz(xml)|<1 to obtain lup, and from the bottom to
491      !!                    the surface to obtain ldown. the resulting length
492      !!                    scales are:
493      !!                        zmxld = sqrt( lup * ldown )
494      !!                        zmxlm = min ( lup , ldown )
495      !!              - Vertical eddy viscosity and diffusivity:
496      !!                      avm = max( avtb, rn_ediff * zmxlm * en^1/2 )
497      !!                      avt = max( avmb, pdlr * avm ) 
498      !!      with pdlr=1 if nn_pdl=0, pdlr=1/pdl=F(Ri) otherwise.
499      !!
500      !! ** Action  : - avt, avm : now vertical eddy diffusivity and viscosity (w-point)
501      !!----------------------------------------------------------------------
502      REAL(wp), DIMENSION(:,:,:), INTENT(in   ) ::   pdepw          ! depth (w-points)
503      REAL(wp), DIMENSION(:,:,:), INTENT(in   ) ::   p_e3t, p_e3w   ! level thickness (t- & w-points)
504      REAL(wp), DIMENSION(:,:,:), INTENT(  out) ::   p_avm, p_avt   ! vertical eddy viscosity & diffusivity (w-points)
505      !
506      INTEGER  ::   ji, jj, jk   ! dummy loop indices
507      REAL(wp) ::   zrn2, zraug, zcoef, zav   ! local scalars
508      REAL(wp) ::   zdku,   zdkv, zsqen       !   -      -
509      REAL(wp) ::   zemxl, zemlm, zemlp       !   -      -
510      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zmxlm, zmxld
511      !!--------------------------------------------------------------------
512      !
513      IF( nn_timing == 1 )  CALL timing_start('tke_avn')
514
515      !                     !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
516      !                     !  Mixing length
517      !                     !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
518      !
519      !                     !* Buoyancy length scale: l=sqrt(2*e/n**2)
520      !
521      ! initialisation of interior minimum value (avoid a 2d loop with mikt)
522      zmxlm(:,:,:)  = rmxl_min   
523      zmxld(:,:,:)  = rmxl_min
524      !
525      IF( ln_mxl0 ) THEN            ! surface mixing length = F(stress) : l=vkarmn*2.e5*taum/(rau0*g)
526         zraug = vkarmn * 2.e5_wp / ( rau0 * grav )
527         DO jj = 2, jpjm1
528            DO ji = fs_2, fs_jpim1
529               zmxlm(ji,jj,1) = MAX( rn_mxl0, zraug * taum(ji,jj) * tmask(ji,jj,1) )
530            END DO
531         END DO
532      ELSE
533         zmxlm(:,:,1) = rn_mxl0
534      ENDIF
535      !
536      DO jk = 2, jpkm1              ! interior value : l=sqrt(2*e/n^2)
537         DO jj = 2, jpjm1
538            DO ji = fs_2, fs_jpim1   ! vector opt.
539               zrn2 = MAX( rn2(ji,jj,jk), rsmall )
540               zmxlm(ji,jj,jk) = MAX(  rmxl_min,  SQRT( 2._wp * en(ji,jj,jk) / zrn2 )  )
541            END DO
542         END DO
543      END DO
544      !
545      !                     !* Physical limits for the mixing length
546      !
547      zmxld(:,:, 1 ) = zmxlm(:,:,1)   ! surface set to the minimum value
548      zmxld(:,:,jpk) = rmxl_min       ! last level  set to the minimum value
549      !
550      SELECT CASE ( nn_mxl )
551      !
552 !!gm Not sure of that coding for ISF....
553      ! where wmask = 0 set zmxlm == p_e3w
554      CASE ( 0 )           ! bounded by the distance to surface and bottom
555         DO jk = 2, jpkm1
556            DO jj = 2, jpjm1
557               DO ji = fs_2, fs_jpim1   ! vector opt.
558                  zemxl = MIN( pdepw(ji,jj,jk) - pdepw(ji,jj,mikt(ji,jj)), zmxlm(ji,jj,jk),   &
559                  &            pdepw(ji,jj,mbkt(ji,jj)+1) - pdepw(ji,jj,jk) )
560                  ! wmask prevent zmxlm = 0 if jk = mikt(ji,jj)
561                  zmxlm(ji,jj,jk) = zemxl * wmask(ji,jj,jk) + MIN( zmxlm(ji,jj,jk) , p_e3w(ji,jj,jk) ) * (1 - wmask(ji,jj,jk))
562                  zmxld(ji,jj,jk) = zemxl * wmask(ji,jj,jk) + MIN( zmxlm(ji,jj,jk) , p_e3w(ji,jj,jk) ) * (1 - wmask(ji,jj,jk))
563               END DO
564            END DO
565         END DO
566         !
567      CASE ( 1 )           ! bounded by the vertical scale factor
568         DO jk = 2, jpkm1
569            DO jj = 2, jpjm1
570               DO ji = fs_2, fs_jpim1   ! vector opt.
571                  zemxl = MIN( p_e3w(ji,jj,jk), zmxlm(ji,jj,jk) )
572                  zmxlm(ji,jj,jk) = zemxl
573                  zmxld(ji,jj,jk) = zemxl
574               END DO
575            END DO
576         END DO
577         !
578      CASE ( 2 )           ! |dk[xml]| bounded by e3t :
579         DO jk = 2, jpkm1         ! from the surface to the bottom :
580            DO jj = 2, jpjm1
581               DO ji = fs_2, fs_jpim1   ! vector opt.
582                  zmxlm(ji,jj,jk) = MIN( zmxlm(ji,jj,jk-1) + p_e3t(ji,jj,jk-1), zmxlm(ji,jj,jk) )
583               END DO
584            END DO
585         END DO
586         DO jk = jpkm1, 2, -1     ! from the bottom to the surface :
587            DO jj = 2, jpjm1
588               DO ji = fs_2, fs_jpim1   ! vector opt.
589                  zemxl = MIN( zmxlm(ji,jj,jk+1) + p_e3t(ji,jj,jk+1), zmxlm(ji,jj,jk) )
590                  zmxlm(ji,jj,jk) = zemxl
591                  zmxld(ji,jj,jk) = zemxl
592               END DO
593            END DO
594         END DO
595         !
596      CASE ( 3 )           ! lup and ldown, |dk[xml]| bounded by e3t :
597         DO jk = 2, jpkm1         ! from the surface to the bottom : lup
598            DO jj = 2, jpjm1
599               DO ji = fs_2, fs_jpim1   ! vector opt.
600                  zmxld(ji,jj,jk) = MIN( zmxld(ji,jj,jk-1) + p_e3t(ji,jj,jk-1), zmxlm(ji,jj,jk) )
601               END DO
602            END DO
603         END DO
604         DO jk = jpkm1, 2, -1     ! from the bottom to the surface : ldown
605            DO jj = 2, jpjm1
606               DO ji = fs_2, fs_jpim1   ! vector opt.
607                  zmxlm(ji,jj,jk) = MIN( zmxlm(ji,jj,jk+1) + p_e3t(ji,jj,jk+1), zmxlm(ji,jj,jk) )
608               END DO
609            END DO
610         END DO
611         DO jk = 2, jpkm1
612            DO jj = 2, jpjm1
613               DO ji = fs_2, fs_jpim1   ! vector opt.
614                  zemlm = MIN ( zmxld(ji,jj,jk),  zmxlm(ji,jj,jk) )
615                  zemlp = SQRT( zmxld(ji,jj,jk) * zmxlm(ji,jj,jk) )
616                  zmxlm(ji,jj,jk) = zemlm
617                  zmxld(ji,jj,jk) = zemlp
618               END DO
619            END DO
620         END DO
621         !
622      END SELECT
623      !
624
625      !                     !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
626      !                     !  Vertical eddy viscosity and diffusivity  (avm and avt)
627      !                     !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
628      DO jk = 1, jpkm1            !* vertical eddy viscosity & diffivity at w-points
629         DO jj = 2, jpjm1
630            DO ji = fs_2, fs_jpim1   ! vector opt.
631               zsqen = SQRT( en(ji,jj,jk) )
632               zav   = rn_ediff * zmxlm(ji,jj,jk) * zsqen
633               p_avm(ji,jj,jk) = MAX( zav,                  avmb(jk) ) * wmask(ji,jj,jk)
634               p_avt(ji,jj,jk) = MAX( zav, avtb_2d(ji,jj) * avtb(jk) ) * wmask(ji,jj,jk)
635               dissl(ji,jj,jk) = zsqen / zmxld(ji,jj,jk)
636            END DO
637         END DO
638      END DO
639      !
640      !
641      IF( nn_pdl == 1 ) THEN      !* Prandtl number case: update avt
642         DO jk = 2, jpkm1
643            DO jj = 2, jpjm1
644               DO ji = fs_2, fs_jpim1   ! vector opt.
645                  p_avt(ji,jj,jk)   = MAX( apdlr(ji,jj,jk) * p_avt(ji,jj,jk), avtb_2d(ji,jj) * avtb(jk) ) * tmask(ji,jj,jk)
646              END DO
647            END DO
648         END DO
649      ENDIF
650
651      IF(ln_ctl) THEN
652         CALL prt_ctl( tab3d_1=en , clinfo1=' tke  - e: ', tab3d_2=avt, clinfo2=' t: ', ovlap=1, kdim=jpk)
653         CALL prt_ctl( tab3d_1=avm, clinfo1=' tke  - m: ', ovlap=1, kdim=jpk )
654      ENDIF
655      !
656      IF( nn_timing == 1 )  CALL timing_stop('tke_avn')
657      !
658   END SUBROUTINE tke_avn
659
660
661   SUBROUTINE zdf_tke_init
662      !!----------------------------------------------------------------------
663      !!                  ***  ROUTINE zdf_tke_init  ***
664      !!                     
665      !! ** Purpose :   Initialization of the vertical eddy diffivity and
666      !!              viscosity when using a tke turbulent closure scheme
667      !!
668      !! ** Method  :   Read the namzdf_tke namelist and check the parameters
669      !!              called at the first timestep (nit000)
670      !!
671      !! ** input   :   Namlist namzdf_tke
672      !!
673      !! ** Action  :   Increase by 1 the nstop flag is setting problem encounter
674      !!----------------------------------------------------------------------
675      INTEGER ::   ji, jj, jk   ! dummy loop indices
676      INTEGER ::   ios
677      !!
678      NAMELIST/namzdf_tke/ rn_ediff, rn_ediss , rn_ebb , rn_emin  ,   &
679         &                 rn_emin0, rn_bshear, nn_mxl , ln_mxl0  ,   &
680         &                 rn_mxl0 , nn_pdl   , ln_lc  , rn_lc    ,   &
681         &                 nn_etau , nn_htau  , rn_efr   
682      !!----------------------------------------------------------------------
683      !
684      REWIND( numnam_ref )              ! Namelist namzdf_tke in reference namelist : Turbulent Kinetic Energy
685      READ  ( numnam_ref, namzdf_tke, IOSTAT = ios, ERR = 901)
686901   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namzdf_tke in reference namelist', lwp )
687
688      REWIND( numnam_cfg )              ! Namelist namzdf_tke in configuration namelist : Turbulent Kinetic Energy
689      READ  ( numnam_cfg, namzdf_tke, IOSTAT = ios, ERR = 902 )
690902   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namzdf_tke in configuration namelist', lwp )
691      IF(lwm) WRITE ( numond, namzdf_tke )
692      !
693      ri_cri   = 2._wp    / ( 2._wp + rn_ediss / rn_ediff )   ! resulting critical Richardson number
694      !
695      IF(lwp) THEN                    !* Control print
696         WRITE(numout,*)
697         WRITE(numout,*) 'zdf_tke_init : tke turbulent closure scheme - initialisation'
698         WRITE(numout,*) '~~~~~~~~~~~~'
699         WRITE(numout,*) '   Namelist namzdf_tke : set tke mixing parameters'
700         WRITE(numout,*) '      coef. to compute avt                        rn_ediff  = ', rn_ediff
701         WRITE(numout,*) '      Kolmogoroff dissipation coef.               rn_ediss  = ', rn_ediss
702         WRITE(numout,*) '      tke surface input coef.                     rn_ebb    = ', rn_ebb
703         WRITE(numout,*) '      minimum value of tke                        rn_emin   = ', rn_emin
704         WRITE(numout,*) '      surface minimum value of tke                rn_emin0  = ', rn_emin0
705         WRITE(numout,*) '      background shear (>0)                       rn_bshear = ', rn_bshear
706         WRITE(numout,*) '      mixing length type                          nn_mxl    = ', nn_mxl
707         WRITE(numout,*) '      prandl number flag                          nn_pdl    = ', nn_pdl
708         WRITE(numout,*) '      surface mixing length = F(stress) or not    ln_mxl0   = ', ln_mxl0
709         WRITE(numout,*) '      surface  mixing length minimum value        rn_mxl0   = ', rn_mxl0
710         WRITE(numout,*) '      flag to take into acc.  Langmuir circ.      ln_lc     = ', ln_lc
711         WRITE(numout,*) '      coef to compute verticla velocity of LC     rn_lc     = ', rn_lc
712         WRITE(numout,*) '      test param. to add tke induced by wind      nn_etau   = ', nn_etau
713         WRITE(numout,*) '      flag for computation of exp. tke profile    nn_htau   = ', nn_htau
714         WRITE(numout,*) '      fraction of en which pene. the thermocline  rn_efr    = ', rn_efr
715         WRITE(numout,*)
716         WRITE(numout,*) '      critical Richardson nb with your parameters  ri_cri = ', ri_cri
717         WRITE(numout,*)
718      ENDIF
719      !
720      IF( ln_zdfiwm ) THEN          ! Internal wave-driven mixing
721         rn_emin  = 1.e-10_wp             ! specific values of rn_emin & rmxl_min are used
722         rmxl_min = 1.e-03_wp             ! associated avt minimum = molecular salt diffusivity (10^-9 m2/s)
723         IF(lwp) WRITE(numout,*) '      Internal wave-driven mixing case:   force   rn_emin = 1.e-10 and rmxl_min = 1.e-3 '
724      ELSE                          ! standard case : associated avt minimum = molecular viscosity (10^-6 m2/s)
725         rmxl_min = 1.e-6_wp / ( rn_ediff * SQRT( rn_emin ) )    ! resulting minimum length to recover molecular viscosity
726         IF(lwp) WRITE(numout,*) '      minimum mixing length with your parameters rmxl_min = ', rmxl_min
727      ENDIF
728      !
729      !                              ! allocate tke arrays
730      IF( zdf_tke_alloc() /= 0 )   CALL ctl_stop( 'STOP', 'zdf_tke_init : unable to allocate arrays' )
731      !
732      !                               !* Check of some namelist values
733      IF( nn_mxl  < 0   .OR.  nn_mxl  > 3 )   CALL ctl_stop( 'bad flag: nn_mxl is  0, 1 or 2 ' )
734      IF( nn_pdl  < 0   .OR.  nn_pdl  > 1 )   CALL ctl_stop( 'bad flag: nn_pdl is  0 or 1    ' )
735      IF( nn_htau < 0   .OR.  nn_htau > 1 )   CALL ctl_stop( 'bad flag: nn_htau is 0, 1 or 2 ' )
736      IF( nn_etau == 3 .AND. .NOT. ln_cpl )   CALL ctl_stop( 'nn_etau == 3 : HF taum only known in coupled mode' )
737
738      IF( ln_mxl0 ) THEN
739         IF(lwp) WRITE(numout,*) '   use a surface mixing length = F(stress) :   set rn_mxl0 = rmxl_min'
740         rn_mxl0 = rmxl_min
741      ENDIF
742     
743      IF( nn_etau == 2  )   CALL zdf_mxl( nit000 )      ! Initialization of nmln
744
745      !                               !* depth of penetration of surface tke
746      IF( nn_etau /= 0 ) THEN     
747         SELECT CASE( nn_htau )             ! Choice of the depth of penetration
748         CASE( 0 )                                 ! constant depth penetration (here 10 meters)
749            htau(:,:) = 10._wp
750         CASE( 1 )                                 ! F(latitude) : 0.5m to 30m poleward of 40 degrees
751            htau(:,:) = MAX(  0.5_wp, MIN( 30._wp, 45._wp* ABS( SIN( rpi/180._wp * gphit(:,:) ) ) )   )           
752         END SELECT
753      ENDIF
754      !                               !* set vertical eddy coef. to the background value
755      DO jk = 1, jpk
756         avt(:,:,jk) = avtb(jk) * wmask(:,:,jk)
757         avm(:,:,jk) = avmb(jk) * wmask(:,:,jk)
758      END DO
759      dissl(:,:,:) = 1.e-12_wp
760      !                             
761      CALL tke_rst( nit000, 'READ' )  !* read or initialize all required files
762      !
763   END SUBROUTINE zdf_tke_init
764
765
766   SUBROUTINE tke_rst( kt, cdrw )
767      !!---------------------------------------------------------------------
768      !!                   ***  ROUTINE tke_rst  ***
769      !!                     
770      !! ** Purpose :   Read or write TKE file (en) in restart file
771      !!
772      !! ** Method  :   use of IOM library
773      !!                if the restart does not contain TKE, en is either
774      !!                set to rn_emin or recomputed
775      !!----------------------------------------------------------------------
776      INTEGER         , INTENT(in) ::   kt     ! ocean time-step
777      CHARACTER(len=*), INTENT(in) ::   cdrw   ! "READ"/"WRITE" flag
778      !
779      INTEGER ::   jit, jk              ! dummy loop indices
780      INTEGER ::   id1, id2, id3, id4   ! local integers
781      !!----------------------------------------------------------------------
782      !
783      IF( TRIM(cdrw) == 'READ' ) THEN        ! Read/initialise
784         !                                   ! ---------------
785         IF( ln_rstart ) THEN                   !* Read the restart file
786            id1 = iom_varid( numror, 'en'   , ldstop = .FALSE. )
787            id2 = iom_varid( numror, 'avt_k', ldstop = .FALSE. )
788            id3 = iom_varid( numror, 'avm_k', ldstop = .FALSE. )
789            id4 = iom_varid( numror, 'dissl', ldstop = .FALSE. )
790            !
791            IF( MIN( id1, id2, id3, id4 ) > 0 ) THEN      ! fields exist
792               CALL iom_get( numror, jpdom_autoglo, 'en', en )
793               CALL iom_get( numror, jpdom_autoglo, 'avt_k', avt_k )
794               CALL iom_get( numror, jpdom_autoglo, 'avm_k', avm_k )
795               CALL iom_get( numror, jpdom_autoglo, 'dissl', dissl )
796            ELSE                                          ! start TKE from rest
797               IF(lwp) WRITE(numout,*) '   ==>>   previous run without TKE scheme, set en to background values'
798               en(:,:,:) = rn_emin * wmask(:,:,:)
799               ! avt_k, avm_k already set to the background value in zdf_phy_init
800            ENDIF
801         ELSE                                   !* Start from rest
802            IF(lwp) WRITE(numout,*) '   ==>>   start from rest: set en to the background value'
803            en(:,:,:) = rn_emin * wmask(:,:,:)
804            ! avt_k, avm_k already set to the background value in zdf_phy_init
805         ENDIF
806         !
807      ELSEIF( TRIM(cdrw) == 'WRITE' ) THEN   ! Create restart file
808         !                                   ! -------------------
809         IF(lwp) WRITE(numout,*) '---- tke-rst ----'
810         CALL iom_rstput( kt, nitrst, numrow, 'en'   , en    )
811         CALL iom_rstput( kt, nitrst, numrow, 'avt_k', avt_k )
812         CALL iom_rstput( kt, nitrst, numrow, 'avm_k', avm_k )
813         CALL iom_rstput( kt, nitrst, numrow, 'dissl', dissl )
814         !
815      ENDIF
816      !
817   END SUBROUTINE tke_rst
818
819   !!======================================================================
820END MODULE zdftke
Note: See TracBrowser for help on using the repository browser.