SUBROUTINE LANHSIB( &
 ! --- INPUT ------------------------------------------------------------------
 & KST,KPROF,PBT,PBDT,PESGP,&
 & PGAGT0L,PGAGT0M,PTOD0,PSPDS0,PLPD0,PSDIV0,PNHXT0,& 
 ! --- INPUT-OUTPUT -----------------------------------------------------------
 & PGMV,PB1, &
 ! --- OUTPUT -----------------------------------------------------------------
 & PB2)

!**** *LANHSIB*   Semi-Lagrangian scheme.
!        Storage and memory transfers for linear terms.
!        NH-PDVD model with LGWADV=T.

!     Purpose.
!     --------
!        Storage and memory transfers for linear terms.
!        NH-PDVD model with LGWADV=T.

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

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

!        INPUT:
!          KST      - first element of work.
!          KPROF    - depth of work.
!          PBT      - PDTS2*BETADT (BETADT is in YOMDYN).
!          PBDT     - PBT if semi-implicit scheme with unreduced
!                        divergence, PBT*(c**2/GM**2) if semi-implicit
!                        scheme with reduced divergence.
!          PESGP    - first  order decentering factor
!          PGAGT0L  - semi-implicit term at time t for U-wind equation.
!          PGAGT0M  - semi-implicit term at time t for V-wind equation.
!          PTOD0    - semi-implicit term at time t for temperature equation.
!          PSPDS0   - semi-implicit term at time t for "P-hat" equation.
!          PLPD0    - semi-implicit term at time t for "d-hat" equation.
!          PSDIV0   - semi-implicit term at time t for "ln(pi_s)" equation.
!          PNHXT0   - "Xterm" on layers at t.

!        INPUT-OUTPUT:
!          PGMV     - GMV variables.
!          PB1      - SLBUF1 buffer for interpolations.

!        OUTPUT:
!          PB2      - SLBUF2 buffer.

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

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

!     Externals.
!     ----------
!           Called by LACDYN.

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

!     Author.
!     -------
!        J. Vivoda (SHMI/LACE) 

!     Modifications.
!     --------------
!   Original : Feb 2005
!   N. Wedi and K. Yessad (Nov 2007): ND4SYS to improve NH model stability
!   N. Wedi and K. Yessad (Jan 2008): different dev for NH model and PC scheme
!     ------------------------------------------------------------------

USE PARKIND1 ,ONLY : JPIM     ,JPRB
USE YOMHOOK  ,ONLY : LHOOK    ,DR_HOOK
USE YOMCT3   ,ONLY : NSTEP
USE YOMDYNA  ,ONLY : NVDVAR   ,ND4SYS
USE YOMDYN   ,ONLY : XIDT     ,LSLINLC2 ,LSLINL   ,NCURRENT_ITER
USE YOMDIM   ,ONLY : NFLEVG   ,NPROMA   ,NPROMNH  ,NFLSA
USE YOMGMV   ,ONLY : NDIMGMV  ,YT9 
USE YOMSC2   ,ONLY : NFLDSLB1 ,NFLDSLB2
USE PTRSLB1  ,ONLY : MSLB1U9_SI,MSLB1V9_SI,MSLB1T9_SI,MSLB1VD9_SI,MSLB1PD9_SI,&
 & MSLB1C9_SI
USE PTRSLB2  ,ONLY : MSLB2USI ,MSLB2VSI ,MSLB2TSI ,MSLB2PDSI,MSLB2VDSI,MSLB2SPSI

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

IMPLICIT NONE

