SUBROUTINE SITNU(KLEV,KLON,PD,PT,PSP,KNLON)

!**** *SITNU*   - Continuity equation for semi-implicit.

!     Purpose.
!     --------
!           Evaluate operators Tau and Nu in semi-implicit.

!**   Interface.
!     ----------
!        *CALL* *SITNU(KLEV,KLON,PD,PT,PSP,KNLON)

!        Explicit arguments :
!        --------------------
!        KLEV   : DISTANCE IN MEMORY BETWEEN VALUES OF THE DIVERGENCE
!                OR TEMPERATURE AT THE SAME VERTICAL
!        KLON   : DISTANCE IN MEMORY BETWEEN VALUES OF THE DIVERGENCE
!                OR TEMPERATURE AT THE SAME LEVEL

!           TYPICAL VALUES ARE  NDLSUR,1  FOR GRID POINT ARRAY
!                               1,NFLSUR  FOR SPECTRAL ARRAY

!        PD    : DIVERGENCE
!        PT    : TEMPERATURE
!        PSP   : SURFACE PRESSURE
!        KNLON : NUMBER OF VERTICAL COLUMNS TREATED

!        Implicit arguments :
!        --------------------

!     Method.
!     -------
!        See documentation

!     Externals.   None.
!     ----------

!     Reference.
!     ----------
!        ECMWF Research Department documentation of the IFS

!     Author.
!     -------
!        Mats Hamrud and Philippe Courtier  *ECMWF*

!     Modifications.
!     --------------
!        Original : 87-10-15
!        MPP group  95-10-01 Adapted for Message Passing
!        M.Hamrud      01-Oct-2003 CY28 Cleaning
!        Modified : 09-Oct-2007 by K. YESSAD: possibility to have a specific
!                   value of LVERTFE in the SI NH linear model.
!        F. Vana + NEC 28-Apr-2009: OpenMP + optimization
!     ------------------------------------------------------------------

USE PARKIND1  ,ONLY : JPIM     ,JPRB
USE YOMHOOK   ,ONLY : LHOOK,   DR_HOOK

USE YOMCT0   , ONLY : LNHDYN
USE YOMDIM   , ONLY : NFLEVG
USE YOMCST   , ONLY : RKAPPA
USE YOMDYN   , ONLY : SIALPH   ,SILNPR   ,SIDELP   ,SIRDEL   ,&
 & SITR     ,SIRPRN   ,SITLAF  
USE YOMGEM   , ONLY : VFE_RDETAH
USE YOMCVER  , ONLY : LVERTFE  ,LRNHC1

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

IMPLICIT NONE

INTEGER(KIND=JPIM),INTENT(IN)    :: KLEV 
INTEGER(KIND=JPIM),INTENT(IN)    :: KLON 
INTEGER(KIND=JPIM),INTENT(IN)    :: KNLON 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PD(1+(NFLEVG-1)*KLEV+(KNLON-1)*KLON) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PT(1+(NFLEVG-1)*KLEV+(KNLON-1)*KLON) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PSP(KNLON) 

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

REAL(KIND=JPRB) :: ZSDIV(KNLON,0:NFLEVG), ZOUT(KNLON,0:NFLEVG)
LOGICAL :: LLVFE
INTEGER(KIND=JPIM) :: IDT, JLEV, JLON
REAL(KIND=JPRB) :: ZREC
REAL(KIND=JPRB) :: ZHOOK_HANDLE

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

#include "verint.intfb.h"

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

IF (LHOOK) CALL DR_HOOK('SITNU',0,ZHOOK_HANDLE)

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

!*       1.    SUM DIVERGENCE AND COMPUTES TEMPERATURE.
!              ----------------------------------------

IF(LNHDYN.AND.LRNHC1) THEN
  LLVFE=.FALSE.
ELSE
  LLVFE=LVERTFE
ENDIF

IF(LLVFE) THEN
!cdir outerunroll=8
!$OMP PARALLEL PRIVATE(JLEV,JLON,IDT)
  DO JLEV=1,NFLEVG
!$OMP DO
    DO JLON=1,KNLON
      IDT=1+(JLEV-1)*KLEV+(JLON-1)*KLON
      ZSDIV(JLON,JLEV)=PD(IDT)*SIDELP(JLEV)*VFE_RDETAH(JLEV)
    ENDDO
!$OMP END DO
  ENDDO
!$OMP END PARALLEL
  CALL VERINT(KNLON,1,KNLON,NFLEVG,ZSDIV(1,1),ZOUT,0)
!cdir outerunroll=8
!$OMP PARALLEL PRIVATE(JLEV,JLON,IDT,ZREC)
  DO JLEV=1,NFLEVG
    ZREC=1.0_JPRB/SITLAF(JLEV)
!$OMP DO
    DO JLON=1,KNLON
      IDT=1+(JLEV-1)*KLEV+(JLON-1)*KLON
      PT(IDT)=RKAPPA*SITR*ZOUT(JLON,JLEV-1)*ZREC
    ENDDO
!$OMP END DO
  ENDDO
!$OMP END PARALLEL
ELSE
  DO JLON=1,KNLON
    ZSDIV(JLON,0)=0.0_JPRB
  ENDDO
!cdir outerunroll=8
!$OMP PARALLEL PRIVATE(JLEV,JLON,IDT)
  DO JLEV=1,NFLEVG
!$OMP DO
    DO JLON=1,KNLON
      IDT=1+(JLEV-1)*KLEV+(JLON-1)*KLON
      ZSDIV(JLON,JLEV)=ZSDIV(JLON,JLEV-1)+PD(IDT)*SIDELP(JLEV)
      PT(IDT)=RKAPPA*SITR*(SIRDEL(JLEV)*SILNPR(JLEV)*ZSDIV(JLON,&
       & JLEV-1)&
       & +SIALPH(JLEV)*PD(IDT))  
    ENDDO
!$OMP END DO
  ENDDO
!$OMP END PARALLEL
ENDIF
!     ------------------------------------------------------------------

!*       2.    COMPUTES SURFACE PRESSURE.
!              --------------------------

DO JLON=1,KNLON
  IF(LLVFE) THEN
    PSP(JLON)=ZOUT(JLON,NFLEVG)*SIRPRN
  ELSE
    PSP(JLON)=ZSDIV(JLON,NFLEVG)*SIRPRN
  ENDIF
ENDDO

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

IF (LHOOK) CALL DR_HOOK('SITNU',1,ZHOOK_HANDLE)
END SUBROUTINE SITNU
