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.
Changeset 6043 for branches/2014/dev_r4650_UKMO14.12_STAND_ALONE_OBSOPER/NEMOGCM/NEMO/OPA_SRC/LDF – NEMO

Ignore:
Timestamp:
2015-12-14T10:27:28+01:00 (8 years ago)
Author:
timgraham
Message:

Merged head of trunk into branch

Location:
branches/2014/dev_r4650_UKMO14.12_STAND_ALONE_OBSOPER/NEMOGCM/NEMO/OPA_SRC/LDF
Files:
14 deleted
3 edited
1 copied

Legend:

Unmodified
Added
Removed
  • branches/2014/dev_r4650_UKMO14.12_STAND_ALONE_OBSOPER/NEMOGCM/NEMO/OPA_SRC/LDF/ldfdyn.F90

    r4624 r6043  
    66   !! History :  OPA  ! 1997-07  (G. Madec)  multi dimensional coefficients 
    77   !!   NEMO     1.0  ! 2002-09  (G. Madec)  F90: Free form and module 
    8    !!---------------------------------------------------------------------- 
    9  
    10    !!---------------------------------------------------------------------- 
    11    !!   ldf_dyn_init : initialization, namelist read, and parameters control 
    12    !!   ldf_dyn_c3d   : 3D eddy viscosity coefficient initialization 
    13    !!   ldf_dyn_c2d   : 2D eddy viscosity coefficient initialization 
    14    !!   ldf_dyn_c1d   : 1D eddy viscosity coefficient initialization 
     8   !!            3.7  ! 2014-01  (F. Lemarie, G. Madec)  restructuration/simplification of ahm specification, 
     9   !!                 !                                  add velocity dependent coefficient and optional read in file 
     10   !!---------------------------------------------------------------------- 
     11 
     12   !!---------------------------------------------------------------------- 
     13   !!   ldf_dyn_init  : initialization, namelist read, and parameters control 
     14   !!   ldf_dyn       : update lateral eddy viscosity coefficients at each time step  
    1515   !!---------------------------------------------------------------------- 
    1616   USE oce             ! ocean dynamics and tracers    
    1717   USE dom_oce         ! ocean space and time domain  
    18    USE ldfdyn_oce      ! ocean dynamics lateral physics 
    1918   USE phycst          ! physical constants 
    20    USE ldfslp          ! ??? 
    21    USE ioipsl 
     19   USE ldfc1d_c2d      ! lateral diffusion: 1D and 2D cases 
     20   ! 
    2221   USE in_out_manager  ! I/O manager 
     22   USE iom             ! I/O module for ehanced bottom friction file 
     23   USE timing          ! Timing 
    2324   USE lib_mpp         ! distribued memory computing library 
    2425   USE lbclnk          ! ocean lateral boundary conditions (or mpp link) 
     
    2829   PRIVATE 
    2930 
    30    PUBLIC   ldf_dyn_init   ! called by opa.F90 
    31  
    32   INTERFACE ldf_zpf 
    33      MODULE PROCEDURE ldf_zpf_1d, ldf_zpf_1d_3d, ldf_zpf_3d 
    34   END INTERFACE 
     31   PUBLIC   ldf_dyn_init   ! called by nemogcm.F90 
     32   PUBLIC   ldf_dyn        ! called by step.F90 
     33 
     34   !                                                !!* Namelist namdyn_ldf : lateral mixing on momentum * 
     35   LOGICAL , PUBLIC ::   ln_dynldf_lap   !: laplacian operator 
     36   LOGICAL , PUBLIC ::   ln_dynldf_blp   !: bilaplacian operator 
     37   LOGICAL , PUBLIC ::   ln_dynldf_lev   !: iso-level direction 
     38   LOGICAL , PUBLIC ::   ln_dynldf_hor   !: horizontal (geopotential) direction 
     39   LOGICAL , PUBLIC ::   ln_dynldf_iso   !: iso-neutral direction 
     40   INTEGER , PUBLIC ::   nn_ahm_ijk_t    !: choice of time & space variations of the lateral eddy viscosity coef. 
     41   REAL(wp), PUBLIC ::   rn_ahm_0        !: lateral laplacian eddy viscosity            [m2/s] 
     42   REAL(wp), PUBLIC ::   rn_ahm_b        !: lateral laplacian background eddy viscosity [m2/s] 
     43   REAL(wp), PUBLIC ::   rn_bhm_0        !: lateral bilaplacian eddy viscosity          [m4/s] 
     44 
     45   LOGICAL , PUBLIC ::   l_ldfdyn_time   !: flag for time variation of the lateral eddy viscosity coef. 
     46 
     47   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   ahmt, ahmf   !: eddy diffusivity coef. at U- and V-points   [m2/s or m4/s] 
     48 
     49   REAL(wp) ::   r1_12   = 1._wp / 12._wp    ! =1/12 
     50   REAL(wp) ::   r1_4    = 0.25_wp           ! =1/4 
     51   REAL(wp) ::   r1_288  = 1._wp / 288._wp   ! =1/( 12^2 * 2 ) 
    3552 
    3653   !! * Substitutions 
    3754#  include "domzgr_substitute.h90" 
    38    !!---------------------------------------------------------------------- 
    39    !! NEMO/OPA 3.3 , NEMO Consortium (2010) 
     55#  include "vectopt_loop_substitute.h90" 
     56   !!---------------------------------------------------------------------- 
     57   !! NEMO/OPA 3.7 , NEMO Consortium (2014) 
    4058   !! $Id$  
    4159   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt) 
     
    4967      !! ** Purpose :   set the horizontal ocean dynamics physics 
    5068      !! 
    51       !! ** Method  :   
    52       !!      -  default option : ahm = constant coef. = rn_ahm_0 (namelist) 
    53       !!      - 'key_dynldf_c1d': ahm = F(depth)                     see ldf_dyn_c1d.h90 
    54       !!      - 'key_dynldf_c2d': ahm = F(latitude,longitude)        see ldf_dyn_c2d.h90 
    55       !!      - 'key_dynldf_c3d': ahm = F(latitude,longitude,depth)  see ldf_dyn_c3d.h90 
    56       !! 
    57       !!      N.B. User defined include files.  By default, 3d and 2d coef. 
    58       !!      are set to a constant value given in the namelist and the 1d 
    59       !!      coefficients are initialized to a hyperbolic tangent vertical 
    60       !!      profile. 
    61       !! 
    62       !! Reference :   Madec, G. and M. Imbard, 1996: Climate Dynamics, 12, 381-388. 
    63       !!---------------------------------------------------------------------- 
    64       INTEGER ::   ioptio         ! ??? 
    65       INTEGER ::   ios            ! Local : output status for namelist read 
    66       LOGICAL ::   ll_print = .FALSE.    ! Logical flag for printing viscosity coef. 
    67       !!  
    68       NAMELIST/namdyn_ldf/ ln_dynldf_lap  , ln_dynldf_bilap,                  & 
    69          &                 ln_dynldf_level, ln_dynldf_hor  , ln_dynldf_iso,   & 
    70          &                 rn_ahm_0_lap   , rn_ahmb_0      , rn_ahm_0_blp ,   & 
    71          &                 rn_cmsmag_1    , rn_cmsmag_2    , rn_cmsh,         & 
    72          &                 rn_ahm_m_lap   , rn_ahm_m_blp 
    73  
    74    !!---------------------------------------------------------------------- 
    75  
     69      !! ** Method  :   the eddy viscosity coef. specification depends on: 
     70      !!              - the operator: 
     71      !!             ln_dynldf_lap = T     laplacian operator 
     72      !!             ln_dynldf_blp = T   bilaplacian operator 
     73      !!              - the parameter nn_ahm_ijk_t: 
     74      !!    nn_ahm_ijk_t  =  0 => = constant 
     75      !!                  = 10 => = F(z) :     = constant with a reduction of 1/4 with depth  
     76      !!                  =-20 => = F(i,j)     = shape read in 'eddy_viscosity.nc' file 
     77      !!                  = 20    = F(i,j)     = F(e1,e2) or F(e1^3,e2^3) (lap or bilap case) 
     78      !!                  =-30 => = F(i,j,k)   = shape read in 'eddy_viscosity.nc'  file 
     79      !!                  = 30    = F(i,j,k)   = 2D (case 20) + decrease with depth (case 10) 
     80      !!                  = 31    = F(i,j,k,t) = F(local velocity) (  |u|e  /12   laplacian operator 
     81      !!                                                           or |u|e^3/12 bilaplacian operator ) 
     82      !!---------------------------------------------------------------------- 
     83      INTEGER  ::   jk                ! dummy loop indices 
     84      INTEGER  ::   ierr, inum, ios   ! local integer 
     85      REAL(wp) ::   zah0              ! local scalar 
     86      ! 
     87      NAMELIST/namdyn_ldf/ ln_dynldf_lap, ln_dynldf_blp,                  & 
     88         &                 ln_dynldf_lev, ln_dynldf_hor, ln_dynldf_iso,   & 
     89         &                 nn_ahm_ijk_t , rn_ahm_0, rn_ahm_b, rn_bhm_0 
     90      !!---------------------------------------------------------------------- 
     91      ! 
    7692      REWIND( numnam_ref )              ! Namelist namdyn_ldf in reference namelist : Lateral physics 
    7793      READ  ( numnam_ref, namdyn_ldf, IOSTAT = ios, ERR = 901) 
     
    88104         WRITE(numout,*) '~~~~~~~' 
    89105         WRITE(numout,*) '   Namelist namdyn_ldf : set lateral mixing parameters' 
    90          WRITE(numout,*) '      laplacian operator                      ln_dynldf_lap   = ', ln_dynldf_lap 
    91          WRITE(numout,*) '      bilaplacian operator                    ln_dynldf_bilap = ', ln_dynldf_bilap 
    92          WRITE(numout,*) '      iso-level                               ln_dynldf_level = ', ln_dynldf_level 
    93          WRITE(numout,*) '      horizontal (geopotential)               ln_dynldf_hor   = ', ln_dynldf_hor 
    94          WRITE(numout,*) '      iso-neutral                             ln_dynldf_iso   = ', ln_dynldf_iso 
    95          WRITE(numout,*) '      horizontal laplacian eddy viscosity     rn_ahm_0_lap    = ', rn_ahm_0_lap 
    96          WRITE(numout,*) '      background viscosity                    rn_ahmb_0       = ', rn_ahmb_0 
    97          WRITE(numout,*) '      horizontal bilaplacian eddy viscosity   rn_ahm_0_blp    = ', rn_ahm_0_blp 
    98          WRITE(numout,*) '      upper limit for laplacian eddy visc     rn_ahm_m_lap    = ', rn_ahm_m_lap 
    99          WRITE(numout,*) '      upper limit for bilap eddy viscosity    rn_ahm_m_blp    = ', rn_ahm_m_blp 
    100  
    101       ENDIF 
    102  
    103       ahm0     = rn_ahm_0_lap              ! OLD namelist variables defined from DOCTOR namelist variables 
    104       ahmb0    = rn_ahmb_0 
    105       ahm0_blp = rn_ahm_0_blp 
    106  
    107       ! ... check of lateral diffusive operator on tracers 
    108       !           ==> will be done in trazdf module 
    109  
    110       ! ... Space variation of eddy coefficients 
    111       ioptio = 0 
    112 #if defined key_dynldf_c3d 
    113       IF(lwp) WRITE(numout,*) '   momentum mixing coef. = F( latitude, longitude, depth)' 
    114       ioptio = ioptio+1 
    115 #endif 
    116 #if defined key_dynldf_c2d 
    117       IF(lwp) WRITE(numout,*) '   momentum mixing coef. = F( latitude, longitude)' 
    118       ioptio = ioptio+1 
    119 #endif 
    120 #if defined key_dynldf_c1d 
    121       IF(lwp) WRITE(numout,*) '   momentum mixing coef. = F( depth )' 
    122       ioptio = ioptio+1 
    123       IF( ln_sco ) CALL ctl_stop( 'key_dynldf_c1d cannot be used in s-coordinate (ln_sco)' ) 
    124 #endif 
    125       IF( ioptio == 0 ) THEN 
    126           IF(lwp) WRITE(numout,*) '   momentum mixing coef. = constant  (default option)' 
    127         ELSEIF( ioptio > 1 ) THEN 
    128            CALL ctl_stop( 'use only one of the following keys: key_dynldf_c3d, key_dynldf_c2d, key_dynldf_c1d' ) 
    129       ENDIF 
    130  
    131  
    132       IF( ln_dynldf_bilap ) THEN 
    133          IF(lwp) WRITE(numout,*) '   biharmonic momentum diffusion' 
    134          IF( .NOT. ln_dynldf_lap ) ahm0 = ahm0_blp   ! Allow spatially varying coefs, which use ahm0 as input 
    135          IF( ahm0_blp > 0 .AND. .NOT. lk_esopa )   CALL ctl_stop( 'The horizontal viscosity coef. ahm0 must be negative' ) 
    136       ELSE 
    137          IF(lwp) WRITE(numout,*) '   harmonic momentum diff. (default)' 
    138          IF( ahm0 < 0 .AND. .NOT. lk_esopa )   CALL ctl_stop( 'The horizontal viscosity coef. ahm0 must be positive' ) 
    139       ENDIF 
    140  
    141  
    142       ! Lateral eddy viscosity 
    143       ! ====================== 
    144 #if defined key_dynldf_c3d 
    145       CALL ldf_dyn_c3d( ll_print )   ! ahm = 3D coef. = F( longitude, latitude, depth ) 
    146 #elif defined key_dynldf_c2d 
    147       CALL ldf_dyn_c2d( ll_print )   ! ahm = 1D coef. = F( longitude, latitude ) 
    148 #elif defined key_dynldf_c1d 
    149       CALL ldf_dyn_c1d( ll_print )   ! ahm = 1D coef. = F( depth ) 
    150 #else 
    151                                      ! Constant coefficients 
    152       IF(lwp) WRITE(numout,*) 
    153       IF(lwp) WRITE(numout,*) 'inildf: constant eddy viscosity coef. ' 
    154       IF(lwp) WRITE(numout,*) '~~~~~~' 
    155       IF(lwp) WRITE(numout,*) '        ahm1 = ahm2 = ahm0 =  ',ahm0 
    156 #endif 
    157      nkahm_smag = 0 
    158 #if defined key_dynldf_smag 
    159      nkahm_smag = 1 
    160 #endif 
    161  
     106         ! 
     107         WRITE(numout,*) '      type :' 
     108         WRITE(numout,*) '         laplacian operator                   ln_dynldf_lap = ', ln_dynldf_lap 
     109         WRITE(numout,*) '         bilaplacian operator                 ln_dynldf_blp = ', ln_dynldf_blp 
     110         ! 
     111         WRITE(numout,*) '      direction of action :' 
     112         WRITE(numout,*) '         iso-level                            ln_dynldf_lev = ', ln_dynldf_lev 
     113         WRITE(numout,*) '         horizontal (geopotential)            ln_dynldf_hor = ', ln_dynldf_hor 
     114         WRITE(numout,*) '         iso-neutral                          ln_dynldf_iso = ', ln_dynldf_iso 
     115         ! 
     116         WRITE(numout,*) '      coefficients :' 
     117         WRITE(numout,*) '         type of time-space variation         nn_ahm_ijk_t  = ', nn_ahm_ijk_t 
     118         WRITE(numout,*) '         lateral laplacian eddy viscosity     rn_ahm_0_lap  = ', rn_ahm_0, ' m2/s' 
     119         WRITE(numout,*) '         background viscosity (iso case)      rn_ahm_b      = ', rn_ahm_b, ' m2/s' 
     120         WRITE(numout,*) '         lateral bilaplacian eddy viscosity   rn_ahm_0_blp  = ', rn_bhm_0, ' m4/s' 
     121      ENDIF 
     122 
     123      !                                ! Parameter control 
     124      IF( .NOT.ln_dynldf_lap .AND. .NOT.ln_dynldf_blp ) THEN 
     125         IF(lwp) WRITE(numout,*) '   No viscous operator selected. ahmt and ahmf are not allocated' 
     126         l_ldfdyn_time = .FALSE. 
     127         RETURN 
     128      ENDIF 
     129      ! 
     130      IF( ln_dynldf_blp .AND. ln_dynldf_iso ) THEN     ! iso-neutral bilaplacian not implemented 
     131         CALL ctl_stop( 'dyn_ldf_init: iso-neutral bilaplacian not coded yet' )  
     132      ENDIF 
     133 
     134      ! ... Space/Time variation of eddy coefficients 
     135      !                                               ! allocate the ahm arrays 
     136      ALLOCATE( ahmt(jpi,jpj,jpk) , ahmf(jpi,jpj,jpk) , STAT=ierr ) 
     137      IF( ierr /= 0 )   CALL ctl_stop( 'STOP', 'ldf_dyn_init: failed to allocate arrays') 
     138      ! 
     139      ahmt(:,:,jpk) = 0._wp                           ! last level always 0   
     140      ahmf(:,:,jpk) = 0._wp 
     141      ! 
     142      !                                               ! value of eddy mixing coef. 
     143      IF    ( ln_dynldf_lap ) THEN   ;   zah0 =      rn_ahm_0         !   laplacian operator 
     144      ELSEIF( ln_dynldf_blp ) THEN   ;   zah0 = ABS( rn_bhm_0 )       ! bilaplacian operator 
     145      ELSE                                                                  ! NO viscous  operator 
     146         CALL ctl_warn( 'ldf_dyn_init: No lateral viscous operator used ' ) 
     147      ENDIF 
     148      ! 
     149      l_ldfdyn_time = .FALSE.                         ! no time variation except in case defined below 
     150      ! 
     151      IF( ln_dynldf_lap .OR. ln_dynldf_blp ) THEN     ! only if a lateral diffusion operator is used 
     152         ! 
     153         SELECT CASE(  nn_ahm_ijk_t  )                ! Specification of space time variations of ahmt, ahmf 
     154         ! 
     155         CASE(   0  )      !==  constant  ==! 
     156            IF(lwp) WRITE(numout,*) '          momentum mixing coef. = constant ' 
     157            ahmt(:,:,:) = zah0 * tmask(:,:,:) 
     158            ahmf(:,:,:) = zah0 * fmask(:,:,:) 
     159            ! 
     160         CASE(  10  )      !==  fixed profile  ==! 
     161            IF(lwp) WRITE(numout,*) '          momentum mixing coef. = F( depth )' 
     162            ahmt(:,:,1) = zah0 * tmask(:,:,1)                      ! constant surface value 
     163            ahmf(:,:,1) = zah0 * fmask(:,:,1) 
     164            CALL ldf_c1d( 'DYN', r1_4, ahmt(:,:,1), ahmf(:,:,1), ahmt, ahmf ) 
     165            ! 
     166         CASE ( -20 )      !== fixed horizontal shape read in file  ==! 
     167            IF(lwp) WRITE(numout,*) '          momentum mixing coef. = F(i,j) read in eddy_viscosity.nc file' 
     168            CALL iom_open( 'eddy_viscosity_2D.nc', inum ) 
     169            CALL iom_get ( inum, jpdom_data, 'ahmt_2d', ahmt(:,:,1) ) 
     170            CALL iom_get ( inum, jpdom_data, 'ahmf_2d', ahmf(:,:,1) ) 
     171            CALL iom_close( inum ) 
     172!!gm Question : info for LAP or BLP case  to take into account the SQRT in the bilaplacian case ??? 
     173!!              do we introduce a scaling by the max value of the array, and then multiply by zah0 ???? 
     174!!              better:  check that the max is <=1  i.e. it is a shape from 0 to 1, not a coef that has physical dimension 
     175            DO jk = 2, jpkm1 
     176               ahmt(:,:,jk) = ahmt(:,:,1) * tmask(:,:,jk) 
     177               ahmf(:,:,jk) = ahmf(:,:,1) * fmask(:,:,jk) 
     178            END DO 
     179            ! 
     180         CASE(  20  )      !== fixed horizontal shape  ==! 
     181            IF(lwp) WRITE(numout,*) '          momentum mixing coef. = F( e1, e2 ) or F( e1^3, e2^3 ) (lap. or blp. case)' 
     182            IF( ln_dynldf_lap )   CALL ldf_c2d( 'DYN', 'LAP', zah0, ahmt, ahmf )    ! surface value proportional to scale factor 
     183            IF( ln_dynldf_blp )   CALL ldf_c2d( 'DYN', 'BLP', zah0, ahmt, ahmf )    ! surface value proportional to scale factor^3 
     184            ! 
     185         CASE( -30  )      !== fixed 3D shape read in file  ==! 
     186            IF(lwp) WRITE(numout,*) '          momentum mixing coef. = F(i,j,k) read in eddy_diffusivity_3D.nc file' 
     187            CALL iom_open( 'eddy_viscosity_3D.nc', inum ) 
     188            CALL iom_get ( inum, jpdom_data, 'ahmt_3d', ahmt ) 
     189            CALL iom_get ( inum, jpdom_data, 'ahmf_3d', ahmf ) 
     190            CALL iom_close( inum ) 
     191!!gm Question : info for LAP or BLP case  to take into account the SQRT in the bilaplacian case ???? 
     192!!              do we introduce a scaling by the max value of the array, and then multiply by zah0 ???? 
     193            DO jk = 1, jpkm1 
     194               ahmt(:,:,jk) = ahmt(:,:,jk) * tmask(:,:,jk) 
     195               ahmf(:,:,jk) = ahmf(:,:,jk) * fmask(:,:,jk) 
     196            END DO 
     197            ! 
     198         CASE(  30  )       !==  fixed 3D shape  ==! 
     199            IF(lwp) WRITE(numout,*) '          momentum mixing coef. = F( latitude, longitude, depth )' 
     200            IF( ln_dynldf_lap )   CALL ldf_c2d( 'DYN', 'LAP', zah0, ahmt, ahmf )    ! surface value proportional to scale factor 
     201            IF( ln_dynldf_blp )   CALL ldf_c2d( 'DYN', 'BLP', zah0, ahmt, ahmf )    ! surface value proportional to scale factor 
     202            !                                                    ! reduction with depth 
     203            CALL ldf_c1d( 'DYN', r1_4, ahmt(:,:,1), ahmf(:,:,1), ahmt, ahmf ) 
     204            ! 
     205         CASE(  31  )       !==  time varying 3D field  ==! 
     206            IF(lwp) WRITE(numout,*) '          momentum mixing coef. = F( latitude, longitude, depth , time )' 
     207            IF(lwp) WRITE(numout,*) '                                proportional to the velocity : |u|e/12 or |u|e^3/12' 
     208            ! 
     209            l_ldfdyn_time = .TRUE.     ! will be calculated by call to ldf_dyn routine in step.F90 
     210            ! 
     211         CASE DEFAULT 
     212            CALL ctl_stop('ldf_dyn_init: wrong choice for nn_ahm_ijk_t, the type of space-time variation of ahm') 
     213         END SELECT 
     214         ! 
     215         IF( ln_dynldf_blp .AND. .NOT. l_ldfdyn_time ) THEN       ! bilapcian and no time variation: 
     216            ahmt(:,:,:) = SQRT( ahmt(:,:,:) )                     ! take the square root of the coefficient 
     217            ahmf(:,:,:) = SQRT( ahmf(:,:,:) ) 
     218         ENDIF 
     219         ! 
     220      ENDIF 
    162221      ! 
    163222   END SUBROUTINE ldf_dyn_init 
    164223 
    165 #if defined key_dynldf_c3d 
    166 #   include "ldfdyn_c3d.h90" 
    167 #elif defined key_dynldf_c2d 
    168 #   include "ldfdyn_c2d.h90" 
    169 #elif defined key_dynldf_c1d 
    170 #   include "ldfdyn_c1d.h90" 
    171 #endif 
    172  
    173  
    174    SUBROUTINE ldf_zpf_1d( ld_print, pdam, pwam, pbot, pdep, pah ) 
    175       !!---------------------------------------------------------------------- 
    176       !!                  ***  ROUTINE ldf_zpf  *** 
    177       !!                    
    178       !! ** Purpose :   vertical adimensional profile for eddy coefficient 
    179       !! 
    180       !! ** Method  :   1D eddy viscosity coefficients ( depth ) 
    181       !!---------------------------------------------------------------------- 
    182       LOGICAL , INTENT(in   )                 ::   ld_print   ! If true, output arrays on numout 
    183       REAL(wp), INTENT(in   )                 ::   pdam       ! depth of the inflection point 
    184       REAL(wp), INTENT(in   )                 ::   pwam       ! width of inflection 
    185       REAL(wp), INTENT(in   )                 ::   pbot       ! bottom value (0<pbot<= 1) 
    186       REAL(wp), INTENT(in   ), DIMENSION(jpk) ::   pdep       ! depth of the gridpoint (T, U, V, F) 
    187       REAL(wp), INTENT(inout), DIMENSION(jpk) ::   pah        ! adimensional vertical profile 
    188       !! 
    189       INTEGER  ::   jk           ! dummy loop indices 
    190       REAL(wp) ::   zm00, zm01, zmhb, zmhs       ! temporary scalars 
    191       !!---------------------------------------------------------------------- 
    192  
    193       zm00 = TANH( ( pdam - gdept_1d(1    ) ) / pwam ) 
    194       zm01 = TANH( ( pdam - gdept_1d(jpkm1) ) / pwam ) 
    195       zmhs = zm00 / zm01 
    196       zmhb = ( 1.e0 - pbot ) / ( 1.e0 - zmhs ) / zm01 
    197  
    198       DO jk = 1, jpk 
    199          pah(jk) = 1.e0 + zmhb * ( zm00 - TANH( ( pdam - pdep(jk) ) / pwam )  ) 
    200       END DO 
    201  
    202       IF(lwp .AND. ld_print ) THEN      ! Control print 
    203          WRITE(numout,*) 
    204          WRITE(numout,*) '         ahm profile : ' 
    205          WRITE(numout,*) 
    206          WRITE(numout,'("  jk      ahm       ","  depth t-level " )') 
    207          DO jk = 1, jpk 
    208             WRITE(numout,'(i6,2f12.4,3x,2f12.4)') jk, pah(jk), pdep(jk) 
    209          END DO 
    210       ENDIF 
    211       ! 
    212    END SUBROUTINE ldf_zpf_1d 
    213  
    214  
    215    SUBROUTINE ldf_zpf_1d_3d( ld_print, pdam, pwam, pbot, pdep, pah ) 
    216       !!---------------------------------------------------------------------- 
    217       !!                  ***  ROUTINE ldf_zpf  *** 
    218       !! 
    219       !! ** Purpose :   vertical adimensional profile for eddy coefficient 
    220       !! 
    221       !! ** Method  :   1D eddy viscosity coefficients ( depth ) 
    222       !!---------------------------------------------------------------------- 
    223       LOGICAL , INTENT(in   )                         ::   ld_print   ! If true, output arrays on numout 
    224       REAL(wp), INTENT(in   )                         ::   pdam       ! depth of the inflection point 
    225       REAL(wp), INTENT(in   )                         ::   pwam       ! width of inflection 
    226       REAL(wp), INTENT(in   )                         ::   pbot       ! bottom value (0<pbot<= 1) 
    227       REAL(wp), INTENT(in   ), DIMENSION          (:) ::   pdep       ! depth of the gridpoint (T, U, V, F) 
    228       REAL(wp), INTENT(inout), DIMENSION      (:,:,:) ::   pah        ! adimensional vertical profile 
    229       !! 
    230       INTEGER  ::   jk           ! dummy loop indices 
    231       REAL(wp) ::   zm00, zm01, zmhb, zmhs, zcf  ! temporary scalars 
    232       !!---------------------------------------------------------------------- 
    233  
    234       zm00 = TANH( ( pdam - gdept_1d(1    ) ) / pwam ) 
    235       zm01 = TANH( ( pdam - gdept_1d(jpkm1) ) / pwam ) 
    236       zmhs = zm00 / zm01 
    237       zmhb = ( 1.e0 - pbot ) / ( 1.e0 - zmhs ) / zm01 
    238  
    239       DO jk = 1, jpk 
    240          zcf = 1.e0 + zmhb * ( zm00 - TANH( ( pdam - pdep(jk) ) / pwam )  ) 
    241          pah(:,:,jk) = zcf 
    242       END DO 
    243  
    244       IF(lwp .AND. ld_print ) THEN      ! Control print 
    245          WRITE(numout,*) 
    246          WRITE(numout,*) '         ahm profile : ' 
    247          WRITE(numout,*) 
    248          WRITE(numout,'("  jk      ahm       ","  depth t-level " )') 
    249          DO jk = 1, jpk 
    250             WRITE(numout,'(i6,2f12.4,3x,2f12.4)') jk, pah(1,1,jk), pdep(jk) 
    251          END DO 
    252       ENDIF 
    253       ! 
    254    END SUBROUTINE ldf_zpf_1d_3d 
    255  
    256  
    257    SUBROUTINE ldf_zpf_3d( ld_print, pdam, pwam, pbot, pdep, pah ) 
    258       !!---------------------------------------------------------------------- 
    259       !!                  ***  ROUTINE ldf_zpf  *** 
    260       !! 
    261       !! ** Purpose :   vertical adimensional profile for eddy coefficient 
    262       !! 
    263       !! ** Method  :   3D for partial step or s-coordinate 
    264       !!---------------------------------------------------------------------- 
    265       LOGICAL , INTENT(in   )                         ::   ld_print   ! If true, output arrays on numout 
    266       REAL(wp), INTENT(in   )                         ::   pdam       ! depth of the inflection point 
    267       REAL(wp), INTENT(in   )                         ::   pwam       ! width of inflection 
    268       REAL(wp), INTENT(in   )                         ::   pbot       ! bottom value (0<pbot<= 1) 
    269       REAL(wp), INTENT(in   ), DIMENSION      (:,:,:) ::   pdep       ! dep of the gridpoint (T, U, V, F) 
    270       REAL(wp), INTENT(inout), DIMENSION      (:,:,:) ::   pah        ! adimensional vertical profile 
    271       !! 
    272       INTEGER  ::   jk           ! dummy loop indices 
    273       REAL(wp) ::   zm00, zm01, zmhb, zmhs       ! temporary scalars 
    274       !!---------------------------------------------------------------------- 
    275  
    276       zm00 = TANH( ( pdam - gdept_1d(1    ) ) / pwam )    
    277       zm01 = TANH( ( pdam - gdept_1d(jpkm1) ) / pwam ) 
    278       zmhs = zm00 / zm01 
    279       zmhb = ( 1.e0 - pbot ) / ( 1.e0 - zmhs ) / zm01 
    280  
    281       DO jk = 1, jpk 
    282          pah(:,:,jk) = 1.e0 + zmhb * ( zm00 - TANH( ( pdam - pdep(:,:,jk) ) / pwam )  ) 
    283       END DO 
    284  
    285       IF(lwp .AND. ld_print ) THEN      ! Control print 
    286          WRITE(numout,*) 
    287          WRITE(numout,*) '         ahm profile : ' 
    288          WRITE(numout,*) 
    289          WRITE(numout,'("  jk      ahm       ","  depth t-level " )') 
    290          DO jk = 1, jpk 
    291             WRITE(numout,'(i6,2f12.4,3x,2f12.4)') jk, pah(1,1,jk), pdep(1,1,jk) 
    292          END DO 
    293       ENDIF 
    294       ! 
    295    END SUBROUTINE ldf_zpf_3d 
     224 
     225   SUBROUTINE ldf_dyn( kt ) 
     226      !!---------------------------------------------------------------------- 
     227      !!                  ***  ROUTINE ldf_dyn  *** 
     228      !!  
     229      !! ** Purpose :   update at kt the momentum lateral mixing coeff. (ahmt and ahmf) 
     230      !! 
     231      !! ** Method  :   time varying eddy viscosity coefficients: 
     232      !! 
     233      !!    nn_ahm_ijk_t = 31    ahmt, ahmf = F(i,j,k,t) = F(local velocity)  
     234      !!                         ( |u|e /12  or  |u|e^3/12 for laplacian or bilaplacian operator ) 
     235      !!                BLP case : sqrt of the eddy coef, since bilaplacian is en re-entrant laplacian 
     236      !! 
     237      !! ** action  :    ahmt, ahmf   update at each time step 
     238      !!---------------------------------------------------------------------- 
     239      INTEGER, INTENT(in) ::   kt   ! time step index 
     240      ! 
     241      INTEGER  ::   ji, jj, jk   ! dummy loop indices 
     242      REAL(wp) ::   zu2pv2_ij_p1, zu2pv2_ij, zu2pv2_ij_m1, zetmax, zefmax   ! local scalar 
     243      !!---------------------------------------------------------------------- 
     244      ! 
     245      IF( nn_timing == 1 )  CALL timing_start('ldf_dyn') 
     246      ! 
     247      SELECT CASE(  nn_ahm_ijk_t  )       !== Eddy vicosity coefficients ==! 
     248      ! 
     249      CASE(  31  )       !==  time varying 3D field  ==!   = F( local velocity ) 
     250         ! 
     251         IF( ln_dynldf_lap   ) THEN          !   laplacian operator : |u| e /12 = |u/144| e 
     252            DO jk = 1, jpkm1 
     253               DO jj = 2, jpjm1 
     254                  DO ji = fs_2, fs_jpim1 
     255                     zu2pv2_ij_p1 = ub(ji  ,jj+1,jk) * ub(ji  ,jj+1,jk) + vb(ji+1,jj  ,jk) * vb(ji+1,jj  ,jk) 
     256                     zu2pv2_ij    = ub(ji  ,jj  ,jk) * ub(ji  ,jj  ,jk) + vb(ji  ,jj  ,jk) * vb(ji  ,jj  ,jk) 
     257                     zu2pv2_ij_m1 = ub(ji-1,jj  ,jk) * ub(ji-1,jj  ,jk) + vb(ji  ,jj-1,jk) * vb(ji  ,jj-1,jk) 
     258                     zetmax = MAX( e1t(ji,jj) , e2t(ji,jj) ) 
     259                     zefmax = MAX( e1f(ji,jj) , e2f(ji,jj) ) 
     260                     ahmt(ji,jj,jk) = SQRT( (zu2pv2_ij + zu2pv2_ij_m1) * r1_288 ) * zetmax * tmask(ji,jj,jk)      ! 288= 12*12 * 2 
     261                     ahmf(ji,jj,jk) = SQRT( (zu2pv2_ij + zu2pv2_ij_p1) * r1_288 ) * zefmax * fmask(ji,jj,jk) 
     262                  END DO 
     263               END DO 
     264            END DO 
     265         ELSEIF( ln_dynldf_blp ) THEN      ! bilaplacian operator : sqrt( |u| e^3 /12 ) = sqrt( |u/144| e ) * e 
     266            DO jk = 1, jpkm1 
     267               DO jj = 2, jpjm1 
     268                  DO ji = fs_2, fs_jpim1 
     269                     zu2pv2_ij_p1 = ub(ji  ,jj+1,jk) * ub(ji  ,jj+1,jk) + vb(ji+1,jj  ,jk) * vb(ji+1,jj  ,jk) 
     270                     zu2pv2_ij    = ub(ji  ,jj  ,jk) * ub(ji  ,jj  ,jk) + vb(ji  ,jj  ,jk) * vb(ji  ,jj  ,jk) 
     271                     zu2pv2_ij_m1 = ub(ji-1,jj  ,jk) * ub(ji-1,jj  ,jk) + vb(ji  ,jj-1,jk) * vb(ji  ,jj-1,jk) 
     272                     zetmax = MAX( e1t(ji,jj) , e2t(ji,jj) ) 
     273                     zefmax = MAX( e1f(ji,jj) , e2f(ji,jj) ) 
     274                     ahmt(ji,jj,jk) = SQRT(  SQRT( (zu2pv2_ij + zu2pv2_ij_m1) * r1_288 ) * zetmax  ) * zetmax * tmask(ji,jj,jk) 
     275                     ahmf(ji,jj,jk) = SQRT(  SQRT( (zu2pv2_ij + zu2pv2_ij_p1) * r1_288 ) * zefmax  ) * zefmax * fmask(ji,jj,jk) 
     276                  END DO 
     277               END DO 
     278            END DO 
     279         ENDIF 
     280         ! 
     281         CALL lbc_lnk( ahmt, 'T', 1. )   ;   CALL lbc_lnk( ahmf, 'F', 1. ) 
     282         ! 
     283      END SELECT 
     284      ! 
     285      CALL iom_put( "ahmt_2d", ahmt(:,:,1) )   ! surface u-eddy diffusivity coeff. 
     286      CALL iom_put( "ahmf_2d", ahmf(:,:,1) )   ! surface v-eddy diffusivity coeff. 
     287      CALL iom_put( "ahmt_3d", ahmt(:,:,:) )   ! 3D      u-eddy diffusivity coeff. 
     288      CALL iom_put( "ahmf_3d", ahmf(:,:,:) )   ! 3D      v-eddy diffusivity coeff. 
     289      ! 
     290      IF( nn_timing == 1 )  CALL timing_stop('ldf_dyn') 
     291      ! 
     292   END SUBROUTINE ldf_dyn 
    296293 
    297294   !!====================================================================== 
  • branches/2014/dev_r4650_UKMO14.12_STAND_ALONE_OBSOPER/NEMOGCM/NEMO/OPA_SRC/LDF/ldfslp.F90

    r5600 r6043  
    1111   !!            3.3  ! 2010-10  (G. Nurser, C. Harris, G. Madec)  add Griffies operator 
    1212   !!             -   ! 2010-11  (F. Dupond, G. Madec)  bug correction in slopes just below the ML 
     13   !!            3.7  ! 2013-12  (F. Lemarie, G. Madec)  add limiter on triad slopes 
    1314   !!---------------------------------------------------------------------- 
    14 #if   defined key_ldfslp   ||   defined key_esopa 
     15 
    1516   !!---------------------------------------------------------------------- 
    16    !!   'key_ldfslp'                      Rotation of lateral mixing tensor 
    17    !!---------------------------------------------------------------------- 
    18    !!   ldf_slp_grif  : calculates the triads of isoneutral slopes (Griffies operator) 
    1917   !!   ldf_slp       : calculates the slopes of neutral surface   (Madec operator) 
     18   !!   ldf_slp_triad : calculates the triads of isoneutral slopes (Griffies operator) 
    2019   !!   ldf_slp_mxl   : calculates the slopes at the base of the mixed layer (Madec operator) 
    2120   !!   ldf_slp_init  : initialization of the slopes computation 
     
    2322   USE oce            ! ocean dynamics and tracers 
    2423   USE dom_oce        ! ocean space and time domain 
    25    USE ldftra_oce     ! lateral diffusion: traceur 
    26    USE ldfdyn_oce     ! lateral diffusion: dynamics 
     24   USE ldfdyn         ! lateral diffusion: eddy viscosity coef. 
    2725   USE phycst         ! physical constants 
    2826   USE zdfmxl         ! mixed layer depth 
     
    3028   ! 
    3129   USE in_out_manager ! I/O manager 
     30   USE prtctl         ! Print control 
    3231   USE lbclnk         ! ocean lateral boundary conditions (or mpp link) 
    33    USE prtctl         ! Print control 
     32   USE lib_mpp        ! distribued memory computing library 
     33   USE lib_fortran    ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 
    3434   USE wrk_nemo       ! work arrays 
    3535   USE timing         ! Timing 
    36    USE lib_fortran    ! Fortran utilities (allows no signed zero when 'key_nosignedzero' defined) 
    3736 
    3837   IMPLICIT NONE 
    3938   PRIVATE 
    4039 
    41    PUBLIC   ldf_slp        ! routine called by step.F90 
    42    PUBLIC   ldf_slp_grif   ! routine called by step.F90 
    43    PUBLIC   ldf_slp_init   ! routine called by opa.F90 
    44  
    45    LOGICAL , PUBLIC, PARAMETER ::   lk_ldfslp = .TRUE.     !: slopes flag 
    46    !                                                                             !! Madec operator 
    47    !  Arrays allocated in ldf_slp_init() routine once we know whether we're using the Griffies or Madec operator 
     40   PUBLIC   ldf_slp         ! routine called by step.F90 
     41   PUBLIC   ldf_slp_triad   ! routine called by step.F90 
     42   PUBLIC   ldf_slp_init    ! routine called by nemogcm.F90 
     43 
     44   LOGICAL , PUBLIC ::   l_ldfslp = .FALSE.     !: slopes flag 
     45 
     46   LOGICAL , PUBLIC ::   ln_traldf_iso   = .TRUE.       !: iso-neutral direction 
     47   LOGICAL , PUBLIC ::   ln_traldf_triad = .FALSE.      !: griffies triad scheme 
     48 
     49   LOGICAL , PUBLIC ::   ln_triad_iso    = .FALSE.      !: pure horizontal mixing in ML 
     50   LOGICAL , PUBLIC ::   ln_botmix_triad = .FALSE.      !: mixing on bottom 
     51   REAL(wp), PUBLIC ::   rn_sw_triad     = 1._wp        !: =1 switching triads ; =0 all four triads used  
     52   REAL(wp), PUBLIC ::   rn_slpmax       = 0.01_wp      !: slope limit 
     53 
     54   LOGICAL , PUBLIC ::   l_grad_zps = .FALSE.           !: special treatment for Horz Tgradients w partial steps (triad operator) 
     55    
     56   !                                                     !! Classic operator (Madec) 
    4857   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)     ::   uslp, wslpi          !: i_slope at U- and W-points 
    4958   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)     ::   vslp, wslpj          !: j-slope at V- and W-points 
    50    !                                                                !! Griffies operator 
     59   !                                                     !! triad operator (Griffies) 
    5160   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)     ::   wslp2                !: wslp**2 from Griffies quarter cells 
    5261   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:,:,:) ::   triadi_g, triadj_g   !: skew flux  slopes relative to geopotentials 
    5362   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:,:,:) ::   triadi  , triadj     !: isoneutral slopes relative to model-coordinate 
    54  
    55    !                                                              !! Madec operator 
    56    !  Arrays allocated in ldf_slp_init() routine once we know whether we're using the Griffies or Madec operator 
     63   !                                                     !! both operators 
     64   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)     ::   ah_wslp2             !: ah * slope^2 at w-point 
     65   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:)     ::   akz                  !: stabilizing vertical diffusivity 
     66    
     67   !                                                     !! Madec operator 
    5768   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   omlmask           ! mask of the surface mixed layer at T-pt 
    5869   REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:)   ::   uslpml, wslpiml   ! i_slope at U- and W-points just below the mixed layer 
     
    6374   !! * Substitutions 
    6475#  include "domzgr_substitute.h90" 
    65 #  include "ldftra_substitute.h90" 
    66 #  include "ldfeiv_substitute.h90" 
    6776#  include "vectopt_loop_substitute.h90" 
    6877   !!---------------------------------------------------------------------- 
    69    !! NEMO/OPA 4.0 , NEMO Consortium (2011) 
     78   !! NEMO/OPA 4.0 , NEMO Consortium (2014) 
    7079   !! $Id$ 
    7180   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt) 
     
    105114      INTEGER  ::   ii0, ii1, iku   ! temporary integer 
    106115      INTEGER  ::   ij0, ij1, ikv   ! temporary integer 
    107       REAL(wp) ::   zeps, zm1_g, zm1_2g, z1_16, zcofw ! local scalars 
     116      REAL(wp) ::   zeps, zm1_g, zm1_2g, z1_16, zcofw, z1_slpmax ! local scalars 
    108117      REAL(wp) ::   zci, zfi, zau, zbu, zai, zbi   !   -      - 
    109118      REAL(wp) ::   zcj, zfj, zav, zbv, zaj, zbj   !   -      - 
    110119      REAL(wp) ::   zck, zfk,      zbw             !   -      - 
    111       REAL(wp) ::   zdepv, zdepu         !   -      - 
    112120      REAL(wp), POINTER, DIMENSION(:,:,:) ::  zwz, zww 
    113121      REAL(wp), POINTER, DIMENSION(:,:,:) ::  zdzr 
    114122      REAL(wp), POINTER, DIMENSION(:,:,:) ::  zgru, zgrv 
    115       REAL(wp), POINTER, DIMENSION(:,:  ) :: zhmlpu, zhmlpv 
    116123      !!---------------------------------------------------------------------- 
    117124      ! 
     
    119126      ! 
    120127      CALL wrk_alloc( jpi,jpj,jpk, zwz, zww, zdzr, zgru, zgrv ) 
    121       CALL wrk_alloc( jpi,jpj, zhmlpu, zhmlpv ) 
    122  
    123       IF ( ln_traldf_iso .OR. ln_dynldf_iso ) THEN  
    124       
    125          zeps   =  1.e-20_wp        !==   Local constant initialization   ==! 
    126          z1_16  =  1.0_wp / 16._wp 
    127          zm1_g  = -1.0_wp / grav 
    128          zm1_2g = -0.5_wp / grav 
    129          ! 
    130          zww(:,:,:) = 0._wp 
    131          zwz(:,:,:) = 0._wp 
    132          ! 
    133          DO jk = 1, jpk             !==   i- & j-gradient of density   ==! 
    134             DO jj = 1, jpjm1 
    135                DO ji = 1, fs_jpim1   ! vector opt. 
    136                   zgru(ji,jj,jk) = umask(ji,jj,jk) * ( prd(ji+1,jj  ,jk) - prd(ji,jj,jk) ) 
    137                   zgrv(ji,jj,jk) = vmask(ji,jj,jk) * ( prd(ji  ,jj+1,jk) - prd(ji,jj,jk) ) 
    138                END DO 
    139             END DO 
    140          END DO 
    141          IF( ln_zps ) THEN                           ! partial steps correction at the bottom ocean level 
    142             DO jj = 1, jpjm1 
    143                DO ji = 1, jpim1 
    144                   zgru(ji,jj,mbku(ji,jj)) = gru(ji,jj) 
    145                   zgrv(ji,jj,mbkv(ji,jj)) = grv(ji,jj) 
    146                END DO 
    147             END DO 
    148          ENDIF 
    149          IF( ln_zps .AND. ln_isfcav ) THEN           ! partial steps correction at the bottom ocean level 
    150             DO jj = 1, jpjm1 
    151                DO ji = 1, jpim1 
    152                IF ( miku(ji,jj) > 1 ) zgru(ji,jj,miku(ji,jj)) = grui(ji,jj)  
    153                IF ( mikv(ji,jj) > 1 ) zgrv(ji,jj,mikv(ji,jj)) = grvi(ji,jj) 
    154                END DO 
    155             END DO 
    156          ENDIF 
    157          ! 
    158          !==   Local vertical density gradient at T-point   == !   (evaluated from N^2) 
    159          ! interior value 
    160          DO jk = 2, jpkm1 
    161             !                                ! zdzr = d/dz(prd)= - ( prd ) / grav * mk(pn2) -- at t point 
    162             !                                !   trick: tmask(ik  )  = 0   =>   all pn2   = 0   =>   zdzr = 0 
    163             !                                !    else  tmask(ik+1)  = 0   =>   pn2(ik+1) = 0   =>   zdzr divides by 1 
    164             !                                !          umask(ik+1) /= 0   =>   all pn2  /= 0   =>   zdzr divides by 2 
    165             !                                ! NB: 1/(tmask+1) = (1-.5*tmask)  substitute a / by a *  ==> faster 
    166             zdzr(:,:,jk) = zm1_g * ( prd(:,:,jk) + 1._wp )              & 
    167                &                 * ( pn2(:,:,jk) + pn2(:,:,jk+1) ) * ( 1._wp - 0.5_wp * tmask(:,:,jk+1) ) 
    168          END DO 
    169          ! surface initialisation  
    170          zdzr(:,:,1) = 0._wp  
    171          IF ( ln_isfcav ) THEN 
    172             ! if isf need to overwrite the interior value at at the first ocean point 
    173             DO jj = 1, jpjm1 
    174                DO ji = 1, jpim1 
    175                   zdzr(ji,jj,1:mikt(ji,jj)) = 0._wp 
    176                END DO 
    177             END DO 
    178          END IF 
    179          ! 
    180          !                          !==   Slopes just below the mixed layer   ==! 
    181          CALL ldf_slp_mxl( prd, pn2, zgru, zgrv, zdzr )        ! output: uslpml, vslpml, wslpiml, wslpjml 
    182  
    183  
    184          ! I.  slopes at u and v point      | uslp = d/di( prd ) / d/dz( prd ) 
    185          ! ===========================      | vslp = d/dj( prd ) / d/dz( prd ) 
    186          ! 
    187          IF ( ln_isfcav ) THEN 
    188             DO jj = 2, jpjm1 
    189                DO ji = fs_2, fs_jpim1   ! vector opt. 
    190                   IF (miku(ji,jj) .GT. miku(ji+1,jj)) zhmlpu(ji,jj) = MAX(hmlpt(ji  ,jj  ),                   5._wp) 
    191                   IF (miku(ji,jj) .LT. miku(ji+1,jj)) zhmlpu(ji,jj) = MAX(hmlpt(ji+1,jj  ),                   5._wp) 
    192                   IF (miku(ji,jj) .EQ. miku(ji+1,jj)) zhmlpu(ji,jj) = MAX(hmlpt(ji  ,jj  ), hmlpt(ji+1,jj  ), 5._wp) 
    193                   IF (mikv(ji,jj) .GT. miku(ji,jj+1)) zhmlpv(ji,jj) = MAX(hmlpt(ji  ,jj  ),                   5._wp) 
    194                   IF (mikv(ji,jj) .LT. miku(ji,jj+1)) zhmlpv(ji,jj) = MAX(hmlpt(ji  ,jj+1),                   5._wp) 
    195                   IF (mikv(ji,jj) .EQ. miku(ji,jj+1)) zhmlpv(ji,jj) = MAX(hmlpt(ji  ,jj  ), hmlpt(ji  ,jj+1), 5._wp) 
    196                ENDDO 
    197             ENDDO 
    198          ELSE 
    199             DO jj = 2, jpjm1 
    200                DO ji = fs_2, fs_jpim1   ! vector opt. 
    201                   zhmlpu(ji,jj) = MAX(hmlpt(ji,jj), hmlpt(ji+1,jj  ), 5._wp) 
    202                   zhmlpv(ji,jj) = MAX(hmlpt(ji,jj), hmlpt(ji  ,jj+1), 5._wp) 
    203                ENDDO 
    204             ENDDO 
    205          END IF 
    206          DO jk = 2, jpkm1                            !* Slopes at u and v points 
    207             DO jj = 2, jpjm1 
    208                DO ji = fs_2, fs_jpim1   ! vector opt. 
    209                   !                                      ! horizontal and vertical density gradient at u- and v-points 
    210                   zau = zgru(ji,jj,jk) / e1u(ji,jj) 
    211                   zav = zgrv(ji,jj,jk) / e2v(ji,jj) 
    212                   zbu = 0.5_wp * ( zdzr(ji,jj,jk) + zdzr(ji+1,jj  ,jk) ) 
    213                   zbv = 0.5_wp * ( zdzr(ji,jj,jk) + zdzr(ji  ,jj+1,jk) ) 
    214                   !                                      ! bound the slopes: abs(zw.)<= 1/100 and zb..<0 
    215                   !                                      ! + kxz max= ah slope max =< e1 e3 /(pi**2 2 dt) 
    216                   zbu = MIN(  zbu, -100._wp* ABS( zau ) , -7.e+3_wp/fse3u(ji,jj,jk)* ABS( zau )  ) 
    217                   zbv = MIN(  zbv, -100._wp* ABS( zav ) , -7.e+3_wp/fse3v(ji,jj,jk)* ABS( zav )  ) 
    218                   !                                      ! uslp and vslp output in zwz and zww, resp. 
    219                   zfi = MAX( omlmask(ji,jj,jk), omlmask(ji+1,jj  ,jk) ) 
    220                   zfj = MAX( omlmask(ji,jj,jk), omlmask(ji  ,jj+1,jk) ) 
    221                   ! thickness of water column between surface and level k at u/v point 
    222                   zdepu = 0.5_wp * ( ( fsdept(ji,jj,jk) + fsdept(ji+1,jj  ,jk) )                              & 
    223                                    - 2 * MAX( risfdep(ji,jj), risfdep(ji+1,jj  ) ) - fse3u(ji,jj,miku(ji,jj)) ) 
    224                   zdepv = 0.5_wp * ( ( fsdept(ji,jj,jk) + fsdept(ji  ,jj+1,jk) )                              & 
    225                                    - 2 * MAX( risfdep(ji,jj), risfdep(ji  ,jj+1) ) - fse3v(ji,jj,mikv(ji,jj)) ) 
    226                   ! 
    227                   zwz(ji,jj,jk) = ( 1. - zfi) * zau / ( zbu - zeps )                                          & 
    228                      &                 + zfi  * uslpml(ji,jj) * zdepu / zhmlpu(ji,jj) 
    229                   zwz(ji,jj,jk) = zwz(ji,jj,jk) * wumask(ji,jj,jk) 
    230                   zww(ji,jj,jk) = ( 1. - zfj) * zav / ( zbv - zeps )                                          & 
    231                      &                 + zfj  * vslpml(ji,jj) * zdepv / zhmlpv(ji,jj)  
    232                   zww(ji,jj,jk) = zww(ji,jj,jk) * wvmask(ji,jj,jk) 
    233                    
    234                   
     128 
     129      zeps   =  1.e-20_wp        !==   Local constant initialization   ==! 
     130      z1_16  =  1.0_wp / 16._wp 
     131      zm1_g  = -1.0_wp / grav 
     132      zm1_2g = -0.5_wp / grav 
     133      z1_slpmax = 1._wp / rn_slpmax 
     134      ! 
     135      zww(:,:,:) = 0._wp 
     136      zwz(:,:,:) = 0._wp 
     137      ! 
     138      DO jk = 1, jpk             !==   i- & j-gradient of density   ==! 
     139         DO jj = 1, jpjm1 
     140            DO ji = 1, fs_jpim1   ! vector opt. 
     141               zgru(ji,jj,jk) = umask(ji,jj,jk) * ( prd(ji+1,jj  ,jk) - prd(ji,jj,jk) ) 
     142               zgrv(ji,jj,jk) = vmask(ji,jj,jk) * ( prd(ji  ,jj+1,jk) - prd(ji,jj,jk) ) 
     143            END DO 
     144         END DO 
     145      END DO 
     146      IF( ln_zps ) THEN                           ! partial steps correction at the bottom ocean level 
     147         DO jj = 1, jpjm1 
     148            DO ji = 1, jpim1 
     149               zgru(ji,jj,mbku(ji,jj)) = gru(ji,jj) 
     150               zgrv(ji,jj,mbkv(ji,jj)) = grv(ji,jj) 
     151            END DO 
     152         END DO 
     153      ENDIF 
     154      ! 
     155      zdzr(:,:,1) = 0._wp        !==   Local vertical density gradient at T-point   == !   (evaluated from N^2) 
     156      DO jk = 2, jpkm1 
     157         !                                ! zdzr = d/dz(prd)= - ( prd ) / grav * mk(pn2) -- at t point 
     158         !                                !   trick: tmask(ik  )  = 0   =>   all pn2   = 0   =>   zdzr = 0 
     159         !                                !    else  tmask(ik+1)  = 0   =>   pn2(ik+1) = 0   =>   zdzr divides by 1 
     160         !                                !          umask(ik+1) /= 0   =>   all pn2  /= 0   =>   zdzr divides by 2 
     161         !                                ! NB: 1/(tmask+1) = (1-.5*tmask)  substitute a / by a *  ==> faster 
     162         zdzr(:,:,jk) = zm1_g * ( prd(:,:,jk) + 1._wp )              & 
     163            &                 * ( pn2(:,:,jk) + pn2(:,:,jk+1) ) * ( 1._wp - 0.5_wp * tmask(:,:,jk+1) ) 
     164      END DO 
     165      ! 
     166      !                          !==   Slopes just below the mixed layer   ==! 
     167      CALL ldf_slp_mxl( prd, pn2, zgru, zgrv, zdzr )        ! output: uslpml, vslpml, wslpiml, wslpjml 
     168 
     169 
     170      ! I.  slopes at u and v point      | uslp = d/di( prd ) / d/dz( prd ) 
     171      ! ===========================      | vslp = d/dj( prd ) / d/dz( prd ) 
     172      ! 
     173      DO jk = 2, jpkm1                            !* Slopes at u and v points 
     174         DO jj = 2, jpjm1 
     175            DO ji = fs_2, fs_jpim1   ! vector opt. 
     176               !                                      ! horizontal and vertical density gradient at u- and v-points 
     177               zau = zgru(ji,jj,jk) * r1_e1u(ji,jj) 
     178               zav = zgrv(ji,jj,jk) * r1_e2v(ji,jj) 
     179               zbu = 0.5_wp * ( zdzr(ji,jj,jk) + zdzr(ji+1,jj  ,jk) ) 
     180               zbv = 0.5_wp * ( zdzr(ji,jj,jk) + zdzr(ji  ,jj+1,jk) ) 
     181               !                                      ! bound the slopes: abs(zw.)<= 1/100 and zb..<0 
     182               !                                      ! + kxz max= ah slope max =< e1 e3 /(pi**2 2 dt) 
     183               zbu = MIN(  zbu, - z1_slpmax * ABS( zau ) , -7.e+3_wp/fse3u(ji,jj,jk)* ABS( zau )  ) 
     184               zbv = MIN(  zbv, - z1_slpmax * ABS( zav ) , -7.e+3_wp/fse3v(ji,jj,jk)* ABS( zav )  ) 
     185               !                                      ! uslp and vslp output in zwz and zww, resp. 
     186               zfi = MAX( omlmask(ji,jj,jk), omlmask(ji+1,jj,jk) ) 
     187               zfj = MAX( omlmask(ji,jj,jk), omlmask(ji,jj+1,jk) ) 
     188               zwz(ji,jj,jk) = ( ( 1. - zfi) * zau / ( zbu - zeps )                                              & 
     189                  &                   + zfi  * uslpml(ji,jj)                                                     & 
     190                  &                          * 0.5_wp * ( fsdept(ji+1,jj,jk)+fsdept(ji,jj,jk)-fse3u(ji,jj,1) )   & 
     191                  &                          / MAX( hmlpt(ji,jj), hmlpt(ji+1,jj), 5._wp ) ) * umask(ji,jj,jk) 
     192               zww(ji,jj,jk) = ( ( 1. - zfj) * zav / ( zbv - zeps )                                              & 
     193                  &                   + zfj  * vslpml(ji,jj)                                                     & 
     194                  &                          * 0.5_wp * ( fsdept(ji,jj+1,jk)+fsdept(ji,jj,jk)-fse3v(ji,jj,1) )   & 
     195                  &                          / MAX( hmlpt(ji,jj), hmlpt(ji,jj+1), 5. ) ) * vmask(ji,jj,jk) 
    235196!!gm  modif to suppress omlmask.... (as in Griffies case) 
    236 !                  !                                         ! jk must be >= ML level for zf=1. otherwise  zf=0. 
    237 !                  zfi = REAL( 1 - 1/(1 + jk / MAX( nmln(ji+1,jj), nmln(ji,jj) ) ), wp ) 
    238 !                  zfj = REAL( 1 - 1/(1 + jk / MAX( nmln(ji,jj+1), nmln(ji,jj) ) ), wp ) 
    239 !                  zci = 0.5 * ( fsdept(ji+1,jj,jk)+fsdept(ji,jj,jk) ) / MAX( hmlpt(ji,jj), hmlpt(ji+1,jj), 10. ) ) 
    240 !                  zcj = 0.5 * ( fsdept(ji,jj+1,jk)+fsdept(ji,jj,jk) ) / MAX( hmlpt(ji,jj), hmlpt(ji,jj+1), 10. ) ) 
    241 !                  zwz(ji,jj,jk) = ( zfi * zai / ( zbi - zeps ) + ( 1._wp - zfi ) * wslpiml(ji,jj) * zci ) * tmask(ji,jj,jk) 
    242 !                  zww(ji,jj,jk) = ( zfj * zaj / ( zbj - zeps ) + ( 1._wp - zfj ) * wslpjml(ji,jj) * zcj ) * tmask(ji,jj,jk) 
     197!               !                                         ! jk must be >= ML level for zf=1. otherwise  zf=0. 
     198!               zfi = REAL( 1 - 1/(1 + jk / MAX( nmln(ji+1,jj), nmln(ji,jj) ) ), wp ) 
     199!               zfj = REAL( 1 - 1/(1 + jk / MAX( nmln(ji,jj+1), nmln(ji,jj) ) ), wp ) 
     200!               zci = 0.5 * ( fsdept(ji+1,jj,jk)+fsdept(ji,jj,jk) ) / MAX( hmlpt(ji,jj), hmlpt(ji+1,jj), 10. ) ) 
     201!               zcj = 0.5 * ( fsdept(ji,jj+1,jk)+fsdept(ji,jj,jk) ) / MAX( hmlpt(ji,jj), hmlpt(ji,jj+1), 10. ) ) 
     202!               zwz(ji,jj,jk) = ( zfi * zai / ( zbi - zeps ) + ( 1._wp - zfi ) * wslpiml(ji,jj) * zci ) * tmask(ji,jj,jk) 
     203!               zww(ji,jj,jk) = ( zfj * zaj / ( zbj - zeps ) + ( 1._wp - zfj ) * wslpjml(ji,jj) * zcj ) * tmask(ji,jj,jk) 
    243204!!gm end modif 
    244                END DO 
    245             END DO 
    246          END DO 
    247          CALL lbc_lnk( zwz, 'U', -1. )   ;   CALL lbc_lnk( zww, 'V', -1. )      ! lateral boundary conditions 
    248          ! 
    249          !                                            !* horizontal Shapiro filter 
    250          DO jk = 2, jpkm1 
    251             DO jj = 2, jpjm1, MAX(1, jpj-3)                        ! rows jj=2 and =jpjm1 only 
    252                DO ji = 2, jpim1 
    253                   uslp(ji,jj,jk) = z1_16 * (        zwz(ji-1,jj-1,jk) + zwz(ji+1,jj-1,jk)      & 
    254                      &                       +      zwz(ji-1,jj+1,jk) + zwz(ji+1,jj+1,jk)      & 
    255                      &                       + 2.*( zwz(ji  ,jj-1,jk) + zwz(ji-1,jj  ,jk)      & 
    256                      &                       +      zwz(ji+1,jj  ,jk) + zwz(ji  ,jj+1,jk) )    & 
    257                      &                       + 4.*  zwz(ji  ,jj  ,jk)                       ) 
    258                   vslp(ji,jj,jk) = z1_16 * (        zww(ji-1,jj-1,jk) + zww(ji+1,jj-1,jk)      & 
    259                      &                       +      zww(ji-1,jj+1,jk) + zww(ji+1,jj+1,jk)      & 
    260                      &                       + 2.*( zww(ji  ,jj-1,jk) + zww(ji-1,jj  ,jk)      & 
    261                      &                       +      zww(ji+1,jj  ,jk) + zww(ji  ,jj+1,jk) )    & 
    262                      &                       + 4.*  zww(ji,jj    ,jk)                       ) 
    263                END DO 
    264             END DO 
    265             DO jj = 3, jpj-2                               ! other rows 
    266                DO ji = fs_2, fs_jpim1   ! vector opt. 
    267                   uslp(ji,jj,jk) = z1_16 * (        zwz(ji-1,jj-1,jk) + zwz(ji+1,jj-1,jk)      & 
    268                      &                       +      zwz(ji-1,jj+1,jk) + zwz(ji+1,jj+1,jk)      & 
    269                      &                       + 2.*( zwz(ji  ,jj-1,jk) + zwz(ji-1,jj  ,jk)      & 
    270                      &                       +      zwz(ji+1,jj  ,jk) + zwz(ji  ,jj+1,jk) )    & 
    271                      &                       + 4.*  zwz(ji  ,jj  ,jk)                       ) 
    272                   vslp(ji,jj,jk) = z1_16 * (        zww(ji-1,jj-1,jk) + zww(ji+1,jj-1,jk)      & 
    273                      &                       +      zww(ji-1,jj+1,jk) + zww(ji+1,jj+1,jk)      & 
    274                      &                       + 2.*( zww(ji  ,jj-1,jk) + zww(ji-1,jj  ,jk)         & 
    275                      &                       +      zww(ji+1,jj  ,jk) + zww(ji  ,jj+1,jk) )    & 
    276                      &                       + 4.*  zww(ji,jj    ,jk)                       ) 
    277                END DO 
    278             END DO 
    279             !                                        !* decrease along coastal boundaries 
    280             DO jj = 2, jpjm1 
    281                DO ji = fs_2, fs_jpim1   ! vector opt. 
    282                   uslp(ji,jj,jk) = uslp(ji,jj,jk) * ( umask(ji,jj+1,jk) + umask(ji,jj-1,jk  ) ) * 0.5_wp   & 
    283                      &                            * ( umask(ji,jj  ,jk) + umask(ji,jj  ,jk+1) ) * 0.5_wp   & 
    284                      &                            *   umask(ji,jj,jk-1) 
    285                   vslp(ji,jj,jk) = vslp(ji,jj,jk) * ( vmask(ji+1,jj,jk) + vmask(ji-1,jj,jk  ) ) * 0.5_wp   & 
    286                      &                            * ( vmask(ji  ,jj,jk) + vmask(ji  ,jj,jk+1) ) * 0.5_wp   & 
    287                      &                            *   vmask(ji,jj,jk-1) 
    288                END DO 
    289             END DO 
    290          END DO 
    291  
    292  
    293          ! II.  slopes at w point           | wslpi = mij( d/di( prd ) / d/dz( prd ) 
    294          ! ===========================      | wslpj = mij( d/dj( prd ) / d/dz( prd ) 
    295          ! 
    296          DO jk = 2, jpkm1 
    297             DO jj = 2, jpjm1 
    298                DO ji = fs_2, fs_jpim1   ! vector opt. 
    299                   !                                  !* Local vertical density gradient evaluated from N^2 
    300                   zbw = zm1_2g * pn2 (ji,jj,jk) * ( prd (ji,jj,jk) + prd (ji,jj,jk-1) + 2. ) * wmask(ji,jj,jk) 
    301                   !                                  !* Slopes at w point 
    302                   !                                        ! i- & j-gradient of density at w-points 
    303                   zci = MAX(  umask(ji-1,jj,jk  ) + umask(ji,jj,jk  )           & 
    304                      &      + umask(ji-1,jj,jk-1) + umask(ji,jj,jk-1) , zeps  ) * e1t(ji,jj) 
    305                   zcj = MAX(  vmask(ji,jj-1,jk  ) + vmask(ji,jj,jk-1)           & 
    306                      &      + vmask(ji,jj-1,jk-1) + vmask(ji,jj,jk  ) , zeps  ) *  e2t(ji,jj) 
    307                   zai =    (  zgru (ji-1,jj,jk  ) + zgru (ji,jj,jk-1)           & 
    308                      &      + zgru (ji-1,jj,jk-1) + zgru (ji,jj,jk  )   ) / zci 
    309                   zaj =    (  zgrv (ji,jj-1,jk  ) + zgrv (ji,jj,jk-1)           & 
    310                      &      + zgrv (ji,jj-1,jk-1) + zgrv (ji,jj,jk  )   ) / zcj 
    311                   !                                        ! bound the slopes: abs(zw.)<= 1/100 and zb..<0. 
    312                   !                                        ! + kxz max= ah slope max =< e1 e3 /(pi**2 2 dt) 
    313                   zbi = MIN( zbw ,- 100._wp* ABS( zai ) , -7.e+3_wp/fse3w(ji,jj,jk)* ABS( zai )  ) 
    314                   zbj = MIN( zbw , -100._wp* ABS( zaj ) , -7.e+3_wp/fse3w(ji,jj,jk)* ABS( zaj )  ) 
    315                   !                                        ! wslpi and wslpj with ML flattening (output in zwz and zww, resp.) 
    316                   zfk = MAX( omlmask(ji,jj,jk), omlmask(ji,jj,jk-1) )   ! zfk=1 in the ML otherwise zfk=0 
    317                   zck = ( fsdepw(ji,jj,jk) - fsdepw(ji,jj,mikt(ji,jj) ) ) / MAX( hmlp(ji,jj), 10._wp ) 
    318                   zwz(ji,jj,jk) = (  zai / ( zbi - zeps ) * ( 1._wp - zfk ) & 
    319                      &            + zck * wslpiml(ji,jj) * zfk  ) * wmask(ji,jj,jk) 
    320                   zww(ji,jj,jk) = (  zaj / ( zbj - zeps ) * ( 1._wp - zfk ) & 
    321                      &            + zck * wslpjml(ji,jj) * zfk  ) * wmask(ji,jj,jk) 
     205            END DO 
     206         END DO 
     207      END DO 
     208      CALL lbc_lnk( zwz, 'U', -1. )   ;   CALL lbc_lnk( zww, 'V', -1. )      ! lateral boundary conditions 
     209      ! 
     210      !                                            !* horizontal Shapiro filter 
     211      DO jk = 2, jpkm1 
     212         DO jj = 2, jpjm1, MAX(1, jpj-3)                        ! rows jj=2 and =jpjm1 only 
     213            DO ji = 2, jpim1 
     214               uslp(ji,jj,jk) = z1_16 * (        zwz(ji-1,jj-1,jk) + zwz(ji+1,jj-1,jk)      & 
     215                  &                       +      zwz(ji-1,jj+1,jk) + zwz(ji+1,jj+1,jk)      & 
     216                  &                       + 2.*( zwz(ji  ,jj-1,jk) + zwz(ji-1,jj  ,jk)      & 
     217                  &                       +      zwz(ji+1,jj  ,jk) + zwz(ji  ,jj+1,jk) )    & 
     218                  &                       + 4.*  zwz(ji  ,jj  ,jk)                       ) 
     219               vslp(ji,jj,jk) = z1_16 * (        zww(ji-1,jj-1,jk) + zww(ji+1,jj-1,jk)      & 
     220                  &                       +      zww(ji-1,jj+1,jk) + zww(ji+1,jj+1,jk)      & 
     221                  &                       + 2.*( zww(ji  ,jj-1,jk) + zww(ji-1,jj  ,jk)      & 
     222                  &                       +      zww(ji+1,jj  ,jk) + zww(ji  ,jj+1,jk) )    & 
     223                  &                       + 4.*  zww(ji,jj    ,jk)                       ) 
     224            END DO 
     225         END DO 
     226         DO jj = 3, jpj-2                               ! other rows 
     227            DO ji = fs_2, fs_jpim1   ! vector opt. 
     228               uslp(ji,jj,jk) = z1_16 * (        zwz(ji-1,jj-1,jk) + zwz(ji+1,jj-1,jk)      & 
     229                  &                       +      zwz(ji-1,jj+1,jk) + zwz(ji+1,jj+1,jk)      & 
     230                  &                       + 2.*( zwz(ji  ,jj-1,jk) + zwz(ji-1,jj  ,jk)      & 
     231                  &                       +      zwz(ji+1,jj  ,jk) + zwz(ji  ,jj+1,jk) )    & 
     232                  &                       + 4.*  zwz(ji  ,jj  ,jk)                       ) 
     233               vslp(ji,jj,jk) = z1_16 * (        zww(ji-1,jj-1,jk) + zww(ji+1,jj-1,jk)      & 
     234                  &                       +      zww(ji-1,jj+1,jk) + zww(ji+1,jj+1,jk)      & 
     235                  &                       + 2.*( zww(ji  ,jj-1,jk) + zww(ji-1,jj  ,jk)      & 
     236                  &                       +      zww(ji+1,jj  ,jk) + zww(ji  ,jj+1,jk) )    & 
     237                  &                       + 4.*  zww(ji,jj    ,jk)                       ) 
     238            END DO 
     239         END DO 
     240         !                                        !* decrease along coastal boundaries 
     241         DO jj = 2, jpjm1 
     242            DO ji = fs_2, fs_jpim1   ! vector opt. 
     243               uslp(ji,jj,jk) = uslp(ji,jj,jk) * ( umask(ji,jj+1,jk) + umask(ji,jj-1,jk  ) ) * 0.5_wp   & 
     244                  &                            * ( umask(ji,jj  ,jk) + umask(ji,jj  ,jk+1) ) * 0.5_wp 
     245               vslp(ji,jj,jk) = vslp(ji,jj,jk) * ( vmask(ji+1,jj,jk) + vmask(ji-1,jj,jk  ) ) * 0.5_wp   & 
     246                  &                            * ( vmask(ji  ,jj,jk) + vmask(ji  ,jj,jk+1) ) * 0.5_wp 
     247            END DO 
     248         END DO 
     249      END DO 
     250 
     251 
     252      ! II.  slopes at w point           | wslpi = mij( d/di( prd ) / d/dz( prd ) 
     253      ! ===========================      | wslpj = mij( d/dj( prd ) / d/dz( prd ) 
     254      ! 
     255      DO jk = 2, jpkm1 
     256         DO jj = 2, jpjm1 
     257            DO ji = fs_2, fs_jpim1   ! vector opt. 
     258               !                                  !* Local vertical density gradient evaluated from N^2 
     259               zbw = zm1_2g * pn2 (ji,jj,jk) * ( prd (ji,jj,jk) + prd (ji,jj,jk-1) + 2. ) 
     260               !                                  !* Slopes at w point 
     261               !                                        ! i- & j-gradient of density at w-points 
     262               zci = MAX(  umask(ji-1,jj,jk  ) + umask(ji,jj,jk  )           & 
     263                  &      + umask(ji-1,jj,jk-1) + umask(ji,jj,jk-1) , zeps  ) * e1t(ji,jj) 
     264               zcj = MAX(  vmask(ji,jj-1,jk  ) + vmask(ji,jj,jk-1)           & 
     265                  &      + vmask(ji,jj-1,jk-1) + vmask(ji,jj,jk  ) , zeps  ) * e2t(ji,jj) 
     266               zai =    (  zgru (ji-1,jj,jk  ) + zgru (ji,jj,jk-1)           & 
     267                  &      + zgru (ji-1,jj,jk-1) + zgru (ji,jj,jk  )   ) / zci * tmask (ji,jj,jk) 
     268               zaj =    (  zgrv (ji,jj-1,jk  ) + zgrv (ji,jj,jk-1)           & 
     269                  &      + zgrv (ji,jj-1,jk-1) + zgrv (ji,jj,jk  )   ) / zcj * tmask (ji,jj,jk) 
     270               !                                        ! bound the slopes: abs(zw.)<= 1/100 and zb..<0. 
     271               !                                        ! + kxz max= ah slope max =< e1 e3 /(pi**2 2 dt) 
     272               zbi = MIN( zbw ,- 100._wp* ABS( zai ) , -7.e+3_wp/fse3w(ji,jj,jk)* ABS( zai )  ) 
     273               zbj = MIN( zbw , -100._wp* ABS( zaj ) , -7.e+3_wp/fse3w(ji,jj,jk)* ABS( zaj )  ) 
     274               !                                        ! wslpi and wslpj with ML flattening (output in zwz and zww, resp.) 
     275               zfk = MAX( omlmask(ji,jj,jk), omlmask(ji,jj,jk-1) )   ! zfk=1 in the ML otherwise zfk=0 
     276               zck = fsdepw(ji,jj,jk) / MAX( hmlp(ji,jj), 10._wp ) 
     277               zwz(ji,jj,jk) = (  zai / ( zbi - zeps ) * ( 1._wp - zfk ) + zck * wslpiml(ji,jj) * zfk  ) * tmask(ji,jj,jk) 
     278               zww(ji,jj,jk) = (  zaj / ( zbj - zeps ) * ( 1._wp - zfk ) + zck * wslpjml(ji,jj) * zfk  ) * tmask(ji,jj,jk) 
    322279 
    323280!!gm  modif to suppress omlmask....  (as in Griffies operator) 
    324 !                  !                                         ! jk must be >= ML level for zfk=1. otherwise  zfk=0. 
    325 !                  zfk = REAL( 1 - 1/(1 + jk / nmln(ji+1,jj)), wp ) 
    326 !                  zck = fsdepw(ji,jj,jk)    / MAX( hmlp(ji,jj), 10. ) 
    327 !                  zwz(ji,jj,jk) = ( zfk * zai / ( zbi - zeps ) + ( 1._wp - zfk ) * wslpiml(ji,jj) * zck ) * tmask(ji,jj,jk) 
    328 !                  zww(ji,jj,jk) = ( zfk * zaj / ( zbj - zeps ) + ( 1._wp - zfk ) * wslpjml(ji,jj) * zck ) * tmask(ji,jj,jk) 
     281!               !                                         ! jk must be >= ML level for zfk=1. otherwise  zfk=0. 
     282!               zfk = REAL( 1 - 1/(1 + jk / nmln(ji+1,jj)), wp ) 
     283!               zck = fsdepw(ji,jj,jk)    / MAX( hmlp(ji,jj), 10. ) 
     284!               zwz(ji,jj,jk) = ( zfk * zai / ( zbi - zeps ) + ( 1._wp - zfk ) * wslpiml(ji,jj) * zck ) * tmask(ji,jj,jk) 
     285!               zww(ji,jj,jk) = ( zfk * zaj / ( zbj - zeps ) + ( 1._wp - zfk ) * wslpjml(ji,jj) * zck ) * tmask(ji,jj,jk) 
    329286!!gm end modif 
    330                END DO 
    331             END DO 
    332          END DO 
    333          CALL lbc_lnk( zwz, 'T', -1. )   ;    CALL lbc_lnk( zww, 'T', -1. )      ! lateral boundary conditions 
    334          ! 
    335          !                                           !* horizontal Shapiro filter 
    336          DO jk = 2, jpkm1 
    337             DO jj = 2, jpjm1, MAX(1, jpj-3)                        ! rows jj=2 and =jpjm1 only 
    338                DO ji = 2, jpim1 
    339                   zcofw = tmask(ji,jj,jk) * z1_16 
    340                   wslpi(ji,jj,jk) = (          zwz(ji-1,jj-1,jk) + zwz(ji+1,jj-1,jk)     & 
    341                        &                +      zwz(ji-1,jj+1,jk) + zwz(ji+1,jj+1,jk)     & 
    342                        &                + 2.*( zwz(ji  ,jj-1,jk) + zwz(ji-1,jj  ,jk)     & 
    343                        &                +      zwz(ji+1,jj  ,jk) + zwz(ji  ,jj+1,jk) )   & 
    344                        &                + 4.*  zwz(ji  ,jj  ,jk)                         ) * zcofw 
    345  
    346                   wslpj(ji,jj,jk) = (          zww(ji-1,jj-1,jk) + zww(ji+1,jj-1,jk)     & 
    347                        &                +      zww(ji-1,jj+1,jk) + zww(ji+1,jj+1,jk)     & 
    348                        &                + 2.*( zww(ji  ,jj-1,jk) + zww(ji-1,jj  ,jk)     & 
    349                        &                +      zww(ji+1,jj  ,jk) + zww(ji  ,jj+1,jk) )   & 
    350                        &                + 4.*  zww(ji  ,jj  ,jk)                         ) * zcofw 
    351                END DO 
    352             END DO 
    353             DO jj = 3, jpj-2                               ! other rows 
    354                DO ji = fs_2, fs_jpim1   ! vector opt. 
    355                   zcofw = tmask(ji,jj,jk) * z1_16 
    356                   wslpi(ji,jj,jk) = (        zwz(ji-1,jj-1,jk) + zwz(ji+1,jj-1,jk)     & 
    357                        &                +      zwz(ji-1,jj+1,jk) + zwz(ji+1,jj+1,jk)     & 
    358                        &                + 2.*( zwz(ji  ,jj-1,jk) + zwz(ji-1,jj  ,jk)     & 
    359                        &                +      zwz(ji+1,jj  ,jk) + zwz(ji  ,jj+1,jk) )   & 
    360                        &                + 4.*  zwz(ji  ,jj  ,jk)                         ) * zcofw 
    361  
    362                   wslpj(ji,jj,jk) = (        zww(ji-1,jj-1,jk) + zww(ji+1,jj-1,jk)     & 
    363                        &                +      zww(ji-1,jj+1,jk) + zww(ji+1,jj+1,jk)     & 
    364                        &                + 2.*( zww(ji  ,jj-1,jk) + zww(ji-1,jj  ,jk)     & 
    365                        &                +      zww(ji+1,jj  ,jk) + zww(ji  ,jj+1,jk) )   & 
    366                        &                + 4.*  zww(ji  ,jj  ,jk)                         ) * zcofw 
    367                END DO 
    368             END DO 
    369             !                                        !* decrease along coastal boundaries 
    370             DO jj = 2, jpjm1 
    371                DO ji = fs_2, fs_jpim1   ! vector opt. 
    372                   zck =   ( umask(ji,jj,jk) + umask(ji-1,jj,jk) )   & 
    373                      &  * ( vmask(ji,jj,jk) + vmask(ji,jj-1,jk) ) * 0.25 
    374                   wslpi(ji,jj,jk) = wslpi(ji,jj,jk) * zck * wmask(ji,jj,jk) 
    375                   wslpj(ji,jj,jk) = wslpj(ji,jj,jk) * zck * wmask(ji,jj,jk) 
    376                END DO 
    377             END DO 
    378          END DO 
    379  
    380          ! III.  Specific grid points 
    381          ! =========================== 
    382          ! 
    383          IF( cp_cfg == "orca" .AND. jp_cfg == 4 ) THEN     !  ORCA_R4 configuration: horizontal diffusion in specific area 
    384             !                                                    ! Gibraltar Strait 
    385             ij0 =  50   ;   ij1 =  53 
    386             ii0 =  69   ;   ii1 =  71   ;   uslp ( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) , : ) = 0._wp 
    387             ij0 =  51   ;   ij1 =  53 
    388             ii0 =  68   ;   ii1 =  71   ;   vslp ( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) , : ) = 0._wp 
    389             ii0 =  69   ;   ii1 =  71   ;   wslpi( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) , : ) = 0._wp 
    390             ii0 =  69   ;   ii1 =  71   ;   wslpj( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) , : ) = 0._wp 
    391             ! 
    392             !                                                    ! Mediterrannean Sea 
    393             ij0 =  49   ;   ij1 =  56 
    394             ii0 =  71   ;   ii1 =  90   ;   uslp ( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) , : ) = 0._wp 
    395             ij0 =  50   ;   ij1 =  56 
    396             ii0 =  70   ;   ii1 =  90   ;   vslp ( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) , : ) = 0._wp 
    397             ii0 =  71   ;   ii1 =  90   ;   wslpi( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) , : ) = 0._wp 
    398             ii0 =  71   ;   ii1 =  90   ;   wslpj( mi0(ii0):mi1(ii1) , mj0(ij0):mj1(ij1) , : ) = 0._wp 
    399          ENDIF 
    400  
    401  
    402          ! IV. Lateral boundary conditions 
    403          ! =============================== 
    404          CALL lbc_lnk( uslp , 'U', -1. )      ;      CALL lbc_lnk( vslp , 'V', -1. ) 
    405          CALL lbc_lnk( wslpi, 'W', -1. )      ;      CALL lbc_lnk( wslpj, 'W', -1. ) 
    406  
    407  
    408          IF(ln_ctl) THEN 
    409             CALL prt_ctl(tab3d_1=uslp , clinfo1=' slp  - u : ', tab3d_2=vslp,  clinfo2=' v : ', kdim=jpk) 
    410             CALL prt_ctl(tab3d_1=wslpi, clinfo1=' slp  - wi: ', tab3d_2=wslpj, clinfo2=' wj: ', kdim=jpk) 
    411          ENDIF 
    412          ! 
    413  
    414       ELSEIF ( lk_vvl ) THEN  
    415   
    416          IF(lwp) THEN  
    417             WRITE(numout,*) '          Horizontal mixing in s-coordinate: slope = slope of s-surfaces'  
    418          ENDIF  
    419  
    420          ! geopotential diffusion in s-coordinates on tracers and/or momentum  
    421          ! The slopes of s-surfaces are computed at each time step due to vvl  
    422          ! The slopes for momentum diffusion are i- or j- averaged of those on tracers  
    423  
    424          ! set the slope of diffusion to the slope of s-surfaces  
    425          !      ( c a u t i o n : minus sign as fsdep has positive value )  
    426          DO jj = 2, jpjm1  
    427             DO ji = fs_2, fs_jpim1   ! vector opt.  
    428                uslp(ji,jj,1) = -1./e1u(ji,jj) * ( fsdept_b(ji+1,jj,1) - fsdept_b(ji ,jj ,1) )  * umask(ji,jj,1)  
    429                vslp(ji,jj,1) = -1./e2v(ji,jj) * ( fsdept_b(ji,jj+1,1) - fsdept_b(ji ,jj ,1) )  * vmask(ji,jj,1)  
    430                wslpi(ji,jj,1) = -1./e1t(ji,jj) * ( fsdepw_b(ji+1,jj,1) - fsdepw_b(ji-1,jj,1) ) * tmask(ji,jj,1) * 0.5  
    431                wslpj(ji,jj,1) = -1./e2t(ji,jj) * ( fsdepw_b(ji,jj+1,1) - fsdepw_b(ji,jj-1,1) ) * tmask(ji,jj,1) * 0.5  
    432             END DO  
    433          END DO  
    434  
    435          DO jk = 2, jpk  
    436             DO jj = 2, jpjm1  
    437                DO ji = fs_2, fs_jpim1   ! vector opt.  
    438                   uslp(ji,jj,jk) = -1./e1u(ji,jj) * ( fsdept_b(ji+1,jj,jk) - fsdept_b(ji ,jj ,jk) ) * umask(ji,jj,jk)  
    439                   vslp(ji,jj,jk) = -1./e2v(ji,jj) * ( fsdept_b(ji,jj+1,jk) - fsdept_b(ji ,jj ,jk) ) * vmask(ji,jj,jk)  
    440                   wslpi(ji,jj,jk) = -1./e1t(ji,jj) * ( fsdepw_b(ji+1,jj,jk) - fsdepw_b(ji-1,jj,jk) ) & 
    441                     &                              * wmask(ji,jj,jk) * 0.5  
    442                   wslpj(ji,jj,jk) = -1./e2t(ji,jj) * ( fsdepw_b(ji,jj+1,jk) - fsdepw_b(ji,jj-1,jk) ) & 
    443                     &                              * wmask(ji,jj,jk) * 0.5  
    444                END DO  
    445             END DO  
    446          END DO  
    447  
    448          ! Lateral boundary conditions on the slopes  
    449          CALL lbc_lnk( uslp , 'U', -1. )      ;      CALL lbc_lnk( vslp , 'V', -1. )  
    450          CALL lbc_lnk( wslpi, 'W', -1. )      ;      CALL lbc_lnk( wslpj, 'W', -1. )  
    451    
    452          if( kt == nit000 ) then  
    453             IF(lwp) WRITE(numout,*) ' max slop: u',SQRT( MAXVAL(uslp*uslp)), ' v ', SQRT(MAXVAL(vslp)),  &  
    454                &                             ' wi', sqrt(MAXVAL(wslpi)), ' wj', sqrt(MAXVAL(wslpj))  
    455          endif  
    456    
    457          IF(ln_ctl) THEN  
    458             CALL prt_ctl(tab3d_1=uslp , clinfo1=' slp  - u : ', tab3d_2=vslp,  clinfo2=' v : ', kdim=jpk)  
    459             CALL prt_ctl(tab3d_1=wslpi, clinfo1=' slp  - wi: ', tab3d_2=wslpj, clinfo2=' wj: ', kdim=jpk)  
    460          ENDIF  
    461  
     287            END DO 
     288         END DO 
     289      END DO 
     290      CALL lbc_lnk( zwz, 'T', -1. )   ;    CALL lbc_lnk( zww, 'T', -1. )      ! lateral boundary conditions 
     291      ! 
     292      !                                           !* horizontal Shapiro filter 
     293      DO jk = 2, jpkm1 
     294         DO jj = 2, jpjm1, MAX(1, jpj-3)                        ! rows jj=2 and =jpjm1 only 
     295            DO ji = 2, jpim1 
     296               zcofw = wmask(ji,jj,jk) * z1_16 
     297               wslpi(ji,jj,jk) = (         zwz(ji-1,jj-1,jk) + zwz(ji+1,jj-1,jk)     & 
     298                    &               +      zwz(ji-1,jj+1,jk) + zwz(ji+1,jj+1,jk)     & 
     299                    &               + 2.*( zwz(ji  ,jj-1,jk) + zwz(ji-1,jj  ,jk)     & 
     300                    &               +      zwz(ji+1,jj  ,jk) + zwz(ji  ,jj+1,jk) )   & 
     301                    &               + 4.*  zwz(ji  ,jj  ,jk)                         ) * zcofw 
     302 
     303               wslpj(ji,jj,jk) = (         zww(ji-1,jj-1,jk) + zww(ji+1,jj-1,jk)     & 
     304                    &               +      zww(ji-1,jj+1,jk) + zww(ji+1,jj+1,jk)     & 
     305                    &               + 2.*( zww(ji  ,jj-1,jk) + zww(ji-1,jj  ,jk)     & 
     306                    &               +      zww(ji+1,jj  ,jk) + zww(ji  ,jj+1,jk) )   & 
     307                    &               + 4.*  zww(ji  ,jj  ,jk)                         ) * zcofw 
     308            END DO 
     309         END DO 
     310         DO jj = 3, jpj-2                               ! other rows 
     311            DO ji = fs_2, fs_jpim1   ! vector opt. 
     312               zcofw = wmask(ji,jj,jk) * z1_16 
     313               wslpi(ji,jj,jk) = (         zwz(ji-1,jj-1,jk) + zwz(ji+1,jj-1,jk)     & 
     314                    &               +      zwz(ji-1,jj+1,jk) + zwz(ji+1,jj+1,jk)     & 
     315                    &               + 2.*( zwz(ji  ,jj-1,jk) + zwz(ji-1,jj  ,jk)     & 
     316                    &               +      zwz(ji+1,jj  ,jk) + zwz(ji  ,jj+1,jk) )   & 
     317                    &               + 4.*  zwz(ji  ,jj  ,jk)                         ) * zcofw 
     318 
     319               wslpj(ji,jj,jk) = (         zww(ji-1,jj-1,jk) + zww(ji+1,jj-1,jk)     & 
     320                    &               +      zww(ji-1,jj+1,jk) + zww(ji+1,jj+1,jk)     & 
     321                    &               + 2.*( zww(ji  ,jj-1,jk) + zww(ji-1,jj  ,jk)     & 
     322                    &               +      zww(ji+1,jj  ,jk) + zww(ji  ,jj+1,jk) )   & 
     323                    &               + 4.*  zww(ji  ,jj  ,jk)                         ) * zcofw 
     324            END DO 
     325         END DO 
     326         !                                        !* decrease in vicinity of topography 
     327         DO jj = 2, jpjm1 
     328            DO ji = fs_2, fs_jpim1   ! vector opt. 
     329               zck =   ( umask(ji,jj,jk) + umask(ji-1,jj,jk) )   & 
     330                  &  * ( vmask(ji,jj,jk) + vmask(ji,jj-1,jk) ) * 0.25 
     331               wslpi(ji,jj,jk) = wslpi(ji,jj,jk) * zck 
     332               wslpj(ji,jj,jk) = wslpj(ji,jj,jk) * zck 
     333            END DO 
     334         END DO 
     335      END DO 
     336 
     337      ! IV. Lateral boundary conditions 
     338      ! =============================== 
     339      CALL lbc_lnk( uslp , 'U', -1. )      ;      CALL lbc_lnk( vslp , 'V', -1. ) 
     340      CALL lbc_lnk( wslpi, 'W', -1. )      ;      CALL lbc_lnk( wslpj, 'W', -1. ) 
     341 
     342 
     343      IF(ln_ctl) THEN 
     344         CALL prt_ctl(tab3d_1=uslp , clinfo1=' slp  - u : ', tab3d_2=vslp,  clinfo2=' v : ', kdim=jpk) 
     345         CALL prt_ctl(tab3d_1=wslpi, clinfo1=' slp  - wi: ', tab3d_2=wslpj, clinfo2=' wj: ', kdim=jpk) 
    462346      ENDIF 
    463        
     347      ! 
    464348      CALL wrk_dealloc( jpi,jpj,jpk, zwz, zww, zdzr, zgru, zgrv ) 
    465       CALL wrk_dealloc( jpi,jpj,     zhmlpu, zhmlpv) 
    466349      ! 
    467350      IF( nn_timing == 1 )  CALL timing_stop('ldf_slp') 
     
    470353 
    471354 
    472    SUBROUTINE ldf_slp_grif ( kt ) 
    473       !!---------------------------------------------------------------------- 
    474       !!                 ***  ROUTINE ldf_slp_grif  *** 
     355   SUBROUTINE ldf_slp_triad ( kt ) 
     356      !!---------------------------------------------------------------------- 
     357      !!                 ***  ROUTINE ldf_slp_triad  *** 
    475358      !! 
    476359      !! ** Purpose :   Compute the squared slopes of neutral surfaces (slope 
    477       !!      of iso-pycnal surfaces referenced locally) (ln_traldf_grif=T) 
     360      !!      of iso-pycnal surfaces referenced locally) (ln_traldf_triad=T) 
    478361      !!      at W-points using the Griffies quarter-cells. 
    479362      !! 
     
    490373      REAL(wp) ::   zfacti, zfactj              ! local scalars 
    491374      REAL(wp) ::   znot_thru_surface           ! local scalars 
    492       REAL(wp) ::   zdit, zdis, zdjt, zdjs, zdkt, zdks, zbu, zbv, zbti, zbtj 
     375      REAL(wp) ::   zdit, zdis, zdkt, zbu, zbti, zisw 
     376      REAL(wp) ::   zdjt, zdjs, zdks, zbv, zbtj, zjsw 
    493377      REAL(wp) ::   zdxrho_raw, zti_coord, zti_raw, zti_lim, zti_g_raw, zti_g_lim 
    494378      REAL(wp) ::   zdyrho_raw, ztj_coord, ztj_raw, ztj_lim, ztj_g_raw, ztj_g_lim 
    495379      REAL(wp) ::   zdzrho_raw 
     380      REAL(wp) ::   zbeta0, ze3_e1, ze3_e2 
    496381      REAL(wp), POINTER, DIMENSION(:,:)     ::   z1_mlbw 
     382      REAL(wp), POINTER, DIMENSION(:,:,:)   ::   zalbet 
    497383      REAL(wp), POINTER, DIMENSION(:,:,:,:) ::   zdxrho , zdyrho, zdzrho     ! Horizontal and vertical density gradients 
    498384      REAL(wp), POINTER, DIMENSION(:,:,:,:) ::   zti_mlb, ztj_mlb            ! for Griffies operator only 
    499385      !!---------------------------------------------------------------------- 
    500386      ! 
    501       IF( nn_timing == 1 )  CALL timing_start('ldf_slp_grif') 
     387      IF( nn_timing == 1 )  CALL timing_start('ldf_slp_triad') 
    502388      ! 
    503389      CALL wrk_alloc( jpi,jpj, z1_mlbw ) 
     390      CALL wrk_alloc( jpi,jpj,jpk, zalbet ) 
    504391      CALL wrk_alloc( jpi,jpj,jpk,2, zdxrho , zdyrho, zdzrho,              klstart = 0  ) 
    505392      CALL wrk_alloc( jpi,jpj,  2,2, zti_mlb, ztj_mlb,        kkstart = 0, klstart = 0  ) 
     
    519406                  zdjt = ( tsb(ji,jj+1,jk,jp_tem) - tsb(ji,jj,jk,jp_tem) )    ! j-gradient of T & S at v-point 
    520407                  zdjs = ( tsb(ji,jj+1,jk,jp_sal) - tsb(ji,jj,jk,jp_sal) ) 
    521                   zdxrho_raw = ( - rab_b(ji+ip,jj   ,jk,jp_tem) * zdit + rab_b(ji+ip,jj   ,jk,jp_sal) * zdis ) / e1u(ji,jj) 
    522                   zdyrho_raw = ( - rab_b(ji   ,jj+jp,jk,jp_tem) * zdjt + rab_b(ji   ,jj+jp,jk,jp_sal) * zdjs ) / e2v(ji,jj) 
    523                   zdxrho(ji+ip,jj   ,jk,1-ip) = SIGN( MAX( repsln, ABS( zdxrho_raw ) ), zdxrho_raw )   ! keep the sign 
    524                   zdyrho(ji   ,jj+jp,jk,1-jp) = SIGN( MAX( repsln, ABS( zdyrho_raw ) ), zdyrho_raw ) 
     408                  zdxrho_raw = ( - rab_b(ji+ip,jj   ,jk,jp_tem) * zdit + rab_b(ji+ip,jj   ,jk,jp_sal) * zdis ) * r1_e1u(ji,jj) 
     409                  zdyrho_raw = ( - rab_b(ji   ,jj+jp,jk,jp_tem) * zdjt + rab_b(ji   ,jj+jp,jk,jp_sal) * zdjs ) * r1_e2v(ji,jj) 
     410                  zdxrho(ji+ip,jj   ,jk,1-ip) = SIGN(  MAX( repsln, ABS( zdxrho_raw ) ), zdxrho_raw )   ! keep the sign 
     411                  zdyrho(ji   ,jj+jp,jk,1-jp) = SIGN(  MAX( repsln, ABS( zdyrho_raw ) ), zdyrho_raw ) 
    525412               END DO 
    526413            END DO 
     
    533420                  zdit = gtsu(ji,jj,jp_tem)   ;   zdjt = gtsv(ji,jj,jp_tem)      ! i- & j-gradient of Temperature 
    534421                  zdis = gtsu(ji,jj,jp_sal)   ;   zdjs = gtsv(ji,jj,jp_sal)      ! i- & j-gradient of Salinity 
    535                   zdxrho_raw = ( - rab_b(ji+ip,jj   ,iku,jp_tem) * zdit + rab_b(ji+ip,jj   ,iku,jp_sal) * zdis ) / e1u(ji,jj) 
    536                   zdyrho_raw = ( - rab_b(ji   ,jj+jp,ikv,jp_tem) * zdjt + rab_b(ji   ,jj+jp,ikv,jp_sal) * zdjs ) / e2v(ji,jj) 
     422                  zdxrho_raw = ( - rab_b(ji+ip,jj   ,iku,jp_tem) * zdit + rab_b(ji+ip,jj   ,iku,jp_sal) * zdis ) * r1_e1u(ji,jj) 
     423                  zdyrho_raw = ( - rab_b(ji   ,jj+jp,ikv,jp_tem) * zdjt + rab_b(ji   ,jj+jp,ikv,jp_sal) * zdjs ) * r1_e2v(ji,jj) 
    537424                  zdxrho(ji+ip,jj   ,iku,1-ip) = SIGN( MAX( repsln, ABS( zdxrho_raw ) ), zdxrho_raw )   ! keep the sign 
    538425                  zdyrho(ji   ,jj+jp,ikv,1-jp) = SIGN( MAX( repsln, ABS( zdyrho_raw ) ), zdyrho_raw ) 
     
    554441                     zdks = 0._wp 
    555442                  ENDIF 
    556                   zdzrho_raw = ( - rab_b(ji,jj,jk,jp_tem) * zdkt + rab_b(ji,jj,jk,jp_sal) * zdks ) / fse3w(ji,jj,jk+kp) 
    557                   zdzrho(ji,jj,jk,kp) = - MIN( - repsln, zdzrho_raw )    ! force zdzrho >= repsln 
     443                  zdzrho_raw = ( - zalbet(ji,jj,jk) * zdkt + zbeta0*zdks ) / fse3w(ji,jj,jk+kp) 
     444                  zdzrho(ji,jj,jk,kp) = - MIN( - repsln , zdzrho_raw )    ! force zdzrho >= repsln 
    558445                 END DO 
    559446            END DO 
     
    588475                  ! 
    589476                  jk = nmln(ji+ip,jj) + 1 
    590                   IF( jk .GT. mbkt(ji+ip,jj) ) THEN  !ML reaches bottom 
    591                     zti_mlb(ji+ip,jj   ,1-ip,kp) = 0.0_wp 
    592                   ELSE 
    593                     ! Add s-coordinate slope at t-points (do this by *subtracting* gradient of depth) 
    594                     zti_g_raw = (  zdxrho(ji+ip,jj,jk-kp,1-ip) / zdzrho(ji+ip,jj,jk-kp,kp)      & 
    595                        &      - ( fsdept(ji+1,jj,jk-kp) - fsdept(ji,jj,jk-kp) ) / e1u(ji,jj)  ) * umask(ji,jj,jk) 
    596                     zti_mlb(ji+ip,jj   ,1-ip,kp) = SIGN( MIN( rn_slpmax, ABS( zti_g_raw ) ), zti_g_raw ) 
     477                  IF( jk > mbkt(ji+ip,jj) ) THEN   ! ML reaches bottom 
     478                     zti_mlb(ji+ip,jj   ,1-ip,kp) = 0.0_wp 
     479                  ELSE                              
     480                     ! Add s-coordinate slope at t-points (do this by *subtracting* gradient of depth) 
     481                     zti_g_raw = (  zdxrho(ji+ip,jj,jk-kp,1-ip) / zdzrho(ji+ip,jj,jk-kp,kp)      & 
     482                        &          - ( fsdept(ji+1,jj,jk-kp) - fsdept(ji,jj,jk-kp) ) * r1_e1u(ji,jj)  ) * umask(ji,jj,jk) 
     483                     ze3_e1    =  fse3w(ji+ip,jj,jk-kp) * r1_e1u(ji,jj)  
     484                     zti_mlb(ji+ip,jj   ,1-ip,kp) = SIGN( MIN( rn_slpmax, 5.0_wp * ze3_e1  , ABS( zti_g_raw ) ), zti_g_raw ) 
    597485                  ENDIF 
    598486                  ! 
    599487                  jk = nmln(ji,jj+jp) + 1 
    600488                  IF( jk .GT. mbkt(ji,jj+jp) ) THEN  !ML reaches bottom 
    601                     ztj_mlb(ji   ,jj+jp,1-jp,kp) = 0.0_wp 
     489                     ztj_mlb(ji   ,jj+jp,1-jp,kp) = 0.0_wp 
    602490                  ELSE 
    603                     ztj_g_raw = (  zdyrho(ji,jj+jp,jk-kp,1-jp) / zdzrho(ji,jj+jp,jk-kp,kp)      & 
    604                        &      - ( fsdept(ji,jj+1,jk-kp) - fsdept(ji,jj,jk-kp) ) / e2v(ji,jj)  ) * vmask(ji,jj,jk) 
    605                     ztj_mlb(ji   ,jj+jp,1-jp,kp) = SIGN( MIN( rn_slpmax, ABS( ztj_g_raw ) ), ztj_g_raw ) 
     491                     ztj_g_raw = (  zdyrho(ji,jj+jp,jk-kp,1-jp) / zdzrho(ji,jj+jp,jk-kp,kp)      & 
     492                        &      - ( fsdept(ji,jj+1,jk-kp) - fsdept(ji,jj,jk-kp) ) / e2v(ji,jj)  ) * vmask(ji,jj,jk) 
     493                     ze3_e2    =  fse3w(ji,jj+jp,jk-kp) / e2v(ji,jj) 
     494                     ztj_mlb(ji   ,jj+jp,1-jp,kp) = SIGN( MIN( rn_slpmax, 5.0_wp * ze3_e2  , ABS( ztj_g_raw ) ), ztj_g_raw ) 
    606495                  ENDIF 
    607496               END DO 
     
    632521                     zti_raw   = zdxrho(ji+ip,jj   ,jk,1-ip) / zdzrho(ji+ip,jj   ,jk,kp)                   ! unmasked 
    633522                     ztj_raw   = zdyrho(ji   ,jj+jp,jk,1-jp) / zdzrho(ji   ,jj+jp,jk,kp) 
    634  
     523                     ! 
    635524                     ! Must mask contribution to slope for triad jk=1,kp=0 that poke up though ocean surface 
    636                      zti_coord = znot_thru_surface * ( fsdept(ji+1,jj  ,jk) - fsdept(ji,jj,jk) ) / e1u(ji,jj) 
    637                      ztj_coord = znot_thru_surface * ( fsdept(ji  ,jj+1,jk) - fsdept(ji,jj,jk) ) / e2v(ji,jj)                  ! unmasked 
     525                     zti_coord = znot_thru_surface * ( fsdept(ji+1,jj  ,jk) - fsdept(ji,jj,jk) ) * r1_e1u(ji,jj) 
     526                     ztj_coord = znot_thru_surface * ( fsdept(ji  ,jj+1,jk) - fsdept(ji,jj,jk) ) * r1_e2v(ji,jj)     ! unmasked 
    638527                     zti_g_raw = zti_raw - zti_coord      ! ref to geopot surfaces 
    639528                     ztj_g_raw = ztj_raw - ztj_coord 
    640                      zti_g_lim = SIGN( MIN( rn_slpmax, ABS( zti_g_raw ) ), zti_g_raw ) 
    641                      ztj_g_lim = SIGN( MIN( rn_slpmax, ABS( ztj_g_raw ) ), ztj_g_raw ) 
     529                     ! additional limit required in bilaplacian case 
     530                     ze3_e1    = fse3w(ji+ip,jj   ,jk+kp) * r1_e1u(ji,jj) 
     531                     ze3_e2    = fse3w(ji   ,jj+jp,jk+kp) * r1_e2v(ji,jj) 
     532                     ! NB: hard coded factor 5 (can be a namelist parameter...) 
     533                     zti_g_lim = SIGN( MIN( rn_slpmax, 5.0_wp * ze3_e1, ABS( zti_g_raw ) ), zti_g_raw ) 
     534                     ztj_g_lim = SIGN( MIN( rn_slpmax, 5.0_wp * ze3_e2, ABS( ztj_g_raw ) ), ztj_g_raw ) 
    642535                     ! 
    643536                     ! Below  ML use limited zti_g as is & mask 
     
    668561                     ! 
    669562                     IF( ln_triad_iso ) THEN 
    670                         zti_raw = zti_lim**2 / zti_raw 
    671                         ztj_raw = ztj_lim**2 / ztj_raw 
     563                        zti_raw = zti_lim*zti_lim / zti_raw 
     564                        ztj_raw = ztj_lim*ztj_lim / ztj_raw 
    672565                        zti_raw = SIGN( MIN( ABS(zti_lim), ABS( zti_raw ) ), zti_raw ) 
    673566                        ztj_raw = SIGN( MIN( ABS(ztj_lim), ABS( ztj_raw ) ), ztj_raw ) 
    674                         zti_lim =           zfacti   * zti_lim                       & 
    675                         &      + ( 1._wp - zfacti ) * zti_raw 
    676                         ztj_lim =           zfactj   * ztj_lim                       & 
    677                         &      + ( 1._wp - zfactj ) * ztj_raw 
     567                        zti_lim = zfacti * zti_lim + ( 1._wp - zfacti ) * zti_raw 
     568                        ztj_lim = zfactj * ztj_lim + ( 1._wp - zfactj ) * ztj_raw 
    678569                     ENDIF 
    679                      triadi(ji+ip,jj   ,jk,1-ip,kp) = zti_lim 
    680                      triadj(ji   ,jj+jp,jk,1-jp,kp) = ztj_lim 
    681                     ! 
    682                      zbu = e1u(ji    ,jj) * e2u(ji   ,jj) * fse3u(ji   ,jj,jk   ) 
    683                      zbv = e1v(ji    ,jj) * e2v(ji   ,jj) * fse3v(ji   ,jj,jk   ) 
    684                      zbti = e1t(ji+ip,jj) * e2t(ji+ip,jj) * fse3w(ji+ip,jj,jk+kp) 
    685                      zbtj = e1t(ji,jj+jp) * e2t(ji,jj+jp) * fse3w(ji,jj+jp,jk+kp) 
    686                      ! 
    687                      !!gm this may inhibit vectorization on Vect Computers, and even on scalar computers....  ==> to be checked 
    688                      wslp2 (ji+ip,jj,jk+kp) = wslp2(ji+ip,jj,jk+kp) + 0.25_wp * zbu / zbti * zti_g_lim**2      ! masked 
    689                      wslp2 (ji,jj+jp,jk+kp) = wslp2(ji,jj+jp,jk+kp) + 0.25_wp * zbv / zbtj * ztj_g_lim**2 
     570                     !                                      ! switching triad scheme  
     571                     zisw = (rn_sw_triad - 1._wp ) + rn_sw_triad    & 
     572                        &            * 2._wp * ABS( 0.5_wp - kp - ( 0.5_wp - ip ) * SIGN( 1._wp , zdxrho(ji+ip,jj,jk,1-ip) )  ) 
     573                     zjsw = (rn_sw_triad - 1._wp ) + rn_sw_triad    & 
     574                        &            * 2._wp * ABS( 0.5_wp - kp - ( 0.5_wp - jp ) * SIGN( 1._wp , zdyrho(ji,jj+jp,jk,1-jp) )  ) 
     575                     ! 
     576                     triadi(ji+ip,jj   ,jk,1-ip,kp) = zti_lim * zisw 
     577                     triadj(ji   ,jj+jp,jk,1-jp,kp) = ztj_lim * zjsw 
     578                     ! 
     579                     zbu  = e1e2u(ji   ,jj   ) * fse3u(ji   ,jj   ,jk   ) 
     580                     zbv  = e1e2v(ji   ,jj   ) * fse3v(ji   ,jj   ,jk   ) 
     581                     zbti = e1e2t(ji+ip,jj   ) * fse3w(ji+ip,jj   ,jk+kp) 
     582                     zbtj = e1e2t(ji   ,jj+jp) * fse3w(ji   ,jj+jp,jk+kp) 
     583                     ! 
     584                     wslp2(ji+ip,jj,jk+kp) = wslp2(ji+ip,jj,jk+kp) + 0.25_wp * zbu / zbti * zti_g_lim*zti_g_lim      ! masked 
     585                     wslp2(ji,jj+jp,jk+kp) = wslp2(ji,jj+jp,jk+kp) + 0.25_wp * zbv / zbtj * ztj_g_lim*ztj_g_lim 
    690586                  END DO 
    691587               END DO 
     
    699595      ! 
    700596      CALL wrk_dealloc( jpi,jpj, z1_mlbw ) 
     597      CALL wrk_dealloc( jpi,jpj,jpk, zalbet ) 
    701598      CALL wrk_dealloc( jpi,jpj,jpk,2, zdxrho , zdyrho, zdzrho,              klstart = 0  ) 
    702599      CALL wrk_dealloc( jpi,jpj,  2,2, zti_mlb, ztj_mlb,        kkstart = 0, klstart = 0  ) 
    703600      ! 
    704       IF( nn_timing == 1 )  CALL timing_stop('ldf_slp_grif') 
    705       ! 
    706    END SUBROUTINE ldf_slp_grif 
     601      IF( nn_timing == 1 )  CALL timing_stop('ldf_slp_triad') 
     602      ! 
     603   END SUBROUTINE ldf_slp_triad 
    707604 
    708605 
     
    730627      INTEGER  ::   ji , jj , jk                   ! dummy loop indices 
    731628      INTEGER  ::   iku, ikv, ik, ikm1             ! local integers 
    732       REAL(wp) ::   zeps, zm1_g, zm1_2g            ! local scalars 
     629      REAL(wp) ::   zeps, zm1_g, zm1_2g, z1_slpmax ! local scalars 
    733630      REAL(wp) ::   zci, zfi, zau, zbu, zai, zbi   !   -      - 
    734631      REAL(wp) ::   zcj, zfj, zav, zbv, zaj, zbj   !   -      - 
     
    741638      zm1_g  = -1.0_wp / grav 
    742639      zm1_2g = -0.5_wp / grav 
     640      z1_slpmax = 1._wp / rn_slpmax 
    743641      ! 
    744642      uslpml (1,:) = 0._wp      ;      uslpml (jpi,:) = 0._wp 
     
    752650            DO ji = 1, jpi 
    753651               ik = nmln(ji,jj) - 1 
    754                IF( jk <= ik .AND. jk >= mikt(ji,jj) ) THEN 
    755                   omlmask(ji,jj,jk) = 1._wp 
    756                ELSE 
    757                   omlmask(ji,jj,jk) = 0._wp 
     652               IF( jk <= ik ) THEN   ;   omlmask(ji,jj,jk) = 1._wp 
     653               ELSE                  ;   omlmask(ji,jj,jk) = 0._wp 
    758654               ENDIF 
    759655            END DO 
     
    777673            ! 
    778674            !                        !- vertical density gradient for u- and v-slopes (from dzr at T-point) 
    779             iku = MIN(  MAX( miku(ji,jj)+1, nmln(ji,jj) , nmln(ji+1,jj) ) , jpkm1  )   ! ML (MAX of T-pts, bound by jpkm1) 
    780             ikv = MIN(  MAX( mikv(ji,jj)+1, nmln(ji,jj) , nmln(ji,jj+1) ) , jpkm1  )   ! 
     675            iku = MIN(  MAX( 1, nmln(ji,jj) , nmln(ji+1,jj) ) , jpkm1  )   ! ML (MAX of T-pts, bound by jpkm1) 
     676            ikv = MIN(  MAX( 1, nmln(ji,jj) , nmln(ji,jj+1) ) , jpkm1  )   ! 
    781677            zbu = 0.5_wp * ( p_dzr(ji,jj,iku) + p_dzr(ji+1,jj  ,iku) ) 
    782678            zbv = 0.5_wp * ( p_dzr(ji,jj,ikv) + p_dzr(ji  ,jj+1,ikv) ) 
    783679            !                        !- horizontal density gradient at u- & v-points 
    784             zau = p_gru(ji,jj,iku) / e1u(ji,jj) 
    785             zav = p_grv(ji,jj,ikv) / e2v(ji,jj) 
     680            zau = p_gru(ji,jj,iku) * r1_e1u(ji,jj) 
     681            zav = p_grv(ji,jj,ikv) * r1_e2v(ji,jj) 
    786682            !                        !- bound the slopes: abs(zw.)<= 1/100 and zb..<0 
    787683            !                           kxz max= ah slope max =< e1 e3 /(pi**2 2 dt) 
    788             zbu = MIN(  zbu , -100._wp* ABS( zau ) , -7.e+3_wp/fse3u(ji,jj,iku)* ABS( zau )  ) 
    789             zbv = MIN(  zbv , -100._wp* ABS( zav ) , -7.e+3_wp/fse3v(ji,jj,ikv)* ABS( zav )  ) 
     684            zbu = MIN(  zbu , - z1_slpmax * ABS( zau ) , -7.e+3_wp/fse3u(ji,jj,iku)* ABS( zau )  ) 
     685            zbv = MIN(  zbv , - z1_slpmax * ABS( zav ) , -7.e+3_wp/fse3v(ji,jj,ikv)* ABS( zav )  ) 
    790686            !                        !- Slope at u- & v-points (uslpml, vslpml) 
    791687            uslpml(ji,jj) = zau / ( zbu - zeps ) * umask(ji,jj,iku) 
     
    812708            zbj = MIN(  zbw , -100._wp* ABS( zaj ) , -7.e+3_wp/fse3w(ji,jj,ik)* ABS( zaj )  ) 
    813709            !                        !- i- & j-slope at w-points (wslpiml, wslpjml) 
    814             wslpiml(ji,jj) = zai / ( zbi - zeps ) * wmask (ji,jj,ik) 
    815             wslpjml(ji,jj) = zaj / ( zbj - zeps ) * wmask (ji,jj,ik) 
     710            wslpiml(ji,jj) = zai / ( zbi - zeps ) * tmask (ji,jj,ik) 
     711            wslpjml(ji,jj) = zaj / ( zbj - zeps ) * tmask (ji,jj,ik) 
    816712         END DO 
    817713      END DO 
     
    831727      !! ** Purpose :   Initialization for the isopycnal slopes computation 
    832728      !! 
    833       !! ** Method  :   read the nammbf namelist and check the parameter 
    834       !!      values called by tra_dmp at the first timestep (nit000) 
     729      !! ** Method  :    
    835730      !!---------------------------------------------------------------------- 
    836731      INTEGER ::   ji, jj, jk   ! dummy loop indices 
     
    845740         WRITE(numout,*) '~~~~~~~~~~~~' 
    846741      ENDIF 
    847  
    848       IF( ln_traldf_grif ) THEN        ! Griffies operator : triad of slopes 
    849          ALLOCATE( triadi_g(jpi,jpj,jpk,0:1,0:1) , triadj_g(jpi,jpj,jpk,0:1,0:1) , wslp2(jpi,jpj,jpk) , STAT=ierr ) 
    850          ALLOCATE( triadi  (jpi,jpj,jpk,0:1,0:1) , triadj  (jpi,jpj,jpk,0:1,0:1)                      , STAT=ierr ) 
    851          IF( ierr > 0             )   CALL ctl_stop( 'STOP', 'ldf_slp_init : unable to allocate Griffies operator slope' ) 
    852          ! 
     742      ! 
     743      ALLOCATE( ah_wslp2(jpi,jpj,jpk) , akz(jpi,jpj,jpk) , STAT=ierr ) 
     744      IF( ierr > 0 )   CALL ctl_stop( 'STOP', 'ldf_slp_init : unable to allocate ah_slp2 or akz' ) 
     745      ! 
     746      IF( ln_traldf_triad ) THEN        ! Griffies operator : triad of slopes 
     747         IF(lwp) WRITE(numout,*) '              Griffies (triad) operator initialisation' 
     748         ALLOCATE( triadi_g(jpi,jpj,jpk,0:1,0:1) , triadj_g(jpi,jpj,jpk,0:1,0:1) ,     & 
     749            &      triadi  (jpi,jpj,jpk,0:1,0:1) , triadj  (jpi,jpj,jpk,0:1,0:1) ,     & 
     750            &      wslp2   (jpi,jpj,jpk)                                         , STAT=ierr ) 
     751         IF( ierr > 0      )   CALL ctl_stop( 'STOP', 'ldf_slp_init : unable to allocate Griffies operator slope' ) 
    853752         IF( ln_dynldf_iso )   CALL ctl_stop( 'ldf_slp_init: Griffies operator on momentum not supported' ) 
    854753         ! 
    855754      ELSE                             ! Madec operator : slopes at u-, v-, and w-points 
    856          ALLOCATE( uslp(jpi,jpj,jpk) , vslp(jpi,jpj,jpk) , wslpi(jpi,jpj,jpk) , wslpj(jpi,jpj,jpk) ,                & 
    857             &   omlmask(jpi,jpj,jpk) , uslpml(jpi,jpj)   , vslpml(jpi,jpj)    , wslpiml(jpi,jpj)   , wslpjml(jpi,jpj) , STAT=ierr ) 
     755         IF(lwp) WRITE(numout,*) '              Madec operator initialisation' 
     756         ALLOCATE( omlmask(jpi,jpj,jpk) ,                                                                        & 
     757            &      uslp(jpi,jpj,jpk) , uslpml(jpi,jpj) , wslpi(jpi,jpj,jpk) , wslpiml(jpi,jpj) ,     & 
     758            &      vslp(jpi,jpj,jpk) , vslpml(jpi,jpj) , wslpj(jpi,jpj,jpk) , wslpjml(jpi,jpj) , STAT=ierr ) 
    858759         IF( ierr > 0 )   CALL ctl_stop( 'STOP', 'ldf_slp_init : unable to allocate Madec operator slope ' ) 
    859760 
     
    865766         wslpj(:,:,:) = 0._wp   ;   wslpjml(:,:) = 0._wp 
    866767 
    867          IF(ln_sco .AND.  (ln_traldf_hor .OR. ln_dynldf_hor )) THEN 
    868             IF(lwp)   WRITE(numout,*) '          Horizontal mixing in s-coordinate: slope = slope of s-surfaces' 
    869  
    870             ! geopotential diffusion in s-coordinates on tracers and/or momentum 
    871             ! The slopes of s-surfaces are computed once (no call to ldfslp in step) 
    872             ! The slopes for momentum diffusion are i- or j- averaged of those on tracers 
    873  
    874             ! set the slope of diffusion to the slope of s-surfaces 
    875             !      ( c a u t i o n : minus sign as fsdep has positive value ) 
    876             DO jk = 1, jpk 
    877                DO jj = 2, jpjm1 
    878                   DO ji = fs_2, fs_jpim1   ! vector opt. 
    879                      uslp (ji,jj,jk) = -1./e1u(ji,jj) * ( fsdept_b(ji+1,jj,jk) - fsdept_b(ji ,jj ,jk) ) * umask(ji,jj,jk) 
    880                      vslp (ji,jj,jk) = -1./e2v(ji,jj) * ( fsdept_b(ji,jj+1,jk) - fsdept_b(ji ,jj ,jk) ) * vmask(ji,jj,jk) 
    881                      wslpi(ji,jj,jk) = -1./e1t(ji,jj) * ( fsdepw_b(ji+1,jj,jk) - fsdepw_b(ji-1,jj,jk) ) * tmask(ji,jj,jk) * 0.5 
    882                      wslpj(ji,jj,jk) = -1./e2t(ji,jj) * ( fsdepw_b(ji,jj+1,jk) - fsdepw_b(ji,jj-1,jk) ) * tmask(ji,jj,jk) * 0.5 
    883                   END DO 
    884                END DO 
    885             END DO 
    886             CALL lbc_lnk( uslp , 'U', -1. )   ;   CALL lbc_lnk( vslp , 'V', -1. )      ! Lateral boundary conditions 
    887             CALL lbc_lnk( wslpi, 'W', -1. )   ;   CALL lbc_lnk( wslpj, 'W', -1. ) 
    888          ENDIF 
     768         !!gm I no longer understand this..... 
     769!!gm         IF( (ln_traldf_hor .OR. ln_dynldf_hor) .AND. .NOT. (lk_vvl .AND. ln_rstart) ) THEN 
     770!            IF(lwp)   WRITE(numout,*) '          Horizontal mixing in s-coordinate: slope = slope of s-surfaces' 
     771! 
     772!            ! geopotential diffusion in s-coordinates on tracers and/or momentum 
     773!            ! The slopes of s-surfaces are computed once (no call to ldfslp in step) 
     774!            ! The slopes for momentum diffusion are i- or j- averaged of those on tracers 
     775! 
     776!            ! set the slope of diffusion to the slope of s-surfaces 
     777!            !      ( c a u t i o n : minus sign as fsdep has positive value ) 
     778!            DO jk = 1, jpk 
     779!               DO jj = 2, jpjm1 
     780!                  DO ji = fs_2, fs_jpim1   ! vector opt. 
     781!                     uslp (ji,jj,jk) = - ( fsdept(ji+1,jj,jk) - fsdept(ji ,jj ,jk) ) * r1_e1u(ji,jj) * umask(ji,jj,jk) 
     782!                     vslp (ji,jj,jk) = - ( fsdept(ji,jj+1,jk) - fsdept(ji ,jj ,jk) ) * r1_e2v(ji,jj) * vmask(ji,jj,jk) 
     783!                     wslpi(ji,jj,jk) = - ( fsdepw(ji+1,jj,jk) - fsdepw(ji-1,jj,jk) ) * r1_e1t(ji,jj) * wmask(ji,jj,jk) * 0.5 
     784!                     wslpj(ji,jj,jk) = - ( fsdepw(ji,jj+1,jk) - fsdepw(ji,jj-1,jk) ) * r1_e2t(ji,jj) * wmask(ji,jj,jk) * 0.5 
     785!                  END DO 
     786!               END DO 
     787!            END DO 
     788!            CALL lbc_lnk( uslp , 'U', -1. )   ;   CALL lbc_lnk( vslp , 'V', -1. )      ! Lateral boundary conditions 
     789!            CALL lbc_lnk( wslpi, 'W', -1. )   ;   CALL lbc_lnk( wslpj, 'W', -1. ) 
     790!!gm         ENDIF 
    889791      ENDIF 
    890792      ! 
     
    892794      ! 
    893795   END SUBROUTINE ldf_slp_init 
    894  
    895 #else 
    896    !!------------------------------------------------------------------------ 
    897    !!   Dummy module :                 NO Rotation of lateral mixing tensor 
    898    !!------------------------------------------------------------------------ 
    899    LOGICAL, PUBLIC, PARAMETER ::   lk_ldfslp = .FALSE.    !: slopes flag 
    900 CONTAINS 
    901    SUBROUTINE ldf_slp( kt, prd, pn2 )   ! Dummy routine 
    902       INTEGER, INTENT(in) :: kt 
    903       REAL, DIMENSION(:,:,:), INTENT(in) :: prd, pn2 
    904       WRITE(*,*) 'ldf_slp: You should not have seen this print! error?', kt, prd(1,1,1), pn2(1,1,1) 
    905    END SUBROUTINE ldf_slp 
    906    SUBROUTINE ldf_slp_grif( kt )        ! Dummy routine 
    907       INTEGER, INTENT(in) :: kt 
    908       WRITE(*,*) 'ldf_slp_grif: You should not have seen this print! error?', kt 
    909    END SUBROUTINE ldf_slp_grif 
    910    SUBROUTINE ldf_slp_init              ! Dummy routine 
    911    END SUBROUTINE ldf_slp_init 
    912 #endif 
    913796 
    914797   !!====================================================================== 
  • branches/2014/dev_r4650_UKMO14.12_STAND_ALONE_OBSOPER/NEMOGCM/NEMO/OPA_SRC/LDF/ldftra.F90

    r4624 r6043  
    22   !!====================================================================== 
    33   !!                       ***  MODULE  ldftra  *** 
    4    !! Ocean physics:  lateral diffusivity coefficient  
     4   !! Ocean physics:  lateral diffusivity coefficients  
    55   !!===================================================================== 
    6    !! History :        ! 1997-07  (G. Madec)  from inimix.F split in 2 routines 
    7    !!   NEMO      1.0  ! 2002-09  (G. Madec)  F90: Free form and module 
    8    !!             2.0  ! 2005-11  (G. Madec)   
     6   !! History :       ! 1997-07  (G. Madec)  from inimix.F split in 2 routines 
     7   !!   NEMO     1.0  ! 2002-09  (G. Madec)  F90: Free form and module 
     8   !!            2.0  ! 2005-11  (G. Madec)   
     9   !!            3.7  ! 2013-12  (F. Lemarie, G. Madec)  restructuration/simplification of aht/aeiv specification, 
     10   !!                 !                                  add velocity dependent coefficient and optional read in file 
    911   !!---------------------------------------------------------------------- 
    1012 
    1113   !!---------------------------------------------------------------------- 
    1214   !!   ldf_tra_init : initialization, namelist read, and parameters control 
    13    !!   ldf_tra_c3d   : 3D eddy viscosity coefficient initialization 
    14    !!   ldf_tra_c2d   : 2D eddy viscosity coefficient initialization 
    15    !!   ldf_tra_c1d   : 1D eddy viscosity coefficient initialization 
     15   !!   ldf_tra      : update lateral eddy diffusivity coefficients at each time step  
     16   !!   ldf_eiv_init : initialization of the eiv coeff. from namelist choices  
     17   !!   ldf_eiv      : time evolution of the eiv coefficients (function of the growth rate of baroclinic instability) 
     18   !!   ldf_eiv_trp  : add to the input ocean transport the contribution of the EIV parametrization 
     19   !!   ldf_eiv_dia  : diagnose the eddy induced velocity from the eiv streamfunction 
    1620   !!---------------------------------------------------------------------- 
    1721   USE oce             ! ocean dynamics and tracers 
    1822   USE dom_oce         ! ocean space and time domain 
    1923   USE phycst          ! physical constants 
    20    USE ldftra_oce      ! ocean tracer   lateral physics 
    21    USE ldfslp          ! ??? 
     24   USE ldfslp          ! lateral diffusion: slope of iso-neutral surfaces 
     25   USE ldfc1d_c2d      ! lateral diffusion: 1D & 2D cases  
     26   USE diaar5, ONLY:   lk_diaar5 
     27   ! 
     28   USE trc_oce, ONLY: lk_offline ! offline flag 
    2229   USE in_out_manager  ! I/O manager 
    23    USE ioipsl 
     30   USE iom             ! I/O module for ehanced bottom friction file 
    2431   USE lib_mpp         ! distribued memory computing library 
    2532   USE lbclnk          ! ocean lateral boundary conditions (or mpp link) 
     33   USE wrk_nemo        ! work arrays 
     34   USE timing          ! timing 
    2635 
    2736   IMPLICIT NONE 
    2837   PRIVATE 
    2938 
    30    PUBLIC   ldf_tra_init   ! called by opa.F90 
     39   PUBLIC   ldf_tra_init   ! called by nemogcm.F90 
     40   PUBLIC   ldf_tra        ! called by step.F90 
     41   PUBLIC   ldf_eiv_init   ! called by nemogcm.F90 
     42   PUBLIC   ldf_eiv        ! called by step.F90 
     43   PUBLIC   ldf_eiv_trp    ! called by traadv.F90 
     44   PUBLIC   ldf_eiv_dia    ! called by traldf_iso and traldf_iso_triad.F90 
     45    
     46   !                                   !!* Namelist namtra_ldf : lateral mixing on tracers *  
     47   !                                    != Operator type =! 
     48   LOGICAL , PUBLIC ::   ln_traldf_lap       !: laplacian operator 
     49   LOGICAL , PUBLIC ::   ln_traldf_blp       !: bilaplacian operator 
     50   !                                    != Direction of action =! 
     51   LOGICAL , PUBLIC ::   ln_traldf_lev       !: iso-level direction 
     52   LOGICAL , PUBLIC ::   ln_traldf_hor       !: horizontal (geopotential) direction 
     53!  LOGICAL , PUBLIC ::   ln_traldf_iso       !: iso-neutral direction                    (see ldfslp) 
     54!  LOGICAL , PUBLIC ::   ln_traldf_triad     !: griffies triad scheme                    (see ldfslp) 
     55   LOGICAL , PUBLIC ::   ln_traldf_msc       !: Method of Stabilizing Correction  
     56!  LOGICAL , PUBLIC ::   ln_triad_iso        !: pure horizontal mixing in ML             (see ldfslp) 
     57!  LOGICAL , PUBLIC ::   ln_botmix_triad     !: mixing on bottom                         (see ldfslp) 
     58!  REAL(wp), PUBLIC ::   rn_sw_triad         !: =1/0 switching triad / all 4 triads used (see ldfslp) 
     59!  REAL(wp), PUBLIC ::   rn_slpmax           !: slope limit                              (see ldfslp) 
     60   !                                    !=  Coefficients =! 
     61   INTEGER , PUBLIC ::   nn_aht_ijk_t        !: choice of time & space variations of the lateral eddy diffusivity coef. 
     62   REAL(wp), PUBLIC ::   rn_aht_0            !:   laplacian lateral eddy diffusivity [m2/s] 
     63   REAL(wp), PUBLIC ::   rn_bht_0            !: bilaplacian lateral eddy diffusivity [m4/s] 
     64 
     65   !                                   !!* Namelist namtra_ldfeiv : eddy induced velocity param. * 
     66   !                                    != Use/diagnose eiv =! 
     67   LOGICAL , PUBLIC ::   ln_ldfeiv           !: eddy induced velocity flag 
     68   LOGICAL , PUBLIC ::   ln_ldfeiv_dia       !: diagnose & output eiv streamfunction and velocity (IOM) 
     69   !                                    != Coefficients =! 
     70   INTEGER , PUBLIC ::   nn_aei_ijk_t        !: choice of time/space variation of the eiv coeff. 
     71   REAL(wp), PUBLIC ::   rn_aeiv_0           !: eddy induced velocity coefficient [m2/s] 
     72    
     73   LOGICAL , PUBLIC ::   l_ldftra_time = .FALSE.   !: flag for time variation of the lateral eddy diffusivity coef. 
     74   LOGICAL , PUBLIC ::   l_ldfeiv_time = .FALSE.   ! flag for time variation of the eiv coef. 
     75 
     76   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   ahtu, ahtv   !: eddy diffusivity coef. at U- and V-points   [m2/s] 
     77   REAL(wp), PUBLIC, ALLOCATABLE, SAVE, DIMENSION(:,:,:) ::   aeiu, aeiv   !: eddy induced velocity coeff.                [m2/s] 
     78 
     79   REAL(wp) ::   r1_4  = 0.25_wp          ! =1/4 
     80   REAL(wp) ::   r1_12 = 1._wp / 12._wp   ! =1/12 
    3181 
    3282   !! * Substitutions 
     
    3484#  include "vectopt_loop_substitute.h90" 
    3585   !!---------------------------------------------------------------------- 
    36    !! NEMO/OPA 3.3 , NEMO Consortium (2010) 
     86   !! NEMO/OPA 3.7 , NEMO Consortium (2015) 
    3787   !! $Id$ 
    3888   !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt) 
     
    4696      !! ** Purpose :   initializations of the tracer lateral mixing coeff. 
    4797      !! 
    48       !! ** Method  :   the Eddy diffusivity and eddy induced velocity ceoff. 
    49       !!      are defined as follows: 
    50       !!         default option   : constant coef. aht0, aeiv0 (namelist) 
    51       !!        'key_traldf_c1d': depth dependent coef. defined in  
    52       !!                            in ldf_tra_c1d routine 
    53       !!        'key_traldf_c2d': latitude and longitude dependent coef. 
    54       !!                            defined in ldf_tra_c2d routine 
    55       !!        'key_traldf_c3d': latitude, longitude, depth dependent coef. 
    56       !!                            defined in ldf_tra_c3d routine 
    57       !! 
    58       !!      N.B. User defined include files.  By default, 3d and 2d coef. 
    59       !!      are set to a constant value given in the namelist and the 1d 
    60       !!      coefficients are initialized to a hyperbolic tangent vertical 
    61       !!      profile. 
    62       !!---------------------------------------------------------------------- 
    63       INTEGER ::   ioptio               ! temporary integer 
    64       INTEGER ::   ios                  ! temporary integer 
    65       LOGICAL ::   ll_print = .FALSE.   ! =T print eddy coef. in numout 
    66       !!  
    67       NAMELIST/namtra_ldf/ ln_traldf_lap  , ln_traldf_bilap,                  & 
    68          &                 ln_traldf_level, ln_traldf_hor  , ln_traldf_iso,   & 
    69          &                 ln_traldf_grif , ln_traldf_gdia ,                  & 
    70          &                 ln_triad_iso   , ln_botmix_grif ,                  & 
    71          &                 rn_aht_0       , rn_ahtb_0      , rn_aeiv_0,       & 
    72          &                 rn_slpmax      , rn_chsmag      ,    rn_smsh,      & 
    73          &                 rn_aht_m 
    74       !!---------------------------------------------------------------------- 
    75  
    76       !  Define the lateral tracer physics parameters 
    77       ! ============================================= 
    78      
    79  
     98      !! ** Method  : * the eddy diffusivity coef. specification depends on: 
     99      !! 
     100      !!    ln_traldf_lap = T     laplacian operator 
     101      !!    ln_traldf_blp = T   bilaplacian operator 
     102      !! 
     103      !!    nn_aht_ijk_t  =  0 => = constant 
     104      !!                  ! 
     105      !!                  = 10 => = F(z) : constant with a reduction of 1/4 with depth  
     106      !!                  ! 
     107      !!                  =-20 => = F(i,j)   = shape read in 'eddy_diffusivity.nc' file 
     108      !!                  = 20    = F(i,j)   = F(e1,e2) or F(e1^3,e2^3) (lap or bilap case) 
     109      !!                  = 21    = F(i,j,t) = F(growth rate of baroclinic instability) 
     110      !!                  ! 
     111      !!                  =-30 => = F(i,j,k)   = shape read in 'eddy_diffusivity.nc' file 
     112      !!                  = 30    = F(i,j,k)   = 2D (case 20) + decrease with depth (case 10) 
     113      !!                  = 31    = F(i,j,k,t) = F(local velocity) (  |u|e  /12   laplacian operator 
     114      !!                                                          or |u|e^3/12 bilaplacian operator ) 
     115      !!              * initialisation of the eddy induced velocity coefficient by a call to ldf_eiv_init  
     116      !!             
     117      !! ** action  : ahtu, ahtv initialized once for all or l_ldftra_time set to true 
     118      !!              aeiu, aeiv initialized once for all or l_ldfeiv_time set to true 
     119      !!---------------------------------------------------------------------- 
     120      INTEGER  ::   jk                ! dummy loop indices 
     121      INTEGER  ::   ierr, inum, ios   ! local integer 
     122      REAL(wp) ::   zah0              ! local scalar 
     123      ! 
     124      NAMELIST/namtra_ldf/ ln_traldf_lap, ln_traldf_blp  ,                   &   ! type of operator 
     125         &                 ln_traldf_lev, ln_traldf_hor  , ln_traldf_triad,  &   ! acting direction of the operator 
     126         &                 ln_traldf_iso, ln_traldf_msc  ,  rn_slpmax     ,  &   ! option for iso-neutral operator 
     127         &                 ln_triad_iso , ln_botmix_triad, rn_sw_triad    ,  &   ! option for triad operator 
     128         &                 rn_aht_0     , rn_bht_0       , nn_aht_ijk_t          ! lateral eddy coefficient 
     129      !!---------------------------------------------------------------------- 
     130      ! 
     131      !  Choice of lateral tracer physics 
     132      ! ================================= 
     133      ! 
    80134      REWIND( numnam_ref )              ! Namelist namtra_ldf in reference namelist : Lateral physics on tracers 
    81135      READ  ( numnam_ref, namtra_ldf, IOSTAT = ios, ERR = 901) 
    82136901   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namtra_ldf in reference namelist', lwp ) 
    83  
     137      ! 
    84138      REWIND( numnam_cfg )              ! Namelist namtra_ldf in configuration namelist : Lateral physics on tracers 
    85139      READ  ( numnam_cfg, namtra_ldf, IOSTAT = ios, ERR = 902 ) 
    86140902   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namtra_ldf in configuration namelist', lwp ) 
    87141      IF(lwm) WRITE ( numond, namtra_ldf ) 
    88  
     142      ! 
    89143      IF(lwp) THEN                      ! control print 
    90144         WRITE(numout,*) 
     
    92146         WRITE(numout,*) '~~~~~~~~~~~~ ' 
    93147         WRITE(numout,*) '   Namelist namtra_ldf : lateral mixing parameters (type, direction, coefficients)' 
    94          WRITE(numout,*) '      laplacian operator            ln_traldf_lap   = ', ln_traldf_lap 
    95          WRITE(numout,*) '      bilaplacian operator          ln_traldf_bilap = ', ln_traldf_bilap 
    96          WRITE(numout,*) '      iso-level                     ln_traldf_level = ', ln_traldf_level 
    97          WRITE(numout,*) '      horizontal (geopotential)     ln_traldf_hor   = ', ln_traldf_hor 
    98          WRITE(numout,*) '      iso-neutral                   ln_traldf_iso   = ', ln_traldf_iso 
    99          WRITE(numout,*) '      iso-neutral (Griffies)        ln_traldf_grif  = ', ln_traldf_grif 
    100          WRITE(numout,*) '      Griffies strmfn diagnostics   ln_traldf_gdia  = ', ln_traldf_gdia 
    101          WRITE(numout,*) '      lateral eddy diffusivity      rn_aht_0        = ', rn_aht_0 
    102          WRITE(numout,*) '      background hor. diffusivity   rn_ahtb_0       = ', rn_ahtb_0 
    103          WRITE(numout,*) '      eddy induced velocity coef.   rn_aeiv_0       = ', rn_aeiv_0 
    104          WRITE(numout,*) '      maximum isoppycnal slope      rn_slpmax       = ', rn_slpmax 
    105          WRITE(numout,*) '      pure lateral mixing in ML     ln_triad_iso    = ', ln_triad_iso 
    106          WRITE(numout,*) '      lateral mixing on bottom      ln_botmix_grif  = ', ln_botmix_grif 
     148         ! 
     149         WRITE(numout,*) '      type :' 
     150         WRITE(numout,*) '         laplacian operator                      ln_traldf_lap   = ', ln_traldf_lap 
     151         WRITE(numout,*) '         bilaplacian operator                    ln_traldf_blp   = ', ln_traldf_blp 
     152         ! 
     153         WRITE(numout,*) '      direction of action :' 
     154         WRITE(numout,*) '         iso-level                               ln_traldf_lev   = ', ln_traldf_lev 
     155         WRITE(numout,*) '         horizontal (geopotential)               ln_traldf_hor   = ', ln_traldf_hor 
     156         WRITE(numout,*) '         iso-neutral Madec operator              ln_traldf_iso   = ', ln_traldf_iso 
     157         WRITE(numout,*) '         iso-neutral triad operator              ln_traldf_triad = ', ln_traldf_triad 
     158         WRITE(numout,*) '            iso-neutral (Method of Stab. Corr.)  ln_traldf_msc   = ', ln_traldf_msc 
     159         WRITE(numout,*) '            maximum isoppycnal slope             rn_slpmax       = ', rn_slpmax 
     160         WRITE(numout,*) '            pure lateral mixing in ML            ln_triad_iso    = ', ln_triad_iso 
     161         WRITE(numout,*) '            switching triad or not               rn_sw_triad     = ', rn_sw_triad 
     162         WRITE(numout,*) '            lateral mixing on bottom             ln_botmix_triad = ', ln_botmix_triad 
     163         ! 
     164         WRITE(numout,*) '      coefficients :' 
     165         WRITE(numout,*) '         lateral eddy diffusivity   (lap case)   rn_aht_0        = ', rn_aht_0 
     166         WRITE(numout,*) '         lateral eddy diffusivity (bilap case)   rn_bht_0        = ', rn_bht_0 
     167         WRITE(numout,*) '         type of time-space variation            nn_aht_ijk_t    = ', nn_aht_ijk_t 
     168      ENDIF 
     169      ! 
     170      !                                ! Parameter control 
     171      ! 
     172      IF( .NOT.ln_traldf_lap .AND. .NOT.ln_traldf_blp ) THEN 
     173         IF(lwp) WRITE(numout,*) '   No diffusive operator selected. ahtu and ahtv are not allocated' 
     174         l_ldftra_time = .FALSE. 
     175         RETURN 
     176      ENDIF 
     177      ! 
     178      IF( ln_traldf_blp .AND. ( ln_traldf_iso .OR. ln_traldf_triad) ) THEN     ! iso-neutral bilaplacian need MSC 
     179         IF( .NOT.ln_traldf_msc )   CALL ctl_stop( 'tra_ldf_init: iso-neutral bilaplacian requires ln_traldf_msc=.true.' ) 
     180      ENDIF 
     181      ! 
     182      !  Space/time variation of eddy coefficients  
     183      ! =========================================== 
     184      !                                               ! allocate the aht arrays 
     185      ALLOCATE( ahtu(jpi,jpj,jpk) , ahtv(jpi,jpj,jpk) , STAT=ierr ) 
     186      IF( ierr /= 0 )   CALL ctl_stop( 'STOP', 'ldf_tra_init: failed to allocate arrays') 
     187      ! 
     188      ahtu(:,:,jpk) = 0._wp                           ! last level always 0   
     189      ahtv(:,:,jpk) = 0._wp 
     190      ! 
     191      !                                               ! value of eddy mixing coef. 
     192      IF    ( ln_traldf_lap ) THEN   ;   zah0 =      rn_aht_0        !   laplacian operator 
     193      ELSEIF( ln_traldf_blp ) THEN   ;   zah0 = ABS( rn_bht_0 )      ! bilaplacian operator 
     194      ENDIF 
     195      ! 
     196      l_ldftra_time = .FALSE.                         ! no time variation except in case defined below 
     197      ! 
     198      IF( ln_traldf_lap .OR. ln_traldf_blp ) THEN     ! only if a lateral diffusion operator is used 
     199         ! 
     200         SELECT CASE(  nn_aht_ijk_t  )                   ! Specification of space time variations of ehtu, ahtv 
     201         ! 
     202         CASE(   0  )      !==  constant  ==! 
     203            IF(lwp) WRITE(numout,*) '          tracer mixing coef. = constant = ', rn_aht_0 
     204            ahtu(:,:,:) = zah0 * umask(:,:,:) 
     205            ahtv(:,:,:) = zah0 * vmask(:,:,:) 
     206            ! 
     207         CASE(  10  )      !==  fixed profile  ==! 
     208            IF(lwp) WRITE(numout,*) '          tracer mixing coef. = F( depth )' 
     209            ahtu(:,:,1) = zah0 * umask(:,:,1)                      ! constant surface value 
     210            ahtv(:,:,1) = zah0 * vmask(:,:,1) 
     211            CALL ldf_c1d( 'TRA', r1_4, ahtu(:,:,1), ahtv(:,:,1), ahtu, ahtv ) 
     212            ! 
     213         CASE ( -20 )      !== fixed horizontal shape read in file  ==! 
     214            IF(lwp) WRITE(numout,*) '          tracer mixing coef. = F(i,j) read in eddy_diffusivity.nc file' 
     215            CALL iom_open( 'eddy_diffusivity_2D.nc', inum ) 
     216            CALL iom_get ( inum, jpdom_data, 'ahtu_2D', ahtu(:,:,1) ) 
     217            CALL iom_get ( inum, jpdom_data, 'ahtv_2D', ahtv(:,:,1) ) 
     218            CALL iom_close( inum ) 
     219            DO jk = 2, jpkm1 
     220               ahtu(:,:,jk) = ahtu(:,:,1) * umask(:,:,jk) 
     221               ahtv(:,:,jk) = ahtv(:,:,1) * vmask(:,:,jk) 
     222            END DO 
     223            ! 
     224         CASE(  20  )      !== fixed horizontal shape  ==! 
     225            IF(lwp) WRITE(numout,*) '          tracer mixing coef. = F( e1, e2 ) or F( e1^3, e2^3 ) (lap or blp case)' 
     226            IF( ln_traldf_lap )   CALL ldf_c2d( 'TRA', 'LAP', zah0, ahtu, ahtv )    ! surface value proportional to scale factor 
     227            IF( ln_traldf_blp )   CALL ldf_c2d( 'TRA', 'BLP', zah0, ahtu, ahtv )    ! surface value proportional to scale factor 
     228            ! 
     229         CASE(  21  )      !==  time varying 2D field  ==! 
     230            IF(lwp) WRITE(numout,*) '          tracer mixing coef. = F( latitude, longitude, time )' 
     231            IF(lwp) WRITE(numout,*) '                              = F( growth rate of baroclinic instability )' 
     232            IF(lwp) WRITE(numout,*) '                              min value = 0.1 * rn_aht_0' 
     233            IF(lwp) WRITE(numout,*) '                              max value = rn_aht_0 (rn_aeiv_0 if nn_aei_ijk_t=21)' 
     234            IF(lwp) WRITE(numout,*) '                              increased to rn_aht_0 within 20N-20S' 
     235            ! 
     236            l_ldftra_time = .TRUE.     ! will be calculated by call to ldf_tra routine in step.F90 
     237            ! 
     238            IF( ln_traldf_blp ) THEN 
     239               CALL ctl_stop( 'ldf_tra_init: aht=F(growth rate of baroc. insta.) incompatible with bilaplacian operator' ) 
     240            ENDIF 
     241            ! 
     242         CASE( -30  )      !== fixed 3D shape read in file  ==! 
     243            IF(lwp) WRITE(numout,*) '          tracer mixing coef. = F(i,j,k) read in eddy_diffusivity.nc file' 
     244            CALL iom_open( 'eddy_diffusivity_3D.nc', inum ) 
     245            CALL iom_get ( inum, jpdom_data, 'ahtu_3D', ahtu ) 
     246            CALL iom_get ( inum, jpdom_data, 'ahtv_3D', ahtv ) 
     247            CALL iom_close( inum ) 
     248            DO jk = 1, jpkm1 
     249               ahtu(:,:,jk) = ahtu(:,:,jk) * umask(:,:,jk) 
     250               ahtv(:,:,jk) = ahtv(:,:,jk) * vmask(:,:,jk) 
     251            END DO 
     252            ! 
     253         CASE(  30  )      !==  fixed 3D shape  ==! 
     254            IF(lwp) WRITE(numout,*) '          tracer mixing coef. = F( latitude, longitude, depth )' 
     255            IF( ln_traldf_lap )   CALL ldf_c2d( 'TRA', 'LAP', zah0, ahtu, ahtv )    ! surface value proportional to scale factor 
     256            IF( ln_traldf_blp )   CALL ldf_c2d( 'TRA', 'BLP', zah0, ahtu, ahtv )    ! surface value proportional to scale factor 
     257            !                                                    ! reduction with depth 
     258            CALL ldf_c1d( 'TRA', r1_4, ahtu(:,:,1), ahtv(:,:,1), ahtu, ahtv ) 
     259            ! 
     260         CASE(  31  )      !==  time varying 3D field  ==! 
     261            IF(lwp) WRITE(numout,*) '          tracer mixing coef. = F( latitude, longitude, depth , time )' 
     262            IF(lwp) WRITE(numout,*) '                                proportional to the velocity : |u|e/12 or |u|e^3/12' 
     263            ! 
     264            l_ldftra_time = .TRUE.     ! will be calculated by call to ldf_tra routine in step.F90 
     265            ! 
     266         CASE DEFAULT 
     267            CALL ctl_stop('ldf_tra_init: wrong choice for nn_aht_ijk_t, the type of space-time variation of aht') 
     268         END SELECT 
     269         ! 
     270         IF( ln_traldf_blp .AND. .NOT. l_ldftra_time ) THEN 
     271            ahtu(:,:,:) = SQRT( ahtu(:,:,:) ) 
     272            ahtv(:,:,:) = SQRT( ahtv(:,:,:) ) 
     273         ENDIF 
     274         ! 
     275      ENDIF 
     276      ! 
     277   END SUBROUTINE ldf_tra_init 
     278 
     279 
     280   SUBROUTINE ldf_tra( kt ) 
     281      !!---------------------------------------------------------------------- 
     282      !!                  ***  ROUTINE ldf_tra  *** 
     283      !!  
     284      !! ** Purpose :   update at kt the tracer lateral mixing coeff. (aht and aeiv) 
     285      !! 
     286      !! ** Method  :   time varying eddy diffusivity coefficients: 
     287      !! 
     288      !!    nn_aei_ijk_t = 21    aeiu, aeiv = F(i,j,  t) = F(growth rate of baroclinic instability) 
     289      !!                                                   with a reduction to 0 in vicinity of the Equator 
     290      !!    nn_aht_ijk_t = 21    ahtu, ahtv = F(i,j,  t) = F(growth rate of baroclinic instability) 
     291      !! 
     292      !!                 = 31    ahtu, ahtv = F(i,j,k,t) = F(local velocity) (  |u|e  /12   laplacian operator 
     293      !!                                                                     or |u|e^3/12 bilaplacian operator ) 
     294      !! 
     295      !! ** action  :   ahtu, ahtv   update at each time step    
     296      !!                aeiu, aeiv      -       -     -    -   (if ln_ldfeiv=T)  
     297      !!---------------------------------------------------------------------- 
     298      INTEGER, INTENT(in) ::   kt   ! time step 
     299      ! 
     300      INTEGER  ::   ji, jj, jk   ! dummy loop indices 
     301      REAL(wp) ::   zaht, zaht_min, z1_f20       ! local scalar 
     302      !!---------------------------------------------------------------------- 
     303      ! 
     304      IF( nn_aei_ijk_t == 21 ) THEN       ! eddy induced velocity coefficients 
     305         !                                ! =F(growth rate of baroclinic instability) 
     306         !                                ! max value rn_aeiv_0 ; decreased to 0 within 20N-20S 
     307         CALL ldf_eiv( kt, rn_aeiv_0, aeiu, aeiv ) 
     308         IF(lwp .AND. kt<=nit000+20 )   WRITE(numout,*) ' kt , ldf_eiv appel', kt 
     309      ENDIF 
     310      ! 
     311      SELECT CASE(  nn_aht_ijk_t  )       ! Eddy diffusivity coefficients 
     312      ! 
     313      CASE(  21  )       !==  time varying 2D field  ==!   = F( growth rate of baroclinic instability ) 
     314         !                                             !   min value rn_aht_0 / 10  
     315         !                                             !   max value rn_aht_0 (rn_aeiv_0 if nn_aei_ijk_t=21) 
     316         !                                             !   increase to rn_aht_0 within 20N-20S 
     317         IF( nn_aei_ijk_t /= 21 ) THEN 
     318            CALL ldf_eiv( kt, rn_aht_0, ahtu, ahtv ) 
     319            IF(lwp .AND. kt<=nit000+20 )   WRITE(numout,*) ' kt , ldf_eiv appel  2', kt 
     320         ELSE 
     321            ahtu(:,:,1) = aeiu(:,:,1) 
     322            ahtv(:,:,1) = aeiv(:,:,1) 
     323            IF(lwp .AND. kt<=nit000+20 )   WRITE(numout,*) ' kt , ahtu=aeiu', kt 
     324         ENDIF 
     325         ! 
     326         z1_f20   = 1._wp / (  2._wp * omega * SIN( rad * 20._wp )  )      ! 1 / ff(20 degrees)    
     327         zaht_min = 0.2_wp * rn_aht_0                                      ! minimum value for aht 
     328         DO jj = 1, jpj 
     329            DO ji = 1, jpi 
     330               zaht = ( 1._wp -  MIN( 1._wp , ABS( ff(ji,jj) * z1_f20 ) ) ) * ( rn_aht_0 - zaht_min ) 
     331               ahtu(ji,jj,1) = (  MAX( zaht_min, ahtu(ji,jj,1) ) + zaht  ) * umask(ji,jj,1)     ! min value zaht_min 
     332               ahtv(ji,jj,1) = (  MAX( zaht_min, ahtv(ji,jj,1) ) + zaht  ) * vmask(ji,jj,1)     ! increase within 20S-20N 
     333            END DO 
     334         END DO 
     335         DO jk = 2, jpkm1                             ! deeper value = surface value 
     336            ahtu(:,:,jk) = ahtu(:,:,1) * umask(:,:,jk) 
     337            ahtv(:,:,jk) = ahtv(:,:,1) * vmask(:,:,jk) 
     338         END DO 
     339         ! 
     340      CASE(  31  )       !==  time varying 3D field  ==!   = F( local velocity ) 
     341         IF( ln_traldf_lap     ) THEN          !   laplacian operator |u| e /12 
     342            DO jk = 1, jpkm1 
     343               ahtu(:,:,jk) = ABS( ub(:,:,jk) ) * e1u(:,:) * r1_12 
     344               ahtv(:,:,jk) = ABS( vb(:,:,jk) ) * e2v(:,:) * r1_12 
     345            END DO 
     346         ELSEIF( ln_traldf_blp ) THEN      ! bilaplacian operator      sqrt( |u| e^3 /12 ) = sqrt( |u| e /12 ) * e 
     347            DO jk = 1, jpkm1 
     348               ahtu(:,:,jk) = SQRT(  ABS( ub(:,:,jk) ) * e1u(:,:) * r1_12  ) * e1u(:,:) 
     349               ahtv(:,:,jk) = SQRT(  ABS( vb(:,:,jk) ) * e2v(:,:) * r1_12  ) * e2v(:,:) 
     350            END DO 
     351         ENDIF 
     352         ! 
     353      END SELECT 
     354      ! 
     355      IF( .NOT.lk_offline ) THEN 
     356         CALL iom_put( "ahtu_2d", ahtu(:,:,1) )   ! surface u-eddy diffusivity coeff. 
     357         CALL iom_put( "ahtv_2d", ahtv(:,:,1) )   ! surface v-eddy diffusivity coeff. 
     358         CALL iom_put( "ahtu_3d", ahtu(:,:,:) )   ! 3D      u-eddy diffusivity coeff. 
     359         CALL iom_put( "ahtv_3d", ahtv(:,:,:) )   ! 3D      v-eddy diffusivity coeff. 
     360         ! 
     361!!gm  : THE IF below is to be checked (comes from Seb) 
     362         IF( ln_ldfeiv ) THEN 
     363           CALL iom_put( "aeiu_2d", aeiu(:,:,1) )   ! surface u-EIV coeff. 
     364           CALL iom_put( "aeiv_2d", aeiv(:,:,1) )   ! surface v-EIV coeff. 
     365           CALL iom_put( "aeiu_3d", aeiu(:,:,:) )   ! 3D      u-EIV coeff. 
     366           CALL iom_put( "aeiv_3d", aeiv(:,:,:) )   ! 3D      v-EIV coeff. 
     367         ENDIF      
     368      ENDIF 
     369      ! 
     370   END SUBROUTINE ldf_tra 
     371 
     372 
     373   SUBROUTINE ldf_eiv_init 
     374      !!---------------------------------------------------------------------- 
     375      !!                  ***  ROUTINE ldf_eiv_init  *** 
     376      !! 
     377      !! ** Purpose :   initialization of the eiv coeff. from namelist choices. 
     378      !! 
     379      !! ** Method : 
     380      !! 
     381      !! ** Action :   aeiu , aeiv   : EIV coeff. at u- & v-points 
     382      !!               l_ldfeiv_time : =T if EIV coefficients vary with time 
     383      !!---------------------------------------------------------------------- 
     384      INTEGER  ::   jk                ! dummy loop indices 
     385      INTEGER  ::   ierr, inum, ios   ! local integer 
     386      ! 
     387      NAMELIST/namtra_ldfeiv/ ln_ldfeiv   , ln_ldfeiv_dia,   &    ! eddy induced velocity (eiv) 
     388         &                    nn_aei_ijk_t, rn_aeiv_0             ! eiv  coefficient 
     389      !!---------------------------------------------------------------------- 
     390      ! 
     391      REWIND( numnam_ref )              ! Namelist namtra_ldfeiv in reference namelist : eddy induced velocity param. 
     392      READ  ( numnam_ref, namtra_ldfeiv, IOSTAT = ios, ERR = 901) 
     393901   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namtra_ldfeiv in reference namelist', lwp ) 
     394      ! 
     395      REWIND( numnam_cfg )              ! Namelist namtra_ldfeiv in configuration namelist : eddy induced velocity param. 
     396      READ  ( numnam_cfg, namtra_ldfeiv, IOSTAT = ios, ERR = 902 ) 
     397902   IF( ios /= 0 ) CALL ctl_nam ( ios , 'namtra_ldfeiv in configuration namelist', lwp ) 
     398      IF(lwm)  WRITE ( numond, namtra_ldfeiv ) 
     399 
     400      IF(lwp) THEN                      ! control print 
    107401         WRITE(numout,*) 
    108       ENDIF 
    109  
    110       !                                ! convert DOCTOR namelist names into OLD names 
    111       aht0  = rn_aht_0 
    112       ahtb0 = rn_ahtb_0 
    113       aeiv0 = rn_aeiv_0 
    114  
    115       !                                ! Parameter control 
    116  
    117       ! ... Check consistency for type and direction : 
    118       !           ==> will be done in traldf module 
    119  
    120       ! ... Space variation of eddy coefficients 
    121       ioptio = 0 
    122 #if defined key_traldf_c3d 
    123       IF(lwp) WRITE(numout,*) '          tracer mixing coef. = F( latitude, longitude, depth)' 
    124       ioptio = ioptio + 1 
    125 #endif 
    126 #if defined key_traldf_c2d 
    127       IF(lwp) WRITE(numout,*) '          tracer mixing coef. = F( latitude, longitude)' 
    128       ioptio = ioptio + 1 
    129 #endif 
    130 #if defined key_traldf_c1d 
    131       IF(lwp) WRITE(numout,*) '          tracer mixing coef. = F( depth )' 
    132       ioptio = ioptio + 1 
    133       IF( .NOT. ln_zco )   CALL ctl_stop( 'key_traldf_c1d can only be used in z-coordinate - full step' ) 
    134 #endif 
    135       IF( ioptio == 0 ) THEN 
    136           IF(lwp) WRITE(numout,*) '          tracer mixing coef. = constant (default option)' 
    137         ELSEIF( ioptio > 1 ) THEN 
    138            CALL ctl_stop('          use only one of the following keys:',   & 
    139              &           ' key_traldf_c3d, key_traldf_c2d, key_traldf_c1d' ) 
    140       ENDIF 
    141  
    142       IF( ln_traldf_bilap ) THEN 
    143          IF(lwp) WRITE(numout,*) '          biharmonic tracer diffusion' 
    144          IF( aht0 > 0 .AND. .NOT. lk_esopa )   CALL ctl_stop( 'The horizontal diffusivity coef. aht0 must be negative' ) 
     402         WRITE(numout,*) 'ldf_eiv_init : eddy induced velocity parametrization' 
     403         WRITE(numout,*) '~~~~~~~~~~~~ ' 
     404         WRITE(numout,*) '   Namelist namtra_ldfeiv : ' 
     405         WRITE(numout,*) '      Eddy Induced Velocity (eiv) param.      ln_ldfeiv     = ', ln_ldfeiv 
     406         WRITE(numout,*) '      eiv streamfunction & velocity diag.     ln_ldfeiv_dia = ', ln_ldfeiv_dia 
     407         WRITE(numout,*) '      eddy induced velocity coef.             rn_aeiv_0     = ', rn_aeiv_0 
     408         WRITE(numout,*) '      type of time-space variation            nn_aei_ijk_t  = ', nn_aei_ijk_t 
     409         WRITE(numout,*) 
     410      ENDIF 
     411      ! 
     412      IF( ln_ldfeiv .AND. ln_traldf_blp )   CALL ctl_stop( 'ldf_eiv_init: eddy induced velocity ONLY with laplacian diffusivity' ) 
     413 
     414      !                                 ! Parameter control 
     415      l_ldfeiv_time = .FALSE.     
     416      ! 
     417      IF( ln_ldfeiv ) THEN                         ! allocate the aei arrays 
     418         ALLOCATE( aeiu(jpi,jpj,jpk), aeiv(jpi,jpj,jpk), STAT=ierr ) 
     419         IF( ierr /= 0 )   CALL ctl_stop('STOP', 'ldf_eiv: failed to allocate arrays') 
     420         ! 
     421         SELECT CASE( nn_aei_ijk_t )               ! Specification of space time variations of eaiu, aeiv 
     422         ! 
     423         CASE(   0  )      !==  constant  ==! 
     424            IF(lwp) WRITE(numout,*) '          eddy induced velocity coef. = constant = ', rn_aeiv_0 
     425            aeiu(:,:,:) = rn_aeiv_0 
     426            aeiv(:,:,:) = rn_aeiv_0 
     427            ! 
     428         CASE(  10  )      !==  fixed profile  ==! 
     429            IF(lwp) WRITE(numout,*) '          eddy induced velocity coef. = F( depth )' 
     430            aeiu(:,:,1) = rn_aeiv_0                                ! constant surface value 
     431            aeiv(:,:,1) = rn_aeiv_0 
     432            CALL ldf_c1d( 'TRA', r1_4, aeiu(:,:,1), aeiv(:,:,1), aeiu, aeiv ) 
     433            ! 
     434         CASE ( -20 )      !== fixed horizontal shape read in file  ==! 
     435            IF(lwp) WRITE(numout,*) '          tracer mixing coef. = F(i,j) read in eddy_diffusivity_2D.nc file' 
     436            CALL iom_open ( 'eddy_induced_velocity_2D.nc', inum ) 
     437            CALL iom_get  ( inum, jpdom_data, 'aeiu', aeiu(:,:,1) ) 
     438            CALL iom_get  ( inum, jpdom_data, 'aeiv', aeiv(:,:,1) ) 
     439            CALL iom_close( inum ) 
     440            DO jk = 2, jpk 
     441               aeiu(:,:,jk) = aeiu(:,:,1) 
     442               aeiv(:,:,jk) = aeiv(:,:,1) 
     443            END DO 
     444            ! 
     445         CASE(  20  )      !== fixed horizontal shape  ==! 
     446            IF(lwp) WRITE(numout,*) '          tracer mixing coef. = F( e1, e2 ) or F( e1^3, e2^3 ) (lap or bilap case)' 
     447            CALL ldf_c2d( 'TRA', 'LAP', rn_aeiv_0, aeiu, aeiv )    ! surface value proportional to scale factor 
     448            ! 
     449         CASE(  21  )       !==  time varying 2D field  ==! 
     450            IF(lwp) WRITE(numout,*) '          tracer mixing coef. = F( latitude, longitude, time )' 
     451            IF(lwp) WRITE(numout,*) '                              = F( growth rate of baroclinic instability )' 
     452            ! 
     453            l_ldfeiv_time = .TRUE.     ! will be calculated by call to ldf_tra routine in step.F90 
     454            ! 
     455         CASE( -30  )      !== fixed 3D shape read in file  ==! 
     456            IF(lwp) WRITE(numout,*) '          tracer mixing coef. = F(i,j,k) read in eddy_diffusivity_3D.nc file' 
     457            CALL iom_open ( 'eddy_induced_velocity_3D.nc', inum ) 
     458            CALL iom_get  ( inum, jpdom_data, 'aeiu', aeiu ) 
     459            CALL iom_get  ( inum, jpdom_data, 'aeiv', aeiv ) 
     460            CALL iom_close( inum ) 
     461            ! 
     462         CASE(  30  )       !==  fixed 3D shape  ==! 
     463            IF(lwp) WRITE(numout,*) '          tracer mixing coef. = F( latitude, longitude, depth )' 
     464            CALL ldf_c2d( 'TRA', 'LAP', rn_aeiv_0, aeiu, aeiv )    ! surface value proportional to scale factor 
     465            !                                                 ! reduction with depth 
     466            CALL ldf_c1d( 'TRA', r1_4, aeiu(:,:,1), aeiv(:,:,1), aeiu, aeiv ) 
     467            ! 
     468         CASE DEFAULT 
     469            CALL ctl_stop('ldf_tra_init: wrong choice for nn_aei_ijk_t, the type of space-time variation of aei') 
     470         END SELECT 
     471         ! 
    145472      ELSE 
    146          IF(lwp) WRITE(numout,*) '          harmonic tracer diffusion (default)' 
    147          IF( aht0 < 0 .AND. .NOT. lk_esopa )   CALL ctl_stop('The horizontal diffusivity coef. aht0 must be positive' ) 
    148       ENDIF 
    149  
    150  
    151       !  Lateral eddy diffusivity and eddy induced velocity coefficients 
    152       ! ================================================================ 
    153 #if defined key_traldf_c3d 
    154       CALL ldf_tra_c3d( ll_print )      ! aht = 3D coef. = F( longitude, latitude, depth ) 
    155 #elif defined key_traldf_c2d 
    156       CALL ldf_tra_c2d( ll_print )      ! aht = 2D coef. = F( longitude, latitude ) 
    157 #elif defined key_traldf_c1d 
    158       CALL ldf_tra_c1d( ll_print )      ! aht = 1D coef. = F( depth ) 
    159 #else 
    160                                         ! Constant coefficients 
    161       IF(lwp)WRITE(numout,*) 
    162       IF(lwp)WRITE(numout,*) '      constant eddy diffusivity coef.   ahtu = ahtv = ahtw = aht0 = ', aht0 
    163       IF( lk_traldf_eiv ) THEN 
    164          IF(lwp)WRITE(numout,*) '      constant eddy induced velocity coef.   aeiu = aeiv = aeiw = aeiv0 = ', aeiv0 
     473          IF(lwp) WRITE(numout,*) '   eddy induced velocity param is NOT used neither diagnosed' 
     474          ln_ldfeiv_dia = .FALSE. 
     475      ENDIF 
     476      !                     
     477   END SUBROUTINE ldf_eiv_init 
     478 
     479 
     480   SUBROUTINE ldf_eiv( kt, paei0, paeiu, paeiv ) 
     481      !!---------------------------------------------------------------------- 
     482      !!                  ***  ROUTINE ldf_eiv  *** 
     483      !! 
     484      !! ** Purpose :   Compute the eddy induced velocity coefficient from the 
     485      !!              growth rate of baroclinic instability. 
     486      !! 
     487      !! ** Method  :   coefficient function of the growth rate of baroclinic instability 
     488      !! 
     489      !! Reference : Treguier et al. JPO 1997   ; Held and Larichev JAS 1996 
     490      !!---------------------------------------------------------------------- 
     491      INTEGER                         , INTENT(in   ) ::   kt             ! ocean time-step index 
     492      REAL(wp)                        , INTENT(inout) ::   paei0          ! max value            [m2/s] 
     493      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   paeiu, paeiv   ! eiv coefficient      [m2/s] 
     494      ! 
     495      INTEGER  ::   ji, jj, jk    ! dummy loop indices 
     496      REAL(wp) ::   zfw, ze3w, zn2, z1_f20, zaht, zaht_min, zzaei   ! local scalars 
     497      REAL(wp), DIMENSION(:,:), POINTER ::   zn, zah, zhw, zross, zaeiw   ! 2D workspace 
     498      !!---------------------------------------------------------------------- 
     499      ! 
     500      IF( nn_timing == 1 )   CALL timing_start('ldf_eiv') 
     501      ! 
     502      CALL wrk_alloc( jpi,jpj,   zn, zah, zhw, zross, zaeiw ) 
     503      !       
     504      zn   (:,:) = 0._wp      ! Local initialization 
     505      zhw  (:,:) = 5._wp 
     506      zah  (:,:) = 0._wp 
     507      zross(:,:) = 0._wp 
     508      !                       ! Compute lateral diffusive coefficient at T-point 
     509      IF( ln_traldf_triad ) THEN 
     510         DO jk = 1, jpk 
     511            DO jj = 2, jpjm1 
     512               DO ji = 2, jpim1 
     513                  ! Take the max of N^2 and zero then take the vertical sum  
     514                  ! of the square root of the resulting N^2 ( required to compute  
     515                  ! internal Rossby radius Ro = .5 * sum_jpk(N) / f  
     516                  zn2 = MAX( rn2b(ji,jj,jk), 0._wp ) 
     517                  zn(ji,jj) = zn(ji,jj) + SQRT( zn2 ) * fse3w(ji,jj,jk) 
     518                  ! Compute elements required for the inverse time scale of baroclinic 
     519                  ! eddies using the isopycnal slopes calculated in ldfslp.F :  
     520                  ! T^-1 = sqrt(m_jpk(N^2*(r1^2+r2^2)*e3w)) 
     521                  ze3w = fse3w(ji,jj,jk) * tmask(ji,jj,jk) 
     522                  zah(ji,jj) = zah(ji,jj) + zn2 * wslp2(ji,jj,jk) * ze3w 
     523                  zhw(ji,jj) = zhw(ji,jj) + ze3w 
     524               END DO 
     525            END DO 
     526         END DO 
     527      ELSE 
     528         DO jk = 1, jpk 
     529            DO jj = 2, jpjm1 
     530               DO ji = 2, jpim1 
     531                  ! Take the max of N^2 and zero then take the vertical sum  
     532                  ! of the square root of the resulting N^2 ( required to compute  
     533                  ! internal Rossby radius Ro = .5 * sum_jpk(N) / f  
     534                  zn2 = MAX( rn2b(ji,jj,jk), 0._wp ) 
     535                  zn(ji,jj) = zn(ji,jj) + SQRT( zn2 ) * fse3w(ji,jj,jk) 
     536                  ! Compute elements required for the inverse time scale of baroclinic 
     537                  ! eddies using the isopycnal slopes calculated in ldfslp.F :  
     538                  ! T^-1 = sqrt(m_jpk(N^2*(r1^2+r2^2)*e3w)) 
     539                  ze3w = fse3w(ji,jj,jk) * tmask(ji,jj,jk) 
     540                  zah(ji,jj) = zah(ji,jj) + zn2 * ( wslpi(ji,jj,jk) * wslpi(ji,jj,jk)   & 
     541                     &                            + wslpj(ji,jj,jk) * wslpj(ji,jj,jk) ) * ze3w 
     542                  zhw(ji,jj) = zhw(ji,jj) + ze3w 
     543               END DO 
     544            END DO 
     545         END DO 
     546      END IF 
     547 
     548      DO jj = 2, jpjm1 
     549         DO ji = fs_2, fs_jpim1   ! vector opt. 
     550            zfw = MAX( ABS( 2. * omega * SIN( rad * gphit(ji,jj) ) ) , 1.e-10 ) 
     551            ! Rossby radius at w-point taken < 40km and  > 2km 
     552            zross(ji,jj) = MAX( MIN( .4 * zn(ji,jj) / zfw, 40.e3 ), 2.e3 ) 
     553            ! Compute aeiw by multiplying Ro^2 and T^-1 
     554            zaeiw(ji,jj) = zross(ji,jj) * zross(ji,jj) * SQRT( zah(ji,jj) / zhw(ji,jj) ) * tmask(ji,jj,1) 
     555         END DO 
     556      END DO 
     557 
     558!!gm      IF( cp_cfg == "orca" .AND. jp_cfg == 2 ) THEN   ! ORCA R2 
     559!!gm         DO jj = 2, jpjm1 
     560!!gm            DO ji = fs_2, fs_jpim1   ! vector opt. 
     561!!gm               ! Take the minimum between aeiw and 1000 m2/s over shelves (depth shallower than 650 m) 
     562!!gm               IF( mbkt(ji,jj) <= 20 )   zaeiw(ji,jj) = MIN( zaeiw(ji,jj), 1000. ) 
     563!!gm            END DO 
     564!!gm         END DO 
     565!!gm      ENDIF 
     566 
     567      !                                         !==  Bound on eiv coeff.  ==! 
     568      z1_f20 = 1._wp / (  2._wp * omega * sin( rad * 20._wp )  ) 
     569      DO jj = 2, jpjm1 
     570         DO ji = fs_2, fs_jpim1   ! vector opt. 
     571            zzaei = MIN( 1._wp, ABS( ff(ji,jj) * z1_f20 ) ) * zaeiw(ji,jj)       ! tropical decrease 
     572            zaeiw(ji,jj) = MIN( zzaei , paei0 )                                  ! Max value = paei0 
     573         END DO 
     574      END DO 
     575      CALL lbc_lnk( zaeiw(:,:), 'W', 1. )       ! lateral boundary condition 
     576      !                
     577      DO jj = 2, jpjm1                          !== aei at u- and v-points  ==! 
     578         DO ji = fs_2, fs_jpim1   ! vector opt. 
     579            paeiu(ji,jj,1) = 0.5_wp * ( zaeiw(ji,jj) + zaeiw(ji+1,jj  ) ) * umask(ji,jj,1) 
     580            paeiv(ji,jj,1) = 0.5_wp * ( zaeiw(ji,jj) + zaeiw(ji  ,jj+1) ) * vmask(ji,jj,1) 
     581         END DO  
     582      END DO  
     583      CALL lbc_lnk( paeiu(:,:,1), 'U', 1. )   ;   CALL lbc_lnk( paeiv(:,:,1), 'V', 1. )      ! lateral boundary condition 
     584 
     585      DO jk = 2, jpkm1                          !==  deeper values equal the surface one  ==! 
     586         paeiu(:,:,jk) = paeiu(:,:,1) * umask(:,:,jk) 
     587         paeiv(:,:,jk) = paeiv(:,:,1) * vmask(:,:,jk) 
     588      END DO 
     589      !   
     590      CALL wrk_dealloc( jpi,jpj,   zn, zah, zhw, zross, zaeiw ) 
     591      ! 
     592      IF( nn_timing == 1 )   CALL timing_stop('ldf_eiv') 
     593      ! 
     594   END SUBROUTINE ldf_eiv 
     595 
     596 
     597   SUBROUTINE ldf_eiv_trp( kt, kit000, pun, pvn, pwn, cdtype ) 
     598      !!---------------------------------------------------------------------- 
     599      !!                  ***  ROUTINE ldf_eiv_trp  *** 
     600      !!  
     601      !! ** Purpose :   add to the input ocean transport the contribution of  
     602      !!              the eddy induced velocity parametrization. 
     603      !! 
     604      !! ** Method  :   The eddy induced transport is computed from a flux stream- 
     605      !!              function which depends on the slope of iso-neutral surfaces 
     606      !!              (see ldf_slp). For example, in the i-k plan :  
     607      !!                   psi_uw = mk(aeiu) e2u mi(wslpi)   [in m3/s] 
     608      !!                   Utr_eiv = - dk[psi_uw] 
     609      !!                   Vtr_eiv = + di[psi_uw] 
     610      !!                ln_ldfeiv_dia = T : output the associated streamfunction, 
     611      !!                                    velocity and heat transport (call ldf_eiv_dia) 
     612      !! 
     613      !! ** Action  : pun, pvn increased by the eiv transport 
     614      !!---------------------------------------------------------------------- 
     615      INTEGER                         , INTENT(in   ) ::   kt       ! ocean time-step index 
     616      INTEGER                         , INTENT(in   ) ::   kit000   ! first time step index 
     617      CHARACTER(len=3)                , INTENT(in   ) ::   cdtype   ! =TRA or TRC (tracer indicator) 
     618      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   pun      ! in : 3 ocean transport components   [m3/s] 
     619      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   pvn      ! out: 3 ocean transport components   [m3/s] 
     620      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   pwn      ! increased by the eiv                [m3/s] 
     621      !! 
     622      INTEGER  ::   ji, jj, jk                 ! dummy loop indices 
     623      REAL(wp) ::   zuwk, zuwk1, zuwi, zuwi1   ! local scalars 
     624      REAL(wp) ::   zvwk, zvwk1, zvwj, zvwj1   !   -      - 
     625      REAL(wp), POINTER, DIMENSION(:,:,:) ::   zpsi_uw, zpsi_vw 
     626      !!---------------------------------------------------------------------- 
     627      ! 
     628      IF( nn_timing == 1 )   CALL timing_start( 'ldf_eiv_trp') 
     629      ! 
     630      CALL wrk_alloc( jpi,jpj,jpk,   zpsi_uw, zpsi_vw ) 
     631 
     632      IF( kt == kit000 )  THEN 
     633         IF(lwp) WRITE(numout,*) 
     634         IF(lwp) WRITE(numout,*) 'ldf_eiv_trp : eddy induced advection on ', cdtype,' :' 
     635         IF(lwp) WRITE(numout,*) '~~~~~~~~~~~   add to velocity fields the eiv component' 
     636      ENDIF 
     637 
    165638       
    166       ENDIF 
    167 #endif 
    168  
    169 #if defined key_traldf_smag && ! defined key_traldf_c3d 
    170         CALL ctl_stop( 'key_traldf_smag can only be used with key_traldf_c3d' ) 
    171 #endif 
    172 #if defined key_traldf_smag 
    173         IF(lwp) WRITE(numout,*)' SMAGORINSKY DIFFUSION' 
    174         IF(lwp .AND. rn_smsh < 1)  WRITE(numout,*)' only  shear is used ' 
    175         IF(lwp.and.ln_traldf_bilap) CALL ctl_stop(' SMAGORINSKY + BILAPLACIAN - UNSTABLE OR NON_CONSERVATIVE' ) 
    176 #endif 
    177  
    178       ! 
    179    END SUBROUTINE ldf_tra_init 
    180  
    181 #if defined key_traldf_c3d 
    182 #   include "ldftra_c3d.h90" 
    183 #elif defined key_traldf_c2d 
    184 #   include "ldftra_c2d.h90" 
    185 #elif defined key_traldf_c1d 
    186 #   include "ldftra_c1d.h90" 
    187 #endif 
     639      zpsi_uw(:,:, 1 ) = 0._wp   ;   zpsi_vw(:,:, 1 ) = 0._wp 
     640      zpsi_uw(:,:,jpk) = 0._wp   ;   zpsi_vw(:,:,jpk) = 0._wp 
     641      ! 
     642      DO jk = 2, jpkm1 
     643         DO jj = 1, jpjm1 
     644            DO ji = 1, fs_jpim1   ! vector opt. 
     645               zpsi_uw(ji,jj,jk) = - 0.25_wp * e2u(ji,jj) * ( wslpi(ji,jj,jk  ) + wslpi(ji+1,jj,jk) )   & 
     646                  &                                       * ( aeiu (ji,jj,jk-1) + aeiu (ji  ,jj,jk) ) * umask(ji,jj,jk) 
     647               zpsi_vw(ji,jj,jk) = - 0.25_wp * e1v(ji,jj) * ( wslpj(ji,jj,jk  ) + wslpj(ji,jj+1,jk) )   & 
     648                  &                                       * ( aeiv (ji,jj,jk-1) + aeiv (ji,jj  ,jk) ) * vmask(ji,jj,jk) 
     649            END DO 
     650         END DO 
     651      END DO 
     652      ! 
     653      DO jk = 1, jpkm1 
     654         DO jj = 1, jpjm1 
     655            DO ji = 1, fs_jpim1   ! vector opt.                
     656               pun(ji,jj,jk) = pun(ji,jj,jk) - ( zpsi_uw(ji,jj,jk) - zpsi_uw(ji,jj,jk+1) ) 
     657               pvn(ji,jj,jk) = pvn(ji,jj,jk) - ( zpsi_vw(ji,jj,jk) - zpsi_vw(ji,jj,jk+1) ) 
     658            END DO 
     659         END DO 
     660      END DO 
     661      DO jk = 1, jpkm1 
     662         DO jj = 2, jpjm1 
     663            DO ji = fs_2, fs_jpim1   ! vector opt. 
     664               pwn(ji,jj,jk) = pwn(ji,jj,jk) + (  zpsi_uw(ji,jj,jk) - zpsi_uw(ji-1,jj  ,jk)   & 
     665                  &                             + zpsi_vw(ji,jj,jk) - zpsi_vw(ji  ,jj-1,jk) ) 
     666            END DO 
     667         END DO 
     668      END DO 
     669      ! 
     670      !                              ! diagnose the eddy induced velocity and associated heat transport 
     671      IF( ln_ldfeiv_dia .AND. cdtype == 'TRA' )   CALL ldf_eiv_dia( zpsi_uw, zpsi_vw ) 
     672      ! 
     673      CALL wrk_dealloc( jpi,jpj,jpk,   zpsi_uw, zpsi_vw ) 
     674      ! 
     675      IF( nn_timing == 1 )   CALL timing_stop( 'ldf_eiv_trp') 
     676      ! 
     677    END SUBROUTINE ldf_eiv_trp 
     678 
     679 
     680   SUBROUTINE ldf_eiv_dia( psi_uw, psi_vw ) 
     681      !!---------------------------------------------------------------------- 
     682      !!                  ***  ROUTINE ldf_eiv_dia  *** 
     683      !! 
     684      !! ** Purpose :   diagnose the eddy induced velocity and its associated 
     685      !!              vertically integrated heat transport. 
     686      !! 
     687      !! ** Method : 
     688      !! 
     689      !!---------------------------------------------------------------------- 
     690      REAL(wp), DIMENSION(jpi,jpj,jpk), INTENT(inout) ::   psi_uw, psi_vw   ! streamfunction   [m3/s] 
     691      ! 
     692      INTEGER  ::   ji, jj, jk    ! dummy loop indices 
     693      REAL(wp) ::   zztmp   ! local scalar 
     694      REAL(wp), DIMENSION(:,:)  , POINTER ::   zw2d   ! 2D workspace 
     695      REAL(wp), DIMENSION(:,:,:), POINTER ::   zw3d   ! 3D workspace 
     696      !!---------------------------------------------------------------------- 
     697      ! 
     698      IF( nn_timing == 1 )  CALL timing_start( 'ldf_eiv_dia') 
     699      ! 
     700      !                                                  !==  eiv stream function: output  ==! 
     701      CALL lbc_lnk( psi_uw, 'U', -1. )                         ! lateral boundary condition 
     702      CALL lbc_lnk( psi_vw, 'V', -1. ) 
     703      ! 
     704!!gm      CALL iom_put( "psi_eiv_uw", psi_uw )                 ! output 
     705!!gm      CALL iom_put( "psi_eiv_vw", psi_vw ) 
     706      ! 
     707      !                                                  !==  eiv velocities: calculate and output  ==! 
     708      CALL wrk_alloc( jpi,jpj,jpk,   zw3d ) 
     709      ! 
     710      zw3d(:,:,jpk) = 0._wp                                    ! bottom value always 0 
     711      ! 
     712      DO jk = 1, jpkm1                                         ! e2u e3u u_eiv = -dk[psi_uw] 
     713         zw3d(:,:,jk) = ( psi_uw(:,:,jk+1) - psi_uw(:,:,jk) ) / ( e2u(:,:) * fse3u(:,:,jk) ) 
     714      END DO 
     715      CALL iom_put( "uoce_eiv", zw3d ) 
     716      ! 
     717      DO jk = 1, jpkm1                                         ! e1v e3v v_eiv = -dk[psi_vw] 
     718         zw3d(:,:,jk) = ( psi_vw(:,:,jk+1) - psi_vw(:,:,jk) ) / ( e1v(:,:) * fse3v(:,:,jk) ) 
     719      END DO 
     720      CALL iom_put( "voce_eiv", zw3d ) 
     721      ! 
     722      DO jk = 1, jpkm1                                         ! e1 e2 w_eiv = dk[psix] + dk[psix] 
     723         DO jj = 2, jpjm1 
     724            DO ji = fs_2, fs_jpim1  ! vector opt. 
     725               zw3d(ji,jj,jk) = (  psi_vw(ji,jj,jk) - psi_vw(ji  ,jj-1,jk)    & 
     726                  &              + psi_uw(ji,jj,jk) - psi_uw(ji-1,jj  ,jk)  ) / e1e2t(ji,jj) 
     727            END DO 
     728         END DO 
     729      END DO 
     730      CALL lbc_lnk( zw3d, 'T', 1. )      ! lateral boundary condition 
     731      CALL iom_put( "woce_eiv", zw3d ) 
     732      ! 
     733      CALL wrk_dealloc( jpi,jpj,jpk,   zw3d ) 
     734      !       
     735      ! 
     736      IF( lk_diaar5 ) THEN                               !==  eiv heat transport: calculate and output  ==! 
     737         CALL wrk_alloc( jpi,jpj,   zw2d ) 
     738         ! 
     739         zztmp = 0.5_wp * rau0 * rcp  
     740         zw2d(:,:) = 0._wp  
     741         DO jk = 1, jpkm1 
     742            DO jj = 2, jpjm1 
     743               DO ji = fs_2, fs_jpim1   ! vector opt. 
     744                  zw2d(ji,jj) = zw2d(ji,jj) + zztmp * ( psi_uw(ji,jj,jk+1)      - psi_uw(ji,jj,jk)          )   & 
     745                     &                              * ( tsn   (ji,jj,jk,jp_tem) + tsn   (ji+1,jj,jk,jp_tem) )  
     746               END DO 
     747            END DO 
     748         END DO 
     749         CALL lbc_lnk( zw2d, 'U', -1. ) 
     750         CALL iom_put( "ueiv_heattr", zw2d )                  ! heat transport in i-direction 
     751         zw2d(:,:) = 0._wp  
     752         DO jk = 1, jpkm1 
     753            DO jj = 2, jpjm1 
     754               DO ji = fs_2, fs_jpim1   ! vector opt. 
     755                  zw2d(ji,jj) = zw2d(ji,jj) + zztmp * ( psi_vw(ji,jj,jk+1)      - psi_vw(ji,jj,jk)          )   & 
     756                     &                              * ( tsn   (ji,jj,jk,jp_tem) + tsn   (ji,jj+1,jk,jp_tem) )  
     757               END DO 
     758            END DO 
     759         END DO 
     760         CALL lbc_lnk( zw2d, 'V', -1. ) 
     761         CALL iom_put( "veiv_heattr", zw2d )                  !  heat transport in i-direction 
     762         ! 
     763         CALL wrk_dealloc( jpi,jpj,   zw2d ) 
     764      ENDIF 
     765      ! 
     766      IF( nn_timing == 1 )  CALL timing_stop( 'ldf_eiv_dia')       
     767      ! 
     768   END SUBROUTINE ldf_eiv_dia 
    188769 
    189770   !!====================================================================== 
Note: See TracChangeset for help on using the changeset viewer.