!------------------------------------------------------------------------------
!                   Harmonized Emissions Component (HEMCO)                    !
!------------------------------------------------------------------------------
!BOP
!
! !MODULE: hcox_lightnox_mod.F90
!
! !DESCRIPTION: Module HCOX\_LightNOx\_Mod contains routines to
!  compute NO lightning emissions, according to the GEOS-Chem lightning
!  algorithms.
!\\
!\\
! This is a HEMCO extension module that uses many of the HEMCO core
! utilities. In particular, the LIS-OTD local redistribution factors are
! now read through the HEMCO framework, and the corresponding netCDF
! input file is specified in the HEMCO configuration file. The table of
! cumulative distribution functions used to vertically distribute lightning
! NOx emissions is specified in the extension switch section of the
! configuration file.
!\\
!\\
! References:
! \begin{itemize}
! \item Murray, L. T., Jacob, D. J., Logan, J. A., Hudman, R. C., and
!       Koshak, W. J.: \emph{Optimized regional and interannual variability
!       of lightning in a global chemical transport model con- strained
!       by LIS/OTD satellite data}, \underline{J. Geophys. Res.},
!       Atmospheres, 117, 2012.
! \item Ott, L. E., K. E. Pickering, G. L. Stenchikov, D. J. Allen,
!       A. J. DeCaria, B. Ridley, R.-F. Lin, S. Lang, and W.-K. Tao,
!       \emph{Production of lightning NOx and its vertical distribution
!       calculated  from three-dimensional cloud-scale chemical transport
!       model simulations}, \underline{J. Geophys. Res.}, 115, D04301, 2010.
! \end{itemize}
!
! !INTERFACE:
!
MODULE HCOX_LightNOx_Mod
!
! !USES:
!
  USE HCO_Error_Mod
  USE HCO_Diagn_Mod
  USE HCOX_TOOLS_MOD
  USE HCO_State_Mod,  ONLY : HCO_State
  USE HCOX_State_MOD, ONLY : Ext_State

  IMPLICIT NONE
  PRIVATE
!
! !PUBLIC MEMBER FUNCTIONS:
!
  PUBLIC  :: HCOX_LightNOX_Run
  PUBLIC  :: HCOX_LightNOX_Final
  PUBLIC  :: HCOX_LightNOX_Init
!
! !PRIVATE MEMBER FUNCTIONS:
!
  PRIVATE :: LIGHTNOX
  PRIVATE :: LIGHTDIST
!
! !PUBLIC DATA MEMBERS:
!
!
! !REMARKS:
!  %%% NOTE: MFLUX and PRECON methods are now deprecated (ltm, bmy, 7/9/09)
!                                                                             .
!  References:
!  ============================================================================
!  (1 ) Price & Rind (1992), JGR, vol. 97, 9919-9933.
!  (2 ) Price & Rind (1994), M. Weather Rev, vol. 122, 1930-1939.
!  (3 ) Allen & Pickering (2002), JGR, 107, D23, 4711, doi:10.1029/2002JD002066
!  (4 ) Hudman et al (2007), JGR, 112, D12S05, doi:10.1029/2006JD007912
!  (5 ) Sauvage et al, 2007, ACP,
!        http://www.atmos-chem-phys.net/7/815/2007/acp-7-815-2007.pdf
!  (6 ) Ott et al., (2010), JGR
!  (7 ) Allen et al., (2010), JGR
!  (8 ) Murray et al., (2011), in prep.
!
! !REVISION HISTORY:
!  14 Apr 2004 - L. Murray, R. Hudman - Initial version
!  See https://github.com/geoschem/hemco for complete history
!EOP
!------------------------------------------------------------------------------
!BOC
!
! !DEFINED PARAMETERS:
!
  INTEGER, PARAMETER            :: NLTYPE        = 4
  INTEGER, PARAMETER            :: NNLIGHT       = 3200
  REAL*8,  PARAMETER            :: RFLASH_MIDLAT = 3.011d26   ! 500 mol/flash applied in the N extratropics
  REAL*8,  PARAMETER            :: RFLASH_TROPIC = 1.566d26   ! 260 mol/flash applied in the tropics / S extratropics
  REAL*8,  PARAMETER            :: EAST_WEST_DIV = -30d0
  REAL*8,  PARAMETER            :: WEST_NS_DIV   =  35d0
  REAL*8,  PARAMETER            :: EAST_NS_DIV   =  35d0
!
! !PRIVATE TYPES:
!
  ! Scalars
  TYPE :: MyInst
   INTEGER                       :: Instance
   INTEGER                       :: IDTNO     ! NO tracer ID
   INTEGER                       :: ExtNr     ! HEMCO Extension ID
   LOGICAL                       :: LCNVFRC   ! Use convective fractions?
   LOGICAL                       :: LLFR      ! Use GEOS-5 flash rates

   ! Arrays
   REAL(dp), POINTER             :: PROFILE(:,:)
   REAL(hp), POINTER             :: SLBASE(:,:,:)
   REAL(sp), POINTER             :: FLASH_DENS_TOT(:,:)
   REAL(sp), POINTER             :: FLASH_DENS_IC(:,:)
   REAL(sp), POINTER             :: FLASH_DENS_CG(:,:)
   REAL(sp), POINTER             :: CONV_DEPTH(:,:)

   ! Overall scale factor to be applied to lightning NOx emissions. Must
   ! be defined in the HEMCO configuration file as extension attribute
   ! 'Scaling_NO'.
   ! SpcScalFldNme is the name of the gridded scale factor. Must be provided
   ! in the HEMCO configuration file as extension attribute 'ScaleField_NO'.
   REAL(sp), ALLOCATABLE          :: SpcScalVal(:)
   CHARACTER(LEN=61), ALLOCATABLE :: SpcScalFldNme(:)

   TYPE(MyInst), POINTER           :: NextInst => NULL()
  END TYPE MyInst

  ! Pointer to all instances
  TYPE(MyInst), POINTER            :: AllInst => NULL()

CONTAINS
!EOC
!------------------------------------------------------------------------------
!                   Harmonized Emissions Component (HEMCO)                    !
!------------------------------------------------------------------------------
!BOP
!
! !IROUTINE: HCOX_LightNOx_Run
!
! !DESCRIPTION: Subroutine HCOX\_LIGHTNOX\_RUN is the driver routine
! to calculate lightning NOx emissions and return them to the HEMCO
! driver routine.
!\\
!\\
! !INTERFACE:
!
  SUBROUTINE HCOX_LightNOx_Run( ExtState, HcoState, RC )
!
! !USES:
!
    USE HCO_FluxArr_Mod,  ONLY : HCO_EmisAdd
!
! !INPUT PARAMETERS:
!
    TYPE(Ext_State), POINTER        :: ExtState   ! Module options
    TYPE(HCO_State), POINTER        :: HcoState   ! HEMCO options
!
! !INPUT/OUTPUT PARAMETERS:
!
    INTEGER,         INTENT(INOUT)  :: RC
