Index: branches/2013/dev_MERGE_2013/NEMOGCM/CONFIG/SHARED/namelist_ref
===================================================================
--- branches/2013/dev_MERGE_2013/NEMOGCM/CONFIG/SHARED/namelist_ref	(revision 4379)
+++ branches/2013/dev_MERGE_2013/NEMOGCM/CONFIG/SHARED/namelist_ref	(revision 4381)
@@ -603,7 +603,9 @@
                            !                              = 2 : nonlinear friction
    rn_bfri1    =    4.e-4  !  bottom drag coefficient (linear case)
-   rn_bfri2    =    1.e-3  !  bottom drag coefficient (non linear case)
+   rn_bfri2    =    1.e-3  !  bottom drag coefficient (non linear case). Minimum coeft if ln_loglayer=T
+   rn_bfri2_max =   1.e-1  !  max. bottom drag coefficient (non linear case and ln_loglayer=T)
    rn_bfeb2    =    2.5e-3 !  bottom turbulent kinetic energy background  (m2/s2)
-   rn_bfrz0    =    3.e-3  ! bottom roughness for loglayer bfr coeff 
+   rn_bfrz0    =    3.e-3  !  bottom roughness [m] if ln_loglayer=T 
+   ln_loglayer = .false.   !  logarithmic formulation (non linear case)
    ln_bfr2d    = .false.   !  horizontal variation of the bottom friction coef (read a 2D mask file )
    rn_bfrien   =    50.    !  local multiplying factor of bfr (ln_bfr2d=T)
Index: branches/2013/dev_MERGE_2013/NEMOGCM/NEMO/OPA_SRC/ZDF/zdfbfr.F90
===================================================================
--- branches/2013/dev_MERGE_2013/NEMOGCM/NEMO/OPA_SRC/ZDF/zdfbfr.F90	(revision 4379)
+++ branches/2013/dev_MERGE_2013/NEMOGCM/NEMO/OPA_SRC/ZDF/zdfbfr.F90	(revision 4381)
@@ -13,7 +13,6 @@
 
    !!----------------------------------------------------------------------
-   !!   zdf_bfr      : update momentum Kz at the ocean bottom due to the type of bottom friction chosen
+   !!   zdf_bfr      : update bottom friction coefficient (non-linear bottom friction only)
    !!   zdf_bfr_init : read in namelist and control the bottom friction parameters.
-   !!   zdf_bfr_2d   : read in namelist and control the bottom friction parameters.
    !!----------------------------------------------------------------------
    USE oce             ! ocean dynamics and tracers variables
@@ -25,5 +24,5 @@
    USE prtctl          ! Print control
    USE timing          ! Timing
-
+   USE wrk_nemo        ! Memory Allocation
    USE phycst, ONLY: vkarmn
 
@@ -32,5 +31,5 @@
 
    PUBLIC   zdf_bfr         ! called by step.F90
-   PUBLIC   zdf_bfr_init    ! called by opa.F90
+   PUBLIC   zdf_bfr_init    ! called by nemogcm.F90
 
    !                                 !!* Namelist nambfr: bottom friction namelist *
@@ -38,4 +37,5 @@
    REAL(wp), PUBLIC ::   rn_bfri1     ! bottom drag coefficient (linear case)  (PUBLIC for TAM)
    REAL(wp), PUBLIC ::   rn_bfri2     ! bottom drag coefficient (non linear case) (PUBLIC for TAM)
+   REAL(wp), PUBLIC ::   rn_bfri2_max ! Maximum bottom drag coefficient (non linear case and ln_loglayer=T) (PUBLIC for TAM)
    REAL(wp), PUBLIC ::   rn_bfeb2     ! background bottom turbulent kinetic energy  [m2/s2] (PUBLIC for TAM)
    REAL(wp), PUBLIC ::   rn_bfrien    ! local factor to enhance coefficient bfri (PUBLIC for TAM)
@@ -43,5 +43,5 @@
    LOGICAL , PUBLIC ::   ln_loglayer  ! switch for log layer bfr coeff. (PUBLIC for TAM)
    REAL(wp), PUBLIC ::   rn_bfrz0     ! bottom roughness for loglayer bfr coeff (PUBLIC for TAM)
-   LOGICAL , PUBLIC ::  ln_bfrimp     ! logical switch for implicit bottom friction
+   LOGICAL , PUBLIC ::   ln_bfrimp    ! logical switch for implicit bottom friction
    REAL(wp), ALLOCATABLE, SAVE, DIMENSION(:,:), PUBLIC ::  bfrcoef2d            ! 2D bottom drag coefficient (PUBLIC for TAM)
 
