Difference between revisions of "Species indexing in GEOS-Chem"

From Geos-chem
Jump to: navigation, search
Line 10: Line 10:
  
  
== Overview ==
+
This content has been migrated to the [https://geos-chem.readthedocs.io/en/latest/geos-chem-shared-docs/supplemental-guides/species-guide.html '''View GEOS-Chem Species Properties''' Supplemental Guide of <tt>geos-chem.readthedocs.io</tt>]
 
+
On this page we provide information about how species are indexed in GEOS-Chem.
+
 
+
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 [[GEOS-Chem v11-01|v11-01]]).
+
 
+
=== Advected tracers ===
+
 
+
'''Advected tracers''' in GEOS-Chem are those species which are subject to [[Advection scheme TPCORE|Transport]], [[Cloud convection]], [[Boundary layer mixing]], and [[Wet deposition]].  (They may also [[Dry deposition|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 <code>STT</code> array.  In v9-02, the <code>STT</code> array was replaced with the derived-type object field <code>State_Chm%Tracers</code>.  For backwards compatibility we have defined several pointers named <code>STT</code> that refer to the <code>State_Chm%Tracers</code> array.
+
 
+
Advected tracers may also be [[#Chemical species|chemical species]] (see next section).
+
 
+
--[[User:Bmy|Bob Yantosca]] ([[User talk:Bmy|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 [[FAST-JX_v7.0_photolysis_mechanism|photolysis]] reactions) in one of [[GEOS-Chem_chemistry_mechanisms|GEOS-Chem's chemistry mechanisms]].  Chemical species, which traditionally have been read from a separate restart file, are stored in the SMVGEAR solver array <code>CSPEC</code> and have units of molec/cm3.
+
 
+
Many chemical species (such as NO, O3, CO, etc.) are also [[#Advected tracers|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 <code>State_Chm%Tracers</code>. These concentrations are then converted to molec/cm3 and are stored in the separate <code>CSPEC</code> 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&deg;).  The new FlexChem solver (added in [[GEOS-Chem v11-01#v11-01g|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.
+
 
+
--[[User:Bmy|Bob Yantosca]] ([[User talk:Bmy|talk]]) 14:54, 27 June 2016 (UTC)
+
 
+
== Prior to GEOS-Chem v11-01 ==
+
 
+
=== Indexing for advected tracers ===
+
 
+
In GEOS-Chem versions prior to the [[GEOS-Chem v11-01|v11-01]] public release, indices of advected tracers were stored in integer variables (which all began with the letters <code>IDT</code>) in the module <tt>GeosCore/tracerid_mod.F</tt>.  These <code>IDT*</code> variables were initialized in a big DO loop in routine <code>TRACERID</code> (see below), which was called as soon as the list of tracers was read from the <tt>input.geos</tt> 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 <code>State_Chm%TRACERS</code> array (formerly known as <code>STT</code>).  For example:
+
 
+
    USE TRACERID_MOD, ONLY : <span style="color:red">IDTNO</span>, <span style="color:blue">IDTPAN</span>
+
+
    ! Print NO at grid box (23,34,1)
+
    print*, State_Chm%TRACERS(23,34,1,<span style="color:red">IDTNO</span>)
+
+
    ! Print PAN at grid box (23,34,1)
+
    print*, State_Chm%TRACERS(23,34,1,<span style="color:blue">IDTPAN</span>)
+
 
+
Whenever new advected tracers were added to the [[GEOS-Chem_chemistry_mechanisms#NOx-Ox-hydrocarbon-aerosol_chemistry_and_variants|full-chemistry simulations]] or to the [[GEOS-Chem_chemistry_mechanisms#Specialty_simulations|specialty simulations]], the corresponding <code>IDT*</code> variables had to be added to <tt>tracerid_mod.F</tt>.
+
 
+
--[[User:Bmy|Bob Yantosca]] ([[User talk:Bmy|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 <code>ID</code> were defined in a separate DO loop in routine <code>SETTRACE</code>, also located in module <tt>GeosCore/tracerid_mod.F</tt>:
+
 
+
      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 <code>ID*</code> varaibles denoted the position of each species in the SMVGEAR <code>CSPEC</code> array.  For example:
+
 
+
    USE TRACERID_MOD, ONLY : <span style="color:darkorange">IDO3</span>
+
   
+
    ! Get O3 concentration in molec/cm3
+
    O3_MOLEC_CM3 = CSPEC(JLOOP,<span style="color:darkorange">IDO3</span>)
+
 
+
--[[User:Bmy|Bob Yantosca]] ([[User talk:Bmy|talk]]) 20:12, 4 May 2016 (UTC)
+
 
+
=== Indexing for tagged Hg tracers ===
+
 
+
The tagged Hg simulation used several variables in <tt>tracerid_mod.F</tt>:
+
 
+
      ! 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 <code>TRACERID</code>:
+
 
+
            !--------------------------------
+
            ! 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, <tt>tracerid_mod.F</tt> 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(<tt>mercury_mod.F</tt>, <tt>depo_mercury_mod.F</tt>, <tt>land_mercury_mod.F</tt>, and <tt>ocean_mercury_mod.F</tt>).
+
 
+
--[[User:Bmy|Bob Yantosca]] ([[User talk:Bmy|talk]]) 15:19, 6 May 2016 (UTC)
+
 
+
=== Problems ===
+
 
+
As described in the [[#Overview|Overview section above]], GEOS-Chem versions prior to [[GEOS-Chem v11-01#v11-01|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 <code>IDT*</code> variables) and species ID's (the <code>ID*</code> variables) had to be added to <tt>tracerid_mod.F</tt>.  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.
+
 
+
--[[User:Bmy|Bob Yantosca]] ([[User talk:Bmy|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]]&mdash;added in intermediate version [[GEOS-Chem v11-01#v11-01e|v11-01e]]&mdash;now provides a central location for storing the [[Physical properties of GEOS-Chem species|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 [[Advection scheme TPCORE|advected]], some are [[Dry deposition|dry-deposited]], and some are [[Wet deposition|wet-deposited]], and some undergo [[FAST-JX_v7.0_photolysis_mechanism|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 <code>State_Chm%Tracers</code> and species concentrations in <code>State_Chm%Species</code>, we can store all concentrations in <code>State_Chm%Species</code>.  We can then retire <code>State_Chm%Tracers</code>, and just use locally-defined pointers to point to the advected species:
+
 
+
    ! Point to the <span style="color:red">number of advected species in the State_Chm%Species array</span>   
+
    Spc => State_Chm%Species( :, :, :, <span style="color:red">1:State_Chm%nAdvect</span> )
+
 
+
This will greatly reduce the amount of memory required for GEOS-Chem simulations.
+
 
+
--[[User:Bmy|Bob Yantosca]] ([[User talk:Bmy|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 <tt>GeosCore/tracerid_mod.F</tt> have been rendered obsolete.  We have therefore removed this module from [[GEOS-Chem v11-01#v11-01g|GEOS-Chem v11-01g]], concurrently with the FlexChem implementation.
+
 
+
--[[User:Bmy|Bob Yantosca]] ([[User talk:Bmy|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&mdash;it can be positive or negative&mdash;that is created from a character string. 
+
 
+
We have modified the <code>Species</code> derived type (defined in <code>Headers/species_mod.F90</code>) 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
+
        <span style="color:red">INTEGER            :: NameHash        ! Integer hash for short name</span>
+
+
        . . . 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 <code>Ind_()</code> (located in <tt>Headers/gigc_state_chm_mod.F90</tt>) performs the [[#Species indexing using a fast lookup algorithm|fast hash-based species name-to-index search mentioned above]]. It returns the species index (i.e. the <code>ModelId</code> field from the [[GEOS-Chem species database|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
+
      <span style="color:purple">USE State_Chm_Mod, ONLY : Ind_</span>
+
             
+
      ! Local variables
+
      INTEGER  :: id_O3, id_Br2, id_CO
+
     
+
      ! Find tracer indices with function the Ind_() function
+
      <span style="color:blue">id_O3</span>  = <span style="color:purple">Ind_</span>( 'O3'  )
+
      <span style="color:green">id_Br2</span> = <span style="color:purple">Ind_</span>( 'Br2' )
+
      <span style="color:brown">id_CO</span>  = <span style="color:purple">Ind_</span>( 'CO'  )
+
+
      ! Print tracer concentrations
+
      print*, 'O3  at (23,34,1) : ', State_Chm%Species(23,34,1,<span style="color:blue">id_O3</span> )
+
      print*, 'Br2 at (23,34,1) : ', State_Chm%Species(23,34,1,<span style="color:green">id_Br2</span>)
+
      print*, 'CO  at (23,34,1) : ', State_Chm%Species(23,34,1,<span style="color:brown">id_CO</span> )
+
+
      ! Print the <span style="color:olive">molecular weight of O3</span> (obtained from the <span style="color:red">Species Database object</span>)
+
      print*, 'Mol wt of O3 [g]: ', State_Chm%<span style="color:red">SpcData</span>(<span style="color:blue">id_O3</span>)%<span style="color:red">Info</span>%<span style="color:olive">MW_g</span>
+
   
+
    END SUBROUTINE MySub
+
 
+
You can therefore use function <code>Ind_()</code> to return the ID for any species in the species database.  (Note that the <code>Ind_()</code> 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 <code>id_O3</code>) to look up the molecular weight of O3 from the Species Database. 
+
 
+
The <code>Ind_()</code> function has now allowed us to finally retire obsolete module <tt>GeosCore/tracerid_mod.F</tt> from [[GEOS-Chem v11-01]] and higher versions. 
+
 
+
==== Obtaining other indices with IND_ ====
+
 
+
The <code>Ind_()</code> function by default will return the species index (i.e. the <code>ModelId</code> value in the [[GEOS-Chem species database|Species Database]].  You may also tell <code>Ind_</code> 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 <code>Ind_()</code> function will return -1 if a species does not belong to any of the above lists.
+
 
+
--[[User:Bmy|Bob Yantosca]] ([[User talk:Bmy|talk]]) 18:24, 24 June 2016 (UTC)
+
 
+
==== Defining species indices at GEOS-Chem initialization ====
+
 
+
For maximum efficiency, we recommend that you use the <code>Ind_()</code> 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 <code>Ind_()</code> 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|POPs simulation module]] (<code>GeosCore/pops_mod.F</code>).  We have deleted some code and comments for clarity.
+
 
+
      MODULE POPS_MOD
+
 
+
  ... omitting code for clarity ...
+
!
+
! !PRIVATE TYPES:
+
!
+
      <span style="color:red">! Species ID flags
+
      INTEGER,  PRIVATE    :: id_POPG
+
      INTEGER,  PRIVATE    :: id_POPPBCPI
+
      INTEGER,  PRIVATE    :: id_POPPBCPO
+
      INTEGER,  PRIVATE    :: id_POPPOCPI
+
      INTEGER,  PRIVATE    :: id_POPPOCPO</span>
+
+
      <span style="color:blue">! 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</span>
+
+
      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 <span style="color:red">species ID</span> and <span style="color:blue">drydep ID</span> flags
+
      !=================================================================
+
      <span style="color:red">id_POPG      = Ind_('POPG'        )</span>
+
      <span style="color:blue">dd_POPG      = Ind_('POPG',    'D')</span>
+
+
      <span style="color:red">id_POPPOCPO  = Ind_('POPPOCPO'    )</span>
+
      <span style="color:blue">dd_POPP_OCPO = Ind_('POPPOCPO','D')</span>
+
+
      <span style="color:red">id_POPPBCPO  = Ind_('POPPBCPO'    )</span>
+
      <span style="color:blue">dd_POPP_BCPO = Ind_('POPPBCPO','D')</span>
+
+
      <span style="color:red">id_POPPOCPI  = Ind_('POPPOCPI'    )</span>
+
      <span style="color:blue">dd_POPP_OCPI = Ind_('POPPOCPI','D')</span>
+
+
      <span style="color:red">id_POPPBCPI  = Ind_('POPPBCPI'    )</span>
+
      <span style="color:blue">dd_POPP_BCPI = Ind_('POPPBCPI','D')</span>
+
+
      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 [[GEOS-Chem species database|Species Database]] object directly, without having to call the <code>Ind_()</code> function.)
+
 
+
Here is a typical example.  The <code>ThisSpc</code> variable, which is an object of type <code>Species</code>, 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
+
           
+
      <span style="color:brown">! Chemistry state object (which also holds the species database)
+
      TYPE(ChmState), INTENT(INOUT) :: State_Chm</span>
+
+
      ! Local variables
+
      INTEGER                      :: N     
+
      <span style="color:blue">TYPE(Species),  POINTER      :: ThisSpc</span>
+
      INTEGER                      :: ModelId,  DryDepId, WetDepId
+
      REAL(fp)                      :: Mw_g,    EmMw_g
+
      REAL(f8)                      :: Henry_K0, Henry_CR, Henry_pKa
+
+
      ! Loop over species
+
      DO N = 1, <span style="color:brown">State_Chm</span>%nSpecies
+
+
          ! Get <span style="color:blue">the entry for a single species</span> from the <span style="color:red">species database object</span>
+
          <span style="color:blue">ThisSpc</span>  => <span style="color:brown">State_Chm</span>%<span style="color:red">SpcData(N)%Info</span>
+
+
          ! Get <span style="color:blue">indices for the Nth species</span> from its entry in the Species Database object
+
          ModelId  =  <span style="color:blue">ThisSpc%ModelId</span>    ! Species ID (aka  the "model ID")
+
          AdvectId  =  <span style="color:blue">ThisSpc%AdvectId</span>  ! Advected species ID
+
          DryDepId  =  <span style="color:blue">ThisSpc%DryDepId</span>  ! Drydep species ID (i.e. internal index for drydep_mod.F)
+
          WetDepId  =  <span style="color:blue">ThisSpc%WetDepId</span>  ! Wetdep species ID (i.e. internal index for wetscav_mod.F)
+
          KppVarId  =  <span style="color:blue">ThisSpc%KppVarId</span>  ! KPP variable species ID (used by the FlexChem/KPP solver)
+
          KppFixId  =  <span style="color:blue">ThisSpc%KppFixId</span>  ! KPP fixed species ID (used by the FlexChem/KPP solver)
+
+
          ! Get <span style="color:blue">information about the Nth species</span> from its entry in the Species Database object
+
          Mw_g      =  <span style="color:blue">ThisSpc%MW_g</span>      ! Molecular weight          [g    ] 
+
          EmMw_g    =  <span style="color:blue">ThisSpc%EmMw_g</span>    ! Emitted molecular weight  [g    ]
+
          Henry_K0  =  <span style="color:blue">ThisSpc%Henry_K0</span>  ! Henry solubility constant  [M/atm]
+
          Henry_CR  =  <span style="color:blue">ThisSpc%Henry_CR</span>  ! Henry volatility constant  [K    ]
+
          Henry_pKa =  <span style="color:blue">ThisSpc%Henry_pKa</span>  ! Henry pH correction factor [1    ]
+
   
+
          IF ( <span style="color:blue">ThisSpc%Is_Gas</span> )
+
            ! ... The species is a gas-phase species
+
            ! ... so do something appropriate
+
          ELSE
+
            ! ... The species is an aerosol
+
            ! ... so do something else appropriate
+
          ENDIF
+
+
          IF ( <span style="color:blue">ThisSpc%Is_Advected</span> ) THEN
+
            ! ... The species is advected
+
            ! ... (i.e. undergoes transport, PBL mixing, cloud convection)
+
          ENDIF
+
+
          IF ( <span style="color:blue">ThisSpc%Is_DryDep</span> ) THEN
+
            ! ... The species is dry deposited
+
          ENDIF
+
+
          IF ( <span style="color:blue">ThisSpc%Is_WetDep</span> ) THEN
+
            ! ... The species is soluble and wet deposits
+
            ! ... it is also scavenged in convective updrafts
+
          ENDIF
+
+
          ... etc ...
+
 
+
          ! Free the pointer
+
          <span style="color:blue">ThisSpc</span> =>  NULL()
+
+
      ENDDO
+
+
    END SUBROUTINE MySub
+
 
+
--[[User:Bmy|Bob Yantosca]] ([[User talk:Bmy|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 <code>State_Chm</code> object.  These arrays, highlighted in <span style="color:green">GREEN</span> 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
+
      <span style="color:red">INTEGER                    :: nAdvect              ! # of advected species</span>
+
      <span style="color:blue">INTEGER                    :: nDryDep              ! # of drydep species</span>
+
      <span style="color:green">INTEGER                    :: nKppSpc              ! # of KPP chem species</span>
+
      <span style="color:darkorange">INTEGER                    :: nWetDep              ! # of wetdep species</span>
+
+
      ! Mapping vectors to subset types of species
+
      <span style="color:red">INTEGER,          POINTER :: Map_Advect (:      ) ! Advected species ID's</span>
+
      <span style="color:blue">INTEGER,          POINTER :: Map_DryDep (:      ) ! Drydep species ID's</span>
+
      <span style="color:green">INTEGER,          POINTER :: Map_KppSpc (:      ) ! KPP chem species ID's</span>
+
      <span style="color:darkorange">INTEGER,          POINTER :: Map_WetDep (:      ) ! Wetdep species IDs'</span>
+
+
      ... 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 <span style="color:red">advected species</span>
+
      !---------------------------------------------------
+
+
      ! Loop over only the number of advected species
+
      DO NA = 1, <span style="color:darkorange">State_Chm%nAdvect</span>
+
+
        ! Get the species ID from the advected species ID
+
        N = <span style="color:red">State_Chm%Map_Advect(NA)</span>
+
+
        ! Set a pointer to this advected species
+
        An_Advected_Species => State_Chm%Species(:,:,:,N)
+
+
        ... etc ...
+
+
        ! Free the pointer
+
        An_Advected_Species => NULL()
+
 
+
      ENDDO
+
+
--[[User:Bmy|Bob Yantosca]] ([[User talk:Bmy|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 <span style="color:blue">dry-deposited species</span>
+
      !---------------------------------------------------
+
+
      ! Loop over only the number of drydep species
+
      DO ND = 1, <span style="color:blue">State_Chm%nDryDep</span>
+
+
        ! Get the species ID from the drydep species ID
+
        N = <span style="color:blue">State_Chm%Map_DryDep(ND)</span>
+
+
        ! Set a pointer to this drydep species
+
        A_DryDep_Species => State_Chm%Species(:,:,:,N)
+
+
        ... etc ...
+
+
        ! Free the pointer
+
        A_DryDep_Species => NULL()
+
 
+
      ENDDO
+
 
+
--[[User:Bmy|Bob Yantosca]] ([[User talk:Bmy|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 <span style="color:darkorange">wet-deposited species</span>
+
      !---------------------------------------------------
+
+
      ! Loop over only the number of wetdep species
+
      DO NW = 1, <span style="color:darkorange">State_Chm%nWetDep</span>
+
+
        ! Get the species ID from the wetdep species ID
+
        N = <span style="color:darkorange">State_Chm%Map_WetDep(NW)</span>
+
+
        ! Set a pointer to this wetdep species
+
        A_WetDep_Species => State_Chm%Species(:,:,:,N)
+
+
        ... etc ...
+
+
        ! Free the pointer
+
        A_WetDep_Species => NULL()
+
 
+
      ENDDO
+
 
+
--[[User:Bmy|Bob Yantosca]] ([[User talk:Bmy|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 <span style="color:green">KPP chemical species</span>
+
      !---------------------------------------------------
+
+
      ! Loop over only the number of KPP species
+
      DO NK = 1, <span style="color:green">State_Chm%nKppSpc</span>
+
+
        ! Get the species ID from the KPP species ID
+
        N = <span style="color:green">State_Chm%Map_KppSpc(NK)</span>
+
+
        ! Set a pointer to this KPP chemical species
+
        A_KPP_Species => State_Chm%Species(:,:,:,N)
+
+
        ... etc ...
+
+
        ! Free the pointer
+
        A_KPP_Species => NULL()
+
 
+
      ENDDO
+
 
+
--[[User:Bmy|Bob Yantosca]] ([[User talk:Bmy|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&mdash;in [[GEOS-Chem v11-01]] and higher versions&mdash;the equivalent functionality for all of the index variables that used to be located in <code>GeosCore/tracerid_mod.F</code>
+
 
+
      TYPE, PUBLIC :: ChmState
+
+
        ... all other stuff as before...
+
+
        ! For the tagged Hg simulation
+
        <span style="color:red">INTEGER                    :: N_HG_CATS            ! # of categories</span>
+
        <span style="color:blue">INTEGER,          POINTER :: Hg0_Id_List(:      ) ! Hg0 cat <-> tracer #</span>
+
        <span style="color:green">INTEGER,          POINTER :: Hg2_Id_List(:      ) ! Hg0 cat <-> tracer #</span>
+
        <span style="color:purple">INTEGER,          POINTER :: HgP_Id_List(:      ) ! Hg0 cat <-> tracer #</span>
+
        <span style="color:darkorange">CHARACTER(LEN=4),  POINTER :: Hg_Cat_Name(:      ) ! Category names</span>       
+
+
      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  = <span style="color:red">State_Chm%N_Hg_CATS</span>
+
     
+
        ! Hg species index corresponding to a given Hg category number
+
        Hg0_Id_List => <span style="color:blue">State_Chm%Hg0_Id_List</span>
+
        Hg2_Id_List => <span style="color:green">State_Chm%Hg2_Id_List</span>
+
        HgP_Id_List => <span style="color:purple">State_Chm%HgP_Id_List</span>
+
        Hg_Cat_Name => <span style="color:darkorange">State_Chm%Hg_Cat_Name</span>
+
+
        ... etc ...
+
 
+
In addition, we have added a few other index fields for Hg species into the <code>Species</code> derived type, which is defined in <code>Headers/species_mod.F90</code>, as follows:
+
 
+
      TYPE, PUBLIC :: Species
+
 
+
        ... all other stuff as before...
+
+
        ! Tagged mercury parameters
+
        <span style="color:red">LOGICAL            :: Is_Hg0          ! TRUE if this is a total or tagged Hg0 species</span>
+
        <span style="color:blue">LOGICAL            :: Is_Hg2          ! TRUE if this is total or tagged Hg2 species</span>
+
        <span style="color:green">LOGICAL            :: Is_HgP          ! TRUE if this is  tagged HgP species</span>
+
        <span style="color:purple">INTEGER            :: Hg_Cat          ! Tagged Hg category number (1..State_Chm%N_Hg_CATS</span>
+
 
+
        ... etc ...
+
 
+
The <code>Species</code> 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&mdash;also known as <code>State_Chm%SpcData</code>&mdash;is a vector, where each element is of type <code>Species</code>.
+
 
+
                  USE Species_Mod, ONLY : Species
+
                  . . .
+
 
+
                  <span style="color:brown">TYPE(Species), POINTER :: ThisSpc</span>
+
+
                  ! Point to the <span style="color:brown">entry for tracer # IC</span> in the <span style="color:darkorange">GEOS-Chem Species Database</span>
+
                  <span style="color:brown">ThisSpc</span> => State_Chm%<span style="color:darkorange">SpcData</span>(<span style="color:brown">IC</span>)<span style="color:darkorange">%Info</span>
+
                  . . .
+
+
                  IF ( ITS_A_MERCURY_SIM ) THEN
+
 
+
                      <span style="color:blue">! Is it a Hg2 tracer?</span>
+
                      IF ( <span style="color:brown">ThisSpc</span>%<span style="color:blue">Is_Hg2</span> ) THEN
+
+
                        ! Wet scavenged Hg(II) in [kg/s], converted
+
                        ! to [kg] by multiplying by NDT
+
                        WET_Hg2 = T0 * AREA_M2 / DNS * NDT
+
                       
+
                        <span style="color:purple">! Category # for this Hg2 tracer</span>
+
                        Hg_Cat  = <span style="color:brown">ThisSpc</span>%<span style="color:purple">Hg_Cat</span>
+
+
                        ! 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
+
                  . . .
+
+
                  <span style="color:brown">ThisSpc => NULL()</span>
+
 
+
--[[User:Bmy|Bob Yantosca]] ([[User talk:Bmy|talk]]) 18:31, 24 June 2016 (UTC)
+
 
+
  
  
 
----
 
----
 
'''''[[Adding passive species to GEOS-Chem|Previous]] | [[Guide to species in GEOS-Chem|Next]] | [[Guide to species in GEOS-Chem]]'''''
 
'''''[[Adding passive species to GEOS-Chem|Previous]] | [[Guide to species in GEOS-Chem|Next]] | [[Guide to species in GEOS-Chem]]'''''

Revision as of 21:16, 9 August 2022

Previous | Next | Guide to species in GEOS-Chem

  1. Species in GEOS-Chem
  2. Physical properties of GEOS-Chem species
  3. GEOS-Chem species database
  4. GEOS-Chem species units
  5. Adding passive species to GEOS-Chem
  6. Species indexing in GEOS-Chem


This content has been migrated to the View GEOS-Chem Species Properties Supplemental Guide of geos-chem.readthedocs.io



Previous | Next | Guide to species in GEOS-Chem