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.
zdfgls.F90 in NEMO/releases/r4.0/r4.0-HEAD/src/OCE/ZDF – NEMO

source: NEMO/releases/r4.0/r4.0-HEAD/src/OCE/ZDF/zdfgls.F90 @ 14590

Last change on this file since 14590 was 14157, checked in by jchanut, 4 years ago

#2560, correct bottom Neumann boundary conditions and bottom friction velocities

  • Property svn:keywords set to Id
File size: 61.4 KB
Line 
1MODULE zdfgls
2   !!======================================================================
3   !!                       ***  MODULE  zdfgls  ***
4   !! Ocean physics:  vertical mixing coefficient computed from the gls
5   !!                 turbulent closure parameterization
6   !!======================================================================
7   !! History :  3.0  !  2009-09  (G. Reffray)  Original code
8   !!            3.3  !  2010-10  (C. Bricaud)  Add in the reference
9   !!            4.0  !  2017-04  (G. Madec)  remove CPP keys & avm at t-point only
10   !!             -   !  2017-05  (G. Madec)  add top friction as boundary condition
11   !!----------------------------------------------------------------------
12
13   !!----------------------------------------------------------------------
14   !!   zdf_gls       : update momentum and tracer Kz from a gls scheme
15   !!   zdf_gls_init  : initialization, namelist read, and parameters control
16   !!   gls_rst       : read/write gls restart in ocean restart file
17   !!----------------------------------------------------------------------
18   USE oce            ! ocean dynamics and active tracers
19   USE dom_oce        ! ocean space and time domain
20   USE domvvl         ! ocean space and time domain : variable volume layer
21   USE zdfdrg  , ONLY : ln_drg_OFF            ! top/bottom free-slip flag
22   USE zdfdrg  , ONLY : r_z0_top , r_z0_bot   ! top/bottom roughness
23   USE zdfdrg  , ONLY : rCdU_top , rCdU_bot   ! top/bottom friction
24   USE sbc_oce        ! surface boundary condition: ocean
25   USE phycst         ! physical constants
26   USE zdfmxl         ! mixed layer
27   USE sbcwave , ONLY : hsw   ! significant wave height
28   !
29   USE lbclnk         ! ocean lateral boundary conditions (or mpp link)
30   USE lib_mpp        ! MPP manager
31   USE prtctl         ! Print control
32   USE in_out_manager ! I/O manager
33   USE iom            ! I/O manager library
34   USE lib_fortran    ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined)
35
36   IMPLICIT NONE
37   PRIVATE
38
39   PUBLIC   zdf_gls        ! called in zdfphy
40   PUBLIC   zdf_gls_init   ! called in zdfphy
41   PUBLIC   gls_rst        ! called in zdfphy
42
43   !
44   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   hmxl_n    !: now mixing length
45   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   zwall   !: wall function
46   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   ustar2_surf !: Squared surface velocity scale at T-points
47   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   ustar2_top  !: Squared top     velocity scale at T-points
48   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   ustar2_bot  !: Squared bottom  velocity scale at T-points
49
50   !                              !! ** Namelist  namzdf_gls  **
51   LOGICAL  ::   ln_length_lim     ! use limit on the dissipation rate under stable stratification (Galperin et al. 1988)
52   LOGICAL  ::   ln_sigpsi         ! Activate Burchard (2003) modification for k-eps closure & wave breaking mixing
53   INTEGER  ::   nn_bc_surf        ! surface boundary condition (=0/1)
54   INTEGER  ::   nn_bc_bot         ! bottom boundary condition (=0/1)
55   INTEGER  ::   nn_z0_met         ! Method for surface roughness computation
56   INTEGER  ::   nn_z0_ice         ! Roughness accounting for sea ice
57   INTEGER  ::   nn_stab_func      ! stability functions G88, KC or Canuto (=0/1/2)
58   INTEGER  ::   nn_clos           ! closure 0/1/2/3 MY82/k-eps/k-w/gen
59   REAL(wp) ::   rn_clim_galp      ! Holt 2008 value for k-eps: 0.267
60   REAL(wp) ::   rn_epsmin         ! minimum value of dissipation (m2/s3)
61   REAL(wp) ::   rn_emin           ! minimum value of TKE (m2/s2)
62   REAL(wp) ::   rn_charn          ! Charnock constant for surface breaking waves mixing : 1400. (standard) or 2.e5 (Stacey value)
63   REAL(wp) ::   rn_crban          ! Craig and Banner constant for surface breaking waves mixing
64   REAL(wp) ::   rn_hsro           ! Minimum surface roughness
65   REAL(wp) ::   rn_hsri           ! Ice ocean roughness
66   REAL(wp) ::   rn_frac_hs        ! Fraction of wave height as surface roughness (if nn_z0_met > 1)
67
68   REAL(wp) ::   rcm_sf        =  0.73_wp     ! Shear free turbulence parameters
69   REAL(wp) ::   ra_sf         = -2.0_wp      ! Must be negative -2 < ra_sf < -1
70   REAL(wp) ::   rl_sf         =  0.2_wp      ! 0 <rl_sf<vkarmn   
71   REAL(wp) ::   rghmin        = -0.28_wp
72   REAL(wp) ::   rgh0          =  0.0329_wp
73   REAL(wp) ::   rghcri        =  0.03_wp
74   REAL(wp) ::   ra1           =  0.92_wp
75   REAL(wp) ::   ra2           =  0.74_wp
76   REAL(wp) ::   rb1           = 16.60_wp
77   REAL(wp) ::   rb2           = 10.10_wp         
78   REAL(wp) ::   re2           =  1.33_wp         
79   REAL(wp) ::   rl1           =  0.107_wp
80   REAL(wp) ::   rl2           =  0.0032_wp
81   REAL(wp) ::   rl3           =  0.0864_wp
82   REAL(wp) ::   rl4           =  0.12_wp
83   REAL(wp) ::   rl5           = 11.9_wp
84   REAL(wp) ::   rl6           =  0.4_wp
85   REAL(wp) ::   rl7           =  0.0_wp
86   REAL(wp) ::   rl8           =  0.48_wp
87   REAL(wp) ::   rm1           =  0.127_wp
88   REAL(wp) ::   rm2           =  0.00336_wp
89   REAL(wp) ::   rm3           =  0.0906_wp
90   REAL(wp) ::   rm4           =  0.101_wp
91   REAL(wp) ::   rm5           = 11.2_wp
92   REAL(wp) ::   rm6           =  0.4_wp
93   REAL(wp) ::   rm7           =  0.0_wp
94   REAL(wp) ::   rm8           =  0.318_wp
95   REAL(wp) ::   rtrans        =  0.1_wp
96   REAL(wp) ::   rc02, rc02r, rc03, rc04                          ! coefficients deduced from above parameters
97   REAL(wp) ::   rsbc_tke1, rsbc_tke2, rfact_tke                  !     -           -           -        -
98   REAL(wp) ::   rsbc_psi1, rsbc_psi2, rfact_psi                  !     -           -           -        -
99   REAL(wp) ::   rsbc_zs1, rsbc_zs2                               !     -           -           -        -
100   REAL(wp) ::   rc0, rc2, rc3, rf6, rcff, rc_diff                !     -           -           -        -
101   REAL(wp) ::   rs0, rs1, rs2, rs4, rs5, rs6                     !     -           -           -        -
102   REAL(wp) ::   rd0, rd1, rd2, rd3, rd4, rd5                     !     -           -           -        -
103   REAL(wp) ::   rsc_tke, rsc_psi, rpsi1, rpsi2, rpsi3, rsc_psi0  !     -           -           -        -
104   REAL(wp) ::   rpsi3m, rpsi3p, rpp, rmm, rnn                    !     -           -           -        -
105   !
106   REAL(wp) ::   r2_3 = 2._wp/3._wp   ! constant=2/3
107
108   !! * Substitutions
109#  include "vectopt_loop_substitute.h90"
110   !!----------------------------------------------------------------------
111   !! NEMO/OCE 4.0 , NEMO Consortium (2018)
112   !! $Id$
113   !! Software governed by the CeCILL license (see ./LICENSE)
114   !!----------------------------------------------------------------------
115CONTAINS
116
117   INTEGER FUNCTION zdf_gls_alloc()
118      !!----------------------------------------------------------------------
119      !!                ***  FUNCTION zdf_gls_alloc  ***
120      !!----------------------------------------------------------------------
121      ALLOCATE( hmxl_n(jpi,jpj,jpk) , ustar2_surf(jpi,jpj) ,                     &
122         &      zwall (jpi,jpj,jpk) , ustar2_top (jpi,jpj) , ustar2_bot(jpi,jpj) , STAT= zdf_gls_alloc )
123         !
124      CALL mpp_sum ( 'zdfgls', zdf_gls_alloc )
125      IF( zdf_gls_alloc /= 0 )   CALL ctl_stop( 'STOP', 'zdf_gls_alloc: failed to allocate arrays' )
126   END FUNCTION zdf_gls_alloc
127
128
129   SUBROUTINE zdf_gls( kt, p_sh2, p_avm, p_avt )
130      !!----------------------------------------------------------------------
131      !!                   ***  ROUTINE zdf_gls  ***
132      !!
133      !! ** Purpose :   Compute the vertical eddy viscosity and diffusivity
134      !!              coefficients using the GLS turbulent closure scheme.
135      !!----------------------------------------------------------------------
136      USE zdf_oce , ONLY : en, avtb, avmb   ! ocean vertical physics
137      !!
138      INTEGER                   , INTENT(in   ) ::   kt             ! ocean time step
139      REAL(wp), DIMENSION(:,:,:), INTENT(in   ) ::   p_sh2          ! shear production term
140      REAL(wp), DIMENSION(:,:,:), INTENT(inout) ::   p_avm, p_avt   !  momentum and tracer Kz (w-points)
141      !
142      INTEGER  ::   ji, jj, jk    ! dummy loop arguments
143      INTEGER  ::   ibot, ibotm1  ! local integers
144      INTEGER  ::   itop, itopp1  !   -       -
145      REAL(wp) ::   zesh2, zsigpsi, zcoef, zex1 , zex2  ! local scalars
146      REAL(wp) ::   ztx2, zty2, zup, zdown, zcof, zdir  !   -      -
147      REAL(wp) ::   zratio, zrn2, zflxb, sh     , z_en  !   -      -
148      REAL(wp) ::   prod, buoy, diss, zdiss, sm         !   -      -
149      REAL(wp) ::   gh, gm, shr, dif, zsqen, zavt, zavm !   -      -
150      REAL(wp) ::   zmsku, zmskv                        !   -      -
151      REAL(wp), DIMENSION(jpi,jpj)     ::   zdep
152      REAL(wp), DIMENSION(jpi,jpj)     ::   zkar
153      REAL(wp), DIMENSION(jpi,jpj)     ::   zflxs       ! Turbulence fluxed induced by internal waves
154      REAL(wp), DIMENSION(jpi,jpj)     ::   zhsro       ! Surface roughness (surface waves)
155      REAL(wp), DIMENSION(jpi,jpj)     ::   zice_fra    ! Tapering of wave breaking under sea ice
156      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   eb          ! tke at time before
157      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   hmxl_b      ! mixing length at time before
158      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   eps         ! dissipation rate
159      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zwall_psi   ! Wall function use in the wb case (ln_sigpsi)
160      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   psi         ! psi at time now
161      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zd_lw, zd_up, zdiag   ! lower, upper  and diagonal of the matrix
162      REAL(wp), DIMENSION(jpi,jpj,jpk) ::   zstt, zstm  ! stability function on tracer and momentum
163      !!--------------------------------------------------------------------
164      !
165      ! Preliminary computing
166
167      ustar2_surf(:,:) = 0._wp   ;         psi(:,:,:) = 0._wp   
168      ustar2_top (:,:) = 0._wp   ;   zwall_psi(:,:,:) = 0._wp
169      ustar2_bot (:,:) = 0._wp
170
171      SELECT CASE ( nn_z0_ice )
172      CASE( 0 )   ;   zice_fra(:,:) = 0._wp
173      CASE( 1 )   ;   zice_fra(:,:) =        TANH( fr_i(:,:) * 10._wp )
174      CASE( 2 )   ;   zice_fra(:,:) =              fr_i(:,:)
175      CASE( 3 )   ;   zice_fra(:,:) = MIN( 4._wp * fr_i(:,:) , 1._wp )
176      END SELECT
177     
178      ! Compute surface, top and bottom friction at T-points
179      DO jj = 2, jpjm1              !==  surface ocean friction
180         DO ji = fs_2, fs_jpim1           ! vector opt.         
181            ustar2_surf(ji,jj) = r1_rau0 * taum(ji,jj) * tmask(ji,jj,1)
182         END DO
183      END DO
184      !   
185!!gm Rq we may add here r_ke0(_top/_bot) ?  ==>> think about that...
186      !   
187      IF( .NOT.ln_drg_OFF ) THEN    !== top/bottom friction   (explicit before friction)
188         DO jj = 2, jpjm1                      ! bottom friction
189            DO ji = fs_2, fs_jpim1   ! vector opt.         
190               zmsku = 0.5_wp * ( 2._wp - umask(ji-1,jj,mbkt(ji,jj)) * umask(ji,jj,mbkt(ji,jj)) )
191               zmskv = 0.5_wp * ( 2._wp - vmask(ji,jj-1,mbkt(ji,jj)) * vmask(ji,jj,mbkt(ji,jj)) )     ! (CAUTION: CdU<0)
192               ustar2_bot(ji,jj) = - rCdU_bot(ji,jj) * SQRT(  ( zmsku*( ub(ji,jj,mbkt(ji,jj))+ub(ji-1,jj,mbkt(ji,jj)) ) )**2  &
193                  &                                         + ( zmskv*( vb(ji,jj,mbkt(ji,jj))+vb(ji,jj-1,mbkt(ji,jj)) ) )**2  )
194            END DO
195         END DO
196         IF( ln_isfcav ) THEN       !top friction
197            DO jj = 2, jpjm1
198               DO ji = fs_2, fs_jpim1   ! vector opt.
199                  zmsku = 0.5_wp * ( 2._wp - umask(ji-1,jj,mikt(ji,jj)) * umask(ji,jj,mikt(ji,jj)) )
200                  zmskv = 0.5_wp * ( 2._wp - vmask(ji,jj-1,mikt(ji,jj)) * vmask(ji,jj,mikt(ji,jj)) )     ! (CAUTION: CdU<0)
201                  ustar2_top(ji,jj) = - rCdU_top(ji,jj) * SQRT(  ( zmsku*( ub(ji,jj,mikt(ji,jj))+ub(ji-1,jj,mikt(ji,jj)) ) )**2  &
202                     &                                         + ( zmskv*( vb(ji,jj,mikt(ji,jj))+vb(ji,jj-1,mikt(ji,jj)) ) )**2  )
203               END DO
204            END DO
205         ENDIF
206      ENDIF
207   
208      SELECT CASE ( nn_z0_met )      !==  Set surface roughness length  ==!
209      CASE ( 0 )                          ! Constant roughness         
210         zhsro(:,:) = rn_hsro
211      CASE ( 1 )             ! Standard Charnock formula
212         zhsro(:,:) = MAX( rsbc_zs1 * ustar2_surf(:,:) , rn_hsro )
213      CASE ( 2 )             ! Roughness formulae according to Rascle et al., Ocean Modelling (2008)
214!!gm faster coding : the 2 comment lines should be used
215!!gm         zcof = 2._wp * 0.6_wp / 28._wp
216!!gm         zdep(:,:)  = 30._wp * TANH(  zcof/ SQRT( MAX(ustar2_surf(:,:),rsmall) )  )       ! Wave age (eq. 10)
217         zdep (:,:) = 30.*TANH( 2.*0.3/(28.*SQRT(MAX(ustar2_surf(:,:),rsmall))) )         ! Wave age (eq. 10)
218         zhsro(:,:) = MAX(rsbc_zs2 * ustar2_surf(:,:) * zdep(:,:)**1.5, rn_hsro)          ! zhsro = rn_frac_hs * Hsw (eq. 11)
219      CASE ( 3 )             ! Roughness given by the wave model (coupled or read in file)
220         zhsro(:,:) = MAX(rn_frac_hs * hsw(:,:), rn_hsro)   ! (rn_frac_hs=1.6 see Eq. (5) of Rascle et al. 2008 )
221      END SELECT
222      !
223      ! adapt roughness where there is sea ice
224      zhsro(:,:) = ( (1._wp-zice_fra(:,:)) * zhsro(:,:) + zice_fra(:,:) * rn_hsri )*tmask(:,:,1)  + (1._wp - tmask(:,:,1))*rn_hsro
225      !
226      DO jk = 2, jpkm1              !==  Compute dissipation rate  ==!
227         DO jj = 2, jpjm1
228            DO ji = 2, jpim1
229               eps(ji,jj,jk)  = rc03 * en(ji,jj,jk) * SQRT( en(ji,jj,jk) ) / hmxl_n(ji,jj,jk)
230            END DO
231         END DO
232      END DO
233
234      ! Save tke at before time step
235      eb    (:,:,:) = en    (:,:,:)
236      hmxl_b(:,:,:) = hmxl_n(:,:,:)
237
238      IF( nn_clos == 0 ) THEN    ! Mellor-Yamada
239         DO jk = 2, jpkm1
240            DO jj = 2, jpjm1 
241               DO ji = fs_2, fs_jpim1   ! vector opt.
242                  zup   = hmxl_n(ji,jj,jk) * gdepw_n(ji,jj,mbkt(ji,jj)+1)
243                  zdown = vkarmn * gdepw_n(ji,jj,jk) * ( -gdepw_n(ji,jj,jk) + gdepw_n(ji,jj,mbkt(ji,jj)+1) )
244                  zcoef = ( zup / MAX( zdown, rsmall ) )
245                  zwall (ji,jj,jk) = ( 1._wp + re2 * zcoef*zcoef ) * tmask(ji,jj,jk)
246               END DO
247            END DO
248         END DO
249      ENDIF
250
251      !!---------------------------------!!
252      !!   Equation to prognostic k      !!
253      !!---------------------------------!!
254      !
255      ! Now Turbulent kinetic energy (output in en)
256      ! -------------------------------
257      ! Resolution of a tridiagonal linear system by a "methode de chasse"
258      ! computation from level 2 to jpkm1  (e(1) computed after and e(jpk)=0 ).
259      ! The surface boundary condition are set after
260      ! The bottom boundary condition are also set after. In standard e(bottom)=0.
261      ! zdiag : diagonal zd_up : upper diagonal zd_lw : lower diagonal
262      ! Warning : after this step, en : right hand side of the matrix
263
264      DO jk = 2, jpkm1
265         DO jj = 2, jpjm1
266            DO ji = 2, jpim1
267               !
268               buoy = - p_avt(ji,jj,jk) * rn2(ji,jj,jk)     ! stratif. destruction
269               !
270               diss = eps(ji,jj,jk)                         ! dissipation
271               !
272               zdir = 0.5_wp + SIGN( 0.5_wp, p_sh2(ji,jj,jk) + buoy )   ! zdir =1(=0) if shear(ji,jj,jk)+buoy >0(<0)
273               !
274               zesh2 = zdir*(p_sh2(ji,jj,jk)+buoy)+(1._wp-zdir)*p_sh2(ji,jj,jk)          ! production term
275               zdiss = zdir*(diss/en(ji,jj,jk))   +(1._wp-zdir)*(diss-buoy)/en(ji,jj,jk) ! dissipation term
276!!gm better coding, identical results
277!               zesh2 =   p_sh2(ji,jj,jk) + zdir*buoy               ! production term
278!               zdiss = ( diss - (1._wp-zdir)*buoy ) / en(ji,jj,jk) ! dissipation term
279!!gm
280               !
281               ! Compute a wall function from 1. to rsc_psi*zwall/rsc_psi0
282               ! Note that as long that Dirichlet boundary conditions are NOT set at the first and last levels (GOTM style)
283               ! there is no need to set a boundary condition for zwall_psi at the top and bottom boundaries.
284               ! Otherwise, this should be rsc_psi/rsc_psi0
285               IF( ln_sigpsi ) THEN
286                  zsigpsi = MIN( 1._wp, zesh2 / eps(ji,jj,jk) )     ! 0. <= zsigpsi <= 1.
287                  zwall_psi(ji,jj,jk) = rsc_psi /   & 
288                     &     (  zsigpsi * rsc_psi + (1._wp-zsigpsi) * rsc_psi0 / MAX( zwall(ji,jj,jk), 1._wp )  )
289               ELSE
290                  zwall_psi(ji,jj,jk) = 1._wp
291               ENDIF
292               !
293               ! building the matrix
294               zcof = rfact_tke * tmask(ji,jj,jk)
295               !                                        ! lower diagonal, in fact not used for jk = 2 (see surface conditions)
296               zd_lw(ji,jj,jk) = zcof * ( p_avm(ji,jj,jk  ) + p_avm(ji,jj,jk-1) ) / ( e3t_n(ji,jj,jk-1) * e3w_n(ji,jj,jk) )
297               !                                        ! upper diagonal, in fact not used for jk = ibotm1 (see bottom conditions)
298               zd_up(ji,jj,jk) = zcof * ( p_avm(ji,jj,jk+1) + p_avm(ji,jj,jk  ) ) / ( e3t_n(ji,jj,jk  ) * e3w_n(ji,jj,jk) )
299               !                                        ! diagonal
300               zdiag(ji,jj,jk) = 1._wp - zd_lw(ji,jj,jk) - zd_up(ji,jj,jk)  + rdt * zdiss * wmask(ji,jj,jk) 
301               !                                        ! right hand side in en
302               en(ji,jj,jk) = en(ji,jj,jk) + rdt * zesh2 * wmask(ji,jj,jk)
303            END DO
304         END DO
305      END DO
306      !
307      zdiag(:,:,jpk) = 1._wp
308      !
309      ! Set surface condition on zwall_psi (1 at the bottom)
310      zwall_psi(:,:, 1 ) = zwall_psi(:,:,2)
311      zwall_psi(:,:,jpk) = 1._wp
312      !
313      ! Surface boundary condition on tke
314      ! ---------------------------------
315      !
316      SELECT CASE ( nn_bc_surf )
317      !
318      CASE ( 0 )             ! Dirichlet boundary condition (set e at k=1 & 2)
319      ! First level
320      en   (:,:,1) = MAX(  rn_emin , rc02r * ustar2_surf(:,:) * (1._wp + (1._wp-zice_fra(:,:))*rsbc_tke1)**r2_3  )
321      zd_lw(:,:,1) = en(:,:,1)
322      zd_up(:,:,1) = 0._wp
323      zdiag(:,:,1) = 1._wp
324      !
325      ! One level below
326      en   (:,:,2) =  MAX(  rc02r * ustar2_surf(:,:) * (  1._wp + (1._wp-zice_fra(:,:))*rsbc_tke1 * ((zhsro(:,:)+gdepw_n(:,:,2)) &
327         &                 / zhsro(:,:) )**(1.5_wp*ra_sf)  )**(2._wp/3._wp) , rn_emin   )
328      zd_lw(:,:,2) = 0._wp 
329      zd_up(:,:,2) = 0._wp
330      zdiag(:,:,2) = 1._wp
331      !
332      !
333      CASE ( 1 )             ! Neumann boundary condition (set d(e)/dz)
334      !
335      ! Dirichlet conditions at k=1
336      en   (:,:,1) = MAX(  rc02r * ustar2_surf(:,:) * (1._wp + (1._wp-zice_fra(:,:))*rsbc_tke1)**r2_3 , rn_emin  )
337      zd_lw(:,:,1) = en(:,:,1)
338      zd_up(:,:,1) = 0._wp
339      zdiag(:,:,1) = 1._wp
340      !
341      ! at k=2, set de/dz=Fw
342      !cbr
343      zdiag(:,:,2) = zdiag(:,:,2) +  zd_lw(:,:,2) ! Remove zd_lw from zdiag
344      zd_lw(:,:,2) = 0._wp
345      zkar (:,:)   = (rl_sf + (vkarmn-rl_sf)*(1.-EXP(-rtrans*gdept_n(:,:,1)/zhsro(:,:)) ))
346      zflxs(:,:)   = rsbc_tke2 * (1._wp-zice_fra(:,:)) * ustar2_surf(:,:)**1.5_wp * zkar(:,:) &
347          &                    * (  ( zhsro(:,:)+gdept_n(:,:,1) ) / zhsro(:,:)  )**(1.5_wp*ra_sf)
348!!gm why not   :                        * ( 1._wp + gdept_n(:,:,1) / zhsro(:,:) )**(1.5_wp*ra_sf)
349      en(:,:,2) = en(:,:,2) + zflxs(:,:) / e3w_n(:,:,2)
350      !
351      !
352      END SELECT
353
354      ! Bottom boundary condition on tke
355      ! --------------------------------
356      !
357      SELECT CASE ( nn_bc_bot )
358      !
359      CASE ( 0 )             ! Dirichlet
360         !                      ! en(ibot) = u*^2 / Co2 and hmxl_n(ibot) = rn_lmin
361         !                      ! Balance between the production and the dissipation terms
362         DO jj = 2, jpjm1
363            DO ji = fs_2, fs_jpim1   ! vector opt.
364!!gm This means that bottom and ocean w-level above have a specified "en" value.   Sure ????
365!!   With thick deep ocean level thickness, this may be quite large, no ???
366!!   in particular in ocean cavities where top stratification can be large...
367               ibot   = mbkt(ji,jj) + 1      ! k   bottom level of w-point
368               ibotm1 = mbkt(ji,jj)          ! k-1 bottom level of w-point but >=1
369               !
370               z_en =  MAX( rc02r * ustar2_bot(ji,jj), rn_emin )
371               !
372               ! Dirichlet condition applied at:
373               !     Bottom level (ibot)      &      Just above it (ibotm1)   
374               zd_lw(ji,jj,ibot) = 0._wp   ;   zd_lw(ji,jj,ibotm1) = 0._wp
375               zd_up(ji,jj,ibot) = 0._wp   ;   zd_up(ji,jj,ibotm1) = 0._wp
376               zdiag(ji,jj,ibot) = 1._wp   ;   zdiag(ji,jj,ibotm1) = 1._wp
377               en   (ji,jj,ibot) = z_en    ;   en   (ji,jj,ibotm1) = z_en
378            END DO
379         END DO
380         !
381         IF( ln_isfcav) THEN     ! top boundary   (ocean cavity)
382            DO jj = 2, jpjm1
383               DO ji = fs_2, fs_jpim1   ! vector opt.
384                  itop   = mikt(ji,jj)       ! k   top w-point
385                  itopp1 = mikt(ji,jj) + 1   ! k+1 1st w-point below the top one
386                  !                                                ! mask at the ocean surface points
387                  z_en = MAX( rc02r * ustar2_top(ji,jj), rn_emin ) * ( 1._wp - tmask(ji,jj,1) )
388                  !
389 !!gm TO BE VERIFIED !!!
390                  ! Dirichlet condition applied at:
391                  !     top level (itop)         &      Just below it (itopp1)   
392                  zd_lw(ji,jj,itop) = 0._wp   ;   zd_lw(ji,jj,itopp1) = 0._wp
393                  zd_up(ji,jj,itop) = 0._wp   ;   zd_up(ji,jj,itopp1) = 0._wp
394                  zdiag(ji,jj,itop) = 1._wp   ;   zdiag(ji,jj,itopp1) = 1._wp
395                  en   (ji,jj,itop) = z_en    ;   en   (ji,jj,itopp1) = z_en
396               END DO
397            END DO
398         ENDIF
399         !
400      CASE ( 1 )             ! Neumman boundary condition
401         !                     
402         DO jj = 2, jpjm1
403            DO ji = fs_2, fs_jpim1   ! vector opt.
404               ibot   = mbkt(ji,jj) + 1      ! k   bottom level of w-point
405               ibotm1 = mbkt(ji,jj)          ! k-1 bottom level of w-point but >=1
406               !
407               z_en =  MAX( rc02r * ustar2_bot(ji,jj), rn_emin )
408               !
409               ! Bottom level Dirichlet condition:
410               !     Bottom level (ibot)      &      Just above it (ibotm1)   
411               !         Dirichlet            !         Neumann
412               zd_lw(ji,jj,ibot) = 0._wp   !   ! Remove zd_up from zdiag
413               zdiag(ji,jj,ibot) = 1._wp   ;   zdiag(ji,jj,ibotm1) = zdiag(ji,jj,ibotm1) + zd_up(ji,jj,ibotm1)
414               zd_up(ji,jj,ibot) = 0._wp   ;   zd_up(ji,jj,ibotm1) = 0._wp
415               en   (ji,jj,ibot) = z_en
416            END DO
417         END DO
418         IF( ln_isfcav) THEN     ! top boundary   (ocean cavity)
419            DO jj = 2, jpjm1
420               DO ji = fs_2, fs_jpim1   ! vector opt.
421                  itop   = mikt(ji,jj)       ! k   top w-point
422                  itopp1 = mikt(ji,jj) + 1   ! k+1 1st w-point below the top one
423                  !                                                ! mask at the ocean surface points
424                  z_en = MAX( rc02r * ustar2_top(ji,jj), rn_emin ) * ( 1._wp - tmask(ji,jj,1) )
425                  !
426                  ! Bottom level Dirichlet condition:
427                  !     Bottom level (ibot)      &      Just above it (ibotm1)   
428                  !         Dirichlet            !         Neumann
429                  zd_lw(ji,jj,itop) = 0._wp   !   ! Remove zd_up from zdiag
430                  zdiag(ji,jj,itop) = 1._wp   ;   zdiag(ji,jj,itopp1) = zdiag(ji,jj,itopp1) + zd_up(ji,jj,itopp1)
431                  zd_up(ji,jj,itop) = 0._wp   ;   zd_up(ji,jj,itopp1) = 0._wp
432                  en   (ji,jj,itop) = z_en
433               END DO
434            END DO
435         ENDIF
436         !
437      END SELECT
438
439      ! Matrix inversion (en prescribed at surface and the bottom)
440      ! ----------------------------------------------------------
441      !
442      DO jk = 2, jpkm1                             ! First recurrence : Dk = Dk - Lk * Uk-1 / Dk-1
443         DO jj = 2, jpjm1
444            DO ji = fs_2, fs_jpim1    ! vector opt.
445               zdiag(ji,jj,jk) = zdiag(ji,jj,jk) - zd_lw(ji,jj,jk) * zd_up(ji,jj,jk-1) / zdiag(ji,jj,jk-1)
446            END DO
447         END DO
448      END DO
449      DO jk = 2, jpkm1                             ! Second recurrence : Lk = RHSk - Lk / Dk-1 * Lk-1
450         DO jj = 2, jpjm1
451            DO ji = fs_2, fs_jpim1    ! vector opt.
452               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)
453            END DO
454         END DO
455      END DO
456      DO jk = jpkm1, 2, -1                         ! thrid recurrence : Ek = ( Lk - Uk * Ek+1 ) / Dk
457         DO jj = 2, jpjm1
458            DO ji = fs_2, fs_jpim1    ! vector opt.
459               en(ji,jj,jk) = ( zd_lw(ji,jj,jk) - zd_up(ji,jj,jk) * en(ji,jj,jk+1) ) / zdiag(ji,jj,jk)
460            END DO
461         END DO
462      END DO
463      !                                            ! set the minimum value of tke
464      en(:,:,:) = MAX( en(:,:,:), rn_emin )
465
466      !!----------------------------------------!!
467      !!   Solve prognostic equation for psi    !!
468      !!----------------------------------------!!
469
470      ! Set psi to previous time step value
471      !
472      SELECT CASE ( nn_clos )
473      !
474      CASE( 0 )               ! k-kl  (Mellor-Yamada)
475         DO jk = 2, jpkm1
476            DO jj = 2, jpjm1
477               DO ji = fs_2, fs_jpim1   ! vector opt.
478                  psi(ji,jj,jk)  = eb(ji,jj,jk) * hmxl_b(ji,jj,jk)
479               END DO
480            END DO
481         END DO
482         !
483      CASE( 1 )               ! k-eps
484         DO jk = 2, jpkm1
485            DO jj = 2, jpjm1
486               DO ji = fs_2, fs_jpim1   ! vector opt.
487                  psi(ji,jj,jk)  = eps(ji,jj,jk)
488               END DO
489            END DO
490         END DO
491         !
492      CASE( 2 )               ! k-w
493         DO jk = 2, jpkm1
494            DO jj = 2, jpjm1
495               DO ji = fs_2, fs_jpim1   ! vector opt.
496                  psi(ji,jj,jk)  = SQRT( eb(ji,jj,jk) ) / ( rc0 * hmxl_b(ji,jj,jk) )
497               END DO
498            END DO
499         END DO
500         !
501      CASE( 3 )               ! generic
502         DO jk = 2, jpkm1
503            DO jj = 2, jpjm1
504               DO ji = fs_2, fs_jpim1   ! vector opt.
505                  psi(ji,jj,jk)  = rc02 * eb(ji,jj,jk) * hmxl_b(ji,jj,jk)**rnn 
506               END DO
507            END DO
508         END DO
509         !
510      END SELECT
511      !
512      ! Now gls (output in psi)
513      ! -------------------------------
514      ! Resolution of a tridiagonal linear system by a "methode de chasse"
515      ! computation from level 2 to jpkm1  (e(1) already computed and e(jpk)=0 ).
516      ! zdiag : diagonal zd_up : upper diagonal zd_lw : lower diagonal
517      ! Warning : after this step, en : right hand side of the matrix
518
519      DO jk = 2, jpkm1
520         DO jj = 2, jpjm1
521            DO ji = fs_2, fs_jpim1   ! vector opt.
522               !
523               ! psi / k
524               zratio = psi(ji,jj,jk) / eb(ji,jj,jk) 
525               !
526               ! psi3+ : stable : B=-KhN²<0 => N²>0 if rn2>0 zdir = 1 (stable) otherwise zdir = 0 (unstable)
527               zdir = 0.5_wp + SIGN( 0.5_wp, rn2(ji,jj,jk) )
528               !
529               rpsi3 = zdir * rpsi3m + ( 1._wp - zdir ) * rpsi3p
530               !
531               ! shear prod. - stratif. destruction
532               prod = rpsi1 * zratio * p_sh2(ji,jj,jk)
533               !
534               ! stratif. destruction
535               buoy = rpsi3 * zratio * (- p_avt(ji,jj,jk) * rn2(ji,jj,jk) )
536               !
537               ! shear prod. - stratif. destruction
538               diss = rpsi2 * zratio * zwall(ji,jj,jk) * eps(ji,jj,jk)
539               !
540               zdir = 0.5_wp + SIGN( 0.5_wp, prod + buoy )     ! zdir =1(=0) if shear(ji,jj,jk)+buoy >0(<0)
541               !
542               zesh2 = zdir * ( prod + buoy )          + (1._wp - zdir ) * prod                        ! production term
543               zdiss = zdir * ( diss / psi(ji,jj,jk) ) + (1._wp - zdir ) * (diss-buoy) / psi(ji,jj,jk) ! dissipation term
544               !                                                       
545               ! building the matrix
546               zcof = rfact_psi * zwall_psi(ji,jj,jk) * tmask(ji,jj,jk)
547               !                                               ! lower diagonal
548               zd_lw(ji,jj,jk) = zcof * ( p_avm(ji,jj,jk  ) + p_avm(ji,jj,jk-1) ) / ( e3t_n(ji,jj,jk-1) * e3w_n(ji,jj,jk) )
549               !                                               ! upper diagonal
550               zd_up(ji,jj,jk) = zcof * ( p_avm(ji,jj,jk+1) + p_avm(ji,jj,jk  ) ) / ( e3t_n(ji,jj,jk  ) * e3w_n(ji,jj,jk) )
551               !                                               ! diagonal
552               zdiag(ji,jj,jk) = 1._wp - zd_lw(ji,jj,jk) - zd_up(ji,jj,jk) + rdt * zdiss * wmask(ji,jj,jk)
553               !                                               ! right hand side in psi
554               psi(ji,jj,jk) = psi(ji,jj,jk) + rdt * zesh2 * wmask(ji,jj,jk)
555            END DO
556         END DO
557      END DO
558      !
559      zdiag(:,:,jpk) = 1._wp
560
561      ! Surface boundary condition on psi
562      ! ---------------------------------
563      !
564      SELECT CASE ( nn_bc_surf )
565      !
566      CASE ( 0 )             ! Dirichlet boundary conditions
567         !
568         ! Surface value
569         zdep    (:,:)   = zhsro(:,:) * rl_sf ! Cosmetic
570         psi     (:,:,1) = rc0**rpp * en(:,:,1)**rmm * zdep(:,:)**rnn * tmask(:,:,1)
571         zd_lw(:,:,1) = psi(:,:,1)
572         zd_up(:,:,1) = 0._wp
573         zdiag(:,:,1) = 1._wp
574         !
575         ! One level below
576         zkar    (:,:)   = (rl_sf + (vkarmn-rl_sf)*(1._wp-EXP(-rtrans*gdepw_n(:,:,2)/zhsro(:,:) )))
577         zdep    (:,:)   = (zhsro(:,:) + gdepw_n(:,:,2)) * zkar(:,:)
578         psi     (:,:,2) = rc0**rpp * en(:,:,2)**rmm * zdep(:,:)**rnn * tmask(:,:,1)
579         zd_lw(:,:,2) = 0._wp
580         zd_up(:,:,2) = 0._wp
581         zdiag(:,:,2) = 1._wp
582         !
583      CASE ( 1 )             ! Neumann boundary condition on d(psi)/dz
584         !
585         ! Surface value: Dirichlet
586         zdep    (:,:)   = zhsro(:,:) * rl_sf
587         psi     (:,:,1) = rc0**rpp * en(:,:,1)**rmm * zdep(:,:)**rnn * tmask(:,:,1)
588         zd_lw(:,:,1) = psi(:,:,1)
589         zd_up(:,:,1) = 0._wp
590         zdiag(:,:,1) = 1._wp
591         !
592         ! Neumann condition at k=2
593         zdiag(:,:,2) = zdiag(:,:,2) +  zd_lw(:,:,2) ! Remove zd_lw from zdiag
594         zd_lw(:,:,2) = 0._wp
595         !
596         ! Set psi vertical flux at the surface:
597         zkar (:,:)   = rl_sf + (vkarmn-rl_sf)*(1._wp-EXP(-rtrans*gdept_n(:,:,1)/zhsro(:,:) )) ! Lengh scale slope
598         zdep (:,:)   = ((zhsro(:,:) + gdept_n(:,:,1)) / zhsro(:,:))**(rmm*ra_sf)
599         zflxs(:,:)   = (rnn + (1._wp-zice_fra(:,:))*rsbc_tke1 * (rnn + rmm*ra_sf) * zdep(:,:)) &
600            &           *(1._wp + (1._wp-zice_fra(:,:))*rsbc_tke1*zdep(:,:))**(2._wp*rmm/3._wp-1_wp)
601         zdep (:,:)   = rsbc_psi1 * (zwall_psi(:,:,1)*p_avm(:,:,1)+zwall_psi(:,:,2)*p_avm(:,:,2)) * &
602            &           ustar2_surf(:,:)**rmm * zkar(:,:)**rnn * (zhsro(:,:) + gdept_n(:,:,1))**(rnn-1.)
603         zflxs(:,:)   = zdep(:,:) * zflxs(:,:)
604         psi  (:,:,2) = psi(:,:,2) + zflxs(:,:) / e3w_n(:,:,2)
605         !
606      END SELECT
607
608      ! Bottom boundary condition on psi
609      ! --------------------------------
610      !
611!!gm should be done for ISF (top boundary cond.)
612!!gm so, totally new staff needed      ===>>> think about that !
613!
614      SELECT CASE ( nn_bc_bot )     ! bottom boundary
615      !
616      CASE ( 0 )             ! Dirichlet
617         !                      ! en(ibot) = u*^2 / Co2 and hmxl_n(ibot) = vkarmn * r_z0_bot
618         !                      ! Balance between the production and the dissipation terms
619         DO jj = 2, jpjm1
620            DO ji = fs_2, fs_jpim1   ! vector opt.
621               ibot   = mbkt(ji,jj) + 1      ! k   bottom level of w-point
622               ibotm1 = mbkt(ji,jj)          ! k-1 bottom level of w-point but >=1
623               zdep(ji,jj) = vkarmn * r_z0_bot
624               psi (ji,jj,ibot) = rc0**rpp * en(ji,jj,ibot)**rmm * zdep(ji,jj)**rnn
625               zd_lw(ji,jj,ibot) = 0._wp
626               zd_up(ji,jj,ibot) = 0._wp
627               zdiag(ji,jj,ibot) = 1._wp
628               !
629               ! Just above last level, Dirichlet condition again (GOTM like)
630               zdep(ji,jj) = vkarmn * ( r_z0_bot + e3t_n(ji,jj,ibotm1) )
631               psi (ji,jj,ibotm1) = rc0**rpp * en(ji,jj,ibot  )**rmm * zdep(ji,jj)**rnn
632               zd_lw(ji,jj,ibotm1) = 0._wp
633               zd_up(ji,jj,ibotm1) = 0._wp
634               zdiag(ji,jj,ibotm1) = 1._wp
635            END DO
636         END DO
637         !
638      CASE ( 1 )             ! Neumman boundary condition
639         !                     
640         DO jj = 2, jpjm1
641            DO ji = fs_2, fs_jpim1   ! vector opt.
642               ibot   = mbkt(ji,jj) + 1      ! k   bottom level of w-point
643               ibotm1 = mbkt(ji,jj)          ! k-1 bottom level of w-point but >=1
644               !
645               ! Bottom level Dirichlet condition:
646               zdep(ji,jj) = vkarmn * r_z0_bot
647               psi (ji,jj,ibot) = rc0**rpp * en(ji,jj,ibot)**rmm * zdep(ji,jj)**rnn
648               !
649               zd_lw(ji,jj,ibot) = 0._wp
650               zd_up(ji,jj,ibot) = 0._wp
651               zdiag(ji,jj,ibot) = 1._wp
652               !
653               ! Just above last level: Neumann condition with flux injection
654               zdiag(ji,jj,ibotm1) = zdiag(ji,jj,ibotm1) + zd_up(ji,jj,ibotm1) ! Remove zd_up from zdiag
655               zd_up(ji,jj,ibotm1) = 0.
656               !
657               ! Set psi vertical flux at the bottom:
658               zdep(ji,jj) = r_z0_bot + 0.5_wp*e3t_n(ji,jj,ibotm1)
659               zflxb = rsbc_psi2 * ( p_avm(ji,jj,ibot) + p_avm(ji,jj,ibotm1) )   &
660                  &  * (0.5_wp*(en(ji,jj,ibot)+en(ji,jj,ibotm1)))**rmm * zdep(ji,jj)**(rnn-1._wp)
661               psi(ji,jj,ibotm1) = psi(ji,jj,ibotm1) + zflxb / e3w_n(ji,jj,ibotm1)
662            END DO
663         END DO
664         !
665      END SELECT
666
667      ! Matrix inversion
668      ! ----------------
669      !
670      DO jk = 2, jpkm1                             ! First recurrence : Dk = Dk - Lk * Uk-1 / Dk-1
671         DO jj = 2, jpjm1
672            DO ji = fs_2, fs_jpim1    ! vector opt.
673               zdiag(ji,jj,jk) = zdiag(ji,jj,jk) - zd_lw(ji,jj,jk) * zd_up(ji,jj,jk-1) / zdiag(ji,jj,jk-1)
674            END DO
675         END DO
676      END DO
677      DO jk = 2, jpkm1                             ! Second recurrence : Lk = RHSk - Lk / Dk-1 * Lk-1
678         DO jj = 2, jpjm1
679            DO ji = fs_2, fs_jpim1    ! vector opt.
680               zd_lw(ji,jj,jk) = psi(ji,jj,jk) - zd_lw(ji,jj,jk) / zdiag(ji,jj,jk-1) * zd_lw(ji,jj,jk-1)
681            END DO
682         END DO
683      END DO
684      DO jk = jpkm1, 2, -1                         ! Third recurrence : Ek = ( Lk - Uk * Ek+1 ) / Dk
685         DO jj = 2, jpjm1
686            DO ji = fs_2, fs_jpim1    ! vector opt.
687               psi(ji,jj,jk) = ( zd_lw(ji,jj,jk) - zd_up(ji,jj,jk) * psi(ji,jj,jk+1) ) / zdiag(ji,jj,jk)
688            END DO
689         END DO
690      END DO
691
692      ! Set dissipation
693      !----------------
694
695      SELECT CASE ( nn_clos )
696      !
697      CASE( 0 )               ! k-kl  (Mellor-Yamada)
698         DO jk = 1, jpkm1
699            DO jj = 2, jpjm1
700               DO ji = fs_2, fs_jpim1   ! vector opt.
701                  eps(ji,jj,jk) = rc03 * en(ji,jj,jk) * en(ji,jj,jk) * SQRT( en(ji,jj,jk) ) / MAX( psi(ji,jj,jk), rn_epsmin)
702               END DO
703            END DO
704         END DO
705         !
706      CASE( 1 )               ! k-eps
707         DO jk = 1, jpkm1
708            DO jj = 2, jpjm1
709               DO ji = fs_2, fs_jpim1   ! vector opt.
710                  eps(ji,jj,jk) = psi(ji,jj,jk)
711               END DO
712            END DO
713         END DO
714         !
715      CASE( 2 )               ! k-w
716         DO jk = 1, jpkm1
717            DO jj = 2, jpjm1
718               DO ji = fs_2, fs_jpim1   ! vector opt.
719                  eps(ji,jj,jk) = rc04 * en(ji,jj,jk) * psi(ji,jj,jk) 
720               END DO
721            END DO
722         END DO
723         !
724      CASE( 3 )               ! generic
725         zcoef = rc0**( 3._wp  + rpp/rnn )
726         zex1  =      ( 1.5_wp + rmm/rnn )
727         zex2  = -1._wp / rnn
728         DO jk = 1, jpkm1
729            DO jj = 2, jpjm1
730               DO ji = fs_2, fs_jpim1   ! vector opt.
731                  eps(ji,jj,jk) = zcoef * en(ji,jj,jk)**zex1 * psi(ji,jj,jk)**zex2
732               END DO
733            END DO
734         END DO
735         !
736      END SELECT
737
738      ! Limit dissipation rate under stable stratification
739      ! --------------------------------------------------
740      DO jk = 1, jpkm1 ! Note that this set boundary conditions on hmxl_n at the same time
741         DO jj = 2, jpjm1
742            DO ji = fs_2, fs_jpim1    ! vector opt.
743               ! limitation
744               eps   (ji,jj,jk)  = MAX( eps(ji,jj,jk), rn_epsmin )
745               hmxl_n(ji,jj,jk)  = rc03 * en(ji,jj,jk) * SQRT( en(ji,jj,jk) ) / eps(ji,jj,jk)
746               ! Galperin criterium (NOTE : Not required if the proper value of C3 in stable cases is calculated)
747               zrn2 = MAX( rn2(ji,jj,jk), rsmall )
748               IF( ln_length_lim )   hmxl_n(ji,jj,jk) = MIN(  rn_clim_galp * SQRT( 2._wp * en(ji,jj,jk) / zrn2 ), hmxl_n(ji,jj,jk) )
749            END DO
750         END DO
751      END DO 
752
753      !
754      ! Stability function and vertical viscosity and diffusivity
755      ! ---------------------------------------------------------
756      !
757      SELECT CASE ( nn_stab_func )
758      !
759      CASE ( 0 , 1 )             ! Galperin or Kantha-Clayson stability functions
760         DO jk = 2, jpkm1
761            DO jj = 2, jpjm1
762               DO ji = fs_2, fs_jpim1   ! vector opt.
763                  ! zcof =  l²/q²
764                  zcof = hmxl_b(ji,jj,jk) * hmxl_b(ji,jj,jk) / ( 2._wp*eb(ji,jj,jk) )
765                  ! Gh = -N²l²/q²
766                  gh = - rn2(ji,jj,jk) * zcof
767                  gh = MIN( gh, rgh0   )
768                  gh = MAX( gh, rghmin )
769                  ! Stability functions from Kantha and Clayson (if C2=C3=0 => Galperin)
770                  sh = ra2*( 1._wp-6._wp*ra1/rb1 ) / ( 1.-3.*ra2*gh*(6.*ra1+rb2*( 1._wp-rc3 ) ) )
771                  sm = ( rb1**(-1._wp/3._wp) + ( 18._wp*ra1*ra1 + 9._wp*ra1*ra2*(1._wp-rc2) )*sh*gh ) / (1._wp-9._wp*ra1*ra2*gh)
772                  !
773                  ! Store stability function in zstt and zstm
774                  zstt(ji,jj,jk) = rc_diff * sh * tmask(ji,jj,jk)
775                  zstm(ji,jj,jk) = rc_diff * sm * tmask(ji,jj,jk)
776               END DO
777            END DO
778         END DO
779         !
780      CASE ( 2, 3 )               ! Canuto stability functions
781         DO jk = 2, jpkm1
782            DO jj = 2, jpjm1
783               DO ji = fs_2, fs_jpim1   ! vector opt.
784                  ! zcof =  l²/q²
785                  zcof = hmxl_b(ji,jj,jk)*hmxl_b(ji,jj,jk) / ( 2._wp * eb(ji,jj,jk) )
786                  ! Gh = -N²l²/q²
787                  gh = - rn2(ji,jj,jk) * zcof
788                  gh = MIN( gh, rgh0   )
789                  gh = MAX( gh, rghmin )
790                  gh = gh * rf6
791                  ! Gm =  M²l²/q² Shear number
792                  shr = p_sh2(ji,jj,jk) / MAX( p_avm(ji,jj,jk), rsmall )
793                  gm = MAX( shr * zcof , 1.e-10 )
794                  gm = gm * rf6
795                  gm = MIN ( (rd0 - rd1*gh + rd3*gh*gh) / (rd2-rd4*gh) , gm )
796                  ! Stability functions from Canuto
797                  rcff = rd0 - rd1*gh +rd2*gm + rd3*gh*gh - rd4*gh*gm + rd5*gm*gm
798                  sm = (rs0 - rs1*gh + rs2*gm) / rcff
799                  sh = (rs4 - rs5*gh + rs6*gm) / rcff
800                  !
801                  ! Store stability function in zstt and zstm
802                  zstt(ji,jj,jk) = rc_diff * sh * tmask(ji,jj,jk)
803                  zstm(ji,jj,jk) = rc_diff * sm * tmask(ji,jj,jk)
804               END DO
805            END DO
806         END DO
807         !
808      END SELECT
809
810      ! Boundary conditions on stability functions for momentum (Neumann):
811      ! Lines below are useless if GOTM style Dirichlet conditions are used
812
813      zstm(:,:,1) = zstm(:,:,2)
814
815      ! default value, in case jpk > mbkt(ji,jj)+1. Not needed but avoid a bug when looking for undefined values (-fpe0)
816      zstm(:,:,jpk) = 0. 
817      DO jj = 2, jpjm1                ! update bottom with good values
818         DO ji = fs_2, fs_jpim1   ! vector opt.
819            zstm(ji,jj,mbkt(ji,jj)+1) = zstm(ji,jj,mbkt(ji,jj))
820         END DO
821      END DO
822
823      zstt(:,:,  1) = wmask(:,:,  1)  ! default value not needed but avoid a bug when looking for undefined values (-fpe0)
824      zstt(:,:,jpk) = wmask(:,:,jpk)  ! default value not needed but avoid a bug when looking for undefined values (-fpe0)
825
826!!gm should be done for ISF (top boundary cond.)
827!!gm so, totally new staff needed!!gm
828
829      ! Compute diffusivities/viscosities
830      ! The computation below could be restrained to jk=2 to jpkm1 if GOTM style Dirichlet conditions are used
831      !  -> yes BUT p_avm(:,:1) and p_avm(:,:jpk) are used when we compute zd_lw(:,:2) and zd_up(:,:jpkm1). These values are
832      !     later overwritten by surface/bottom boundaries conditions, so we don't really care of p_avm(:,:1) and p_avm(:,:jpk)
833      !     for zd_lw and zd_up but they have to be defined to avoid a bug when looking for undefined values (-fpe0)
834      DO jk = 1, jpk
835         DO jj = 2, jpjm1
836            DO ji = fs_2, fs_jpim1   ! vector opt.
837               zsqen = SQRT( 2._wp * en(ji,jj,jk) ) * hmxl_n(ji,jj,jk)
838               zavt  = zsqen * zstt(ji,jj,jk)
839               zavm  = zsqen * zstm(ji,jj,jk)
840               p_avt(ji,jj,jk) = MAX( zavt, avtb(jk) ) * wmask(ji,jj,jk) ! apply mask for zdfmxl routine
841               p_avm(ji,jj,jk) = MAX( zavm, avmb(jk) )                   ! Note that avm is not masked at the surface and the bottom
842            END DO
843         END DO
844      END DO
845      p_avt(:,:,1) = 0._wp
846      !
847      IF(ln_ctl) THEN
848         CALL prt_ctl( tab3d_1=en   , clinfo1=' gls  - e: ', tab3d_2=p_avt, clinfo2=' t: ', kdim=jpk)
849         CALL prt_ctl( tab3d_1=p_avm, clinfo1=' gls  - m: ', kdim=jpk )
850      ENDIF
851      !
852   END SUBROUTINE zdf_gls
853
854
855   SUBROUTINE zdf_gls_init
856      !!----------------------------------------------------------------------
857      !!                  ***  ROUTINE zdf_gls_init  ***
858      !!                     
859      !! ** Purpose :   Initialization of the vertical eddy diffivity and
860      !!              viscosity computed using a GLS turbulent closure scheme
861      !!
862      !! ** Method  :   Read the namzdf_gls namelist and check the parameters
863      !!
864      !! ** input   :   Namlist namzdf_gls
865      !!
866      !! ** Action  :   Increase by 1 the nstop flag is setting problem encounter
867      !!
868      !!----------------------------------------------------------------------
869      INTEGER ::   jk    ! dummy loop indices
870      INTEGER ::   ios   ! Local integer output status for namelist read
871      REAL(wp)::   zcr   ! local scalar
872      !!
873      NAMELIST/namzdf_gls/rn_emin, rn_epsmin, ln_length_lim,       &
874         &            rn_clim_galp, ln_sigpsi, rn_hsro, rn_hsri,   &
875         &            rn_crban, rn_charn, rn_frac_hs,              &
876         &            nn_bc_surf, nn_bc_bot, nn_z0_met, nn_z0_ice, &
877         &            nn_stab_func, nn_clos
878      !!----------------------------------------------------------
879      !
880      REWIND( numnam_ref )              ! Namelist namzdf_gls in reference namelist : Vertical eddy diffivity and viscosity using gls turbulent closure scheme
881      READ  ( numnam_ref, namzdf_gls, IOSTAT = ios, ERR = 901)
882901   IF( ios /= 0 )   CALL ctl_nam ( ios , 'namzdf_gls in reference namelist' )
883
884      REWIND( numnam_cfg )              ! Namelist namzdf_gls in configuration namelist : Vertical eddy diffivity and viscosity using gls turbulent closure scheme
885      READ  ( numnam_cfg, namzdf_gls, IOSTAT = ios, ERR = 902 )
886902   IF( ios >  0 )   CALL ctl_nam ( ios , 'namzdf_gls in configuration namelist' )
887      IF(lwm) WRITE ( numond, namzdf_gls )
888
889      IF(lwp) THEN                     !* Control print
890         WRITE(numout,*)
891         WRITE(numout,*) 'zdf_gls_init : GLS turbulent closure scheme'
892         WRITE(numout,*) '~~~~~~~~~~~~'
893         WRITE(numout,*) '   Namelist namzdf_gls : set gls mixing parameters'
894         WRITE(numout,*) '      minimum value of en                           rn_emin        = ', rn_emin
895         WRITE(numout,*) '      minimum value of eps                          rn_epsmin      = ', rn_epsmin
896         WRITE(numout,*) '      Limit dissipation rate under stable stratif.  ln_length_lim  = ', ln_length_lim
897         WRITE(numout,*) '      Galperin limit (Standard: 0.53, Holt: 0.26)   rn_clim_galp   = ', rn_clim_galp
898         WRITE(numout,*) '      TKE Surface boundary condition                nn_bc_surf     = ', nn_bc_surf
899         WRITE(numout,*) '      TKE Bottom boundary condition                 nn_bc_bot      = ', nn_bc_bot
900         WRITE(numout,*) '      Modify psi Schmidt number (wb case)           ln_sigpsi      = ', ln_sigpsi
901         WRITE(numout,*) '      Craig and Banner coefficient                  rn_crban       = ', rn_crban
902         WRITE(numout,*) '      Charnock coefficient                          rn_charn       = ', rn_charn
903         WRITE(numout,*) '      Surface roughness formula                     nn_z0_met      = ', nn_z0_met
904         WRITE(numout,*) '      surface wave breaking under ice               nn_z0_ice      = ', nn_z0_ice
905         SELECT CASE( nn_z0_ice )
906         CASE( 0 )   ;   WRITE(numout,*) '   ==>>>   no impact of ice cover on surface wave breaking'
907         CASE( 1 )   ;   WRITE(numout,*) '   ==>>>   roughness uses rn_hsri and is weigthed by 1-TANH( fr_i(:,:) * 10 )'
908         CASE( 2 )   ;   WRITE(numout,*) '   ==>>>   roughness uses rn_hsri and is weighted by 1-fr_i(:,:)'
909         CASE( 3 )   ;   WRITE(numout,*) '   ==>>>   roughness uses rn_hsri and is weighted by 1-MIN( 1, 4 * fr_i(:,:) )'
910         CASE DEFAULT
911            CALL ctl_stop( 'zdf_gls_init: wrong value for nn_z0_ice, should be 0,1,2, or 3')
912         END SELECT
913         WRITE(numout,*) '      Wave height frac. (used if nn_z0_met=2)       rn_frac_hs     = ', rn_frac_hs
914         WRITE(numout,*) '      Stability functions                           nn_stab_func   = ', nn_stab_func
915         WRITE(numout,*) '      Type of closure                               nn_clos        = ', nn_clos
916         WRITE(numout,*) '      Surface roughness (m)                         rn_hsro        = ', rn_hsro
917         WRITE(numout,*) '      Ice-ocean roughness (used if nn_z0_ice/=0)    rn_hsri        = ', rn_hsri
918         WRITE(numout,*)
919         WRITE(numout,*) '   Namelist namdrg_top/_bot:   used values:'
920         WRITE(numout,*) '      top    ocean cavity roughness (m)             rn_z0(_top)   = ', r_z0_top
921         WRITE(numout,*) '      Bottom seafloor     roughness (m)             rn_z0(_bot)   = ', r_z0_bot
922         WRITE(numout,*)
923      ENDIF
924
925      !                                !* allocate GLS arrays
926      IF( zdf_gls_alloc() /= 0 )   CALL ctl_stop( 'STOP', 'zdf_gls_init : unable to allocate arrays' )
927
928      !                                !* Check of some namelist values
929      IF( nn_bc_surf < 0   .OR. nn_bc_surf   > 1 )              CALL ctl_stop( 'zdf_gls_init: bad flag: nn_bc_surf is 0 or 1' )
930      IF( nn_bc_surf < 0   .OR. nn_bc_surf   > 1 )              CALL ctl_stop( 'zdf_gls_init: bad flag: nn_bc_surf is 0 or 1' )
931      IF( nn_z0_met  < 0   .OR. nn_z0_met    > 3 )              CALL ctl_stop( 'zdf_gls_init: bad flag: nn_z0_met is 0, 1, 2 or 3' )
932      IF( nn_z0_met == 3  .AND. .NOT. (ln_wave .AND. ln_sdw ) ) CALL ctl_stop( 'zdf_gls_init: nn_z0_met=3 requires ln_wave=T and ln_sdw=T' )
933      IF( nn_stab_func < 0 .OR. nn_stab_func > 3 )              CALL ctl_stop( 'zdf_gls_init: bad flag: nn_stab_func is 0, 1, 2 and 3' )
934      IF( nn_clos      < 0 .OR. nn_clos      > 3 )              CALL ctl_stop( 'zdf_gls_init: bad flag: nn_clos is 0, 1, 2 or 3' )
935
936      SELECT CASE ( nn_clos )          !* set the parameters for the chosen closure
937      !
938      CASE( 0 )                              ! k-kl  (Mellor-Yamada)
939         !
940         IF(lwp) WRITE(numout,*) '   ==>>   k-kl closure chosen (i.e. closed to the classical Mellor-Yamada)'
941         IF(lwp) WRITE(numout,*)
942         rpp     = 0._wp
943         rmm     = 1._wp
944         rnn     = 1._wp
945         rsc_tke = 1.96_wp
946         rsc_psi = 1.96_wp
947         rpsi1   = 0.9_wp
948         rpsi3p  = 1._wp
949         rpsi2   = 0.5_wp
950         !
951         SELECT CASE ( nn_stab_func )
952         CASE( 0, 1 )   ;   rpsi3m = 2.53_wp       ! G88 or KC stability functions
953         CASE( 2 )      ;   rpsi3m = 2.62_wp       ! Canuto A stability functions
954         CASE( 3 )      ;   rpsi3m = 2.38          ! Canuto B stability functions (caution : constant not identified)
955         END SELECT
956         !
957      CASE( 1 )                              ! k-eps
958         !
959         IF(lwp) WRITE(numout,*) '   ==>>   k-eps closure chosen'
960         IF(lwp) WRITE(numout,*)
961         rpp     =  3._wp
962         rmm     =  1.5_wp
963         rnn     = -1._wp
964         rsc_tke =  1._wp
965         rsc_psi =  1.2_wp  ! Schmidt number for psi
966         rpsi1   =  1.44_wp
967         rpsi3p  =  1._wp
968         rpsi2   =  1.92_wp
969         !
970         SELECT CASE ( nn_stab_func )
971         CASE( 0, 1 )   ;   rpsi3m = -0.52_wp      ! G88 or KC stability functions
972         CASE( 2 )      ;   rpsi3m = -0.629_wp     ! Canuto A stability functions
973         CASE( 3 )      ;   rpsi3m = -0.566        ! Canuto B stability functions
974         END SELECT
975         !
976      CASE( 2 )                              ! k-omega
977         !
978         IF(lwp) WRITE(numout,*) '   ==>>   k-omega closure chosen'
979         IF(lwp) WRITE(numout,*)
980         rpp     = -1._wp
981         rmm     =  0.5_wp
982         rnn     = -1._wp
983         rsc_tke =  2._wp
984         rsc_psi =  2._wp
985         rpsi1   =  0.555_wp
986         rpsi3p  =  1._wp
987         rpsi2   =  0.833_wp
988         !
989         SELECT CASE ( nn_stab_func )
990         CASE( 0, 1 )   ;   rpsi3m = -0.58_wp       ! G88 or KC stability functions
991         CASE( 2 )      ;   rpsi3m = -0.64_wp       ! Canuto A stability functions
992         CASE( 3 )      ;   rpsi3m = -0.64_wp       ! Canuto B stability functions caution : constant not identified)
993         END SELECT
994         !
995      CASE( 3 )                              ! generic
996         !
997         IF(lwp) WRITE(numout,*) '   ==>>   generic closure chosen'
998         IF(lwp) WRITE(numout,*)
999         rpp     = 2._wp
1000         rmm     = 1._wp
1001         rnn     = -0.67_wp
1002         rsc_tke = 0.8_wp
1003         rsc_psi = 1.07_wp
1004         rpsi1   = 1._wp
1005         rpsi3p  = 1._wp
1006         rpsi2   = 1.22_wp
1007         !
1008         SELECT CASE ( nn_stab_func )
1009         CASE( 0, 1 )   ;   rpsi3m = 0.1_wp         ! G88 or KC stability functions
1010         CASE( 2 )      ;   rpsi3m = 0.05_wp        ! Canuto A stability functions
1011         CASE( 3 )      ;   rpsi3m = 0.05_wp        ! Canuto B stability functions caution : constant not identified)
1012         END SELECT
1013         !
1014      END SELECT
1015
1016      !
1017      SELECT CASE ( nn_stab_func )     !* set the parameters of the stability functions
1018      !
1019      CASE ( 0 )                             ! Galperin stability functions
1020         !
1021         IF(lwp) WRITE(numout,*) '   ==>>   Stability functions from Galperin'
1022         rc2     =  0._wp
1023         rc3     =  0._wp
1024         rc_diff =  1._wp
1025         rc0     =  0.5544_wp
1026         rcm_sf  =  0.9884_wp
1027         rghmin  = -0.28_wp
1028         rgh0    =  0.0233_wp
1029         rghcri  =  0.02_wp
1030         !
1031      CASE ( 1 )                             ! Kantha-Clayson stability functions
1032         !
1033         IF(lwp) WRITE(numout,*) '   ==>>   Stability functions from Kantha-Clayson'
1034         rc2     =  0.7_wp
1035         rc3     =  0.2_wp
1036         rc_diff =  1._wp
1037         rc0     =  0.5544_wp
1038         rcm_sf  =  0.9884_wp
1039         rghmin  = -0.28_wp
1040         rgh0    =  0.0233_wp
1041         rghcri  =  0.02_wp
1042         !
1043      CASE ( 2 )                             ! Canuto A stability functions
1044         !
1045         IF(lwp) WRITE(numout,*) '   ==>>   Stability functions from Canuto A'
1046         rs0 = 1.5_wp * rl1 * rl5*rl5
1047         rs1 = -rl4*(rl6+rl7) + 2._wp*rl4*rl5*(rl1-(1._wp/3._wp)*rl2-rl3) + 1.5_wp*rl1*rl5*rl8
1048         rs2 = -(3._wp/8._wp) * rl1*(rl6*rl6-rl7*rl7)
1049         rs4 = 2._wp * rl5
1050         rs5 = 2._wp * rl4
1051         rs6 = (2._wp/3._wp) * rl5 * ( 3._wp*rl3*rl3 - rl2*rl2 ) - 0.5_wp * rl5*rl1 * (3._wp*rl3-rl2)   &
1052            &                                                    + 0.75_wp * rl1 * ( rl6 - rl7 )
1053         rd0 = 3._wp * rl5*rl5
1054         rd1 = rl5 * ( 7._wp*rl4 + 3._wp*rl8 )
1055         rd2 = rl5*rl5 * ( 3._wp*rl3*rl3 - rl2*rl2 ) - 0.75_wp*(rl6*rl6 - rl7*rl7 )
1056         rd3 = rl4 * ( 4._wp*rl4 + 3._wp*rl8)
1057         rd4 = rl4 * ( rl2 * rl6 - 3._wp*rl3*rl7 - rl5*(rl2*rl2 - rl3*rl3 ) ) + rl5*rl8 * ( 3._wp*rl3*rl3 - rl2*rl2 )
1058         rd5 = 0.25_wp * ( rl2*rl2 - 3._wp *rl3*rl3 ) * ( rl6*rl6 - rl7*rl7 )
1059         rc0 = 0.5268_wp
1060         rf6 = 8._wp / (rc0**6._wp)
1061         rc_diff = SQRT(2._wp) / (rc0**3._wp)
1062         rcm_sf  =  0.7310_wp
1063         rghmin  = -0.28_wp
1064         rgh0    =  0.0329_wp
1065         rghcri  =  0.03_wp
1066         !
1067      CASE ( 3 )                             ! Canuto B stability functions
1068         !
1069         IF(lwp) WRITE(numout,*) '   ==>>   Stability functions from Canuto B'
1070         rs0 = 1.5_wp * rm1 * rm5*rm5
1071         rs1 = -rm4 * (rm6+rm7) + 2._wp * rm4*rm5*(rm1-(1._wp/3._wp)*rm2-rm3) + 1.5_wp * rm1*rm5*rm8
1072         rs2 = -(3._wp/8._wp) * rm1 * (rm6*rm6-rm7*rm7 )
1073         rs4 = 2._wp * rm5
1074         rs5 = 2._wp * rm4
1075         rs6 = (2._wp/3._wp) * rm5 * (3._wp*rm3*rm3-rm2*rm2) - 0.5_wp * rm5*rm1*(3._wp*rm3-rm2) + 0.75_wp * rm1*(rm6-rm7)
1076         rd0 = 3._wp * rm5*rm5
1077         rd1 = rm5 * (7._wp*rm4 + 3._wp*rm8)
1078         rd2 = rm5*rm5 * (3._wp*rm3*rm3 - rm2*rm2) - 0.75_wp * (rm6*rm6 - rm7*rm7)
1079         rd3 = rm4 * ( 4._wp*rm4 + 3._wp*rm8 )
1080         rd4 = rm4 * ( rm2*rm6 -3._wp*rm3*rm7 - rm5*(rm2*rm2 - rm3*rm3) ) + rm5 * rm8 * ( 3._wp*rm3*rm3 - rm2*rm2 )
1081         rd5 = 0.25_wp * ( rm2*rm2 - 3._wp*rm3*rm3 ) * ( rm6*rm6 - rm7*rm7 )
1082         rc0 = 0.5268_wp            !!       rc0 = 0.5540_wp (Warner ...) to verify !
1083         rf6 = 8._wp / ( rc0**6._wp )
1084         rc_diff = SQRT(2._wp)/(rc0**3.)
1085         rcm_sf  =  0.7470_wp
1086         rghmin  = -0.28_wp
1087         rgh0    =  0.0444_wp
1088         rghcri  =  0.0414_wp
1089         !
1090      END SELECT
1091   
1092      !                                !* Set Schmidt number for psi diffusion in the wave breaking case
1093      !                                     ! See Eq. (13) of Carniel et al, OM, 30, 225-239, 2009
1094      !                                     !  or Eq. (17) of Burchard, JPO, 31, 3133-3145, 2001
1095      IF( ln_sigpsi ) THEN
1096         ra_sf = -1.5 ! Set kinetic energy slope, then deduce rsc_psi and rl_sf
1097         ! Verification: retrieve Burchard (2001) results by uncomenting the line below:
1098         ! Note that the results depend on the value of rn_cm_sf which is constant (=rc0) in his work
1099         ! ra_sf = -SQRT(2./3.*rc0**3./rn_cm_sf*rn_sc_tke)/vkarmn
1100         rsc_psi0 = rsc_tke/(24.*rpsi2)*(-1.+(4.*rnn + ra_sf*(1.+4.*rmm))**2./(ra_sf**2.))
1101      ELSE
1102         rsc_psi0 = rsc_psi
1103      ENDIF
1104 
1105      !                                !* Shear free turbulence parameters
1106      !
1107      ra_sf  = -4._wp*rnn*SQRT(rsc_tke) / ( (1._wp+4._wp*rmm)*SQRT(rsc_tke) &
1108               &                              - SQRT(rsc_tke + 24._wp*rsc_psi0*rpsi2 ) )
1109
1110      IF ( rn_crban==0._wp ) THEN
1111         rl_sf = vkarmn
1112      ELSE
1113         rl_sf = rc0 * SQRT(rc0/rcm_sf) * SQRT( ( (1._wp + 4._wp*rmm + 8._wp*rmm**2_wp) * rsc_tke        &
1114            &                                            + 12._wp*rsc_psi0*rpsi2 - (1._wp + 4._wp*rmm)   &
1115            &                                                     *SQRT(rsc_tke*(rsc_tke                 &
1116            &                                                        + 24._wp*rsc_psi0*rpsi2)) )         &
1117            &                                              /(12._wp*rnn**2.)                             )
1118      ENDIF
1119
1120      !
1121      IF(lwp) THEN                     !* Control print
1122         WRITE(numout,*)
1123         WRITE(numout,*) '   Limit values :'
1124         WRITE(numout,*) '      Parameter  m = ', rmm
1125         WRITE(numout,*) '      Parameter  n = ', rnn
1126         WRITE(numout,*) '      Parameter  p = ', rpp
1127         WRITE(numout,*) '      rpsi1    = ', rpsi1
1128         WRITE(numout,*) '      rpsi2    = ', rpsi2
1129         WRITE(numout,*) '      rpsi3m   = ', rpsi3m
1130         WRITE(numout,*) '      rpsi3p   = ', rpsi3p
1131         WRITE(numout,*) '      rsc_tke  = ', rsc_tke
1132         WRITE(numout,*) '      rsc_psi  = ', rsc_psi
1133         WRITE(numout,*) '      rsc_psi0 = ', rsc_psi0
1134         WRITE(numout,*) '      rc0      = ', rc0
1135         WRITE(numout,*)
1136         WRITE(numout,*) '   Shear free turbulence parameters:'
1137         WRITE(numout,*) '      rcm_sf   = ', rcm_sf
1138         WRITE(numout,*) '      ra_sf    = ', ra_sf
1139         WRITE(numout,*) '      rl_sf    = ', rl_sf
1140      ENDIF
1141
1142      !                                !* Constants initialization
1143      rc02  = rc0  * rc0   ;   rc02r = 1. / rc02
1144      rc03  = rc02 * rc0
1145      rc04  = rc03 * rc0
1146      rsbc_tke1 = -3._wp/2._wp*rn_crban*ra_sf*rl_sf                      ! Dirichlet + Wave breaking
1147      rsbc_tke2 = rdt * rn_crban / rl_sf                                 ! Neumann + Wave breaking
1148      zcr = MAX(rsmall, rsbc_tke1**(1./(-ra_sf*3._wp/2._wp))-1._wp )
1149      rtrans = 0.2_wp / zcr                                              ! Ad. inverse transition length between log and wave layer
1150      rsbc_zs1  = rn_charn/grav                                          ! Charnock formula for surface roughness
1151      rsbc_zs2  = rn_frac_hs / 0.85_wp / grav * 665._wp                  ! Rascle formula for surface roughness
1152      rsbc_psi1 = -0.5_wp * rdt * rc0**(rpp-2._wp*rmm) / rsc_psi
1153      rsbc_psi2 = -0.5_wp * rdt * rc0**rpp * rnn * vkarmn**rnn / rsc_psi ! Neumann + NO Wave breaking
1154      !
1155      rfact_tke = -0.5_wp / rsc_tke * rdt                                ! Cst used for the Diffusion term of tke
1156      rfact_psi = -0.5_wp / rsc_psi * rdt                                ! Cst used for the Diffusion term of tke
1157      !
1158      !                                !* Wall proximity function
1159!!gm tmask or wmask ????
1160      zwall(:,:,:) = 1._wp * tmask(:,:,:)
1161
1162      !                                !* read or initialize all required files 
1163      CALL gls_rst( nit000, 'READ' )      ! (en, avt_k, avm_k, hmxl_n)
1164      !
1165      IF( lwxios ) THEN
1166         CALL iom_set_rstw_var_active('en')
1167         CALL iom_set_rstw_var_active('avt_k')
1168         CALL iom_set_rstw_var_active('avm_k')
1169         CALL iom_set_rstw_var_active('hmxl_n')
1170      ENDIF
1171      !
1172   END SUBROUTINE zdf_gls_init
1173
1174
1175   SUBROUTINE gls_rst( kt, cdrw )
1176      !!---------------------------------------------------------------------
1177      !!                   ***  ROUTINE gls_rst  ***
1178      !!                     
1179      !! ** Purpose :   Read or write TKE file (en) in restart file
1180      !!
1181      !! ** Method  :   use of IOM library
1182      !!                if the restart does not contain TKE, en is either
1183      !!                set to rn_emin or recomputed (nn_igls/=0)
1184      !!----------------------------------------------------------------------
1185      USE zdf_oce , ONLY : en, avt_k, avm_k   ! ocean vertical physics
1186      !!
1187      INTEGER         , INTENT(in) ::   kt     ! ocean time-step
1188      CHARACTER(len=*), INTENT(in) ::   cdrw   ! "READ"/"WRITE" flag
1189      !
1190      INTEGER ::   jit, jk   ! dummy loop indices
1191      INTEGER ::   id1, id2, id3, id4
1192      INTEGER ::   ji, jj, ikbu, ikbv
1193      REAL(wp)::   cbx, cby
1194      !!----------------------------------------------------------------------
1195      !
1196      IF( TRIM(cdrw) == 'READ' ) THEN        ! Read/initialise
1197         !                                   ! ---------------
1198         IF( ln_rstart ) THEN                   !* Read the restart file
1199            id1 = iom_varid( numror, 'en'    , ldstop = .FALSE. )
1200            id2 = iom_varid( numror, 'avt_k' , ldstop = .FALSE. )
1201            id3 = iom_varid( numror, 'avm_k' , ldstop = .FALSE. )
1202            id4 = iom_varid( numror, 'hmxl_n', ldstop = .FALSE. )
1203            !
1204            IF( MIN( id1, id2, id3, id4 ) > 0 ) THEN        ! all required arrays exist
1205               CALL iom_get( numror, jpdom_autoglo, 'en'    , en    , ldxios = lrxios )
1206               CALL iom_get( numror, jpdom_autoglo, 'avt_k' , avt_k , ldxios = lrxios )
1207               CALL iom_get( numror, jpdom_autoglo, 'avm_k' , avm_k , ldxios = lrxios )
1208               CALL iom_get( numror, jpdom_autoglo, 'hmxl_n', hmxl_n, ldxios = lrxios )
1209            ELSE                       
1210               IF(lwp) WRITE(numout,*)
1211               IF(lwp) WRITE(numout,*) '   ==>>   previous run without GLS scheme, set en and hmxl_n to background values'
1212               en    (:,:,:) = rn_emin
1213               hmxl_n(:,:,:) = 0.05_wp
1214               ! avt_k, avm_k already set to the background value in zdf_phy_init
1215            ENDIF
1216         ELSE                                   !* Start from rest
1217            IF(lwp) WRITE(numout,*)
1218            IF(lwp) WRITE(numout,*) '   ==>>   start from rest, set en and hmxl_n by background values'
1219            en    (:,:,:) = rn_emin
1220            hmxl_n(:,:,:) = 0.05_wp
1221            ! avt_k, avm_k already set to the background value in zdf_phy_init
1222         ENDIF
1223         !
1224      ELSEIF( TRIM(cdrw) == 'WRITE' ) THEN   ! Create restart file
1225         !                                   ! -------------------
1226         IF(lwp) WRITE(numout,*) '---- gls-rst ----'
1227         IF( lwxios ) CALL iom_swap(      cwxios_context         )
1228         CALL iom_rstput( kt, nitrst, numrow, 'en'    , en    , ldxios = lwxios )
1229         CALL iom_rstput( kt, nitrst, numrow, 'avt_k' , avt_k , ldxios = lwxios )
1230         CALL iom_rstput( kt, nitrst, numrow, 'avm_k' , avm_k , ldxios = lwxios )
1231         CALL iom_rstput( kt, nitrst, numrow, 'hmxl_n', hmxl_n, ldxios = lwxios )
1232         IF( lwxios ) CALL iom_swap(      cxios_context          )
1233         !
1234      ENDIF
1235      !
1236   END SUBROUTINE gls_rst
1237
1238   !!======================================================================
1239END MODULE zdfgls
1240
Note: See TracBrowser for help on using the repository browser.