SUBROUTINE LASSIETL(KST,KPROF,PRCORI,PGMV,PGMVS,PGFL, &
 & PSDIV0,PTOD0,PGAGT0L,PGAGT0M, &
 & PGMV5,PGMV5S,PGFL5,PSDIV5,PTOD5,PGAGT5L,PGAGT5M)

!**** *LASSIETL* Semi-Lagrangian scheme.  (tangent-linear version)
!                Computation of linear terms used in the semi-implicit scheme. 

!     Purpose.
!     --------
!        Computation of linear terms used in the semi-implicit scheme:
!        Nabla(Gamma*T+Mu*Pi), (Tau*D) and (Nu*D).

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

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

!        INPUT:
!          KST      - first element of work.
!          KPROF    - depth of work.
!          PRCORI   - Coriolis parameter.
!          PGMV     - GMV variables at t-dt and t.
!          PGMVS    - GMVS variables at t-dt and t.
!          PGFL     - unified_treatment grid-point (GFL) fields.

!        OUTPUT:
!          PSDIV0   - semi-implicit term at time t for continuity equation
!                     (Nu*D).
!          PTOD0    - semi-implicit term at time t for temperature equation
!                     (Tau*D).
!          PGAGT0L  - semi-implicit term at time t for U-wind equation
!                     (zonal component of Nabla(Gamma*T+Mu*Pi)).
!          PGAGT0M  - semi-implicit term at time t for V-wind equation
!                     (meridian component of Nabla(Gamma*T+Mu*Pi)).

!        TRAJECTORY INPUT:
!          PGMV5    - trajectory for PGMV.
!          PGMV5S   - trajectory for PGMVS.
!          PGFL5    - trajectory for PGFL.

!        TRAJECTORY OUTPUT:
!          PSDIV5   - semi-implicit term at time t for continuity equation
!                     (Nu*D).  (trajectory)
!          PTOD5    - semi-implicit term at time t for temperature equation
!                     (Tau*D). (trajectory)
!          PGAGT5L  - semi-implicit term at time t for U-wind equation
!                     (zonal component of Nabla(Gamma*T+Mu*Pi)). (traj.)
!          PGAGT5M  - semi-implicit term at time t for V-wind equation
!                     (meridian component of Nabla(Gamma*T+Mu*Pi)). (traj.)

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

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

!     Externals.
!     ----------
!           Called by LACDYNTL.

!     Reference.
!     ----------
!             Arpege documentation about semi-lagrangian scheme.

!     Author.
!     -------
!        C. Temperton (ECMWF)

!     Modifications.
!     --------------
!     Original : 99/07/20
!     Modified 01-01-23 by C. Temperton: case LSPRT=.T. corrected.
!     Modified by A. Untch 2000-12 : Vertical finite element scheme
!     M.Hamrud      01-Oct-2003 CY28 Cleaning
!     M.Jidane  08-04-2006 : Reintro of R dep. on q variables under key
!     K. Yessad Aug 2008: rationalisation of dummy argument interfaces
!     ------------------------------------------------------------------

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

USE YOMCST   , ONLY : RD       ,RV
USE YOMCT0   , ONLY : LTWOTL   ,LSPRT
USE YOMDIM   , ONLY : NPROMA   ,NFLEVG
USE YOMDYN   , ONLY : LIMPF    ,LDRY_ECMWF
USE YOMGMV   , ONLY : NDIMGMV  ,NDIMGMVS ,YT0      ,YT5
USE YOM_YGFL , ONLY : YGFL     ,YQ

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

IMPLICIT NONE

