SUBROUTINE GPPREF(KPROMA,KSTART,KPROF,KFLEV,PALPH,PRESH,PRESF,LDSI)

!**** *GPPREF* - Computes full level pressure

!     Purpose.
!     --------
!           Computes pressures at half and full model levels.

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

!        Explicit arguments :
!        --------------------
!         KPROMA :  dimensioning
!         KSTART :  start of work
!         KPROF  :  depth of work
!         KFLEV     : vert. dimensioning
!         PALPH (KPROMA,KFLEV)  - COEFF OF THE HYDROST
!         PRESH(KPROMA,0:KFLEV) - HALF LEVEL PRESSURE
!         PRESF(KPROMA,KFLEV)   - FULL LEVEL PRESSURE
!         LDSI   : if routine is called in the SI scheme (NH model).

!        Implicit arguments :  NONE.
!        --------------------

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

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

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

!                                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)

!     Author.
!     -------
!        Erik Andersson, Mats Hamrud and Philippe Courtier  *ECMWF*

!     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 : 00-11-22 by Agathe Untch: modifications for vertical
!                            finite elements
!        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
!        Modified : 09-Oct-2007 by K. YESSAD: possibility to have a specific
!                   value (LVERTFE,NDLNPR)=(F,1) in the SI NH linear model. 
!     ------------------------------------------------------------------

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  ,LRNHC1
USE YOMGEM   , ONLY : VAF      ,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) 
LOGICAL,OPTIONAL  ,INTENT(IN)    :: LDSI

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

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

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

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

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

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

IF (PRESENT(LDSI)) THEN
  IF (LDSI.AND.LRNHC1) THEN
    LLVFE=.FALSE.
    INDLNPR=1
  ELSE
    LLVFE=LVERTFE
    INDLNPR=NDLNPR
  ENDIF
ELSE
  LLVFE=LVERTFE
  INDLNPR=NDLNPR
ENDIF

! This is introduced to allow the use of GPPREF 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 INDLNPR=1.

IF ((.NOT.LLVFE).AND.(INDLNPR == 1)) THEN
  IF(PRESH(KSTART,0) <= TOPPRES)THEN
    IFIRST=2
  ELSE
    IFIRST=1
    DO JLON=KSTART,KPROF
      IF(PRESH(JLON,0) <= TOPPRES)THEN
        IFIRST=2
        EXIT
      ENDIF
    ENDDO
  ENDIF
ENDIF

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

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

IF (LLVFE) THEN
  DO JLEV=1,KFLEV
    PRESF(KSTART:KPROF,JLEV)=VAF(JLEV)+VBF(JLEV)*PRESH(KSTART:KPROF,KFLEV)  
  ENDDO
ELSE
  IF (INDLNPR == 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(-PALPH(JLON,JLEV))*PRESH(JLON,JLEV)
        ENDDO
      ENDDO
    ENDIF
  ELSEIF (INDLNPR == 1) THEN
    DO JLEV=IFIRST,KFLEV
      DO JLON=KSTART,KPROF
        PRESF(JLON,JLEV)=(1.0_JPRB-PALPH(JLON,JLEV))*PRESH(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('GPPREF',1,ZHOOK_HANDLE)
END SUBROUTINE GPPREF
