Index: branches/2014/dev_CNRS_2014/NEMOGCM/CONFIG/SHARED/namelist_ref
===================================================================
--- branches/2014/dev_CNRS_2014/NEMOGCM/CONFIG/SHARED/namelist_ref	(revision 4897)
+++ branches/2014/dev_CNRS_2014/NEMOGCM/CONFIG/SHARED/namelist_ref	(revision 4898)
@@ -304,9 +304,7 @@
 
    cn_dir      = './'      !  root directory for the location of the bulk files
-   ln_2m       = .false.   !  air temperature and humidity referenced at 2m (T) instead 10m (F)
    ln_taudif   = .false.   !  HF tau contribution: use "mean of stress module - module of the mean stress" data
-   ln_bulk2z   = .false.   !  Air temperature/humidity and wind vectors are referenced at heights rn_zqt and rn_zu
-   rn_zqt      = 3.        !  Air temperature and humidity reference height (m) (ln_bulk2z)
-   rn_zu       = 4.        !  Wind vector reference height (m)                  (ln_bulk2z)
+   rn_zqt      = 10.        !  Air temperature and humidity reference height (m)
+   rn_zu       = 10.        !  Wind vector reference height (m)                 
    rn_pfac     = 1.        !  multiplicative factor for precipitation (total & snow)
    rn_efac     = 1.        !  multiplicative factor for evaporation (0. or 1.)
Index: branches/2014/dev_CNRS_2014/NEMOGCM/NEMO/OPA_SRC/SBC/sbcblk_core.F90
===================================================================
--- branches/2014/dev_CNRS_2014/NEMOGCM/NEMO/OPA_SRC/SBC/sbcblk_core.F90	(revision 4897)
+++ branches/2014/dev_CNRS_2014/NEMOGCM/NEMO/OPA_SRC/SBC/sbcblk_core.F90	(revision 4898)
@@ -5,22 +5,27 @@
    !!=====================================================================
    !! History :  1.0  !  2004-08  (U. Schweckendiek)  Original code
-   !!            2.0  !  2005-04  (L. Brodeau, A.M. Treguier) additions: 
+   !!            2.0  !  2005-04  (L. Brodeau, A.M. Treguier) additions:
    !!                           -  new bulk routine for efficiency
    !!                           -  WINDS ARE NOW ASSUMED TO BE AT T POINTS in input files !!!!
-   !!                           -  file names and file characteristics in namelist 
-   !!                           -  Implement reading of 6-hourly fields   
-   !!            3.0  !  2006-06  (G. Madec) sbc rewritting   
-   !!             -   !  2006-12  (L. Brodeau) Original code for TURB_CORE_2Z
+   !!                           -  file names and file characteristics in namelist
+   !!                           -  Implement reading of 6-hourly fields
+   !!            3.0  !  2006-06  (G. Madec) sbc rewritting
+   !!             -   !  2006-12  (L. Brodeau) Original code for turb_core_2z
    !!            3.2  !  2009-04  (B. Lemaire)  Introduce iom_put
    !!            3.3  !  2010-10  (S. Masson)  add diurnal cycle
    !!            3.4  !  2011-11  (C. Harris) Fill arrays required by CICE
+   !!            3.7  !  2014-06  (L. Brodeau) simplification and optimization of CORE bulk
    !!----------------------------------------------------------------------
 
    !!----------------------------------------------------------------------
-   !!   sbc_blk_core  : bulk formulation as ocean surface boundary condition
-   !!                   (forced mode, CORE bulk formulea)
-   !!   blk_oce_core  : ocean: computes momentum, heat and freshwater fluxes
-   !!   blk_ice_core  : ice  : computes momentum, heat and freshwater fluxes
-   !!   turb_core     : computes the CORE turbulent transfer coefficients 
+   !!   sbc_blk_core    : bulk formulation as ocean surface boundary condition (forced mode, CORE bulk formulea)
+   !!   blk_oce_core    : computes momentum, heat and freshwater fluxes over ocean
+   !!   blk_ice_core    : computes momentum, heat and freshwater fluxes over ice
+   !!   blk_bio_meanqsr : compute daily mean short wave radiation over the ocean
+   !!   blk_ice_meanqsr : compute daily mean short wave radiation over the ice
+   !!   turb_core_2z    : Computes turbulent transfert coefficients
+   !!   cd_neutral_10m  : Estimate of the neutral drag coefficient at 10m
+   !!   psi_m           : universal profile stability function for momentum
+   !!   psi_h           : universal profile stability function for temperature and humidity
    !!----------------------------------------------------------------------
    USE oce             ! ocean dynamics and tracers
@@ -38,5 +43,5 @@
    USE lbclnk          ! ocean lateral boundary conditions (or mpp link)
    USE prtctl          ! Print control
-   USE sbcwave,ONLY :  cdn_wave !wave module 
+   USE sbcwave, ONLY   :  cdn_wave ! wave module
 #if defined key_lim3 || defined key_cice
    USE sbc_ice         ! Surface boundary condition: ice fields
@@ -52,5 +57,5 @@
    PUBLIC   turb_core_2z         ! routine calles in sbcblk_mfs module
 
-   INTEGER , PARAMETER ::   jpfld   = 9           ! maximum number of files to read 
+   INTEGER , PARAMETER ::   jpfld   = 9           ! maximum number of files to read
    INTEGER , PARAMETER ::   jp_wndi = 1           ! index of 10m wind velocity (i-component) (m/s)    at T-point
    INTEGER , PARAMETER ::   jp_wndj = 2           ! index of 10m wind velocity (j-component) (m/s)    at T-point
@@ -62,7 +67,7 @@
    INTEGER , PARAMETER ::   jp_snow = 8           ! index of snow (solid prcipitation)       (kg/m2/s)
    INTEGER , PARAMETER ::   jp_tdif = 9           ! index of tau diff associated to HF tau   (N/m2)   at T-point
-   
+
    TYPE(FLD), ALLOCATABLE, DIMENSION(:) ::   sf   ! structure of input fields (file informations, fields read)
-         
+
    !                                             !!! CORE bulk parameters
    REAL(wp), PARAMETER ::   rhoa =    1.22        ! air density
@@ -75,10 +80,8 @@
 
    !                                  !!* Namelist namsbc_core : CORE bulk parameters
-   LOGICAL  ::   ln_2m       ! logical flag for height of air temp. and hum
    LOGICAL  ::   ln_taudif   ! logical flag to use the "mean of stress module - module of mean stress" data
    REAL(wp) ::   rn_pfac     ! multiplication factor for precipitation
    REAL(wp) ::   rn_efac     ! multiplication factor for evaporation (clem)
    REAL(wp) ::   rn_vfac     ! multiplication factor for ice/ocean velocity in the calculation of wind stress (clem)
-   LOGICAL  ::   ln_bulk2z   ! logical flag for case where z(q,t) and z(u) are specified in the namelist
    REAL(wp) ::   rn_zqt      ! z(q,t) : height of humidity and temperature measurements
    REAL(wp) ::   rn_zu       ! z(u)   : height of wind measurements
@@ -88,5 +91,5 @@
 #  include "vectopt_loop_substitute.h90"
    !!----------------------------------------------------------------------
-   !! NEMO/OPA 3.3 , NEMO-consortium (2010) 
+   !! NEMO/OPA 3.7 , NEMO-consortium (2014)
    !! $Id$
    !! Software governed by the CeCILL licence     (NEMOGCM/NEMO_CeCILL.txt)
@@ -97,7 +100,7 @@
       !!---------------------------------------------------------------------
       !!                    ***  ROUTINE sbc_blk_core  ***
-      !!                   
+      !!
       !! ** Purpose :   provide at each time step the surface ocean fluxes
-      !!      (momentum, heat, freshwater and runoff) 
+      !!      (momentum, heat, freshwater and runoff)
       !!
       !! ** Method  : (1) READ each fluxes in NetCDF files:
@@ -123,12 +126,15 @@
       !!              - sfx         salt flux due to freezing/melting (non-zero only if ice is present)
       !!                            (set in limsbc(_2).F90)