@@ -86,41 +86,43 @@
       !!
       INTEGER  ::   ji, jj                       ! dummy loop indices
-      INTEGER  ::   ikbu, ikbv                   ! local integers
-      REAL(wp) ::   zvu, zuv, zecu, zecv         ! temporary scalars
-      REAL(wp) ::   ztmp, ztmp1                  ! temporary scalars
+      INTEGER  ::   ikbt, ikbu, ikbv             ! local integers
+      REAL(wp) ::   zvu, zuv, zecu, zecv, ztmp   ! temporary scalars
+      REAL(wp), POINTER, DIMENSION(:,:) ::  zbfrt
       !!----------------------------------------------------------------------
       !
       IF( nn_timing == 1 )  CALL timing_start('zdf_bfr')
       !
-      IF( nn_bfr == 2 ) THEN                 ! quadratic botton friction
-         ! Calculate and store the quadratic bottom friction coefficient bfrua and bfrva
-         ! where bfrUa = C_d*SQRT(u_bot^2 + v_bot^2 + e_b) {U=[u,v]}
-         ! from these the trend due to bottom friction:  -F_h/e3U  can be calculated
-         ! where -F_h/e3U_bot = bfrUa*Ub/e3U_bot {U=[u,v]}
-         !
-
-         IF(ln_loglayer) THEN       ! "log layer" bottom friction coefficient
-
-           ! add 2D-enhancement bottom friction
-           ztmp1 = 1._wp
-           IF(ABS(rn_bfri2) >= 1.e-10 ) THEN
-             ztmp1 = 1._wp / rn_bfri2
-           ELSE
-             CALL ctl_stop( 'rn_bfri2 must not be less than 1.e-10')
-           END IF
+      IF( kt == nit000 .AND. lwp ) THEN
+         WRITE(numout,*)
+         WRITE(numout,*) 'zdf_bfr : Set bottom friction coefficient (non-linear case)'
+         WRITE(numout,*) '~~~~~~~~'
+      ENDIF
+      !
+      IF( nn_bfr == 2 ) THEN                 ! quadratic bottom friction only
+         !
+         CALL wrk_alloc( jpi, jpj, zbfrt )
+
+         IF ( ln_loglayer.AND.lk_vvl ) THEN ! "log layer" bottom friction coefficient
 
 #  if defined key_vectopt_loop
-           DO jj = 1, 1
-             DO ji = 1, jpij   ! vector opt. (forced unrolling)
+            DO jj = 1, 1
+!CDIR NOVERRCHK
+               DO ji = 1, jpij   ! vector opt. (forced unrolling)
 #  else
-           DO jj = 1, jpj
-             DO ji = 1, jpi
+!CDIR NOVERRCHK
+            DO jj = 1, jpj
+!CDIR NOVERRCHK
+               DO ji = 1, jpi
 #  endif
-                ztmp = 0.5_wp * fse3t(ji,jj,mbkt(ji,jj))
-                ztmp = max(ztmp, rn_bfrz0 + 1.e-10)
-                bfrcoef2d(ji,jj) = bfrcoef2d(ji,jj) * ztmp1 * &
-                                 & ( log( ztmp / rn_bfrz0 ) / vkarmn ) ** (-2)
-             END DO
-           END DO
+                  ikbt = mbkt(ji,jj)
+! JC: possible WAD implementation should modify line below if layers vanish
+                  ztmp = tmask(ji,jj,ikbt) * ( vkarmn / LOG( 0.5_wp * fse3t_n(ji,jj,ikbt) / rn_bfrz0 ))**2._wp
+                  zbfrt(ji,jj) = MAX(bfrcoef2d(ji,jj), ztmp)
+                  zbfrt(ji,jj) = MIN(zbfrt(ji,jj), rn_bfri2_max)
+               END DO
+            END DO
+         !   
+         ELSE
+            zbfrt(:,:) = bfrcoef2d(:,:)
          ENDIF
 
@@ -146,6 +148,6 @@
                zecv = SQRT(  vn(ji,jj,ikbv) * vn(ji,jj,ikbv) + zuv*zuv + rn_bfeb2  )
                !
