SUBROUTINE LASCAW_VINTW_TL(KPROM,KFLEV,KSLEV,KST,KPROF,LDT_SLHD,&
 & KLEV,PLEV,PDVER,PKAPPA,PVETA,PVCUICO_,PVSLD_,PVSLDW_,&
 & PLEV5,PDVER5,PKAPPA5,PVINTW,PVINTWSLD,PVINTW5,PVINTWSLD5)

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

!**** *LASCAW_VINTW_TL-  Weights for semi-LAgrangian interpolator:
!                        Computes PVINTW and PVINTWSLD for one layer
!                        (high-order vertical weights):
!                        TL + trajectory code

!     Purpose.
!     --------

!**   Interface.
!     ----------
!        *CALL* *LASCAW_VINTW_TL( ... )

!        Explicit arguments :
!        --------------------

!        INPUT:
!          KPROM    - horizontal dimension.
!          KFLEV    - vertical dimension.
!          KSLEV    - start vertical dimension (0 or 1).
!                     if zero, the routine is used for half level data.
!                     if one, the routine is used for full level data.
!          KST      - first element of arrays where computations are performed.
!          KPROF    - depth of work.
!          LDT_SLHD - keys for SLHD.
!          KLEV     - lower level of the vertical interpolation
!                     grid needed for vertical interpolations.
!          PLEV     - vertical coordinate of the interpolation point.
!          PDVER    - distance for vertical linear interpolation.
!          PKAPPA   - kappa function ("coefficient of SLHD").
!          PVETA    - Values of ETA (full or half level according to KSLEV).
!          PVCUICO_ - Denominators of the vertical cubic interpolation coef.
!          PVSLD_   - auxiliary quantities for vertical SLHD interpolation.
!          PVSLDW_  - weights for SLHD vertical Laplacian smoother.
!          PLEV5    - cf. PLEV (trajectory).
!          PDVER5   - cf. PDVER (trajectory).
!          PKAPPA5  - cf. PKAPPA (trajectory).

!        OUTPUT:
!          PVINTW    - vertical cubic interpolation weights.
!          PVINTWSLD - vertical cubic interpolation weights, SLHD case.
!          PVINTW5   - cf. PVINTW (trajectory).
!          PVINTWSLD5- cf. PVINTWSLD (trajectory).

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

!     Method.
!     -------
!        See documentation about semi-Lagrangian scheme.

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

!        No external.
!        Called by some (E)LASCAWTL routines.

!     Reference.
!     ----------

!     Author.
!     -------
!        K. YESSAD, after former LASCAWTL code (JAN 2009).
!        METEO-FRANCE, CNRM/GMAP.

!     Modifications.
!     --------------
!     ------------------------------------------------------------------

USE PARKIND1  ,ONLY : JPIM     ,JPRB
USE YOMHOOK   ,ONLY : LHOOK    ,DR_HOOK 
USE YOMDYNA  , ONLY : SLHDKMIN ,SLHDKMAX
USE YOMLASCAW, ONLY : KPDUP

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

IMPLICIT NONE

INTEGER(KIND=JPIM), INTENT(IN)  :: KPROM
INTEGER(KIND=JPIM), INTENT(IN)  :: KFLEV
INTEGER(KIND=JPIM), INTENT(IN)  :: KSLEV
INTEGER(KIND=JPIM), INTENT(IN)  :: KST
INTEGER(KIND=JPIM), INTENT(IN)  :: KPROF
LOGICAL           , INTENT(IN)  :: LDT_SLHD(3)
INTEGER(KIND=JPIM), INTENT(IN)  :: KLEV(KPROM,KSLEV:KFLEV+KSLEV-1)
REAL(KIND=JPRB)   , INTENT(IN)  :: PLEV(KPROM,KSLEV:KFLEV+KSLEV-1)
REAL(KIND=JPRB)   , INTENT(IN)  :: PDVER(KPROM,KSLEV:KFLEV+KSLEV-1)
REAL(KIND=JPRB)   , INTENT(IN)  :: PKAPPA(KPROM,KSLEV:KFLEV+KSLEV-1)
REAL(KIND=JPRB)   , INTENT(IN)  :: PVETA(0:KFLEV+KSLEV)
REAL(KIND=JPRB)   , INTENT(IN)  :: PVCUICO_(KPDUP,4,0:KFLEV-KSLEV)
REAL(KIND=JPRB)   , INTENT(IN)  :: PVSLD_(KPDUP,3,0:KFLEV-KSLEV)
REAL(KIND=JPRB)   , INTENT(IN)  :: PVSLDW_(KPDUP,3,3,0:KFLEV-KSLEV)
REAL(KIND=JPRB)   , INTENT(IN)  :: PLEV5(KPROM,KSLEV:KFLEV+KSLEV-1)
REAL(KIND=JPRB)   , INTENT(IN)  :: PDVER5(KPROM,KSLEV:KFLEV+KSLEV-1)
REAL(KIND=JPRB)   , INTENT(IN)  :: PKAPPA5(KPROM,KSLEV:KFLEV+KSLEV-1)
REAL(KIND=JPRB)   , INTENT(OUT) :: PVINTW(KPROM,KSLEV:KFLEV+KSLEV-1,3)
REAL(KIND=JPRB)   , INTENT(OUT) :: PVINTWSLD(KPROM,KSLEV:KFLEV+KSLEV-1,3)
REAL(KIND=JPRB)   , INTENT(OUT) :: PVINTW5(KPROM,KSLEV:KFLEV+KSLEV-1,3)
REAL(KIND=JPRB)   , INTENT(OUT) :: PVINTWSLD5(KPROM,KSLEV:KFLEV+KSLEV-1,3)

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

