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 NEMO/branches/2020/temporary_r4_trunk/src/OCE/ZDF – NEMO

source: NEMO/branches/2020/temporary_r4_trunk/src/OCE/ZDF/zdftke.F90 @ 13470

Last change on this file since 13470 was 13470, checked in by smasson, 4 years ago

r4_trunk: second change of DO loops for routines to be merged, see #2523

  • Property svn:keywords set to Id
File size: 43.5 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   !!             -   !  2017-05  (G. Madec)  add top/bottom friction as boundary condition
31   !!----------------------------------------------------------------------
32
33   !!----------------------------------------------------------------------
34   !!   zdf_tke       : update momentum and tracer Kz from a tke scheme
35   !!   tke_tke       : tke time stepping: update tke at now time step (en)
36   !!   tke_avn       : compute mixing length scale and deduce avm and avt
37   !!   zdf_tke_init  : initialization, namelist read, and parameters control
38   !!   tke_rst       : read/write tke restart in ocean restart file
39   !!----------------------------------------------------------------------
40   USE oce            ! ocean: dynamics and active tracers variables
41   USE phycst         ! physical constants
42   USE dom_oce        ! domain: ocean
43   USE domvvl         ! domain: variable volume layer
44   USE sbc_oce        ! surface boundary condition: ocean
45   USE zdfdrg         ! vertical physics: top/bottom drag coef.
46   USE zdfmxl         ! vertical physics: mixed layer
47   !
48#if defined key_si3
49   USE ice, ONLY: hm_i, h_i
50#endif
51#if defined key_cice
52   USE sbc_ice, ONLY: h_i
53#endif
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 lib_fortran    ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 
60
61   IMPLICIT NONE
62   PRIVATE
63
64   PUBLIC   zdf_tke        ! routine called in step module
65   PUBLIC   zdf_tke_init   ! routine called in opa module
66   PUBLIC   tke_rst        ! routine called in step module
67
68   !                      !!** Namelist  namzdf_tke  **
69   LOGICAL  ::   ln_mxl0   ! mixing length scale surface value as function of wind stress or not
70   INTEGER  ::   nn_mxlice ! type of scaling under sea-ice (=0/1/2/3)
71   REAL(wp) ::   rn_mxlice ! ice thickness value when scaling under sea-ice
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   INTEGER  ::   nn_eice   ! attenutaion of langmuir & surface wave breaking under ice (=0/1/2/3)   
87
88   REAL(wp) ::   ri_cri    ! critic Richardson number (deduced from rn_ediff and rn_ediss values)
89   REAL(wp) ::   rmxl_min  ! minimum mixing length value (deduced from rn_ediff and rn_emin values)  [m]
90   REAL(wp) ::   rhftau_add = 1.e-3_wp     ! add offset   applied to HF part of taum  (nn_etau=3)
91   REAL(wp) ::   rhftau_scl = 1.0_wp       ! scale factor applied to HF part of taum  (nn_etau=3)
92
93   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   htau    ! depth of tke penetration (nn_htau)
94   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   dissl   ! now mixing lenght of dissipation
95   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   apdlr   ! now mixing lenght of dissipation
96
97   !! * Substitutions
98#  include "vectopt_loop_substitute.h90"
99   !!----------------------------------------------------------------------
100   !! NEMO/OCE 4.0 , NEMO Consortium (2018)
101   !! $Id$
102   !! Software governed by the CeCILL license (see ./LICENSE)
103   !!----------------------------------------------------------------------
104CONTAINS
105
106   INTEGER FUNCTION zdf_tke_alloc()
107      !!----------------------------------------------------------------------
108      !!                ***  FUNCTION zdf_tke_alloc  ***
109      !!----------------------------------------------------------------------
110      ALLOCATE( htau(jpi,jpj) , dissl(jpi,jpj,jpk) , apdlr(jpi,jpj,jpk) ,   STAT= zdf_tke_alloc )
111      !
112      CALL mpp_sum ( 'zdftke', zdf_tke_alloc )
113      IF( zdf_tke_alloc /= 0 )   CALL ctl_stop( 'STOP', 'zdf_tke_alloc: failed to allocate arrays' )
114      !
115   END FUNCTION zdf_tke_alloc
116
117
118   SUBROUTINE zdf_tke( kt, p_sh2, p_avm, p_avt )
119      !!----------------------------------------------------------------------
120      !!                   ***  ROUTINE zdf_tke  ***
121      !!
122      !! ** Purpose :   Compute the vertical eddy viscosity and diffusivity
123      !!              coefficients using a turbulent closure scheme (TKE).
124      !!
125      !! ** Method  :   The time evolution of the turbulent kinetic energy (tke)
126      !!              is computed from a prognostic equation :
127      !!         d(en)/dt = avm (d(u)/dz)**2             ! shear production
128      !!                  + d( avm d(en)/dz )/dz         ! diffusion of tke
129      !!                  + avt N^2                      ! stratif. destruc.
130      !!                  - rn_ediss / emxl en**(2/3)    ! Kolmogoroff dissipation
131      !!      with the boundary conditions:
132      !!         surface: en = max( rn_emin0, rn_ebb * taum )
133      !!         bottom : en = rn_emin
134      !!      The associated critical Richardson number is: ri_cri = 2/(2+rn_ediss/rn_ediff)
135      !!
136      !!        The now Turbulent kinetic energy is computed using the following
137      !!      time stepping: implicit for vertical diffusion term, linearized semi
138      !!      implicit for kolmogoroff dissipation term, and explicit forward for
139      !!      both buoyancy and shear production terms. Therefore a tridiagonal
140      !!      linear system is solved. Note that buoyancy and shear terms are
141      !!      discretized in a energy conserving form (Bruchard 2002).
142      !!
143      !!        The dissipative and mixing length scale are computed from en and
144      !!      the stratification (see tke_avn)
145      !!
146      !!        The now vertical eddy vicosity and diffusivity coefficients are
147      !!      given by:
148      !!              avm = max( avtb, rn_ediff * zmxlm * en^1/2 )
149      !!              avt = max( avmb, pdl * avm                 ) 
150      !!              eav = max( avmb, avm )
151      !!      where pdl, the inverse of the Prandtl number is 1 if nn_pdl=0 and
152      !!      given by an empirical funtion of the localRichardson number if nn_pdl=1
153      !!
154      !! ** Action  :   compute en (now turbulent kinetic energy)
155      !!                update avt, avm (before vertical eddy coef.)
156      !!
157      !! References : Gaspar et al., JGR, 1990,
158      !!              Blanke and Delecluse, JPO, 1991
159      !!              Mellor and Blumberg, JPO 2004
160      !!              Axell, JGR, 2002
161      !!              Bruchard OM 2002
162      !!----------------------------------------------------------------------
163      INTEGER                   , INTENT(in   ) ::   kt             ! ocean time step
164      REAL(wp), DIMENSION(:,:,:), INTENT(in   ) ::   p_sh2          ! shear production term
165      REAL(wp), DIMENSION(:,:,:), INTENT(inout) ::   p_avm, p_avt   !  momentum and tracer Kz (w-points)
166      !!----------------------------------------------------------------------
167      !
168      CALL tke_tke( gdepw_n, e3t_n, e3w_n, p_sh2, p_avm, p_avt )   ! now tke (en)
169      !
170      CALL tke_avn( gdepw_n, e3t_n, e3w_n,        p_avm, p_avt )   ! now avt, avm, dissl
171      !
172  END SUBROUTINE zdf_tke
173
174
175   SUBROUTINE tke_tke( pdepw, p_e3t, p_e3w, p_sh2, p_avm, p_avt )
176      !!----------------------------------------------------------------------
177      !!                   ***  ROUTINE tke_tke  ***
178      !!
179      !! ** Purpose :   Compute the now Turbulente Kinetic Energy (TKE)
180      !!
181      !! ** Method  : - TKE surface boundary condition
182      !!              - source term due to Langmuir cells (Axell JGR 2002) (ln_lc=T)
183      !!              - source term due to shear (= Kz dz[Ub] * dz[Un] )
184      !!              - Now TKE : resolution of the TKE equation by inverting
185      !!                a tridiagonal linear system by a "methode de chasse"
186      !!              - increase TKE due to surface and internal wave breaking
187      !!             NB: when sea-ice is present, both LC parameterization
188      !!                 and TKE penetration are turned off when the ice fraction
189      !!                 is smaller than 0.25
190      !!
191      !! ** Action  : - en : now turbulent kinetic energy)
192      !! ---------------------------------------------------------------------
193      USE zdf_oce , ONLY : en   ! ocean vertical physics
194      !!
195      REAL(wp), DIMENSION(:,:,:) , INTENT(in   ) ::   pdepw          ! depth of w-points
196      REAL(wp), DIMENSION(:,:,:) , INTENT(in   ) ::   p_e3t, p_e3w   ! level thickness (t- & w-points)
197      REAL(wp), DIMENSION(:,:,:) , INTENT(in   ) ::   p_sh2          ! shear production term
198      REAL(wp), DIMENSION(:,:,:) , INTENT(in   ) ::   p_avm, p_avt   ! vertical eddy viscosity & diffusivity (w-points)
199      !
200      INTEGER ::   ji, jj, jk                  ! dummy loop arguments
201      REAL(wp) ::   zetop, zebot, zmsku, zmskv ! local scalars
202      REAL(wp) ::   zrhoa  = 1.22              ! Air density kg/m3
203      REAL(wp) ::   zcdrag = 1.5e-3            ! drag coefficient
204      REAL(wp) ::   zbbrau, zbbirau, zri       ! local scalars
205      REAL(wp) ::   zfact1, zfact2, zfact3     !   -      -
206      REAL(wp) ::   ztx2  , zty2  , zcof       !   -      -
207      REAL(wp) ::   ztau  , zdif               !   -      -
208      REAL(wp) ::   zus   , zwlc  , zind       !   -      -
209      REAL(wp) ::   zzd_up, zzd_lw             !   -      -
210      INTEGER , DIMENSION(jpi,jpj)     ::   imlc
211      REAL(wp), DIMENSION(jpi,jpj)     ::   zice_fra, zhlc, zus3
212      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zpelc, zdiag, zd_up, zd_lw
213      !!--------------------------------------------------------------------
214      !
215      zbbrau  =  rn_ebb / rau0       ! Local constant initialisation
216      zbbirau =  3.75_wp / rau0
217      zfact1  = -0.5_wp * rdt 
218      zfact2  =  1.5_wp * rdt * rn_ediss
219      zfact3  =  0.5_wp       * rn_ediss
220      !
221      ! ice fraction considered for attenuation of langmuir & wave breaking
222      SELECT CASE ( nn_eice )
223      CASE( 0 )   ;   zice_fra(:,:) = 0._wp
224      CASE( 1 )   ;   zice_fra(:,:) =        TANH( fr_i(:,:) * 10._wp )
225      CASE( 2 )   ;   zice_fra(:,:) =              fr_i(:,:)
226      CASE( 3 )   ;   zice_fra(:,:) = MIN( 4._wp * fr_i(:,:) , 1._wp )
227      END SELECT
228      !
229      !                     !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
230      !                     !  Surface/top/bottom boundary condition on tke
231      !                     !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
232      !
233      DO_2D( 0, 0, 0, 0 )
234!! clem: this should be the right formulation but it makes the model unstable unless drags are calculated implicitly
235!!       one way around would be to increase zbbirau
236!!          en(ji,jj,1) = MAX( rn_emin0, ( ( 1._wp - fr_i(ji,jj) ) * zbbrau + &
237!!             &                                     fr_i(ji,jj)   * zbbirau ) * taum(ji,jj) ) * tmask(ji,jj,1)
238         en(ji,jj,1) = MAX( rn_emin0, zbbrau * taum(ji,jj) ) * tmask(ji,jj,1)
239      END_2D
240      !
241      !                     !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
242      !                     !  Bottom boundary condition on tke
243      !                     !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
244      !
245      !   en(bot)   = (ebb0/rau0)*0.5*sqrt(u_botfr^2+v_botfr^2) (min value rn_emin)
246      ! where ebb0 does not includes surface wave enhancement (i.e. ebb0=3.75)
247      ! Note that stress averaged is done using an wet-only calculation of u and v at t-point like in zdfsh2
248      !
249      IF( .NOT.ln_drg_OFF ) THEN    !== friction used as top/bottom boundary condition on TKE
250         !
251         DO_2D( 0, 0, 0, 0 )
252            zmsku = ( 2. - umask(ji-1,jj,mbkt(ji,jj)) * umask(ji,jj,mbkt(ji,jj)) )
253            zmskv = ( 2. - vmask(ji,jj-1,mbkt(ji,jj)) * vmask(ji,jj,mbkt(ji,jj)) )
254            !                       ! where 0.001875 = (rn_ebb0/rau0) * 0.5 = 3.75*0.5/1000. (CAUTION CdU<0)
255            zebot = - 0.001875_wp * rCdU_bot(ji,jj) * SQRT(  ( zmsku*( uu(ji,jj,mbkt(ji,jj),Nnn)+uu(ji-1,jj,mbkt(ji,jj),Nnn) ) )**2  &
256               &                                           + ( zmskv*( vv(ji,jj,mbkt(ji,jj),Nnn)+vv(ji,jj-1,mbkt(ji,jj),Nnn) ) )**2  )
257            en(ji,jj,mbkt(ji,jj)+1) = MAX( zebot, rn_emin ) * ssmask(ji,jj)
258         END_2D
259         IF( ln_isfcav ) THEN       ! top friction
260            DO_2D( 0, 0, 0, 0 )
261               zmsku = ( 2. - umask(ji-1,jj,mikt(ji,jj)) * umask(ji,jj,mikt(ji,jj)) )
262               zmskv = ( 2. - vmask(ji,jj-1,mikt(ji,jj)) * vmask(ji,jj,mikt(ji,jj)) )
263               !                             ! where 0.001875 = (rn_ebb0/rau0) * 0.5 = 3.75*0.5/1000.  (CAUTION CdU<0)
264               zetop = - 0.001875_wp * rCdU_top(ji,jj) * SQRT(  ( zmsku*( uu(ji,jj,mikt(ji,jj),Nnn)+uu(ji-1,jj,mikt(ji,jj),Nnn) ) )**2  &
265                  &                                           + ( zmskv*( vv(ji,jj,mikt(ji,jj),Nnn)+vv(ji,jj-1,mikt(ji,jj),Nnn) ) )**2  )
266               en(ji,jj,mikt(ji,jj)) = en(ji,jj,1)           * tmask(ji,jj,1) &     
267                  &                  + MAX( zetop, rn_emin ) * (1._wp - tmask(ji,jj,1)) * ssmask(ji,jj)
268            END_2D
269         ENDIF
270         !
271      ENDIF
272      !
273      !                     !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
274      IF( ln_lc ) THEN      !  Langmuir circulation source term added to tke   !   (Axell JGR 2002)
275         !                  !>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
276         !
277         !                        !* total energy produce by LC : cumulative sum over jk
278         zpelc(:,:,1) =  MAX( rn2b(:,:,1), 0._wp ) * pdepw(:,:,1) * p_e3w(:,:,1)
279         DO jk = 2, jpk
280            zpelc(:,:,jk)  = zpelc(:,:,jk-1) + MAX( rn2b(:,:,jk), 0._wp ) * pdepw(:,:,jk) * p_e3w(:,:,jk)
281         END DO
282         !                        !* finite Langmuir Circulation depth
283         zcof = 0.5 * 0.016 * 0.016 / ( zrhoa * zcdrag )
284         imlc(:,:) = mbkt(:,:) + 1       ! Initialization to the number of w ocean point (=2 over land)
285         DO_3D( 1, 1, 1, 1, jpkm1, 2, -1 )
286            zus  = zcof * taum(ji,jj)
287            IF( zpelc(ji,jj,jk) > zus )   imlc(ji,jj) = jk
288         END_3D
289         !                               ! finite LC depth
290         DO_2D( 1, 1, 1, 1 )
291            zhlc(ji,jj) = pdepw(ji,jj,imlc(ji,jj))
292         END_2D
293         zcof = 0.016 / SQRT( zrhoa * zcdrag )
294         DO_2D( 0, 0, 0, 0 )
295            zus  = zcof * SQRT( taum(ji,jj) )           ! Stokes drift
296            zus3(ji,jj) = MAX( 0._wp, 1._wp - zice_fra(ji,jj) ) * zus * zus * zus * tmask(ji,jj,1) ! zus > 0. ok
297         END_2D
298         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
299            IF ( zus3(ji,jj) /= 0._wp ) THEN               
300               ! vertical velocity due to LC   
301               IF ( pdepw(ji,jj,jk) - zhlc(ji,jj) < 0 .AND. wmask(ji,jj,jk) /= 0. ) THEN
302                  !                                           ! vertical velocity due to LC
303                  zwlc = rn_lc * SIN( rpi * pdepw(ji,jj,jk) / zhlc(ji,jj) )
304                  !                                           ! TKE Langmuir circulation source term
305                  en(ji,jj,jk) = en(ji,jj,jk) + rdt * zus3(ji,jj) * ( zwlc * zwlc * zwlc ) / zhlc(ji,jj)
306               ENDIF
307            ENDIF
308         END_3D
309         !
310      ENDIF
311      !
312      !                     !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
313      !                     !  Now Turbulent kinetic energy (output in en)
314      !                     !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
315      !                     ! Resolution of a tridiagonal linear system by a "methode de chasse"
316      !                     ! computation from level 2 to jpkm1  (e(1) already computed and e(jpk)=0 ).
317      !                     ! zdiag : diagonal zd_up : upper diagonal zd_lw : lower diagonal
318      !
319      IF( nn_pdl == 1 ) THEN      !* Prandtl number = F( Ri )
320         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
321            !                             ! local Richardson number
322            zri = MAX( rn2b(ji,jj,jk), 0._wp ) * p_avm(ji,jj,jk) / ( p_sh2(ji,jj,jk) + rn_bshear )
323            !                             ! inverse of Prandtl number
324            apdlr(ji,jj,jk) = MAX(  0.1_wp,  ri_cri / MAX( ri_cri , zri )  )
325         END_3D
326      ENDIF
327      !         
328      DO_3D( 0, 0, 0, 0, 2, jpkm1 )
329         zcof   = zfact1 * tmask(ji,jj,jk)
330         !                                   ! A minimum of 2.e-5 m2/s is imposed on TKE vertical
331         !                                   ! eddy coefficient (ensure numerical stability)
332         zzd_up = zcof * MAX(  p_avm(ji,jj,jk+1) + p_avm(ji,jj,jk  ) , 2.e-5_wp  )   &  ! upper diagonal
333            &          /    (  p_e3t(ji,jj,jk  ) * p_e3w(ji,jj,jk  )  )
334         zzd_lw = zcof * MAX(  p_avm(ji,jj,jk  ) + p_avm(ji,jj,jk-1) , 2.e-5_wp  )   &  ! lower diagonal
335            &          /    (  p_e3t(ji,jj,jk-1) * p_e3w(ji,jj,jk  )  )
336         !
337         zd_up(ji,jj,jk) = zzd_up            ! Matrix (zdiag, zd_up, zd_lw)
338         zd_lw(ji,jj,jk) = zzd_lw
339         zdiag(ji,jj,jk) = 1._wp - zzd_lw - zzd_up + zfact2 * dissl(ji,jj,jk) * wmask(ji,jj,jk)
340         !
341         !                                   ! right hand side in en
342         en(ji,jj,jk) = en(ji,jj,jk) + rdt * (  p_sh2(ji,jj,jk)                          &   ! shear
343            &                                 - p_avt(ji,jj,jk) * rn2(ji,jj,jk)          &   ! stratification
344            &                                 + zfact3 * dissl(ji,jj,jk) * en(ji,jj,jk)  &   ! dissipation
345            &                                ) * wmask(ji,jj,jk)
346      END_3D
347      !                          !* Matrix inversion from level 2 (tke prescribed at level 1)
348      DO_3D( 0, 0, 0, 0, 3, jpkm1 )
349         zdiag(ji,jj,jk) = zdiag(ji,jj,jk) - zd_lw(ji,jj,jk) * zd_up(ji,jj,jk-1) / zdiag(ji,jj,jk-1)
350      END_3D
351      DO_2D( 0, 0, 0, 0 )
352         zd_lw(ji,jj,2) = en(ji,jj,2) - zd_lw(ji,jj,2) * en(ji,jj,1)    ! Surface boudary conditions on tke
353      END_2D
354      DO_3D( 0, 0, 0, 0, 3, jpkm1 )
355         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)
356      END_3D
357      DO_2D( 0, 0, 0, 0 )
358         en(ji,jj,jpkm1) = zd_lw(ji,jj,jpkm1) / zdiag(ji,jj,jpkm1)
359      END_2D
360      DO_3D( 0, 0, 0, 0, jpk-2, 2, -1 )
361         en(ji,jj,jk) = ( zd_lw(ji,jj,jk) - zd_up(ji,jj,jk) * en(ji,jj,jk+1) ) / zdiag(ji,jj,jk)
362      END_3D
363      DO_3D( 0, 0, 0, 0, 2, jpkm1 )
364         en(ji,jj,jk) = MAX( en(ji,jj,jk), rn_emin ) * wmask(ji,jj,jk)
365      END_3D
366      !
367      !                            !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
368      !                            !  TKE due to surface and internal wave breaking
369      !                            !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
370!!gm BUG : in the exp  remove the depth of ssh !!!
371!!gm       i.e. use gde3w in argument (pdepw)
372     
373     
374      IF( nn_etau == 1 ) THEN           !* penetration below the mixed layer (rn_efr fraction)
375         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
376            en(ji,jj,jk) = en(ji,jj,jk) + rn_efr * en(ji,jj,1) * EXP( -pdepw(ji,jj,jk) / htau(ji,jj) )   &
377               &                                 * MAX( 0._wp, 1._wp - zice_fra(ji,jj) ) * wmask(ji,jj,jk) * tmask(ji,jj,1)
378         END_3D
379      ELSEIF( nn_etau == 2 ) THEN       !* act only at the base of the mixed layer (jk=nmln)  (rn_efr fraction)
380         DO_2D( 0, 0, 0, 0 )
381            jk = nmln(ji,jj)
382            en(ji,jj,jk) = en(ji,jj,jk) + rn_efr * en(ji,jj,1) * EXP( -pdepw(ji,jj,jk) / htau(ji,jj) )   &
383               &                                 * MAX( 0._wp, 1._wp - zice_fra(ji,jj) ) * wmask(ji,jj,jk) * tmask(ji,jj,1)
384         END_2D
385      ELSEIF( nn_etau == 3 ) THEN       !* penetration belox the mixed layer (HF variability)
386         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
387            ztx2 = utau(ji-1,jj  ) + utau(ji,jj)
388            zty2 = vtau(ji  ,jj-1) + vtau(ji,jj)
389            ztau = 0.5_wp * SQRT( ztx2 * ztx2 + zty2 * zty2 ) * tmask(ji,jj,1)    ! module of the mean stress
390            zdif = taum(ji,jj) - ztau                            ! mean of modulus - modulus of the mean
391            zdif = rhftau_scl * MAX( 0._wp, zdif + rhftau_add )  ! apply some modifications...
392            en(ji,jj,jk) = en(ji,jj,jk) + zbbrau * zdif * EXP( -pdepw(ji,jj,jk) / htau(ji,jj) )   &
393               &                                 * MAX( 0._wp, 1._wp - zice_fra(ji,jj) ) * wmask(ji,jj,jk) * tmask(ji,jj,1)
394         END_3D
395      ENDIF
396      !
397   END SUBROUTINE tke_tke
398
399
400   SUBROUTINE tke_avn( pdepw, p_e3t, p_e3w, p_avm, p_avt )
401      !!----------------------------------------------------------------------
402      !!                   ***  ROUTINE tke_avn  ***
403      !!
404      !! ** Purpose :   Compute the vertical eddy viscosity and diffusivity
405      !!
406      !! ** Method  :   At this stage, en, the now TKE, is known (computed in
407      !!              the tke_tke routine). First, the now mixing lenth is
408      !!      computed from en and the strafification (N^2), then the mixings
409      !!      coefficients are computed.
410      !!              - Mixing length : a first evaluation of the mixing lengh
411      !!      scales is:
412      !!                      mxl = sqrt(2*en) / N 
413      !!      where N is the brunt-vaisala frequency, with a minimum value set
414      !!      to rmxl_min (rn_mxl0) in the interior (surface) ocean.
415      !!        The mixing and dissipative length scale are bound as follow :
416      !!         nn_mxl=0 : mxl bounded by the distance to surface and bottom.
417      !!                        zmxld = zmxlm = mxl
418      !!         nn_mxl=1 : mxl bounded by the e3w and zmxld = zmxlm = mxl
419      !!         nn_mxl=2 : mxl bounded such that the vertical derivative of mxl is
420      !!                    less than 1 (|d/dz(mxl)|<1) and zmxld = zmxlm = mxl
421      !!         nn_mxl=3 : mxl is bounded from the surface to the bottom usings
422      !!                    |d/dz(xml)|<1 to obtain lup, and from the bottom to
423      !!                    the surface to obtain ldown. the resulting length
424      !!                    scales are:
425      !!                        zmxld = sqrt( lup * ldown )
426      !!                        zmxlm = min ( lup , ldown )
427      !!              - Vertical eddy viscosity and diffusivity:
428      !!                      avm = max( avtb, rn_ediff * zmxlm * en^1/2 )
429      !!                      avt = max( avmb, pdlr * avm ) 
430      !!      with pdlr=1 if nn_pdl=0, pdlr=1/pdl=F(Ri) otherwise.
431      !!
432      !! ** Action  : - avt, avm : now vertical eddy diffusivity and viscosity (w-point)
433      !!----------------------------------------------------------------------
434      USE zdf_oce , ONLY : en, avtb, avmb, avtb_2d   ! ocean vertical physics
435      !!
436      REAL(wp), DIMENSION(:,:,:), INTENT(in   ) ::   pdepw          ! depth (w-points)
437      REAL(wp), DIMENSION(:,:,:), INTENT(in   ) ::   p_e3t, p_e3w   ! level thickness (t- & w-points)
438      REAL(wp), DIMENSION(:,:,:), INTENT(  out) ::   p_avm, p_avt   ! vertical eddy viscosity & diffusivity (w-points)
439      !
440      INTEGER  ::   ji, jj, jk   ! dummy loop indices
441      REAL(wp) ::   zrn2, zraug, zcoef, zav   ! local scalars
442      REAL(wp) ::   zdku,   zdkv, zsqen       !   -      -
443      REAL(wp) ::   zemxl, zemlm, zemlp, zmaxice       !   -      -
444      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zmxlm, zmxld   ! 3D workspace
445      !!--------------------------------------------------------------------
446      !
447      !                     !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
448      !                     !  Mixing length
449      !                     !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
450      !
451      !                     !* Buoyancy length scale: l=sqrt(2*e/n**2)
452      !
453      ! initialisation of interior minimum value (avoid a 2d loop with mikt)
454      zmxlm(:,:,:)  = rmxl_min   
455      zmxld(:,:,:)  = rmxl_min
456      !
457      IF( ln_mxl0 ) THEN            ! surface mixing length = F(stress) : l=vkarmn*2.e5*taum/(rau0*g)
458         !
459         zraug = vkarmn * 2.e5_wp / ( rau0 * grav )
460#if ! defined key_si3 && ! defined key_cice
461         DO_2D( 0, 0, 0, 0 )
462            zmxlm(ji,jj,1) =  zraug * taum(ji,jj) * tmask(ji,jj,1)
463         END_2D
464#else
465
466         SELECT CASE( nn_mxlice )             ! Type of scaling under sea-ice
467         !
468         CASE( 0 )                      ! No scaling under sea-ice
469            DO_2D( 0, 0, 0, 0 )
470               zmxlm(ji,jj,1) = zraug * taum(ji,jj) * tmask(ji,jj,1)
471            END_2D
472            !
473         CASE( 1 )                      ! scaling with constant sea-ice thickness
474            DO_2D( 0, 0, 0, 0 )
475               zmxlm(ji,jj,1) =  ( ( 1._wp - fr_i(ji,jj) ) * zraug * taum(ji,jj) + &
476                  &                          fr_i(ji,jj)   * rn_mxlice           ) * tmask(ji,jj,1)
477            END_2D
478            !
479         CASE( 2 )                      ! scaling with mean sea-ice thickness
480            DO_2D( 0, 0, 0, 0 )
481#if defined key_si3
482               zmxlm(ji,jj,1) = ( ( 1._wp - fr_i(ji,jj) ) * zraug * taum(ji,jj) + &
483                  &                         fr_i(ji,jj)   * hm_i(ji,jj) * 2._wp ) * tmask(ji,jj,1)
484#elif defined key_cice
485               zmaxice = MAXVAL( h_i(ji,jj,:) )
486               zmxlm(ji,jj,1) = ( ( 1._wp - fr_i(ji,jj) ) * zraug * taum(ji,jj) + &
487                  &                         fr_i(ji,jj)   * zmaxice             ) * tmask(ji,jj,1)
488#endif
489            END_2D
490            !
491         CASE( 3 )                      ! scaling with max sea-ice thickness
492            DO_2D( 0, 0, 0, 0 )
493               zmaxice = MAXVAL( h_i(ji,jj,:) )
494               zmxlm(ji,jj,1) = ( ( 1._wp - fr_i(ji,jj) ) * zraug * taum(ji,jj) + &
495                  &                         fr_i(ji,jj)   * zmaxice             ) * tmask(ji,jj,1)
496            END_2D
497            !
498         END SELECT
499#endif
500         !
501         DO_2D( 0, 0, 0, 0 )
502            zmxlm(ji,jj,1) = MAX( rn_mxl0, zmxlm(ji,jj,1) )
503         END_2D
504         !
505      ELSE
506         zmxlm(:,:,1) = rn_mxl0
507      ENDIF
508      !
509      DO_3D( 0, 0, 0, 0, 2, jpkm1 )
510         zrn2 = MAX( rn2(ji,jj,jk), rsmall )
511         zmxlm(ji,jj,jk) = MAX(  rmxl_min,  SQRT( 2._wp * en(ji,jj,jk) / zrn2 )  )
512      END_3D
513      !
514      !                     !* Physical limits for the mixing length
515      !
516      zmxld(:,:, 1 ) = zmxlm(:,:,1)   ! surface set to the minimum value
517      zmxld(:,:,jpk) = rmxl_min       ! last level  set to the minimum value
518      !
519      SELECT CASE ( nn_mxl )
520      !
521 !!gm Not sure of that coding for ISF....
522      ! where wmask = 0 set zmxlm == p_e3w
523      CASE ( 0 )           ! bounded by the distance to surface and bottom
524         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
525            zemxl = MIN( pdepw(ji,jj,jk) - pdepw(ji,jj,mikt(ji,jj)), zmxlm(ji,jj,jk),   &
526            &            pdepw(ji,jj,mbkt(ji,jj)+1) - pdepw(ji,jj,jk) )
527            ! wmask prevent zmxlm = 0 if jk = mikt(ji,jj)
528            zmxlm(ji,jj,jk) = zemxl * wmask(ji,jj,jk) + MIN( zmxlm(ji,jj,jk) , p_e3w(ji,jj,jk) ) * (1 - wmask(ji,jj,jk))
529            zmxld(ji,jj,jk) = zemxl * wmask(ji,jj,jk) + MIN( zmxlm(ji,jj,jk) , p_e3w(ji,jj,jk) ) * (1 - wmask(ji,jj,jk))
530         END_3D
531         !
532      CASE ( 1 )           ! bounded by the vertical scale factor
533         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
534            zemxl = MIN( p_e3w(ji,jj,jk), zmxlm(ji,jj,jk) )
535            zmxlm(ji,jj,jk) = zemxl
536            zmxld(ji,jj,jk) = zemxl
537         END_3D
538         !
539      CASE ( 2 )           ! |dk[xml]| bounded by e3t :
540         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
541            zmxlm(ji,jj,jk) = MIN( zmxlm(ji,jj,jk-1) + p_e3t(ji,jj,jk-1), zmxlm(ji,jj,jk) )
542         END_3D
543         DO_3D( 0, 0, 0, 0, jpkm1, 2, -1 )
544            zemxl = MIN( zmxlm(ji,jj,jk+1) + p_e3t(ji,jj,jk+1), zmxlm(ji,jj,jk) )
545            zmxlm(ji,jj,jk) = zemxl
546            zmxld(ji,jj,jk) = zemxl
547         END_3D
548         !
549      CASE ( 3 )           ! lup and ldown, |dk[xml]| bounded by e3t :
550         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
551            zmxld(ji,jj,jk) = MIN( zmxld(ji,jj,jk-1) + p_e3t(ji,jj,jk-1), zmxlm(ji,jj,jk) )
552         END_3D
553         DO_3D( 0, 0, 0, 0, jpkm1, 2, -1 )
554            zmxlm(ji,jj,jk) = MIN( zmxlm(ji,jj,jk+1) + p_e3t(ji,jj,jk+1), zmxlm(ji,jj,jk) )
555         END_3D
556         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
557            zemlm = MIN ( zmxld(ji,jj,jk),  zmxlm(ji,jj,jk) )
558            zemlp = SQRT( zmxld(ji,jj,jk) * zmxlm(ji,jj,jk) )
559            zmxlm(ji,jj,jk) = zemlm
560            zmxld(ji,jj,jk) = zemlp
561         END_3D
562         !
563      END SELECT
564      !
565      !                     !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
566      !                     !  Vertical eddy viscosity and diffusivity  (avm and avt)
567      !                     !<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
568      DO_3D( 0, 0, 0, 0, 1, jpkm1 )
569         zsqen = SQRT( en(ji,jj,jk) )
570         zav   = rn_ediff * zmxlm(ji,jj,jk) * zsqen
571         p_avm(ji,jj,jk) = MAX( zav,                  avmb(jk) ) * wmask(ji,jj,jk)
572         p_avt(ji,jj,jk) = MAX( zav, avtb_2d(ji,jj) * avtb(jk) ) * wmask(ji,jj,jk)
573         dissl(ji,jj,jk) = zsqen / zmxld(ji,jj,jk)
574      END_3D
575      !
576      !
577      IF( nn_pdl == 1 ) THEN      !* Prandtl number case: update avt
578         DO_3D( 0, 0, 0, 0, 2, jpkm1 )
579            p_avt(ji,jj,jk)   = MAX( apdlr(ji,jj,jk) * p_avt(ji,jj,jk), avtb_2d(ji,jj) * avtb(jk) ) * wmask(ji,jj,jk)
580         END_3D
581      ENDIF
582      !
583      IF(ln_ctl) THEN
584         CALL prt_ctl( tab3d_1=en   , clinfo1=' tke  - e: ', tab3d_2=p_avt, clinfo2=' t: ', kdim=jpk)
585         CALL prt_ctl( tab3d_1=p_avm, clinfo1=' tke  - m: ', kdim=jpk )
586      ENDIF
587      !
588   END SUBROUTINE tke_avn
589
590
591   SUBROUTINE zdf_tke_init
592      !!----------------------------------------------------------------------
593      !!                  ***  ROUTINE zdf_tke_init  ***
594      !!                     
595      !! ** Purpose :   Initialization of the vertical eddy diffivity and
596      !!              viscosity when using a tke turbulent closure scheme
597      !!
598      !! ** Method  :   Read the namzdf_tke namelist and check the parameters
599      !!              called at the first timestep (nit000)
600      !!
601      !! ** input   :   Namlist namzdf_tke
602      !!
603      !! ** Action  :   Increase by 1 the nstop flag is setting problem encounter
604      !!----------------------------------------------------------------------
605      USE zdf_oce , ONLY : ln_zdfiwm   ! Internal Wave Mixing flag
606      !!
607      INTEGER ::   ji, jj, jk   ! dummy loop indices
608      INTEGER ::   ios
609      !!
610      NAMELIST/namzdf_tke/ rn_ediff, rn_ediss , rn_ebb   , rn_emin  ,  &
611         &                 rn_emin0, rn_bshear, nn_mxl   , ln_mxl0  ,  &
612         &                 rn_mxl0 , nn_mxlice, rn_mxlice,             &
613         &                 nn_pdl  , ln_lc    , rn_lc,                 &
614         &                 nn_etau , nn_htau  , rn_efr   , nn_eice 
615      !!----------------------------------------------------------------------
616      !
617      REWIND( numnam_ref )              ! Namelist namzdf_tke in reference namelist : Turbulent Kinetic Energy
618      READ  ( numnam_ref, namzdf_tke, IOSTAT = ios, ERR = 901)
619901   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namzdf_tke in reference namelist' )
620
621      REWIND( numnam_cfg )              ! Namelist namzdf_tke in configuration namelist : Turbulent Kinetic Energy
622      READ  ( numnam_cfg, namzdf_tke, IOSTAT = ios, ERR = 902 )
623902   IF( ios >  0 ) CALL ctl_nam ( ios , 'namzdf_tke in configuration namelist' )
624      IF(lwm) WRITE ( numond, namzdf_tke )
625      !
626      ri_cri   = 2._wp    / ( 2._wp + rn_ediss / rn_ediff )   ! resulting critical Richardson number
627      !
628      IF(lwp) THEN                    !* Control print
629         WRITE(numout,*)
630         WRITE(numout,*) 'zdf_tke_init : tke turbulent closure scheme - initialisation'
631         WRITE(numout,*) '~~~~~~~~~~~~'
632         WRITE(numout,*) '   Namelist namzdf_tke : set tke mixing parameters'
633         WRITE(numout,*) '      coef. to compute avt                        rn_ediff  = ', rn_ediff
634         WRITE(numout,*) '      Kolmogoroff dissipation coef.               rn_ediss  = ', rn_ediss
635         WRITE(numout,*) '      tke surface input coef.                     rn_ebb    = ', rn_ebb
636         WRITE(numout,*) '      minimum value of tke                        rn_emin   = ', rn_emin
637         WRITE(numout,*) '      surface minimum value of tke                rn_emin0  = ', rn_emin0
638         WRITE(numout,*) '      prandl number flag                          nn_pdl    = ', nn_pdl
639         WRITE(numout,*) '      background shear (>0)                       rn_bshear = ', rn_bshear
640         WRITE(numout,*) '      mixing length type                          nn_mxl    = ', nn_mxl
641         WRITE(numout,*) '         surface mixing length = F(stress) or not    ln_mxl0   = ', ln_mxl0
642         WRITE(numout,*) '         surface  mixing length minimum value        rn_mxl0   = ', rn_mxl0
643         IF( ln_mxl0 ) THEN
644            WRITE(numout,*) '      type of scaling under sea-ice               nn_mxlice = ', nn_mxlice
645            IF( nn_mxlice == 1 ) &
646            WRITE(numout,*) '      ice thickness when scaling under sea-ice    rn_mxlice = ', rn_mxlice
647            SELECT CASE( nn_mxlice )             ! Type of scaling under sea-ice
648            CASE( 0 )   ;   WRITE(numout,*) '   ==>>>   No scaling under sea-ice'
649            CASE( 1 )   ;   WRITE(numout,*) '   ==>>>   scaling with constant sea-ice thickness'
650            CASE( 2 )   ;   WRITE(numout,*) '   ==>>>   scaling with mean sea-ice thickness'
651            CASE( 3 )   ;   WRITE(numout,*) '   ==>>>   scaling with max sea-ice thickness'
652            CASE DEFAULT
653               CALL ctl_stop( 'zdf_tke_init: wrong value for nn_mxlice, should be 0,1,2,3 or 4')
654            END SELECT
655         ENDIF
656         WRITE(numout,*) '      Langmuir cells parametrization              ln_lc     = ', ln_lc
657         WRITE(numout,*) '         coef to compute vertical velocity of LC     rn_lc  = ', rn_lc
658         WRITE(numout,*) '      test param. to add tke induced by wind      nn_etau   = ', nn_etau
659         WRITE(numout,*) '          type of tke penetration profile            nn_htau   = ', nn_htau
660         WRITE(numout,*) '          fraction of TKE that penetrates            rn_efr    = ', rn_efr
661         WRITE(numout,*) '      langmuir & surface wave breaking under ice  nn_eice = ', nn_eice
662         SELECT CASE( nn_eice ) 
663         CASE( 0 )   ;   WRITE(numout,*) '   ==>>>   no impact of ice cover on langmuir & surface wave breaking'
664         CASE( 1 )   ;   WRITE(numout,*) '   ==>>>   weigthed by 1-TANH( fr_i(:,:) * 10 )'
665         CASE( 2 )   ;   WRITE(numout,*) '   ==>>>   weighted by 1-fr_i(:,:)'
666         CASE( 3 )   ;   WRITE(numout,*) '   ==>>>   weighted by 1-MIN( 1, 4 * fr_i(:,:) )'
667         CASE DEFAULT
668            CALL ctl_stop( 'zdf_tke_init: wrong value for nn_eice, should be 0,1,2, or 3')
669         END SELECT     
670         IF( .NOT.ln_drg_OFF ) THEN
671            WRITE(numout,*)
672            WRITE(numout,*) '   Namelist namdrg_top/_bot:   used values:'
673            WRITE(numout,*) '      top    ocean cavity roughness (m)          rn_z0(_top)= ', r_z0_top
674            WRITE(numout,*) '      Bottom seafloor     roughness (m)          rn_z0(_bot)= ', r_z0_bot
675         ENDIF
676         WRITE(numout,*)
677         WRITE(numout,*) '   ==>>>   critical Richardson nb with your parameters  ri_cri = ', ri_cri
678         WRITE(numout,*)
679      ENDIF
680      !
681      IF( ln_zdfiwm ) THEN          ! Internal wave-driven mixing
682         rn_emin  = 1.e-10_wp             ! specific values of rn_emin & rmxl_min are used
683         rmxl_min = 1.e-03_wp             ! associated avt minimum = molecular salt diffusivity (10^-9 m2/s)
684         IF(lwp) WRITE(numout,*) '   ==>>>   Internal wave-driven mixing case:   force   rn_emin = 1.e-10 and rmxl_min = 1.e-3'
685      ELSE                          ! standard case : associated avt minimum = molecular viscosity (10^-6 m2/s)
686         rmxl_min = 1.e-6_wp / ( rn_ediff * SQRT( rn_emin ) )    ! resulting minimum length to recover molecular viscosity
687         IF(lwp) WRITE(numout,*) '   ==>>>   minimum mixing length with your parameters rmxl_min = ', rmxl_min
688      ENDIF
689      !
690      !                              ! allocate tke arrays
691      IF( zdf_tke_alloc() /= 0 )   CALL ctl_stop( 'STOP', 'zdf_tke_init : unable to allocate arrays' )
692      !
693      !                               !* Check of some namelist values
694      IF( nn_mxl  < 0   .OR.  nn_mxl  > 3 )   CALL ctl_stop( 'bad flag: nn_mxl is  0, 1 or 2 ' )
695      IF( nn_pdl  < 0   .OR.  nn_pdl  > 1 )   CALL ctl_stop( 'bad flag: nn_pdl is  0 or 1    ' )
696      IF( nn_htau < 0   .OR.  nn_htau > 1 )   CALL ctl_stop( 'bad flag: nn_htau is 0, 1 or 2 ' )
697      IF( nn_etau == 3 .AND. .NOT. ln_cpl )   CALL ctl_stop( 'nn_etau == 3 : HF taum only known in coupled mode' )
698      !
699      IF( ln_mxl0 ) THEN
700         IF(lwp) WRITE(numout,*)
701         IF(lwp) WRITE(numout,*) '   ==>>>   use a surface mixing length = F(stress) :   set rn_mxl0 = rmxl_min'
702         rn_mxl0 = rmxl_min
703      ENDIF
704     
705      IF( nn_etau == 2  )   CALL zdf_mxl( nit000 )      ! Initialization of nmln
706
707      !                               !* depth of penetration of surface tke
708      IF( nn_etau /= 0 ) THEN     
709         SELECT CASE( nn_htau )             ! Choice of the depth of penetration
710         CASE( 0 )                                 ! constant depth penetration (here 10 meters)
711            htau(:,:) = 10._wp
712         CASE( 1 )                                 ! F(latitude) : 0.5m to 30m poleward of 40 degrees
713            htau(:,:) = MAX(  0.5_wp, MIN( 30._wp, 45._wp* ABS( SIN( rpi/180._wp * gphit(:,:) ) ) )   )           
714         END SELECT
715      ENDIF
716      !                                !* read or initialize all required files
717      CALL tke_rst( nit000, 'READ' )      ! (en, avt_k, avm_k, dissl)
718      !
719      IF( lwxios ) THEN
720         CALL iom_set_rstw_var_active('en')
721         CALL iom_set_rstw_var_active('avt_k')
722         CALL iom_set_rstw_var_active('avm_k')
723         CALL iom_set_rstw_var_active('dissl')
724      ENDIF
725   END SUBROUTINE zdf_tke_init
726
727
728   SUBROUTINE tke_rst( kt, cdrw )
729      !!---------------------------------------------------------------------
730      !!                   ***  ROUTINE tke_rst  ***
731      !!                     
732      !! ** Purpose :   Read or write TKE file (en) in restart file
733      !!
734      !! ** Method  :   use of IOM library
735      !!                if the restart does not contain TKE, en is either
736      !!                set to rn_emin or recomputed
737      !!----------------------------------------------------------------------
738      USE zdf_oce , ONLY : en, avt_k, avm_k   ! ocean vertical physics
739      !!
740      INTEGER         , INTENT(in) ::   kt     ! ocean time-step
741      CHARACTER(len=*), INTENT(in) ::   cdrw   ! "READ"/"WRITE" flag
742      !
743      INTEGER ::   jit, jk              ! dummy loop indices
744      INTEGER ::   id1, id2, id3, id4   ! local integers
745      !!----------------------------------------------------------------------
746      !
747      IF( TRIM(cdrw) == 'READ' ) THEN        ! Read/initialise
748         !                                   ! ---------------
749         IF( ln_rstart ) THEN                   !* Read the restart file
750            id1 = iom_varid( numror, 'en'   , ldstop = .FALSE. )
751            id2 = iom_varid( numror, 'avt_k', ldstop = .FALSE. )
752            id3 = iom_varid( numror, 'avm_k', ldstop = .FALSE. )
753            id4 = iom_varid( numror, 'dissl', ldstop = .FALSE. )
754            !
755            IF( MIN( id1, id2, id3, id4 ) > 0 ) THEN      ! fields exist
756               CALL iom_get( numror, jpdom_autoglo, 'en'   , en   , ldxios = lrxios )
757               CALL iom_get( numror, jpdom_autoglo, 'avt_k', avt_k, ldxios = lrxios )
758               CALL iom_get( numror, jpdom_autoglo, 'avm_k', avm_k, ldxios = lrxios )
759               CALL iom_get( numror, jpdom_autoglo, 'dissl', dissl, ldxios = lrxios )
760            ELSE                                          ! start TKE from rest
761               IF(lwp) WRITE(numout,*)
762               IF(lwp) WRITE(numout,*) '   ==>>>   previous run without TKE scheme, set en to background values'
763               en   (:,:,:) = rn_emin * wmask(:,:,:)
764               dissl(:,:,:) = 1.e-12_wp
765               ! avt_k, avm_k already set to the background value in zdf_phy_init
766            ENDIF
767         ELSE                                   !* Start from rest
768            IF(lwp) WRITE(numout,*)
769            IF(lwp) WRITE(numout,*) '   ==>>>   start from rest: set en to the background value'
770            en   (:,:,:) = rn_emin * wmask(:,:,:)
771            dissl(:,:,:) = 1.e-12_wp
772            ! avt_k, avm_k already set to the background value in zdf_phy_init
773         ENDIF
774         !
775      ELSEIF( TRIM(cdrw) == 'WRITE' ) THEN   ! Create restart file
776         !                                   ! -------------------
777         IF(lwp) WRITE(numout,*) '---- tke_rst ----'
778         IF( lwxios ) CALL iom_swap(      cwxios_context          ) 
779         CALL iom_rstput( kt, nitrst, numrow, 'en'   , en   , ldxios = lwxios )
780         CALL iom_rstput( kt, nitrst, numrow, 'avt_k', avt_k, ldxios = lwxios )
781         CALL iom_rstput( kt, nitrst, numrow, 'avm_k', avm_k, ldxios = lwxios )
782         CALL iom_rstput( kt, nitrst, numrow, 'dissl', dissl, ldxios = lwxios )
783         IF( lwxios ) CALL iom_swap(      cxios_context          )
784         !
785      ENDIF
786      !
787   END SUBROUTINE tke_rst
788
789   !!======================================================================
790END MODULE zdftke
Note: See TracBrowser for help on using the repository browser.