+      !!
+      !! ** References :   Large & Yeager, 2004 / Large & Yeager, 2008
+      !!                   Brodeau et al. Ocean Modelling 2010
       !!----------------------------------------------------------------------
       INTEGER, INTENT(in) ::   kt   ! ocean time step
-      !!
+      !
       INTEGER  ::   ierror   ! return error code
       INTEGER  ::   ifpr     ! dummy loop indice
       INTEGER  ::   jfld     ! dummy loop arguments
       INTEGER  ::   ios      ! Local integer output status for namelist read
-      !!
+      !
       CHARACTER(len=100) ::  cn_dir   !   Root directory for location of core files
       TYPE(FLD_N), DIMENSION(jpfld) ::   slf_i     ! array of namelist informations on the fields to read
@@ -136,10 +142,10 @@
       TYPE(FLD_N) ::   sn_qlw , sn_tair, sn_prec, sn_snow      !   "                                 "
       TYPE(FLD_N) ::   sn_tdif                                 !   "                                 "
-      NAMELIST/namsbc_core/ cn_dir , ln_2m  , ln_taudif, rn_pfac, rn_efac, rn_vfac,  &
+      NAMELIST/namsbc_core/ cn_dir , ln_taudif, rn_pfac, rn_efac, rn_vfac,  &
          &                  sn_wndi, sn_wndj, sn_humi  , sn_qsr ,           &
          &                  sn_qlw , sn_tair, sn_prec  , sn_snow,           &
-         &                  sn_tdif, rn_zqt , ln_bulk2z, rn_zu
-      !!---------------------------------------------------------------------
-
+         &                  sn_tdif, rn_zqt,  rn_zu
+      !!---------------------------------------------------------------------
+      !
       !                                         ! ====================== !
       IF( kt == nit000 ) THEN                   !  First call kt=nit000  !
@@ -149,16 +155,16 @@
          READ  ( numnam_ref, namsbc_core, IOSTAT = ios, ERR = 901)
 901      IF( ios /= 0 ) CALL ctl_nam ( ios , 'namsbc_core in reference namelist', lwp )
-
+         !
          REWIND( numnam_cfg )              ! Namelist namsbc_core in configuration namelist : CORE bulk parameters
          READ  ( numnam_cfg, namsbc_core, IOSTAT = ios, ERR = 902 )
 902      IF( ios /= 0 ) CALL ctl_nam ( ios , 'namsbc_core in configuration namelist', lwp )
 
-         IF(lwm) WRITE ( numond, namsbc_core )
+         WRITE ( numond, namsbc_core )
          !                                         ! check: do we plan to use ln_dm2dc with non-daily forcing?
-         IF( ln_dm2dc .AND. sn_qsr%nfreqh /= 24 )   & 
-            &   CALL ctl_stop( 'sbc_blk_core: ln_dm2dc can be activated only with daily short-wave forcing' ) 
+         IF( ln_dm2dc .AND. sn_qsr%nfreqh /= 24 )   &
+            &   CALL ctl_stop( 'sbc_blk_core: ln_dm2dc can be activated only with daily short-wave forcing' )
          IF( ln_dm2dc .AND. sn_qsr%ln_tint ) THEN
             CALL ctl_warn( 'sbc_blk_core: ln_dm2dc is taking care of the temporal interpolation of daily qsr',   &
-                 &         '              ==> We force time interpolation = .false. for qsr' )
+               &         '              ==> We force time interpolation = .false. for qsr' )
             sn_qsr%ln_tint = .false.
          ENDIF
@@ -169,5 +175,5 @@
          slf_i(jp_prec) = sn_prec   ;   slf_i(jp_snow) = sn_snow
          slf_i(jp_tdif) = sn_tdif
-         !                 
+         !
          lhftau = ln_taudif                        ! do we use HF tau information?
          jfld = jpfld - COUNT( (/.NOT. lhftau/) )
@@ -191,5 +197,5 @@
       IF( MOD( kt - 1, nn_fsbc ) == 0 )   CALL blk_oce_core( kt, sf, sst_m, ssu_m, ssv_m )
 
-      ! If diurnal cycle is activated, compute a daily mean short waves flux for biogeochemistery 
+      ! If diurnal cycle is activated, compute a daily mean short waves flux for biogeochemistery
       IF( ltrcdm2dc )   CALL blk_bio_meanqsr
 
@@ -269,5 +275,5 @@
       zwnd_j(:,:) = 0.e0
 #if defined key_cyclone
-      CALL wnd_cyc( kt, zwnd_i, zwnd_j )
+      CALL wnd_cyc( kt, zwnd_i, zwnd_j )    ! add analytical tropical cyclone (Vincent et al. JGR 2012)
       DO jj = 2, jpjm1
          DO ji = fs_2, fs_jpim1   ! vect. opt.
@@ -292,5 +298,5 @@
       !      I   Radiative FLUXES                                                     !
       ! ----------------------------------------------------------------------------- !
-    
+
       ! ocean albedo assumed to be constant + modify now Qsr to include the diurnal cycle                    ! Short Wave
       zztmp = 1. - albo
@@ -298,5 +304,4 @@
       ELSE                  ;   qsr(:,:) = zztmp *          sf(jp_qsr)%fnow(:,:,1)   * tmask(:,:,1)
       ENDIF
-!CDIR COLLAPSE
       zqlw(:,:) = (  sf(jp_qlw)%fnow(:,:,1) - Stef * zst(:,:)*zst(:,:)*zst(:,:)*zst(:,:)  ) * tmask(:,:,1)   ! Long  Wave
       ! ----------------------------------------------------------------------------- !
@@ -305,43 +310,10 @@
 
       ! ... specific humidity at SST and IST
-!CDIR NOVERRCHK
-!CDIR COLLAPSE
-      zqsatw(:,:) = zcoef_qsatw * EXP( -5107.4 / zst(:,:) ) 
+      zqsatw(:,:) = zcoef_qsatw * EXP( -5107.4 / zst(:,:) )
 
       ! ... NCAR Bulk formulae, computation of Cd, Ch, Ce at T-point :
-      IF( ln_2m ) THEN
-         !! If air temp. and spec. hum. are given at different height (2m) than wind (10m) :
-         CALL TURB_CORE_2Z(2.,10., zst   , sf(jp_tair)%fnow,         &
-            &                      zqsatw, sf(jp_humi)%fnow, wndm,   &
-            &                      Cd    , Ch              , Ce  ,   &
-            &                      zt_zu , zq_zu                   )
-      ELSE IF( ln_bulk2z ) THEN
-         !! If the height of the air temp./spec. hum. and wind are to be specified by hand :
-         IF( rn_zqt == rn_zu ) THEN
-            !! If air temp. and spec. hum. are at the same height as wind :
-            CALL TURB_CORE_1Z( rn_zu, zst   , sf(jp_tair)%fnow(:,:,1),       &
-               &                      zqsatw, sf(jp_humi)%fnow(:,:,1), wndm, &
-               &                      Cd    , Ch                     , Ce  )
-         ELSE
-            !! If air temp. and spec. hum. are at a different height to wind :
-            CALL TURB_CORE_2Z(rn_zqt, rn_zu , zst   , sf(jp_tair)%fnow,         &
-               &                              zqsatw, sf(jp_humi)%fnow, wndm,   &
-               &                              Cd    , Ch              , Ce  ,   &
-               &                              zt_zu , zq_zu                 )
-         ENDIF
-      ELSE
-         !! If air temp. and spec. hum. are given at same height than wind (10m) :
-!gm bug?  at the compiling phase, add a copy in temporary arrays...  ==> check perf
-!         CALL TURB_CORE_1Z( 10., zst   (:,:), sf(jp_tair)%fnow(:,:),              &
-!            &                    zqsatw(:,:), sf(jp_humi)%fnow(:,:), wndm(:,:),   &
-!            &                    Cd    (:,:),             Ch  (:,:), Ce  (:,:)  )
-!gm bug
-! ARPDBG - this won't compile with gfortran. Fix but check performance
-! as per comment above.
-         CALL TURB_CORE_1Z( 10., zst   , sf(jp_tair)%fnow(:,:,1),       &
-            &                    zqsatw, sf(jp_humi)%fnow(:,:,1), wndm, &
-            &                    Cd    , Ch              , Ce    )
-      ENDIF
-
+      CALL turb_core_2z( rn_zqt, rn_zu, zst, sf(jp_tair)%fnow, zqsatw, sf(jp_humi)%fnow, wndm,   &
+         &               Cd, Ch, Ce, zt_zu, zq_zu )
+    
       ! ... tau module, i and j component
       DO jj = 1, jpj
