!options xopt(noeval)
subroutine hlturb(  kstep  ,                      &
     &              ldmse  ,                      & 
     &              knhor  ,  knlev ,   kstart  , &
     &              kstop  ,  pdtime,   pt      , &
     &              pq     ,  pu    ,   pv      , &
     &              pcw    ,  pcice ,   ptke    , &
     &              pgpoth ,                      &
     &              pgpot  ,  ppf   ,   pph     , &
     &              pts    ,  ppblh ,             &
     &              pcld2  ,  pdifts,   pdiftq  , &
     &              pdiftql,  pdiftqn,  pdiftke , &
     &              pstrtu ,  pstrtv,   psenf   , &
     &              pfev   ,  pfmdu,    pfmdv   , &
     &              ptendu ,  ptendv,   ptendt  , &
     &              ptendtke, ptendq,   ptendql , &
     &              ptendqi,                      &
     &              cdlock )  

!     -------------------------------------------------------------------

!     PURPOSE: (*)  Interface routine between the physics calling
!     --------      routine HL_APLPAR and the HIRLAM turbulence scheme 
!                   HLVCBR. This remark applies to both input and output. 

!     -------------------------------------------------------------------
!     INTERFACE  :  subroutine 'HLTURB' is called 
!     ------------  from subroutine 'HL_APLPAR' 

