SUBROUTINE GPNOXAD(KPROMA,KSTART,KPROF,KFLEV,PNO2,PT,PO3,PNOX,PSOL,PJNO2,PRXP,&
& PT5,PO35,PNOX5,PJNO25,PRXP5)

!**** *GPNOXAD* - Computes half level NO2 columns.

!     Purpose.
!     --------
!           Computes half level NO2 columns, adjoint.

!**   Interface.
!     ----------
!        *CALL* *GPNOXAD(KPROMA,KSTART,KPROF,KFLEV,PNO2,PT,PO3,PNOX,PJNO2,PRXP
!                                              ,PT5,PO35,PNOX5,PJNO25,PRXP5)

!        Explicit arguments :
!        --------------------
!        KPROMA                      - HORIZ. DIMENSIONING        (INPUT-C)
!        KSTART                      - START OF WORK              (INPUT-C)
!        KPROF                       - DEPTH OF WORK              (INPUT-C)
!        KFLEV                       - NUMBER OF LEVELS           (INPUT-C)
!        PNO2 (KPROMA,KFLEV)        - NO2 PERTURBATION          (OUTPUT)
!        PT  (KPROMA,KFLEV)          - TEMPERATURE PERT           (INPUT)
!        PO3 (KPROMA,KFLEV)          - OZONE PERT                 (INPUT)
!        PNOX  (KPROMA,KFLEV)        - NOX PERT                   (INPUT)
!        PSOL (KPROMA)               - solar elevation          (INPUT)
!        PJNO2(KPROMA,KFLEV)         - NO2 PHOTOLYSIS FREQ PERT   (INPUT)
!        PRXP(KPROMA,0:KFLEV,NPPM)   - HALF,FULL AND LN HALF LEVEL
!                                      PRESSURES (SEE PPINIT)     (INPUT)
!        PT5 (KPROMA,KFLEV)          - TEMPERATURE                (INPUT-T)
!        PO35 (KPROMA,KFLEV)         - OZONE                      (INPUT-T)
!        PNOX5 (KPROMA,KFLEV)        - NOX                        (INPUT-T)
!        PJNO25(KPROMA,KFLEV)        - NO2 PHOTOLYSIS FREQ        (INPUT-T)
!        PRXP5(KPROMA,0:KFLEV,NPPM)  - HALF,FULL AND LN HALF LEVEL
!                                      PRESSURES (SEE PPINIT)     (INPUT)

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

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

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

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

!     Author.
!     -------
!        Erik Andersson, based on PP-routines by
!        Mats Hamrud and Philippe Courtier  *ECMWF*

!     Modifications.
!     --------------
!        Original : 92-06-08
!        M.Hamrud      01-Oct-2003 CY28 Cleaning
!        A.Dethof      04-Jan-2007 Adapt for NOx operator
!     ------------------------------------------------------------------

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