@@ -355,6 +327,5 @@
 
       ! ... add the HF tau contribution to the wind stress module?
-      IF( lhftau ) THEN 
-!CDIR COLLAPSE
+      IF( lhftau ) THEN
          taum(:,:) = taum(:,:) + sf(jp_tdif)%fnow(:,:,1)
       ENDIF
@@ -372,17 +343,17 @@
       CALL lbc_lnk( vtau(:,:), 'V', -1. )
 
+    
       !  Turbulent fluxes over ocean
       ! -----------------------------
-      IF( ln_2m .OR. ( ln_bulk2z .AND. rn_zqt /= rn_zu ) ) THEN
-         ! Values of temp. and hum. adjusted to height of wind must be used
-         zevap(:,:) = rn_efac * MAX( 0.e0, rhoa    *Ce(:,:)*( zqsatw(:,:) - zq_zu(:,:) ) * wndm(:,:) )   ! Evaporation
-         zqsb (:,:) =                      rhoa*cpa*Ch(:,:)*( zst   (:,:) - zt_zu(:,:) ) * wndm(:,:)     ! Sensible Heat
+      IF( ABS( rn_zu - rn_zqt) < 0.01_wp ) THEN
+         !! q_air and t_air are (or "are almost") given at 10m (wind reference height)
+         zevap(:,:) = rn_efac*MAX( 0._wp,     rhoa*Ce(:,:)*( zqsatw(:,:) - sf(jp_humi)%fnow(:,:,1) )*wndm(:,:) ) ! Evaporation
+         zqsb (:,:) =                     cpa*rhoa*Ch(:,:)*( zst   (:,:) - sf(jp_tair)%fnow(:,:,1) )*wndm(:,:)   ! Sensible Heat
       ELSE
-!CDIR COLLAPSE
-         zevap(:,:) = rn_efac * MAX( 0.e0, rhoa    *Ce(:,:)*( zqsatw(:,:) - sf(jp_humi)%fnow(:,:,1) ) * wndm(:,:) )   ! Evaporation
-!CDIR COLLAPSE
-         zqsb (:,:) =            rhoa*cpa*Ch(:,:)*( zst   (:,:) - sf(jp_tair)%fnow(:,:,1) ) * wndm(:,:)     ! Sensible Heat
+         !! q_air and t_air are not given at 10m (wind reference height)
+         ! Values of temp. and hum. adjusted to height of wind during bulk algorithm iteration must be used!!!
+         zevap(:,:) = rn_efac*MAX( 0.e0,     rhoa*Ce(:,:)*( zqsatw(:,:) - zq_zu(:,:) )*wndm(:,:) )   ! Evaporation
+         zqsb (:,:) =                    cpa*rhoa*Ch(:,:)*( zst   (:,:) - zt_zu(:,:) )*wndm(:,:)     ! Sensible Heat
       ENDIF
-!CDIR COLLAPSE
       zqla (:,:) = Lv * zevap(:,:)                                                              ! Latent Heat
 
@@ -401,14 +372,12 @@
       !     III    Total FLUXES                                                       !
       ! ----------------------------------------------------------------------------- !
-     
-!CDIR COLLAPSE
+      !
       emp (:,:) = (  zevap(:,:)                                          &   ! mass flux (evap. - precip.)
          &         - sf(jp_prec)%fnow(:,:,1) * rn_pfac  ) * tmask(:,:,1)
-!CDIR COLLAPSE
       qns(:,:) = zqlw(:,:) - zqsb(:,:) - zqla(:,:)                                &   ! Downward Non Solar flux
          &     - sf(jp_snow)%fnow(:,:,1) * rn_pfac * lfus                         &   ! remove latent melting heat for solid precip
          &     - zevap(:,:) * pst(:,:) * rcp                                      &   ! remove evap heat content at SST
          &     + ( sf(jp_prec)%fnow(:,:,1) - sf(jp_snow)%fnow(:,:,1) ) * rn_pfac  &   ! add liquid precip heat content at Tair
-         &     * ( sf(jp_tair)%fnow(:,:,1) - rt0 ) * rcp                          &   
+         &     * ( sf(jp_tair)%fnow(:,:,1) - rt0 ) * rcp                          &
          &     + sf(jp_snow)%fnow(:,:,1) * rn_pfac                                &   ! add solid  precip heat content at min(Tair,Tsnow)
          &     * ( MIN( sf(jp_tair)%fnow(:,:,1), rt0_snow ) - rt0 ) * cpic 
@@ -434,59 +403,4 @@
       !
    END SUBROUTINE blk_oce_core
-  
-  
-   SUBROUTINE blk_bio_meanqsr
-      !!---------------------------------------------------------------------
-      !!                     ***  ROUTINE blk_bio_meanqsr
-      !!                     
-      !! ** Purpose :   provide daily qsr_mean for PISCES when
-      !!                analytic diurnal cycle is applied in physic
-      !!                
-      !! ** Method  :   add part where there is no ice
-      !! 
-      !!---------------------------------------------------------------------
-      IF( nn_timing == 1 )   CALL timing_start('blk_bio_meanqsr')
-      !
-      qsr_mean(:,:) = (1. - albo ) * sf(jp_qsr)%fnow(:,:,1)
-      !
-      IF( nn_timing == 1 )   CALL timing_stop('blk_bio_meanqsr')
-      !
-   END SUBROUTINE blk_bio_meanqsr
- 
- 
-   SUBROUTINE blk_ice_meanqsr(palb,p_qsr_mean,pdim)
-      !!---------------------------------------------------------------------
-      !!
-      !! ** Purpose :   provide the daily qsr_mean over sea_ice for PISCES when
-      !!                analytic diurnal cycle is applied in physic
-      !!
-      !! ** Method  :   compute qsr
-      !! 
-      !!---------------------------------------------------------------------
-      REAL(wp), DIMENSION(:,:,:), INTENT(in   ) ::   palb       ! ice albedo (clear sky) (alb_ice_cs)               [%]
-      REAL(wp), DIMENSION(:,:,:), INTENT(  out) ::   p_qsr_mean !     solar heat flux over ice (T-point)         [W/m2]
-      INTEGER                   , INTENT(in   ) ::   pdim       ! number of ice categories
-      !!
-      INTEGER  ::   ijpl          ! number of ice categories (size of 3rd dim of input arrays)
-      INTEGER  ::   ji, jj, jl    ! dummy loop indices
-      REAL(wp) ::   zztmp         ! temporary variable
-      !!---------------------------------------------------------------------
-      IF( nn_timing == 1 )  CALL timing_start('blk_ice_meanqsr')
-      !
-      ijpl  = pdim                            ! number of ice categories
-      zztmp = 1. / ( 1. - albo )
-      !                                     ! ========================== !
-      DO jl = 1, ijpl                       !  Loop over ice categories  !
-         !                                  ! ========================== !
-         DO jj = 1 , jpj
-            DO ji = 1, jpi
-                  p_qsr_mean(ji,jj,jl) = zztmp * ( 1. - palb(ji,jj,jl) ) * qsr_mean(ji,jj)
-            END DO
-         END DO
-      END DO
-      !
-      IF( nn_timing == 1 )  CALL timing_stop('blk_ice_meanqsr')
-      !
-   END SUBROUTINE blk_ice_meanqsr  
  
    
@@ -572,5 +486,4 @@
       CASE( 'I' )                  ! B-grid ice dynamics :   I-point (i.e. F-point with sea-ice indexation)
          !                           and scalar wind at T-point ( = | U10m - U_ice | ) (masked)
-!CDIR NOVERRCHK
          DO jj = 2, jpjm1
             DO ji = 2, jpim1   ! B grid : NO vector opt
@@ -660,7 +573,7 @@
                ! ----------------------------!
                ! Downward Non Solar flux