INTEGER(KIND=JPIM) :: JROF,IJ_,ILEVV,JLEV
REAL(KIND=JPRB) :: ZWA1,ZWA2,ZWA3,ZWD1,ZWD2,ZWD3,ZWH1,ZWH2,ZWH3
REAL(KIND=JPRB) :: ZWDS1,ZWDS2,ZWDS3,ZWL1,ZWL2,ZWL3
REAL(KIND=JPRB) :: ZWA15,ZWA25,ZWA35,ZWD15,ZWD25,ZWD35,ZWH15,ZWH25,ZWH35
REAL(KIND=JPRB) :: ZWDS15,ZWDS25,ZWDS35,ZWL15,ZWL25,ZWL35
REAL(KIND=JPRB) :: ZD05,ZD15,ZD25,ZD35
LOGICAL :: LLSLHD,LLSLHDQUAD,LLSLHD_OLD
REAL(KIND=JPRB) :: ZHOOK_HANDLE

!     ------------------------------------------------------------------
IF (LHOOK) CALL DR_HOOK('LASCAW_VINTW_TL',0,ZHOOK_HANDLE)
!     ------------------------------------------------------------------

LLSLHD=LDT_SLHD(1)
LLSLHDQUAD=LDT_SLHD(2)
LLSLHD_OLD=LDT_SLHD(3)

! * Calculation of PVINTW and PVINTWSLD
!   + calculation of PVINTW5 and PVINTWSLD5:
DO JLEV=1,KFLEV
!CDIR NODEP
DO JROF=KST,KPROF

  ! a/ Preliminary calculations:
  IJ_ = MOD(JROF+1-KST,KPDUP)+1
  ILEVV=KLEV(JROF,JLEV)

  ! b/ Trajectory code (in particuliar computes PVINTW5 and PVINTWSLD5):

#if defined(NECSX)
  ! scalar variable initialization (to meet vectorization condition)
  ZWA15=0._JPRB
  ZWA25=0._JPRB
  ZWA35=0._JPRB
  ZWD15=0._JPRB
  ZWD25=0._JPRB
  ZWD35=0._JPRB
  ZWDS15=0._JPRB
  ZWDS25=0._JPRB
  ZWDS35=0._JPRB
  ZWL15=0._JPRB
  ZWL25=0._JPRB
  ZWL35=0._JPRB
  ZWH15=0._JPRB
  ZWH25=0._JPRB
  ZWH35=0._JPRB
  ZD05=0._JPRB
  ZD15=0._JPRB
  ZD25=0._JPRB
  ZD35=0._JPRB
