SUBROUTINE LAINOR2AD(KASLB1,KPROMA,KSTART,KPROF,KGLN,KGLX,KFLDN,KFLDX,&
 & KSTABUF,&
 & KVLAG,KWLAG,LDPLANE,&
 & KFLDSLB1,PSLBUF1,&
 & PUL9,PVL9,PCL9,PUL0,PVL0,PCL0,&
 & PUL95,PVL95,PCL95,PUL05,PVL05,PCL05,&
 & PINDX,PINDY,&
 & KSTTYP,PDSTRET,PC2M1,PC2P1,P4JP,PI,PDEPI,PIS2,&
 & PLOCEN,PMUCEN,PLSDEPI,PLATI,PIPI0,PIPI1,PIPI2,&
 & PCOLON,PSILON,PGEMU,PGSQM2,PGECLO,PGESLO,&
 & PCOSCO,PSINCO,PSINLA,PCOPHI,&
 & PCOSCO5,PSINCO5,PSINLA5,PCOPHI5,&
 & PLON,PLAT,&
 & PO,PQ,&
 & PU9,PV9,PC9,&
 & PLON5,PLAT5,&
 & PO5,PQ5,&
 & PU95,PV95,PC95,&
 & PZUZ9,PZVZ9)  

!**** *LAINOR2AD- semi-LAgrangian scheme:   (adjoint version)
!                 INterpolations corresponding to the ORigin.
!                 2D shallow-water model.

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

!      Once the medium point M is known, this subroutine determines
!      the origin O in computing a bow on a great circle and calls
!      a subroutine that performs interpolations at the origin point
!      of the SL trajectory.

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

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

!        INPUT AND INOUT MATCHING WITH INPUT VARIABLES IN THE TL CODE:
!          KASLB1  - horizontal dimension of SLBUF1 array.
!          KPROMA  - horizontal dimension of point handled by this call.
!          KSTART  - first element of arrays where
!                    computations are performed.
!          KPROF   - depth of work.
!          KGLN    - lower dimension for latitude.
!          KGLX    - upper dimension for latitude.
!          KFLDN   - number of the first field.
!          KFLDX   - number of the last field.
!          KSTABUF - for a latitude IGL, KSTABUF(IGL) is the
!                    address of the element corresponding to
!                    (ILON=1,IGL) in the KPROMA arrays.
!          KVLAG   - switch for discretization of continuity equation.
!          KWLAG   - switch for discretization of momentum equation.
!          LDPLANE - switch: .T. = plane geometry; .F. = spherical geometry.
!          KFLDSLB1- second dimension of PSLBUF1
!          PSLBUF1 - SL buffer for interpolations.
!          PUL9    - Quantity to interpolate at O in the U-wind equation.
!          PVL9    - Quantity to interpolate at O in the V-wind equation.
!          PCL9    - Quantity to interpolate at O in the continuity equation.
!          PUL0    - Second quantity to interpolate at O
!                    (if NWLAG=3) in the U-component of the wind equation.
!          PVL0    - Second quantity to interpolate at O
!                    (if NWLAG=3) in the V-component of the wind equation.
!          PCL0    - Second quantity to interpolate at O
!                    (if NVLAG=3) in the continuity equation.
! -------------------------- trajectory variables ---------------------------
!          PUL95   - cf. PUL9.
!          PVL95   - cf. PVL9.
!          PCL95   - cf. PCL9.
!          PUL05   - cf. PUL0.
!          PVL05   - cf. PVL0.
!          PCL05   - cf. PCL0.
! ---------------------------------------------------------------------------
!          PINDX   - x coordinate on the plane.
!          PINDY   - y coordinate on the plane.
!          KSTTYP  - 1: Not tilted pole;  2: Tilted pole.
!          PDSTRET - 2*c (where c is the stretching factor).
!          PC2M1   - c*c-1.
!          PC2P1   - c*c+1.
!          P4JP    - Approximative inverse of the differences of latitudes.
!          PI      - number PI
!          PDEPI   - 2 * PI
!          PIS2    - PI / 2
!          PLOCEN  - geographical longitude of the stretching pole.
!          PMUCEN  - sine of the geographical latitude of the pole.
!          PLSDEPI - (Number of points by latitude) / (2 * PI) .
!          PLATI   - latitude on the computational sphere.
!          PIPI0   - coefficients for the bicubic interpolations.
!          PIPI1   -      "
!          PIPI2   -      "
!          PCOLON  - cosine of the grid-point longitude on the
!                    computational sphere.
!          PSILON  - sine of the grid-point longitude on the
!                    computational sphere.
!          PGEMU   - sine of the grid-point geographical latitude.
!          PGSQM2  - cosine of the grid-point geographical latitude.
!          PGECLO  - cosine of the grid-point geographical longitude.
!          PGESLO  - sine of the grid-point geographical longitude.