-               p_qns (ji,jj,jl) =     z_qlw (ji,jj,jl) - z_qsb (ji,jj,jl) - p_qla (ji,jj,jl)      
+               p_qns (ji,jj,jl) =     z_qlw (ji,jj,jl) - z_qsb (ji,jj,jl) - p_qla (ji,jj,jl)
                ! Total non solar heat flux sensitivity for ice
-               p_dqns(ji,jj,jl) = - ( z_dqlw(ji,jj,jl) + z_dqsb(ji,jj,jl) + p_dqla(ji,jj,jl) )    
+               p_dqns(ji,jj,jl) = - ( z_dqlw(ji,jj,jl) + z_dqsb(ji,jj,jl) + p_dqla(ji,jj,jl) )
             END DO
             !
@@ -673,16 +586,12 @@
       ! thin surface layer and penetrates inside the ice cover
       ! ( Maykut and Untersteiner, 1971 ; Ebert and Curry, 1993 )
-    
-!CDIR COLLAPSE
+
       p_fr1(:,:) = ( 0.18 * ( 1.0 - zcoef_frca ) + 0.35 * zcoef_frca )
-!CDIR COLLAPSE
       p_fr2(:,:) = ( 0.82 * ( 1.0 - zcoef_frca ) + 0.65 * zcoef_frca )
-       
-!CDIR COLLAPSE
+
       p_tpr(:,:) = sf(jp_prec)%fnow(:,:,1) * rn_pfac      ! total precipitation [kg/m2/s]
-!CDIR COLLAPSE
       p_spr(:,:) = sf(jp_snow)%fnow(:,:,1) * rn_pfac      ! solid precipitation [kg/m2/s]
-      CALL iom_put( 'snowpre', p_spr * 86400. )                  ! Snow precipitation 
-      CALL iom_put( 'precip' , p_tpr * 86400. )                  ! Total precipitation 
+      CALL iom_put( 'snowpre', p_spr * 86400. )                  ! Snow precipitation
+      CALL iom_put( 'precip' , p_tpr * 86400. )                  ! Total precipitation
       !
       IF(ln_ctl) THEN
@@ -698,162 +607,89 @@
 
       CALL wrk_dealloc( jpi,jpj, z_wnds_t )
-      CALL wrk_dealloc( jpi,jpj,pdim, z_qlw, z_qsb, z_dqlw, z_dqsb ) 
+      CALL wrk_dealloc( jpi,jpj,pdim, z_qlw, z_qsb, z_dqlw, z_dqsb )
       !
       IF( nn_timing == 1 )  CALL timing_stop('blk_ice_core')
       !
    END SUBROUTINE blk_ice_core
-  
-
-   SUBROUTINE TURB_CORE_1Z(zu, sst, T_a, q_sat, q_a,   &
-      &                        dU , Cd , Ch   , Ce   )
+
+
+   SUBROUTINE blk_bio_meanqsr
+      !!---------------------------------------------------------------------
+      !!                     ***  ROUTINE blk_bio_meanqsr
+      !!                     
+      !! ** Purpose :   provide daily qsr_mean for PISCES when
+      !!                analytic diurnal cycle is applied in physic
+      !!                
+      !! ** Method  :   add part where there is no ice
+      !! 
+      !!---------------------------------------------------------------------
+      IF( nn_timing == 1 )  CALL timing_start('blk_bio_meanqsr')
+      !
+      qsr_mean(:,:) = (1. - albo ) *  sf(jp_qsr)%fnow(:,:,1)
+      !
+      IF( nn_timing == 1 )  CALL timing_stop('blk_bio_meanqsr')
+      !
+   END SUBROUTINE blk_bio_meanqsr
+ 
+ 
+   SUBROUTINE blk_ice_meanqsr( palb, p_qsr_mean, pdim )
+      !!---------------------------------------------------------------------
+      !!
+      !! ** Purpose :   provide the daily qsr_mean over sea_ice for PISCES when
+      !!                analytic diurnal cycle is applied in physic
+      !!
+      !! ** Method  :   compute qsr
+      !! 
+      !!---------------------------------------------------------------------
+      REAL(wp), DIMENSION(:,:,:), INTENT(in   ) ::   palb       ! ice albedo (clear sky) (alb_ice_cs)               [%]
+      REAL(wp), DIMENSION(:,:,:), INTENT(  out) ::   p_qsr_mean !     solar heat flux over ice (T-point)         [W/m2]
+      INTEGER                   , INTENT(in   ) ::   pdim       ! number of ice categories
+      !
+      INTEGER  ::   ijpl          ! number of ice categories (size of 3rd dim of input arrays)
+      INTEGER  ::   ji, jj, jl    ! dummy loop indices
+      REAL(wp) ::   zztmp         ! temporary variable
+      !!---------------------------------------------------------------------
+      IF( nn_timing == 1 )  CALL timing_start('blk_ice_meanqsr')
+      !
+      ijpl  = pdim                            ! number of ice categories
+      zztmp = 1. / ( 1. - albo )
+      !                                     ! ========================== !
+      DO jl = 1, ijpl                       !  Loop over ice categories  !
+         !                                  ! ========================== !
+         DO jj = 1 , jpj
+            DO ji = 1, jpi
+                  p_qsr_mean(ji,jj,jl) = zztmp * ( 1. - palb(ji,jj,jl) ) * qsr_mean(ji,jj)
+            END DO
+         END DO
+      END DO
+      !
+      IF( nn_timing == 1 )  CALL timing_stop('blk_ice_meanqsr')
+      !
+   END SUBROUTINE blk_ice_meanqsr  
+
+
+   SUBROUTINE turb_core_2z( zt, zu, sst, T_zt, q_sat, q_zt, dU,    &
+      &                      Cd, Ch, Ce , T_zu, q_zu )
       !!----------------------------------------------------------------------
       !!                      ***  ROUTINE  turb_core  ***
       !!
       !! ** Purpose :   Computes turbulent transfert coefficients of surface