!
! !REVISION HISTORY:
!  09 Oct 1997 - R. Yantosca - Initial version
!  See https://github.com/geoschem/hemco for complete history
!EOP
!------------------------------------------------------------------------------
!BOC
!
! !LOCAL VARIABLES:
!
    TYPE(MyInst), POINTER :: Inst
    INTEGER               :: Yr, Mt
    LOGICAL               :: FOUND
    CHARACTER(LEN=255)    :: MSG, LOC

    !=================================================================
    ! HCOX_LIGHTNOX_RUN begins here!
    !=================================================================
    LOC = 'HCOX_LIGHTNOX_RUN (HCOX_LIGHTNOX_MOD.F90)'

    ! Enter
    CALL HCO_ENTER( HcoState%Config%Err, LOC, RC )
    IF ( RC /= HCO_SUCCESS ) THEN
        CALL HCO_ERROR( 'ERROR 0', RC, THISLOC=LOC )
        RETURN
    ENDIF

    ! Return if extension disabled
    IF ( ExtState%LightNOx <= 0 ) THEN
       CALL HCO_LEAVE( HcoState%Config%Err,RC )
       RETURN
    ENDIF

    ! Get pointer to this instance. Varible Inst contains all module
    ! variables for the current instance. The instance number is
    ! ExtState%<yourname>.
    Inst => NULL()
    CALL InstGet ( ExtState%LightNOx, Inst, RC )
    IF ( RC /= HCO_SUCCESS ) THEN
       WRITE(MSG,*) 'Cannot find lightning NOx instance Nr. ', ExtState%LightNOx
       CALL HCO_ERROR(MSG,RC)
       RETURN
    ENDIF

    ! Update lightnox NOx emissions (fill SLBASE)
    CALL LIGHTNOX( HcoState, ExtState, Inst, RC )
    IF ( RC /= HCO_SUCCESS ) THEN
        CALL HCO_ERROR( 'ERROR 1', RC, THISLOC=LOC )
        RETURN
    ENDIF

    !=================================================================
    ! Pass to HEMCO State and update diagnostics
    !=================================================================
    IF ( Inst%IDTNO > 0 ) THEN

       ! Add flux to emission array
       CALL HCO_EmisAdd( HcoState, Inst%SLBASE, Inst%IDTNO, &
                         RC, ExtNr=Inst%ExtNr)
       IF ( RC /= HCO_SUCCESS ) THEN
          CALL HCO_ERROR( 'HCO_EmisAdd error: SLBASE', RC )
          RETURN
       ENDIF

    ENDIF

    ! Return w/ success
    Inst => NULL()
    CALL HCO_LEAVE( HcoState%Config%Err,RC )

  END SUBROUTINE HCOX_LightNOx_Run
!EOC
!------------------------------------------------------------------------------
!                   Harmonized Emissions Component (HEMCO)                    !
!------------------------------------------------------------------------------
!BOP
!
! !IROUTINE: LightNOx
!
! !DESCRIPTION: Subroutine LIGHTNOX uses Price \& Rind's formulation for
!  computing NOx emission from lightning (with various updates).
!\\
!\\
! !INTERFACE:
!
  SUBROUTINE LightNOx( HcoState, ExtState, Inst, RC )
!
! !USES:
!
    USE HCO_Calc_Mod,     ONLY : HCO_EvalFld
    USE HCO_EmisList_Mod, ONLY : HCO_GetPtr
    USE HCO_GeoTools_Mod, ONLY : HCO_LANDTYPE
    USE HCO_Clock_Mod,    ONLY : HcoClock_Get
    USE HCO_Clock_Mod,    ONLY : HcoClock_First
    USE HCO_ExtList_Mod,  ONLY : GetExtOpt
!
! !INPUT PARAMETERS:
!
    TYPE(HCO_State), POINTER        :: HcoState  ! Output obj
    TYPE(Ext_State), POINTER        :: ExtState    ! Module options
    TYPE(MyInst   ), POINTER        :: Inst
!
! !INPUT/OUTPUT PARAMETERS:
!
    INTEGER,         INTENT(INOUT)  :: RC
!
! !REMARKS:
!
! !REVISION HISTORY:
!  10 May 2006 - L. Murray - Initial version
!  See https://github.com/geoschem/hemco for complete history
!EOP
!------------------------------------------------------------------------------
!BOC
!
! !LOCAL VARIABLES:
!
    INTEGER             :: I, J, L
    INTEGER             :: LTOP
    INTEGER             :: MONTH
    INTEGER             :: MTYPE
    REAL*8              :: A_M2
    REAL*8              :: A_KM2
    REAL*8              :: H0
    REAL*8              :: IC_CG_RATIO
    REAL*8              :: RATE
    REAL*8              :: RATE_SAVE
    REAL*8              :: TOTAL
    REAL*8              :: TOTAL_CG
    REAL*8              :: TOTAL_IC
    REAL*8              :: X
    REAL*8              :: YMID
    REAL*8              :: XMID
    REAL*8              :: VERTPROF(HcoState%NZ)
    INTEGER             :: LMAX
    INTEGER             :: LNDTYPE
    INTEGER             :: SFCTYPE
    REAL(hp)            :: TROPP
    REAL(dp)            :: TmpScale
    CHARACTER(LEN=255)  :: LOC

    !=================================================================
    ! LIGHTNOX begins here!
    !=================================================================
    LOC = 'LIGHTNOX (HCOX_LIGHTNOX_MOD.F90)'

    ! Enter
    CALL HCO_ENTER( HcoState%Config%Err, LOC, RC )
    IF ( RC /= HCO_SUCCESS ) THEN
        CALL HCO_ERROR( 'ERROR 2', RC, THISLOC=LOC )
        RETURN
    ENDIF

    ! Reset arrays
    Inst%SLBASE         = 0.0_hp
    Inst%FLASH_DENS_TOT = 0.0_sp
    !Inst%FLASH_DENS_IC  = 0.0_sp
    !Inst%FLASH_DENS_CG  = 0.0_sp
    Inst%CONV_DEPTH     = 0.0_sp

    ! LMAX: the highest L-level to look for lightning NOx (usually LLPAR-1)
    LMAX   = HcoState%NZ - 1

    ! Get current month (to be passed to LIGHTDIST)
    CALL HcoClock_Get( HcoState%Clock, cMM=MONTH, RC=RC)
    IF ( RC /= HCO_SUCCESS ) THEN
        CALL HCO_ERROR( 'ERROR 3', RC, THISLOC=LOC )
        RETURN
    ENDIF

    !=================================================================
    ! Compute lightning NOx emissions for each (I,J) column
    !=================================================================

