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.
zdftmx.F90 in branches/UKMO/dev_r5518_GO6_package/NEMOGCM/NEMO/OPA_SRC/ZDF – NEMO

source: branches/UKMO/dev_r5518_GO6_package/NEMOGCM/NEMO/OPA_SRC/ZDF/zdftmx.F90 @ 11101

Last change on this file since 11101 was 11101, checked in by frrh, 5 years ago

Merge changes from Met Office GMED ticket 450 to reduce unnecessary
text output from NEMO.
This output, which is typically not switchable, is rarely of interest
in normal (non-debugging) runs and simply redunantley consumes extra
file space.
Further, the presence of this text output has been shown to
significantly degrade performance of models which are run during
Met Office HPC RAID (disk) checks.
The new code introduces switches which are configurable via the
changes made in the associated Met Office MOCI ticket 399.

File size: 53.3 KB
Line 
1MODULE zdftmx
2   !!========================================================================
3   !!                       ***  MODULE  zdftmx  ***
4   !! Ocean physics: vertical tidal mixing coefficient
5   !!========================================================================
6   !! History :  1.0  !  2004-04  (L. Bessieres, G. Madec)  Original code
7   !!             -   !  2006-08  (A. Koch-Larrouy) Indonesian strait
8   !!            3.3  !  2010-10  (C. Ethe, G. Madec) reorganisation of initialisation phase
9   !!----------------------------------------------------------------------
10#if defined key_zdftmx   ||   defined key_esopa
11   !!----------------------------------------------------------------------
12   !!   'key_zdftmx'                                  Tidal vertical mixing
13   !!----------------------------------------------------------------------
14   !!   zdf_tmx       : global     momentum & tracer Kz with tidal induced Kz
15   !!   tmx_itf       : Indonesian momentum & tracer Kz with tidal induced Kz
16   !!----------------------------------------------------------------------
17   USE oce            ! ocean dynamics and tracers variables
18   USE dom_oce        ! ocean space and time domain variables
19   USE zdf_oce        ! ocean vertical physics variables
20   USE lbclnk         ! ocean lateral boundary conditions (or mpp link)
21   USE eosbn2         ! ocean equation of state
22   USE phycst         ! physical constants
23   USE prtctl         ! Print control
24   USE in_out_manager ! I/O manager
25   USE iom            ! I/O Manager
26   USE lib_mpp        ! MPP library
27   USE wrk_nemo       ! work arrays
28   USE timing         ! Timing
29   USE lib_fortran    ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 
30
31   IMPLICIT NONE
32   PRIVATE
33
34   PUBLIC   zdf_tmx         ! called in step module
35   PUBLIC   zdf_tmx_init    ! called in opa module
36   PUBLIC   zdf_tmx_alloc   ! called in nemogcm module
37
38   LOGICAL, PUBLIC, PARAMETER ::   lk_zdftmx = .TRUE.    !: tidal mixing flag
39
40   !                              !!* Namelist  namzdf_tmx : tidal mixing *
41   REAL(wp)        ::  rn_htmx     ! vertical decay scale for turbulence (meters)
42   REAL(wp)        ::  rn_n2min    ! threshold of the Brunt-Vaisala frequency (s-1)
43   REAL(wp)        ::  rn_tfe      ! tidal dissipation efficiency (St Laurent et al. 2002)
44   REAL(wp)        ::  rn_me       ! mixing efficiency (Osborn 1980)
45   LOGICAL, PUBLIC ::  ln_tmx_itf  ! Indonesian Through Flow (ITF): Koch-Larrouy et al. (2007) parameterization
46   REAL(wp)        ::  rn_tfe_itf  ! ITF tidal dissipation efficiency (St Laurent et al. 2002)
47
48   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)         ::   en_tmx     ! energy available for tidal mixing (W/m2)
49   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:), PUBLIC ::   mask_itf   ! mask to use over Indonesian area
50   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:)       ::   az_tmx     ! coefficient used to evaluate the tidal induced Kz
51
52   !! * Substitutions
53#  include "domzgr_substitute.h90"
54#  include "vectopt_loop_substitute.h90"
55   !!----------------------------------------------------------------------
56   !! NEMO/OPA 4.0 , NEMO Consortium (2011)
57   !! $Id$
58   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
59   !!----------------------------------------------------------------------
60CONTAINS
61
62   INTEGER FUNCTION zdf_tmx_alloc()
63      !!----------------------------------------------------------------------
64      !!                ***  FUNCTION zdf_tmx_alloc  ***
65      !!----------------------------------------------------------------------
66      ALLOCATE(en_tmx(jpi,jpj), mask_itf(jpi,jpj), az_tmx(jpi,jpj,jpk), STAT=zdf_tmx_alloc )
67      !
68      IF( lk_mpp             )   CALL mpp_sum ( zdf_tmx_alloc )
69      IF( zdf_tmx_alloc /= 0 )   CALL ctl_warn('zdf_tmx_alloc: failed to allocate arrays')
70   END FUNCTION zdf_tmx_alloc
71
72
73   SUBROUTINE zdf_tmx( kt )
74      !!----------------------------------------------------------------------
75      !!                  ***  ROUTINE zdf_tmx  ***
76      !!                   
77      !! ** Purpose :   add to the vertical mixing coefficients the effect of
78      !!              tidal mixing (Simmons et al 2004).
79      !!
80      !! ** Method  : - tidal-induced vertical mixing is given by:
81      !!                  Kz_tides = az_tmx / max( rn_n2min, N^2 )
82      !!              where az_tmx is a coefficient that specified the 3D space
83      !!              distribution of the faction of tidal energy taht is used
84      !!              for mixing. Its expression is set in zdf_tmx_init routine,
85      !!              following Simmons et al. 2004.
86      !!                NB: a specific bounding procedure is performed on av_tide
87      !!              so that the input tidal energy is actually almost used. The
88      !!              basic maximum value is 60 cm2/s, but values of 300 cm2/s
89      !!              can be reached in area where bottom stratification is too
90      !!              weak.
91      !!
92      !!              - update av_tide in the Indonesian Through Flow area
93      !!              following Koch-Larrouy et al. (2007) parameterisation
94      !!              (see tmx_itf routine).
95      !!
96      !!              - update the model vertical eddy viscosity and diffusivity:
97      !!                     avt  = avt  +    av_tides
98      !!                     avm  = avm  +    av_tides
99      !!                     avmu = avmu + mi(av_tides)
100      !!                     avmv = avmv + mj(av_tides)
101      !!
102      !! ** Action  :   avt, avm, avmu, avmv   increased by tidal mixing
103      !!
104      !! References : Simmons et al. 2004, Ocean Modelling, 6, 3-4, 245-263.
105      !!              Koch-Larrouy et al. 2007, GRL.
106      !!----------------------------------------------------------------------
107      USE oce, zav_tide  =>   ua    ! use ua as workspace
108      !!
109      INTEGER, INTENT(in) ::   kt   ! ocean time-step
110      !!
111      INTEGER  ::   ji, jj, jk   ! dummy loop indices
112      REAL(wp) ::   ztpc         ! scalar workspace
113      REAL(wp), POINTER, DIMENSION(:,:) ::   zkz
114      !!----------------------------------------------------------------------
115      !
116      IF( nn_timing == 1 )  CALL timing_start('zdf_tmx')
117      !
118      CALL wrk_alloc( jpi,jpj, zkz )
119
120      !                          ! ----------------------- !
121      !                          !  Standard tidal mixing  !  (compute zav_tide)
122      !                          ! ----------------------- !
123      !                             !* First estimation (with n2 bound by rn_n2min) bounded by 60 cm2/s
124      zav_tide(:,:,:) = MIN(  60.e-4, az_tmx(:,:,:) / MAX( rn_n2min, rn2(:,:,:) )  )
125
126      zkz(:,:) = 0.e0               !* Associated potential energy consummed over the whole water column
127      DO jk = 2, jpkm1
128         zkz(:,:) = zkz(:,:) + fse3w(:,:,jk) * MAX( 0.e0, rn2(:,:,jk) ) * rau0 * zav_tide(:,:,jk) * wmask(:,:,jk)
129      END DO
130
131      DO jj = 1, jpj                !* Here zkz should be equal to en_tmx ==> multiply by en_tmx/zkz to recover en_tmx
132         DO ji = 1, jpi
133            IF( zkz(ji,jj) /= 0.e0 )   zkz(ji,jj) = en_tmx(ji,jj) / zkz(ji,jj)
134         END DO
135      END DO
136
137      DO jk = 2, jpkm1     !* Mutiply by zkz to recover en_tmx, BUT bound by 30/6 ==> zav_tide bound by 300 cm2/s
138         DO jj = 1, jpj                !* Here zkz should be equal to en_tmx ==> multiply by en_tmx/zkz to recover en_tmx
139            DO ji = 1, jpi
140               zav_tide(ji,jj,jk) = zav_tide(ji,jj,jk) * MIN( zkz(ji,jj), 30./6. ) * wmask(ji,jj,jk)  !kz max = 300 cm2/s
141            END DO
142         END DO
143      END DO
144
145      IF( kt == nit000 ) THEN       !* check at first time-step: diagnose the energy consumed by zav_tide
146         ztpc = 0.e0
147         DO jk= 1, jpk
148            DO jj= 1, jpj
149               DO ji= 1, jpi
150                  ztpc = ztpc + fse3w(ji,jj,jk) * e1t(ji,jj) * e2t(ji,jj)   &
151                     &         * MAX( 0.e0, rn2(ji,jj,jk) ) * zav_tide(ji,jj,jk) * tmask(ji,jj,jk) * tmask_i(ji,jj)
152               END DO
153            END DO
154         END DO
155         ztpc= rau0 / ( rn_tfe * rn_me ) * ztpc
156         IF(lwp) WRITE(numout,*) 
157         IF(lwp) WRITE(numout,*) '          N Total power consumption by av_tide    : ztpc = ', ztpc * 1.e-12 ,'TW'
158         IF(lwp .AND. lflush) CALL flush(numout)
159      ENDIF
160       
161      !                          ! ----------------------- !
162      !                          !    ITF  tidal mixing    !  (update zav_tide)
163      !                          ! ----------------------- !
164      IF( ln_tmx_itf )   CALL tmx_itf( kt, zav_tide )
165
166      !                          ! ----------------------- !
167      !                          !   Update  mixing coefs  !                         
168      !                          ! ----------------------- !
169      DO jk = 2, jpkm1              !* update momentum & tracer diffusivity with tidal mixing
170         DO jj = 1, jpj                !* Here zkz should be equal to en_tmx ==> multiply by en_tmx/zkz to recover en_tmx
171            DO ji = 1, jpi
172               avt(ji,jj,jk) = avt(ji,jj,jk) + zav_tide(ji,jj,jk) * wmask(ji,jj,jk)
173               avm(ji,jj,jk) = avm(ji,jj,jk) + zav_tide(ji,jj,jk) * wmask(ji,jj,jk)
174            END DO
175         END DO
176      END DO
177     
178      DO jk = 2, jpkm1              !* update momentum & tracer diffusivity with tidal mixing
179         DO jj = 2, jpjm1
180            DO ji = fs_2, fs_jpim1  ! vector opt.
181               avmu(ji,jj,jk) = avmu(ji,jj,jk) + 0.5 * ( zav_tide(ji,jj,jk) + zav_tide(ji+1,jj  ,jk) ) * wumask(ji,jj,jk)
182               avmv(ji,jj,jk) = avmv(ji,jj,jk) + 0.5 * ( zav_tide(ji,jj,jk) + zav_tide(ji  ,jj+1,jk) ) * wvmask(ji,jj,jk)
183            END DO
184         END DO
185      END DO
186      CALL lbc_lnk( avmu, 'U', 1. )   ;   CALL lbc_lnk( avmv, 'V', 1. )      ! lateral boundary condition
187
188      !                             !* output tidal mixing coefficient
189      CALL iom_put( "av_tide", zav_tide )
190
191      IF(ln_ctl)   CALL prt_ctl(tab3d_1=zav_tide , clinfo1=' tmx - av_tide: ', tab3d_2=avt, clinfo2=' avt: ', ovlap=1, kdim=jpk)
192      !
193      CALL wrk_dealloc( jpi,jpj, zkz )
194      !
195      IF( nn_timing == 1 )  CALL timing_stop('zdf_tmx')
196      !
197   END SUBROUTINE zdf_tmx
198
199
200   SUBROUTINE tmx_itf( kt, pav )
201      !!----------------------------------------------------------------------
202      !!                  ***  ROUTINE tmx_itf  ***
203      !!                   
204      !! ** Purpose :   modify the vertical eddy diffusivity coefficients
205      !!              (pav) in the Indonesian Through Flow area (ITF).
206      !!
207      !! ** Method  : - Following Koch-Larrouy et al. (2007), in the ITF defined
208      !!                by msk_itf (read in a file, see tmx_init), the tidal
209      !!                mixing coefficient is computed with :
210      !!                  * q=1 (i.e. all the tidal energy remains trapped in
211      !!                         the area and thus is used for mixing)
212      !!                  * the vertical distribution of the tifal energy is a
213      !!                    proportional to N above the thermocline (d(N^2)/dz > 0)
214      !!                    and to N^2 below the thermocline (d(N^2)/dz < 0)
215      !!
216      !! ** Action  :   av_tide   updated in the ITF area (msk_itf)
217      !!
218      !! References :  Koch-Larrouy et al. 2007, GRL
219      !!----------------------------------------------------------------------
220      INTEGER , INTENT(in   )                         ::   kt   ! ocean time-step
221      REAL(wp), INTENT(inout), DIMENSION(jpi,jpj,jpk) ::   pav  ! Tidal mixing coef.
222      !!
223      INTEGER  ::   ji, jj, jk    ! dummy loop indices
224      REAL(wp) ::   zcoef, ztpc   ! temporary scalar
225      REAL(wp), DIMENSION(:,:)  , POINTER ::   zkz                        ! 2D workspace
226      REAL(wp), DIMENSION(:,:)  , POINTER ::   zsum1 , zsum2 , zsum       !  -      -
227      REAL(wp), DIMENSION(:,:,:), POINTER ::   zempba_3d_1, zempba_3d_2   ! 3D workspace
228      REAL(wp), DIMENSION(:,:,:), POINTER ::   zempba_3d  , zdn2dz        !  -      -
229      REAL(wp), DIMENSION(:,:,:), POINTER ::   zavt_itf                   !  -      -
230      !!----------------------------------------------------------------------
231      !
232      IF( nn_timing == 1 )  CALL timing_start('tmx_itf')
233      !
234      CALL wrk_alloc( jpi,jpj, zkz, zsum1 , zsum2 , zsum )
235      CALL wrk_alloc( jpi,jpj,jpk, zempba_3d_1, zempba_3d_2, zempba_3d, zdn2dz, zavt_itf )
236
237      !                             ! compute the form function using N2 at each time step
238      zempba_3d_1(:,:,jpk) = 0.e0
239      zempba_3d_2(:,:,jpk) = 0.e0
240      DO jk = 1, jpkm1             
241         zdn2dz     (:,:,jk) = rn2(:,:,jk) - rn2(:,:,jk+1)           ! Vertical profile of dN2/dz
242!CDIR NOVERRCHK
243         zempba_3d_1(:,:,jk) = SQRT(  MAX( 0.e0, rn2(:,:,jk) )  )    !    -        -    of N
244         zempba_3d_2(:,:,jk) =        MAX( 0.e0, rn2(:,:,jk) )       !    -        -    of N^2
245      END DO
246      !
247      zsum (:,:) = 0.e0
248      zsum1(:,:) = 0.e0
249      zsum2(:,:) = 0.e0
250      DO jk= 2, jpk
251         zsum1(:,:) = zsum1(:,:) + zempba_3d_1(:,:,jk) * fse3w(:,:,jk) * tmask(:,:,jk) * tmask(:,:,jk-1)
252         zsum2(:,:) = zsum2(:,:) + zempba_3d_2(:,:,jk) * fse3w(:,:,jk) * tmask(:,:,jk) * tmask(:,:,jk-1)               
253      END DO
254      DO jj = 1, jpj
255         DO ji = 1, jpi
256            IF( zsum1(ji,jj) /= 0.e0 )   zsum1(ji,jj) = 1.e0 / zsum1(ji,jj)
257            IF( zsum2(ji,jj) /= 0.e0 )   zsum2(ji,jj) = 1.e0 / zsum2(ji,jj)               
258         END DO
259      END DO
260
261      DO jk= 1, jpk
262         DO jj = 1, jpj
263            DO ji = 1, jpi
264               zcoef = 0.5 - SIGN( 0.5, zdn2dz(ji,jj,jk) )       ! =0 if dN2/dz > 0, =1 otherwise
265               ztpc  = zempba_3d_1(ji,jj,jk) * zsum1(ji,jj) *        zcoef     &
266                  &  + zempba_3d_2(ji,jj,jk) * zsum2(ji,jj) * ( 1. - zcoef )
267               !
268               zempba_3d(ji,jj,jk) =               ztpc 
269               zsum     (ji,jj)    = zsum(ji,jj) + ztpc * fse3w(ji,jj,jk)
270            END DO
271         END DO
272       END DO
273       DO jj = 1, jpj
274          DO ji = 1, jpi
275             IF( zsum(ji,jj) > 0.e0 )   zsum(ji,jj) = 1.e0 / zsum(ji,jj)               
276          END DO
277       END DO
278
279      !                             ! first estimation bounded by 10 cm2/s (with n2 bounded by rn_n2min)
280      zcoef = rn_tfe_itf / ( rn_tfe * rau0 )
281      DO jk = 1, jpk
282         zavt_itf(:,:,jk) = MIN(  10.e-4, zcoef * en_tmx(:,:) * zsum(:,:) * zempba_3d(:,:,jk)   &
283            &                                      / MAX( rn_n2min, rn2(:,:,jk) ) * tmask(:,:,jk)  )
284      END DO           
285
286      zkz(:,:) = 0.e0               ! Associated potential energy consummed over the whole water column
287      DO jk = 2, jpkm1
288         zkz(:,:) = zkz(:,:) + fse3w(:,:,jk) * MAX( 0.e0, rn2(:,:,jk) ) * rau0 * zavt_itf(:,:,jk) * tmask(:,:,jk) * tmask(:,:,jk-1)
289      END DO
290
291      DO jj = 1, jpj                ! Here zkz should be equal to en_tmx ==> multiply by en_tmx/zkz to recover en_tmx
292         DO ji = 1, jpi
293            IF( zkz(ji,jj) /= 0.e0 )   zkz(ji,jj) = en_tmx(ji,jj) * rn_tfe_itf / rn_tfe / zkz(ji,jj)
294         END DO
295      END DO
296
297      DO jk = 2, jpkm1              ! Mutiply by zkz to recover en_tmx, BUT bound by 30/6 ==> zavt_itf bound by 300 cm2/s
298         zavt_itf(:,:,jk) = zavt_itf(:,:,jk) * MIN( zkz(:,:), 120./10. ) * tmask(:,:,jk) * tmask(:,:,jk-1)   ! kz max = 120 cm2/s
299      END DO
300
301      IF( kt == nit000 ) THEN       ! diagnose the nergy consumed by zavt_itf
302         ztpc = 0.e0
303         DO jk= 1, jpk
304            DO jj= 1, jpj
305               DO ji= 1, jpi
306                  ztpc = ztpc + e1t(ji,jj) * e2t(ji,jj) * fse3w(ji,jj,jk) * MAX( 0.e0, rn2(ji,jj,jk) )   &
307                     &                     * zavt_itf(ji,jj,jk) * tmask(ji,jj,jk) * tmask_i(ji,jj)
308               END DO
309            END DO
310         END DO
311         ztpc= rau0 * ztpc / ( rn_me * rn_tfe_itf )
312         IF(lwp) WRITE(numout,*) '          N Total power consumption by zavt_itf: ztpc = ', ztpc * 1.e-12 ,'TW'
313         IF(lwp .AND. lflush) CALL flush(numout)
314      ENDIF
315
316      !                             ! Update pav with the ITF mixing coefficient
317      DO jk = 2, jpkm1
318         pav(:,:,jk) = pav     (:,:,jk) * ( 1.e0 - mask_itf(:,:) )   &
319            &        + zavt_itf(:,:,jk) *          mask_itf(:,:) 
320      END DO
321      !
322      CALL wrk_dealloc( jpi,jpj, zkz, zsum1 , zsum2 , zsum )
323      CALL wrk_dealloc( jpi,jpj,jpk, zempba_3d_1, zempba_3d_2, zempba_3d, zdn2dz, zavt_itf )
324      !
325      IF( nn_timing == 1 )  CALL timing_stop('tmx_itf')
326      !
327   END SUBROUTINE tmx_itf
328
329
330   SUBROUTINE zdf_tmx_init
331      !!----------------------------------------------------------------------
332      !!                  ***  ROUTINE zdf_tmx_init  ***
333      !!                     
334      !! ** Purpose :   Initialization of the vertical tidal mixing, Reading
335      !!              of M2 and K1 tidal energy in nc files
336      !!
337      !! ** Method  : - Read the namtmx namelist and check the parameters
338      !!
339      !!              - Read the input data in NetCDF files :
340      !!              M2 and K1 tidal energy. The total tidal energy, en_tmx,
341      !!              is the sum of M2, K1 and S2 energy where S2 is assumed
342      !!              to be: S2=(1/2)^2 * M2
343      !!              mask_itf, a mask array that determine where substituing
344      !!              the standard Simmons et al. (2005) formulation with the
345      !!              one of Koch_Larrouy et al. (2007).
346      !!
347      !!              - Compute az_tmx, a 3D coefficient that allows to compute
348      !!             the standard tidal-induced vertical mixing as follows:
349      !!                  Kz_tides = az_tmx / max( rn_n2min, N^2 )
350      !!             with az_tmx a bottom intensified coefficient is given by:
351      !!                 az_tmx(z) = en_tmx / ( rau0 * rn_htmx ) * EXP( -(H-z)/rn_htmx )
352      !!                                                  / ( 1. - EXP( - H   /rn_htmx ) )
353      !!             where rn_htmx the characteristic length scale of the bottom
354      !!             intensification, en_tmx the tidal energy, and H the ocean depth
355      !!
356      !! ** input   :   - Namlist namtmx
357      !!                - NetCDF file : M2_ORCA2.nc, K1_ORCA2.nc, and mask_itf.nc
358      !!
359      !! ** Action  : - Increase by 1 the nstop flag is setting problem encounter
360      !!              - defined az_tmx used to compute tidal-induced mixing
361      !!
362      !! References : Simmons et al. 2004, Ocean Modelling, 6, 3-4, 245-263.
363      !!              Koch-Larrouy et al. 2007, GRL.
364      !!----------------------------------------------------------------------
365      USE oce     ,         zav_tide =>  ua         ! ua used as workspace
366      !!
367      INTEGER  ::   ji, jj, jk   ! dummy loop indices
368      INTEGER  ::   inum         ! local integer
369      INTEGER  ::   ios
370      REAL(wp) ::   ztpc, ze_z   ! local scalars
371      REAL(wp), DIMENSION(:,:)  , POINTER ::  zem2, zek1   ! read M2 and K1 tidal energy
372      REAL(wp), DIMENSION(:,:)  , POINTER ::  zkz          ! total M2, K1 and S2 tidal energy
373      REAL(wp), DIMENSION(:,:)  , POINTER ::  zfact        ! used for vertical structure function
374      REAL(wp), DIMENSION(:,:)  , POINTER ::  zhdep        ! Ocean depth
375      REAL(wp), DIMENSION(:,:,:), POINTER ::  zpc      ! power consumption
376      !!
377      NAMELIST/namzdf_tmx/ rn_htmx, rn_n2min, rn_tfe, rn_me, ln_tmx_itf, rn_tfe_itf
378      !!----------------------------------------------------------------------
379      !
380      IF( nn_timing == 1 )  CALL timing_start('zdf_tmx_init')
381      !
382      CALL wrk_alloc( jpi,jpj, zem2, zek1, zkz, zfact, zhdep )
383      CALL wrk_alloc( jpi,jpj,jpk, zpc )
384     
385      REWIND( numnam_ref )              ! Namelist namzdf_tmx in reference namelist : Tidal Mixing
386      READ  ( numnam_ref, namzdf_tmx, IOSTAT = ios, ERR = 901)
387901   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namzdf_tmx in reference namelist', lwp )
388
389      REWIND( numnam_cfg )              ! Namelist namzdf_tmx in configuration namelist : Tidal Mixing
390      READ  ( numnam_cfg, namzdf_tmx, IOSTAT = ios, ERR = 902 )
391902   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namzdf_tmx in configuration namelist', lwp )
392      IF(lwm .AND. nprint > 2) WRITE ( numond, namzdf_tmx )
393
394      IF(lwp) THEN                   ! Control print
395         WRITE(numout,*)
396         WRITE(numout,*) 'zdf_tmx_init : tidal mixing'
397         WRITE(numout,*) '~~~~~~~~~~~~'
398         WRITE(numout,*) '   Namelist namzdf_tmx : set tidal mixing parameters'
399         WRITE(numout,*) '      Vertical decay scale for turbulence   = ', rn_htmx 
400         WRITE(numout,*) '      Brunt-Vaisala frequency threshold     = ', rn_n2min
401         WRITE(numout,*) '      Tidal dissipation efficiency          = ', rn_tfe
402         WRITE(numout,*) '      Mixing efficiency                     = ', rn_me
403         WRITE(numout,*) '      ITF specific parameterisation         = ', ln_tmx_itf
404         WRITE(numout,*) '      ITF tidal dissipation efficiency      = ', rn_tfe_itf
405         IF(lflush) CALL flush(numout)
406      ENDIF
407
408      !                              ! allocate tmx arrays
409      IF( zdf_tmx_alloc() /= 0 )   CALL ctl_stop( 'STOP', 'zdf_tmx_init : unable to allocate tmx arrays' )
410
411      IF( ln_tmx_itf ) THEN          ! read the Indonesian Through Flow mask
412         CALL iom_open('mask_itf',inum)
413         CALL iom_get (inum, jpdom_data, 'tmaskitf',mask_itf,1) !
414         CALL iom_close(inum)
415      ENDIF
416
417      ! read M2 tidal energy flux : W/m2  ( zem2 < 0 )
418      CALL iom_open('M2rowdrg',inum)
419      CALL iom_get (inum, jpdom_data, 'field',zem2,1) !
420      CALL iom_close(inum)
421
422      ! read K1 tidal energy flux : W/m2  ( zek1 < 0 )
423      CALL iom_open('K1rowdrg',inum)
424      CALL iom_get (inum, jpdom_data, 'field',zek1,1) !
425      CALL iom_close(inum)
426 
427      ! Total tidal energy ( M2, S2 and K1  with S2=(1/2)^2 * M2 )
428      ! only the energy available for mixing is taken into account,
429      ! (mixing efficiency tidal dissipation efficiency)
430      en_tmx(:,:) = - rn_tfe * rn_me * ( zem2(:,:) * 1.25 + zek1(:,:) ) * ssmask(:,:)
431
432!============
433!TG: Bug for VVL? Should this section be moved out of _init and be updated at every timestep?
434      ! Vertical structure (az_tmx)
435      DO jj = 1, jpj                ! part independent of the level
436         DO ji = 1, jpi
437            zhdep(ji,jj) = gdepw_0(ji,jj,mbkt(ji,jj)+1)       ! depth of the ocean
438            zfact(ji,jj) = rau0 * rn_htmx * ( 1. - EXP( -zhdep(ji,jj) / rn_htmx ) )
439            IF( zfact(ji,jj) /= 0 )   zfact(ji,jj) = en_tmx(ji,jj) / zfact(ji,jj)
440         END DO
441      END DO
442      DO jk= 1, jpk                 ! complete with the level-dependent part
443         DO jj = 1, jpj
444            DO ji = 1, jpi
445               az_tmx(ji,jj,jk) = zfact(ji,jj) * EXP( -( zhdep(ji,jj)-gdepw_0(ji,jj,jk) ) / rn_htmx ) * tmask(ji,jj,jk)
446            END DO
447         END DO
448      END DO
449!===========
450
451      IF( nprint > 2 .AND. lwp ) THEN
452         ! Control print
453         ! Total power consumption due to vertical mixing
454         ! zpc = rau0 * 1/rn_me * rn2 * zav_tide
455         zav_tide(:,:,:) = 0.e0
456         DO jk = 2, jpkm1
457            zav_tide(:,:,jk) = az_tmx(:,:,jk) / MAX( rn_n2min, rn2(:,:,jk) )
458         END DO
459
460         ztpc = 0.e0
461         zpc(:,:,:) = MAX(rn_n2min,rn2(:,:,:)) * zav_tide(:,:,:)
462         DO jk= 2, jpkm1
463            DO jj = 1, jpj
464               DO ji = 1, jpi
465                  ztpc = ztpc + fse3w(ji,jj,jk) * e1t(ji,jj) * e2t(ji,jj) * zpc(ji,jj,jk) * wmask(ji,jj,jk) * tmask_i(ji,jj)
466               END DO
467            END DO
468         END DO
469         ztpc= rau0 * 1/(rn_tfe * rn_me) * ztpc
470
471         WRITE(numout,*) 
472         WRITE(numout,*) '          Total power consumption of the tidally driven part of Kz : ztpc = ', ztpc * 1.e-12 ,'TW'
473         IF(lflush) CALL flush(numout)
474
475
476         ! control print 2
477         zav_tide(:,:,:) = MIN( zav_tide(:,:,:), 60.e-4 )   
478         zkz(:,:) = 0.e0
479         DO jk = 2, jpkm1
480            DO jj = 1, jpj
481               DO ji = 1, jpi
482                  zkz(ji,jj) = zkz(ji,jj) + fse3w(ji,jj,jk) * MAX(0.e0, rn2(ji,jj,jk)) * rau0 * zav_tide(ji,jj,jk) * wmask(ji,jj,jk)
483               END DO
484            END DO
485         END DO
486         ! Here zkz should be equal to en_tmx ==> multiply by en_tmx/zkz
487         DO jj = 1, jpj
488            DO ji = 1, jpi
489               IF( zkz(ji,jj) /= 0.e0 )   THEN
490                   zkz(ji,jj) = en_tmx(ji,jj) / zkz(ji,jj)
491               ENDIF
492            END DO
493         END DO
494         ztpc = 1.e50
495         DO jj = 1, jpj
496            DO ji = 1, jpi
497               IF( zkz(ji,jj) /= 0.e0 )   THEN
498                   ztpc = Min( zkz(ji,jj), ztpc)
499               ENDIF
500            END DO
501         END DO
502         WRITE(numout,*) '          Min de zkz ', ztpc, ' Max = ', maxval(zkz(:,:) )
503         IF(lflush) CALL flush(numout)
504
505         DO jk = 2, jpkm1
506            DO jj = 1, jpj
507               DO ji = 1, jpi
508                  zav_tide(ji,jj,jk) = zav_tide(ji,jj,jk) * MIN( zkz(ji,jj), 30./6. ) * wmask(ji,jj,jk)  !kz max = 300 cm2/s
509               END DO
510            END DO
511         END DO
512         ztpc = 0.e0
513         zpc(:,:,:) = Max(0.e0,rn2(:,:,:)) * zav_tide(:,:,:)
514         DO jk= 1, jpk
515            DO jj = 1, jpj
516               DO ji = 1, jpi
517                  ztpc = ztpc + fse3w(ji,jj,jk) * e1t(ji,jj) * e2t(ji,jj) * zpc(ji,jj,jk) * wmask(ji,jj,jk) * tmask_i(ji,jj)
518               END DO
519            END DO
520         END DO
521         ztpc= rau0 * 1/(rn_tfe * rn_me) * ztpc
522         WRITE(numout,*) '          2 Total power consumption of the tidally driven part of Kz : ztpc = ', ztpc * 1.e-12 ,'TW'
523         IF(lflush) CALL flush(numout)
524
525         DO jk = 1, jpk
526            ze_z =                  SUM( e1t(:,:) * e2t(:,:) * zav_tide(:,:,jk)     * tmask_i(:,:) )   &
527               &     / MAX( 1.e-20, SUM( e1t(:,:) * e2t(:,:) * wmask (:,:,jk) * tmask_i(:,:) ) )
528            ztpc = 1.E50
529            DO jj = 1, jpj
530               DO ji = 1, jpi
531                  IF( zav_tide(ji,jj,jk) /= 0.e0 )   ztpc =Min( ztpc, zav_tide(ji,jj,jk) )
532               END DO
533            END DO
534            WRITE(numout,*) '            N2 min - jk= ', jk,'   ', ze_z * 1.e4,' cm2/s min= ',ztpc*1.e4,   &
535               &       'max= ', MAXVAL(zav_tide(:,:,jk) )*1.e4, ' cm2/s'
536            IF(lflush) CALL flush(numout)
537         END DO
538
539         WRITE(numout,*) '          e_tide : ', SUM( e1t*e2t*en_tmx ) / ( rn_tfe * rn_me ) * 1.e-12, 'TW'
540         WRITE(numout,*) 
541         WRITE(numout,*) '          Initial profile of tidal vertical mixing'
542         IF(lflush) CALL flush(numout)
543
544         DO jk = 1, jpk
545            DO jj = 1,jpj
546               DO ji = 1,jpi
547                  zkz(ji,jj) = az_tmx(ji,jj,jk) /MAX( rn_n2min, rn2(ji,jj,jk) )
548               END DO
549            END DO
550            ze_z =                  SUM( e1t(:,:) * e2t(:,:) * zkz(:,:)     * tmask_i(:,:) )   &
551               &     / MAX( 1.e-20, SUM( e1t(:,:) * e2t(:,:) * wmask (:,:,jk) * tmask_i(:,:) ) )
552            WRITE(numout,*) '                jk= ', jk,'   ', ze_z * 1.e4,' cm2/s'
553         END DO
554         IF(lflush) CALL flush(numout)
555         DO jk = 1, jpk
556            zkz(:,:) = az_tmx(:,:,jk) /rn_n2min
557            ze_z =                  SUM( e1t(:,:) * e2t(:,:) * zkz(:,:)     * tmask_i(:,:) )   &
558               &     / MAX( 1.e-20, SUM( e1t(:,:) * e2t(:,:) * wmask (:,:,jk) * tmask_i(:,:) ) )
559            WRITE(numout,*) 
560            WRITE(numout,*) '          N2 min - jk= ', jk,'   ', ze_z * 1.e4,' cm2/s min= ',MINVAL(zkz)*1.e4,   &
561               &       'max= ', MAXVAL(zkz)*1.e4, ' cm2/s'
562         END DO
563         IF(lflush) CALL flush(numout)
564         !
565      ENDIF
566      !
567      CALL wrk_dealloc( jpi,jpj, zem2, zek1, zkz, zfact, zhdep )
568      CALL wrk_dealloc( jpi,jpj,jpk, zpc )
569      !
570      IF( nn_timing == 1 )  CALL timing_stop('zdf_tmx_init')
571      !
572   END SUBROUTINE zdf_tmx_init
573
574#elif defined key_zdftmx_new
575   !!----------------------------------------------------------------------
576   !!   'key_zdftmx_new'               Internal wave-driven vertical mixing
577   !!----------------------------------------------------------------------
578   !!   zdf_tmx       : global     momentum & tracer Kz with wave induced Kz
579   !!   zdf_tmx_init  : global     momentum & tracer Kz with wave induced Kz
580   !!----------------------------------------------------------------------
581   USE oce            ! ocean dynamics and tracers variables
582   USE dom_oce        ! ocean space and time domain variables
583   USE zdf_oce        ! ocean vertical physics variables
584   USE zdfddm         ! ocean vertical physics: double diffusive mixing
585   USE lbclnk         ! ocean lateral boundary conditions (or mpp link)
586   USE eosbn2         ! ocean equation of state
587   USE phycst         ! physical constants
588   USE prtctl         ! Print control
589   USE in_out_manager ! I/O manager
590   USE iom            ! I/O Manager
591   USE lib_mpp        ! MPP library
592   USE wrk_nemo       ! work arrays
593   USE timing         ! Timing
594   USE lib_fortran    ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 
595
596   IMPLICIT NONE
597   PRIVATE
598
599   PUBLIC   zdf_tmx         ! called in step module
600   PUBLIC   zdf_tmx_init    ! called in nemogcm module
601   PUBLIC   zdf_tmx_alloc   ! called in nemogcm module
602
603   LOGICAL, PUBLIC, PARAMETER ::   lk_zdftmx = .TRUE.    !: wave-driven mixing flag
604
605   !                       !!* Namelist  namzdf_tmx : internal wave-driven mixing *
606   INTEGER  ::  nn_zpyc     ! pycnocline-intensified mixing energy proportional to N (=1) or N^2 (=2)
607   LOGICAL  ::  ln_mevar    ! variable (=T) or constant (=F) mixing efficiency
608   LOGICAL  ::  ln_tsdiff   ! account for differential T/S wave-driven mixing (=T) or not (=F)
609
610   REAL(wp) ::  r1_6 = 1._wp / 6._wp
611
612   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   ebot_tmx     ! power available from high-mode wave breaking (W/m2)
613   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   epyc_tmx     ! power available from low-mode, pycnocline-intensified wave breaking (W/m2)
614   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   ecri_tmx     ! power available from low-mode, critical slope wave breaking (W/m2)
615   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   hbot_tmx     ! WKB decay scale for high-mode energy dissipation (m)
616   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   hcri_tmx     ! decay scale for low-mode critical slope dissipation (m)
617   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   emix_tmx     ! local energy density available for mixing (W/kg)
618   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   bflx_tmx     ! buoyancy flux Kz * N^2 (W/kg)
619   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   pcmap_tmx    ! vertically integrated buoyancy flux (W/m2)
620   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   zav_ratio    ! S/T diffusivity ratio (only for ln_tsdiff=T)
621   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   zav_wave     ! Internal wave-induced diffusivity
622
623   !! * Substitutions
624#  include "zdfddm_substitute.h90"
625#  include "domzgr_substitute.h90"
626#  include "vectopt_loop_substitute.h90"
627   !!----------------------------------------------------------------------
628   !! NEMO/OPA 4.0 , NEMO Consortium (2016)
629   !! $Id$
630   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
631   !!----------------------------------------------------------------------
632CONTAINS
633
634   INTEGER FUNCTION zdf_tmx_alloc()
635      !!----------------------------------------------------------------------
636      !!                ***  FUNCTION zdf_tmx_alloc  ***
637      !!----------------------------------------------------------------------
638      ALLOCATE(     ebot_tmx(jpi,jpj),  epyc_tmx(jpi,jpj),  ecri_tmx(jpi,jpj)    ,   &
639      &             hbot_tmx(jpi,jpj),  hcri_tmx(jpi,jpj),  emix_tmx(jpi,jpj,jpk),   &
640      &         bflx_tmx(jpi,jpj,jpk), pcmap_tmx(jpi,jpj), zav_ratio(jpi,jpj,jpk),   & 
641      &         zav_wave(jpi,jpj,jpk), STAT=zdf_tmx_alloc     )
642      !
643      IF( lk_mpp             )   CALL mpp_sum ( zdf_tmx_alloc )
644      IF( zdf_tmx_alloc /= 0 )   CALL ctl_warn('zdf_tmx_alloc: failed to allocate arrays')
645   END FUNCTION zdf_tmx_alloc
646
647
648   SUBROUTINE zdf_tmx( kt )
649      !!----------------------------------------------------------------------
650      !!                  ***  ROUTINE zdf_tmx  ***
651      !!                   
652      !! ** Purpose :   add to the vertical mixing coefficients the effect of
653      !!              breaking internal waves.
654      !!
655      !! ** Method  : - internal wave-driven vertical mixing is given by:
656      !!                  Kz_wave = min(  100 cm2/s, f(  Reb = emix_tmx /( Nu * N^2 )  )
657      !!              where emix_tmx is the 3D space distribution of the wave-breaking
658      !!              energy and Nu the molecular kinematic viscosity.
659      !!              The function f(Reb) is linear (constant mixing efficiency)
660      !!              if the namelist parameter ln_mevar = F and nonlinear if ln_mevar = T.
661      !!
662      !!              - Compute emix_tmx, the 3D power density that allows to compute
663      !!              Reb and therefrom the wave-induced vertical diffusivity.
664      !!              This is divided into three components:
665      !!                 1. Bottom-intensified low-mode dissipation at critical slopes
666      !!                     emix_tmx(z) = ( ecri_tmx / rau0 ) * EXP( -(H-z)/hcri_tmx )
667      !!                                   / ( 1. - EXP( - H/hcri_tmx ) ) * hcri_tmx
668      !!              where hcri_tmx is the characteristic length scale of the bottom
669      !!              intensification, ecri_tmx a map of available power, and H the ocean depth.
670      !!                 2. Pycnocline-intensified low-mode dissipation
671      !!                     emix_tmx(z) = ( epyc_tmx / rau0 ) * ( sqrt(rn2(z))^nn_zpyc )
672      !!                                   / SUM( sqrt(rn2(z))^nn_zpyc * e3w(z) )
673      !!              where epyc_tmx is a map of available power, and nn_zpyc
674      !!              is the chosen stratification-dependence of the internal wave
675      !!              energy dissipation.
676      !!                 3. WKB-height dependent high mode dissipation
677      !!                     emix_tmx(z) = ( ebot_tmx / rau0 ) * rn2(z) * EXP(-z_wkb(z)/hbot_tmx)
678      !!                                   / SUM( rn2(z) * EXP(-z_wkb(z)/hbot_tmx) * e3w(z) )
679      !!              where hbot_tmx is the characteristic length scale of the WKB bottom
680      !!              intensification, ebot_tmx is a map of available power, and z_wkb is the
681      !!              WKB-stretched height above bottom defined as
682      !!                    z_wkb(z) = H * SUM( sqrt(rn2(z'>=z)) * e3w(z'>=z) )
683      !!                                 / SUM( sqrt(rn2(z'))    * e3w(z')    )
684      !!
685      !!              - update the model vertical eddy viscosity and diffusivity:
686      !!                     avt  = avt  +    av_wave
687      !!                     avm  = avm  +    av_wave
688      !!                     avmu = avmu + mi(av_wave)
689      !!                     avmv = avmv + mj(av_wave)
690      !!
691      !!              - if namelist parameter ln_tsdiff = T, account for differential mixing:
692      !!                     avs  = avt  +    av_wave * diffusivity_ratio(Reb)
693      !!
694      !! ** Action  : - Define emix_tmx used to compute internal wave-induced mixing
695      !!              - avt, avs, avm, avmu, avmv increased by internal wave-driven mixing   
696      !!
697      !! References :  de Lavergne et al. 2015, JPO; 2016, in prep.
698      !!----------------------------------------------------------------------
699      INTEGER, INTENT(in) ::   kt   ! ocean time-step
700      !
701      INTEGER  ::   ji, jj, jk   ! dummy loop indices
702      REAL(wp) ::   ztpc         ! scalar workspace
703      REAL(wp), DIMENSION(:,:)  , POINTER ::  zfact     ! Used for vertical structure
704      REAL(wp), DIMENSION(:,:)  , POINTER ::  zhdep     ! Ocean depth
705      REAL(wp), DIMENSION(:,:,:), POINTER ::  zwkb      ! WKB-stretched height above bottom
706      REAL(wp), DIMENSION(:,:,:), POINTER ::  zweight   ! Weight for high mode vertical distribution
707      REAL(wp), DIMENSION(:,:,:), POINTER ::  znu_t     ! Molecular kinematic viscosity (T grid)
708      REAL(wp), DIMENSION(:,:,:), POINTER ::  znu_w     ! Molecular kinematic viscosity (W grid)
709      REAL(wp), DIMENSION(:,:,:), POINTER ::  zReb      ! Turbulence intensity parameter
710      !!----------------------------------------------------------------------
711      !
712      IF( nn_timing == 1 )   CALL timing_start('zdf_tmx')
713      !
714      CALL wrk_alloc( jpi,jpj,       zfact, zhdep )
715      CALL wrk_alloc( jpi,jpj,jpk,   zwkb, zweight, znu_t, znu_w, zReb )
716
717      !                          ! ----------------------------- !
718      !                          !  Internal wave-driven mixing  !  (compute zav_wave)
719      !                          ! ----------------------------- !
720      !                             
721      !                        !* Critical slope mixing: distribute energy over the time-varying ocean depth,
722      !                                                 using an exponential decay from the seafloor.
723      DO jj = 1, jpj                ! part independent of the level
724         DO ji = 1, jpi
725            zhdep(ji,jj) = fsdepw(ji,jj,mbkt(ji,jj)+1)       ! depth of the ocean
726            zfact(ji,jj) = rau0 * (  1._wp - EXP( -zhdep(ji,jj) / hcri_tmx(ji,jj) )  )
727            IF( zfact(ji,jj) /= 0 )   zfact(ji,jj) = ecri_tmx(ji,jj) / zfact(ji,jj)
728         END DO
729      END DO
730
731      DO jk = 2, jpkm1              ! complete with the level-dependent part
732         emix_tmx(:,:,jk) = zfact(:,:) * (  EXP( ( fsde3w(:,:,jk  ) - zhdep(:,:) ) / hcri_tmx(:,:) )                      &
733            &                             - EXP( ( fsde3w(:,:,jk-1) - zhdep(:,:) ) / hcri_tmx(:,:) )  ) * wmask(:,:,jk)   &
734            &                          / ( fsde3w(:,:,jk) - fsde3w(:,:,jk-1) )
735      END DO
736
737      !                        !* Pycnocline-intensified mixing: distribute energy over the time-varying
738      !                        !* ocean depth as proportional to sqrt(rn2)^nn_zpyc
739
740      SELECT CASE ( nn_zpyc )
741
742      CASE ( 1 )               ! Dissipation scales as N (recommended)
743
744         zfact(:,:) = 0._wp
745         DO jk = 2, jpkm1              ! part independent of the level
746            zfact(:,:) = zfact(:,:) + fse3w(:,:,jk) * SQRT(  MAX( 0._wp, rn2(:,:,jk) )  ) * wmask(:,:,jk)
747         END DO
748
749         DO jj = 1, jpj
750            DO ji = 1, jpi
751               IF( zfact(ji,jj) /= 0 )   zfact(ji,jj) = epyc_tmx(ji,jj) / ( rau0 * zfact(ji,jj) )
752            END DO
753         END DO
754
755         DO jk = 2, jpkm1              ! complete with the level-dependent part
756            emix_tmx(:,:,jk) = emix_tmx(:,:,jk) + zfact(:,:) * SQRT(  MAX( 0._wp, rn2(:,:,jk) )  ) * wmask(:,:,jk)
757         END DO
758
759      CASE ( 2 )               ! Dissipation scales as N^2
760
761         zfact(:,:) = 0._wp
762         DO jk = 2, jpkm1              ! part independent of the level
763            zfact(:,:) = zfact(:,:) + fse3w(:,:,jk) * MAX( 0._wp, rn2(:,:,jk) ) * wmask(:,:,jk)
764         END DO
765
766         DO jj= 1, jpj
767            DO ji = 1, jpi
768               IF( zfact(ji,jj) /= 0 )   zfact(ji,jj) = epyc_tmx(ji,jj) / ( rau0 * zfact(ji,jj) )
769            END DO
770         END DO
771
772         DO jk = 2, jpkm1              ! complete with the level-dependent part
773            emix_tmx(:,:,jk) = emix_tmx(:,:,jk) + zfact(:,:) * MAX( 0._wp, rn2(:,:,jk) ) * wmask(:,:,jk)
774         END DO
775
776      END SELECT
777
778      !                        !* WKB-height dependent mixing: distribute energy over the time-varying
779      !                        !* ocean depth as proportional to rn2 * exp(-z_wkb/rn_hbot)
780     
781      zwkb(:,:,:) = 0._wp
782      zfact(:,:) = 0._wp
783      DO jk = 2, jpkm1
784         zfact(:,:) = zfact(:,:) + fse3w(:,:,jk) * SQRT(  MAX( 0._wp, rn2(:,:,jk) )  ) * wmask(:,:,jk)
785         zwkb(:,:,jk) = zfact(:,:)
786      END DO
787
788      DO jk = 2, jpkm1
789         DO jj = 1, jpj
790            DO ji = 1, jpi
791               IF( zfact(ji,jj) /= 0 )   zwkb(ji,jj,jk) = zhdep(ji,jj) * ( zfact(ji,jj) - zwkb(ji,jj,jk) )   &
792                                            &           * tmask(ji,jj,jk) / zfact(ji,jj)
793            END DO
794         END DO
795      END DO
796      zwkb(:,:,1) = zhdep(:,:) * tmask(:,:,1)
797
798      zweight(:,:,:) = 0._wp
799      DO jk = 2, jpkm1
800         zweight(:,:,jk) = MAX( 0._wp, rn2(:,:,jk) ) * hbot_tmx(:,:) * wmask(:,:,jk)                    &
801            &   * (  EXP( -zwkb(:,:,jk) / hbot_tmx(:,:) ) - EXP( -zwkb(:,:,jk-1) / hbot_tmx(:,:) )  )
802      END DO
803
804      zfact(:,:) = 0._wp
805      DO jk = 2, jpkm1              ! part independent of the level
806         zfact(:,:) = zfact(:,:) + zweight(:,:,jk)
807      END DO
808
809      DO jj = 1, jpj
810         DO ji = 1, jpi
811            IF( zfact(ji,jj) /= 0 )   zfact(ji,jj) = ebot_tmx(ji,jj) / ( rau0 * zfact(ji,jj) )
812         END DO
813      END DO
814
815      DO jk = 2, jpkm1              ! complete with the level-dependent part
816         emix_tmx(:,:,jk) = emix_tmx(:,:,jk) + zweight(:,:,jk) * zfact(:,:) * wmask(:,:,jk)   &
817            &                                / ( fsde3w(:,:,jk) - fsde3w(:,:,jk-1) )
818      END DO
819
820
821      ! Calculate molecular kinematic viscosity
822      znu_t(:,:,:) = 1.e-4_wp * (  17.91_wp - 0.53810_wp * tsn(:,:,:,jp_tem) + 0.00694_wp * tsn(:,:,:,jp_tem) * tsn(:,:,:,jp_tem)  &
823         &                                  + 0.02305_wp * tsn(:,:,:,jp_sal)  ) * tmask(:,:,:) * r1_rau0
824      DO jk = 2, jpkm1
825         znu_w(:,:,jk) = 0.5_wp * ( znu_t(:,:,jk-1) + znu_t(:,:,jk) ) * wmask(:,:,jk)
826      END DO
827
828      ! Calculate turbulence intensity parameter Reb
829      DO jk = 2, jpkm1
830         zReb(:,:,jk) = emix_tmx(:,:,jk) / MAX( 1.e-20_wp, znu_w(:,:,jk) * rn2(:,:,jk) )
831      END DO
832
833      ! Define internal wave-induced diffusivity
834      DO jk = 2, jpkm1
835         zav_wave(:,:,jk) = znu_w(:,:,jk) * zReb(:,:,jk) * r1_6   ! This corresponds to a constant mixing efficiency of 1/6
836      END DO
837
838      IF( ln_mevar ) THEN              ! Variable mixing efficiency case : modify zav_wave in the
839         DO jk = 2, jpkm1              ! energetic (Reb > 480) and buoyancy-controlled (Reb <10.224 ) regimes
840            DO jj = 1, jpj
841               DO ji = 1, jpi
842                  IF( zReb(ji,jj,jk) > 480.00_wp ) THEN
843                     zav_wave(ji,jj,jk) = 3.6515_wp * znu_w(ji,jj,jk) * SQRT( zReb(ji,jj,jk) )
844                  ELSEIF( zReb(ji,jj,jk) < 10.224_wp ) THEN
845                     zav_wave(ji,jj,jk) = 0.052125_wp * znu_w(ji,jj,jk) * zReb(ji,jj,jk) * SQRT( zReb(ji,jj,jk) )
846                  ENDIF
847               END DO
848            END DO
849         END DO
850      ENDIF
851
852      DO jk = 2, jpkm1                 ! Bound diffusivity by molecular value and 100 cm2/s
853         zav_wave(:,:,jk) = MIN(  MAX( 1.4e-7_wp, zav_wave(:,:,jk) ), 1.e-2_wp  ) * wmask(:,:,jk)
854      END DO
855
856      IF( kt == nit000 ) THEN        !* Control print at first time-step: diagnose the energy consumed by zav_wave
857         ztpc = 0._wp
858         DO jk = 2, jpkm1
859            DO jj = 1, jpj
860               DO ji = 1, jpi
861                  ztpc = ztpc + fse3w(ji,jj,jk) * e1e2t(ji,jj)   &
862                     &         * MAX( 0._wp, rn2(ji,jj,jk) ) * zav_wave(ji,jj,jk) * wmask(ji,jj,jk) * tmask_i(ji,jj)
863               END DO
864            END DO
865         END DO
866         IF( lk_mpp )   CALL mpp_sum( ztpc )
867         ztpc = rau0 * ztpc ! Global integral of rauo * Kz * N^2 = power contributing to mixing
868 
869         IF(lwp) THEN
870            WRITE(numout,*)
871            WRITE(numout,*) 'zdf_tmx : Internal wave-driven mixing (tmx)'
872            WRITE(numout,*) '~~~~~~~ '
873            WRITE(numout,*)
874            WRITE(numout,*) '      Total power consumption by av_wave: ztpc =  ', ztpc * 1.e-12_wp, 'TW'
875            IF(lflush) CALL flush(numout)
876         ENDIF
877      ENDIF
878
879      !                          ! ----------------------- !
880      !                          !   Update  mixing coefs  !                         
881      !                          ! ----------------------- !
882      !     
883      IF( ln_tsdiff ) THEN          !* Option for differential mixing of salinity and temperature
884         DO jk = 2, jpkm1              ! Calculate S/T diffusivity ratio as a function of Reb
885            DO jj = 1, jpj
886               DO ji = 1, jpi
887                  zav_ratio(ji,jj,jk) = ( 0.505_wp + 0.495_wp *                                                                  &
888                      &   TANH(    0.92_wp * (   LOG10(  MAX( 1.e-20_wp, zReb(ji,jj,jk) * 5._wp * r1_6 )  ) - 0.60_wp   )    )   &
889                      &                 ) * wmask(ji,jj,jk)
890               END DO
891            END DO
892         END DO
893         CALL iom_put( "av_ratio", zav_ratio )
894         DO jk = 2, jpkm1           !* update momentum & tracer diffusivity with wave-driven mixing
895            fsavs(:,:,jk) = avt(:,:,jk) + zav_wave(:,:,jk) * zav_ratio(:,:,jk)
896            avt  (:,:,jk) = avt(:,:,jk) + zav_wave(:,:,jk)
897            avm  (:,:,jk) = avm(:,:,jk) + zav_wave(:,:,jk)
898         END DO
899         !
900      ELSE                          !* update momentum & tracer diffusivity with wave-driven mixing
901         DO jk = 2, jpkm1
902            fsavs(:,:,jk) = avt(:,:,jk) + zav_wave(:,:,jk)
903            avt  (:,:,jk) = avt(:,:,jk) + zav_wave(:,:,jk)
904            avm  (:,:,jk) = avm(:,:,jk) + zav_wave(:,:,jk)
905         END DO
906      ENDIF
907
908      DO jk = 2, jpkm1              !* update momentum diffusivity at wu and wv points
909         DO jj = 2, jpjm1
910            DO ji = fs_2, fs_jpim1  ! vector opt.
911               avmu(ji,jj,jk) = avmu(ji,jj,jk) + 0.5_wp * ( zav_wave(ji,jj,jk) + zav_wave(ji+1,jj  ,jk) ) * wumask(ji,jj,jk)
912               avmv(ji,jj,jk) = avmv(ji,jj,jk) + 0.5_wp * ( zav_wave(ji,jj,jk) + zav_wave(ji  ,jj+1,jk) ) * wvmask(ji,jj,jk)
913            END DO
914         END DO
915      END DO
916      CALL lbc_lnk( avmu, 'U', 1. )   ;   CALL lbc_lnk( avmv, 'V', 1. )      ! lateral boundary condition
917
918      !                             !* output internal wave-driven mixing coefficient
919      CALL iom_put( "av_wave", zav_wave )
920                                    !* output useful diagnostics: N^2, Kz * N^2 (bflx_tmx),
921                                    !  vertical integral of rau0 * Kz * N^2 (pcmap_tmx), energy density (emix_tmx)
922      IF( iom_use("bflx_tmx") .OR. iom_use("pcmap_tmx") ) THEN
923         bflx_tmx(:,:,:) = MAX( 0._wp, rn2(:,:,:) ) * zav_wave(:,:,:)
924         pcmap_tmx(:,:) = 0._wp
925         DO jk = 2, jpkm1
926            pcmap_tmx(:,:) = pcmap_tmx(:,:) + fse3w(:,:,jk) * bflx_tmx(:,:,jk) * wmask(:,:,jk)
927         END DO
928         pcmap_tmx(:,:) = rau0 * pcmap_tmx(:,:)
929         CALL iom_put( "bflx_tmx", bflx_tmx )
930         CALL iom_put( "pcmap_tmx", pcmap_tmx )
931      ENDIF
932      CALL iom_put( "emix_tmx", emix_tmx )
933     
934      CALL wrk_dealloc( jpi,jpj,       zfact, zhdep )
935      CALL wrk_dealloc( jpi,jpj,jpk,   zwkb, zweight, znu_t, znu_w, zReb )
936
937      IF(ln_ctl)   CALL prt_ctl(tab3d_1=zav_wave , clinfo1=' tmx - av_wave: ', tab3d_2=avt, clinfo2=' avt: ', ovlap=1, kdim=jpk)
938      !
939      IF( nn_timing == 1 )   CALL timing_stop('zdf_tmx')
940      !
941   END SUBROUTINE zdf_tmx
942
943
944   SUBROUTINE zdf_tmx_init
945      !!----------------------------------------------------------------------
946      !!                  ***  ROUTINE zdf_tmx_init  ***
947      !!                     
948      !! ** Purpose :   Initialization of the wave-driven vertical mixing, reading
949      !!              of input power maps and decay length scales in netcdf files.
950      !!
951      !! ** Method  : - Read the namzdf_tmx namelist and check the parameters
952      !!
953      !!              - Read the input data in NetCDF files :
954      !!              power available from high-mode wave breaking (mixing_power_bot.nc)
955      !!              power available from pycnocline-intensified wave-breaking (mixing_power_pyc.nc)
956      !!              power available from critical slope wave-breaking (mixing_power_cri.nc)
957      !!              WKB decay scale for high-mode wave-breaking (decay_scale_bot.nc)
958      !!              decay scale for critical slope wave-breaking (decay_scale_cri.nc)
959      !!
960      !! ** input   : - Namlist namzdf_tmx
961      !!              - NetCDF files : mixing_power_bot.nc, mixing_power_pyc.nc, mixing_power_cri.nc,
962      !!              decay_scale_bot.nc decay_scale_cri.nc
963      !!
964      !! ** Action  : - Increase by 1 the nstop flag is setting problem encounter
965      !!              - Define ebot_tmx, epyc_tmx, ecri_tmx, hbot_tmx, hcri_tmx
966      !!
967      !! References : de Lavergne et al. 2015, JPO; 2016, in prep.
968      !!         
969      !!----------------------------------------------------------------------
970      INTEGER  ::   ji, jj, jk   ! dummy loop indices
971      INTEGER  ::   inum         ! local integer
972      INTEGER  ::   ios
973      REAL(wp) ::   zbot, zpyc, zcri   ! local scalars
974      !!
975      NAMELIST/namzdf_tmx_new/ nn_zpyc, ln_mevar, ln_tsdiff
976      !!----------------------------------------------------------------------
977      !
978      IF( nn_timing == 1 )  CALL timing_start('zdf_tmx_init')
979      !
980      REWIND( numnam_ref )              ! Namelist namzdf_tmx in reference namelist : Wave-driven mixing
981      READ  ( numnam_ref, namzdf_tmx_new, IOSTAT = ios, ERR = 901)
982901   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namzdf_tmx in reference namelist', lwp )
983      !
984      REWIND( numnam_cfg )              ! Namelist namzdf_tmx in configuration namelist : Wave-driven mixing
985      READ  ( numnam_cfg, namzdf_tmx_new, IOSTAT = ios, ERR = 902 )
986902   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namzdf_tmx in configuration namelist', lwp )
987      IF(lwm .AND. nprint > 2) WRITE ( numond, namzdf_tmx_new )
988      !
989      IF(lwp) THEN                  ! Control print
990         WRITE(numout,*)
991         WRITE(numout,*) 'zdf_tmx_init : internal wave-driven mixing'
992         WRITE(numout,*) '~~~~~~~~~~~~'
993         WRITE(numout,*) '   Namelist namzdf_tmx_new : set wave-driven mixing parameters'
994         WRITE(numout,*) '      Pycnocline-intensified diss. scales as N (=1) or N^2 (=2) = ', nn_zpyc
995         WRITE(numout,*) '      Variable (T) or constant (F) mixing efficiency            = ', ln_mevar
996         WRITE(numout,*) '      Differential internal wave-driven mixing (T) or not (F)   = ', ln_tsdiff
997         IF(lflush) CALL flush(numout)
998      ENDIF
999     
1000      ! The new wave-driven mixing parameterization elevates avt and avm in the interior, and
1001      ! ensures that avt remains larger than its molecular value (=1.4e-7). Therefore, avtb should
1002      ! be set here to a very small value, and avmb to its (uniform) molecular value (=1.4e-6).
1003      avmb(:) = 1.4e-6_wp        ! viscous molecular value
1004      avtb(:) = 1.e-10_wp        ! very small diffusive minimum (background avt is specified in zdf_tmx)   
1005      avtb_2d(:,:) = 1.e0_wp     ! uniform
1006      IF(lwp) THEN                  ! Control print
1007         WRITE(numout,*)
1008         WRITE(numout,*) '   Force the background value applied to avm & avt in TKE to be everywhere ',   &
1009            &               'the viscous molecular value & a very small diffusive value, resp.'
1010         IF(lflush) CALL flush(numout)
1011      ENDIF
1012     
1013      IF( .NOT.lk_zdfddm )   CALL ctl_stop( 'STOP', 'zdf_tmx_init_new : key_zdftmx_new requires key_zdfddm' )
1014     
1015      !                             ! allocate tmx arrays
1016      IF( zdf_tmx_alloc() /= 0 )   CALL ctl_stop( 'STOP', 'zdf_tmx_init : unable to allocate tmx arrays' )
1017      !
1018      !                             ! read necessary fields
1019      CALL iom_open('mixing_power_bot',inum)       ! energy flux for high-mode wave breaking [W/m2]
1020      CALL iom_get  (inum, jpdom_data, 'field', ebot_tmx, 1 ) 
1021      CALL iom_close(inum)
1022      !
1023      CALL iom_open('mixing_power_pyc',inum)       ! energy flux for pynocline-intensified wave breaking [W/m2]
1024      CALL iom_get  (inum, jpdom_data, 'field', epyc_tmx, 1 )
1025      CALL iom_close(inum)
1026      !
1027      CALL iom_open('mixing_power_cri',inum)       ! energy flux for critical slope wave breaking [W/m2]
1028      CALL iom_get  (inum, jpdom_data, 'field', ecri_tmx, 1 )
1029      CALL iom_close(inum)
1030      !
1031      CALL iom_open('decay_scale_bot',inum)        ! spatially variable decay scale for high-mode wave breaking [m]
1032      CALL iom_get  (inum, jpdom_data, 'field', hbot_tmx, 1 )
1033      CALL iom_close(inum)
1034      !
1035      CALL iom_open('decay_scale_cri',inum)        ! spatially variable decay scale for critical slope wave breaking [m]
1036      CALL iom_get  (inum, jpdom_data, 'field', hcri_tmx, 1 )
1037      CALL iom_close(inum)
1038
1039      ebot_tmx(:,:) = ebot_tmx(:,:) * ssmask(:,:)
1040      epyc_tmx(:,:) = epyc_tmx(:,:) * ssmask(:,:)
1041      ecri_tmx(:,:) = ecri_tmx(:,:) * ssmask(:,:)
1042
1043      ! Set once for all to zero the first and last vertical levels of appropriate variables
1044      emix_tmx (:,:, 1 ) = 0._wp
1045      emix_tmx (:,:,jpk) = 0._wp
1046      zav_ratio(:,:, 1 ) = 0._wp
1047      zav_ratio(:,:,jpk) = 0._wp
1048      zav_wave (:,:, 1 ) = 0._wp
1049      zav_wave (:,:,jpk) = 0._wp
1050
1051      zbot = glob_sum( e1e2t(:,:) * ebot_tmx(:,:) )
1052      zpyc = glob_sum( e1e2t(:,:) * epyc_tmx(:,:) )
1053      zcri = glob_sum( e1e2t(:,:) * ecri_tmx(:,:) )
1054      IF(lwp) THEN
1055         WRITE(numout,*) '      High-mode wave-breaking energy:             ', zbot * 1.e-12_wp, 'TW'
1056         WRITE(numout,*) '      Pycnocline-intensifed wave-breaking energy: ', zpyc * 1.e-12_wp, 'TW'
1057         WRITE(numout,*) '      Critical slope wave-breaking energy:        ', zcri * 1.e-12_wp, 'TW'
1058         IF(lflush) CALL flush(numout)
1059      ENDIF
1060      !
1061      IF( nn_timing == 1 )  CALL timing_stop('zdf_tmx_init')
1062      !
1063   END SUBROUTINE zdf_tmx_init
1064
1065#else
1066   !!----------------------------------------------------------------------
1067   !!   Default option          Dummy module                NO Tidal MiXing
1068   !!----------------------------------------------------------------------
1069   LOGICAL, PUBLIC, PARAMETER ::   lk_zdftmx = .FALSE.   !: tidal mixing flag
1070CONTAINS
1071   SUBROUTINE zdf_tmx_init           ! Dummy routine
1072      WRITE(*,*) 'zdf_tmx: You should not have seen this print! error?'
1073   END SUBROUTINE zdf_tmx_init
1074   SUBROUTINE zdf_tmx( kt )          ! Dummy routine
1075      WRITE(*,*) 'zdf_tmx: You should not have seen this print! error?', kt
1076   END SUBROUTINE zdf_tmx
1077#endif
1078
1079   !!======================================================================
1080END MODULE zdftmx
Note: See TracBrowser for help on using the repository browser.