-      !!                fluxes according to Large & Yeager (2004)
-      !!
-      !! ** Method  :   I N E R T I A L   D I S S I P A T I O N   M E T H O D
-      !!      Momentum, Latent and sensible heat exchange coefficients
-      !!      Caution: this procedure should only be used in cases when air
-      !!      temperature (T_air), air specific humidity (q_air) and wind (dU)
-      !!      are provided at the same height 'zzu'!
-      !!
-      !! References :   Large & Yeager, 2004 : ???
-      !!----------------------------------------------------------------------
-      REAL(wp)                , INTENT(in   ) ::   zu      ! altitude of wind measurement       [m]
-      REAL(wp), DIMENSION(:,:), INTENT(in   ) ::   sst     ! sea surface temperature         [Kelvin]
-      REAL(wp), DIMENSION(:,:), INTENT(in   ) ::   T_a     ! potential air temperature       [Kelvin]
-      REAL(wp), DIMENSION(:,:), INTENT(in   ) ::   q_sat   ! sea surface specific humidity   [kg/kg]
-      REAL(wp), DIMENSION(:,:), INTENT(in   ) ::   q_a     ! specific air humidity           [kg/kg]
-      REAL(wp), DIMENSION(:,:), INTENT(in   ) ::   dU      ! wind module |U(zu)-U(0)|        [m/s]
-      REAL(wp), DIMENSION(:,:), INTENT(  out) ::   Cd      ! transfert coefficient for momentum       (tau)
-      REAL(wp), DIMENSION(:,:), INTENT(  out) ::   Ch      ! transfert coefficient for temperature (Q_sens)
-      REAL(wp), DIMENSION(:,:), INTENT(  out) ::   Ce      ! transfert coefficient for evaporation  (Q_lat)
-      !!
-      INTEGER :: j_itt
-      INTEGER , PARAMETER ::   nb_itt = 3
-      REAL(wp), PARAMETER ::   grav   = 9.8   ! gravity                       
-      REAL(wp), PARAMETER ::   kappa  = 0.4   ! von Karman s constant
-
-      REAL(wp), DIMENSION(:,:), POINTER  ::   dU10          ! dU                                   [m/s]
-      REAL(wp), DIMENSION(:,:), POINTER  ::   dT            ! air/sea temperature differeence      [K]
-      REAL(wp), DIMENSION(:,:), POINTER  ::   dq            ! air/sea humidity difference          [K]
-      REAL(wp), DIMENSION(:,:), POINTER  ::   Cd_n10        ! 10m neutral drag coefficient
-      REAL(wp), DIMENSION(:,:), POINTER  ::   Ce_n10        ! 10m neutral latent coefficient
-      REAL(wp), DIMENSION(:,:), POINTER  ::   Ch_n10        ! 10m neutral sensible coefficient
-      REAL(wp), DIMENSION(:,:), POINTER  ::   sqrt_Cd_n10   ! root square of Cd_n10
-      REAL(wp), DIMENSION(:,:), POINTER  ::   sqrt_Cd       ! root square of Cd
-      REAL(wp), DIMENSION(:,:), POINTER  ::   T_vpot        ! virtual potential temperature        [K]
-      REAL(wp), DIMENSION(:,:), POINTER  ::   T_star        ! turbulent scale of tem. fluct.
-      REAL(wp), DIMENSION(:,:), POINTER  ::   q_star        ! turbulent humidity of temp. fluct.
-      REAL(wp), DIMENSION(:,:), POINTER  ::   U_star        ! turb. scale of velocity fluct.
-      REAL(wp), DIMENSION(:,:), POINTER  ::   L             ! Monin-Obukov length                  [m]
-      REAL(wp), DIMENSION(:,:), POINTER  ::   zeta          ! stability parameter at height zu
-      REAL(wp), DIMENSION(:,:), POINTER  ::   U_n10         ! neutral wind velocity at 10m         [m]   
-      REAL(wp), DIMENSION(:,:), POINTER  ::   xlogt, xct, zpsi_h, zpsi_m
-      
-      INTEGER , DIMENSION(:,:), POINTER  ::   stab          ! 1st guess stability test integer
-      !!----------------------------------------------------------------------
-      !
-      IF( nn_timing == 1 )  CALL timing_start('TURB_CORE_1Z')
-      !
-      CALL wrk_alloc( jpi,jpj, stab )   ! integer
-      CALL wrk_alloc( jpi,jpj, dU10, dT, dq, Cd_n10, Ce_n10, Ch_n10, sqrt_Cd_n10, sqrt_Cd, L )
-      CALL wrk_alloc( jpi,jpj, T_vpot, T_star, q_star, U_star, zeta, U_n10, xlogt, xct, zpsi_h, zpsi_m )
-
-      !! * Start
-      !! Air/sea differences
-      dU10 = max(0.5, dU)     ! we don't want to fall under 0.5 m/s
-      dT = T_a - sst          ! assuming that T_a is allready the potential temp. at zzu
-      dq = q_a - q_sat
-      !!    
-      !! Virtual potential temperature
-      T_vpot = T_a*(1. + 0.608*q_a)
-      !!
-      !! Neutral Drag Coefficient
-      stab    = 0.5 + sign(0.5,dT)    ! stable : stab = 1 ; unstable : stab = 0 
-      IF  ( ln_cdgw ) THEN
-        cdn_wave = cdn_wave - rsmall*(tmask(:,:,1)-1)
-        Cd_n10(:,:) =   cdn_wave
-      ELSE
-        Cd_n10  = 1.e-3 * ( 2.7/dU10 + 0.142 + dU10/13.09 )    !   L & Y eq. (6a)
-      ENDIF
-      sqrt_Cd_n10 = sqrt(Cd_n10)
-      Ce_n10  = 1.e-3 * ( 34.6 * sqrt_Cd_n10 )               !   L & Y eq. (6b)
-      Ch_n10  = 1.e-3*sqrt_Cd_n10*(18.*stab + 32.7*(1.-stab)) !   L & Y eq. (6c), (6d)
-      !!
-      !! Initializing transfert coefficients with their first guess neutral equivalents :
-      Cd = Cd_n10 ;  Ce = Ce_n10 ;  Ch = Ch_n10 ;  sqrt_Cd = sqrt(Cd)
-
-      !! * Now starting iteration loop
-      DO j_itt=1, nb_itt
-         !! Turbulent scales :
-         U_star  = sqrt_Cd*dU10                !   L & Y eq. (7a)
-         T_star  = Ch/sqrt_Cd*dT               !   L & Y eq. (7b)
-         q_star  = Ce/sqrt_Cd*dq               !   L & Y eq. (7c)
-
-         !! Estimate the Monin-Obukov length :
-         L = U_star*U_star / ( kappa*grav*(T_star/T_vpot + q_star/(q_a + 1./0.608)) )
-!!gm  !lolo  suggestion ......   TO BE TAKEN  ?
-!!         L = U_star*U_star / ( kappa*grav/T_vpot*(T_star*(1. + 0.608*q_a) + 0.608*T_a*q_star) )
-!!gm     !lolo.
-
-         !! Stability parameters :
-         zeta  = zu/L ;  zeta   = sign( min(abs(zeta),10.0), zeta )
-         zpsi_h  = psi_h(zeta)
-         zpsi_m  = psi_m(zeta)
-
-         IF  ( ln_cdgw ) THEN
-           sqrt_Cd=kappa/((kappa/sqrt_Cd_n10) - zpsi_m) ; Cd=sqrt_Cd*sqrt_Cd;
-         ELSE
-           !! Shifting the wind speed to 10m and neutral stability :
-           U_n10 = dU10*1./(1. + sqrt_Cd_n10/kappa*(log(zu/10.) - zpsi_m)) !  L & Y eq. (9a)
-
-           !! Updating the neutral 10m transfer coefficients :
-           Cd_n10  = 1.e-3 * (2.7/U_n10 + 0.142 + U_n10/13.09)              !  L & Y eq. (6a)
-           sqrt_Cd_n10 = sqrt(Cd_n10)
-           Ce_n10  = 1.e-3 * (34.6 * sqrt_Cd_n10)                           !  L & Y eq. (6b)
-           stab    = 0.5 + sign(0.5,zeta)
-           Ch_n10  = 1.e-3*sqrt_Cd_n10*(18.*stab + 32.7*(1.-stab))           !  L & Y eq. (6c), (6d)
-
-           !! Shifting the neutral  10m transfer coefficients to ( zu , zeta ) :
-           !!
-           xct = 1. + sqrt_Cd_n10/kappa*(log(zu/10) - zpsi_m)
-           Cd  = Cd_n10/(xct*xct) ;  sqrt_Cd = sqrt(Cd)
-         ENDIF
-         !!
-         xlogt = log(zu/10.) - zpsi_h
-         !!
-         xct = 1. + Ch_n10*xlogt/kappa/sqrt_Cd_n10
-         Ch  = Ch_n10*sqrt_Cd/sqrt_Cd_n10/xct
-         !!
-         xct = 1. + Ce_n10*xlogt/kappa/sqrt_Cd_n10
-         Ce  = Ce_n10*sqrt_Cd/sqrt_Cd_n10/xct
-         !!
-      END DO
-      !!
-      CALL wrk_dealloc( jpi,jpj, stab )   ! integer
-      CALL wrk_dealloc( jpi,jpj, dU10, dT, dq, Cd_n10, Ce_n10, Ch_n10, sqrt_Cd_n10, sqrt_Cd, L )
-      CALL wrk_dealloc( jpi,jpj, T_vpot, T_star, q_star, U_star, zeta, U_n10, xlogt, xct, zpsi_h, zpsi_m )
-      !
-      IF( nn_timing == 1 )  CALL timing_stop('TURB_CORE_1Z')
-      !
-    END SUBROUTINE TURB_CORE_1Z
-
-
-    SUBROUTINE TURB_CORE_2Z(zt, zu, sst, T_zt, q_sat, q_zt, dU, Cd, Ch, Ce, T_zu, q_zu)
-      !!----------------------------------------------------------------------
-      !!                      ***  ROUTINE  turb_core  ***
-      !!
-      !! ** Purpose :   Computes turbulent transfert coefficients of surface 
-      !!                fluxes according to Large & Yeager (2004).
-      !!
-      !! ** Method  :   I N E R T I A L   D I S S I P A T I O N   M E T H O D
-      !!      Momentum, Latent and sensible heat exchange coefficients
-      !!      Caution: this procedure should only be used in cases when air
-      !!      temperature (T_air) and air specific humidity (q_air) are at a
-      !!      different height to wind (dU).
-      !!
-      !! References :   Large & Yeager, 2004 : ???
+      !!                fluxes according to Large & Yeager (2004) and Large & Yeager (2008)
+      !!                If relevant (zt /= zu), adjust temperature and humidity from height zt to zu
+      !!
+      !! ** Method : Monin Obukhov Similarity Theory 
+      !!             + Large & Yeager (2004,2008) closure: CD_n10 = f(U_n10)
+      !!
+      !! ** References :   Large & Yeager, 2004 / Large & Yeager, 2008
+      !!
+      !! ** Last update: Laurent Brodeau, June 2014:
+      !!    - handles both cases zt=zu and zt/=zu
+      !!    - optimized: less 2D arrays allocated and less operations
+      !!    - better first guess of stability by checking air-sea difference of virtual temperature
+      !!       rather than temperature difference only...
+      !!    - added function "cd_neutral_10m" that uses the improved parametrization of 
+      !!      Large & Yeager 2008. Drag-coefficient reduction for Cyclone conditions!
+      !!    - using code-wide physical constants defined into "phycst.mod" rather than redifining them
+      !!      => 'vkarmn' and 'grav'
       !!----------------------------------------------------------------------
       REAL(wp), INTENT(in   )                     ::   zt       ! height for T_zt and q_zt                   [m]