USE YOMDIM   , ONLY : NPPM
USE YOMCST   , ONLY : RG, RD, RNAVO,RPI
USE YOMANCS  , ONLY : RMDI

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

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(INOUT) :: PNO2(KPROMA,KFLEV)
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PT(KPROMA,KFLEV) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PO3(KPROMA,KFLEV) 
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PNOX(KPROMA,KFLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PSOL(KPROMA)
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PJNO2(KPROMA,KFLEV)
REAL(KIND=JPRB)   ,INTENT(INOUT) :: PRXP(KPROMA,0:KFLEV,NPPM) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PT5(KPROMA,KFLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PO35(KPROMA,KFLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PNOX5(KPROMA,KFLEV) 
REAL(KIND=JPRB)   ,INTENT(IN)    :: PJNO25(KPROMA,KFLEV)
REAL(KIND=JPRB)   ,INTENT(IN)    :: PRXP5(KPROMA,0:KFLEV,NPPM) 

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

INTEGER(KIND=JPIM) :: JL, JLEV

REAL(KIND=JPRB)  :: ZNO25(KPROMA,KFLEV)

REAL(KIND=JPRB) , PARAMETER :: ZC1=1.7E-12_JPRB,ZC2=-1310.0_JPRB
REAL(KIND=JPRB) , PARAMETER :: ZC3=4.5E19_JPRB

REAL(KIND=JPRB) :: ZDELP, ZDELP5, ZRGI,ZZK,ZZK5,ZRATIO,ZRATIO5
REAL(KIND=JPRB) :: ZSZA(KPROMA),ZSZA_H(KPROMA),ZSOL(KPROMA)
REAL(KIND=JPRB) :: ZRHO,ZRHO5,ZC4
REAL(KIND=JPRB) ::ZO3mol,ZO3mol5,ZZB,ZZB5,ZZN,ZZN5
REAL(KIND=JPRB) :: ZHOOK_HANDLE

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

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

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

!*       1.    COMPUTES HALF LEVEL NO2 columns
!              --------------------------------

ZRATIO=0.0_JPRB
ZDELP=0.0_JPRB
ZZB=0.0_JPRB
ZZN=0.0_JPRB
ZZK=0.0_JPRB
ZO3mol=0.0_JPRB
ZRHO=0.0_JPRB

ZRGI=1.0_JPRB/RG
!*       1.1   Convert solar elevation to SZA
DO JL=KSTART,KPROF
  ZSOL(JL) = PSOL(JL)
  IF (ZSOL(JL) == RMDI) ZSOL(JL)=45.0_JPRB  !Set missing SOE values to 45 deg
  ZSZA_H(JL)=COS(RPI/180.0_JPRB*(90._JPRB-ZSOL(JL)))
  ZSZA(JL) = MAX(0.01_JPRB,ZSZA_H(JL))
ENDDO

ZC4= RNAVO / (1000000.0_JPRB * 0.048_JPRB)

DO JLEV=KFLEV,1,-1
  DO JL=KSTART,KPROF

    IF (ZSZA(JL) > 0.01_JPRB) THEN
!Trajectory
      ZZK5=ZC1*EXP(ZC2/PT5(JL,JLEV))
      ZZN5=PJNO25(JL,JLEV)/ZZK5
      ZRHO5 = PRXP5(JL,JLEV,2)/(RD*PT5(JL,JLEV))
!      ZO3mol5=PO35(JL,JLEV)*ZRHO5*ZC4
      ZO3mol5=(PO35(JL,JLEV)+0.5 * ZSZA(JL) * 1.3E-7 )*ZRHO5*ZC4
      ZZB5=1.0_JPRB + ZZN5/ZO3mol5
      ZRATIO5=1.0_JPRB/ZZB5
      ZNO25=PNOX5(JL,JLEV)*ZRATIO5
      ZDELP5=PRXP5(JL,JLEV,1)-PRXP5(JL,JLEV-1,1)

!Gradients

      ZRATIO=ZRATIO+PNOX5(JL,JLEV)*PNO2(JL,JLEV)
      PNOX(JL,JLEV)=PNOX(JL,JLEV)+ZRATIO5*PNO2(JL,JLEV)
      PNO2(JL,JLEV)=0.0_JPRB

      ZZB=ZZB-ZRATIO/ZZB5**2
      ZRATIO=0.0_JPRB

      ZZN=ZZN + ZZB/ZO3MOL5
      ZO3mol=ZO3MOL -ZZN5*ZZB/ZO3MOL5**2
      ZZB=0.0_JPRB
  
!      PO3(JL,JLEV)=PO3(JL,JLEV)+ZO3mol*ZRHO5*ZC4
!     ZRHO=ZRHO+ZO3mol*PO35(JL,JLEV)*ZC4
!     ZO3mol=0.0_JPRB
      PO3(JL,JLEV)=PO3(JL,JLEV)+ZO3mol*ZRHO5*ZC4
      ZRHO=ZRHO+ZO3mol*(PO35(JL,JLEV)+0.5*ZSZA(JL)*1.3E-7)*ZC4
      ZO3mol=0.0_JPRB

      PRXP(JL,JLEV,2)=PRXP(JL,JLEV,2)+ZRHO/PT5(JL,JLEV)/RD
      PT(JL,JLEV)=PT(JL,JLEV)-ZRHO*PRXP5(JL,JLEV,2)/PT5(JL,JLEV)**2/RD
      ZRHO=0.0_JPRB

      PJNO2(JL,JLEV)=PJNO2(JL,JLEV) +ZZN/ZZK5
      ZZK=ZZK-ZZN*PJNO25(JL,JLEV)/ZZK5**2
      ZZN=0.0_JPRB
    
      PT(JL,JLEV)=PT(JL,JLEV) - &
       & ZC2/PT5(JL,JLEV)**2*ZC1*EXP(ZC2/PT5(JL,JLEV))*ZZK
      ZZK=0.0_JPRB

    ELSE

      ZNO25=PNOX5(JL,JLEV)

      PNOX(JL,JLEV)=PNOX(JL,JLEV)+PNO2(JL,JLEV)
      PNO2(JL,JLEV)=0.0_JPRB
    ENDIF
  ENDDO
ENDDO

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

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