INTEGER(KIND=JPIM),INTENT(IN)    :: KST 
INTEGER(KIND=JPIM),INTENT(IN)    :: KPROF 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PBT
REAL(KIND=JPRB)   ,INTENT(IN)    :: PBDT(NPROMA)
REAL(KIND=JPRB)   ,INTENT(IN)    :: PESGP
REAL(KIND=JPRB)   ,INTENT(IN)    :: PGAGT0L(NPROMA,NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PGAGT0M(NPROMA,NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PTOD0(NPROMA,NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PSPDS0(NPROMNH,NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PLPD0(NPROMNH,NFLEVG) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PSDIV0(NPROMA) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PNHXT0(NPROMA,NFLEVG)
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PGMV(NPROMA,NFLEVG,NDIMGMV)
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PB1(NPROMA,NFLDSLB1)
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PB2(NPROMA,NFLDSLB2)

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

INTEGER(KIND=JPIM) :: JLEV, JROF
REAL(KIND=JPRB)    :: ZBT,ZBDT(NPROMA) 
REAL(KIND=JPRB)    :: ZHOOK_HANDLE

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

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

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

!     1. SEMI-IMPLICIT LINEAR MODEL CORRECTED WITH TIME STEP AND
!       CENTERING FACTORS
!     ----------------------------------------------------------

IF (XIDT > 0.0_JPRB)THEN
  ZBT=(1.0_JPRB+XIDT)*PBT
  ZBDT(KST:KPROF)=(1.0_JPRB+XIDT)*PBDT(KST:KPROF)
ELSE
  ZBT=PBT
  ZBDT(KST:KPROF)=PBDT(KST:KPROF)
ENDIF

! * multiplication by time step
DO JLEV = 1,NFLEVG
  DO JROF = KST,KPROF
    PB2(JROF,MSLB2USI-1+JLEV)=ZBT*PGAGT0L(JROF,JLEV)
    PB2(JROF,MSLB2VSI-1+JLEV)=ZBT*PGAGT0M(JROF,JLEV)
    PB2(JROF,MSLB2TSI-1+JLEV)=ZBDT(JROF)*PTOD0(JROF,JLEV)
    PB2(JROF,MSLB2PDSI-1+JLEV)=ZBDT(JROF)*PSPDS0(JROF,JLEV)
    PB2(JROF,MSLB2VDSI-1+JLEV)=ZBT*PLPD0(JROF,JLEV)
  ENDDO
ENDDO
DO JROF = KST,KPROF
  PB2(JROF,MSLB2SPSI)=ZBDT(JROF)*PSDIV0(JROF)
ENDDO

! * first-order decentering factor
IF(PESGP > 1.0_JPRB)THEN
  DO JROF = KST,KPROF
    PB2(JROF,MSLB2SPSI)=PESGP*PB2(JROF,MSLB2SPSI)
  ENDDO
  DO JLEV=1,NFLEVG
    DO JROF = KST,KPROF
      PB2(JROF,MSLB2USI-1+JLEV)=PESGP*PB2(JROF,MSLB2USI-1+JLEV)
      PB2(JROF,MSLB2VSI-1+JLEV)=PESGP*PB2(JROF,MSLB2VSI-1+JLEV)
      PB2(JROF,MSLB2TSI-1+JLEV)=PESGP*PB2(JROF,MSLB2TSI-1+JLEV)
      PB2(JROF,MSLB2PDSI-1+JLEV)=PESGP*PB2(JROF,MSLB2PDSI-1+JLEV)
      PB2(JROF,MSLB2VDSI-1+JLEV)=PESGP*PB2(JROF,MSLB2VDSI-1+JLEV)
    ENDDO
  ENDDO
ENDIF

! * add NHX-term to the equation for 
!   (K.Y.: I have serious doubts about the multiplication of NHX by PESGP).
IF( NVDVAR == 4 )THEN
  IF (ND4SYS==1 .OR. (ND4SYS==2 .AND. NCURRENT_ITER==0)) THEN
    DO JLEV=1,NFLEVG
      DO JROF = KST,KPROF
        PB2(JROF,MSLB2VDSI-1+JLEV)=PB2(JROF,MSLB2VDSI-1+JLEV) &
         & +PESGP*PNHXT0(JROF,JLEV)
      ENDDO
    ENDDO
  ELSEIF (ND4SYS==2 .AND. NCURRENT_ITER>0) THEN
    DO JLEV=1,NFLEVG
      DO JROF = KST,KPROF
        PB2(JROF,MSLB2VDSI-1+JLEV)=PB2(JROF,MSLB2VDSI-1+JLEV) &
         & +PESGP*PGMV(JROF,JLEV,YT9%MNHX)
      ENDDO
    ENDDO
  ENDIF
ENDIF

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

!     2. FILL PB1 WHEN REQUIRED 
!     -------------------------

! If NSTEP <= 0, values at t-dt are equal to values a 't', what is added in PB1
! is simply 0 in this case.
IF (NSTEP > 0 .AND. NCURRENT_ITER==0) THEN
  ! * Put 0.5 Dt betadt (Lin(t)-Lin(t-dt)) if XIDT=0 in PB1
  !   Put 0.5 Dt (1+XIDT) betadt (Lin(t)-Lin(t-dt)) in PB1 if XIDT>0
  IF (LSLINLC2) THEN
    DO JLEV = 1,NFLEVG
      DO JROF = KST,KPROF
        PB1(JROF,MSLB1C9_SI+JLEV-NFLSA)=PB1(JROF,MSLB1C9_SI+JLEV-NFLSA) &
         & +ZBDT(JROF)*PSDIV0(JROF)-PGMV(JROF,JLEV,YT9%MSPNL_SI)
      ENDDO
    ENDDO
  ENDIF
  IF (LSLINL) THEN
    DO JLEV = 1,NFLEVG
      DO JROF = KST,KPROF
        PB1(JROF,MSLB1U9_SI+JLEV-NFLSA)=PB1(JROF,MSLB1U9_SI+JLEV-NFLSA) &
         & + ZBT*PGAGT0L(JROF,JLEV)-PGMV(JROF,JLEV,YT9%MUNL_SI)
        PB1(JROF,MSLB1V9_SI+JLEV-NFLSA)=PB1(JROF,MSLB1V9_SI+JLEV-NFLSA) &
         & + ZBT*PGAGT0M(JROF,JLEV)-PGMV(JROF,JLEV,YT9%MVNL_SI)
        PB1(JROF,MSLB1T9_SI+JLEV-NFLSA)=PB1(JROF,MSLB1T9_SI+JLEV-NFLSA) &
         & + ZBDT(JROF)*PTOD0(JROF,JLEV)-PGMV(JROF,JLEV,YT9%MTNL_SI)
        PB1(JROF,MSLB1PD9_SI+JLEV-NFLSA)=PB1(JROF,MSLB1PD9_SI+JLEV-NFLSA) &
         & + ZBDT(JROF)*PSPDS0(JROF,JLEV)-PGMV(JROF,JLEV,YT9%MSPDNL_SI)
        PB1(JROF,MSLB1VD9_SI+JLEV-NFLSA)=PB1(JROF,MSLB1VD9_SI+JLEV-NFLSA) &
         & + ZBT*PLPD0(JROF,JLEV)-PGMV(JROF,JLEV,YT9%MSVDNL_SI)
      ENDDO
    ENDDO
  ENDIF
ENDIF

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

!     3. SAVE 't' VALUES WHEN REQUIRED 
!     --------------------------------

! * Save 't' values of linear terms (with 'beta Dt' but without uncentering
!   factor) when required:
IF (LSLINLC2 .AND. NCURRENT_ITER==0) THEN
  DO JLEV = 1,NFLEVG
    DO JROF = KST,KPROF
      PGMV(JROF,JLEV,YT9%MSPNL_SI)=ZBDT(JROF)*PSDIV0(JROF)
    ENDDO
  ENDDO
ENDIF
IF (LSLINL .AND. NCURRENT_ITER==0) THEN
  DO JLEV = 1,NFLEVG
    DO JROF = KST,KPROF
      PGMV(JROF,JLEV,YT9%MUNL_SI)=ZBT*PGAGT0L(JROF,JLEV)
      PGMV(JROF,JLEV,YT9%MVNL_SI)=ZBT*PGAGT0M(JROF,JLEV)
      PGMV(JROF,JLEV,YT9%MTNL_SI)=ZBDT(JROF)*PTOD0(JROF,JLEV)
      PGMV(JROF,JLEV,YT9%MSPDNL_SI)=ZBDT(JROF)*PSPDS0(JROF,JLEV)
      PGMV(JROF,JLEV,YT9%MSVDNL_SI)=ZBT*PLPD0(JROF,JLEV)
    ENDDO
  ENDDO
ENDIF

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

