SUBROUTINE TRICSI(PD,PX,PCA,PCB,PCC,PRDELP,KSPSTA,KSPEND)

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

USE YOMDIM   , ONLY : NFLEVG   ,NFLSUR ,NSMAX
USE YOMLAP   , ONLY : NVALUE

!**** *TRICSI*   - Solve the semi-implicit Helmholtz equation

!     Purpose.    Solve the semi-implicit Helmholtz equation
!     --------    in simple cases (for which
!                 horizontal wavenumbers are independent)
!                 via a tridiagonal matrix.
!                 Can be used only in unstretched version of ARPEGE/IFS
!                  with LIMPF=F.

!**   Interface.
!     ----------
!        *CALL* *TRICSI(PD,PX,PCA,PCB,PCC,PRDELP,KSPSTA,KSPEND)

!        Explicit arguments :
!        --------------------
!        PD          - solution vectors                    (output)
!        PX          - right-hand side vectors             (input)
!        PCA,PCB,PCC - precalculated help arrays           (input)
!        PRDELP      - inverse of reference (delta p)      (input)
!        KSPSTA      - first columns treated               (input)
!        KSPEND      - last  columns treated               (input)

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

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

!     Externals.
!     ----------
!          None.
!          Called by SPCSI.

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

!     Author.
!     -------
!        CLIVE TEMPERTON (MAY 1996)

!     Modifications.
!     --------------
!      L. Isaksen :  96-12-12  Adapted for Message Passing
!      M.Hamrud      01-Oct-2003 CY28 Cleaning
!      K. Yessad (Sep 2008): update comments + cleanings.
!     ------------------------------------------------------------------

IMPLICIT NONE

INTEGER(KIND=JPIM),INTENT(IN)    :: KSPSTA 
INTEGER(KIND=JPIM),INTENT(IN)    :: KSPEND 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PD(NFLSUR,KSPSTA:KSPEND)
REAL(KIND=JPRB)   ,INTENT(IN)    :: PX(NFLSUR,KSPSTA:KSPEND) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PCA(NSMAX,NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PCB(NSMAX,NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PCC(NSMAX,NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PRDELP(NFLEVG) 

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

INTEGER(KIND=JPIM) :: IN, JLEV, JSP
REAL(KIND=JPRB) :: ZHOOK_HANDLE

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

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

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

DO JSP=KSPSTA,KSPEND
  PD(1,JSP)=PCB(NVALUE(JSP),1)*(PX(1,JSP)-PX(2,JSP))
ENDDO

DO JLEV=2,NFLEVG-1
!DIR$ IVDEP
  DO JSP=KSPSTA,KSPEND
    IN=NVALUE(JSP)
    PD(JLEV,JSP)=PCB(IN,JLEV)*(PX(JLEV,JSP)-PX(JLEV+1,JSP)&
     & -PCA(IN,JLEV)*PD(JLEV-1,JSP))  
  ENDDO
ENDDO

!DIR$ IVDEP
DO JSP=KSPSTA,KSPEND
  IN=NVALUE(JSP)
  PD(NFLEVG,JSP)=PCB(IN,NFLEVG)*(PX(NFLEVG,JSP)&
   & -PCA(IN,NFLEVG)*PD(NFLEVG-1,JSP))  
ENDDO

DO JLEV=NFLEVG-1,1,-1
!DIR$ IVDEP
  DO JSP=KSPSTA,KSPEND
    IN=NVALUE(JSP)
    PD(JLEV,JSP)=PD(JLEV,JSP)+PCC(IN,JLEV)*PD(JLEV+1,JSP)
    PD(JLEV+1,JSP)=PRDELP(JLEV+1)*(PD(JLEV+1,JSP)-PD(JLEV,JSP))
  ENDDO

ENDDO

DO JSP=KSPSTA,KSPEND
  PD(1,JSP)=PRDELP(1)*PD(1,JSP)
ENDDO

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

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