!        INPUT/OUTPUT MATCHING WITH INPUT/OUTPUT VARIABLES IN THE TL CODE:
!          PCOSCO  - cos(Longitude-Longitude(grid-point))*cos(Latitude)
!                    of the interpolation point (geographical longitude
!                    and latitude).
!          PSINCO  - sin(Longitude-Longitude(grid-point))*cos(Latitude)
!                    of the interpolation point (geographical longitude
!                    and latitude).
!          PSINLA  - sine of the interpolation point geographical latitude.
!          PCOPHI  - cosine of the geographical angle between the
!                    interpolation point and the grid-point.
! -------------------------- trajectory variables ---------------------------
!          PCOSCO5 - cos(Longitude-Longitude(grid-point))*cos(Latitude)
!                    of the interpolation point (geographical longitude
!                    and latitude).
!          PSINCO5 - sin(Longitude-Longitude(grid-point))*cos(Latitude)
!                    of the interpolation point (geographical longitude
!                    and latitude).
!          PSINLA5 - sine of the interpolation point geographical latitude.
!          PCOPHI5 - cosine of the geographical angle between the
!                    interpolation point and the grid-point.
! ---------------------------------------------------------------------------

!        INPUT AND OUTPUT MATCHING WITH OUTPUT VARIABLES IN THE TL CODE.
!          PLON    - computational sphere longitude of interpolation point.
!          PLAT    - computational sphere latitude of interpolation point.
!          PO      - first element of the wind displacement matrix.
!          PQ      - second element of the wind displacement matrix.
!          PU9     - Interpolated quantity at O in the U-wind equation.
!          PV9     - Interpolated quantity at O in the V-wind equation.
!          PC9     - Interpolated quantity at O in the continuity equation.
! -------------------------- trajectory variables ---------------------------
!          PLON5   - computational sphere longitude of interpolation point.
!          PLAT5   - computational sphere latitude of interpolation point.
!          PO5     - first element of the wind displacement matrix.
!          PQ5     - second element of the wind displacement matrix.
!          PU95    - cf. PU9.
!          PV95    - cf. PV9.
!          PC95    - cf. PC9.
! ---------------------------------------------------------------------------
!          PZUZ9   - Interpolated quantity at O in the U-wind equation
!                    in the SL2TL scheme for case L2TLFF=.T.
!          PZVZ9   - Interpolated quantity at O in the V-wind equation
!                    in the SL2TL scheme for case L2TLFF=.T.
! ---------------------------------------------------------------------------

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

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

!     Externals.
!     ----------
!        Calls LARCIN2AD.
!        Is called by LADINEAD (2D shallow water model).

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

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

!     Modifications.
!     --------------
!        Original : 98/06/15
!        Modified 98-12-15 by C.Temperton: Cleaning, following LAINOR2.
!        Modified 99-07-14 by C.Temperton: [correction to LAINOR2TL]
!        Modified 00-03-06 by C.Temperton: Repairs following optimization
!                                          of 3-D semi-Lagrangian adjoint.
!        Modified 01-08-30 by K. YESSAD: pruning and some other cleanings.
!        M.Hamrud      01-Oct-2003 CY28 Cleaning
!        K. Yessad (Sep 2008): update comments + cleanings.
!        K. Yessad Nov 2008: rationalisation of dummy argument interfaces
!     ------------------------------------------------------------------

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

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

IMPLICIT NONE