!$OMP PARALLEL DO                                                     &
!$OMP DEFAULT( SHARED )                                               &
!$OMP PRIVATE( I,         J,           L,        A_M2,        A_KM2  ) &
!$OMP PRIVATE( YMID,      XMID,        LTOP,     MTYPE               ) &
!$OMP PRIVATE( LNDTYPE,   SFCTYPE,     TROPP                         ) &
!$OMP PRIVATE( RATE,      RATE_SAVE,   H0,       IC_CG_RATIO         ) &
!$OMP PRIVATE( TOTAL,     TOTAL_IC,    TOTAL_CG, VERTPROF,    X      ) &
!$OMP SCHEDULE( DYNAMIC )

    ! Loop over surface boxes
    DO J = 1, HcoState%NY
    DO I = 1, HcoState%NX

       ! Grid box surface areas in [m2] and [km2]
       A_M2     = HcoState%Grid%AREA_M2%Val( I, J )
       A_KM2    = A_M2 / 1d6

       ! Grid box latitude and longitude [degrees]
       YMID     = HcoState%Grid%YMID%Val( I, J )
       XMID     = HcoState%Grid%XMID%Val( I, J )

       ! Make sure xmid is between -180 and +180
       IF ( XMID >= 180.0d0 ) XMID = XMID - 360.0d0

       ! Get surface type. Note that these types are different than
       ! the types used elsewhere in this module. HCO_LANDTYPE returns
       ! 0=ocean, 1=land, 2=ice; elsewhere we use 0=land, 1=ocean, 2=ice!
       LNDTYPE = HCO_LANDTYPE( ExtState%FRLAND%Arr%Val(I,J),   &
                               ExtState%FRLANDIC%Arr%Val(I,J), &
                               ExtState%FROCEAN%Arr%Val(I,J),  &
                               ExtState%FRSEAICE%Arr%Val(I,J), &
                               ExtState%FRLAKE%Arr%Val(I,J))

       ! Set surface type (0=land, 1=ocean, 2=ice) based on land type
       IF ( LNDTYPE == 2 ) THEN
          SFCTYPE = 2    ! Ice
       ELSEIF ( LNDTYPE == 1 ) THEN
          SFCTYPE = 0    ! Land
       ELSE
          SFCTYPE = 1    ! Ocean (default)
       ENDIF

       ! Tropopause pressure. Convert to Pa
       TROPP = ExtState%TROPP%Arr%Val(I,J) !* 100.0_hp

       !===========================================================
       ! Initialize
       !===========================================================
       RATE          = 0.0
       RATE_SAVE     = 0.0
       H0            = 0.0
       IC_CG_RATIO   = 1.0

       TOTAL         = 0d0
       TOTAL_IC      = 0d0
       TOTAL_CG      = 0d0

       !===========================================================
       ! (1) Get flash density [#/km2/s] from meteorology
       !===========================================================

       !-----------------------------------------------------------
       ! (1a) Prescribed in HEMCO_Config.rc
       !-----------------------------------------------------------
       RATE        = ExtState%FLASH_DENS%Arr%Val(I,J)

       !-----------------------------------------------------------
       ! (1b) From GEOS-5
       !-----------------------------------------------------------
       IF ( Inst%LLFR                                  &
            .AND. ASSOCIATED( ExtState%LFR%Arr%Val   ) &
            .AND. ASSOCIATED( ExtState%BYNCY%Arr%Val )  ) THEN
          RATE     = ExtState%LFR%Arr%Val(I,J)
       ENDIF

       ! Error check: do not continue if flash rate is zero
       IF ( RATE <= 0.0 ) CYCLE

       !===========================================================
       ! (2) Get depth of convection [m] and find associated LTOP
       !===========================================================

       !-----------------------------------------------------------
       ! (2a) Prescribed in HEMCO_Config.rc
       !-----------------------------------------------------------
       H0          = ExtState%CONV_DEPTH%Arr%Val(I,J)
       LTOP = 1
       DO L = 1, HcoState%NZ
          IF ( SUM(HcoState%Grid%BXHEIGHT_M%Val(I,J,1:L)) > H0 ) THEN
             LTOP = L
             EXIT
          ENDIF
       ENDDO
       ! Reset H0 to be the height of that layer in the model,
       ! to avoid negative values in the partitioning
       H0          = SUM(HcoState%Grid%BXHEIGHT_M%Val(I,J,1:LTOP))

       !-----------------------------------------------------------
       ! (2b) From GEOS-5
       !-----------------------------------------------------------
       IF ( Inst%LLFR                                  &
            .AND. ASSOCIATED( ExtState%LFR%Arr%Val   ) &
            .AND. ASSOCIATED( ExtState%BYNCY%Arr%Val )  ) THEN

          ! Set LTOP to top of buoyancy
          DO L = HcoState%NZ, 1, -1
             IF ( ExtState%BYNCY%Arr%Val(I,J,L) >= 0.0_sp ) THEN
                LTOP = L + 1
                EXIT
             ENDIF
          ENDDO
          !LTOP = MAX( LTOP, LMAX )
          ! H0 is the convective cloud top height [m].  This is the
          ! distance from the surface to the top edge of box (I,J,LTOP).
          H0 = SUM(HcoState%Grid%BXHEIGHT_M%Val(I,J,1:LTOP))
       ENDIF

       ! Save out convective cloud depth
       Inst%CONV_DEPTH(I,J) = LTOP

       !===========================================================
       ! (3) Compute ratio of CG vs total flashes
       !===========================================================

       ! Ratio of cloud-to-ground flashes to total # of flashes
       X    = 1d0 / ( 1d0 + IC_CG_RATIO )

       !-----------------------------------------------------------
       ! Store flash rates [flashes/km2/min]
       !-----------------------------------------------------------
       IF ( RATE > 0d0 ) THEN

          ! Flashes per km2 per minute
          RATE_SAVE   = RATE / 60d0

          ! Store total, IC, and CG flash rates
          Inst%FLASH_DENS_TOT(I,J) = RATE_SAVE
          !Inst%FLASH_DENS_IC(I,J)  = RATE_SAVE * X
          !Inst%FLASH_DENS_CG(I,J)  = RATE_SAVE * ( 1d0 - X )

       ENDIF

       !===========================================================
       ! (4) Compute LNOx yield for IC and CG flashes (molec/km2/s)
       !===========================================================

       ! Compute LNOx emissions for tropics or midlats
       IF ( XMID > EAST_WEST_DIV ) THEN

          !--------------------------------------------------------
          ! (4a) We are in EURASIA
          !--------------------------------------------------------
          IF ( YMID > EAST_NS_DIV ) THEN

             ! Eurasian Mid-Latitudes
             TOTAL_IC = RFLASH_MIDLAT * RATE * ( 1d0 - X )
             TOTAL_CG = RFLASH_MIDLAT * RATE * X

          ELSE

             ! Eurasian Tropics
             TOTAL_IC = RFLASH_TROPIC * RATE * ( 1d0 - X )
             TOTAL_CG = RFLASH_TROPIC * RATE * X

          ENDIF

       ELSE

          !--------------------------------------------------------
          ! (4b) We are in the AMERICAS
          !--------------------------------------------------------
          IF ( YMID > WEST_NS_DIV ) THEN

             ! American Mid-Latitudes
             TOTAL_IC = RFLASH_MIDLAT * RATE * ( 1d0 - X )
             TOTAL_CG = RFLASH_MIDLAT * RATE * X

          ELSE

             ! American Tropics
             TOTAL_IC = RFLASH_TROPIC * RATE * ( 1d0 - X )
             TOTAL_CG = RFLASH_TROPIC * RATE * X

          ENDIF
       ENDIF

       !===========================================================
       ! (5) Compute column total lightning NOx yield (kg/km2/s)
       !===========================================================

       ! Sum of IC + CG
       TOTAL = TOTAL_IC + TOTAL_CG

       ! Convert from molec km-2 s-1 to kg(NO) m-2 s-1
       TOTAL = TOTAL * ( HcoState%Spc(Inst%IDTNO)%MW_g / 1000.0_hp ) / &
                         HcoState%Phys%Avgdr / 1000000.0_hp

       !===========================================================
       ! (6) Distribute column LNOx vertically from surface to LTOP
       !===========================================================

       !-----------------------------------------------------------
       ! LIGHTDIST computes the lightning NOx distribution from
       ! the ground to the convective cloud top using cumulative
       ! distribution functions for ocean flashes, tropical land
       ! flashes, and non-tropical land flashes, as specified by
       ! Lesley Ott [JGR, 2010]
       !-----------------------------------------------------------

       ! If there's lightning NOx w/in the column ...
       IF ( TOTAL > 0d0 ) THEN

          ! Partition the column total NOx [kg/m2/s] from lightning
          ! into the vertical using Ott et al. [2010] PDF functions
          CALL LIGHTDIST( I, J, LTOP, H0, YMID, TOTAL, VERTPROF, &
                          ExtState, HcoState, SFCTYPE, MONTH, MTYPE, Inst )

          ! Add vertically partitioned NOx into SLBASE array
          DO L = 1, HcoState%NZ
             Inst%SLBASE(I,J,L) = VERTPROF(L)

             ! No lightning NOx emissions in the stratosphere (cdh, 4/25/2013)
             IF ( HcoState%Grid%PEDGE%Val(I,J,L) < TROPP ) THEN
                Inst%SLBASE(I,J,L) = 0.0_hp
             ENDIF

          ENDDO
       ENDIF

    ENDDO
    ENDDO
!$OMP END PARALLEL DO

    !-----------------------------------------------------------------
    ! Eventually add scale factors
    !-----------------------------------------------------------------

    ! Eventually apply species specific scale factor
    IF ( Inst%SpcScalVal(1) /= 1.0_sp ) THEN
       Inst%SLBASE = Inst%SLBASE * Inst%SpcScalVal(1)
    ENDIF

    ! Eventually apply spatiotemporal scale factors
    CALL HCOX_SCALE( HcoState, Inst%SLBASE, TRIM(Inst%SpcScalFldNme(1)), RC )
    IF ( RC /= HCO_SUCCESS ) THEN
        CALL HCO_ERROR( 'ERROR 4', RC, THISLOC=LOC )
        RETURN
    ENDIF

    ! Return w/ success
    CALL HCO_LEAVE( HcoState%Config%Err,RC )

  END SUBROUTINE LightNOx
!EOC
!------------------------------------------------------------------------------
!                   Harmonized Emissions Component (HEMCO)                    !
!------------------------------------------------------------------------------
!BOP
!
! !IROUTINE: LightDist
!
! !DESCRIPTION: Subroutine LightDist reads in the CDF used to partition the
!  column lightning NOx into the GEOS-Chem vertical layers.
!\\
!\\
! !INTERFACE:
!
  SUBROUTINE LightDist( I, J, LTOP, H0, XLAT, TOTAL, VERTPROF, &
                        ExtState, HcoState, SFCTYPE, MONTH, MTYPE, Inst )
!
! !INPUT PARAMETERS:
!
    INTEGER,         INTENT(IN)  :: I          ! Longitude index
    INTEGER,         INTENT(IN)  :: J          ! Latitude index
    INTEGER,         INTENT(IN)  :: LTOP       ! Level of conv cloud top
    REAL*8,          INTENT(IN)  :: H0         ! Conv cloud top height [m]
    REAL*8,          INTENT(IN)  :: XLAT       ! Latitude value [degrees]
    REAL*8,          INTENT(IN)  :: TOTAL      ! Column Total # of LNOx molec
    TYPE(Ext_State), POINTER     :: ExtState   ! Module options
    TYPE(HCO_State), POINTER     :: HcoState   ! Hemco state object
    INTEGER,         INTENT(IN)  :: SFCTYPE    ! Surface type
    INTEGER,         INTENT(IN)  :: MONTH      ! Current month
    TYPE(MyInst),    POINTER     :: Inst       ! Hemco state object
!
! !OUTPUT PARAMETERS:
!
    REAL*8,          INTENT(OUT) :: VERTPROF(HcoState%NZ) ! Vertical profile
    INTEGER,         INTENT(OUT) :: MTYPE                 ! lightning type
!
! !REMARKS:
!  References:
!  ============================================================================
!  (1 ) Pickering et al., JGR 103, 31,203 - 31,316, 1998.
!  (2 ) Ott et al., JGR, 2010
!  (3 ) Allen et al., JGR, 2010
!
! !REVISION HISTORY:
!  18 Sep 2002 - M. Evans - Initial version (based on Yuhang Wang's code)
!  See https://github.com/geoschem/hemco for complete history
!EOP
!------------------------------------------------------------------------------
!BOC
!
! !LOCAL VARIABLES:
!
    INTEGER :: L
    REAL*8  :: ZHEIGHT, YMID
    REAL*8  :: FRAC(HcoState%NZ)

      !=================================================================
      ! LIGHTDIST begins here!
      !=================================================================

    ! Initialize
    MTYPE    = 0
    VERTPROF = 0d0

    !%%% NOTE: Use L=1 for GRID_MOD functions.  This is OK for the
    !%%% existing GEOS-Chem with a pure cartesian grid, but may be an
    !%%% issue when interfaced with a GCM with a non-regular grid
    !%%% (bmy, 3/1/12)
    YMID     = HcoState%Grid%YMID%Val( I, J )

    !=================================================================
    ! Test whether location (I,J) is continental, marine, or snow/ice
    !
    ! Depending on the combination of land/water and latitude,
    ! assign a flag describing the type of lightning:
    !
    !   MTYPE = 1: ocean lightning
    !   MTYPE = 2: tropical continental lightning
    !   MTYPE = 3: midlatitude continental lightning
    !   MTYPE = 4: subtropical lightning
    !
    ! (ltm, bmy, 1/25/11)
    !=================================================================

    ! Assign profile kind to grid box, following Allen et al.
    ! [JGR, 2010] (ltm, 1/25,11)

    SELECT CASE ( MONTH )

       ! Southern Hemisphere Summer
       CASE ( 1,2,3,12 )

           IF ( ABS(YMID) .le. 15 ) THEN
              IF ( SFCTYPE == 0 ) THEN
                 MTYPE = 2        ! Tropical continental
              ELSE
                 MTYPE = 1        ! Tropical marine
              ENDIF
           ELSE IF ( ( YMID .gt. 15. ) .and. ( YMID .le. 30. ) ) THEN
              MTYPE = 4           ! N. Subtropics
           ELSE IF ( ( YMID .ge. -40. ) .and. ( YMID .lt. -15. ) ) THEN
              MTYPE = 4           ! S. Subtropics
           ELSE
              MTYPE = 3           ! Midlatitude
           ENDIF

        ! Equinox months
        CASE ( 4,5,10,11 )

           IF ( ABS(YMID) .le. 15 ) THEN
              IF ( SFCTYPE == 0 ) THEN
                 MTYPE = 2        ! Tropical continental
              ELSE
                 MTYPE = 1        ! Tropical marine
              ENDIF
           ELSE IF ( ABS(YMID) .le. 30 ) THEN
              MTYPE = 4           ! Subtropics
           ELSE
              MTYPE = 3           ! Midlatitude
           ENDIF

        ! Northern Hemisphere Summer
        CASE ( 6,7,8,9 )

           IF ( ABS(YMID) .le. 15 ) THEN
              IF ( SFCTYPE == 0 ) THEN
                 MTYPE = 2        ! Tropical continental
              ELSE
                 MTYPE = 1        ! Tropical marine
              ENDIF
           ELSE IF ( ( YMID .gt. 15. ) .and. ( YMID .le. 40. ) ) THEN
              MTYPE = 4           ! N. Subtropics
           ELSE IF ( ( YMID .ge. -30. ) .and. ( YMID .lt. -15. ) ) THEN
              MTYPE = 4           ! S. Subtropics
           ELSE
              MTYPE = 3           ! Midlatitude
           ENDIF

    END SELECT

    ! Extra safety check for pathological grid boxes (bmy, 11/29/06)
    IF ( MTYPE == 0 ) RETURN

    !=================================================================
    ! Use the CDF for this type of lightning to partition the total
    ! column lightning NOx into the layers
    !=================================================================
    ZHEIGHT = 0.0

    ! Compute the height [km] at the top of each vertical level.
    ! Look up the cumulative fraction of NOx for each vertical level
    DO L = 1, LTOP
       ZHEIGHT = ZHEIGHT + HcoState%Grid%BXHEIGHT_M%Val(I,J,L)
       FRAC(L) = Inst%PROFILE( NINT( ( ZHEIGHT/H0 )*3200. ), MTYPE ) *0.01
    ENDDO

    ! Convert from cumulative fraction to fraction for each level
    DO L = LTOP, 2, - 1
       FRAC(L) = FRAC(L) - FRAC(L-1)
    ENDDO

    ! Partition lightning NOx by layer into VERTPROF
    DO L = 1, LTOP
       VERTPROF(L) = ( FRAC(L) * TOTAL )
    ENDDO

  END SUBROUTINE LightDist
!EOC
!------------------------------------------------------------------------------
!                   Harmonized Emissions Component (HEMCO)                    !
!------------------------------------------------------------------------------
!BOP
!
! !IROUTINE: HCOX_LightNOx_Init
!
! !DESCRIPTION: Subroutine HCOX\_LIGHTNOX\_INIT allocates all module arrays.
!  It also reads the lightning CDF data from disk before the first lightning
!  timestep.
!\\
!\\
! !INTERFACE:
!
  SUBROUTINE HCOX_LightNOx_Init( HcoState, ExtName, ExtState, RC )
!
! !USES:
!
    USE HCO_Chartools_Mod, ONLY : HCO_CharParse
    USE HCO_ExtList_Mod,   ONLY : GetExtNr
    USE HCO_ExtList_Mod,   ONLY : GetExtOpt
    USE HCO_ExtList_Mod,   ONLY : GetExtSpcVal
    USE HCO_State_Mod,     ONLY : HCO_GetHcoID
    USE HCO_State_Mod,     ONLY : HCO_GetExtHcoID
    USE HCO_ReadList_Mod,  ONLY : ReadList_Remove
    USE HCO_inquireMod,    ONLY : findfreeLUN
!
! !INPUT PARAMETERS:
!
    TYPE(HCO_State),  POINTER        :: HcoState   ! Hemco options
    CHARACTER(LEN=*), INTENT(IN   )  :: ExtName    ! Extension name
    TYPE(Ext_State),  POINTER        :: ExtState     ! Module options
!
! !OUTPUT PARAMETERS:
!
    INTEGER,          INTENT(  OUT)  :: RC
!
! !REVISION HISTORY:
!  14 Apr 2004 - R. Yantosca - Initial version
!  See https://github.com/geoschem/hemco for complete history
!EOP
!------------------------------------------------------------------------------
!BOC
!
! !LOCAL VARIABLES:
!
    INTEGER                        :: AS, III, IOS, JJJ, IU_FILE, nSpc
    INTEGER                        :: ExtNr
    LOGICAL                        :: FOUND, FileExists
    INTEGER, ALLOCATABLE           :: HcoIDs(:)
    CHARACTER(LEN=31), ALLOCATABLE :: SpcNames(:)
    CHARACTER(LEN=255)             :: MSG, LOC, FILENAME, FileMsg
    TYPE(MyInst), POINTER          :: Inst

    !=======================================================================
    ! HCOX_LightNOX_Init begins here!
    !=======================================================================
    LOC = 'HCOX_LightNOX_Init (HCOX_LIGHTNOX_MOD.F90)'

    ! Extension Nr.
    ExtNr = GetExtNr( HcoState%Config%ExtList, TRIM(ExtName) )
    IF ( ExtNr <= 0 ) RETURN

    ! Enter
    CALL HCO_ENTER( HcoState%Config%Err, LOC, RC )
    IF ( RC /= HCO_SUCCESS ) THEN
        CALL HCO_ERROR( 'ERROR 5', RC, THISLOC=LOC )
        RETURN
    ENDIF

    ! Create LightNOx instance for this simulation
    Inst => NULL()
    CALL InstCreate ( ExtNr, ExtState%LightNOx, Inst, RC )
    IF ( RC /= HCO_SUCCESS ) THEN
       CALL HCO_ERROR ( 'Cannot create LightNOx instance', RC )
       RETURN
    ENDIF

    !=======================================================================
    ! Obtain lightning CDF's from Ott et al [JGR, 2010].
    !
    ! PART 1 --- Move the file name check to the front of this routine to
    ! facilitate the GEOS-Chem dry-run and HEMCO-standalone dry-run.
    !=======================================================================

    ! Get filename from configuration file
    CALL GetExtOpt( HcoState%Config, ExtNr, 'CDF table',                     &
                    OptValChar=FILENAME, RC=RC                              )
    IF ( RC /= HCO_SUCCESS ) THEN
        CALL HCO_ERROR( 'ERROR 6', RC, THISLOC=LOC )
        RETURN
    ENDIF

    ! Call HEMCO parser to replace tokens such as $ROOT, $MET, or $RES.
    ! There shouldn't be any date token in there ($YYYY, etc.), so just
    ! provide some dummy variables here
    CALL HCO_CharParse( HcoState%Config, FILENAME, -999, -1, -1, -1, -1, RC )
    IF ( RC /= HCO_SUCCESS ) THEN
        CALL HCO_ERROR( 'ERROR 7', RC, THISLOC=LOC )
        RETURN
    ENDIF

    !-----------------------------------------------------------------------
    ! In dry-run mode, print file path to dryrun log and exit.
    ! Otherwise, print file path to the HEMCO log file and continue.
    !-----------------------------------------------------------------------

    ! Test if the file exists
    INQUIRE( FILE=TRIM( FileName ), EXIST=FileExists )

    ! Create a display string based on whether or not the file is found
    IF ( FileExists ) THEN
       FileMsg = 'HEMCO (LIGHTNOX): Opening'
    ELSE
       FileMsg = 'HEMCO (LIGHTNOX): REQUIRED FILE NOT FOUND'
    ENDIF

    ! Write file status to stdout and the HEMCO log
    IF ( HcoState%amIRoot ) THEN
       WRITE( 6,   300 ) TRIM( FileMsg ), TRIM( FileName )
       WRITE( MSG, 300 ) TRIM( FileMsg ), TRIM( FileName )
       CALL HCO_MSG( HcoState%Config%Err, MSG )
 300   FORMAT( a, ' ', a )
    ENDIF

    ! For dry-run simulation, return to calling program.
    ! For regular simulations, throw an error if we can't find the file.
    IF ( HcoState%Options%IsDryRun ) THEN
       RETURN
    ELSE
       IF ( .not. FileExists ) THEN
          WRITE( MSG, 300 ) TRIM( FileMsg ), TRIM( FileName )
          CALL HCO_ERROR(MSG, RC )
          RETURN
       ENDIF
    ENDIF

    !=======================================================================
    ! Exit if this is a GEOS-Chem or HEMCO-standalone dry-run
    !=======================================================================
    IF ( HcoState%Options%IsDryRun ) THEN
       Inst => NULL()
       CALL HCO_LEAVE( HcoState%Config%Err,RC )
       RETURN
    ENDIF

    !=======================================================================
    ! Continue for regular simulations ...
    !=======================================================================

    ! Check for usage of convective fractions. This becomes only active
    ! if both the convective fraction and the buoyancy field are available.
    CALL GetExtOpt( HcoState%Config, ExtNr, 'Use CNV_FRC', &
                     OptValBool=Inst%LCNVFRC, FOUND=FOUND, RC=RC )
    IF ( RC /= HCO_SUCCESS ) THEN
        CALL HCO_ERROR( 'ERROR 8', RC, THISLOC=LOC )
        RETURN
    ENDIF
    IF ( .NOT. FOUND ) Inst%LCNVFRC = .FALSE.

    ! Check for usage of GEOS-5 lightning flash rates. If on, the GEOS-5
    ! flash rates (where available) are used instead of the computed flash
    ! rates. This is off by default.
    CALL GetExtOpt( HcoState%Config, ExtNr, 'GEOS-5 flash rates', &
                     OptValBool=Inst%LLFR, FOUND=FOUND, RC=RC )
    IF ( RC /= HCO_SUCCESS ) THEN
        CALL HCO_ERROR( 'ERROR 9', RC, THISLOC=LOC )
        RETURN
    ENDIF
    IF ( .NOT. FOUND ) Inst%LLFR = .FALSE.

    ! Get species ID
    CALL HCO_GetExtHcoID( HcoState, ExtNr, HcoIDs, SpcNames, nSpc, RC )
    IF ( RC /= HCO_SUCCESS ) THEN
        CALL HCO_ERROR( 'ERROR 10', RC, THISLOC=LOC )
        RETURN
    ENDIF
    IF ( nSpc /= 1 ) THEN
       MSG = 'Lightning NOx module must have exactly one species!'
       CALL HCO_ERROR(MSG, RC )
       RETURN
    ENDIF
    Inst%IDTNO = HcoIDs(1)

    ! Get species scale factor
    CALL GetExtSpcVal( HcoState%Config, ExtNr, nSpc, &
                       SpcNames, 'Scaling', 1.0_sp, Inst%SpcScalVal, RC )
    IF ( RC /= HCO_SUCCESS ) THEN
        CALL HCO_ERROR( 'ERROR 11', RC, THISLOC=LOC )
        RETURN
    ENDIF

    CALL GetExtSpcVal( HcoState%Config, ExtNr, nSpc, &
                       SpcNames, 'ScaleField', HCOX_NOSCALE, Inst%SpcScalFldNme, RC )
    IF ( RC /= HCO_SUCCESS ) THEN
        CALL HCO_ERROR( 'ERROR 12', RC, THISLOC=LOC )
        RETURN
    ENDIF

    ! Echo info about this extension
    IF ( HcoState%amIRoot ) THEN
       MSG = 'Use lightning NOx emissions (extension module)'
       CALL HCO_MSG(HcoState%Config%Err,MSG, SEP1='-' )
       WRITE(MSG,*) ' - Use species ', TRIM(SpcNames(1)), '->', Inst%IDTNO
       CALL HCO_MSG(HcoState%Config%Err,MSG)
       WRITE(MSG,*) ' - Use GEOS-5 flash rates: ', Inst%LLFR
       CALL HCO_MSG(HcoState%Config%Err,MSG)
       WRITE(MSG,*) ' - Use scalar scale factor: ', Inst%SpcScalVal(1)
       CALL HCO_MSG(HcoState%Config%Err,MSG)
       WRITE(MSG,*) ' - Use gridded scale field: ', TRIM(Inst%SpcScalFldNme(1))
       CALL HCO_MSG(HcoState%Config%Err,MSG)
    ENDIF

    !=======================================================================
    ! Allocate arrays
    !=======================================================================

    ALLOCATE( Inst%PROFILE( NNLIGHT, NLTYPE ), STAT=AS )
    IF( AS /= 0 ) THEN
       CALL HCO_ERROR ( 'PROFILE', RC )
       RETURN
    ENDIF
    Inst%PROFILE = 0.0_hp

    ALLOCATE( Inst%SLBASE(HcoState%NX,HcoState%NY,HcoState%NZ), STAT=AS )
    IF( AS /= 0 ) THEN
       CALL HCO_ERROR ( 'SLBASE', RC )
       RETURN
    ENDIF
    Inst%SLBASE = 0.0_hp

    ALLOCATE ( Inst%FLASH_DENS_TOT( HcoState%NX, HcoState%NY), STAT=AS )
    IF ( AS/=0 ) THEN
       CALL HCO_ERROR( 'FLASH_DENS_TOT', RC )
       RETURN
    ENDIF
    Inst%FLASH_DENS_TOT = 0.0_sp

    !ALLOCATE ( Inst%FLASH_DENS_IC( HcoState%NX, HcoState%NY), STAT=AS )
    !IF ( AS/=0 ) THEN
    !   CALL HCO_ERROR( 'FLASH_DENS_IC', RC )
    !   RETURN
    !ENDIF
    !Inst%FLASH_DENS_IC = 0.0_sp

    !ALLOCATE ( Inst%FLASH_DENS_CG( HcoState%NX, HcoState%NY), STAT=AS )
    !IF ( AS/=0 ) THEN
    !   CALL HCO_ERROR( 'FLASH_DENS_CG', RC )
    !   RETURN
    !ENDIF
    !Inst%FLASH_DENS_CG = 0.0_sp

    ALLOCATE ( Inst%CONV_DEPTH( HcoState%NX, HcoState%NY), STAT=AS )
    IF ( AS/=0 ) THEN
       CALL HCO_ERROR( 'CONV_DEPTH', RC )
       RETURN
    ENDIF
    Inst%CONV_DEPTH = 0.0_sp

    !=======================================================================
    ! Obtain lightning CDF's from Ott et al [JGR, 2010].
    !
    ! PART 2 --- Read the data!
    !=======================================================================

    ! Find a free file LUN
    IU_FILE = findFreeLUN()

    ! Open file containing lightning NOx PDF data
    OPEN( IU_FILE, FILE=TRIM( FILENAME ), STATUS='OLD', IOSTAT=IOS )
    IF ( IOS /= 0 ) THEN
       MSG = 'IOERROR: LightDist: 1'
       CALL HCO_ERROR(MSG, RC )
       RETURN
    ENDIF

    ! Read 12 header lines
    DO III = 1, 12
       READ( IU_FILE, '(a)', IOSTAT=IOS )
       IF ( IOS /= 0 ) THEN
          MSG = 'IOERROR: LightDist: 2'
          CALL HCO_ERROR(MSG, RC )
          RETURN
       ENDIF
    ENDDO

    ! Read NNLIGHT types of lightning profiles
    DO III = 1, NNLIGHT
       READ( IU_FILE,*,IOSTAT=IOS) (Inst%PROFILE(III,JJJ),JJJ=1,NLTYPE)
       IF ( IOS /= 0 ) THEN
          MSG = 'IOERROR: LightDist: 3'
          CALL HCO_ERROR(MSG, RC )
          RETURN
       ENDIF
    ENDDO

    ! Close file
    CLOSE( IU_FILE )

    !=======================================================================
    ! Create diagnostics for lightning flash rates and convective cloud height
    !=======================================================================
    CALL Diagn_Create( HcoState  = HcoState,                        &
                       cName     = 'HcoLightningFlashRate_Total',   &
                       ExtNr     = ExtNr,                           &
                       Cat       = -1,                              &
                       Hier      = -1,                              &
                       HcoID     = -1,                              &
                       SpaceDim  = 2,                               &
                       OutUnit   = 'flashes/min/km2',               &
                       AutoFill  = 0,                               &
                       Trgt2D    = Inst%FLASH_DENS_TOT,             &
                       RC        = RC )
    IF ( RC /= HCO_SUCCESS ) THEN
        CALL HCO_ERROR( 'ERROR 13', RC, THISLOC=LOC )
        RETURN
    ENDIF

    !CALL Diagn_Create( HcoState  = HcoState,                        &
    !                   cName     = 'HcoLightningFlashRate_IntraCld', &
    !                   ExtNr     = ExtNr,                           &
    !                   Cat       = -1,                              &
    !                   Hier      = -1,                              &
    !                   HcoID     = -1,                              &
    !                   SpaceDim  = 2,                               &
    !                   OutUnit   = 'flashes/min/km2',               &
    !                   AutoFill  = 0,                               &
    !                   Trgt2D    = Inst%FLASH_DENS_IC,              &
    !                   RC        = RC )
    !IF ( RC /= HCO_SUCCESS ) RETURN
    !    
    !CALL Diagn_Create( HcoState  = HcoState,                         &
    !                   cName     = 'HcoLightningFlashRate_CldGround', &
    !                   ExtNr     = ExtNr,                            &
    !                   Cat       = -1,                               &
    !                   Hier      = -1,                               &
    !                   HcoID     = -1,                               &
    !                   SpaceDim  = 2,                                &
    !                   OutUnit   = 'flashes/min/km2',                &
    !                   AutoFill  = 0,                                &
    !                   Trgt2D    = Inst%FLASH_DENS_CG,               &
    !                   RC        = RC )
    !IF ( RC /= HCO_SUCCESS ) RETURN

    CALL Diagn_Create( HcoState  = HcoState,                         &
                       cName     = 'HcoConvectiveCloudTopHeight',       &
                       ExtNr     = ExtNr,                            &
                       Cat       = -1,                               &
                       Hier      = -1,                               &
                       HcoID     = -1,                               &
                       SpaceDim  = 2,                                &
                       OutUnit   = '1',                              &
                       AutoFill  = 0,                                &
                       Trgt2D    = Inst%CONV_DEPTH,                  &
                       RC        = RC )
    IF ( RC /= HCO_SUCCESS ) THEN
        CALL HCO_ERROR( 'ERROR 14', RC, THISLOC=LOC )
        RETURN
    ENDIF

    !=======================================================================
    ! Activate met fields required by this module
    !=======================================================================
    ExtState%TK%DoUse         = .TRUE.
    ExtState%TROPP%DoUse      = .TRUE.
    ExtState%CNV_MFC%DoUse    = .TRUE.
    ExtState%CNV_FRC%DoUse    = .TRUE.
    ExtState%LFR%DoUse        = .TRUE.
    ExtState%FLASH_DENS%DoUse = .TRUE.
    ExtState%CONV_DEPTH%DoUse = .TRUE.
    ExtState%FRLAND%DoUse     = .TRUE.
    ExtState%FRLANDIC%DoUse   = .TRUE.
    ExtState%FROCEAN%DoUse    = .TRUE.
    ExtState%FRSEAICE%DoUse   = .TRUE.
    ExtState%FRLAKE%DoUse     = .TRUE.

    ! Only activate BYNCY and LFR if they are needed
    IF ( Inst%LCNVFRC .OR. Inst%LLFR ) ExtState%BYNCY%DoUse = .TRUE.
    IF ( Inst%LLFR ) ExtState%LFR%DoUse = .TRUE.

    ! Cleanup
    Inst => NULL()

    ! Leave w/ success
    IF ( ALLOCATED(HcoIDs  ) ) DEALLOCATE(HcoIDs  )
    IF ( ALLOCATED(SpcNames) ) DEALLOCATE(SpcNames)
    CALL HCO_LEAVE( HcoState%Config%Err,RC )

  END SUBROUTINE HCOX_LightNOx_Init
!EOC
!------------------------------------------------------------------------------
!                   Harmonized Emissions Component (HEMCO)                    !
!------------------------------------------------------------------------------
!BOP
!
! !IROUTINE: hcox_lightnox_final
!
! !DESCRIPTION: Subroutine HCOX\_LIGHTNOX\_FINAL deallocates all module
!  arrays.
!\\
!\\
! !INTERFACE:
!
  SUBROUTINE HCOX_LightNOx_Final( ExtState )
!
! !INPUT PARAMETERS:
!
    TYPE(Ext_State),  POINTER       :: ExtState   ! Module options
!
! !REVISION HISTORY:
!  14 Apr 2004 - R. Yantosca - Initial version
!  See https://github.com/geoschem/hemco for complete history
!EOP
!------------------------------------------------------------------------------
!BOC

    !=================================================================
    ! Cleanup module arrays
    !=================================================================
    CALL InstRemove ( ExtState%LightNOx )

  END SUBROUTINE HCOX_LightNOx_Final
!EOC
!------------------------------------------------------------------------------
!                   Harmonized Emissions Component (HEMCO)                    !
!------------------------------------------------------------------------------
!BOP
!
! !IROUTINE: InstGet
!
! !DESCRIPTION: Subroutine InstGet returns a pointer to the desired instance.
!\\
!\\
! !INTERFACE:
!
  SUBROUTINE InstGet ( Instance, Inst, RC, PrevInst )
!
! !INPUT PARAMETERS:
!
    INTEGER                             :: Instance
    TYPE(MyInst),     POINTER           :: Inst
    INTEGER                             :: RC
    TYPE(MyInst),     POINTER, OPTIONAL :: PrevInst
!
! !REVISION HISTORY:
!  18 Feb 2016 - C. Keller   - Initial version
!  See https://github.com/geoschem/hemco for complete history
!EOP
!------------------------------------------------------------------------------
!BOC
    TYPE(MyInst),     POINTER    :: PrvInst

    !=================================================================
    ! InstGet begins here!
    !=================================================================

    ! Get instance. Also archive previous instance.
    PrvInst => NULL()
    Inst    => AllInst
    DO WHILE ( ASSOCIATED(Inst) )
       IF ( Inst%Instance == Instance ) EXIT
       PrvInst => Inst
       Inst    => Inst%NextInst
    END DO
    IF ( .NOT. ASSOCIATED( Inst ) ) THEN
       RC = HCO_FAIL
       RETURN
    ENDIF

    ! Pass output arguments
    IF ( PRESENT(PrevInst) ) PrevInst => PrvInst

    ! Cleanup & Return
    PrvInst => NULL()
    RC = HCO_SUCCESS

  END SUBROUTINE InstGet
!EOC
!------------------------------------------------------------------------------
!                   Harmonized Emissions Component (HEMCO)                    !
!------------------------------------------------------------------------------
!BOP
!
! !IROUTINE: InstCreate
!
! !DESCRIPTION: Subroutine InstCreate adds a new instance to the list of
!  instances, assigns a unique instance number to this new instance, and
!  archives this instance number to output argument Instance.
!\\
!\\
! !INTERFACE:
!
  SUBROUTINE InstCreate ( ExtNr, Instance, Inst, RC )
!
! !INPUT PARAMETERS:
!
    INTEGER,       INTENT(IN)       :: ExtNr
!
! !OUTPUT PARAMETERS:
!
    INTEGER,       INTENT(  OUT)    :: Instance
    TYPE(MyInst),  POINTER          :: Inst
!
! !INPUT/OUTPUT PARAMETERS:
!
    INTEGER,       INTENT(INOUT)    :: RC
!
! !REVISION HISTORY:
!  18 Feb 2016 - C. Keller   - Initial version
!  See https://github.com/geoschem/hemco for complete history
!EOP
!------------------------------------------------------------------------------
!BOC
    TYPE(MyInst), POINTER          :: TmpInst
    INTEGER                        :: nnInst

    !=================================================================
    ! InstCreate begins here!
    !=================================================================

    ! ----------------------------------------------------------------
    ! Generic instance initialization
    ! ----------------------------------------------------------------

    ! Initialize
    Inst => NULL()

    ! Get number of already existing instances
    TmpInst => AllInst
    nnInst = 0
    DO WHILE ( ASSOCIATED(TmpInst) )
       nnInst  =  nnInst + 1
       TmpInst => TmpInst%NextInst
    END DO

    ! Create new instance
    ALLOCATE(Inst)
    Inst%Instance = nnInst + 1
    Inst%ExtNr    = ExtNr

    ! Attach to instance list
    Inst%NextInst => AllInst
    AllInst       => Inst

    ! Update output instance
    Instance = Inst%Instance

    ! Return w/ success
    RC = HCO_SUCCESS

  END SUBROUTINE InstCreate
!EOC
!------------------------------------------------------------------------------
!                   Harmonized Emissions Component (HEMCO)                    !
!------------------------------------------------------------------------------
!BOP
!
! !IROUTINE: InstRemove
!
! !DESCRIPTION: Subroutine InstRemove removes an instance from the list of
! instances.
!\\
!\\
! !INTERFACE:
!
  SUBROUTINE InstRemove ( Instance )
!
! !INPUT PARAMETERS:
!
    INTEGER                         :: Instance
!
! !REVISION HISTORY:
!  18 Feb 2016 - C. Keller   - Initial version
!  See https://github.com/geoschem/hemco for complete history
!EOP
!------------------------------------------------------------------------------
!BOC
    INTEGER                     :: RC
    TYPE(MyInst), POINTER       :: PrevInst => NULL()
    TYPE(MyInst), POINTER       :: Inst     => NULL()

    !=================================================================
    ! InstRemove begins here!
    !=================================================================

    ! Init
    PrevInst => NULL()
    Inst     => NULL()

    ! Get instance. Also archive previous instance.
    CALL InstGet ( Instance, Inst, RC, PrevInst=PrevInst )

    ! Instance-specific deallocation
    IF ( ASSOCIATED(Inst) ) THEN

       !---------------------------------------------------------------------
       ! Deallocate fields of Inst before popping off from the list
       ! in order to avoid memory leaks (Bob Yantosca (17 Aug 2022)
       !---------------------------------------------------------------------   
       IF ( ASSOCIATED( Inst%PROFILE ) ) THEN
          DEALLOCATE( Inst%PROFILE )
       ENDIF
       Inst%PROFILE => NULL()

       IF ( ASSOCIATED( Inst%SLBASE ) ) THEN
          DEALLOCATE( Inst%SLBASE )
       ENDIF
       Inst%SLBASE => NULL()

       IF ( ASSOCIATED( Inst%FLASH_DENS_TOT ) ) THEN
          DEALLOCATE( Inst%FLASH_DENS_TOT )
       ENDIF
       Inst%FLASH_DENS_TOT => NULL()

       !IF ( ASSOCIATED( Inst%FLASH_DENS_IC ) ) THEN
       !   DEALLOCATE( Inst%FLASH_DENS_IC )
       !ENDIF
       Inst%FLASH_DENS_IC => NULL()

       !IF ( ASSOCIATED( Inst%FLASH_DENS_CG ) ) THEN
       !   DEALLOCATE ( Inst%FLASH_DENS_CG )
       !ENDIF
       Inst%FLASH_DENS_CG => NULL()

       IF ( ASSOCIATED( Inst%CONV_DEPTH ) ) THEN
          DEALLOCATE( Inst%CONV_DEPTH )
       ENDIF
       Inst%CONV_DEPTH => NULL()

       IF ( ALLOCATED ( Inst%SpcScalVal ) ) THEN
          DEALLOCATE( Inst%SpcScalVal )
       ENDIF

       IF ( ALLOCATED( Inst%SpcScalFldNme ) ) THEN
          DEALLOCATE( Inst%SpcScalFldNme )
       ENDIF

       !---------------------------------------------------------------------
       ! Pop off instance from list
       !---------------------------------------------------------------------
       IF ( ASSOCIATED(PrevInst) ) THEN
          PrevInst%NextInst => Inst%NextInst
       ELSE
          AllInst => Inst%NextInst
       ENDIF
       DEALLOCATE(Inst)
    ENDIF

    ! Free pointers before exiting
    PrevInst => NULL()
    Inst     => NULL()

   END SUBROUTINE InstRemove
!EOC
END MODULE HCOX_LightNOx_Mod