-               bfrua(ji,jj) = - 0.5_wp * ( bfrcoef2d(ji,jj) + bfrcoef2d(ji+1,jj  ) ) * zecu
-               bfrva(ji,jj) = - 0.5_wp * ( bfrcoef2d(ji,jj) + bfrcoef2d(ji  ,jj+1) ) * zecv
+               bfrua(ji,jj) = - 0.5_wp * ( zbfrt(ji,jj) + zbfrt(ji+1,jj  ) ) * zecu
+               bfrva(ji,jj) = - 0.5_wp * ( zbfrt(ji,jj) + zbfrt(ji  ,jj+1) ) * zecv
             END DO
          END DO
@@ -156,6 +158,6 @@
          IF(ln_ctl)   CALL prt_ctl( tab2d_1=bfrua, clinfo1=' bfr  - u: ', mask1=umask,        &
             &                       tab2d_2=bfrva, clinfo2=       ' v: ', mask2=vmask,ovlap=1 )
-      ENDIF
-
+         CALL wrk_dealloc( jpi,jpj,zbfrt )
+      ENDIF
       !
       IF( nn_timing == 1 )  CALL timing_stop('zdf_bfr')
@@ -170,6 +172,6 @@
       !! ** Purpose :   Initialization of the bottom friction
       !!
-      !! ** Method  :   Read the nammbf namelist and check their consistency
-      !!              called at the first timestep (nit000)
+      !! ** Method  :   Read the nambfr namelist and check their consistency
+      !!                called at the first timestep (nit000)
       !!----------------------------------------------------------------------
       USE iom   ! I/O module for ehanced bottom friction file
@@ -177,15 +179,20 @@
       INTEGER   ::   inum         ! logical unit for enhanced bottom friction file
       INTEGER   ::   ji, jj       ! dummy loop indexes
-      INTEGER   ::   ikbu, ikbv   ! temporary integers
-      INTEGER   ::   ictu, ictv   !    -          -
+      INTEGER   ::   ikbt, ikbu, ikbv   ! temporary integers
+      INTEGER   ::   ictu, ictv         !    -          -
       INTEGER   ::   ios
       REAL(wp)  ::   zminbfr, zmaxbfr   ! temporary scalars
-      REAL(wp)  ::   zfru, zfrv         !    -         -
-      !!
-      NAMELIST/nambfr/ nn_bfr, rn_bfri1, rn_bfri2, rn_bfeb2, rn_bfrz0, ln_bfr2d, &
+      REAL(wp)  ::   ztmp, zfru, zfrv   !    -         -
+      !!
+      NAMELIST/nambfr/ nn_bfr, rn_bfri1, rn_bfri2, rn_bfri2_max, rn_bfeb2, rn_bfrz0, ln_bfr2d, &
                     &  rn_bfrien, ln_bfrimp, ln_loglayer
       !!----------------------------------------------------------------------
       !
       IF( nn_timing == 1 )  CALL timing_start('zdf_bfr_init')
+      !
+      !                              !* Allocate zdfbfr arrays
+      IF( zdf_bfr_alloc() /= 0 )   CALL ctl_stop( 'STOP', 'zdf_bfr_init : unable to allocate arrays' )
+      !
+      !                              !* Parameter control and print
       !
       REWIND( numnam_ref )              ! Namelist nambfr in reference namelist : Bottom momentum boundary condition
@@ -197,14 +204,91 @@
 902   IF( ios /= 0 ) CALL ctl_nam ( ios , 'nambfr in configuration namelist', lwp )
       WRITE ( numond, nambfr )
-
-      !                               !* Parameter control and print
       IF(lwp) WRITE(numout,*)
-      IF(lwp) WRITE(numout,*) 'zdf_bfr : momentum bottom friction'
-      IF(lwp) WRITE(numout,*) '~~~~~~~'
+      IF(lwp) WRITE(numout,*) 'zdf_bfr_init : momentum bottom friction'
+      IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~~'
       IF(lwp) WRITE(numout,*) '   Namelist nam_bfr : set bottom friction parameters'