INTEGER(KIND=JPIM),INTENT(IN)    :: KASLB1 
INTEGER(KIND=JPIM),INTENT(IN)    :: KPROMA 
INTEGER(KIND=JPIM),INTENT(IN)    :: KGLN 
INTEGER(KIND=JPIM),INTENT(IN)    :: KGLX 
INTEGER(KIND=JPIM),INTENT(IN)    :: KFLDN 
INTEGER(KIND=JPIM),INTENT(IN)    :: KFLDX 
INTEGER(KIND=JPIM),INTENT(IN)    :: KFLDSLB1 
INTEGER(KIND=JPIM),INTENT(IN)    :: KSTART 
INTEGER(KIND=JPIM),INTENT(IN)    :: KPROF 
INTEGER(KIND=JPIM),INTENT(IN)    :: KSTABUF(KGLN:KGLX) 
INTEGER(KIND=JPIM),INTENT(IN)    :: KVLAG 
INTEGER(KIND=JPIM),INTENT(IN)    :: KWLAG 
LOGICAL           ,INTENT(IN)    :: LDPLANE 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PSLBUF1(KASLB1,KFLDSLB1) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PUL9(KASLB1,KFLDN:KFLDX) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PVL9(KASLB1,KFLDN:KFLDX) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PCL9(KASLB1,KFLDN:KFLDX) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PUL0(KASLB1,KFLDN:KFLDX) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PVL0(KASLB1,KFLDN:KFLDX) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PCL0(KASLB1,KFLDN:KFLDX) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PUL95(KASLB1,KFLDN:KFLDX) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PVL95(KASLB1,KFLDN:KFLDX) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PCL95(KASLB1,KFLDN:KFLDX) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PUL05(KASLB1,KFLDN:KFLDX) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PVL05(KASLB1,KFLDN:KFLDX) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PCL05(KASLB1,KFLDN:KFLDX) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PINDX(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PINDY(KPROMA) 
INTEGER(KIND=JPIM),INTENT(IN)    :: KSTTYP 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PDSTRET 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PC2M1 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PC2P1 
REAL(KIND=JPRB)   ,INTENT(IN)    :: P4JP 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PI 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PDEPI 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PIS2 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PLOCEN 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PMUCEN 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PLSDEPI(KGLN:KGLX) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PLATI(KGLN:KGLX) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PIPI0(KGLN:KGLX) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PIPI1(KGLN:KGLX) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PIPI2(KGLN:KGLX) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PCOLON(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PSILON(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PGEMU(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PGSQM2(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PGECLO(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PGESLO(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PCOSCO(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PSINCO(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PSINLA(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PCOPHI(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PCOSCO5(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PSINCO5(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PSINLA5(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PCOPHI5(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PLON(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PLAT(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PO(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PQ(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PU9(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PV9(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PC9(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PLON5(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PLAT5(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PO5(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PQ5(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PU95(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PV95(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PC95(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PZUZ9(KPROMA) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PZVZ9(KPROMA) 

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

INTEGER(KIND=JPIM) :: IWISA
INTEGER(KIND=JPIM) :: IXLAG(6)

REAL(KIND=JPRB) :: ZCOSCO5(KPROMA)
REAL(KIND=JPRB) :: ZSINCO5(KPROMA)
REAL(KIND=JPRB) :: ZSINLA5(KPROMA)
REAL(KIND=JPRB) :: ZCOPHI5(KPROMA)

INTEGER(KIND=JPIM) :: IINC, IROT, JROF

REAL(KIND=JPRB) :: ZUF0(1), ZUF05(1), ZURL0(1), ZURL05(1), ZVF0(1)
REAL(KIND=JPRB) :: ZVF05(1), ZVRL0(1), ZVRL05(1)
REAL(KIND=JPRB) :: ZHOOK_HANDLE

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

#include "larcin2ad.intfb.h"

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

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

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

!*       1.    COMPUTATION OF THE ORIGIN POINT "O" COORDINATES.
!              ------------------------------------------------

IWISA=3
IXLAG(1)=KVLAG
IXLAG(4)=KWLAG

IF(LDPLANE) THEN    !! AD not done !!

  DO JROF=KSTART,KPROF

!   * computations on horizontal plans.

    PSINCO(JROF)=2.0_JPRB*PSINCO(JROF)-PINDY(JROF)
    PCOSCO(JROF)=2.0_JPRB*PCOSCO(JROF)-PINDX(JROF)
  ENDDO

ELSE

  DO JROF=KSTART,KPROF

!   * computations on horizontal plans (TRAJECTORY).

    ZSINLA5(JROF)=PSINLA5(JROF)
    ZSINCO5(JROF)=PSINCO5(JROF)
    ZCOSCO5(JROF)=PCOSCO5(JROF)
    PSINLA5(JROF)=2.0_JPRB*PCOPHI5(JROF)*PSINLA5(JROF)-PGEMU (JROF)
    PSINCO5(JROF)=2.0_JPRB*PCOPHI5(JROF)*PSINCO5(JROF)
    PCOSCO5(JROF)=2.0_JPRB*PCOPHI5(JROF)*PCOSCO5(JROF)-PGSQM2(JROF)

!   * Computation of the angle <0,G> before calling LARCIN:

    ZCOPHI5(JROF)=PCOPHI5(JROF)
    PCOPHI5(JROF)=2.0_JPRB*PCOPHI5(JROF)*PCOPHI5(JROF)-1.0_JPRB

  ENDDO

ENDIF

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

!*       2.    CALL OF LARCIN FOR INTERPOLATIONS.
!              ----------------------------------

IROT=1

!  Warning: ZURL0,ZVRL0,ZUF0,ZVF0,ZURL05,ZVRL05,ZUF05,ZVF05 are not
!              used in this call to LARCIN2AD.

! Compute number of updates for LARCIN2AD:
! 2D-cubic interpolations, 12 each (3 basic ones to start with):
IINC=36 
! 2D-linear interpolations, 4 each :
IF (KWLAG == 3) IINC=IINC+8
IF (KVLAG == 3) IINC=IINC+4

CALL LARCIN2AD(KASLB1,KPROMA,KSTART,KPROF,KGLN,KGLX,KFLDN,KFLDX,&
 & KSTABUF,IWISA,IXLAG,IROT,&
 & LDPLANE,IINC,KFLDSLB1,PSLBUF1,&
 & KSTTYP,PDSTRET,PC2M1,PC2P1,P4JP,PI,PDEPI,PIS2,&
 & PLOCEN,PMUCEN,PLSDEPI,PLATI,PIPI0,PIPI1,PIPI2,&
 & PCOLON,PSILON,PGEMU,PGSQM2,PGECLO,PGESLO,&
 & PCOSCO,PSINCO,PSINLA,PCOPHI,&
 & PCOSCO5,PSINCO5,PSINLA5,PCOPHI5,&
 & ZURL0,ZVRL0,&
 & PUL9,PVL9,PCL9,PUL0,PVL0,PCL0,&
 & ZURL05,ZVRL05,&
 & PUL95,PVL95,PCL95,PUL05,PVL05,PCL05,&
 & PLON,PLAT,&
 & PO,PQ,&
 & ZUF0,ZVF0,&
 & PU9,PV9,PC9,&
 & PLON5,PLAT5,&
 & PO5,PQ5,&
 & ZUF05,ZVF05,&
 & PU95,PV95,PC95,&
 & PZUZ9,PZVZ9)  

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

!*       1.    COMPUTATION OF THE ORIGIN POINT "O" COORDINATES.
!              ------------------------------------------------

IF(LDPLANE) THEN    !! AD not done !!

  DO JROF=KSTART,KPROF

!           computations on horizontal plans.

    PSINCO(JROF)=2.0_JPRB*PSINCO(JROF)-PINDY(JROF)
    PCOSCO(JROF)=2.0_JPRB*PCOSCO(JROF)-PINDX(JROF)
  ENDDO

ELSE

  DO JROF=KSTART,KPROF   !!  (ADJOINT loop)

!           Computation of the angle <0,G> after calling LARCIN2AD:

    PCOPHI(JROF)=4._JPRB*PCOPHI(JROF)*ZCOPHI5(JROF)

!           computations on horizontal plans.

    PCOPHI(JROF)=PCOPHI(JROF)+2.0_JPRB*ZCOSCO5(JROF)*PCOSCO(JROF)
    PCOSCO(JROF)=2.0_JPRB*ZCOPHI5(JROF)*PCOSCO(JROF)
    PCOPHI(JROF)=PCOPHI(JROF)+2.0_JPRB*ZSINCO5(JROF)*PSINCO(JROF)
    PSINCO(JROF)=2.0_JPRB*ZCOPHI5(JROF)*PSINCO(JROF)
    PCOPHI(JROF)=PCOPHI(JROF)+2.0_JPRB*ZSINLA5(JROF)*PSINLA(JROF)
    PSINLA(JROF)=2.0_JPRB*ZCOPHI5(JROF)*PSINLA(JROF)

  ENDDO

ENDIF

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

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

