SUBROUTINE GNHPRE( &
 ! --- INPUT -------------------------------------------
 & KPROMA,KFLEV,KSTART,KEND,PSPD,PREF, &
 ! --- OUTPUT ------------------------------------------
 & PNHPREF,PNHPPI,PRNHPPI,PDEP, &
 ! --- OPTIONAL INPUT ----------------------------------
 & PLNPR,PRT,POROG,PHIHYD &
 & )

! GNHPRE - Computation of the total pressure "pre" at full levels,
!          from the 'PD' prognostic variable.

! Purpose
! -------
!   Computes at model full levels.
!    * the total pressure "pre".
!    * the pressure departure "pre - prehyd".
!    * the ratios pre/prehyd and prehyd/pre.
!   The vertical derivative is applied to the NH departure of Phi.

! Interface
! ---------
!   INPUT:
!    KPROMA  - horizontal dimension.
!    KFLEV   - number of levels.
!    KSTART  - start of work.
!    KEND    - end of work.
!    PSPD    - NH pressure departure prognostic variable.
!    PREF    - hydrostatic pressure "prehyd" at full levels.

!   OUTPUT:
!    PNHPREF - total pressure "pre" at full levels.
!    PNHPPI  - ratio pre/prehyd at full levels.
!    PRNHPPI - ratio prehyd/pre at full levels.
!    PDEP    - pressure departure "pre - prehyd" at full levels.

!   OPTIONAL INPUT:
!    PLNPR   - 'delta=delta(log(prehyd))' at full levels.
!    PRT     - RT at full levels.
!    POROG   - surface orography.
!    PHIHYD  - hydrostatic component of orography at full levels.

! Externals
! ---------

! Method
! ------

! Reference
! ---------

! Author
! ------
!   K. YESSAD (MF/CNRM/GMAP), Dec 2004.

! Modifications
! -------------
!   N. Wedi and K. Yessad (Jan 2008): different dev for NH model and PC scheme
!------------------------------------------------------------------

USE PARKIND1 , ONLY : JPIM     ,JPRB
USE YOMDYNA  , ONLY : NPDVAR   ,LRWSDLR
USE YOMDYN   , ONLY : RC_PD1   ,RCORPDF
USE YOMCVER  , ONLY : LVERTFE  ,LVFE_DERIB
USE YOMGEM   , ONLY : VFE_RDETAH,VBF

USE YOMHOOK  , ONLY : LHOOK    ,DR_HOOK

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

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)        :: KEND 
REAL(KIND=JPRB),INTENT(IN)           :: PSPD(KPROMA,KFLEV) 
REAL(KIND=JPRB),INTENT(IN)           :: PREF(KPROMA,KFLEV) 
REAL(KIND=JPRB),INTENT(OUT)          :: PNHPREF(KPROMA,KFLEV) 
REAL(KIND=JPRB),INTENT(OUT)          :: PNHPPI(KPROMA,KFLEV) 
REAL(KIND=JPRB),INTENT(OUT)          :: PRNHPPI(KPROMA,KFLEV) 
REAL(KIND=JPRB),INTENT(OUT)          :: PDEP(KPROMA,KFLEV) 
REAL(KIND=JPRB),OPTIONAL,INTENT(IN)  :: PLNPR(KPROMA,KFLEV) 
REAL(KIND=JPRB),OPTIONAL,INTENT(IN)  :: PRT(KPROMA,KFLEV) 
REAL(KIND=JPRB),OPTIONAL,INTENT(IN)  :: POROG(KPROMA) 
REAL(KIND=JPRB),OPTIONAL,INTENT(IN)  :: PHIHYD(KPROMA,KFLEV) 

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

INTEGER(KIND=JPIM) :: JLEV, JROF
REAL(KIND=JPRB)    :: ZSPDDER(KPROMA,0:KFLEV+1) 
REAL(KIND=JPRB)    :: ZPHIDEP(KPROMA,0:KFLEV+1) 
REAL(KIND=JPRB)    :: ZZ

REAL(KIND=JPRB) :: ZHOOK_HANDLE

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

