SUBROUTINE GPPREFTL(KPROMA,KSTART,KPROF,KFLEV,&
 & PALPH,PRESH,PRESF,&
 & PALPH5,PRESH5)  

!**** *GPPREFTL* - Computes full level pressure, tangent linear

!     Purpose.
!     --------
!           Computes pressures at full model levels - T.L.

!**   Interface.
!     ----------
!        *CALL* *GPPREFTL(KPROMA,KSTART,KPROF,KFLEV,
!                       ,PALPH,PRESH,PRESF
!                       ,PALPH5,PRESH5)

!        Explicit arguments :
!        --------------------
!                              KPROMA    : DIMENSIONING
!                              KSTART    : START OF THE PACKET.
!                              KPROF     : DEPTH OF WORK
!                              KFLEV     : VERT. DIMENSIONING
!                              PRESH(KPROMA,0:KFLEV) - HALF LEVEL PRESSURE
!                              PRESF(KPROMA,KFLEV)   - FULL LEVEL PRESSURE
!                              PALPH (KPROMA,KFLEV)  - COEFF OF THE HYDROST
!                              PRESH(KPROF,0:KFLEV) - HALF LEVEL PRESSURE
!                              PRESF(KPROF,KFLEV)   - FULL LEVEL PRESSURE

!                              PALPH5(KPROMA,KFLEV)  - COEFF OF THE HYDROST
!                              PRESH5(KPROMA,0:KFLEV)- HALF LEVEL PRESSURE

!        Implicit arguments :  None.
!        --------------------

!     Method.
!     -------
!        See documentation
!     Half level P:     PHk = Ak + Bk * Ps

!                                PHk*ln(PHk) - PHk-1*ln(PHk-1)
!     Full level P: ln(PFk) = [ ------------------------------- - 1. ]
!                                        PHk - PHk-1

!     which simplifies to:  PFk = Pk+1/2 * exp(-ALPHA)

!     In case of NDLNPR=1 it becomes even simpler (no need of LAPRXP any
!     more in principle !) :
!                           PFk = Pk+1/2 * (1.-ALPHA) except at the top
!     level :
!                           PF1 = P1.5 / (2+Cv/R)

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

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

!     Author.
!     -------
!        Erik Andersson and Jean-Noel THEPAUT

!     Modifications.
!     --------------
!        Original : 92-11-23
!        Modified : 95-01-31 by Radmila Bubnova: correction in the case
!                            of the other approximation of d (ln p).
!        Modified : 2000-11 by Agathe Untch: vertical finite element scheme
!        M.Hamrud      01-Oct-2003 CY28 Cleaning
!        Modified : 04-11-15 by K. YESSAD: improve the hierarchy of tests
!        Modified : 15-Feb-2005 by K. YESSAD: ZTOPPRES becomes TOPPRES
!     ---------------------------------------------------------------------

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

USE YOMCT0   , ONLY : LAPRXPK
USE YOMDYN   , ONLY : NDLNPR
USE YOMCST   , ONLY : RD       ,RCVD
USE YOMCVER  , ONLY : LVERTFE
USE YOMGEM   , ONLY : VBF      ,TOPPRES

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

IMPLICIT NONE

INTEGER(KIND=JPIM),INTENT(IN)    :: KPROMA 
INTEGER(KIND=JPIM),INTENT(IN)    :: KFLEV 
INTEGER(KIND=JPIM),INTENT(IN)    :: KSTART 
INTEGER(KIND=JPIM),INTENT(IN)    :: KPROF 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PALPH(KPROMA,KFLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PRESH(KPROMA,0:KFLEV) 
REAL(KIND=JPRB)   ,INTENT(OUT)   :: PRESF(KPROMA,KFLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PALPH5(KPROMA,KFLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PRESH5(KPROMA,0:KFLEV) 

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

INTEGER(KIND=JPIM) :: IFIRST, JLEV, JLON
REAL(KIND=JPRB) :: ZMUL
REAL(KIND=JPRB) :: ZHOOK_HANDLE

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

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

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

!*       1.    Level to begin normal computations
!              ----------------------------------

! This is introduced to allow the use of GPPREFTL without the implicit
! assumption that the top level input for pressure is 0 hPa.
! This restriction is only necessary in the case of use of NDLNPR=1.

IF ((.NOT.LVERTFE).AND.(NDLNPR == 1)) THEN
  IF(PRESH5(KSTART,0) <= TOPPRES)THEN
    IFIRST=2
  ELSE
    IFIRST=1
    DO JLON=KSTART,KPROF
      IF(PRESH5(JLON,0) <= TOPPRES)THEN
        IFIRST=2
        EXIT
      ENDIF
    ENDDO
  ENDIF
ENDIF

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

!*       2.    COMPUTES FULL LEVEL PRESSURES.
!              ------------------------------

IF (LVERTFE) THEN
  DO JLEV=1,KFLEV
    PRESF(KSTART:KPROF,JLEV)=VBF(JLEV)*PRESH(KSTART:KPROF,KFLEV)
  ENDDO
ELSE
  IF (NDLNPR == 0) THEN
    IF (LAPRXPK) THEN
      DO JLEV=1,KFLEV
        DO JLON=KSTART,KPROF
          PRESF(JLON,JLEV)=(PRESH(JLON,JLEV-1)+PRESH(JLON,JLEV))*0.5_JPRB
        ENDDO
      ENDDO
    ELSE
      DO JLEV=1,KFLEV
        DO JLON=KSTART,KPROF
          PRESF(JLON,JLEV)=EXP(-PALPH5(JLON,JLEV))*PRESH(JLON,JLEV)&
           & -EXP(-PALPH5(JLON,JLEV))*PRESH5(JLON,JLEV)&
           & *PALPH(JLON,JLEV)  
        ENDDO
      ENDDO
    ENDIF
  ELSEIF (NDLNPR == 1) THEN
    DO JLEV=IFIRST,KFLEV
      DO JLON=KSTART,KPROF
        PRESF(JLON,JLEV)=(1.0_JPRB-PALPH5(JLON,JLEV))*PRESH(JLON,JLEV)&
         & -PRESH5(JLON,JLEV)*PALPH(JLON,JLEV)  
      ENDDO
    ENDDO
    ZMUL=1.0_JPRB/(2.0_JPRB+RCVD/RD)
    DO JLEV=1,IFIRST-1
      DO JLON=KSTART,KPROF
        PRESF(JLON,JLEV)=PRESH(JLON,JLEV)*ZMUL
      ENDDO
    ENDDO
  ENDIF
ENDIF

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

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