#endif

  IF (ILEVV >= KSLEV.AND.ILEVV <= KFLEV-3) THEN
    ZD05=PLEV5(JROF,JLEV)-PVETA(ILEVV  )
    ZD15=PLEV5(JROF,JLEV)-PVETA(ILEVV+1)
    ZD25=PLEV5(JROF,JLEV)-PVETA(ILEVV+2)
    ZD35=PLEV5(JROF,JLEV)-PVETA(ILEVV+3)
    ZWH15=ZD05     *ZD25*ZD35*PVCUICO_(IJ_,2,ILEVV)
    ZWH25=ZD05*ZD15     *ZD35*PVCUICO_(IJ_,3,ILEVV)
    ZWH35=ZD05*ZD15*ZD25     *PVCUICO_(IJ_,4,ILEVV)
    IF (LLSLHDQUAD) THEN
      ZWL25=PDVER5(JROF,JLEV)
      ZWL15=1.0_JPRB-ZWL25
      ZWL35=PVSLD_(IJ_,3,ILEVV)*ZWL15*ZWL25
      ZWL15=ZWL15+PVSLD_(IJ_,1,ILEVV)*ZWL35
      ZWL25=ZWL25+PVSLD_(IJ_,2,ILEVV)*ZWL35
    ELSEIF (LLSLHD_OLD) THEN
      ZWL25=PDVER5(JROF,JLEV)
      ZWL15=1.0_JPRB-ZWL25
      ZWL35=0.0_JPRB
    ENDIF
    IF (LLSLHD) THEN
      ZWA15=ZWH15+SLHDKMIN*(ZWL15-ZWH15)
      ZWA25=ZWH25+SLHDKMIN*(ZWL25-ZWH25)
      ZWA35=ZWH35+SLHDKMIN*(ZWL35-ZWH35)
      ZWD15=ZWH15+SLHDKMAX*(ZWL15-ZWH15)
      ZWD25=ZWH25+SLHDKMAX*(ZWL25-ZWH25)
      ZWD35=ZWH35+SLHDKMAX*(ZWL35-ZWH35)
      ZWDS15=PVSLDW_(IJ_,1,1,ILEVV)*ZWD15+PVSLDW_(IJ_,1,2,ILEVV)*ZWD25+ &
       & PVSLDW_(IJ_,1,3,ILEVV)*ZWD35
      ZWDS25=PVSLDW_(IJ_,2,1,ILEVV)*ZWD15+PVSLDW_(IJ_,2,2,ILEVV)*ZWD25+ &
       & PVSLDW_(IJ_,2,3,ILEVV)*ZWD35
      ZWDS35=PVSLDW_(IJ_,3,1,ILEVV)*ZWD15+PVSLDW_(IJ_,3,2,ILEVV)*ZWD25+ &
       & PVSLDW_(IJ_,3,3,ILEVV)*ZWD35
      PVINTW5(JROF,JLEV,1)=ZWA15
      PVINTW5(JROF,JLEV,2)=ZWA25
      PVINTW5(JROF,JLEV,3)=ZWA35
      PVINTWSLD5(JROF,JLEV,1)=ZWA15+PKAPPA5(JROF,JLEV)*(ZWDS15-ZWA15)
      PVINTWSLD5(JROF,JLEV,2)=ZWA25+PKAPPA5(JROF,JLEV)*(ZWDS25-ZWA25)
      PVINTWSLD5(JROF,JLEV,3)=ZWA35+PKAPPA5(JROF,JLEV)*(ZWDS35-ZWA35)
    ELSEIF (LLSLHDQUAD) THEN
      ZWA15=ZWH15+SLHDKMIN*(ZWL15-ZWH15)
      ZWA25=ZWH25+SLHDKMIN*(ZWL25-ZWH25)
      ZWA35=ZWH35+SLHDKMIN*(ZWL35-ZWH35)
      PVINTW5(JROF,JLEV,1)=ZWA15
      PVINTW5(JROF,JLEV,2)=ZWA25
      PVINTW5(JROF,JLEV,3)=ZWA35
    ELSE
      PVINTW5(JROF,JLEV,1)=ZWH15
      PVINTW5(JROF,JLEV,2)=ZWH25
      PVINTW5(JROF,JLEV,3)=ZWH35
    ENDIF
  ELSE
    PVINTW5(JROF,JLEV,1)=1.0_JPRB-PDVER5(JROF,JLEV)
    PVINTW5(JROF,JLEV,2)=PDVER5(JROF,JLEV)
    PVINTW5(JROF,JLEV,3)=0.0_JPRB
    IF (LLSLHD) THEN
      PVINTWSLD5(JROF,JLEV,1)=PVINTW5(JROF,JLEV,1)
      PVINTWSLD5(JROF,JLEV,2)=PVINTW5(JROF,JLEV,2)
      PVINTWSLD5(JROF,JLEV,3)=PVINTW5(JROF,JLEV,3)
    ENDIF
  ENDIF

  ! c/ TL code (in particuliar computes PVINTW and PVINTWSLD):

#if defined(NECSX)
  ! scalar variable initialization (to meet vectorization condition)
  ZWA1=0._JPRB
  ZWA2=0._JPRB
  ZWA3=0._JPRB
  ZWD1=0._JPRB
  ZWD2=0._JPRB
  ZWD3=0._JPRB
  ZWDS1=0._JPRB
  ZWDS2=0._JPRB
  ZWDS3=0._JPRB
  ZWL1=0._JPRB
  ZWL2=0._JPRB
  ZWL3=0._JPRB
  ZWH1=0._JPRB
  ZWH2=0._JPRB
  ZWH3=0._JPRB