#include "abor1.intfb.h"
#include "verder.intfb.h"

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

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

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

IF ( NPDVAR == 2 ) THEN

  DO JLEV=1,KFLEV
    IF (LRWSDLR) THEN
      DO JROF=KSTART,KEND
        PNHPPI(JROF,JLEV)=EXP(PSPD(JROF,JLEV)-RC_PD1*RCORPDF(JLEV))
      ENDDO
    ELSE
      DO JROF=KSTART,KEND
        PNHPPI(JROF,JLEV)=EXP(PSPD(JROF,JLEV))
      ENDDO
    ENDIF
    DO JROF=KSTART,KEND
      PRNHPPI(JROF,JLEV)=1.0_JPRB/PNHPPI(JROF,JLEV)
      PDEP(JROF,JLEV)=( PNHPPI(JROF,JLEV) - 1.0_JPRB )*PREF(JROF,JLEV)  
      PNHPREF(JROF,JLEV)=PDEP(JROF,JLEV)+PREF(JROF,JLEV)
    ENDDO
  ENDDO

ELSEIF ( NPDVAR == 3 .OR. NPDVAR == 4 ) THEN

  IF ( .NOT.(PRESENT(PLNPR).AND.PRESENT(PRT).AND.PRESENT(POROG) &
   & .AND.PRESENT(PHIHYD)) ) THEN
    CALL ABOR1('GNHPRE: if NPDVAR=3 or 4, arg PLNPR to PHIHYD should be present!')
  ENDIF

  IF (LVERTFE) THEN
    IF ( NPDVAR == 3 ) THEN
      DO JLEV=1,KFLEV
        DO JROF=KSTART,KEND
          ZPHIDEP(JROF,JLEV)= &
           & PSPD(JROF,JLEV)+VBF(JLEV)*POROG(JROF)-PHIHYD(JROF,JLEV)
        ENDDO
      ENDDO
    ELSEIF ( NPDVAR == 4 ) THEN
      DO JLEV=1,KFLEV
        DO JROF=KSTART,KEND
          ZPHIDEP(JROF,JLEV)=PSPD(JROF,JLEV)-PHIHYD(JROF,JLEV)
        ENDDO
      ENDDO
    ENDIF
    IF (LVFE_DERIB) THEN
      ! Constant upper BC.
      ZPHIDEP(KSTART:KEND,0)=ZPHIDEP(KSTART:KEND,1)
      ! Lower BC is zero.
      ZPHIDEP(KSTART:KEND,KFLEV+1)=0.0_JPRB
      CALL VERDER(KPROMA,KSTART,KEND,KFLEV+2,ZPHIDEP(1,0),ZSPDDER(1,0),.TRUE.)
    ELSE
      CALL VERDER(KPROMA,KSTART,KEND,KFLEV,ZPHIDEP(1,1),ZSPDDER(1,1))
    ENDIF
    DO JLEV=1,KFLEV
      DO JROF=KSTART,KEND
        ZSPDDER(JROF,JLEV)=ZSPDDER(JROF,JLEV)/VFE_RDETAH(JLEV)
        ZZ=ZSPDDER(JROF,JLEV)/(PLNPR(JROF,JLEV)*PRT(JROF,JLEV))
        PNHPPI(JROF,JLEV)=1.0_JPRB/(1.0_JPRB-ZZ)
        PRNHPPI(JROF,JLEV)=1.0_JPRB/PNHPPI(JROF,JLEV)
        PDEP(JROF,JLEV)=( PNHPPI(JROF,JLEV) - 1.0_JPRB )*PREF(JROF,JLEV)  
        PNHPREF(JROF,JLEV)=PDEP(JROF,JLEV)+PREF(JROF,JLEV)
      ENDDO
    ENDDO
  ELSE
    CALL ABOR1('GNHPRE: NPDVAR=3 or 4 is coded only for VFE!')
  ENDIF

ENDIF

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

IF (LHOOK) CALL DR_HOOK('GNHPRE',1,ZHOOK_HANDLE)

END SUBROUTINE GNHPRE