-
-      !                              ! allocate zdfbfr arrays
-      IF( zdf_bfr_alloc() /= 0 )   CALL ctl_stop( 'STOP', 'zdf_bfr_init : unable to allocate arrays' )
-
+      !
+      SELECT CASE (nn_bfr)
+      !
+      CASE( 0 )
+         IF(lwp) WRITE(numout,*) '      free-slip '
+         bfrua(:,:) = 0.e0
+         bfrva(:,:) = 0.e0
+         !
+      CASE( 1 )
+         IF(lwp) WRITE(numout,*) '      linear botton friction'
+         IF(lwp) WRITE(numout,*) '      friction coef.   rn_bfri1  = ', rn_bfri1
+         IF( ln_bfr2d ) THEN
+            IF(lwp) WRITE(numout,*) '      read coef. enhancement distribution from file   ln_bfr2d  = ', ln_bfr2d
+            IF(lwp) WRITE(numout,*) '      coef rn_bfri2 enhancement factor                rn_bfrien  = ',rn_bfrien
+         ENDIF
+         !
+         IF(ln_bfr2d) THEN
+            ! bfr_coef is a coefficient in [0,1] giving the mask where to apply the bfr enhancement
+            CALL iom_open('bfr_coef.nc',inum)
+            CALL iom_get (inum, jpdom_data, 'bfr_coef',bfrcoef2d,1) ! bfrcoef2d is used as tmp array
+            CALL iom_close(inum)
+            bfrcoef2d(:,:) = rn_bfri1 * ( 1 + rn_bfrien * bfrcoef2d(:,:) )
+         ELSE
+            bfrcoef2d(:,:) = rn_bfri1  ! initialize bfrcoef2d to the namelist variable
+         ENDIF
+         !
+         bfrua(:,:) = - bfrcoef2d(:,:)
+         bfrva(:,:) = - bfrcoef2d(:,:)
+         !
+      CASE( 2 )
+         IF(lwp) WRITE(numout,*) '      quadratic bottom friction'
+         IF(lwp) WRITE(numout,*) '      friction coef.   rn_bfri2  = ', rn_bfri2
+         IF(lwp) WRITE(numout,*) '      Max. coef. (log case)   rn_bfri2_max  = ', rn_bfri2_max
+         IF(lwp) WRITE(numout,*) '      background tke   rn_bfeb2  = ', rn_bfeb2
+         IF(lwp) WRITE(numout,*) '      log formulation   ln_bfr2d = ', ln_loglayer
+         IF(lwp) WRITE(numout,*) '      bottom roughness  rn_bfrz0 [m] = ', rn_bfrz0
+         IF( rn_bfrz0<=0.e0 ) THEN
+            WRITE(ctmp1,*) '      bottom roughness must be strictly positive'
+            CALL ctl_stop( ctmp1 )
+         ENDIF
+         IF( ln_bfr2d ) THEN
+            IF(lwp) WRITE(numout,*) '      read coef. enhancement distribution from file   ln_bfr2d  = ', ln_bfr2d
+            IF(lwp) WRITE(numout,*) '      coef rn_bfri2 enhancement factor                rn_bfrien  = ',rn_bfrien
+         ENDIF
+         !
+         IF(ln_bfr2d) THEN
+            ! bfr_coef is a coefficient in [0,1] giving the mask where to apply the bfr enhancement
+            CALL iom_open('bfr_coef.nc',inum)
+            CALL iom_get (inum, jpdom_data, 'bfr_coef',bfrcoef2d,1) ! bfrcoef2d is used as tmp array
+            CALL iom_close(inum)
+            !
+            bfrcoef2d(:,:) = rn_bfri2 * ( 1 + rn_bfrien * bfrcoef2d(:,:) )
+         ELSE
+            bfrcoef2d(:,:) = rn_bfri2  ! initialize bfrcoef2d to the namelist variable
+         ENDIF
+         !
+         IF ( ln_loglayer.AND.(.NOT.lk_vvl) ) THEN ! set "log layer" bottom friction once for all
+#  if defined key_vectopt_loop
+            DO jj = 1, 1
+!CDIR NOVERRCHK
+               DO ji = 1, jpij   ! vector opt. (forced unrolling)
+#  else
+!CDIR NOVERRCHK
+            DO jj = 1, jpj
+!CDIR NOVERRCHK
+               DO ji = 1, jpi
+#  endif
+                  ikbt = mbkt(ji,jj)
+                  ztmp = tmask(ji,jj,ikbt) * ( vkarmn / LOG( 0.5_wp * fse3t_n(ji,jj,ikbt) / rn_bfrz0 ))**2._wp
+                  bfrcoef2d(ji,jj) = MAX(bfrcoef2d(ji,jj), ztmp)
+                  bfrcoef2d(ji,jj) = MIN(bfrcoef2d(ji,jj), rn_bfri2_max)
+               END DO
+            END DO
+         ENDIF
+         !
+      CASE DEFAULT
+         IF(lwp) WRITE(ctmp1,*) '         bad flag value for nn_bfr = ', nn_bfr
+         CALL ctl_stop( ctmp1 )
+         !
+      END SELECT
+      !
+      IF(lwp) WRITE(numout,*) '      implicit bottom friction switch                ln_bfrimp  = ', ln_bfrimp
+      !
       !                              ! Make sure ln_zdfexp=.false. when use implicit bfr
       IF( ln_bfrimp .AND. ln_zdfexp ) THEN
