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

!**** *SIGAM* - Solve hydrostatic operator in semi-implicit

!     Purpose.
!     --------
!           Operator gamma to compute p.

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

!        Explicit arguments :
!        --------------------
!        KLEV   : DISTANCE IN MEMORY BETWEEN VALUES OF THE DIVERGENCE
!                OR TEMPERATURE AT THE 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       (output)
!        PT    : TEMPERATURE      (input)
!        PSP   : SURFACE PRESSURE (input)
!        KNLON : NUMBER OF VERTICAL COLUMNS TREATED

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

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

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

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

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

!     Modifications.
!     --------------
!        Original : 87-10-15
!        Modified 95-10-01 Adapted for Message Passing
!        Modified 2000-05  Modifications for vertical finite elements
!        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 linear model.
!        F. Vana + NEC 28-Apr-2009: OpenMP
!     ------------------------------------------------------------------

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

USE YOMCT0   , ONLY : LNHDYN
USE YOMDIM   , ONLY : NFLEVG
USE YOMCST   , ONLY : RD
USE YOMDYN   , ONLY : SIALPH   ,SILNPR   ,SIRPRG
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(OUT)   :: PD(1+(NFLEVG-1)*KLEV+(KNLON-1)*KLON) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PT(1+(NFLEVG-1)*KLEV+(KNLON-1)*KLON) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PSP(KNLON) 

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

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

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

#include "verint.intfb.h"

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

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

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

!*       1.    SUM GEOPOTENTIAL, COMPUTES P AND PUT IT IN PD.
!              ----------------------------------------------

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
      ZSPHI(JLON,JLEV)=-RD*PT(IDT)*SILNPR(JLEV)*VFE_RDETAH(JLEV)
    ENDDO
!$OMP END DO
  ENDDO
!$OMP END PARALLEL
  CALL VERINT(KNLON,1,KNLON,NFLEVG,ZSPHI(1,1),ZOUT,1)
!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
      PD(IDT)=ZOUT(JLON,JLEV-1)+PSP(JLON)*SIRPRG
    ENDDO
!$OMP END DO
  ENDDO
!$OMP END PARALLEL
ELSE
  ZSPHI(:,NFLEVG)=0.0_JPRB

!cdir outerunroll=8
!$OMP PARALLEL PRIVATE(JLEV,JLON,IDT)
  DO JLEV=NFLEVG,1,-1
!$OMP DO
    DO JLON=1,KNLON
      IDT=1+(JLEV-1)*KLEV+(JLON-1)*KLON
      ZSPHI(JLON,JLEV-1)=ZSPHI(JLON,JLEV)+RD*PT(IDT)*SILNPR(JLEV)
      PD(IDT)=ZSPHI(JLON,JLEV)+SIALPH(JLEV)*RD*PT(IDT)+PSP(JLON)*SIRPRG
    ENDDO
!$OMP END DO
  ENDDO
!$OMP END PARALLEL
ENDIF

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

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