@@ -863,5 +699,5 @@
       REAL(wp), INTENT(in   ), DIMENSION(jpi,jpj) ::   q_sat    ! sea surface specific humidity         [kg/kg]
       REAL(wp), INTENT(in   ), DIMENSION(jpi,jpj) ::   q_zt     ! specific air humidity                 [kg/kg]
-      REAL(wp), INTENT(in   ), DIMENSION(jpi,jpj) ::   dU       ! relative wind module |U(zu)-U(0)|       [m/s]
+      REAL(wp), INTENT(in   ), DIMENSION(jpi,jpj) ::   dU       ! relative wind module at zu            [m/s]
       REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   Cd       ! transfer coefficient for momentum         (tau)
       REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   Ch       ! transfer coefficient for sensible heat (Q_sens)
@@ -869,168 +705,199 @@
       REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   T_zu     ! air temp. shifted at zu                     [K]
       REAL(wp), INTENT(  out), DIMENSION(jpi,jpj) ::   q_zu     ! spec. hum.  shifted at zu               [kg/kg]
-
-      INTEGER :: j_itt
-      INTEGER , PARAMETER :: nb_itt = 5              ! number of itterations
-      REAL(wp), PARAMETER ::   grav   = 9.8          ! gravity                       
-      REAL(wp), PARAMETER ::   kappa  = 0.4          ! von Karman's constant
-      
-      REAL(wp), DIMENSION(:,:), POINTER ::   dU10          ! dU                                [m/s]
-      REAL(wp), DIMENSION(:,:), POINTER ::   dT            ! air/sea temperature differeence   [K]
-      REAL(wp), DIMENSION(:,:), POINTER ::   dq            ! air/sea humidity difference       [K]
-      REAL(wp), DIMENSION(:,:), POINTER ::   Cd_n10        ! 10m neutral drag coefficient
+      !
+      INTEGER ::   j_itt
+      INTEGER , PARAMETER ::   nb_itt = 5       ! number of itterations
+      LOGICAL ::   l_zt_equal_zu = .FALSE.      ! if q and t are given at different height than U
+      !
+      REAL(wp), DIMENSION(:,:), POINTER ::   U_zu          ! relative wind at zu                            [m/s]
       REAL(wp), DIMENSION(:,:), POINTER ::   Ce_n10        ! 10m neutral latent coefficient
       REAL(wp), DIMENSION(:,:), POINTER ::   Ch_n10        ! 10m neutral sensible coefficient
       REAL(wp), DIMENSION(:,:), POINTER ::   sqrt_Cd_n10   ! root square of Cd_n10
       REAL(wp), DIMENSION(:,:), POINTER ::   sqrt_Cd       ! root square of Cd
-      REAL(wp), DIMENSION(:,:), POINTER ::   T_vpot        ! virtual potential temperature        [K]
-      REAL(wp), DIMENSION(:,:), POINTER ::   T_star        ! turbulent scale of tem. fluct.
-      REAL(wp), DIMENSION(:,:), POINTER ::   q_star        ! turbulent humidity of temp. fluct.
-      REAL(wp), DIMENSION(:,:), POINTER ::   U_star        ! turb. scale of velocity fluct.
-      REAL(wp), DIMENSION(:,:), POINTER ::   L             ! Monin-Obukov length                  [m]
       REAL(wp), DIMENSION(:,:), POINTER ::   zeta_u        ! stability parameter at height zu
       REAL(wp), DIMENSION(:,:), POINTER ::   zeta_t        ! stability parameter at height zt
-      REAL(wp), DIMENSION(:,:), POINTER ::   U_n10         ! neutral wind velocity at 10m        [m]
-      REAL(wp), DIMENSION(:,:), POINTER ::   xlogt, xct, zpsi_hu, zpsi_ht, zpsi_m
-
-      INTEGER , DIMENSION(:,:), POINTER ::   stab          ! 1st stability test integer
+      REAL(wp), DIMENSION(:,:), POINTER ::   zpsi_h_u, zpsi_m_u
+      REAL(wp), DIMENSION(:,:), POINTER ::   ztmp0, ztmp1, ztmp2
+      REAL(wp), DIMENSION(:,:), POINTER ::   stab          ! 1st stability test integer
       !!----------------------------------------------------------------------
-      !
-      IF( nn_timing == 1 )  CALL timing_start('TURB_CORE_2Z')
-      !
-      CALL wrk_alloc( jpi,jpj, dU10, dT, dq, Cd_n10, Ce_n10, Ch_n10, sqrt_Cd_n10, sqrt_Cd, L )
-      CALL wrk_alloc( jpi,jpj, T_vpot, T_star, q_star, U_star, zeta_u, zeta_t, U_n10 )
-      CALL wrk_alloc( jpi,jpj, xlogt, xct, zpsi_hu, zpsi_ht, zpsi_m )
-      CALL wrk_alloc( jpi,jpj, stab )   ! interger
-
-      !! Initial air/sea differences
-      dU10 = max(0.5, dU)      !  we don't want to fall under 0.5 m/s
-      dT = T_zt - sst 
-      dq = q_zt - q_sat
-
-      !! Neutral Drag Coefficient :
-      stab = 0.5 + sign(0.5,dT)                 ! stab = 1  if dT > 0  -> STABLE
-      IF( ln_cdgw ) THEN
-        cdn_wave = cdn_wave - rsmall*(tmask(:,:,1)-1)
-        Cd_n10(:,:) =   cdn_wave
+
+      IF( nn_timing == 1 )  CALL timing_start('turb_core_2z')
+    
+      CALL wrk_alloc( jpi,jpj, U_zu, Ce_n10, Ch_n10, sqrt_Cd_n10, sqrt_Cd )
+      CALL wrk_alloc( jpi,jpj, zeta_u, stab )
+      CALL wrk_alloc( jpi,jpj, zpsi_h_u, zpsi_m_u, ztmp0, ztmp1, ztmp2 )
+
+      l_zt_equal_zu = .FALSE.
+      IF( ABS(zu - zt) < 0.01 ) l_zt_equal_zu = .TRUE.    ! testing "zu == zt" is risky with double precision
+
+      IF( .NOT. l_zt_equal_zu )   CALL wrk_alloc( jpi,jpj, zeta_t )
+
+      U_zu = MAX( 0.5 , dU )   !  relative wind speed at zu (normally 10m), we don't want to fall under 0.5 m/s
+
+      !! First guess of stability: 
+      ztmp0 = T_zt*(1. + 0.608*q_zt) - sst*(1. + 0.608*q_sat) ! air-sea difference of virtual pot. temp. at zt
+      stab  = 0.5 + sign(0.5,ztmp0)                           ! stab = 1 if dTv > 0  => STABLE, 0 if unstable
+
+      !! Neutral coefficients at 10m:
+      IF( ln_cdgw ) THEN      ! wave drag case
+         cdn_wave(:,:) = cdn_wave(:,:) + rsmall * ( 1._wp - tmask(:,:,1) )
+         ztmp0   (:,:) = cdn_wave(:,:)
       ELSE
