SUBROUTINE GRG_JNO2TL(KPROMA,KSTART,KPROF,KFLEV,PPCO3,PT,PSOL,PAL,PJNO2,PRXP,PPCO35,PT5,PRXP5)

!**** *GRG_JNO2TL* - Computes NO2 photolysis frequency JNO2, tangent linear

!     Purpose.
!     --------
!           Computes NO2 photolysis frequency JNO2, tangent linear

!**   Interface.
!     ----------
!        *CALL* *GRG_JNO2TL(KPROMA,KSTART,KPROF,KFLEV,PPCO3,PT,PSOL,PAL,PJNO2,PRXP,PPCO35,PT5,PRXP5)

!        Explicit arguments :
!        --------------------
!        KPROMA                - HORIZ. DIMENSIONING          (INPUT)
!        KSTART                - START OF WORK                (INPUT)
!        KPROF                 - DEPTH OF WORK                (INPUT)
!        KFLEV                 - NUMBER OF LEVELS             (INPUT)
!        PPCO3 (KPROMA,KFLEV)  - HALF LEVEL O3 partial column PERT (INPUT)
!        PT  (KPROMA,KFLEV)    - TEMPERATURE PERT             (INPUT)
!        PSOL (KPROMA)         - COS(SZA)                     (INPUT)
!        PAL (KPROMA)          - Albedo                       (INPUT)
!        PJNO2 (KPROMA,KFLEV)  - JNO2 photolysis freq. PERT   (OUTPUT)
!        PRXP(KPROMA,0:KFLEV,NPPM)  - HALF,FULL AND LN HALF LEVEL
!                                     PRESSURES (SEE PPINIT)   (INPUT)
!        PPCO35 (KPROMA,KFLEV) - HALF LEVEL O3 partial column (INPUT)
!        PT5  (KPROMA,KFLEV)   - TEMPERATURE                  (INPUT)
!        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.
!     -------
!        Antje Dethof based on TM5 routine *ECMWF*

!     Modifications.
!     --------------
!        Original : 09-Oct-2006

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

USE PARKIND1  ,ONLY : JPIM     ,JPRB
USE YOMHOOK   ,ONLY : LHOOK,   DR_HOOK
USE YOMDIM   , ONLY : NPPM
USE YOMCST   , ONLY : RPI
USE GRG_PHOTOLYSIS_MIX
USE YOMANCS  , ONLY : RMDI

IMPLICIT NONE

INTEGER(KIND=JPIM),INTENT(IN)  :: KPROMA
INTEGER(KIND=JPIM),INTENT(IN)  :: KSTART
INTEGER(KIND=JPIM),INTENT(IN)  :: KPROF
INTEGER(KIND=JPIM),INTENT(IN)  :: KFLEV
REAL(KIND=JPRB)   ,INTENT(IN)  :: PPCO3(KPROMA,KFLEV) !overhead ozone (kg/m2)
REAL(KIND=JPRB)   ,INTENT(IN)  :: PT(KPROMA,KFLEV)
REAL(KIND=JPRB)   ,INTENT(IN)  :: PSOL(KPROMA)
REAL(KIND=JPRB)   ,INTENT(IN)  :: PAL(KPROMA)
REAL(KIND=JPRB)   ,INTENT(OUT) :: PJNO2(KPROMA,KFLEV)
REAL(KIND=JPRB)   ,INTENT(IN)  :: PRXP(KPROMA,0:KFLEV,NPPM)
! Trajectory input fields
REAL(KIND=JPRB)   ,INTENT(IN)  :: PPCO35(KPROMA,KFLEV) !overhead ozone (kg/m2)
REAL(KIND=JPRB)   ,INTENT(IN)  :: PT5(KPROMA,KFLEV)
REAL(KIND=JPRB)   ,INTENT(IN)  :: PRXP5(KPROMA,0:KFLEV,NPPM)