!     INPUT/OUTPUT  arguments  (arguments d'entree/sortie)
!     -----------------------------------------------------  
!     kstep  : time step number of forecast
!     knhor  : number of horizontal grid points in loops
!     knlev  : number of vertical levels 
!     kstart : start index of horizontal loops 
!     kstop  : end index of horiczontal loops 
!     pdtime : time step (s)
!     pt     : current time level model level temperature (K)  
!     pq     : current time level model level specific humidity 
!     pu     : current time level model level wind towards east 
!     pv     : current time level model level wind towards north
!     pcw    : current time level model level cloud water 
!     pcice  : current time level model level cloud ice
!     ptke   : current time level model level turb.kin. energy.(m**2/s**2)
!     pgpoth : half level geopotential relative to MSL ( m**2/s**2 )
!     pgpot  : full level geopotential relative to MSL ( m**2/s**2 ) 
!     ppf    : full level model pressure (Pa) 
!     pph    : half level model pressure (Pa), NB: defined from 0:NLEV 
!     pts    : surface temperature (K)
!     psenf  : surface sensible heat flux (W/m2) ,positive downwards.
!     pfev   : surface evaporation flux (kg/(m2 s)), positive downwards 
!     pfmdu  : surface momentum flux (u-dir),(kg/(m*s2)), positive downward
!     pfmdv  : surface momentum flux (v-dir),(kg/(m*s2)), positive downward
!     pblh   : boundary layer height (m) 
!     pcld2  : model level total cloud cover  
!     pdifts : flux profile of enthalpy due to turbulence  
!     pdiftq : flux profile of specific humidity due to turbulence
!     pdiftql: flux profile of cloud water due to turbulence
!     pdiftqn: flux profile of cloud ice due to turbulence 
!     pdiftke: flux profile of TKE due to turbulence 
!     pstrtu : flux profile of momentum (Kg/(m s2)) due to turbulence    
!     pstrtv : flux profile of momentum (Kg/(m s2)) due to turbulence   
!     ptendu   : accumulated  u-momentum physics tendency     
!     ptendv   : accumulated  v-momentum physics tendency
!     ptendt   : accumulated  temperature physics tendency 
!     ptendtke : accumulated  tke physics tendency 
!     ptendq   : accumulated  specific humidity physics tendency 
!     ptendql  : accumulated  specific cloud water physics tendency 
!     ptendqi  : accumulated  cpecific cloud ice physics tendency
!     ------------------------------------------------------------------

!     EXTERNAL SUBROUTINES:   HLVCBR
!     ----------------------     

!     AUTHOR:         Bent H. Sass,   01 June 2006 
!     -------      

!     MODIFICATIONS.
!     --------------
!     13-May-2007  S.Niemela     Renaming from HLVCBR to HLTURB in order not
!                                to mix this interface to HIRLAM one.


!     ==================================================================
!     1. Declarations. 
!     ==================================================================
!     1.1 MODULES USED  

use parkind1  ,only : jpim     ,jprb
use yhlconst  ,only : cpair    ,ccpq,   latvap,   latice,   tmelt,  rair
use yhloption ,only : lhltend
use yomhook   ,only : lhook,   dr_hook

!     1.2 ARGUMENT DECLARATIONS
!     ----------------------------------------------------
      implicit none                                                           

integer(kind=jpim),  intent(in)           ::   kstep
integer(kind=jpim),  intent(in)           ::   knhor
integer(kind=jpim),  intent(in)           ::   knlev
integer(kind=jpim),  intent(in)           ::   kstart
integer(kind=jpim),  intent(in)           ::   kstop

logical,             intent(in)           ::   ldmse

real(kind=jprb)   ,  intent(in)           ::   pdtime

real(kind=jprb)   ,  intent(in)           ::   pts(knhor)
real(kind=jprb)   ,  intent(in)           ::   psenf(knhor)
real(kind=jprb)   ,  intent(in)           ::   pfev(knhor)
real(kind=jprb)   ,  intent(in)           ::   pfmdu(knhor)
real(kind=jprb)   ,  intent(in)           ::   pfmdv(knhor)
real(kind=jprb)   ,  intent(in)           ::   ppblh(knhor)

real(kind=jprb)   ,  intent(in)           ::   pt(knhor,knlev) 
real(kind=jprb)   ,  intent(in)           ::   pq(knhor,knlev)
real(kind=jprb)   ,  intent(in)           ::   pu(knhor,knlev)
real(kind=jprb)   ,  intent(in)           ::   pv(knhor,knlev)
real(kind=jprb)   ,  intent(in)           ::   pcw(knhor,knlev)
real(kind=jprb)   ,  intent(in)           ::   pcice(knhor,knlev)
real(kind=jprb)   ,  intent(inout)        ::   ptke(knhor,knlev)
real(kind=jprb)   ,  intent(in)           ::   pgpoth(knhor,0:knlev)
real(kind=jprb)   ,  intent(in)           ::   pgpot(knhor,knlev)
real(kind=jprb)   ,  intent(in)           ::   ppf(knhor,knlev)
real(kind=jprb)   ,  intent(in)           ::   pph(knhor,0:knlev)
real(kind=jprb)   ,  intent(in)           ::   pcld2(knhor,knlev)
real(kind=jprb)   ,  intent(inout)        ::   pdifts(knhor, 0:knlev) 
real(kind=jprb)   ,  intent(inout)        ::   pdiftq(knhor, 0:knlev)
real(kind=jprb)   ,  intent(inout)        ::   pdiftql(knhor,0:knlev)
real(kind=jprb)   ,  intent(inout)        ::   pdiftqn(knhor,0:knlev)
real(kind=jprb)   ,  intent(inout)        ::   pdiftke(knhor,0:knlev)
real(kind=jprb)   ,  intent(inout)        ::   pstrtu(knhor, 0:knlev)
real(kind=jprb)   ,  intent(inout)        ::   pstrtv(knhor, 0:knlev) 
real(kind=jprb)   ,  intent(inout)        ::   ptendu  (knhor,knlev)
real(kind=jprb)   ,  intent(inout)        ::   ptendv  (knhor,knlev)
real(kind=jprb)   ,  intent(inout)        ::   ptendt  (knhor,knlev)
real(kind=jprb)   ,  intent(inout)        ::   ptendtke(knhor,knlev)
real(kind=jprb)   ,  intent(inout)        ::   ptendq  (knhor,knlev)
real(kind=jprb)   ,  intent(inout)        ::   ptendql (knhor,knlev)
real(kind=jprb)   ,  intent(inout)        ::   ptendqi (knhor,knlev)

CHARACTER(LEN=6)  ,  INTENT(IN)           ::   cdlock 

!  1.3  OTHER DECLARATIONS
!  -------------------------

logical            ::   llstat

real(kind=jprb)    ::   zstdif(knlev)
real(kind=jprb)    ::   zstddif(knlev) 

real(kind=jprb)    ::   zgpot(knhor,knlev)
real(kind=jprb)    ::   zdtdt(knhor,knlev)
real(kind=jprb)    ::   zdqdt(knhor,knlev)
real(kind=jprb)    ::   zdudt(knhor,knlev)
real(kind=jprb)    ::   zdvdt(knhor,knlev)
real(kind=jprb)    ::   zdcwdt(knhor,knlev)
real(kind=jprb)    ::   zdicedt(knhor,knlev)
real(kind=jprb)    ::   zdtkedt(knhor,knlev)

real(kind=jprb)    ::   zdpf(knhor,knlev)
real(kind=jprb)    ::   zps(knhor)
real(kind=jprb)    ::   ztaux(knhor)
real(kind=jprb)    ::   ztauy(knhor)
real(kind=jprb)    ::   ztau(knhor)
real(kind=jprb)    ::   zuvnum(knhor)
real(kind=jprb)    ::   zlatf(knhor)
real(kind=jprb)    ::   zustar(knhor) 

real(kind=jprb)    ::   zsecur 
real(kind=jprb)    ::   zhook_handle
integer(kind=jpim) ::   jk, jl

!     1.5  Special include files (interface files):
!     ---------------------------------------------
#include "abor1.intfb.h"
#include "hlvcbr.intfb.h"
#include "hltend2flx.intfb.h"

if (lhook) call dr_hook('hlturb',0,zhook_handle)

!     CHECK RELIABILITY OF INPUT ARGUMENTS.
IF(CDLOCK /= 'HLTURB') CALL ABOR1('BAD NUMBER OF ARGUMENTS!')

!     ----------------------------------------------- 
!     2.   Call the turbulence scheme 
!     -----------------------------------------------

!     ======================================================
!     2.0: Preparation of the correct input arpuments 

        llstat=.false.

        zsecur=1.0E-12_JPRB

        do jk=1,knlev
          zstdif(jk) =0._JPRB
          zstddif(jk)=0._JPRB
        enddo 

       
        do jl=kstart,kstop 
          zps(jl)   = pph(jl,knlev)
        enddo        

      if( ldmse ) then   

        do jl=kstart,kstop 
          ztau(jl)  = sqrt( pfmdu(jl)*pfmdu(jl) + &
  &                         pfmdv(jl)*pfmdv(jl) +zsecur )
        enddo 

      else 

        do jl=kstart,kstop
          ztau(jl)  = sqrt( pstrtu(jl,knlev)*pstrtu(jl,knlev) + &
  &                         pstrtv(jl,knlev)*pstrtv(jl,knlev) +zsecur )
        enddo

      endif 

        do jl=kstart,kstop
          zuvnum(jl)= sqrt( pu(jl,knlev)*pu(jl,knlev) + &
  &                         pv(jl,knlev)*pv(jl,knlev) +zsecur )

          ztaux(jl) = ztau(jl)*pu(jl,knlev)/zuvnum(jl)
          ztauy(jl) = ztau(jl)*pv(jl,knlev)/zuvnum(jl)

        enddo 

      if( ldmse ) then   

        do jl=kstart,kstop 
          if( pts(jl) >= tmelt ) then 
            zlatf(jl)=pfev(jl)*latvap
          else 
            zlatf(jl)=pfev(jl)*(latvap +latice)
          endif 
        enddo
      else  

        do jl=kstart,kstop
          if( pts(jl) >= tmelt ) then
            zlatf(jl)=pdiftq(jl,knlev)*latvap
          else
            zlatf(jl)=pdiftq(jl,knlev)*(latvap +latice)
          endif
        enddo
      endif 

        do jl=kstart,kstop 
          zustar(jl)=ztau(jl)*( rair*pts(jl) )/zps(jl)
          zustar(jl)=sqrt( zustar(jl) )
          zustar(jl)= max( zustar(jl) , 0.005_jprb )
        enddo 

     do jk=1,knlev
      do jl=kstart,kstop
          ptke(jl,jk)=max( 0.01_jprb, min( ptke(jl,jk), 20.0_jprb ) )
       enddo
     enddo

      do jk=knlev,1,-1
        do jl=kstart,kstop
          zgpot(jl,jk)=pgpot(jl,jk) -pgpoth(jl,knlev)
        enddo 
      enddo    

      do jk=1,knlev
        do jl=kstart,kstop
          zdtdt  (jl,jk)=0.0_jprb
          zdqdt  (jl,jk)=0.0_jprb
          zdcwdt (jl,jk)=0.0_jprb
          zdicedt(jl,jk)=0.0_jprb
          zdtkedt(jl,jk)=0.0_jprb
          zdudt  (jl,jk)=0.0_jprb
          zdvdt  (jl,jk)=0.0_jprb
        enddo 
      enddo 

      do jk=0,knlev
        do jl=kstart,kstop 
          pdifts(jl,jk) =0.0_jprb
          pdiftql(jl,jk)=0.0_jprb
          pdiftqn(jl,jk)=0.0_jprb
          pdiftke(jl,jk)=0.0_jprb
        enddo 
      enddo

      do jk=0,knlev-1 
        do jl=kstart,kstop     
          pdiftq(jl,jk) =0.0_jprb
          pstrtu(jl,jk) =0.0_jprb
          pstrtv(jl,jk) =0.0_jprb
        enddo 
      enddo 
!     ---------------------------------------------------------
!     Call the CBR scheme 

      call hlvcbr( knhor   ,  knlev  ,    kstart ,    &
     &             kstop   ,  pdtime ,    llstat ,    &
     &             pt      ,  pq     ,    pu     ,    &
     &             pv      ,  pcw    ,    pcice  ,    &
     &             2       ,                          &
     &             ptke    ,  zgpot  ,    ppf    ,    &
     &             pph     ,  pcld2  ,                &
     &             pts     ,  zps    ,    ztaux  ,    &
     &             ztauy   ,  psenf  ,    zlatf  ,    &
     &             zustar  ,  ppblh  ,    zdtdt  ,    &
     &             zdqdt   ,  zdudt  ,    zdvdt  ,    &
     &             zdcwdt  ,  zdicedt,    zdtkedt,    &
     &             zstdif  ,  zstddif,    'hlvcbr'    )

!     =========================================================
!     3. Make appropriate conversions to produce 
!        suitable output (tendencies to fluxes)  
!     ---------------------------------------------------------

!     3.1  (Save fluxes in tendency arrays)  
!          Save tendencies in 'flux arrays'

      do jk=1,knlev
        do jl=kstart,kstop
          pdifts (jl,jk) = zdtdt(jl,jk)  
          pdiftq (jl,jk) = zdqdt(jl,jk) 
          pdiftql(jl,jk) = zdcwdt(jl,jk)       
          pdiftqn(jl,jk) = zdicedt(jl,jk)
          pdiftke(jl,jk) = zdtkedt(jl,jk)
          pstrtu (jl,jk) = zdudt(jl,jk)
          pstrtv (jl,jk) = zdvdt(jl,jk) 

!         Update accumulated physics tendencies

          if( lhltend ) then 
            ptendu(jl,jk)   = ptendu(jl,jk)   + zdudt(jl,jk)
            ptendv(jl,jk)   = ptendv(jl,jk)   + zdvdt(jl,jk)
            ptendt(jl,jk)   = ptendt(jl,jk)   + zdtdt(jl,jk)
            ptendtke(jl,jk) = ptendtke(jl,jk) + zdtkedt(jl,jk)
            ptendq(jl,jk)   = ptendq(jl,jk)   + zdqdt(jl,jk)
            ptendql(jl,jk)  = ptendql(jl,jk)  + zdcwdt(jl,jk)
            ptendqi(jl,jk)  = ptendqi(jl,jk)  + zdicedt(jl,jk)
          endif 

        enddo 
      enddo 


        do jl=kstart,kstop
          pdifts  (jl,0) = 0.0_jprb
          pdiftq  (jl,0) = 0.0_jprb
          pdiftql (jl,0) = 0.0_jprb
          pdiftqn (jl,0) = 0.0_jprb
          pdiftke (jl,0) = 0.0_jprb 
          pstrtu  (jl,0) = 0.0_jprb
          pstrtv  (jl,0) = 0.0_jprb
        enddo 

!     3.2 Convert 'pdifts' (temporary temperature tendency) and 
!         'pdiftq' (temporary humidity tendency) to enthalpy 
!         tendency ("enthalpy") = T*cpair*ccpq* dq/dt + cp*dT/dt
!         Compute pressure thickness 'zdpf' 
!     ---------------------------------------------------------      

      do jk=1,knlev
        do jl=kstart,kstop
          pdifts(jl,jk)=                              &
     &    pdifts(jl,jk)*cpair*(1. +ccpq*pq(jl,jk)) +  &
     &    pt(jl,jk)*cpair*ccpq*pdiftq(jl,jk)
          zdpf(jl,jk)=pph(jl,jk) -pph(jl,jk-1)
        enddo 
      enddo 

!     3.3 Compute the conversion from tendencies to fluxes for
!         the different output parameters , by calls to the
!         conversion routine 'tend2flx':
!     ---------------------------------------------------------

      call hltend2flx ( knhor ,    knlev,    kstart,  &
     &                  kstop ,    zdpf ,    pdifts   )

      call hltend2flx ( knhor ,    knlev,    kstart,  &
     &                  kstop ,    zdpf ,    pdiftq   )

      call hltend2flx ( knhor ,    knlev,    kstart,  &
     &                  kstop ,    zdpf ,    pdiftql  )

      call hltend2flx ( knhor ,    knlev,    kstart,  &
     &                  kstop ,    zdpf ,    pdiftqn  )

      call hltend2flx ( knhor ,    knlev,    kstart,  &
     &                  kstop ,    zdpf ,    pdiftke  )

      call hltend2flx ( knhor ,    knlev,    kstart,  &
     &                  kstop ,    zdpf ,    pstrtu   )

      call hltend2flx ( knhor ,    knlev,    kstart,  &
     &                  kstop ,    zdpf ,    pstrtv   )

!    =========================================================
if (lhook) call dr_hook('hlturb',1,zhook_handle)
end subroutine hlturb