INTEGER(KIND=JPIM),INTENT(IN)    :: KST 
INTEGER(KIND=JPIM),INTENT(IN)    :: KPROF 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PRCORI(NPROMA) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PGMV(NPROMA,NFLEVG,NDIMGMV)
REAL(KIND=JPRB)   ,INTENT(IN)    :: PGMVS(NPROMA,NDIMGMVS)
REAL(KIND=JPRB)   ,INTENT(IN)    :: PGFL(NPROMA,NFLEVG,YGFL%NDIM)
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PSDIV0(NPROMA) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PTOD0(NPROMA,NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PGAGT0L(NPROMA,NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PGAGT0M(NPROMA,NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PGMV5(NPROMA,NFLEVG,YT5%NDIM)
REAL(KIND=JPRB)   ,INTENT(IN)    :: PGMV5S(NPROMA,YT5%NDIMS)
REAL(KIND=JPRB)   ,INTENT(IN)    :: PGFL5(NPROMA,NFLEVG,YGFL%NDIM5)
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PSDIV5(NPROMA) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PTOD5(NPROMA,NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PGAGT5L(NPROMA,NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PGAGT5M(NPROMA,NFLEVG) 

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

REAL(KIND=JPRB) :: ZR0  (NPROMA,NFLEVG)
REAL(KIND=JPRB) :: ZR5  (NPROMA,NFLEVG)
INTEGER(KIND=JPIM) :: IPROFS, JLEV, JROF

REAL(KIND=JPRB) :: ZHOOK_HANDLE

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

#include "abor1.intfb.h"
#include "sigam.intfb.h"
#include "sitnu.intfb.h"

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

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

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

IF (.NOT.LTWOTL) THEN
  CALL ABOR1(' LASSIETL: CALLED WITH LTWOTL=.F.')
ENDIF

IPROFS=KPROF-KST+1

! * Trajectory 
!  - Computation of Nu*D (SI term for continuity equation)
!     and Tau*D (SI term for temperature equation).
CALL SITNU(NPROMA,1,PGMV5(KST,1,YT5%MDIV),PTOD5(KST,1),PSDIV5(KST),IPROFS)
!   - Computation of Nabla(Gamma*T+Mu*Pi) (SI term for momentum equation).
CALL SIGAM(NPROMA,1,PGAGT5L(KST,1),PGMV5(KST,1,YT5%MTL),PGMV5S(KST,YT5%MSPL),&
 & IPROFS)
CALL SIGAM(NPROMA,1,PGAGT5M(KST,1),PGMV5(KST,1,YT5%MTM),PGMV5S(KST,YT5%MSPM),&
 & IPROFS)

! * Perturbation
!  - Computation of Nu*D (SI term for continuity equation)
!     and Tau*D (SI term for temperature equation).
CALL SITNU(NPROMA,1,PGMV(KST,1,YT0%MDIV),PTOD0(KST,1),PSDIV0(KST),IPROFS)
!   - Computation of Nabla(Gamma*T+Mu*Pi) (SI term for momentum equation).
CALL SIGAM(NPROMA,1,PGAGT0L(KST,1),PGMV(KST,1,YT0%MTL),PGMVS(KST,YT0%MSPL),&
 & IPROFS)
CALL SIGAM(NPROMA,1,PGAGT0M(KST,1),PGMV(KST,1,YT0%MTM),PGMVS(KST,YT0%MSPM),&
 & IPROFS)

!     * Modify (Tau*D) if (LSPRT=.T.) in temperature equation to compensate
!       for later multiplication by R/Rd:

IF (LSPRT) THEN
  DO JLEV=1,NFLEVG
    DO JROF=KST,KPROF
      ZR5(JROF,JLEV)=RD+(RV-RD)*PGFL5(JROF,JLEV,YQ%MP5)
      PTOD0(JROF,JLEV)=RD*PTOD0(JROF,JLEV)/ZR5(JROF,JLEV)  
    ENDDO
    IF (.NOT. LDRY_ECMWF) THEN
      DO JROF=KST,KPROF
        ZR0(JROF,JLEV)=(RV-RD)*PGFL(JROF,JLEV,YQ%MP)
        PTOD0(JROF,JLEV)=PTOD0(JROF,JLEV)-RD*PTOD5(JROF,JLEV)*ZR0(JROF,JLEV)&
          & /(ZR5(JROF,JLEV)*ZR5(JROF,JLEV)) 
      ENDDO
    ENDIF
    DO JROF=KST,KPROF
      PTOD5(JROF,JLEV)=RD*PTOD5(JROF,JLEV)/ZR5(JROF,JLEV)
    ENDDO
  ENDDO
ENDIF

!     * Add semi-implicit Coriolis terms to Nabla(Gamma*T+Mu*Pi)
!       if required (LIMPF=.T.).

IF (LIMPF) THEN
  DO JLEV=1,NFLEVG
    DO JROF=KST,KPROF
      PGAGT0L(JROF,JLEV)=PGAGT0L(JROF,JLEV)-PRCORI(JROF)*PGMV(JROF,JLEV,YT0%MV)
      PGAGT0M(JROF,JLEV)=PGAGT0M(JROF,JLEV)+PRCORI(JROF)*PGMV(JROF,JLEV,YT0%MU)
      PGAGT5L(JROF,JLEV)=PGAGT5L(JROF,JLEV)-PRCORI(JROF)*PGMV5(JROF,JLEV,YT5%MV)
      PGAGT5M(JROF,JLEV)=PGAGT5M(JROF,JLEV)+PRCORI(JROF)*PGMV5(JROF,JLEV,YT5%MU)
    ENDDO
  ENDDO
ENDIF

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

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