!mvw added declarations
REAL(KIND=JPRB) :: zTAUC(KPROMA,KFLEV) ! cloud optical thickness per level
REAL(KIND=JPRB) :: zTAUS(KPROMA)       ! total cloud optical thickness
REAL(KIND=JPRB) :: ZALB(KPROMA)       ! surface albedo
REAL(KIND=JPRB) :: zPS(KPROMA)         ! surface pressure (for now I just take: PMID(KFLEV)
REAL(KIND=JPRB) :: zPS5(KPROMA)        ! surface pressure (for now I just take: PMID(KFLEV)

!LOCAL PARAMETERS
INTEGER(KIND=JPIM),PARAMETER :: inbands=7
REAL(KIND=JPRB), PARAMETER   :: todu = 3.767e-17    ! O3 from molecules/cm2 --> du
!antje REAL(KIND=JPRB), PARAMETER   :: todu = 47296 ! O3 from kg/m2 --> du
REAL(KIND=JPRB), PARAMETER   :: tomol = 1.255e+21   ! O3 from kg/m2 --> mol/cm2
REAL(KIND=JPRB), PARAMETER   :: zf0(inbands) = &      ! f0: bruhl wavelength works with fintwb.data
 &   (/73.44,4.977,16.13,8.017,27.9,19.00,48.12/)
REAL(KIND=JPRB), PARAMETER   :: zcrs_o3(inbands) = &
 &   (/3.6448e-19,1.7115e-18,2.8218e-19,1.1091e-19, &
 &     2.8145e-20,1.9000e-23,4.5500e-21/)
REAL(KIND=JPRB), PARAMETER   :: zfe(inbands) = &
 &   (/2.20560e+12,2.22730e+14,7.52530e+13,1.01010e+14, &
 &     1.19010e+14,1.07760e+15,2.67400e+15/)

!LOCAL VARIABLES
INTEGER(KIND=JPIM):: JL, JLEV
INTEGER(KIND=JPIM):: i2,i3,ind !indices lookup tables

REAL(KIND=JPRB) :: ZHOOK_HANDLE
REAL(KIND=JPRB) :: ZPCO3(KPROMA,KFLEV)     !overhead ozone (molecules/cm2)
REAL(KIND=JPRB) :: ZPCO35(KPROMA,KFLEV)    !overhead ozone (molecules/cm2)
REAL(KIND=JPRB) :: ZO3COL(KPROMA,KFLEV)    !overhead ozone (molecules/cm2)
REAL(KIND=JPRB) :: ZO3COL5(KPROMA,KFLEV)   !overhead ozone (molecules/cm2)
REAL(KIND=JPRB) :: ZO3TCOL(KPROMA)         !overhead total ozone (molecules/cm2)
REAL(KIND=JPRB) :: ZO3TCOL5(KPROMA)        !overhead total ozone (molecules/cm2)
REAL(KIND=JPRB) :: ZCC_COL(KPROMA)         !overhead cloud cover

REAL(KIND=JPRB) :: ztscale
REAL(KIND=JPRB) :: ztscale5
REAL(KIND=JPRB) :: zv3_du(KPROMA,KFLEV), zv3_du1(KPROMA,KFLEV), zv3_du2(KPROMA,KFLEV)
REAL(KIND=JPRB) :: zv3s1(KPROMA,KFLEV),zv3s2(KPROMA,KFLEV)            ! ozone column variables
REAL(KIND=JPRB) :: zv3_du5(KPROMA,KFLEV), zv3_du15(KPROMA,KFLEV), zv3_du25(KPROMA,KFLEV)
REAL(KIND=JPRB) :: zv3s15(KPROMA,KFLEV),zv3s25(KPROMA,KFLEV)          ! ozone column variables
REAL(KIND=JPRB) :: ztau_2,ztau_3,ztau_4,ztau_5                          ! optical depth
REAL(KIND=JPRB) :: ztau_25,ztau_35,ztau_45,ztau_55                      ! optical depth
REAL(KIND=JPRB) :: zfint_2,zfint_3,zfint_4, zfint_5,zfint_6       ! integrated actinic fluxes
REAL(KIND=JPRB) :: zfint_25,zfint_35,zfint_45, zfint_55,zfint_65 ! integrated actinic fluxes
REAL(KIND=JPRB) :: zsig_2,zsig_3,zsig_4,zsig_5,zsig_6              ! effective cross-sections
REAL(KIND=JPRB) :: zsig_25,zsig_35,zsig_45,zsig_55,zsig_65        ! effective cross-sections
REAL(KIND=JPRB) :: zfact(7)                                          ! cloud scaling stuff
REAL(KIND=JPRB) :: zfact5(7)                                          ! cloud scaling stuff
real(KIND=JPRB) :: ZPRES(KPROMA,KFLEV),ZPRES5(KPROMA,KFLEV)

REAL(KIND=JPRB) :: ZSZA(KPROMA),ZSZA_H(KPROMA),ZSOl(KPROMA)

#include "grg_fparam.intfb.h"
#include "grg_fparamtl.intfb.h"
!     ------------------------------------------------------------------

!*       1.    COMPUTES NO2 photolysis frequency PJNO2, tangent linear
!              -------------------------------------------------------

  ! ===========================================================
  
IF (LHOOK) CALL DR_HOOK('GRG_JNO2TL',0,ZHOOK_HANDLE)
    
!fact = 1.0

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

!*       2.   COMPUTE J(NO2)


!*       2.1   Convert ozone columns to DU
DO JLEV=1,KFLEV
  DO JL=KSTART,KPROF

    IF (ZSZA(JL) > 0.01_JPRB) THEN
      ZPCO35(JL,JLEV) = PPCO35(JL,JLEV)*tomol/ZSZA(JL) ! o3 overhead slant column (molec/cm2) 
      zv3_du5(JL,JLEV) = ZPCO35(JL,JLEV)*todu     ! DU
      ZPCO3(JL,JLEV)  = PPCO3(JL,JLEV)*tomol/ZSZA(JL)  ! o3 overhead slant column (molec/cm2)
      zv3_du(JL,JLEV)  = ZPCO3(JL,JLEV)*todu      ! DU

!*       2.2   Interval 1 + 2, TRAJECTORY
      if (zv3_du5(JL,JLEV) >= 300._JPRB) then
        zv3_du15(JL,JLEV) = 300._JPRB
        zv3s15(JL,JLEV)   = 8.161e+18_JPRB
      else
        zv3_du15(JL,JLEV) = zv3_du5(JL,JLEV)
        zv3s15(JL,JLEV)   = ZPCO35(JL,JLEV)
      endif

!*       2.2   Interval 1 + 2, PERTURBATION
      if (zv3_du5(JL,JLEV) >= 300._JPRB) then
        zv3_du1(JL,JLEV) = 0.0_JPRB
        zv3s1(JL,JLEV)   = 0.0_JPRB
      else
        zv3_du1(JL,JLEV) = zv3_du(JL,JLEV)
        zv3s1(JL,JLEV)   = ZPCO3(JL,JLEV)
      endif

!*       2.3   Interval 3 - 7, TRAJECTORY
      if ( zv3_du5(JL,JLEV) >= 3000.0_JPRB ) then
        zv3_du25(JL,JLEV)   = 3000.0_JPRB
        zv3s25(JL,JLEV)     = 8.161e+19_JPRB
      else
        zv3_du25(JL,JLEV)   = zv3_du5(JL,JLEV)
        zv3s25(JL,JLEV)     = ZPCO35(JL,JLEV)
      endif

!*       2.3   Interval 3 - 7, PERTURBATION
      if ( zv3_du5(JL,JLEV) >= 3000.0_JPRB ) then
        zv3_du2(JL,JLEV)   = 0.0_JPRB
        zv3s2(JL,JLEV)     = 0.0_JPRB
      else
        zv3_du2(JL,JLEV)   = zv3_du(JL,JLEV)
        zv3s2(JL,JLEV)     = ZPCO3(JL,JLEV)
      endif

!*       2.4   Calculate fact using fparam routine
!              first set clouds to zero and set surface albedo, no clouds
      ZCC_COL(JL)   = 0._JPRB   ! overhead cloud cover
      zTAUC(JL,JLEV) = 0._JPRB   ! cloud optical thickness per level
      zTAUS(JL) = 0._JPRB        ! total cloud optical thickness
      ZALB(JL) = 0.05_JPRB      ! surface albedo =0.05 for tests

      ZPRES5(JL,JLEV) = PRXP5(JL,JLEV,2)  ! full level pressures
      ZPRES(JL,JLEV) = PRXP(JL,JLEV,2)  ! full level pressures
      zPS5(JL) = PRXP5(JL,KFLEV,1)  ! half level pressure of lowest level, surface pressure
      zPS(JL) = PRXP(JL,KFLEV,1)  ! half level pressure of lowest level, surface pressure
      ZO3COL5(JL,JLEV) =PPCO35(JL,JLEV)*tomol
      ZO3COL(JL,JLEV) =PPCO3(JL,JLEV)*tomol
      ZO3TCOL5(JL) =PPCO35(JL,KFLEV)*tomol
      ZO3TCOL(JL) =PPCO3(JL,KFLEV)*tomol

! calculate fact and include overhead ozone corrections, Trajectory
      CALL GRG_FPARAM(ZO3COL5(JL,JLEV),ZO3TCOL5(JL), &
       & ZCC_COL(JL),zTAUC(JL,JLEV),zTAUS(JL),ZPRES5(JL,JLEV),zPS5(JL),PAL(JL), &
       & ZSOL(JL),zCRS_O3,zFACT5)

! calculate fact and include overhead ozone corrections, Perturbation
      CALL GRG_FPARAMTL(ZO3COL(JL,JLEV),ZO3TCOL(JL), &
       & ZCC_COL(JL),zTAUC(JL,JLEV),zTAUS(JL),ZPRES(JL,JLEV),zPS(JL),PAL(JL), &
       & ZSOL(JL),zCRS_O3,zFACT,&
       & ZO3COL5(JL,JLEV),ZO3TCOL5(JL),ZPRES5(JL,JLEV),zPS5(JL))

!*       2.5   Scaled temperature
      ztscale5 = (PT5(JL,JLEV)-250.0_JPRB)/250.0_JPRB
      ztscale  = PT(JL,JLEV)/250.0_JPRB

!*       2.6   get indices for lookup-tables (needs only to be done for TRAJ)
      ind = nint(min(max(1.0_JPRB,(zv3_du5(JL,JLEV)-0.5_JPRB)/2.5_JPRB+1.0_JPRB),115.0_JPRB))
      i2  = ifil(ind)
      ind = nint(min(max(1.0_JPRB,(zv3_du5(JL,JLEV)-5.0_JPRB)/25.0_JPRB+1.0_JPRB),115.0_JPRB))
      i3  = ifil(ind)

!*       2.7   calculate optical depth due to ozone absorbtion, TRAJECTORY

      ztau_25 = taub2(i2)+taua2(i2)*zv3_du15(JL,JLEV) 
      ztau_35 = taub3(i3)+taua3(i3)*zv3_du25(JL,JLEV) 
      ztau_45 = c4_tau(1) +c4_tau(2)*zv3_du25(JL,JLEV) + &
       &       c4_tau(3)*zv3_du25(JL,JLEV)**2 + &
       &       c4_tau(4)*zv3_du25(JL,JLEV)**3
      ztau_55 = c5_tau(1)+c5_tau(2)*zv3_du25(JL,JLEV)+ &
       &       c5_tau(3)*zv3_du25(JL,JLEV)**2

!*       2.8   calculate optical depth due to ozone absorbtion, PERTURBATION
      ztau_2 = taua2(i2)*zv3_du1(JL,JLEV)
      ztau_3 = taua3(i3)*zv3_du2(JL,JLEV)
      ztau_4 = c4_tau(2)*zv3_du2(JL,JLEV) + &
       &      2.0_JPRB*c4_tau(3)*zv3_du2(JL,JLEV)*zv3_du25(JL,JLEV) + &
       &      3.0_JPRB*c4_tau(4)*zv3_du2(JL,JLEV)*zv3_du25(JL,JLEV)**2
      ztau_5 = c5_tau(2)*zv3_du2(JL,JLEV)+ &
       &      2.0_JPRB*c5_tau(3)*zv3_du2(JL,JLEV)*zv3_du25(JL,JLEV)
  
!*       2.9   effective actinic fluxes in units quanta/s/cm2, TRAJECTORY

      zfint_25 = exp(-ztau_25+zcrs_o3(2)*zv3s15(JL,JLEV))*zf0(2)*zfact(2)*zfe(2) 
      zfint_35 = exp(-ztau_35+zcrs_o3(3)*zv3s25(JL,JLEV))*zf0(3)*zfact(3)*zfe(3)
      zfint_45 = exp(-ztau_45+zcrs_o3(4)*zv3s25(JL,JLEV))*zf0(4)*zfact(4)*zfe(4)
      zfint_55 = exp(-ztau_55+zcrs_o3(5)*zv3s25(JL,JLEV))*zf0(5)*zfact(5)*zfe(5)
      zfint_65 = zf0(6)*zfact(6)*zfe(6)

!*       2.10   effective actinic fluxes in units quanta/s/cm2, PERTURBATION
      zfint_2 = (-ztau_2+zcrs_o3(2)*zv3s1(JL,JLEV))*&
       &        exp(-ztau_25+zcrs_o3(2)*zv3s15(JL,JLEV))*zf0(2)*zfact5(2)*zfe(2) + &
       &        exp(-ztau_25+zcrs_o3(2)*zv3s15(JL,JLEV))*zf0(2)*zfact(2)*zfe(2)
      zfint_3 = (-ztau_3+zcrs_o3(3)*zv3s2(JL,JLEV))*&
       &        exp(-ztau_35+zcrs_o3(3)*zv3s25(JL,JLEV))*zf0(3)*zfact5(3)*zfe(3) + &
       &        exp(-ztau_35+zcrs_o3(3)*zv3s25(JL,JLEV))*zf0(3)*zfact(3)*zfe(3)
      zfint_4 = (-ztau_4+zcrs_o3(4)*zv3s2(JL,JLEV))* &
       &        exp(-ztau_45+zcrs_o3(4)*zv3s25(JL,JLEV))*zf0(4)*zfact5(4)*zfe(4) + &
       &        exp(-ztau_45+zcrs_o3(4)*zv3s25(JL,JLEV))*zf0(4)*zfact(4)*zfe(4)
      zfint_5 = (-ztau_5+zcrs_o3(5)*zv3s2(JL,JLEV))* &
       &        exp(-ztau_55+zcrs_o3(5)*zv3s25(JL,JLEV))*zf0(5)*zfact5(5)*zfe(5) + &
       &        exp(-ztau_55+zcrs_o3(5)*zv3s25(JL,JLEV))*zf0(5)*zfact(5)*zfe(5)
      zfint_6 = zf0(6)*zfact(6)*zfe(6)                            


!*       2.11  NO2, photolosis rate, TRAJECTORY

      zsig_25 = (tj_no2(1,2)+tj_no2(2,2)*ztscale5) * &
       &       (b2_no2(i2)+a2_no2(i2)*zv3_du15(JL,JLEV))

      zsig_35 = (tj_no2(1,3)+tj_no2(2,3)*ztscale5) * &
       &       (b3_no2(i3)+a3_no2(i3)*zv3_du25(JL,JLEV))

      zsig_45 = (tj_no2(1,4)+tj_no2(2,4)*ztscale5) * &
       &       (c4_no2(1) +c4_no2(2)*zv3_du25(JL,JLEV)+c4_no2(3)*zv3_du25(JL,JLEV)**2)

      zsig_55 = (tj_no2(1,5)+tj_no2(2,5)*ztscale5) * &
       &       (c5_no2(1) +c5_no2(2)*zv3_du25(JL,JLEV)+c5_no2(3)*zv3_du25(JL,JLEV)**2)

      zsig_65 = (tj_no2(1,6)+tj_no2(2,6)*ztscale5) * &
       &       (c6_no2(1) +c6_no2(2)*zv3_du25(JL,JLEV))

!*       2.8  NO2, photolosis rate, PERTURBATION
      zsig_2 = tj_no2(2,2)*ztscale * (b2_no2(i2)+a2_no2(i2)*zv3_du15(JL,JLEV)) + &
       &      (tj_no2(1,2)+tj_no2(2,2)*ztscale5)*a2_no2(i2)*zv3_du1(JL,JLEV)

      zsig_3 = tj_no2(2,3)*ztscale * (b3_no2(i3)+a3_no2(i3)*zv3_du25(JL,JLEV)) + &
       &      (tj_no2(1,3)+tj_no2(2,3)*ztscale5) * a3_no2(i3)*zv3_du2(JL,JLEV)

      zsig_4 = tj_no2(2,4)*ztscale * (c4_no2(1) + &
       &       c4_no2(2)*zv3_du25(JL,JLEV)+c4_no2(3)*zv3_du25(JL,JLEV)**2) + &
       &      (tj_no2(1,4)+tj_no2(2,4)*ztscale5)*(c4_no2(2)*zv3_du2(JL,JLEV)+ &
       &       2.0_JPRB*c4_no2(3)*zv3_du2(JL,JLEV)*zv3_du25(JL,JLEV))

      zsig_5 = tj_no2(2,5)*ztscale * &
       &      (c5_no2(1) +c5_no2(2)*zv3_du25(JL,JLEV)+ &
       &       c5_no2(3)*zv3_du25(JL,JLEV)**2) + &
       &      (tj_no2(1,5)+tj_no2(2,5)*ztscale5)*(c5_no2(2)*zv3_du2(JL,JLEV)+ &
       &       2.0_JPRB*c5_no2(3)*zv3_du2(JL,JLEV)*zv3_du25(JL,JLEV))

      zsig_6 = tj_no2(2,6)*ztscale * (c6_no2(1) +c6_no2(2)*zv3_du25(JL,JLEV)) + &
       &       (tj_no2(1,6)+tj_no2(2,6)*ztscale5) * c6_no2(2)*zv3_du2(JL,JLEV) 

      PJNO2(JL,JLEV) =  zsig_25*zfint_2 + zsig_2*zfint_25 + &
       &                zsig_35*zfint_3 + zsig_3*zfint_35 + &
       &                zsig_45*zfint_4 + zsig_4*zfint_45 + &
       &                zsig_55*zfint_5 + zsig_5*zfint_55 + &
       &                zsig_65*zfint_6 + zsig_6*zfint_65

    ELSE

      PJNO2(JL,JLEV) = 0.0_JPRB

    ENDIF
  ENDDO
ENDDO

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

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

END SUBROUTINE GRG_JNO2TL