@@ -217,70 +301,4 @@
          END IF
       END IF
-
-      SELECT CASE (nn_bfr)
-      !
-      CASE( 0 )
-         IF(lwp) WRITE(numout,*) '      free-slip '
-         bfrua(:,:) = 0.e0
-         bfrva(:,:) = 0.e0
-         !
-      CASE( 1 )
-         IF(lwp) WRITE(numout,*) '      linear botton friction'
-         IF(lwp) WRITE(numout,*) '      friction coef.   rn_bfri1  = ', rn_bfri1
-         IF( ln_bfr2d ) THEN
-            IF(lwp) WRITE(numout,*) '      read coef. enhancement distribution from file   ln_bfr2d  = ', ln_bfr2d
-            IF(lwp) WRITE(numout,*) '      coef rn_bfri2 enhancement factor                rn_bfrien  = ',rn_bfrien
-         ENDIF
-         !
-         bfrcoef2d(:,:) = rn_bfri1  ! initialize bfrcoef2d to the namelist variable
-         !
-         IF(ln_bfr2d) THEN
-            ! bfr_coef is a coefficient in [0,1] giving the mask where to apply the bfr enhancement
-            CALL iom_open('bfr_coef.nc',inum)
-            CALL iom_get (inum, jpdom_data, 'bfr_coef',bfrcoef2d,1) ! bfrcoef2d is used as tmp array
-            CALL iom_close(inum)
-            bfrcoef2d(:,:) = rn_bfri1 * ( 1 + rn_bfrien * bfrcoef2d(:,:) )
-         ENDIF
-         bfrua(:,:) = - bfrcoef2d(:,:)
-         bfrva(:,:) = - bfrcoef2d(:,:)
-         !
-      CASE( 2 )
-         IF(lwp) WRITE(numout,*) '      quadratic botton friction'
-         IF(lwp) WRITE(numout,*) '      friction coef.   rn_bfri2  = ', rn_bfri2
-         IF(lwp) WRITE(numout,*) '      background tke   rn_bfeb2  = ', rn_bfeb2
-         IF( ln_bfr2d ) THEN
-            IF(lwp) WRITE(numout,*) '      read coef. enhancement distribution from file   ln_bfr2d  = ', ln_bfr2d
-            IF(lwp) WRITE(numout,*) '      coef rn_bfri2 enhancement factor                rn_bfrien  = ',rn_bfrien
-         ENDIF
-         bfrcoef2d(:,:) = rn_bfri2  ! initialize bfrcoef2d to the namelist variable
-
-         !
-         IF(ln_bfr2d) THEN
-            ! bfr_coef is a coefficient in [0,1] giving the mask where to apply the bfr enhancement
-            CALL iom_open('bfr_coef.nc',inum)
-            CALL iom_get (inum, jpdom_data, 'bfr_coef',bfrcoef2d,1) ! bfrcoef2d is used as tmp array
-            CALL iom_close(inum)
-            bfrcoef2d(:,:)= rn_bfri2 * ( 1 + rn_bfrien * bfrcoef2d(:,:) )
-         ENDIF
-         !
-      CASE DEFAULT
-         IF(lwp) WRITE(ctmp1,*) '         bad flag value for nn_bfr = ', nn_bfr
-         CALL ctl_stop( ctmp1 )
-         !
-      END SELECT
-
-      IF( nn_bfr /= 2 .AND. ln_loglayer ) THEN
-         IF(lwp) THEN
-            WRITE(numout,*)
-            WRITE(numout,*) 'Loglayer can only be by applied for quadratic bottom friction' 
-            WRITE(numout,*) 'but you have set: nn_bfr /= 2 and ln_loglayer=.true.!!!!'
-            WRITE(ctmp1,*)  'check nn_bfr and ln_loglayer (should be 2 and true)'
-            CALL ctl_stop( ctmp1 )
-         END IF
-      END IF
-
-
-
-      IF(lwp) WRITE(numout,*) '      implicit bottom friction switch                ln_bfrimp  = ', ln_bfrimp
       !
       ! Basic stability check on bottom friction coefficient
