Species indexing in GEOS-Chem

From Geos-chem
Jump to: navigation, search

On this page we provide information about advected tracers and chemical species are indexed in GEOS-Chem.

Overview

GEOS-Chem versions prior to v11-01 carried advected tracers and chemical species in separate arrays. This is due to the structure of the original models from which GEOS-Chem was constructed. In the sections below we shall describe how GEOS-Chem's current indexing scheme for advected tracers and chemical species, and our new scheme (which will be implemented in v11-01).

Advected tracers

Advected tracers in GEOS-Chem are those species which are subject to Transport, Cloud convection, Boundary layer mixing, and Wet deposition. (They may also dry deposit.) Historically, advected tracers have been read from restart files in volume mixing ratio, then were converted to kg and further converted to molec/cm3 before being passed into the chemistry modules. (In GEOS-Chem v11-01, advected tracers will be carried in mass mixing ratio to allow us to remove dependence on grid box areas from GEOS-Chem.)

Prior to GEOS-Chem v9-02, GEOS-Chem advected tracers were stored in the STT array. In v9-02, the STT array was replaced with the derived-type object field State_Chm%Tracers. For backwards compatibility we have defined several pointers named STT that refer to the State_Chm%Tracers array.

Advected tracers may also be chemical species (see next section).

--Bob Yantosca (talk) 15:16, 6 May 2016 (UTC)

Chemical species

Chemical species are those GEOS-Chem species that are listed as reactants or products (either of gas-phase or photolysis reactions) in one of GEOS-Chem's chemistry mechanisms. Chemical species, which traditionally have been read from a separate restart file, are stored in the SMVGEAR solver array CSPEC and have units of molec/cm3.

Many chemical species (such as NO, O3, CO, etc.) are also advected tracers; that is, they are moved around by the winds and convective mass fluxes. On the other hand, several species (notably OH) are not advected tracers. This is because the lifetime of these species are so small that they never get transported outside of the confines of the grid box where they are created.