-        Cd_n10  = 1.e-3*( 2.7/dU10 + 0.142 + dU10/13.09 ) 
+         ztmp0 = cd_neutral_10m( U_zu )
       ENDIF
-      sqrt_Cd_n10 = sqrt(Cd_n10)
+      sqrt_Cd_n10 = SQRT( ztmp0 )
       Ce_n10  = 1.e-3*( 34.6 * sqrt_Cd_n10 )
       Ch_n10  = 1.e-3*sqrt_Cd_n10*(18.*stab + 32.7*(1. - stab))
-
+    
       !! Initializing transf. coeff. with their first guess neutral equivalents :
-      Cd = Cd_n10 ;  Ce = Ce_n10 ;  Ch = Ch_n10 ;  sqrt_Cd = sqrt(Cd)
-
-      !! Initializing z_u values with z_t values :
-      T_zu = T_zt ;  q_zu = q_zt
+      Cd = ztmp0   ;   Ce = Ce_n10   ;   Ch = Ch_n10   ;   sqrt_Cd = sqrt_Cd_n10
+
+      !! Initializing values at z_u with z_t values:
+      T_zu = T_zt   ;   q_zu = q_zt
 
       !!  * Now starting iteration loop
       DO j_itt=1, nb_itt
-         dT = T_zu - sst ;  dq = q_zu - q_sat ! Updating air/sea differences
-         T_vpot = T_zu*(1. + 0.608*q_zu)    ! Updating virtual potential temperature at zu
-         U_star = sqrt_Cd*dU10                ! Updating turbulent scales :   (L & Y eq. (7))
-         T_star  = Ch/sqrt_Cd*dT              !
-         q_star  = Ce/sqrt_Cd*dq              !
-         !!
-         L = (U_star*U_star) &                ! Estimate the Monin-Obukov length at height zu
-              & / (kappa*grav/T_vpot*(T_star*(1.+0.608*q_zu) + 0.608*T_zu*q_star))
+         !
+         ztmp1 = T_zu - sst   ! Updating air/sea differences
+         ztmp2 = q_zu - q_sat 
+
+         ! Updating turbulent scales :   (L&Y 2004 eq. (7))
+         ztmp1  = Ch/sqrt_Cd*ztmp1    ! theta*
+         ztmp2  = Ce/sqrt_Cd*ztmp2    ! q*
+       
+         ztmp0 = T_zu*(1. + 0.608*q_zu) ! virtual potential temperature at zu
+
+         ! Estimate the inverse of Monin-Obukov length (1/L) at height zu:
+         ztmp0 =  (vkarmn*grav/ztmp0*(ztmp1*(1.+0.608*q_zu) + 0.608*T_zu*ztmp2)) / (Cd*U_zu*U_zu) 
+         !                                                                     ( Cd*U_zu*U_zu is U*^2 at zu)
+
          !! Stability parameters :
-         zeta_u  = zu/L  ;  zeta_u = sign( min(abs(zeta_u),10.0), zeta_u )
-         zeta_t  = zt/L  ;  zeta_t = sign( min(abs(zeta_t),10.0), zeta_t )
-         zpsi_hu = psi_h(zeta_u)
-         zpsi_ht = psi_h(zeta_t)
-         zpsi_m  = psi_m(zeta_u)
-         !!
-         !! Shifting the wind speed to 10m and neutral stability : (L & Y eq.(9a))
-!        U_n10 = dU10/(1. + sqrt_Cd_n10/kappa*(log(zu/10.) - psi_m(zeta_u)))
-         U_n10 = dU10/(1. + sqrt_Cd_n10/kappa*(log(zu/10.) - zpsi_m))
-         !!
-         !! Shifting temperature and humidity at zu :          (L & Y eq. (9b-9c))
-!        T_zu = T_zt - T_star/kappa*(log(zt/zu) + psi_h(zeta_u) - psi_h(zeta_t))
-         T_zu = T_zt - T_star/kappa*(log(zt/zu) + zpsi_hu - zpsi_ht)
-!        q_zu = q_zt - q_star/kappa*(log(zt/zu) + psi_h(zeta_u) - psi_h(zeta_t))
-         q_zu = q_zt - q_star/kappa*(log(zt/zu) + zpsi_hu - zpsi_ht)
-         !!
-         !! q_zu cannot have a negative value : forcing 0
-         stab = 0.5 + sign(0.5,q_zu) ;  q_zu = stab*q_zu
-         !!
-         IF( ln_cdgw ) THEN
-            sqrt_Cd=kappa/((kappa/sqrt_Cd_n10) - zpsi_m) ; Cd=sqrt_Cd*sqrt_Cd;
+         zeta_u   = zu*ztmp0   ;  zeta_u = sign( min(abs(zeta_u),10.0), zeta_u )
+         zpsi_h_u = psi_h( zeta_u )
+         zpsi_m_u = psi_m( zeta_u )
+       
+         !! Shifting temperature and humidity at zu (L&Y 2004 eq. (9b-9c))
+         IF ( .NOT. l_zt_equal_zu ) THEN
+            zeta_t = zt*ztmp0 ;  zeta_t = sign( min(abs(zeta_t),10.0), zeta_t )
+            stab = LOG(zu/zt) - zpsi_h_u + psi_h(zeta_t)  ! stab just used as temp array!!!
+            T_zu = T_zt + ztmp1/vkarmn*stab    ! ztmp1 is still theta*
+            q_zu = q_zt + ztmp2/vkarmn*stab    ! ztmp2 is still q*
+            q_zu = max(0., q_zu)
+         END IF
+       
+         IF( ln_cdgw ) THEN      ! surface wave case
+            sqrt_Cd = vkarmn / ( vkarmn / sqrt_Cd_n10 - zpsi_m_u ) 
+            Cd      = sqrt_Cd * sqrt_Cd
          ELSE
-           !! Updating the neutral 10m transfer coefficients :
-           Cd_n10  = 1.e-3 * (2.7/U_n10 + 0.142 + U_n10/13.09)    ! L & Y eq. (6a)
-           sqrt_Cd_n10 = sqrt(Cd_n10)
-           Ce_n10  = 1.e-3 * (34.6 * sqrt_Cd_n10)                 ! L & Y eq. (6b)
-           stab    = 0.5 + sign(0.5,zeta_u)
-           Ch_n10  = 1.e-3*sqrt_Cd_n10*(18.*stab + 32.7*(1.-stab)) ! L & Y eq. (6c-6d)
-           !!
-           !!
-           !! Shifting the neutral 10m transfer coefficients to (zu,zeta_u) :
-           xct = 1. + sqrt_Cd_n10/kappa*(log(zu/10.) - zpsi_m)   ! L & Y eq. (10a)
-           Cd = Cd_n10/(xct*xct) ; sqrt_Cd = sqrt(Cd)
+           ! Update neutral wind speed at 10m and neutral Cd at 10m (L&Y 2004 eq. 9a)...
+           !   In very rare low-wind conditions, the old way of estimating the
+           !   neutral wind speed at 10m leads to a negative value that causes the code
+           !   to crash. To prevent this a threshold of 0.25m/s is imposed.
+           ztmp0 = MAX( 0.25 , U_zu/(1. + sqrt_Cd_n10/vkarmn*(LOG(zu/10.) - zpsi_m_u)) ) !  U_n10
+           ztmp0 = cd_neutral_10m(ztmp0)                                                 ! Cd_n10
+           sqrt_Cd_n10 = sqrt(ztmp0)
+       
+           Ce_n10  = 1.e-3 * (34.6 * sqrt_Cd_n10)                     ! L&Y 2004 eq. (6b)
+           stab    = 0.5 + sign(0.5,zeta_u)                           ! update stability
+           Ch_n10  = 1.e-3*sqrt_Cd_n10*(18.*stab + 32.7*(1. - stab))  ! L&Y 2004 eq. (6c-6d)
+
+           !! Update of transfer coefficients:
+           ztmp1 = 1. + sqrt_Cd_n10/vkarmn*(LOG(zu/10.) - zpsi_m_u)   ! L&Y 2004 eq. (10a)
+           Cd      = ztmp0 / ( ztmp1*ztmp1 )   
+           sqrt_Cd = SQRT( Cd )
          ENDIF
