SUBROUTINE PPLTEMP(KPROMA,KST,KND,KFLEV,PGEO,PT,PXTEMP,LDTOP,PXGEO)

!**** *PPLTEMP* Compute the geopotential for a given temperature in a vertical profile

!      PURPOSE.
!      --------
!           COMPUTE THE PRESSURE OF A GIVEN TEMPERATURE

!**    INTERFACE.
!      ----------
!           *CALL* PPLTEMP( ... )

!           EXPLICITE ARGUMENTS.
!           --------------------
!           KPROMA   : horizontal dimension.                  (INPUT)
!           KST      : start of work.                         (INPUT)
!           KND      : depth of work.                         (INPUT)
!           KFLEV    : number of input model levels.          (INPUT)
!           PGEO     : model full level geopotential          (INPUT)
!           PT       : temperature at full levels             (INPUT)
!           PXTEMP   : value of the given temperature         (INPUT)
!           LDTOP    : search from the top ; else from bottom (INPUT) 
!           PXGEO   : geopotential of the given temperature  (OUTPUT)

!     METHOD.
!     -------
!        SEE DOCUMENTATION
!        Vertical interpolation : linear in geopotential. 
!        Research is performed below the tropopause to avoid selecting
!        a level inthe statosphere.
!        If no level is found, the outut value is either :
!         - the top of the atmosphere if the temperature profile is always 
!           above PXTEMP,
!         - an extrapolated value (following the standard gradient) if the 
!           temperature profile is always below PXTEMP

!      EXTERNALS.
!      ----------
!           NONE

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

!      AUTHOR.
!      -------
!           Ryad El Khatib

!     MODIFICATIONS.
!     --------------
!        ORIGINAL : 2000-12-04
!    R. El Khatib : 03-04-17 Extrapolation below surface.
!        M.Hamrud      01-Oct-2003 CY28 Cleaning
!      -----------------------------------------------------------------

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

USE YOMSTA   , ONLY : RDTDZ1   ,RZTROP   ,STZ      ,NLEXTRAP
USE YOMCST   , ONLY : RG

IMPLICIT NONE

INTEGER(KIND=JPIM),INTENT(IN)    :: KPROMA 
INTEGER(KIND=JPIM),INTENT(IN)    :: KFLEV 
INTEGER(KIND=JPIM),INTENT(IN)    :: KST 
INTEGER(KIND=JPIM),INTENT(IN)    :: KND 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PGEO(KPROMA,KFLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PT(KPROMA,KFLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PXTEMP 
LOGICAL           ,INTENT(IN)    :: LDTOP 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PXGEO(KPROMA) 
INTEGER(KIND=JPIM) :: ILEVT(KPROMA), ILEVB(KPROMA)

INTEGER(KIND=JPIM) :: JROF, JLEV, ISTLEV, IENDLEV, IINCLEV, ILEVTOP

REAL(KIND=JPRB) :: ZDT, ZSECUR, ZDIFF, ZDP, ZINCT

LOGICAL :: LLDONE(KPROMA), LLEXTRA(KPROMA)
REAL(KIND=JPRB) :: ZHOOK_HANDLE

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

!*       1.    COMPUTE LEVELS SURROUNDING THE SEARCHED VALUE
!              ---------------------------------------------

IF (LHOOK) CALL DR_HOOK('PPLTEMP',0,ZHOOK_HANDLE)
DO JLEV=2,KFLEV
  IF (STZ(JLEV) < RZTROP) THEN
    ILEVTOP=JLEV-1
    EXIT
  ENDIF
ENDDO

IF (LDTOP) THEN
  ISTLEV=ILEVTOP+1
  IENDLEV=KFLEV
  IINCLEV=1
ELSE
  ISTLEV=KFLEV
  IENDLEV=ILEVTOP+1
  IINCLEV=-1
ENDIF

ILEVT(KST:KND)=1
ILEVB(KST:KND)=1
LLDONE(KST:KND)=.FALSE.
LLEXTRA(KST:KND)=.FALSE.

ZSECUR=EPSILON(1.0_JPRB)*1000._JPRB
DO JLEV=ISTLEV,IENDLEV,IINCLEV
  DO JROF=KST,KND
    IF (.NOT.LLDONE(JROF)) THEN
      ZDIFF=(PT(JROF,JLEV)-PXTEMP)*(PXTEMP-PT(JROF,JLEV-1))
      IF (ZDIFF > -ZSECUR) THEN
        ILEVT(JROF)=JLEV-1
        ILEVB(JROF)=JLEV
        LLDONE(JROF)=.TRUE.
      ENDIF
    ENDIF
  ENDDO
ENDDO

DO JROF=KST,KND
  IF (LLDONE(JROF)) THEN
    LLEXTRA(JROF) = .FALSE.
  ELSE
    LLEXTRA(JROF) = (MAXVAL(PT(JROF,ILEVTOP:KFLEV)) < PXTEMP)
  ENDIF
ENDDO

!*       2.    INTERPOLATIONS/EXTRAPOLATIONS
!              -----------------------------

DO JROF=KST,KND
  IF (.NOT.LLEXTRA(JROF)) THEN
    ZDT=PT(JROF,ILEVT(JROF))-PT(JROF,ILEVB(JROF))
    ZDP=PGEO(JROF,ILEVT(JROF))-PGEO(JROF,ILEVB(JROF))
    ZINCT=PXTEMP-PT(JROF,ILEVB(JROF))
    IF (ABS(ZDT) < ZSECUR) THEN
      ZINCT=0.0_JPRB
      ZDT=1.0_JPRB
    ENDIF
    PXGEO(JROF)=PGEO(JROF,ILEVB(JROF))+ZINCT*ZDP/ZDT
  ELSE
    PXGEO(JROF)=PGEO(JROF,NLEXTRAP)+(PXTEMP-PT(JROF,NLEXTRAP))*RG/RDTDZ1
  ENDIF
ENDDO

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

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