#endif

  IF (ILEVV >= KSLEV.AND.ILEVV <= KFLEV-3) THEN
    ZWH1=(ZD05*(ZD25+ZD35)+ZD25*ZD35)*PLEV(JROF,JLEV)*PVCUICO_(IJ_,2,ILEVV)  
    ZWH2=(ZD05*(ZD15+ZD35)+ZD15*ZD35)*PLEV(JROF,JLEV)*PVCUICO_(IJ_,3,ILEVV)  
    ZWH3=(ZD05*(ZD15+ZD25)+ZD15*ZD25)*PLEV(JROF,JLEV)*PVCUICO_(IJ_,4,ILEVV)  
    IF (LLSLHDQUAD) THEN
      ZWL2=PDVER(JROF,JLEV)
      ZWL1=-ZWL2
      ZWL3=PVSLD_(IJ_,3,ILEVV)*((ZWL1-ZWL2)*PDVER5(JROF,JLEV)+ZWL2)
      ZWL1=ZWL1+PVSLD_(IJ_,1,ILEVV)*ZWL3
      ZWL2=ZWL2+PVSLD_(IJ_,2,ILEVV)*ZWL3
    ELSEIF (LLSLHD_OLD) THEN
      ZWL2=PDVER(JROF,JLEV)
      ZWL1=-ZWL2
      ZWL3=0.0_JPRB
    ENDIF
    IF (LLSLHD) THEN
      ZWA1=ZWH1+SLHDKMIN*(ZWL1-ZWH1)
      ZWA2=ZWH2+SLHDKMIN*(ZWL2-ZWH2)
      ZWA3=ZWH3+SLHDKMIN*(ZWL3-ZWH3)
      ZWD1=ZWH1+SLHDKMAX*(ZWL1-ZWH1)
      ZWD2=ZWH2+SLHDKMAX*(ZWL2-ZWH2)
      ZWD3=ZWH3+SLHDKMAX*(ZWL3-ZWH3)
      ZWDS1=PVSLDW_(IJ_,1,1,ILEVV)*ZWD1+PVSLDW_(IJ_,1,2,ILEVV)*ZWD2+ &
       & PVSLDW_(IJ_,1,3,ILEVV)*ZWD3
      ZWDS2=PVSLDW_(IJ_,2,1,ILEVV)*ZWD1+PVSLDW_(IJ_,2,2,ILEVV)*ZWD2+ &
       & PVSLDW_(IJ_,2,3,ILEVV)*ZWD3
      ZWDS3=PVSLDW_(IJ_,3,1,ILEVV)*ZWD1+PVSLDW_(IJ_,3,2,ILEVV)*ZWD2+ &
       & PVSLDW_(IJ_,3,3,ILEVV)*ZWD3
      PVINTW(JROF,JLEV,1)=ZWA1
      PVINTW(JROF,JLEV,2)=ZWA2
      PVINTW(JROF,JLEV,3)=ZWA3
      PVINTWSLD(JROF,JLEV,1)=ZWA1+PKAPPA(JROF,JLEV)*(ZWDS15-ZWA15) &
       & +PKAPPA5(JROF,JLEV)*(ZWDS1-ZWA1)
      PVINTWSLD(JROF,JLEV,2)=ZWA2+PKAPPA(JROF,JLEV)*(ZWDS25-ZWA25) &
       & +PKAPPA5(JROF,JLEV)*(ZWDS2-ZWA2)
      PVINTWSLD(JROF,JLEV,3)=ZWA3+PKAPPA(JROF,JLEV)*(ZWDS35-ZWA35) &
       & +PKAPPA5(JROF,JLEV)*(ZWDS3-ZWA3)
    ELSEIF (LLSLHDQUAD) THEN
      ZWA1=ZWH1+SLHDKMIN*(ZWL1-ZWH1)
      ZWA2=ZWH2+SLHDKMIN*(ZWL2-ZWH2)
      ZWA3=ZWH3+SLHDKMIN*(ZWL3-ZWH3)
      PVINTW(JROF,JLEV,1)=ZWA1
      PVINTW(JROF,JLEV,2)=ZWA2
      PVINTW(JROF,JLEV,3)=ZWA3
    ELSE
      PVINTW(JROF,JLEV,1)=ZWH1
      PVINTW(JROF,JLEV,2)=ZWH2
      PVINTW(JROF,JLEV,3)=ZWH3
    ENDIF
  ELSE
    PVINTW(JROF,JLEV,1)=-PDVER(JROF,JLEV)
    PVINTW(JROF,JLEV,2)=PDVER(JROF,JLEV)
    PVINTW(JROF,JLEV,3)=0.0_JPRB
    IF (LLSLHD) THEN
      PVINTWSLD(JROF,JLEV,1)=PVINTW(JROF,JLEV,1)
      PVINTWSLD(JROF,JLEV,2)=PVINTW(JROF,JLEV,2)
      PVINTWSLD(JROF,JLEV,3)=PVINTW(JROF,JLEV,3)
    ENDIF
  ENDIF

ENDDO
ENDDO

!     ------------------------------------------------------------------
IF (LHOOK) CALL DR_HOOK('LASCAW_VINTW_TL',1,ZHOOK_HANDLE)
END SUBROUTINE LASCAW_VINTW_TL