-         !!
-         xlogt = log(zu/10.) - zpsi_hu
-         !!
-         xct = 1. + Ch_n10*xlogt/kappa/sqrt_Cd_n10               ! L & Y eq. (10b)
-         Ch  = Ch_n10*sqrt_Cd/sqrt_Cd_n10/xct
-         !!
-         xct = 1. + Ce_n10*xlogt/kappa/sqrt_Cd_n10               ! L & Y eq. (10c)
-         Ce  = Ce_n10*sqrt_Cd/sqrt_Cd_n10/xct
-         !!
-         !!
+         !
+         ztmp0 = (LOG(zu/10.) - zpsi_h_u) / vkarmn / sqrt_Cd_n10
+         ztmp2 = sqrt_Cd / sqrt_Cd_n10
+         ztmp1 = 1. + Ch_n10*ztmp0               
+         Ch  = Ch_n10*ztmp2 / ztmp1  ! L&Y 2004 eq. (10b)
+         !
+         ztmp1 = 1. + Ce_n10*ztmp0               
+         Ce  = Ce_n10*ztmp2 / ztmp1  ! L&Y 2004 eq. (10c)
+         !
       END DO
-      !!
-      CALL wrk_dealloc( jpi,jpj, dU10, dT, dq, Cd_n10, Ce_n10, Ch_n10, sqrt_Cd_n10, sqrt_Cd, L )
-      CALL wrk_dealloc( jpi,jpj, T_vpot, T_star, q_star, U_star, zeta_u, zeta_t, U_n10 )
-      CALL wrk_dealloc( jpi,jpj, xlogt, xct, zpsi_hu, zpsi_ht, zpsi_m )
-      CALL wrk_dealloc( jpi,jpj, stab )   ! interger
-      !
-      IF( nn_timing == 1 )  CALL timing_stop('TURB_CORE_2Z')
-      !
-    END SUBROUTINE TURB_CORE_2Z
-
-
-    FUNCTION psi_m(zta)   !! Psis, L & Y eq. (8c), (8d), (8e)
+
+      CALL wrk_dealloc( jpi,jpj, U_zu, Ce_n10, Ch_n10, sqrt_Cd_n10, sqrt_Cd )
+      CALL wrk_dealloc( jpi,jpj, zeta_u, stab )
+      CALL wrk_dealloc( jpi,jpj, zpsi_h_u, zpsi_m_u, ztmp0, ztmp1, ztmp2 )
+
+      IF( .NOT. l_zt_equal_zu ) CALL wrk_dealloc( jpi,jpj, zeta_t )
+
+      IF( nn_timing == 1 )  CALL timing_stop('turb_core_2z')
+      !
+   END SUBROUTINE turb_core_2z
+
+
+   FUNCTION cd_neutral_10m( zw10 )
+      !!----------------------------------------------------------------------
+      !! Estimate of the neutral drag coefficient at 10m as a function 
+      !! of neutral wind  speed at 10m
+      !!
+      !! Origin: Large & Yeager 2008 eq.(11a) and eq.(11b)
+      !!
+      !! Author: L. Brodeau, june 2014
+      !!----------------------------------------------------------------------    
+      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   zw10           ! scalar wind speed at 10m (m/s)
+      REAL(wp), DIMENSION(jpi,jpj)             ::   cd_neutral_10m
+      !
+      REAL(wp), DIMENSION(:,:), POINTER ::   rgt33
+      !!----------------------------------------------------------------------    
+      !
+      CALL wrk_alloc( jpi,jpj, rgt33 )
+      !
+      !! When wind speed > 33 m/s => Cyclone conditions => special treatment
+      rgt33 = 0.5_wp + SIGN( 0.5_wp, (zw10 - 33._wp) )   ! If zw10 < 33. => 0, else => 1  
+      cd_neutral_10m = 1.e-3 * ( &
+         &       (rgt33 + 1._wp)*( 2.7_wp/zw10 + 0.142_wp + zw10/13.09_wp - 3.14807E-10*zw10**6) & ! zw10< 33.
+         &      + rgt33         *      2.34   )                                                    ! zw10 >= 33.
+      !
+      CALL wrk_dealloc( jpi,jpj, rgt33)
+      !
+   END FUNCTION cd_neutral_10m
+
+
+   FUNCTION psi_m(pta)   !! Psis, L&Y 2004 eq. (8c), (8d), (8e)
       !-------------------------------------------------------------------------------
-      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: zta
-
-      REAL(wp), PARAMETER :: pi = 3.141592653589793_wp
+      ! universal profile stability function for momentum
+      !-------------------------------------------------------------------------------
+      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) :: pta
+      !
       REAL(wp), DIMENSION(jpi,jpj)             :: psi_m
       REAL(wp), DIMENSION(:,:), POINTER        :: X2, X, stabit
       !-------------------------------------------------------------------------------
-
+      !
       CALL wrk_alloc( jpi,jpj, X2, X, stabit )
-
-      X2 = sqrt(abs(1. - 16.*zta))  ;  X2 = max(X2 , 1.0) ;  X  = sqrt(X2)
-      stabit    = 0.5 + sign(0.5,zta)
-      psi_m = -5.*zta*stabit  &                                                          ! Stable
-         &    + (1. - stabit)*(2*log((1. + X)/2) + log((1. + X2)/2) - 2*atan(X) + pi/2)  ! Unstable 
-
+      !
+      X2 = SQRT( ABS( 1. - 16.*pta ) )  ;  X2 = MAX( X2 , 1. )   ;   X = SQRT( X2 )
+      stabit = 0.5 + SIGN( 0.5 , pta )
+      psi_m = -5.*pta*stabit  &                                                          ! Stable
+         &    + (1. - stabit)*(2.*LOG((1. + X)*0.5) + LOG((1. + X2)*0.5) - 2.*ATAN(X) + rpi*0.5)  ! Unstable
+      !
       CALL wrk_dealloc( jpi,jpj, X2, X, stabit )
       !
-    END FUNCTION psi_m
-
-
-    FUNCTION psi_h( zta )    !! Psis, L & Y eq. (8c), (8d), (8e)
+   END FUNCTION psi_m
+
+
+   FUNCTION psi_h( pta )    !! Psis, L&Y 2004 eq. (8c), (8d), (8e)
       !-------------------------------------------------------------------------------
-      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   zta
+      ! universal profile stability function for temperature and humidity
+      !-------------------------------------------------------------------------------
+      REAL(wp), DIMENSION(jpi,jpj), INTENT(in) ::   pta
       !
       REAL(wp), DIMENSION(jpi,jpj)             ::   psi_h
-      REAL(wp), DIMENSION(:,:), POINTER        :: X2, X, stabit
+      REAL(wp), DIMENSION(:,:), POINTER        ::   X2, X, stabit
       !-------------------------------------------------------------------------------
       !
       CALL wrk_alloc( jpi,jpj, X2, X, stabit )
       !
-      X2 = sqrt(abs(1. - 16.*zta))  ;  X2 = max(X2 , 1.) ;  X  = sqrt(X2)
-      stabit    = 0.5 + sign(0.5,zta)
-      psi_h = -5.*zta*stabit   &                                       ! Stable
-         &    + (1. - stabit)*(2.*log( (1. + X2)/2. ))                 ! Unstable
-         !
+      X2 = SQRT( ABS( 1. - 16.*pta ) )   ;   X2 = MAX( X2 , 1. )   ;   X = SQRT( X2 )
+      stabit = 0.5 + SIGN( 0.5 , pta )
+      psi_h = -5.*pta*stabit   &                                       ! Stable
+         &    + (1. - stabit)*(2.*LOG( (1. + X2)*0.5 ))                ! Unstable
+      !
       CALL wrk_dealloc( jpi,jpj, X2, X, stabit )
       !
-    END FUNCTION psi_h
-  
+   END FUNCTION psi_h
+
    !!======================================================================
 END MODULE sbcblk_core