Due to the legacy structure of GEOS-Chem, those chemical species that are also advected tracers actually get stored twice in GEOS-Chem. The advected tracer concentrations (as mentioned in the previous section) are stored in mixing ratio units in State_Chm%Tracers. These concentrations are then converted to molec/cm3 and are stored in the separate CSPEC array before the chemistry solver is called. This duplication of storage increases the memory requirements of GEOS-Chem, particularly when running at very fine resolution (i.e. 0.25°). The new FlexChem solver (added in v11-01g improves this situation by only keeping one array for species concentrations. It also introduces a new, faster way to find a species index number from its name. We shall discuss these developments in the following sections.

--Bob Yantosca (talk) 14:54, 27 June 2016 (UTC)

Prior to GEOS-Chem v11-01

Indexing for advected tracers

In GEOS-Chem versions prior to the v11-01 public release, indices of advected tracers were stored in integer variables (which all began with the letters IDT) in the module GeosCore/tracerid_mod.F. These IDT* variables were initialized in a big DO loop in routine TRACERID (see below), which was called as soon as the list of tracers was read from the input.geos file.

      !=================================================================
      ! Assign tracer, biomass, biofuel, and anthro emission ID's
      !=================================================================
      DO N = 1, Input_Opt%N_TRACERS

         ! Save TRACER_NAME into a CHARACTER*14 variable
         NAME = Input_Opt%TRACER_NAME(N)

         ! Convert name to uppercase
         CALL TRANUC( NAME )

         ! Find each tracer
         SELECT CASE ( TRIM( NAME ) )
        
            !------------------------
            ! Full chem tracers
            !------------------------
            CASE ( 'NO' )
               IDTNO    = N

            CASE ( 'NO2' )
               IDTNO2   = N

            CASE ( 'NO3' )
              IDTNO3   = N
 
            CASE ( 'HNO2' )
              IDTHNO2  = N

            CASE ( 'O3' )
               IDTO3    = N

            CASE ( 'PAN' )
               IDTPAN   = N
               
            CASE ( 'CO' )
               IDTCO    = N 

            ... etc ...

These variables denoted the position of each advected tracer in the State_Chm%TRACERS array (formerly known as STT). For example:

   USE TRACERID_MOD, ONLY : IDTNO, IDTPAN

   ! Print NO at grid box (23,34,1)
   print*, State_Chm%TRACERS(23,34,1,IDTNO)

   ! Print PAN at grid box (23,34,1)
   print*, State_Chm%TRACERS(23,34,1,IDTPAN)

Whenever new advected tracers were added to the full-chemistry simulations or to the specialty simulations, the corresponding IDT* variables had to be added to tracerid_mod.F.

--Bob Yantosca (talk) 20:19, 4 May 2016 (UTC)

Indexing for chemical species

The SMVGEAR routines used a separate set of integer variables to store indices of species in the chemical mechanism. These variables (which began with ID were defined in a separate DO loop in routine SETTRACE, also located in module GeosCore/tracerid_mod.F:

      DO I = 1, NSPEC(NCS)
         IF ( NAMEGAS(I) == 'O3'     ) IDO3     = I
         IF ( NAMEGAS(I) == 'NO2'    ) IDNO2    = I
         IF ( NAMEGAS(I) == 'NO3'    ) IDNO3    = I
         IF ( NAMEGAS(I) == 'N2O5'   ) IDN2O5   = I
         IF ( NAMEGAS(I) == 'HNO4'   ) IDHNO4   = I
         IF ( NAMEGAS(I) == 'HNO2'   ) IDHNO2   = I
         IF ( NAMEGAS(I) == 'NO'     ) IDNO     = I
         IF ( NAMEGAS(I) == 'CO'     ) IDCO     = I
         IF ( NAMEGAS(I) == 'PRPE'   ) IDPRPE   = I
         IF ( NAMEGAS(I) == 'C3H8'   ) IDC3H8   = I
         IF ( NAMEGAS(I) == 'ISOP'   ) IDISOP   = I
         IF ( NAMEGAS(I) == 'ALK4'   ) IDALK4   = I
         IF ( NAMEGAS(I) == 'PAN'    ) IDPAN    = I
         IF ( NAMEGAS(I) == 'GLPAN'  ) IDGLPAN  = I
         IF ( NAMEGAS(I) == 'GPAN'   ) IDGPAN   = I
         IF ( NAMEGAS(I) == 'PMN'    ) IDPMN    = I
         IF ( NAMEGAS(I) == 'PPN'    ) IDPPN    = I
         ... etc ...

These ID* varaibles denoted the position of each species in the SMVGEAR CSPEC array. For example:

   USE TRACERID_MOD, ONLY : IDO3
   
   ! Get O3 concentration in molec/cm3
   O3_MOLEC_CM3 = CSPEC(JLOOP,IDO3)

--Bob Yantosca (talk) 20:12, 4 May 2016 (UTC)

Indexing for tagged Hg tracers

The tagged Hg simulation used several variables in tracerid_mod.F:

      ! For tagged Hg simulation
      INTEGER              :: N_Hg_CATS
      INTEGER, ALLOCATABLE :: ID_Hg0(:),  ID_Hg2(:), ID_HgP(:)
      INTEGER              :: ID_Hg_tot,  ID_Hg_can,  ID_Hg_usa
      INTEGER              :: ID_Hg_cam,  ID_Hg_sam,  ID_Hg_waf
      INTEGER              :: ID_Hg_eaf,  ID_Hg_saf,  ID_Hg_naf
      INTEGER              :: ID_Hg_eur,  ID_Hg_eeu,  ID_Hg_sov
      INTEGER              :: ID_Hg_mde,  ID_Hg_sas,  ID_Hg_eas
      INTEGER              :: ID_Hg_sea,  ID_Hg_jpn,  ID_Hg_oce
      INTEGER              :: ID_Hg_so,   ID_Hg_bb,   ID_Hg_geo
      INTEGER              :: ID_Hg_atl,  ID_Hg_nat,  ID_Hg_sat
      INTEGER              :: ID_Hg_npa,  ID_Hg_arc,  ID_Hg_ant
      INTEGER              :: ID_Hg_ocn,  ID_Hg_str

These were defined in the big DO loop in routine TRACERID:

           !--------------------------------
           ! Total & tagged mercury tracers 
           ! (eck, cdh, bmy, 12/15/05)
           !--------------------------------
           CASE ( 'HG0' )
              COUNT_Hg0         = COUNT_Hg0 + 1              
              ID_Hg_tot         = COUNT_Hg0
              IDTHg0            = N
              ID_Hg0(COUNT_Hg0) = N

           CASE ( 'HG2' )
              COUNT_Hg2         = COUNT_Hg2 + 1
              ID_Hg2(COUNT_Hg2) = N

           CASE ( 'HGP' )
              COUNT_HgP         = COUNT_HgP + 1
              ID_HgP(COUNT_HgP) = N

           ! New Tagged Hg Simulation (eds 8/31/10)
           CASE ( 'HG0_AN_CAN', 'HG0_CAN' )
              COUNT_Hg0         = COUNT_Hg0 + 1
              ID_Hg_can          = COUNT_Hg0
              ID_Hg0(COUNT_Hg0) = N

           . . . many other Hg0 variables ...

           CASE ( 'HG2_AN_CAN', 'HG2_CAN' )
              COUNT_Hg2         = COUNT_Hg2 + 1
              ID_Hg2(COUNT_Hg2) = N

           . . . many other Hg2 variables ...          

           CASE ( 'HGP_AN_CAN', 'HGP_CAN' )
              COUNT_HgP         = COUNT_HgP + 1
              ID_HgP(COUNT_HgP) = N

           . . . many other HgP variables . . .          

In addition, tracerid_mod.F contained several lookup functions:

      FUNCTION IS_Hg0( N ) RESULT( IT_IS_Hg0 )  ! = .TRUE. if N is a Hg0 tracer
      FUNCTION IS_Hg2( N ) RESULT( IT_IS_Hg2 )  ! = .TRUE. if N is a Hg2 tracer 
      FUNCTION IS_HgP( N ) RESULT( IT_IS_HgP )  ! = .TRUE. if N is a HgP tracer

      FUNCTION GET_Hg0_CAT( N ) RESULT( NN )    ! Returns Hg category number from Hg0 tracer number
      FUNCTION GET_Hg2_CAT( N ) RESULT( NN )    ! Returns Hg category number from Hg0 tracer number
      FUNCTION GET_HgP_CAT( N ) RESULT( NN )    ! Returns Hg category number from Hg0 tracer number

These functions and variables were used in the mercury modules(mercury_mod.F, depo_mercury_mod.F, land_mercury_mod.F, and ocean_mercury_mod.F).

--Bob Yantosca (talk) 15:19, 6 May 2016 (UTC)

Problems

As described in the Overview section above, GEOS-Chem versions prior to v11-01 stored chemical species separately from advected tracers. While this arrangement has worked for many years, it is not optimal, as it requires duplicating the amount of storage necessary for advected tracers that are also defined as species included in the SMVGEAR chemical mechanism.

Furthermore, as the number of GEOS-Chem full-chemistry and specialty simulations increased, more tracer ID's (the IDT* variables) and species ID's (the ID* variables) had to be added to tracerid_mod.F. This is not only a very messy approach, but it also complicates the addition of new chemistry mechanisms.

Lastly, the implementation of the Hg tagged tracer indices was somewhat cumbersome and needed to be streamlined.

--Bob Yantosca (talk) 15:20, 6 May 2016 (UTC)

In GEOS-Chem v11-01 and higher versions

No more distinction between tracers and species

In GEOS-Chem v11-01, we are retiring the SMVGEAR chemistry solver and replacing it with FlexChem, a new, clean implementation of the KPP chemical solver. This is necessary in order to obtain the best performance when running GEOS-Chem in high-performance computing environments. FlexChem will also allow GEOS-Chem users to change chemistry mechanisms on-the-fly, without having to hardwire many variables in many different locations throughout GEOS-Chem.

The new GEOS-Chem species database—added in intermediate version v11-01e—now provides a central location for storing the physical properties of GEOS-Chem species, including names, indices, molecular weights, and Henry's law constants. It also stores logical flags that denote whether each species is advected, is dry deposited, or is wet scavenged.

As a result, the distinction between advected tracers and chemical species now becomes a little more blurred. We can now speak of everything as a GEOS-Chem "species". Some species are advected, some are dry-deposited, and some are wet-deposited, and some undergo photolysis.

In the FlexChem implementation, we will use a single array field to store GEOS-Chem species information. For example instead of having to keep store tracer concentrations in State_Chm%Tracers and species concentrations in State_Chm%Species, we can store all concentrations in State_Chm%Species. We can then retire State_Chm%Tracers, and just use locally-defined pointers to point to the advected species:

    ! Point to the number of advected species in the State_Chm%Species array     
    Spc => State_Chm%Species( :, :, :, 1:State_Chm%nAdvect )

This will greatly reduce the amount of memory required for GEOS-Chem simulations.

--Bob Yantosca (talk) 18:17, 31 October 2016 (UTC)

tracerid_mod.F has now been retired

Because the GEOS-Chem species database now lets us store all species information (including its indices) in a single location, the old species indexing routines in GeosCore/tracerid_mod.F have been rendered obsolete. We have therefore removed this module from GEOS-Chem v11-01g, concurrently with the FlexChem implementation.

--Bob Yantosca (talk) 18:48, 24 June 2016 (UTC)

Species indexing using a fast lookup algorithm

We have now given GEOS-Chem v11-01 an improved species lookup algorithm that relies on the concept of hashing. A hash is a unique integer variable—it can be positive or negative—that is created from a character string.

We have modified the Species derived type (defined in Headers/species_mod.F90) to store a hash value corresponding to the species name:

     !=========================================================================
     ! Type for individual species information
     ! (i.e. this is a single entry in the Species Database)
     !=========================================================================
     TYPE, PUBLIC :: Species
  
        . . . etc . . .

        ! Names
        CHARACTER(LEN=31)  :: Name             ! Short name
        CHARACTER(LEN=80)  :: FullName         ! Long name
        INTEGER            :: NameHash         ! Integer hash for short name

        . . . etc . . .

When we create each entry in the GEOS-Chem species database, we save the the species name (aka "Short name") along with its corresponding hash value. When we want to look up the index corresponding to a given species, we can now do an integer search on the hash value instead of a character search on the species name. In Fortran, integer searches are much faster than character searches, so this has the potential to speed up the species name indexing by 30 to 40 times.

Hash-based species index lookup with the IND_ function

Function Ind_() (located in Headers/gigc_state_chm_mod.F90) performs the fast hash-based species name-to-index search mentioned above. It returns the species index (i.e. the ModelId field from the Species Database object) given the species name. Here is an example of how it is used:

   SUBROUTINE MySub( ..., State_Chm, ... )

      !%%% MySub is an example of the new indexing scheme %%% 

      ! Uses
      USE State_Chm_Mod, ONLY : Ind_
             
      ! Local variables
      INTEGER  :: id_O3, id_Br2, id_CO
      
      ! Find tracer indices with function the Ind_() function
      id_O3  = Ind_( 'O3'  )
      id_Br2 = Ind_( 'Br2' )
      id_CO  = Ind_( 'CO'  )

      ! Print tracer concentrations
      print*, 'O3  at (23,34,1) : ', State_Chm%Species(23,34,1,id_O3 )
      print*, 'Br2 at (23,34,1) : ', State_Chm%Species(23,34,1,id_Br2)
      print*, 'CO  at (23,34,1) : ', State_Chm%Species(23,34,1,id_CO )

      ! Print the molecular weight of O3 (obtained from the Species Database object)
      print*, 'Mol wt of O3 [g]: ', State_Chm%SpcData(id_O3)%Info%MW_g
   
   END SUBROUTINE MySub

You can therefore use function Ind_() to return the ID for any species in the species database. (Note that the Ind_() function is particularly useful when you need to look up a species index outside of a DO loop over all species.) Once you have obtained the species ID, you can use that to access the individual fields in the Species Database object. In the example above, we use the species ID for O3 (stored in id_O3) to look up the molecular weight of O3 from the Species Database.

The Ind_() function has now allowed us to finally retire obsolete module GeosCore/tracerid_mod.F from GEOS-Chem v11-01 and higher versions.

Obtaining other indices with IND_

The Ind_() function by default will return the species index (i.e. the ModelId value in the Species Database. You may also tell Ind_ to return other indices by passing an optional second argument. For example:

AdvectId = Ind( 'HNO3', 'A' ) ! Position of HNO3 in the list of advected species

DryDepId = Ind( 'HNO3', 'D' ) ! Position of HNO3 in the list of dry deposited species (used by drydep_mod.F)

WetDepId = Ind( 'HNO3', 'W' ) ! Position of HNO3 in the list of wet deposited species (used by wetscav_mod.F)

KppFixId = Ind( 'HNO3', 'F' ) ! Position of HNO3 in the list of fixed (aka "inactive") chemical species (used by KPP)

KppVarId = Ind( 'HNO3', 'V' ) ! Position of HNO3 in the list of variable (aka "active") chemical species (used by KPP)

The Ind_() function will return -1 if a species does not belong to any of the above lists.

--Bob Yantosca (talk) 18:24, 24 June 2016 (UTC)

Defining species indices at GEOS-Chem initialization

For maximum efficiency, we recommend that you use the Ind_() function to obtain the species indices only at the start of a GEOS-Chem simulation. This will minimize the amount of times the name-to-index lookup has to be done. You can call Ind_() from the initialization routine of each module, and store the results in global module variables so that they will be preserved for the duration of the simulation.

Here is an example using the POPs simulation module (GeosCore/pops_mod.F). We have deleted some code and comments for clarity.

      MODULE POPS_MOD
 
 ... omitting code for clarity ...
!
! !PRIVATE TYPES:
!
      ! Species ID flags
      INTEGER,  PRIVATE     :: id_POPG
      INTEGER,  PRIVATE     :: id_POPPBCPI
      INTEGER,  PRIVATE     :: id_POPPBCPO 
      INTEGER,  PRIVATE     :: id_POPPOCPI
      INTEGER,  PRIVATE     :: id_POPPOCPO

      ! Species drydep ID flags
      INTEGER,  PRIVATE     :: dd_POPG
      INTEGER,  PRIVATE     :: dd_POPP_BCPI
      INTEGER,  PRIVATE     :: dd_POPP_BCPO
      INTEGER,  PRIVATE     :: dd_POPP_OCPI
      INTEGER,  PRIVATE     :: dd_POPP_OCPO

      CONTAINS 
  
 ... omitting code for clarity ...

      SUBROUTINE INIT_POPS( am_I_Root, Input_Opt, State_Chm, RC )
!
! !USES:
!
 ... omitting code for clarity ...

     USE GIGC_State_Chm_Mod, ONLY : Ind_

... omitting code for clarity ...  

     !=================================================================
     ! Initialize species ID and drydep ID flags
     !=================================================================
     id_POPG      = Ind_('POPG'        )
     dd_POPG      = Ind_('POPG',    'D')

     id_POPPOCPO  = Ind_('POPPOCPO'    )
     dd_POPP_OCPO = Ind_('POPPOCPO','D')

     id_POPPBCPO  = Ind_('POPPBCPO'    )
     dd_POPP_BCPO = Ind_('POPPBCPO','D')

     id_POPPOCPI  = Ind_('POPPOCPI'    )
     dd_POPP_OCPI = Ind_('POPPOCPI','D')

     id_POPPBCPI  = Ind_('POPPBCPI'    )
     dd_POPP_BCPI = Ind_('POPPBCPI','D')

     END SUBROUTINE INIT_POPS

Alternate method: Species information lookup within a loop

Many GEOS-Chem routines loop over tracers (aka advected species). Typically, the advected species DO loop is the outermost DO loop. In such cases, you can easily obtain information about species by querying the Species Database object directly, without having to call the Ind_() function.)

Here is a typical example. The ThisSpc variable, which is an object of type Species, points to the Species Database entry for species number N.

   SUBROUTINE MySub( ..., State_Chm, ... )

      !%%% MySub is an example of the new indexing scheme %%% 
 
      ! Uses
      USE Precision_Mod,      ONLY : fp, f8
      USE GIGC_State_Chm_Mod, ONLY : ChmState
      USE Species_Mod,        ONLY : Species
           
      ! Chemistry state object (which also holds the species database)
      TYPE(ChmState), INTENT(INOUT) :: State_Chm

      ! Local variables
      INTEGER                       :: N       
      TYPE(Species),  POINTER       :: ThisSpc
      INTEGER                       :: ModelId,  DryDepId, WetDepId
      REAL(fp)                      :: Mw_g,     EmMw_g
      REAL(f8)                      :: Henry_K0, Henry_CR, Henry_pKa

      ! Loop over species
      DO N = 1, State_Chm%nSpecies

         ! Get the entry for a single species from the species database object
         ThisSpc   => State_Chm%SpcData(N)%Info

         ! Get indices for the Nth species from its entry in the Species Database object
         ModelId   =  ThisSpc%ModelId    ! Species ID (aka  the "model ID")
         AdvectId  =  ThisSpc%AdvectId   ! Advected species ID
         DryDepId  =  ThisSpc%DryDepId   ! Drydep species ID (i.e. internal index for drydep_mod.F)
         WetDepId  =  ThisSpc%WetDepId   ! Wetdep species ID (i.e. internal index for wetscav_mod.F)
         KppVarId  =  ThisSpc%KppVarId   ! KPP variable species ID (used by the FlexChem/KPP solver)
         KppFixId  =  ThisSpc%KppFixId   ! KPP fixed species ID (used by the FlexChem/KPP solver)

         ! Get information about the Nth species from its entry in the Species Database object
         Mw_g      =  ThisSpc%MW_g       ! Molecular weight           [g    ]   
         EmMw_g    =  ThisSpc%EmMw_g     ! Emitted molecular weight   [g    ]
         Henry_K0  =  ThisSpc%Henry_K0   ! Henry solubility constant  [M/atm]
         Henry_CR  =  ThisSpc%Henry_CR   ! Henry volatility constant  [K    ]
         Henry_pKa =  ThisSpc%Henry_pKa  ! Henry pH correction factor [1    ]
   
         IF ( ThisSpc%Is_Gas ) 
            ! ... The species is a gas-phase species
            ! ... so do something appropriate
         ELSE 
            ! ... The species is an aerosol
            ! ... so do something else appropriate
         ENDIF

         IF ( ThisSpc%Is_Advected ) THEN
            ! ... The species is advected 
            ! ... (i.e. undergoes transport, PBL mixing, cloud convection)
         ENDIF 

         IF ( ThisSpc%Is_DryDep ) THEN
            ! ... The species is dry deposited
         ENDIF 

         IF ( ThisSpc%Is_WetDep ) THEN
            ! ... The species is soluble and wet deposits
            ! ... it is also scavenged in convective updrafts
         ENDIF 

         ... etc ...
 
         ! Free the pointer
         ThisSpc =>  NULL()

      ENDDO

   END SUBROUTINE MySub

--Bob Yantosca (talk) 18:09, 24 June 2016 (UTC)

The State_Chm object now contains mapping arrays for subsetting species

In GEOS-Chem v11-01 and higher versions, we have added mapping arrays to the State_Chm object. These arrays, highlighted in GREEN below, contain the species ID's (aka ModelId's) corresponding to the subset of advected, dry-deposited, wet-deposited, and KPP chemical species.

  !=========================================================================
  ! Derived type for Chemistry State
  !=========================================================================
  TYPE, PUBLIC :: ChmState

     ! Count of each type of species
     INTEGER                    :: nSpecies             ! # of species
     INTEGER                    :: nAdvect              ! # of advected species
     INTEGER                    :: nDryDep              ! # of drydep species
     INTEGER                    :: nKppSpc              ! # of KPP chem species
     INTEGER                    :: nWetDep              ! # of wetdep species

     ! Mapping vectors to subset types of species
     INTEGER,           POINTER :: Map_Advect (:      ) ! Advected species ID's
     INTEGER,           POINTER :: Map_DryDep (:      ) ! Drydep species ID's
     INTEGER,           POINTER :: Map_KppSpc (:      ) ! KPP chem species ID's
     INTEGER,           POINTER :: Map_WetDep (:      ) ! Wetdep species IDs'

     ... etc ...

These mapping arrays can be used as follows:

Example 1: Pointing to the advected species

     ! Scalars
     INTEGER           :: N, NA
 
     ! Pointer arrays
     REAL(fp), POINTER :: An_Advected_Species(:,:,:)

     !---------------------------------------------------
     ! Point to each of the advected species
     !---------------------------------------------------

     ! Loop over only the number of advected species
     DO NA = 1, State_Chm%nAdvect

        ! Get the species ID from the advected species ID
        N = State_Chm%Map_Advect(NA)

        ! Set a pointer to this advected species
        An_Advected_Species => State_Chm%Species(:,:,:,N)

        ... etc ...

        ! Free the pointer
        An_Advected_Species => NULL()
 
     ENDDO

--Bob Yantosca (talk) 18:57, 2 August 2016 (UTC)

Example 2: Pointing to the dry-deposited species

     ! Scalars
     INTEGER           :: N, ND

     ! Pointer arrays
     REAL(fp), POINTER :: A_DryDep_Species(:,:,:)

     !---------------------------------------------------
     ! Point to each of the dry-deposited species
     !---------------------------------------------------

     ! Loop over only the number of drydep species
     DO ND = 1, State_Chm%nDryDep

        ! Get the species ID from the drydep species ID
        N = State_Chm%Map_DryDep(ND)

        ! Set a pointer to this drydep species
        A_DryDep_Species => State_Chm%Species(:,:,:,N)

        ... etc ...

        ! Free the pointer
        A_DryDep_Species => NULL()
 
     ENDDO

--Bob Yantosca (talk) 18:57, 2 August 2016 (UTC)

Example 3: Pointing to the wet-deposited species

     ! Scalars
     INTEGER           :: N, NW

     ! Pointer arrays
     REAL(fp), POINTER :: A_WetDep_Species(:,:,:)

     !---------------------------------------------------
     ! Point to each of the wet-deposited species
     !---------------------------------------------------

     ! Loop over only the number of wetdep species
     DO NW = 1, State_Chm%nWetDep

        ! Get the species ID from the wetdep species ID
        N = State_Chm%Map_WetDep(NW)

        ! Set a pointer to this wetdep species
        A_WetDep_Species => State_Chm%Species(:,:,:,N)

        ... etc ...

        ! Free the pointer
        A_WetDep_Species => NULL()
 
     ENDDO

--Bob Yantosca (talk) 18:57, 2 August 2016 (UTC)

Example 4: Pointing to the species in the KPP chemical mechanism

     ! Scalars
     INTEGER           :: N, NK

     ! Pointer arrays
     REAL(fp), POINTER :: A_KPP_Species(:,:,:)

     !---------------------------------------------------
     ! Point to each of the KPP chemical species
     !---------------------------------------------------

     ! Loop over only the number of KPP species
     DO NK = 1, State_Chm%nKppSpc

        ! Get the species ID from the KPP species ID
        N = State_Chm%Map_KppSpc(NK)

        ! Set a pointer to this KPP chemical species
        A_KPP_Species => State_Chm%Species(:,:,:,N)

        ... etc ...

        ! Free the pointer
        A_KPP_Species => NULL()
 
     ENDDO 

--Bob Yantosca (talk) 18:57, 2 August 2016 (UTC)

Tagged Hg index variables are now moved to State_Chm

In order to preserve the functionality of the Tagged Hg simulation, we have created—in GEOS-Chem v11-01 and higher versions—the equivalent functionality for all of the index variables that used to be located in GeosCore/tracerid_mod.F

     TYPE, PUBLIC :: ChmState

        ... all other stuff as before...

        ! For the tagged Hg simulation
        INTEGER                    :: N_HG_CATS            ! # of categories
        INTEGER,           POINTER :: Hg0_Id_List(:      ) ! Hg0 cat <-> tracer #
        INTEGER,           POINTER :: Hg2_Id_List(:      ) ! Hg0 cat <-> tracer #
        INTEGER,           POINTER :: HgP_Id_List(:      ) ! Hg0 cat <-> tracer #
        CHARACTER(LEN=4),  POINTER :: Hg_Cat_Name(:      ) ! Category names         

     END TYPE ChmState

You can refer to these where needed in existing code by pointer references:

     SUBROUTINE MySub1( ..., State_Chm, ... )

        ! Uses
        USE GIGC_State_Chm_Mod, ONLY: ChmState
        . . .

        ! Input arguments 
        TYPE(ChmState), POINTER :: State_Chm       

        ! Local definitions for Hg indexing variables
        INTEGER                    :: N_HG_CATS            ! # of categories
        INTEGER,           POINTER :: Hg0_Id_List(:      ) ! Hg0 cat <-> tracer #
        INTEGER,           POINTER :: Hg2_Id_List(:      ) ! Hg0 cat <-> tracer #
        INTEGER,           POINTER :: HgP_Id_List(:      ) ! Hg0 cat <-> tracer #
        CHARACTER(LEN=4),  POINTER :: Hg_Cat_Name(:      ) ! Category names

        !=================================================================
        ! Now handle Hg indexing locally (bmy, 4/26/16)
        ! These were all in tracerid_mod.F, which is being removed
        !=================================================================

        ! Store the # of tagged Hg categories in a module variable
        N_Hg_CATS   = State_Chm%N_Hg_CATS
     
        ! Hg species index corresponding to a given Hg category number
        Hg0_Id_List => State_Chm%Hg0_Id_List
        Hg2_Id_List => State_Chm%Hg2_Id_List
        HgP_Id_List => State_Chm%HgP_Id_List
        Hg_Cat_Name => State_Chm%Hg_Cat_Name

        ... etc ...

In addition, we have added a few other index fields for Hg species into the Species derived type, which is defined in Headers/species_mod.F90, as follows:

     TYPE, PUBLIC :: Species
 
        ... all other stuff as before...

        ! Tagged mercury parameters
        LOGICAL            :: Is_Hg0           ! TRUE if this is a total or tagged Hg0 species
        LOGICAL            :: Is_Hg2           ! TRUE if this is total or tagged Hg2 species
        LOGICAL            :: Is_HgP           ! TRUE if this is  tagged HgP species
        INTEGER            :: Hg_Cat           ! Tagged Hg category number (1..State_Chm%N_Hg_CATS
 
       ... etc ...

The Species type, as you recall, is used to store a single entry in the GEOS-Chem species database. Or in other words, the GEOS-Chem species database object—also known as State_Chm%SpcData—is a vector, where each element is of type Species.

                  USE Species_Mod, ONLY : Species
                  . . .
 
                  TYPE(Species), POINTER :: ThisSpc

                  ! Point to the entry for tracer # IC in the GEOS-Chem Species Database 
                  ThisSpc => State_Chm%SpcData(IC)%Info
                  . . .

                  IF ( ITS_A_MERCURY_SIM ) THEN
 
                     ! Is it a Hg2 tracer?
                     IF ( ThisSpc%Is_Hg2 ) THEN

                        ! Wet scavenged Hg(II) in [kg/s], converted
                        ! to [kg] by multiplying by NDT
                        WET_Hg2 = T0 * AREA_M2 / DNS * NDT
                       
                        ! Category # for this Hg2 tracer
                        Hg_Cat  = ThisSpc%Hg_Cat

                        ! Pass to "ocean_mercury_mod.f"
                        CALL ADD_Hg2_WD      ( I, J, Hg_Cat, WET_Hg2   )
                        CALL ADD_Hg2_SNOWPACK( I, J, Hg_Cat, WET_Hg2,
    &                                                       State_Met )
                     ENDIF
                  ENDIF
                  . . .

                  ThisSpc => NULL()

--Bob Yantosca (talk) 18:31, 24 June 2016 (UTC)

Timeline for implementation of the fast species indexing algorithm

We shall introduce the fast species indexing algorithm into GEOS-Chem v11-01 concurrently with the FlexChem implementation. The table below shows the various phases of the project.

Phase Version Description Status
Phase 1 v11-01g Removal of index variables from tracerid_mod.F for the following simulations:
  • Completed 02 May 2015
Phase 2 v11-01g Relying on the GEOS-Chem species database for species indexing
  • Completed 24 Jun 2016
Phase 3 v11-01g Storing advected tracers and chemical species in the same array (to reduce memory requirements)
  • Completed 29 Aug 2016

--Bob Yantosca (talk) 18:34, 24 June 2016 (UTC)