LCOV - code coverage report
Current view: top level - hemco/HEMCO/src/Core - hco_config_mod.F90 (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 1438 0.0 %
Date: 2025-01-13 21:54:50 Functions: 0 32 0.0 %

          Line data    Source code
       1             : !------------------------------------------------------------------------------
       2             : !                   Harmonized Emissions Component (HEMCO)                    !
       3             : !------------------------------------------------------------------------------
       4             : !BOP
       5             : !
       6             : ! !MODULE: hco_config_mod.F90
       7             : !
       8             : ! !DESCRIPTION: Module HCO\_Config\_Mod contains routines related
       9             : ! to the HEMCO configuration file. It reads the content of the
      10             : ! configuration file, checks which entires therein are actually used
      11             : ! for this simulation run, and stores these information. This occurs
      12             : ! in two calls: Config\_ReadFile and SetReadList. Config\_ReadFile
      13             : ! writes the entire content of the configuration file into buffer
      14             : ! except for the input data associated with a disabled extension.
      15             : ! SetReadList does many more logical checks and adds all data used
      16             : ! by HEMCO to ReadList. Scale factors not used by any of the base
      17             : ! emissions and base emission fields (e.g. scale factors that won't
      18             : ! be used ) are removed in this step.
      19             : !\\
      20             : !\\
      21             : ! All data fields are saved in individual data containers, which are
      22             : ! organized in the ConfigList. Hence, ConfigList is a collection of
      23             : ! all HEMCO data containers, with every container representing an
      24             : ! entry of the configuration file. Each data container has its unique
      25             : ! container ID for identification. All HEMCO lists (ConfigList,
      26             : ! ReadList, EmisList) access the same containers.
      27             : !\\
      28             : !\\
      29             : ! The configuration file provides all source file information of the
      30             : ! emission fields and scale factors to be used. It must be read at the
      31             : ! beginning of a simulation run.
      32             : !\\
      33             : !\\
      34             : ! As of HEMCO v2.0, the ConfigList linked list sits within the HEMCO
      35             : ! configuration object (HcoConfig). HcoConfig must be passed to all
      36             : ! routines. This allows the parallel usage of multiple invocations
      37             : ! of HEMCO that use different input data. HcoConfig is initialized
      38             : ! upon reading the HEMCO configuration file (within subroutine
      39             : ! Config\_ReadFile).
      40             : !\\
      41             : !\\
      42             : ! !INTERFACE:
      43             : !
      44             : MODULE HCO_Config_Mod
      45             : !
      46             : ! !USES:
      47             : !
      48             :   USE HCO_ERROR_MOD
      49             :   USE HCO_DIAGN_MOD
      50             :   USE HCO_CHARTOOLS_MOD
      51             :   USE HCO_TYPES_MOD
      52             :   USE HCO_STATE_MOD,          ONLY : HCO_State
      53             : 
      54             :   IMPLICIT NONE
      55             :   PRIVATE
      56             : !
      57             : ! !PUBLIC MEMBER FUNCTIONS:
      58             : !
      59             :   PUBLIC  :: SetReadList
      60             :   PUBLIC  :: Config_ReadFile
      61             :   PUBLIC  :: Config_GetnSpecies
      62             :   PUBLIC  :: Config_GetSpecNames
      63             :   PUBLIC  :: ConfigInit
      64             : !
      65             : ! !PRIVATE MEMBER FUNCTIONS:
      66             : !
      67             :   PRIVATE :: ReadSettings
      68             :   PRIVATE :: ExtSwitch2Buffer
      69             :   PRIVATE :: ConfigList_AddCont
      70             :   PRIVATE :: Config_ReadCont
      71             :   PRIVATE :: RegisterPrepare
      72             :   PRIVATE :: Get_targetID
      73             :   PRIVATE :: Calc_Coverage
      74             :   PRIVATE :: Register_Base
      75             :   PRIVATE :: Register_Scal
      76             :   PRIVATE :: ReadAndSplit_Line
      77             :   PRIVATE :: Config_GetSpecAttr
      78             :   PRIVATE :: BracketCheck
      79             :   PRIVATE :: AddZeroScal
      80             :   PRIVATE :: AddShadowFields
      81             :   PRIVATE :: ParseEmisL
      82             :   PRIVATE :: CheckForDuplicateName
      83             :   PRIVATE :: Hco_GetTagInfo
      84             : !
      85             : ! !REVISION HISTORY:
      86             : !  18 Jun 2013 - C. Keller   -  Initialization
      87             : !  See https://github.com/geoschem/hemco for complete history
      88             : !EOP
      89             : !------------------------------------------------------------------------------
      90             : !BOC
      91             : !
      92             : ! !MODULE TYPES/ARGUMENTS:
      93             : !
      94             : 
      95             :   !----------------------------------------------------------------
      96             :   ! MODULE ROUTINES follow below
      97             :   !----------------------------------------------------------------
      98             : 
      99             : CONTAINS
     100             : !EOC
     101             : !------------------------------------------------------------------------------
     102             : !                   Harmonized Emissions Component (HEMCO)                    !
     103             : !------------------------------------------------------------------------------
     104             : !BOP
     105             : !
     106             : ! !IROUTINE: Config_Readfile
     107             : !
     108             : ! !DESCRIPTION: Subroutine CONFIG\_READFILE reads the HEMCO configuration file,
     109             : ! archives all HEMCO options and settings (including traceback/error setup),
     110             : ! and creates a data container for every (used) emission field in the config.
     111             : ! file. All containers become linked through the ConfigList linked list.
     112             : ! Note that lists EmisList and ReadList (created lateron)  will point to the
     113             : ! same containers, but will order the containers in a manner that is most
     114             : ! efficient for the respective purpose.
     115             : ! Argument HcoConfig represents the HEMCO configuration object. It contains
     116             : ! pointers to the HEMCO traceback and error information as well as a pointer
     117             : ! to ConfigList. If undefined, HcoConfig becomes initialized as part of this
     118             : ! routine.
     119             : !\\
     120             : !\\
     121             : ! !INTERFACE:
     122             : !
     123           0 :   SUBROUTINE Config_ReadFile( am_I_Root, HcoConfig, ConfigFile, Phase, &
     124             :                               RC,        IsNest,    IsDryRun )
     125             : !
     126             : ! !USES:
     127             : !
     128             :     USE HCO_inquireMod,    ONLY : findFreeLUN
     129             :     USE HCO_CharPak_Mod,   ONLY : STRREPL
     130             :     USE HCO_EXTLIST_MOD,   ONLY : AddExt, CoreNr, ExtNrInUse
     131             : !
     132             : ! !INPUT PARAMETERS:
     133             : !
     134             :     LOGICAL,            INTENT(IN)              :: am_I_Root  ! root CPU?
     135             :     TYPE(ConfigObj),    POINTER                 :: HcoConfig  ! HEMCO config obj
     136             :     CHARACTER(LEN=*),   INTENT(IN)              :: ConfigFile ! Full file name
     137             :     INTEGER,            INTENT(IN)              :: Phase      ! 0: all
     138             :                                                               ! 1: Settings and switches only
     139             :                                                               ! 2: fields only
     140             :     LOGICAL,            INTENT(IN),    OPTIONAL :: IsNest     ! Nested call?
     141             :     LOGICAL,            INTENT(IN),    OPTIONAL :: IsDryRun   ! Dry-run?
     142             : !
     143             : ! !INPUT/OUTPUT PARAMETERS:
     144             : !
     145             :     INTEGER,            INTENT(INOUT)           :: RC         ! Success?
     146             : !
     147             : ! !REVISION HISTORY:
     148             : !  17 Sep 2012 - C. Keller   - Initialization
     149             : !  See https://github.com/geoschem/hemco for complete history
     150             : !EOP
     151             : !------------------------------------------------------------------------------
     152             : !BOC
     153             : !
     154             : ! !LOCAL VARIABLES:
     155             : !
     156             :     ! Scalars
     157             :     LOGICAL              :: EOF
     158             :     LOGICAL              :: EXISTS, NEST, DoDryRUn
     159             :     INTEGER              :: NN
     160             :     INTEGER              :: IU_HCO, IOS
     161             : 
     162             :     ! Strings
     163             :     CHARACTER(LEN=255)   :: loc,  fileMsg
     164             :     CHARACTER(LEN=512)   :: msg
     165             :     CHARACTER(LEN=2047)  :: CFDIR
     166             :     CHARACTER(LEN=2047)  :: LINE
     167             : 
     168             :     !======================================================================
     169             :     ! Config_ReadFile begins here
     170             :     !======================================================================
     171             : 
     172             :     ! Enter
     173           0 :     RC  = HCO_SUCCESS
     174           0 :     msg = ''
     175           0 :     loc = 'Config_ReadFile (hco_config_mod.F90)'
     176             : 
     177             :     ! Initialize config object if not already initialized
     178           0 :     IF ( .NOT. ASSOCIATED(HcoConfig) ) THEN
     179           0 :        CALL ConfigInit( HcoConfig, RC )
     180           0 :        HcoConfig%ConfigFileName =  TRIM(ConfigFile)
     181             :     ENDIF
     182             : 
     183             :     ! Initialize
     184           0 :     HcoConfig%amIRoot = am_I_Root
     185             : 
     186             :     ! Leave here if configuration file is already read
     187           0 :     IF ( HcoConfig%ConfigFileRead ) THEN
     188           0 :        RETURN
     189             :     ENDIF
     190             : 
     191             :     ! Nested call?
     192           0 :     IF ( PRESENT( IsNest ) ) THEN
     193           0 :        NEST = IsNest
     194             :     ELSE
     195             :        NEST = .FALSE.
     196             :     ENDIF
     197             : 
     198             :     ! Is this a dry-run simulation?
     199           0 :     IF ( PRESENT( IsDryRun) ) THEN
     200           0 :        DoDryRun= IsDryRun
     201             :     ELSE
     202             :        DoDryRun = .FALSE.
     203             :     ENDIF
     204             : 
     205             :     ! Prompt to standard output (only on the root core
     206           0 :     IF ( HcoConfig%amIRoot ) THEN
     207             : 
     208           0 :        IF ( DoDryRun ) THEN
     209             : 
     210             :           !-----------------------------------------------------------------
     211             :           ! For dry-run simulations: state if the configuration file
     212             :           ! is found on disk, or not.  Only write this message once.
     213             :           !-----------------------------------------------------------------
     214             : 
     215             :           ! Test if the file exists
     216           0 :           INQUIRE( FILE=TRIM( ConfigFile ), EXIST=Exists )
     217             : 
     218             :           ! Test if the file exists and define an output string
     219           0 :           IF ( Exists ) THEN
     220           0 :              FileMsg = 'HEMCO (INIT): Opening '
     221             :           ELSE
     222           0 :              FileMsg = 'HEMCO (INIT): REQUIRED FILE NOT FOUND '
     223             :           ENDIF
     224             : 
     225             :           ! Write message to stdout
     226           0 :           WRITE( 6, 300 ) TRIM( FileMsg ), TRIM( ConfigFile )
     227             :  300      FORMAT( a, ' ./', a )
     228             : 
     229             :        ELSE
     230             : 
     231             :           !-----------------------------------------------------------------
     232             :           ! For regular simulations, write a message containing
     233             :           ! the configuration file as well as the Phase value.
     234             :           !-----------------------------------------------------------------
     235           0 :           WRITE(6,*) ' '
     236           0 :           IF ( Phase == 1 ) THEN
     237           0 :              WRITE( 6, 310 ) TRIM(ConfigFile)
     238             :  310         FORMAT( 'Reading settings & switches of HEMCO configuration file: ', a )
     239             : 
     240           0 :           ELSEIF ( Phase == 2 ) THEN
     241           0 :              WRITE( 6, 320 ) TRIM(ConfigFile)
     242             :  320         FORMAT( 'Reading fields of HEMCO configuration file: ', a )
     243             : 
     244             :           ELSE
     245           0 :              WRITE( 6, 330 ) TRIM(ConfigFile)
     246             :  330         FORMAT( 'Reading entire HEMCO configuration file: ', a )
     247             :           ENDIF
     248             :        ENDIF
     249             :     ENDIF
     250             : 
     251             :     ! Extract configuration file directory. This is the directory containing
     252             :     ! the configuration file. Any tokens $CFDIR in the given configuration
     253             :     ! file will be replaced with the configuration file directory
     254           0 :     CALL HCO_GetBase( ConfigFile, CFDIR, RC )
     255           0 :     IF ( RC /= HCO_SUCCESS ) THEN
     256           0 :        msg = 'Could not replace $CFDIR token in: ' // TRIM( ConfigFile )
     257           0 :        CALL HCO_Error( msg, RC, thisLoc=LOC )
     258           0 :        RETURN
     259             :     ENDIF
     260             : 
     261             :     ! Find free LUN
     262           0 :     IU_HCO = findFreeLUN()
     263             : 
     264           0 :     INQUIRE( FILE=TRIM(ConfigFile), EXIST=EXISTS )
     265           0 :     IF ( .NOT. EXISTS ) THEN
     266           0 :        IF ( HcoConfig%amIRoot ) THEN
     267           0 :           WRITE(*,*) 'Cannot read file - it does not exist: ', TRIM(ConfigFile)
     268             :        ENDIF
     269           0 :        RC = HCO_FAIL
     270           0 :        RETURN
     271             :     ENDIF
     272             : 
     273             :     ! Open configuration file
     274           0 :     OPEN ( IU_HCO, FILE=TRIM( ConfigFile ), STATUS='OLD', IOSTAT=IOS )
     275           0 :     IF ( IOS /= 0 ) THEN
     276           0 :        IF ( HcoConfig%amIRoot ) THEN
     277           0 :           WRITE(*,*) 'Error reading ', TRIM(ConfigFile)
     278             :        ENDIF
     279           0 :        RC = HCO_FAIL
     280           0 :        RETURN
     281             :     ENDIF
     282             : 
     283             :     ! Register HEMCO core as extension Nr. CoreNr (default). The
     284             :     ! core module is used by all HEMCO simulations, and the overall
     285             :     ! HEMCO settings are stored as options of this extension.
     286             :     ! Note: cannot use HCO_GetOpt('Wildcard') for species here because
     287             :     ! this is linked to the core extension...
     288           0 :     IF ( .NOT. ExtNrInUse( HcoConfig%ExtList, CoreNr ) ) THEN
     289           0 :        CALL AddExt( HcoConfig, 'CORE', CoreNr, .TRUE., 'all', RC )
     290           0 :        IF ( RC /= HCO_SUCCESS ) THEN
     291           0 :           msg = 'Error adding CORE extension'
     292           0 :           CALL HCO_Error( msg, RC, thisLoc=loc )
     293           0 :           RC = HCO_FAIL
     294           0 :           RETURN
     295             :        ENDIF
     296             :     ENDIF
     297             : 
     298             :     ! NN counts how many sections have ben read already
     299           0 :     NN = 0
     300             : 
     301             :     ! Loop until EOF
     302             :     DO
     303             : 
     304             :        ! Read a line from the file, exit if EOF
     305           0 :        CALL HCO_ReadLine ( IU_HCO, LINE, EOF, RC )
     306           0 :        IF ( RC /= HCO_SUCCESS ) THEN
     307           0 :           msg = 'Error in HEMCO_Config.rc @ line: ' // TRIM( Line )
     308           0 :           CALL HCO_Error( msg, RC, thisLoc=loc )
     309           0 :           RETURN
     310             :        ENDIF
     311           0 :        IF ( EOF ) EXIT
     312             : 
     313             :        ! Replace tab characters in LINE (if any) w/ spaces
     314           0 :        CALL STRREPL( LINE, HCO_TAB, HCO_SPC )
     315             : 
     316             :        ! Read settings if this is beginning of settings section
     317             :        ! This reads all settings into buffer and initializes the
     318             :        ! HEMCO traceback/error options.
     319           0 :        IF ( INDEX ( LINE, 'BEGIN SECTION SETTINGS' ) > 0 ) THEN
     320             : 
     321           0 :           IF ( PHASE < 2 ) THEN
     322           0 :              CALL ReadSettings( HcoConfig, IU_HCO, EOF, RC )
     323           0 :              IF ( RC /= HCO_SUCCESS ) THEN
     324           0 :                 msg = 'Error in HEMCO_Config.rc @ section ' // TRIM( line )
     325           0 :                 CALL HCO_Error( msg, RC, thisLoc=loc )
     326           0 :                 RETURN
     327             :              ENDIF
     328           0 :              IF ( EOF ) EXIT
     329             : 
     330             :              ! Increase counter
     331           0 :              NN = NN + 1
     332             : 
     333             :              ! Can we leave here?
     334           0 :              IF ( PHASE == 1 .AND. NN == 2 ) EXIT
     335             :           ENDIF
     336             : 
     337             :        ! Read extension switches. This registers all enabled extensions.
     338             :        ! This must include the core extension.
     339           0 :        ELSEIF ( INDEX ( LINE, 'BEGIN SECTION EXTENSION SWITCHES' ) > 0 ) THEN
     340             : 
     341           0 :           IF ( PHASE < 2 ) THEN
     342           0 :              CALL ExtSwitch2Buffer( HcoConfig, IU_HCO, EOF, RC )
     343           0 :              IF ( RC /= HCO_SUCCESS ) THEN
     344           0 :                 msg = 'Error in HEMCO_Config,rc @ section: ' // TRIM( line )
     345           0 :                 CALL HCO_Error( msg, RC, thisLoc=loc )
     346           0 :                 RETURN
     347             :              ENDIF
     348           0 :              IF ( EOF ) EXIT
     349             : 
     350             :              ! Increase counter
     351           0 :              NN = NN + 1
     352             : 
     353             :              ! Can we leave here?
     354           0 :              IF ( PHASE == 1 .AND. NN == 2 ) EXIT
     355             :           ENDIF
     356             : 
     357             :        ! Read base emissions. This creates a new data container for each
     358             :        ! base emission field.
     359           0 :        ELSEIF ( INDEX ( LINE, 'BEGIN SECTION BASE EMISSIONS' ) > 0 ) THEN
     360             : 
     361             :           ! Read data and write into container
     362             :           ! For dry-run simulations, print name of any
     363             :           ! nested configuration files (e.g. for standalone)
     364           0 :           IF ( PHASE == 0 .OR. PHASE == 2 ) THEN
     365             :              CALL Config_ReadCont( HcoConfig,        IU_HCO, CFDIR,          &
     366             :                                    HCO_DCTTYPE_BASE, EOF,    RC,             &
     367           0 :                                    IsDryRun=IsDryRun                        )
     368           0 :              IF ( RC /= HCO_SUCCESS ) THEN
     369           0 :                 msg = 'Error in HEMCO_Config.rc @ section: ' // TRIM( Line )
     370           0 :                 CALL HCO_Error( msg, RC, thisLoc=loc )
     371           0 :                 RETURN
     372             :              ENDIF
     373           0 :              IF ( EOF ) EXIT
     374             : 
     375             :              ! Increase counter
     376           0 :              NN = NN + 1
     377             :           ENDIF
     378             : 
     379             :        ! Read scale factors. This creates a new data container for each
     380             :        ! scale factor.
     381           0 :        ELSE IF ( INDEX ( LINE, 'BEGIN SECTION SCALE FACTORS' ) > 0 ) THEN
     382             : 
     383             :           CALL Config_ReadCont( HcoConfig, IU_HCO, CFDIR, &
     384           0 :                                 HCO_DCTTYPE_SCAL, EOF, RC )
     385           0 :           IF ( RC /= HCO_SUCCESS ) THEN
     386           0 :              msg= 'Error in HEMCO_Config.rc @ section: ' // TRIM( Line )
     387           0 :              CALL HCO_Error( msg, RC, thisLoc=loc )
     388           0 :              RETURN
     389             :           ENDIF
     390           0 :           IF ( EOF ) EXIT
     391             : 
     392             :        ! Read masks. This creates a new data container for each mask
     393           0 :        ELSE IF ( INDEX ( LINE, 'BEGIN SECTION MASKS' ) > 0 ) THEN
     394             : 
     395           0 :           IF ( PHASE == 0 .OR. PHASE == 2 ) THEN
     396             :              CALL Config_ReadCont( HcoConfig, IU_HCO, CFDIR, &
     397           0 :                                    HCO_DCTTYPE_MASK, EOF, RC )
     398           0 :              IF ( RC /= HCO_SUCCESS ) THEN
     399           0 :                 msg = 'Error in HEMCO_Config.rc @ line: ' // TRIM( Line )
     400           0 :                 CALL HCO_Error( msg, RC, thisLoc=LOC )
     401           0 :                 RETURN
     402             :              ENDIF
     403           0 :              IF ( EOF ) EXIT
     404             : 
     405             :              ! Increase counter
     406           0 :              NN = NN + 1
     407             :           ENDIF
     408             : 
     409             :        ENDIF
     410             :     ENDDO
     411             : 
     412             :     ! Check if we caught all sections. Do that only for phase 1.
     413             :     ! Sections SETTINGS and extension switches are needed.
     414           0 :     IF ( PHASE == 1 .AND. NN /= 2 .AND. .NOT. NEST ) THEN
     415           0 :        WRITE(*,*) 'Expected 2 sections, found/read ', NN
     416           0 :        WRITE(*,*) 'Should read SETTINGS and EXTENSION SWITCHES'
     417           0 :        RC = HCO_FAIL
     418           0 :        RETURN
     419             :     ENDIF
     420             : 
     421             :     ! Close file
     422           0 :     CLOSE( UNIT=IU_HCO, IOSTAT=IOS )
     423           0 :     IF ( IOS /= 0 ) THEN
     424           0 :        msg = 'Error closing ' // TRIM(ConfigFile)
     425           0 :        CALL HCO_Error( msg, RC, thisLoc=loc )
     426           0 :        RC = HCO_FAIL
     427           0 :        RETURN
     428             :     ENDIF
     429             : 
     430             :     ! Configuration file is now read
     431           0 :     IF ( .NOT. NEST ) THEN
     432           0 :        IF ( PHASE == 0 .OR. PHASE == 2 ) THEN
     433           0 :           HcoConfig%ConfigFileRead = .TRUE.
     434             :        ENDIF
     435             :     ENDIF
     436             : 
     437             :     ! Leave w/ success
     438           0 :     RC = HCO_SUCCESS
     439             : 
     440             :   END SUBROUTINE Config_ReadFile
     441             : !EOC
     442             : !------------------------------------------------------------------------------
     443             : !                   Harmonized Emissions Component (HEMCO)                    !
     444             : !------------------------------------------------------------------------------
     445             : !BOP
     446             : !
     447             : ! !IROUTINE: SetReadList
     448             : !
     449             : ! !DESCRIPTION: Subroutine SetReadList writes data to the data reading
     450             : ! lists (ReadList). This routine assumes that the configuration file has
     451             : ! been read beforehand (via Config\_ReadFile).
     452             : !\\
     453             : !\\
     454             : ! !INTERFACE:
     455             : !
     456           0 :   SUBROUTINE SetReadList( HcoState, RC )
     457             : !
     458             : ! !USES:
     459             : !
     460             :     USE HCO_DATACONT_Mod,    ONLY : cIDList_Create
     461             :     USE HCO_READLIST_Mod,    ONLY : ReadList_Init, ReadList_Print
     462             : !
     463             : ! !INPUT PARAMETERS:
     464             : !
     465             :     TYPE(HCO_State), POINTER       :: HcoState    ! HEMCO state
     466             : !
     467             : ! !INPUT/OUTPUT PARAMETERS:
     468             : !
     469             :     INTEGER,         INTENT(INOUT) :: RC          ! Error stat
     470             : !
     471             : ! !REVISION HISTORY:
     472             : !  18 Jun 2013 - C. Keller: Initialization
     473             : !  See https://github.com/geoschem/hemco for complete history
     474             : !EOP
     475             : !------------------------------------------------------------------------------
     476             : !BOC
     477             : 
     478             :     CHARACTER(LEN=255) :: loc
     479             :     CHARACTER(LEN=512) :: msg
     480             : 
     481             :     !======================================================================
     482             :     ! SetReadList begins here
     483             :     !======================================================================
     484           0 :     msg = ''
     485           0 :     loc = 'SetReadList (HCO_CONFIG_MOD.F90)'
     486             : 
     487             :     ! Init
     488           0 :     CALL HCO_ENTER ( HcoState%Config%Err, LOC, RC )
     489           0 :     IF ( RC /= HCO_SUCCESS ) THEN
     490           0 :        msg = 'Error encountered in routine "HCO_Enter"!'
     491           0 :        CALL HCO_Error( msg, RC, thisLoc=loc )
     492           0 :        RETURN
     493             :     ENDIF
     494             : 
     495             :     ! Return w/ error if configuration file hasn't been read yet!
     496           0 :     IF ( .NOT. ASSOCIATED(HcoState%Config) ) THEN
     497           0 :        msg = 'HEMCO configuration object in HEMCO state is empty!'
     498           0 :        CALL HCO_Error( msg, RC, thisLoc=loc )
     499           0 :        RETURN
     500             :     ENDIF
     501           0 :     IF ( .NOT. HcoState%Config%ConfigFileRead ) THEN
     502           0 :        msg = 'HEMCO configuration file not read!'
     503           0 :        CALL HCO_Error( msg, RC, thisLoc=loc )
     504           0 :        RETURN
     505             :     ENDIF
     506             : 
     507             :     ! Only if not yet done so...
     508           0 :     IF ( .NOT. HcoState%SetReadListCalled ) THEN
     509             : 
     510             :        ! Initialize ReadList
     511           0 :        CALL ReadList_Init ( HcoState%ReadLists, RC )
     512           0 :        IF ( RC /= HCO_SUCCESS ) THEN
     513           0 :           PRINT *,'Error in ReadList_Init called from HEMCO SetReadList'
     514           0 :           RETURN
     515             :        ENDIF
     516             : 
     517             :        ! Prepare data in buffer. This call identifies all base fields
     518             :        ! that have to be read by this CPU. It also kicks out base
     519             :        ! fields for emissions with an invalid species ID (if any) or
     520             :        ! if there are other base fields with higher priority.
     521           0 :        CALL RegisterPrepare ( HcoState, RC )
     522           0 :        IF ( RC /= HCO_SUCCESS ) THEN
     523           0 :           PRINT *,'Error in RegisterPrepare called from HEMCO SetReadList'
     524           0 :           RETURN
     525             :        ENDIF
     526             : 
     527             :        ! Register base emissions. In this step, we also redefine the
     528             :        ! list UnqScalIDs to make sure that only those scale factors
     529             :        ! will be registered that are effectively used in the next step.
     530           0 :        CALL Register_Base( HcoState, RC )
     531           0 :        IF ( RC /= HCO_SUCCESS ) THEN
     532           0 :           PRINT *,'Error in Register_Base called from HEMCO SetReadList'
     533           0 :           RETURN
     534             :        ENDIF
     535             : 
     536             :        ! Register scale factors based upon UnqScalIDs.
     537           0 :        CALL Register_Scal( HcoState, RC )
     538           0 :        IF ( RC /= HCO_SUCCESS ) THEN
     539           0 :           PRINT *,'Error in Register_Scal called from HEMCO SetReadList'
     540           0 :           RETURN
     541             :        ENDIF
     542             : 
     543             :        ! Create cIDList which allows quick access to all data containers
     544             :        ! based on their container IDs cID
     545           0 :        CALL cIDList_Create ( HcoState, HcoState%Config%ConfigList, RC )
     546           0 :        IF ( RC /= HCO_SUCCESS ) THEN
     547           0 :           PRINT *,'Error in cIDList_Create called from HEMCO SetReadlist'
     548           0 :           RETURN
     549             :        ENDIF
     550             : 
     551             :        ! Don't need internal lists anymore.
     552           0 :        CALL ScalID_Cleanup  ( HcoState%Config%ScalIDList   )
     553           0 :        CALL SpecName_Cleanup( HcoState%Config%SpecNameList )
     554             : 
     555             :     ENDIF ! SetReadListCalled
     556             : 
     557             :     ! SetReadList has now been called
     558           0 :     HcoState%SetReadListCalled = .TRUE.
     559             : 
     560             :     ! Debug
     561           0 :     IF ( HCO_IsVerb( HcoState%Config%Err ) ) THEN
     562           0 :        CALL ReadList_Print( HcoState, HcoState%ReadLists )
     563             :     ENDIF
     564             : 
     565             :     ! Leave w/ success
     566           0 :     CALL HCO_LEAVE( HcoState%Config%Err, RC )
     567             : 
     568             :   END SUBROUTINE SetReadList
     569             : !EOC
     570             : !------------------------------------------------------------------------------
     571             : !                   Harmonized Emissions Component (HEMCO)                    !
     572             : !------------------------------------------------------------------------------
     573             : !BOP
     574             : !
     575             : ! !IROUTINE: Config_ReadCont
     576             : !
     577             : ! !DESCRIPTION: Subroutine CONFIG\_READCONT reads the given line into a
     578             : ! list container. Depending on the specified data type, the line is
     579             : ! assumed to hold base emissions, scale factors, or mask information.
     580             : !\\
     581             : !\\
     582             : ! !INTERFACE:
     583             : !
     584           0 :   SUBROUTINE Config_ReadCont( HcoConfig, IU_HCO,  CFDIR,          &
     585             :                               DctType,   EOF,       RC,      IsDryRun       )
     586             : !
     587             : ! !USES:
     588             : !
     589             :     USE HCO_CHARPAK_MOD,  ONLY : StrSplit
     590             :     USE HCO_EXTLIST_MOD,  ONLY : ExtNrInUse, HCO_GetOpt
     591             :     USE HCO_TIDX_Mod,     ONLY : HCO_ExtractTime
     592             :     USE HCO_FILEDATA_Mod, ONLY : FileData_Init
     593             :     USE HCO_DATACONT_Mod, ONLY : CatMax, ZeroScalID
     594             : !
     595             : ! !INPUT PARAMETERS:
     596             : !
     597             :     TYPE(ConfigObj),  POINTER       :: HcoConfig ! Config object
     598             :     INTEGER,          INTENT(IN   ) :: IU_HCO    ! Logfile LUN
     599             :     CHARACTER(LEN=*), INTENT(IN   ) :: CFDIR     ! Configuration file directory
     600             :     INTEGER,          INTENT(IN   ) :: DctType   ! 1=base; 2=scale; 3=mask
     601             :     LOGICAL,          OPTIONAL      :: IsDryRun  ! Is this a HEMCO dry-run?
     602             : !
     603             : ! !INPUT/OUTPUT PARAMETERS:
     604             : !
     605             :     LOGICAL,          INTENT(INOUT) :: EOF       ! end of file encountered?
     606             : !
     607             : ! !OUTPUT PARAMETERS:
     608             : !
     609             :     INTEGER,          INTENT(  OUT) :: RC        ! error code
     610             : !
     611             : ! !REVISION HISTORY:
     612             : !  03 Jan 2014 - C. Keller - Initial version
     613             : !  See https://github.com/geoschem/hemco for complete history
     614             : !EOP
     615             : !------------------------------------------------------------------------------
     616             : !BOC
     617             : !
     618             : ! !LOCAL VARIABLES:
     619             : !
     620             :     ! Scalars
     621             :     INTEGER                   :: I, N, nEdges
     622             :     INTEGER                   :: nScl
     623             :     INTEGER                   :: STAT
     624             :     INTEGER                   :: Int1
     625             :     INTEGER                   :: Int2
     626             :     INTEGER                   :: Int3
     627             :     INTEGER                   :: Int4
     628             :     INTEGER                   :: nCat
     629             :     INTEGER                   :: Cats(CatMax)
     630             :     INTEGER                   :: STRLEN
     631             :     INTEGER                   :: levScal1
     632             :     INTEGER                   :: levScal2
     633             :     INTEGER                   :: nTags
     634             :     LOGICAL                   :: SKIP
     635             :     LOGICAL                   :: Found
     636             :     CHARACTER(LEN= 63)        :: cName
     637             :     CHARACTER(LEN=255)        :: srcFile
     638             :     CHARACTER(LEN=100)        :: srcVar
     639             :     CHARACTER(LEN= 31)        :: srcTime
     640             :     CHARACTER(LEN= 31)        :: TmCycle
     641             :     CHARACTER(LEN=  1)        :: WildCard
     642             :     CHARACTER(LEN=  1)        :: Separator
     643             :     CHARACTER(LEN= 31)        :: srcDim
     644             :     CHARACTER(LEN= 31)        :: srcUnit
     645             :     CHARACTER(LEN= 31)        :: SpcName
     646             :     CHARACTER(LEN=255)        :: Char1
     647             :     CHARACTER(LEN=255)        :: Char2
     648             :     CHARACTER(LEN=255)        :: loc
     649             :     CHARACTER(LEN=255)        :: LINE
     650             :     CHARACTER(LEN=255)        :: tagId
     651             :     CHARACTER(LEN=255)        :: tagName
     652             :     CHARACTER(LEN=255)        :: tagcName
     653             :     CHARACTER(LEN=255)        :: ItemPrefix
     654             :     CHARACTER(LEN=512)        :: msg
     655             : 
     656             :     ! Arrays
     657             :     INTEGER                   :: SplitInts(255)
     658             :     CHARACTER(LEN=255)        :: SubStrs(255)
     659             : 
     660             :     ! Pointers
     661             :     TYPE(ListCont), POINTER   :: Lct
     662             :     TYPE(ListCont), POINTER   :: Tmp
     663             :     TYPE(FileData), POINTER   :: Dta
     664             : 
     665             :     !=================================================================
     666             :     ! Config_ReadCont begins here!
     667             :     !=================================================================
     668             : 
     669             :     ! Enter
     670           0 :     loc = 'Config_ReadCont (hco_config_mod.F90)'
     671             : 
     672             :     ! Initialize
     673           0 :     SKIP           = .FALSE.
     674           0 :     nCat           = -1
     675           0 :     Lct            => NULL()
     676           0 :     Tmp            => NULL()
     677           0 :     Dta            => NULL()
     678             : 
     679             :     ! Get tokens
     680           0 :     WildCard  = HCO_GetOpt( HcoConfig%ExtList, 'Wildcard'  )
     681           0 :     Separator = HCO_GetOpt( HcoConfig%ExtList, 'Separator' )
     682             : 
     683             :     ! Repeat until end of the given section is found
     684             :     DO
     685             : 
     686             :        ! Zero loop variables for safety's sake (bmy, 07 Mar 2022)
     687           0 :        srcFile = ''
     688           0 :        srcVar  = ''
     689           0 :        srcTime = ''
     690           0 :        tmCycle = ''
     691           0 :        srcDim  = ''
     692           0 :        srcUnit = ''
     693           0 :        spcName = ''
     694           0 :        char1   = ''
     695           0 :        char2   = ''
     696           0 :        int1    = 0
     697           0 :        int2    = 0
     698           0 :        int3    = 0
     699             : 
     700             :        !==============================================================
     701             :        ! Read line and get desired character strings
     702             :        ! Since base emissions, scale factors and masks have different
     703             :        ! configuration file input parameter, need to use a different
     704             :        ! call for the three data types.
     705             :        !==============================================================
     706           0 :        IF ( DctType == HCO_DCTTYPE_BASE ) THEN
     707             :           CALL ReadAndSplit_Line ( HcoConfig, IU_HCO, cName,    2,  &
     708             :                                    srcFile,   3,      srcVar,   4,  &
     709             :                                    srcTime,   5,      TmCycle,  6,  &
     710             :                                    srcDim,    7,      srcUnit,  8,  &
     711             :                                    SpcName,   9,      Char1,   10,  &
     712             :                                    Char2,    11,                    &
     713             :                                    Int1,     -1,      Int2,    12,  &
     714             :                                    Int3,      1,      STAT,         &
     715           0 :                                    OutLine=LINE                      )
     716             : 
     717           0 :        ELSEIF ( DctType == HCO_DCTTYPE_SCAL ) THEN
     718             :           CALL ReadAndSplit_Line ( HcoConfig, IU_HCO, cName,    2,  &
     719             :                                    srcFile,   3,      srcVar,   4,  &
     720             :                                    srcTime,   5,      TmCycle,  6,  &
     721             :                                    srcDim,    7,      srcUnit,  8,  &
     722             :                                    SpcName,  -1,      Char1,   -1,  &
     723             :                                    Char2,    -1,                    &
     724             :                                    Int1,      1,      Int2,     9,  &
     725             :                                    Int3,     10,      STAT,         &
     726           0 :                                    optcl=10    ,      OutLine=LINE   )
     727             : 
     728           0 :        ELSEIF ( DctType == HCO_DCTTYPE_MASK ) THEN
     729             :           CALL ReadAndSplit_Line ( HcoConfig, IU_HCO, cName,    2,  &
     730             :                                    srcFile,   3,      srcVar,   4,  &
     731             :                                    srcTime,   5,      TmCycle,  6,  &
     732             :                                    srcDim,    7,      srcUnit,  8,  &
     733             :                                    SpcName,  -1,      Char1,   10,  &
     734             :                                    Char2,    11,                    &
     735             :                                    Int1,      1,      Int2,     9,  &
     736             :                                    Int3,     -1,      STAT,         &
     737           0 :                                    optcl=11,          OutLine=LINE   )
     738             :        ENDIF
     739             : 
     740             :        !--------------------------------------------------------------
     741             :        ! Error checks
     742             :        !--------------------------------------------------------------
     743             : 
     744             :        ! Check for end of file
     745           0 :        IF ( STAT < 0 ) THEN
     746           0 :           EOF = .TRUE.
     747           0 :           EXIT
     748             :        ENDIF
     749             : 
     750             :        ! Skip this entry if commented line
     751           0 :        IF ( STAT == 1 ) THEN
     752             :           CYCLE
     753             :        ENDIF
     754             : 
     755             :        ! Leave routine here if end of section encountered
     756           0 :        IF ( STAT == 10 ) THEN
     757             :           EXIT
     758             :        ENDIF
     759             : 
     760             :        ! Error if not enough entries found
     761           0 :        IF ( STAT == 100 ) THEN
     762           0 :           msg = 'STAT == 100; not enough entries found!'
     763           0 :           CALL HCO_Error( msg, RC, thisLoc=loc )
     764           0 :           RETURN
     765             :        ENDIF
     766             : 
     767             :        ! -------------------------------------------------------------
     768             :        ! Check for emission shortcuts. Fields can be bracketed into
     769             :        ! 'collections'.
     770             :        ! -------------------------------------------------------------
     771           0 :        CALL BracketCheck( HcoConfig, STAT, LINE, SKIP, RC )
     772           0 :        IF ( RC /= HCO_SUCCESS ) THEN
     773           0 :           msg = 'Bracket error in HEMCO_Config.rc @ line ' // TRIM( line )
     774           0 :           CALL HCO_ERROR( msg, RC, thisLoc=loc )
     775           0 :           RETURN
     776             :        ENDIF
     777             : 
     778             :        ! Skip if needed
     779           0 :        IF ( SKIP ) CYCLE
     780             : 
     781             :        ! Can advance to next line if this was a bracket line: nothing
     782             :        ! else to do with this line.
     783           0 :        IF ( STAT == 5 .OR. STAT == 6 ) CYCLE
     784             : 
     785             :        ! Read include file. Configuration files can be 'nested', e.g.
     786             :        ! configuration files can be included into the 'main' configuration
     787             :        ! file. These files must be listed as '>>>include FileName', where
     788             :        ! FileName is the actual path of the file.
     789           0 :        IF ( STAT == 1000 ) THEN
     790             : 
     791             :           ! Call the parser. This is to make sure that any $ROOT statements
     792             :           ! will be evaluated properly. The configuration file must not
     793             :           ! contain any data tokens ($YR, $MM, etc.).
     794           0 :           CALL HCO_CharParse ( HcoConfig, LINE, 0, 0, 0, 0, 0, RC )
     795           0 :           IF ( RC /= HCO_SUCCESS ) THEN
     796           0 :              msg = 'Parse error in HEMCO_Config.rc @ line: ' // TRIM( line )
     797           0 :              CALL HCO_Error( msg, RC, thisLoc=LOC )
     798           0 :              RETURN
     799             :           ENDIF
     800             : 
     801             :           CALL Config_ReadFile( HcoConfig%amIRoot, HcoConfig, LINE, 0, RC,  &
     802           0 :                                 IsNest=.TRUE., IsDryRun=IsDryRun            )
     803           0 :           IF ( RC /= HCO_SUCCESS ) THEN
     804           0 :              msg = 'Error reading HEMCO_Config.rc @ line: ' // TRIM( line )
     805           0 :              CALL HCO_Error( msg, RC, thisLoc=loc )
     806           0 :              RETURN
     807             :           ENDIF
     808             : 
     809             :           ! All done with this line
     810             :           CYCLE
     811             :        ENDIF
     812             : 
     813             :        ! Output status should be 0 if none of the statuses above applies
     814           0 :        IF ( STAT /= 0 ) THEN
     815           0 :           msg = 'STAT /= 0; indicates I/O error!'
     816           0 :           CALL HCO_Error( msg, RC, thisLoc=loc )
     817           0 :           RETURN
     818             :        ENDIF
     819             : 
     820             :        ! For base fields, check if this extension number is indeed in
     821             :        ! use. Otherwise, we can ignore this line completely! The
     822             :        ! extension switches are read and evaluated prior to the
     823             :        ! extension data!
     824           0 :        IF ( DctType == HCO_DCTTYPE_BASE .AND. &
     825             :             .NOT. ExtNrInUse( HcoConfig%ExtList, Int3 ) ) CYCLE
     826             : 
     827             :        !==============================================================
     828             :        ! Create and fill list container and add to ConfigList
     829             :        !==============================================================
     830             : 
     831             :        ! Test if wildcard is present
     832           0 :        IF ( INDEX( srcVar, '?' ) > 0 ) THEN
     833             : 
     834             :           ! Split the name to get wildcard and string prior to wildcard
     835           0 :           CALL StrSplit( srcVar, '?', SubStrs, N )
     836           0 :           tagId = SubStrs(N-1)
     837           0 :           ItemPrefix = SubStrs(1)
     838             : 
     839             :           ! Get number of tags for this wildcard
     840           0 :           CALL Hco_GetTagInfo( tagId, HcoConfig, Found, RC, nTags=nTags )
     841             : 
     842             :           ! Add each tagged name as a separate item in the collection
     843           0 :           DO N = 1, nTags
     844             :              ! Construct the item name
     845           0 :              tagcName = ''
     846             : 
     847             :              ! Get tag, if any
     848             :              CALL Hco_GetTagInfo( tagId, HcoConfig, Found, RC, N=N, &
     849           0 :                                   tagName=tagName )
     850           0 :              IF ( RC /= HCO_SUCCESS ) THEN
     851             :                 msg = 'Error retrieving tag name for' //            &
     852           0 :                       ' wildcard ' // TRIM(tagId)
     853           0 :                 CALL HCO_Error( msg, RC, thisLoc=loc )
     854           0 :                 RETURN
     855             :              ENDIF
     856             : 
     857             :              ! Append the tag name to the output name
     858           0 :              srcVar   = TRIM( ItemPrefix ) // TRIM( tagName )
     859           0 :              tagcName = TRIM( cName      ) // TRIM( tagName )
     860             :              ! Do not overwrite species name for now. Use HEMCO wildcard
     861             :              ! to read all external model species.
     862             :              !spcName  = TRIM( tagName    )
     863             : 
     864             :              ! -------------------------------------------------------------
     865             :              ! Fill data container
     866             :              ! -------------------------------------------------------------
     867             : 
     868             :              ! Add blank list container (ListCont object) to ConfigList.
     869             :              ! The container is placed at the beginning of the list.
     870           0 :              CALL ConfigList_AddCont ( Lct, HcoConfig%ConfigList )
     871             : 
     872             :              ! Check if name exists already
     873           0 :              CALL CheckForDuplicateName( HcoConfig, tagcName, RC )
     874           0 :              IF ( RC /= HCO_SUCCESS ) THEN
     875           0 :                 msg = 'Duplicate container name: ' // TRIM( tagcName )
     876           0 :                 CALL HCO_ERROR( msg, RC, thisLoc=loc )
     877           0 :                 RETURN
     878             :              ENDIF
     879             : 
     880             :              ! Attributes used by all data types: data type number and
     881             :              ! container name.
     882           0 :              Lct%Dct%DctType = DctType
     883           0 :              Lct%Dct%cName   = ADJUSTL( tagcName )
     884             : 
     885             :              ! Set species name, extension number, emission category,
     886             :              ! hierarchy
     887           0 :              Lct%Dct%SpcName = ADJUSTL( SpcName )
     888           0 :              Lct%Dct%Hier    = Int2
     889           0 :              Lct%Dct%ExtNr   = Int3
     890             : 
     891             :              ! Extract category from character 2. This can be up to
     892             :              ! CatMax integers, or empty.
     893           0 :              CALL HCO_CharSplit( Char2, Separator, Wildcard, Cats, nCat, RC )
     894           0 :              IF ( RC /= HCO_SUCCESS ) THEN
     895           0 :                 msg = 'Could not extract category at line: ' // TRIM( char2 )
     896           0 :                 CALL HCO_Error( msg, RC, thisLoc=LOC )
     897           0 :                 RETURN
     898             :              ENDIF
     899           0 :              IF ( nCat == 0 ) THEN
     900           0 :                 Lct%Dct%Cat = -999
     901             :              ELSE
     902           0 :                 Lct%Dct%Cat = Cats(1)
     903             :              ENDIF
     904             : 
     905             :              ! Set scale factor IDs into Scal_cID. These values will be
     906             :              ! replaced lateron with the container IDs (in register_base)!
     907             :              CALL HCO_CharSplit( Char1, Separator, Wildcard, &
     908           0 :                                  SplitInts, nScl, RC )
     909           0 :              IF ( RC /= HCO_SUCCESS ) THEN
     910             :                 msg = 'Could not get scale factor ID''s in line: '        // &
     911           0 :                       TRIM( char1 )
     912           0 :                 CALL HCO_Error( msg, RC, thisLoc=loc )
     913           0 :                 RETURN
     914             :              ENDIF
     915           0 :              IF ( nScl > 0 ) THEN
     916           0 :                 ALLOCATE ( Lct%Dct%Scal_cID(nScl) )
     917           0 :                 Lct%Dct%Scal_cID(1:nScl) = SplitInts(1:nScl)
     918           0 :                 Lct%Dct%nScalID          = nScl
     919             :              ENDIF
     920             : 
     921             :              ! Register species name. A list of all species names can be
     922             :              ! returned to the atmospheric model to match HEMCO species
     923             :              ! with model species (see Config\_GetSpecNames).
     924           0 :              CALL SpecName_Register ( HcoConfig, ADJUSTL(SpcName), RC )
     925           0 :              IF ( RC /= HCO_SUCCESS ) THEN
     926           0 :                 msg = 'Could not register species name: ' // TRIM(SpcName)
     927           0 :                 CALL HCO_Error( msg, RC, thisLoc=loc )
     928           0 :                 RETURN
     929             :              ENDIF
     930             : 
     931             :              ! -------------------------------------------------------------
     932             :              ! Create and fill file data object. Use previous file data
     933             :              ! object if filename is undefined. Do not yet update the
     934             :              ! DoShare and DtaHome flags of the data file object and data
     935             :              ! container, respectively, since we still don't know which
     936             :              ! data containers will be effectively used for emission
     937             :              ! calculation (containers may be dropped lateron because the
     938             :              ! emission category / hierarchy is too low, species is not
     939             :              ! used, etc.). The DoShare and DtaHome flags will be set the
     940             :              ! first time that data is read (in hco_readlist_mod.F90).
     941             :              ! Here, we only set the DtaHome flag to -1000 instead of the
     942             :              ! default value of -999 to be able to identify data objects
     943             :              ! used by multiple containers.
     944             :              ! -------------------------------------------------------------
     945           0 :              IF ( TRIM( srcFile ) == '-' ) THEN
     946             : 
     947             :                 ! The current entry of the configuration file specifies that
     948             :                 ! we will get data from the file listed immediately above it.
     949             :                 ! Thus we have to reuse a previously-defined FileData object
     950             :                 ! (aka Dta).  Stop if Dta is not initialized.
     951           0 :                 IF ( .not. ASSOCIATED( Dta ) ) THEN
     952           0 :                    MSG = 'Cannot use previous data container: '//TRIM(tagcName)
     953           0 :                    CALL HCO_Error( msg, RC, thisLoc=loc )
     954           0 :                    RETURN
     955             :                 ENDIF
     956             : 
     957             :                 ! Reuse the file metadata specified in PrevDta for
     958             :                 ! this entry of the HEMCO configuration file.
     959           0 :                 Lct%Dct%DtaHome = Lct%Dct%DtaHome - 1
     960             : 
     961             :              ELSE
     962             : 
     963             :                 ! The current entry of the configuration file specifies that
     964             :                 ! we will read data from a file.  We thus need to initialize
     965             :                 ! a new FileData object to keep track of the file metadata.
     966             :                 !
     967             :                 ! >>> NOTE: This seems to cause a memory leak! <<<
     968             :                 ! >>> We will look into this at a later date.  <<<
     969           0 :                 CALL FileData_Init( Dta )
     970             : 
     971             :                 ! Set source file name. Check if the read file name starts
     972             :                 ! with the configuration file token '$CFDIR', in which case
     973             :                 ! we replace this value with the passed CFDIR value.
     974           0 :                 STRLEN = LEN( srcFile )
     975             :                 IF ( STRLEN > 6 ) THEN
     976           0 :                    IF ( srcFile(1:6) == '$CFDIR' ) THEN
     977           0 :                       srcFile = TRIM( CFDIR ) // TRIM( srcFile(7:STRLEN) )
     978             :                    ENDIF
     979             :                 ENDIF
     980           0 :                 Dta%ncFile   = srcFile
     981             : 
     982             :                 ! Set source variable and original data unit.
     983           0 :                 Dta%ncPara   = ADJUSTL( srcVar )
     984           0 :                 Dta%OrigUnit = ADJUSTL( srcUnit )
     985             : 
     986             :                 ! If the parameter ncPara is not defined, attempt to read data
     987             :                 ! directly from configuration file instead of netCDF.
     988             :                 ! These data are always assumed to be in local time. Gridded
     989             :                 ! data read from netCDF is always in UTC, except for weekdaily
     990             :                 ! data that is treated in local time. The corresponding
     991             :                 ! IsLocTime flag is updated when reading the data (see
     992             :                 ! hcoio_dataread_mod.F90).
     993           0 :                 IF ( TRIM( Dta%ncPara ) == '-' ) THEN
     994           0 :                    Dta%ncRead    = .FALSE.
     995           0 :                    Dta%IsLocTime = .TRUE.
     996             :                 ENDIF
     997             : 
     998             :                 ! Extract information from time stamp character and pass values
     999             :                 ! to the corresponding container variables. If no time string is
    1000             :                 ! defined, keep default values (-1 for all of them)
    1001           0 :                 IF ( TRIM(srcTime) /= '-' ) THEN
    1002           0 :                    CALL HCO_ExtractTime( HcoConfig, srcTime, Dta, RC )
    1003           0 :                    IF ( RC /= HCO_SUCCESS ) THEN
    1004           0 :                       msg = 'Could not extract time cycle information!'
    1005           0 :                       CALL HCO_Error( msg, RC, thisLoc=loc )
    1006           0 :                       RETURN
    1007             :                    ENDIF
    1008             :                 ENDIF
    1009             : 
    1010             : #if defined(ESMF_)
    1011             :                 ! In an ESMF environment, the source data will be imported
    1012             :                 ! through ExtData by name, hence need to set ncFile equal to
    1013             :                 ! container name!
    1014             :                 IF ( Dta%ncRead ) THEN
    1015             :                    Dta%ncFile = ADJUSTL( tagcName )
    1016             :                 ENDIF
    1017             : #endif
    1018             : 
    1019             :                 ! Update the properties of the data container
    1020             :                 ! NOTE: This routine abstracts the big IF/ELSE block that
    1021             :                 ! processes the time cycle information (bmy, 07 Mar 2022)
    1022             :                 CALL UpdateDtaProperties(                                    &
    1023             :                      dctType   = dctType,                                    &
    1024             :                      int3      = int3,                                       &
    1025             :                      char1     = TRIM( char1     ),                          &
    1026             :                      char2     = char2(1:1),                                 &
    1027             :                      tagCName  = TRIM( tagCName  ),                          &
    1028             :                      tmCycle   = TRIM( tmCycle   ),                          &
    1029             :                      separator = TRIM( separator ),                          &
    1030             :                      srcDim    = TRIM( srcDim    ),                          &
    1031             :                      wildCard  = TRIM( wildCard  ),                          &
    1032             :                      HcoConfig = HcoConfig,                                  &
    1033             :                      Lct       = Lct,                                        &
    1034             :                      Dta       = Dta,                                        &
    1035           0 :                      RC        = RC                                         )
    1036             : 
    1037             :                 ! Trap potential errors
    1038           0 :                 IF ( RC /= HCO_Success ) THEN
    1039           0 :                    MSG = 'Error encountered in routine "UpdateDtaProperties"'
    1040           0 :                    CALL HCO_Error( MSG, RC, thisLoc=loc )
    1041           0 :                    RETURN
    1042             :                 ENDIF
    1043             : 
    1044             :              ENDIF
    1045             : 
    1046             :              ! Connect this FileData object to the HcoState%HcoConfigList.
    1047           0 :              Lct%Dct%Dta => Dta
    1048             : 
    1049             :              ! Free list container for next cycle
    1050           0 :              Lct => NULL()
    1051             : 
    1052             :           ENDDO
    1053             : 
    1054             :        ! If no wildcard is present in variable name
    1055             :        ELSE
    1056             : 
    1057             :           ! -------------------------------------------------------------
    1058             :           ! Fill data container
    1059             :           ! -------------------------------------------------------------
    1060             : 
    1061             :           ! Add blank list container (ListCont object) to ConfigList.
    1062             :           ! The container is placed at the beginning of the list.
    1063           0 :           CALL ConfigList_AddCont ( Lct, HcoConfig%ConfigList )
    1064             : 
    1065             :           ! Check if name exists already
    1066           0 :           CALL CheckForDuplicateName( HcoConfig, cName, RC )
    1067           0 :           IF ( RC /= HCO_SUCCESS ) THEN
    1068           0 :              msg = 'Duplicate name: ' // TRIM( cName )
    1069           0 :              CALL HCO_Error( msg, RC, thisLoc=loc )
    1070           0 :              RETURN
    1071             :           ENDIF
    1072             : 
    1073             :           ! Attributes used by all data types: data type number and
    1074             :           ! container name.
    1075           0 :           Lct%Dct%DctType      = DctType
    1076           0 :           Lct%Dct%cName        = ADJUSTL(cName)
    1077             : 
    1078             :           ! Base container specific attributes
    1079           0 :           IF ( DctType == HCO_DCTTYPE_BASE ) THEN
    1080             : 
    1081             :              ! Set species name, extension number, emission category,
    1082             :              ! hierarchy
    1083           0 :              Lct%Dct%SpcName = ADJUSTL( SpcName )
    1084           0 :              Lct%Dct%Hier    = Int2
    1085           0 :              Lct%Dct%ExtNr   = Int3
    1086             : 
    1087             :              ! Extract category from character 2. This can be up to
    1088             :              ! CatMax integers, or empty.
    1089           0 :              CALL HCO_CharSplit( Char2, Separator, Wildcard, Cats, nCat, RC )
    1090           0 :              IF ( RC /= HCO_SUCCESS ) THEN
    1091           0 :                 msg = 'Could not extract category from: ' // TRIM( char2 )
    1092           0 :                  CALL HCO_Error( msg, RC, thisLoc=loc )
    1093           0 :                  RETURN
    1094             :              ENDIF
    1095           0 :              IF ( nCat == 0 ) THEN
    1096           0 :                 Lct%Dct%Cat = -999
    1097             :              ELSE
    1098           0 :                 Lct%Dct%Cat = Cats(1)
    1099             :              ENDIF
    1100             : 
    1101             :              ! Set scale factor IDs into Scal_cID. These values will be
    1102             :              ! replaced lateron with the container IDs (in register_base)!
    1103             :              CALL HCO_CharSplit( Char1, Separator, Wildcard, &
    1104           0 :                                  SplitInts, nScl, RC )
    1105           0 :              IF ( RC /= HCO_SUCCESS ) THEN
    1106           0 :                 msg = 'Could not get scale factor IDs from: ' // TRIM( char1 )
    1107           0 :                 CALL HCO_Error( msg, RC, thisLoc=loc )
    1108           0 :                 RETURN
    1109             :              ENDIF
    1110           0 :              IF ( nScl > 0 ) THEN
    1111           0 :                 ALLOCATE ( Lct%Dct%Scal_cID(nScl) )
    1112           0 :                 Lct%Dct%Scal_cID(1:nScl) = SplitInts(1:nScl)
    1113           0 :                 Lct%Dct%nScalID          = nScl
    1114             :              ENDIF
    1115             : 
    1116             :              ! Register species name. A list of all species names can be
    1117             :              ! returned to the atmospheric model to match HEMCO species
    1118             :              ! with model species (see Config\_GetSpecNames).
    1119           0 :              CALL SpecName_Register ( HcoConfig, ADJUSTL(SpcName), RC )
    1120           0 :              IF ( RC /= HCO_SUCCESS ) THEN
    1121           0 :                 msg = 'Could not register species: ' // TRIM( SpcName )
    1122           0 :                 CALL HCO_ERROR( msg, RC, thisLoc=loc )
    1123           0 :                 RETURN
    1124             :              ENDIF
    1125             : 
    1126             :           ! Scale factor & mask specific attributes
    1127           0 :           ELSE IF ( DctType == HCO_DCTTYPE_SCAL .OR. &
    1128             :                     DctType == HCO_DCTTYPE_MASK       ) THEN
    1129             : 
    1130             :              ! Set scale factor ID and data operator
    1131           0 :              Lct%Dct%ScalID = Int1
    1132           0 :              Lct%Dct%Oper   = Int2
    1133             : 
    1134             :              ! Make sure that negative scale factors are always read
    1135           0 :              IF ( Lct%Dct%ScalID < 0 ) THEN
    1136           0 :                 CALL ScalID2List( HcoConfig%ScalIDList, Lct%Dct%ScalID, RC )
    1137           0 :                 IF ( RC /= HCO_SUCCESS ) THEN
    1138             :                    msg = 'Could not make sure that negative scale '       // &
    1139           0 :                          'are always read!'
    1140           0 :                    CALL HCO_Error( msg, RC, thisLoc=loc )
    1141           0 :                    RETURN
    1142             :                 ENDIF
    1143             :              ENDIF
    1144             : 
    1145             :           ELSE
    1146           0 :              msg = 'Invalid data type!'
    1147           0 :              CALL HCO_Error( msg, RC, thisLoc=loc )
    1148           0 :              RETURN
    1149             :           ENDIF
    1150             : 
    1151             :           ! -------------------------------------------------------------
    1152             :           ! Create and fill file data object. Use previous file data
    1153             :           ! object if filename is undefined. Do not yet update the
    1154             :           ! DoShare and DtaHome flags of the data file object and data
    1155             :           ! container, respectively, since we still don't know which
    1156             :           ! data containers will be effectively used for emission
    1157             :           ! calculation (containers may be dropped lateron because the
    1158             :           ! emission category / hierarchy is too low, species is not
    1159             :           ! used, etc.). The DoShare and DtaHome flags will be set the
    1160             :           ! first time that data is read (in hco_readlist_mod.F90).
    1161             :           ! Here, we only set the DtaHome flag to -1000 instead of the
    1162             :           ! default value of -999 to be able to identify data objects
    1163             :           ! used by multiple containers.
    1164             :           ! -------------------------------------------------------------
    1165           0 :           IF ( TRIM( srcFile ) == '-' ) THEN
    1166             : 
    1167             :              ! The current entry of the configuration file specifies that
    1168             :              ! we will get data from the file listed immediately above it.
    1169             :              ! Thus we have to reuse a previously-defined FileData object
    1170             :              ! (aka Dta).  Stop if Dta is not initialized.
    1171           0 :              IF ( .NOT. ASSOCIATED(Dta) ) THEN
    1172           0 :                 MSG = 'Cannot use previous data container: '//TRIM(cName)
    1173           0 :                 CALL HCO_Error( msg, RC, thisLoc=loc)
    1174           0 :                 RETURN
    1175             :              ENDIF
    1176             : 
    1177             :              ! Reuse the file metadata specified in Dta for
    1178             :              ! this entry of the HEMCO configuration file.
    1179           0 :              Lct%Dct%DtaHome = Lct%Dct%DtaHome - 1
    1180             : 
    1181             :           ELSE
    1182             : 
    1183             :              ! The current entry of the configuration file specifies that
    1184             :              ! we will read data from a file.  We thus need to initialize
    1185             :              ! a new FileData object to keep track of the file metadata.
    1186             :              !
    1187             :              ! >>> NOTE: This seems to cause a memory leak; <<<
    1188             :              ! >>> We will look into this at a later date   <<<
    1189           0 :              CALL FileData_Init( Dta )
    1190             : 
    1191             :              ! Set source file name. Check if the read file name starts
    1192             :              ! with the configuration file token '$CFDIR', in which case
    1193             :              ! we replace this value with the passed CFDIR value.
    1194           0 :              STRLEN = LEN( srcFile )
    1195             :              IF ( STRLEN > 6 ) THEN
    1196           0 :                 IF ( srcFile(1:6) == '$CFDIR' ) THEN
    1197           0 :                    srcFile = TRIM( CFDIR ) // TRIM( srcFile(7:STRLEN) )
    1198             :                 ENDIF
    1199             :              ENDIF
    1200           0 :              Dta%ncFile   = srcFile
    1201             : 
    1202             :              ! Set source variable and original data unit.
    1203           0 :              Dta%ncPara   = ADJUSTL( srcVar  )
    1204           0 :              Dta%OrigUnit = ADJUSTL( srcUnit )
    1205             : 
    1206             :              ! If the parameter ncPara is not defined, attempt to read data
    1207             :              ! directly from configuration file instead of netCDF.
    1208             :              ! These data are always assumed to be in local time. Gridded
    1209             :              ! data read from netCDF is always in UTC, except for weekdaily
    1210             :              ! data that is treated in local time. The corresponding
    1211             :              ! IsLocTime flag is updated when reading the data (see
    1212             :              ! hcoio_dataread_mod.F90).
    1213           0 :              IF ( TRIM( Dta%ncPara ) == '-' ) THEN
    1214           0 :                 Dta%ncRead    = .FALSE.
    1215           0 :                 Dta%IsLocTime = .TRUE.
    1216             :              ENDIF
    1217             : 
    1218             :              ! Extract information from time stamp character and pass values
    1219             :              ! to the corresponding container variables. If no time string is
    1220             :              ! defined, keep default values (-1 for all of them)
    1221           0 :              IF ( TRIM(srcTime) /= '-' ) THEN
    1222           0 :                 CALL HCO_ExtractTime( HcoConfig, srcTime, Dta, RC )
    1223           0 :                 IF ( RC /= HCO_SUCCESS ) THEN
    1224           0 :                    msg = 'Could not extract time information!'
    1225           0 :                    CALL HCO_Error( msg, RC, thisLoc=loc )
    1226           0 :                    RETURN
    1227             :                 ENDIF
    1228             :              ENDIF
    1229             : 
    1230             : #if defined(ESMF_)
    1231             :              ! In an ESMF environment, the source data will be imported
    1232             :              ! through ExtData by name, hence need to set ncFile equal to
    1233             :              ! container name!
    1234             :              IF ( Dta%ncRead ) THEN
    1235             :                 Dta%ncFile = ADJUSTL( cName )
    1236             :              ENDIF
    1237             : #endif
    1238             : 
    1239             :              ! Update the properties of the data container
    1240             :              ! NOTE: This routine abstracts the big IF/ELSE block that
    1241             :              ! processes the time cycle information (bmy, 07 Mar 2022)
    1242             :              CALL UpdateDtaProperties(                                    &
    1243             :                   dctType   = dctType,                                    &
    1244             :                   int3      = int3,                                       &
    1245             :                   char1     = TRIM( char1     ),                          &
    1246             :                   char2     = char2(1:1),                                 &
    1247             :                   tagCName  = TRIM( tagCName  ),                          &
    1248             :                   tmCycle   = TRIM( tmCycle   ),                          &
    1249             :                   separator = TRIM( separator ),                          &
    1250             :                   srcDim    = TRIM( srcDim    ),                          &
    1251             :                   wildCard  = TRIM( wildCard  ),                          &
    1252             :                   HcoConfig = HcoConfig,                                  &
    1253             :                   Lct       = Lct,                                        &
    1254             :                   Dta       = Dta,                                        &
    1255           0 :                   RC        = RC                                         )
    1256             : 
    1257             :              ! Trap potential errors
    1258           0 :              IF ( RC /= HCO_Success ) THEN
    1259           0 :                 MSG = 'Error encountered in routine "UpdateDtaProperties"'
    1260           0 :                 CALL HCO_Error( MSG, RC, thisLoc=loc )
    1261           0 :                 RETURN
    1262             :              ENDIF
    1263             : 
    1264             :           ENDIF
    1265             : 
    1266             :           ! Connect FileData object to the HcoState%HcoConfigList
    1267           0 :           Lct%Dct%Dta => Dta
    1268             : 
    1269             :           ! If a base emission field covers multiple emission categories,
    1270             :           ! create a 'shadow' container for each additional category.
    1271             :           ! These shadow container have the same information as the main
    1272             :           ! container except that a scale factor of zero will be applied in
    1273             :           ! addition. This makes sure that the inventory cancels out other
    1274             :           ! inventories with lower hierarchy for every specified category,
    1275             :           ! while emission totals are not changed. All emissions of a base
    1276             :           ! field with multiple categories is written into the category
    1277             :           ! listed first.
    1278           0 :           IF ( nCat > 1 ) THEN
    1279             : 
    1280             :              ! nCat cannot exceed CatMax
    1281           0 :              IF ( nCat > CatMax ) THEN
    1282           0 :                 MSG = 'Exceeded maximum number of categories!'
    1283           0 :                 CALL HCO_Error( msg, RC, thisLoc=loc )
    1284           0 :                 RETURN
    1285             :              ENDIF
    1286             : 
    1287           0 :              CALL AddShadowFields( HcoConfig, Lct, Cats, nCat, RC )
    1288           0 :              IF ( RC /= HCO_SUCCESS ) THEN
    1289           0 :                 msg = 'Could not create shadow emission container!'
    1290           0 :                 CALL HCO_ERROR( msg, RC, thisLoc=loc )
    1291           0 :                 RETURN
    1292             :              ENDIF
    1293             : 
    1294             :              ! Reset nCat
    1295           0 :              nCat = -1
    1296             :           ENDIF
    1297             : 
    1298             :           ! Free list container for next cycle
    1299           0 :           Lct => NULL()
    1300             : 
    1301             :        ENDIF
    1302             : 
    1303             :     ENDDO
    1304             : 
    1305             :     ! Leave w/ success
    1306           0 :     Dta => NULL()
    1307           0 :     RC  =  HCO_SUCCESS
    1308             : 
    1309             :   END SUBROUTINE Config_ReadCont
    1310             : !EOC
    1311             : !------------------------------------------------------------------------------
    1312             : !                   Harmonized Emissions Component (HEMCO)                    !
    1313             : !------------------------------------------------------------------------------
    1314             : !BOP
    1315             : !
    1316             : ! !IROUTINE: BracketCheck
    1317             : !
    1318             : ! !DESCRIPTION: Subroutine BracketCheck checks if base emission data is within
    1319             : ! a bracket and if that field shall be ignored or not. Brackets can be used to
    1320             : ! lump entires of the HEMCO configuration file into collections that can be
    1321             : ! collectively enabled or disabled. The first entry of a collection is marked
    1322             : ! adding an 'opening bracket' to the HEMCO configuration file (on the line
    1323             : ! above the entry). Opening brackets must start with three opening brackets,
    1324             : ! e.g.: '(((TEST'. Similarly, the end of a collection is marked by placing a
    1325             : ! closing bracket after the last entry of the collection: '))))TEST'.
    1326             : ! Brackets can be enabled / disabled in the EXTENSION SWITCH section of the
    1327             : ! HEMCO configuration file:
    1328             : ! \# ExtNr ExtName           on/off  Species
    1329             : ! 0       Base              : on    *
    1330             : !     --> TEST              :       true
    1331             : !\\
    1332             : !\\
    1333             : ! It is also possible to use 'opposite' brackets, e.g. to use a collection
    1334             : ! only if the given setting is *disabled*. This can be achieved by precede
    1335             : ! the collection word with '.not.', e.g. '(((.not.TEST' and '))).not.TEST'.
    1336             : ! Similarly, multiple collections can be combined to be evaluated together,
    1337             : ! e.g. NAME1.or.NAME2.
    1338             : !\\
    1339             : !\\
    1340             : ! !INTERFACE:
    1341             : !
    1342           0 :   SUBROUTINE BracketCheck( HcoConfig, STAT, LINE, SKIP, RC )
    1343             : !
    1344             : ! !USES:
    1345             : !
    1346             :     USE HCO_EXTLIST_MOD,  ONLY : GetExtOpt, GetExtNr
    1347             : !
    1348             : ! !INPUT PARAMETERS:
    1349             : !
    1350             :     INTEGER,          INTENT(IN)    :: STAT        !
    1351             :     CHARACTER(LEN=*), INTENT(IN)    :: LINE        !
    1352             : !
    1353             : ! !INPUT/OUTPUT PARAMETERS:
    1354             : !
    1355             :     TYPE(ConfigObj),  POINTER       :: HcoConfig ! Config object
    1356             :     LOGICAL,          INTENT(INOUT) :: SKIP        ! Skip
    1357             :     INTEGER,          INTENT(INOUT) :: RC          ! Success/failure
    1358             : !
    1359             : ! !REVISION HISTORY:
    1360             : !  15 Feb 2015 - C. Keller   - Initial version.
    1361             : !  See https://github.com/geoschem/hemco for complete history
    1362             : !EOP
    1363             : !------------------------------------------------------------------------------
    1364             : !BOC
    1365             : !
    1366             : ! !LOCAL VARIABLES:
    1367             : !
    1368             :     ! Maximum number of nested brackets
    1369             :     INTEGER, PARAMETER            :: MAXBRACKNEST = 10
    1370             :     INTEGER                       :: IDX, STRLEN, ExtNr
    1371             :     LOGICAL                       :: FOUND
    1372             :     LOGICAL                       :: UseBracket, UseThis
    1373             :     LOGICAL                       :: verb
    1374             :     LOGICAL                       :: REV
    1375             :     INTEGER, SAVE                 :: NEST      = 0
    1376             :     INTEGER, SAVE                 :: SKIPLEVEL = 0
    1377             :     CHARACTER(LEN=255), SAVE      :: AllBrackets(MAXBRACKNEST) = ''
    1378             :     CHARACTER(LEN=255)            :: TmpBracket, CheckBracket, ThisBracket
    1379             :     CHARACTER(LEN=512)            :: msg
    1380             : 
    1381             :     CHARACTER(LEN=255), PARAMETER :: LOC = 'BracketCheck (hco_config_mod.F90)'
    1382             : 
    1383             :     !======================================================================
    1384             :     ! BracketCheck begins here
    1385             :     !======================================================================
    1386             : 
    1387             :     ! Init
    1388           0 :     verb = HCO_IsVerb( HcoConfig%Err )
    1389             : 
    1390             :     ! Get name of this bracket
    1391           0 :     IF ( STAT == 5 .OR. STAT == 6 ) THEN
    1392           0 :        STRLEN     = LEN(LINE)
    1393           0 :        IF ( STRLEN < 4 ) THEN
    1394           0 :           msg = 'Illegal bracket length: ' // TRIM(line)
    1395           0 :           CALL HCO_ERROR ( msg, RC, thisLoc=loc )
    1396           0 :           RETURN
    1397             :        ELSE
    1398           0 :           TmpBracket = TRIM(LINE(4:STRLEN))
    1399             :        ENDIF
    1400             :     ENDIF
    1401             : 
    1402             :     ! Open a bracket. Save out the bracket name in the list of all
    1403             :     ! opened brackets. This is primarily to ensure that every opening
    1404             :     ! brackets is properly closed. Only register it as skipping bracket
    1405             :     ! if needed.
    1406           0 :     IF ( STAT == 5 ) THEN
    1407             : 
    1408             :        ! Archive bracket name
    1409           0 :        NEST = NEST + 1
    1410           0 :        IF ( NEST > MAXBRACKNEST ) THEN
    1411           0 :           MSG = 'Too many nested brackets'
    1412           0 :           CALL HCO_Error( msg, RC, thisLoc=LOC )
    1413           0 :           RETURN
    1414             :        ENDIF
    1415           0 :        AllBrackets(NEST) = TmpBracket
    1416             : 
    1417             :        ! Check if this bracket content shall be skipped. Always skip
    1418             :        ! if this is a nested bracket in an already skipped bracket.
    1419           0 :        IF ( .NOT. SKIP ) THEN
    1420             : 
    1421             :           ! Check for 'inverse' bracket. These start with '.not.'
    1422           0 :           CheckBracket = TmpBracket
    1423           0 :           REV          = .FALSE.
    1424           0 :           IF ( STRLEN > 5 ) THEN
    1425           0 :              IF ( TmpBracket(1:5) == '.not.' ) THEN
    1426           0 :                 STRLEN       = LEN(TmpBracket)
    1427           0 :                 CheckBracket = TmpBracket(6:STRLEN)
    1428           0 :                 REV          = .TRUE.
    1429             :              ENDIF
    1430             :           ENDIF
    1431             : 
    1432             :           ! Check if the evaluation of CheckBracket returns true, i.e.
    1433             :           ! if any of the elements of CheckBracket is enabled. These
    1434             :           ! can be multiple settings separated by '.or.'.
    1435             :           ! By default, don't use the content of the bracket
    1436           0 :           UseBracket = .FALSE.
    1437             : 
    1438             :           ! Make sure variable ThisBracket is initialized. Needed in the
    1439             :           ! DO loop below
    1440           0 :           ThisBracket = ''
    1441             : 
    1442             :           ! Pack the following into a DO loop to check for multiple
    1443             :           ! flags separated by '.or.'.
    1444             :           DO
    1445             : 
    1446             :              ! Leave do loop if ThisBracket is equal to CheckBracket.
    1447             :              ! In this case, the entire bracket has already been
    1448             :              ! evaluated.
    1449           0 :              IF ( TRIM(CheckBracket) == TRIM(ThisBracket) ) EXIT
    1450             : 
    1451             :              ! Evaluate bracket for '.or.':
    1452           0 :              IDX = INDEX(TRIM(CheckBracket),'.or.')
    1453             : 
    1454             :              ! If '.or.' is a substring of the whole bracket, get
    1455             :              ! substring up to the first '.or.' and write it into variable
    1456             :              ! ThisBracket, which will be evaluated below. The tail
    1457             :              ! (everything after the first '.or.') is written into
    1458             :              ! CheckBracket.
    1459           0 :              IF ( IDX > 0 ) THEN
    1460           0 :                 ThisBracket  = CheckBracket(1:(IDX-1))
    1461           0 :                 STRLEN       = LEN(CheckBracket)
    1462           0 :                 CheckBracket = CheckBracket((IDX+4):STRLEN)
    1463             : 
    1464             :              ! If there is no '.or.' in the bracket, simply evaluate the
    1465             :              ! whole bracket.
    1466             :              ELSE
    1467           0 :                 ThisBracket = CheckBracket
    1468             :              ENDIF
    1469             : 
    1470             :              ! Check if this bracket has been registered as being used.
    1471             :              ! Scan all extensions, including the core one.
    1472             :              CALL GetExtOpt( HcoConfig, -999, TRIM(ThisBracket), &
    1473           0 :                 OptValBool=UseThis, FOUND=FOUND, RC=RC )
    1474           0 :              IF ( RC /= HCO_SUCCESS ) THEN
    1475           0 :                 msg = 'Error when checking '// TRIM( thisBracket ) // '!'
    1476           0 :                 CALL HCO_Error( msg, RC, thisLoc=loc )
    1477           0 :                 RETURN
    1478             :              ENDIF
    1479             : 
    1480             :              ! If bracket name was found in options, update the UseBracket
    1481             :              ! variable accordingly.
    1482           0 :              IF ( FOUND ) THEN
    1483           0 :                 UseBracket = UseThis
    1484             : 
    1485             :              ! If bracket name was not found, check if this is an extension
    1486             :              ! name
    1487             :              ELSE
    1488           0 :                 ExtNr = GetExtNr( HcoConfig%ExtList, TRIM(ThisBracket) )
    1489           0 :                 IF ( ExtNr > 0 ) THEN
    1490           0 :                    UseBracket = .TRUE.
    1491             :                 ENDIF
    1492             : 
    1493             :              ENDIF
    1494             : 
    1495             :              ! As soon as UseBracket is true, we don't need to evaluate
    1496             :              ! further
    1497           0 :              IF ( UseBracket ) EXIT
    1498             : 
    1499             :           ENDDO
    1500             : 
    1501             :           ! We need to skip the content of this bracket?
    1502           0 :           SKIP = .NOT. UseBracket
    1503             : 
    1504             :           ! Eventually reverse the skip flag
    1505           0 :           IF ( REV ) THEN
    1506           0 :              SKIP = .NOT. SKIP
    1507             :           ENDIF
    1508             : 
    1509             :           ! If bracket is skipped, adjust skip level accordingly.
    1510             :           ! This is so that we know when it's time to flip back to
    1511             :           ! a bracket that is being used (if brackets are nested).
    1512           0 :           IF ( SKIP ) THEN
    1513           0 :              SKIPLEVEL = NEST
    1514             :           ENDIF
    1515             :        ENDIF
    1516             : 
    1517             :        ! Verbose mode
    1518           0 :        IF ( verb ) THEN
    1519           0 :           MSG = 'Opened shortcut bracket: '//TRIM(TmpBracket)
    1520           0 :           CALL HCO_MSG( HcoConfig%Err, msg )
    1521           0 :           WRITE(MSG,*) ' - Skip content of this bracket: ', SKIP
    1522           0 :           CALL HCO_MSG( HcoConfig%Err, msg )
    1523             :        ENDIF
    1524             :     ENDIF
    1525             : 
    1526             :     ! Close a bracket
    1527           0 :     IF ( STAT == 6 ) THEN
    1528             : 
    1529             :        ! This must be the latest opened bracket
    1530           0 :        IF ( TRIM(TmpBracket) /= TRIM(AllBrackets(NEST)) ) THEN
    1531             :           MSG = 'Closing bracket does not match opening bracket: '// &
    1532           0 :              TRIM(TmpBracket)//', expected: '//TRIM(AllBrackets(NEST))
    1533           0 :           CALL HCO_Error( msg, RC, thisLoc=LOC )
    1534           0 :           RETURN
    1535             :        ENDIF
    1536             : 
    1537             :        ! If that was the latest opened bracket that was disabled
    1538           0 :        IF ( SKIPLEVEL == NEST ) THEN
    1539           0 :           SKIP = .FALSE.
    1540             :        ENDIF
    1541             : 
    1542             :        ! Update nesting level
    1543           0 :        AllBrackets(NEST) = ''
    1544           0 :        NEST              = NEST - 1
    1545             : 
    1546             :        ! Verbose mode
    1547           0 :        IF ( verb ) THEN
    1548           0 :           MSG = 'Closed shortcut bracket: '//TRIM(TmpBracket)
    1549           0 :           CALL HCO_MSG( HcoConfig%Err, msg )
    1550           0 :           WRITE(MSG,*) ' - Skip following lines: ', SKIP
    1551           0 :           CALL HCO_MSG( HcoConfig%Err, msg )
    1552             :        ENDIF
    1553             :     ENDIF
    1554             : 
    1555             :     ! Return w/ success
    1556           0 :     RC = HCO_SUCCESS
    1557             : 
    1558             :   END SUBROUTINE BracketCheck
    1559             : !EOC
    1560             : !------------------------------------------------------------------------------
    1561             : !                   Harmonized Emissions Component (HEMCO)                    !
    1562             : !------------------------------------------------------------------------------
    1563             : !BOP
    1564             : !
    1565             : ! !IROUTINE: AddShadowFields
    1566             : !
    1567             : ! !DESCRIPTION: Subroutine AddShadowFields adds a shadow container for every
    1568             : ! additional category of a base emission field. These container contain the
    1569             : ! same container as the 'mother' container, but an additional scale factor
    1570             : ! of zero will be applied to them. This makes sure that no additional emissions
    1571             : ! are created by the virtue of the shadow container.
    1572             : !\\
    1573             : !\\
    1574             : ! !INTERFACE:
    1575             : !
    1576           0 :   SUBROUTINE AddShadowFields( HcoConfig, Lct, Cats, nCat, RC )
    1577             : !
    1578             : ! !USES:
    1579             : !
    1580             :     USE HCO_DATACONT_MOD,  ONLY : CatMax, ZeroScalID
    1581             : !
    1582             : ! !INPUT PARAMETERS:
    1583             : !
    1584             :     TYPE(ConfigObj), POINTER        :: HcoConfig    ! Config object
    1585             :     TYPE(ListCont),  POINTER        :: Lct          ! List container of interest
    1586             :     INTEGER,         INTENT(IN)     :: Cats(CatMax) ! Category numbers
    1587             :     INTEGER,         INTENT(IN)     :: nCat         ! number of categories
    1588             : !
    1589             : ! !INPUT/OUTPUT PARAMETERS:
    1590             : !
    1591             :     INTEGER,        INTENT(INOUT)  :: RC           ! Success/failure
    1592             : !
    1593             : ! !REVISION HISTORY:
    1594             : !  15 Feb 2015 - C. Keller   - Initial version.
    1595             : !  See https://github.com/geoschem/hemco for complete history
    1596             : !EOP
    1597             : !------------------------------------------------------------------------------
    1598             : !BOC
    1599             : !
    1600             : ! !LOCAL VARIABLES:
    1601             : !
    1602             :     LOGICAL                       :: verb
    1603             :     INTEGER                       :: I, N
    1604             :     TYPE(ListCont), POINTER       :: Shd
    1605             :     CHARACTER(LEN=512)            :: msg
    1606             :     CHARACTER(LEN=5)              :: C5
    1607             : 
    1608             :     CHARACTER(LEN=255), PARAMETER :: LOC   = 'AddShadowFields (hco_config_mod.F90)'
    1609             : 
    1610             :     !======================================================================
    1611             :     ! AddShadowFields begins here
    1612             :     !======================================================================
    1613             : 
    1614             :     ! Nothing to do if ncat is only 1
    1615           0 :     IF ( nCat <= 1 ) THEN
    1616           0 :        RC = HCO_SUCCESS
    1617           0 :        RETURN
    1618             :     ENDIF
    1619             : 
    1620             :     ! Init
    1621           0 :     verb = HCO_IsVerb( HcoConfig%Err )
    1622           0 :     Shd  => NULL()
    1623             : 
    1624             : 
    1625             : !    ! Get number of currently used scale factors
    1626             : !    N = 0
    1627             : !    DO I = 1, SclMax
    1628             : !       IF ( Lct%Dct%Scal_cID(I) < 0 ) EXIT
    1629             : !       N = N + 1
    1630             : !    ENDDO
    1631             : !
    1632             : !    ! There has to be space for scale factor zero.
    1633             : !    IF ( N >= SclMax ) THEN
    1634             : !       MSG = 'Cannot add shadow scale factor (zeros) - : ' // &
    1635             : !             'All scale factors already used: ' // TRIM(Lct%Dct%cName)
    1636             : !       CALL HCO_ERROR ( MSG, RC, THISLOC=LOC )
    1637             : !       RETURN
    1638             : !    ENDIF
    1639             : 
    1640             :     ! Get number of scale factor IDs. Will add one more scale factor of
    1641             :     ! zero to this list.
    1642           0 :     N = Lct%Dct%nScalID
    1643             : 
    1644             :     ! Create 'shadow' container for every additional category.
    1645             :     ! Add scale factor zero to it, so that emissions will all be zero.
    1646           0 :     DO I = 2, nCat
    1647             : 
    1648             :        ! Create new data container (ListCont object)
    1649           0 :        CALL ConfigList_AddCont ( Shd, HcoConfig%ConfigList )
    1650             : 
    1651             :        ! Character of category
    1652           0 :        Write(C5,'(I5.5)') Cats(I)
    1653             : 
    1654             :        ! Shadow variables. Append category name to name
    1655           0 :        Shd%Dct%DctType       = Lct%Dct%DctType
    1656           0 :        Shd%Dct%cName         = TRIM(Lct%Dct%cName) // '_Cat' // TRIM(C5)
    1657           0 :        Shd%Dct%SpcName       = Lct%Dct%SpcName
    1658           0 :        Shd%Dct%Hier          = Lct%Dct%Hier
    1659           0 :        Shd%Dct%ExtNr         = Lct%Dct%ExtNr
    1660           0 :        Shd%Dct%Cat           = Cats(I)
    1661             : 
    1662             :        ! Pass scale factors, add scale factor of zero to it
    1663           0 :        ALLOCATE ( Shd%Dct%Scal_cID(N+1) )
    1664           0 :        IF ( N > 0 ) THEN
    1665           0 :           Shd%Dct%Scal_cID(1:N) = Lct%Dct%Scal_cID(1:N)
    1666             :        ENDIF
    1667           0 :        Shd%Dct%Scal_cID(N+1) = ZeroScalID
    1668           0 :        Shd%Dct%nScalID       = N + 1
    1669             : 
    1670             :        ! Connect to data from main container. Make sure the new container
    1671             :        ! is not identified as the home container (only points to the file
    1672             :        ! data container of another data container.
    1673           0 :        Shd%Dct%DtaHome =  Shd%Dct%DtaHome - 1
    1674           0 :        Shd%Dct%Dta     => Lct%Dct%Dta
    1675             : 
    1676             :        ! verbose mode
    1677           0 :        IF ( verb ) THEN
    1678           0 :           MSG = 'Created shadow base emission field: ' // TRIM(Shd%Dct%cName)
    1679           0 :           CALL HCO_MSG( HcoConfig%Err, msg )
    1680             :        ENDIF
    1681             : 
    1682             :        ! Cleanup
    1683           0 :        Shd => NULL()
    1684             :     ENDDO !I
    1685             : 
    1686             :     ! Add zero scale factor container
    1687           0 :     CALL AddZeroScal( HcoConfig, RC )
    1688           0 :     IF ( RC /= HCO_SUCCESS ) THEN
    1689           0 :        msg = 'Call to AddZeroScal could not add zero scale factor container!'
    1690           0 :        CALL HCO_Error( msg, RC, thisLoc=loc )
    1691           0 :        RETURN
    1692             :     ENDIF
    1693             : 
    1694             :     ! Return w/ success
    1695           0 :     RC = HCO_SUCCESS
    1696             : 
    1697             :   END SUBROUTINE AddShadowFields
    1698             : !EOC
    1699             : !------------------------------------------------------------------------------
    1700             : !                   Harmonized Emissions Component (HEMCO)                    !
    1701             : !------------------------------------------------------------------------------
    1702             : !BOP
    1703             : !
    1704             : ! !IROUTINE: AddZeroScal
    1705             : !
    1706             : ! !DESCRIPTION: Subroutine AddZeroScal adds a scale factor of zero to the
    1707             : ! configuration container list. This scale factor is an internal scale factor
    1708             : ! used in combination with the 'shadow' containers. Its scale factor ID is
    1709             : ! defined in Hco\_DataCont\_Mod and must not be used otherwise, e.g. there
    1710             : ! must not be another scale factor in the HEMCO configuration file with the
    1711             : ! same scale factor ID. Otherwise, HEMCO will create an error lateron.
    1712             : !\\
    1713             : !\\
    1714             : ! !INTERFACE:
    1715             : !
    1716           0 :   SUBROUTINE AddZeroScal( HcoConfig, RC )
    1717             : !
    1718             : ! !USES:
    1719             : !
    1720             :     USE HCO_DATACONT_MOD,  ONLY : ZeroScalID
    1721             :     USE HCO_DATACONT_MOD,  ONLY : ListCont_Find
    1722             :     USE HCO_FILEDATA_MOD,  ONLY : FileData_Init
    1723             : !
    1724             : ! !INPUT PARAMETERS:
    1725             : !
    1726             :     TYPE(ConfigObj), POINTER       :: HcoConfig   ! Config object
    1727             : !
    1728             : ! !INPUT/OUTPUT PARAMETERS:
    1729             : !
    1730             :     INTEGER, INTENT(INOUT)         :: RC          ! Success/failure
    1731             : !
    1732             : ! !REVISION HISTORY:
    1733             : !  15 Feb 2015 - C. Keller   - Initial version.
    1734             : !  See https://github.com/geoschem/hemco for complete history
    1735             : !EOP
    1736             : !------------------------------------------------------------------------------
    1737             : !BOC
    1738             : !
    1739             : ! !LOCAL VARIABLES:
    1740             : !
    1741             :     TYPE(ListCont), POINTER       :: Lct
    1742             :     TYPE(FileData), POINTER       :: Dta
    1743             :     CHARACTER(LEN=255)            :: MSG
    1744             : 
    1745             :     LOGICAL                       :: FOUND
    1746             :     CHARACTER(LEN=255), PARAMETER :: LOC   = 'AddZeroScal (hco_config_mod.F90)'
    1747             : 
    1748             :     !======================================================================
    1749             :     ! AddZeroScal begins here
    1750             :     !======================================================================
    1751             : 
    1752             :     ! Initialize
    1753           0 :     Lct => NULL()
    1754           0 :     Dta => NULL()
    1755             : 
    1756             :     ! Check if this container already exists
    1757           0 :     CALL ListCont_Find ( HcoConfig%ConfigList, 'DUMMYSCALE_ZERO', FOUND )
    1758             : 
    1759             :     ! Only do on first call
    1760           0 :     IF ( .NOT. FOUND ) THEN
    1761             : 
    1762             :        ! Add new container to configuration list and set data container
    1763             :        ! attributes.
    1764           0 :        CALL ConfigList_AddCont ( Lct, HcoConfig%ConfigList )
    1765           0 :        Lct%Dct%DctType      = HCO_DCTTYPE_SCAL
    1766           0 :        Lct%Dct%cName        = 'DUMMYSCALE_ZERO'
    1767           0 :        Lct%Dct%ScalID       = ZeroScalID
    1768           0 :        Lct%Dct%Oper         = 1
    1769             : 
    1770             :        ! Create new file data container and fill it with values.
    1771           0 :        CALL FileData_Init ( Dta )
    1772           0 :        Dta%ncFile    = '0.0'
    1773           0 :        Dta%ncPara    = '-'
    1774           0 :        Dta%OrigUnit  = 'unitless'
    1775           0 :        Dta%CycleFlag = HCO_CFLAG_CYCLE
    1776           0 :        Dta%SpaceDim  = 2
    1777           0 :        Dta%ncRead    = .FALSE.
    1778           0 :        Dta%IsLocTime = .TRUE.
    1779             : 
    1780             :        ! Connect data container
    1781           0 :        Lct%Dct%Dta => Dta
    1782             : 
    1783             :        ! verbose mode
    1784           0 :        IF ( HCO_IsVerb( HcoConfig%Err ) ) THEN
    1785           0 :           MSG = 'Created a fake scale factor with zeros'
    1786           0 :           CALL HCO_MSG(HcoConfig%Err,MSG)
    1787             :           MSG = 'This field will be used to artificially expand ' // &
    1788           0 :                 'over multiple emission categories'
    1789           0 :           CALL HCO_MSG(HcoConfig%Err,MSG)
    1790             :        ENDIF
    1791             : 
    1792             :        ! Cleanup
    1793           0 :        Lct => NULL()
    1794           0 :        Dta => NULL()
    1795             :     ENDIF
    1796             : 
    1797             :     ! Return w/ success
    1798           0 :     RC = HCO_SUCCESS
    1799             : 
    1800           0 :   END SUBROUTINE AddZeroScal
    1801             : !EOC
    1802             : !------------------------------------------------------------------------------
    1803             : !                   Harmonized Emissions Component (HEMCO)                    !
    1804             : !------------------------------------------------------------------------------
    1805             : !BOP
    1806             : !
    1807             : ! !IROUTINE: ExtSwitch2Buffer
    1808             : !
    1809             : ! !DESCRIPTION: Subroutine ExtSwitch2Buffer reads the HEMCO extension
    1810             : ! switches and registers all enabled extensions.
    1811             : !\\
    1812             : !\\
    1813             : ! !INTERFACE:
    1814             : !
    1815           0 :   SUBROUTINE ExtSwitch2Buffer( HcoConfig, IU_HCO, EOF, RC )
    1816             : !
    1817             : ! !USES:
    1818             : !
    1819             :     USE HCO_CHARPAK_Mod,    ONLY : STRREPL,  STRSPLIT, TRANLC
    1820             :     USE HCO_EXTLIST_MOD,    ONLY : AddExt,   AddExtOpt, HCO_GetOpt
    1821             :     USE HCO_EXTLIST_MOD,    ONLY : GetExtNr, GetExtOpt
    1822             : !
    1823             : ! !INPUT PARAMETERS:
    1824             : !
    1825             :     TYPE(ConfigObj), POINTER       :: HcoConfig   ! Config object
    1826             :     INTEGER,         INTENT(IN)    :: IU_HCO      ! HEMCO configfile LUN
    1827             : !
    1828             : ! !INPUT/OUTPUT PARAMETERS:
    1829             : !
    1830             :     LOGICAL,         INTENT(INOUT) :: EOF         ! End of file?
    1831             :     INTEGER,         INTENT(INOUT) :: RC          ! Success/failure
    1832             : !
    1833             : ! !REVISION HISTORY:
    1834             : !  17 Sep 2013 - C. Keller   - Initialization (update)
    1835             : !  See https://github.com/geoschem/hemco for complete history
    1836             : !EOP
    1837             : !------------------------------------------------------------------------------
    1838             : !BOC
    1839             : !
    1840             : ! !LOCAL VARIABLES:
    1841             : !
    1842             :     INTEGER               :: I, N, Idx, ExtNr
    1843             :     LOGICAL               :: Enabled, NewExt
    1844             :     LOGICAL               :: DoEmis,  Found, LTMP
    1845             :     CHARACTER(LEN=255)    :: loc
    1846             :     CHARACTER(LEN=512)    :: msg
    1847             :     CHARACTER(LEN=1023)   :: OPTS
    1848             :     CHARACTER(LEN=2047)   :: LINE
    1849             :     CHARACTER(LEN=2047)   :: SUBSTR(255), SPECS(255)
    1850             : 
    1851             :     !======================================================================
    1852             :     ! ExtSwitch2Buffer begins here
    1853             :     !======================================================================
    1854             : 
    1855             :     ! Enter
    1856           0 :     RC    = HCO_SUCCESS
    1857           0 :     msg   = ''
    1858           0 :     loc   = 'ExtSwitch2Buffer (hco_config_mod.F90)'
    1859           0 :     ExtNr = -1
    1860             : 
    1861             :     ! Initialize
    1862           0 :     DoEmis= .TRUE.
    1863           0 :     Found = .FALSE.
    1864             : 
    1865             :     ! Do until exit
    1866             :     DO
    1867             : 
    1868             :        ! Read line
    1869           0 :        CALL HCO_ReadLine ( IU_HCO, LINE, EOF, RC )
    1870           0 :        IF ( RC /= HCO_SUCCESS ) THEN
    1871           0 :           msg = 'Error in HEMCO_Config.rc @ line: ' // TRIM( line )
    1872           0 :           CALL HCO_Error( msg, RC, thisLoc=loc )
    1873           0 :           RETURN
    1874             :        ENDIF
    1875             : 
    1876             :        ! Return if EOF
    1877           0 :        IF ( EOF ) RETURN
    1878             : 
    1879             :        ! Exit here if end of section encountered.  Place this before the
    1880             :        ! test for comment to allow for "### END SECTION" tags (bmy, 4/21/15)
    1881           0 :        IF ( INDEX ( LINE, 'END SECTION' ) > 0 ) RETURN
    1882             : 
    1883             :        ! Jump to next line if line is commented out
    1884           0 :        IF ( LINE(1:1) == HCO_CMT ) CYCLE
    1885             : 
    1886             :        ! Check if these are options
    1887           0 :        IF ( INDEX(LINE,'-->') > 0 ) THEN
    1888             :           ! Only add if extension is defined!
    1889           0 :           IF ( ExtNr >= 0 .AND. Enabled ) THEN
    1890             :              CALL AddExtOpt( HcoConfig, TRIM(LINE), &
    1891           0 :                              ExtNr, RC, IgnoreIfExist=.TRUE. )
    1892           0 :              IF ( RC /= HCO_SUCCESS ) THEN
    1893           0 :                 msg = 'Error in HEMCO_Config.rc @ line: ' // TRIM( line )
    1894           0 :                 CALL HCO_ERROR( msg, RC, thisLoc=loc )
    1895           0 :                 RETURN
    1896             :              ENDIF
    1897             :           ENDIF
    1898             : 
    1899             :           ! Check if EMISSIONS setting is found. If so, overwrite DoEmis.
    1900           0 :           IF ( .not. Found ) THEN
    1901             :              CALL GetExtOpt( HcoConfig, -999, 'EMISSIONS',           &
    1902           0 :                              OptValBool=LTMP, FOUND=Found,  RC=RC )
    1903           0 :              IF ( RC /= HCO_SUCCESS ) THEN
    1904           0 :                 msg = 'Error encountered in "GetExtOpt( EMISSIONS )"!'
    1905           0 :                 CALL HCO_Error( msg, RC, ThisLoc=loc )
    1906           0 :                 RETURN
    1907             :              ENDIF
    1908           0 :              IF ( Found ) DoEmis = LTMP
    1909             :           ENDIF
    1910             :           CYCLE
    1911             :        ENDIF
    1912             : 
    1913             :        ! ---------------------------------------------------------------------
    1914             :        ! If the line is not an extension option, treat it as an extension
    1915             :        ! definition (e.g. 108 MEGAN : on ISOP/ACET/PRPE/C2H4/ALD2)
    1916             :        ! ---------------------------------------------------------------------
    1917             : 
    1918             :        ! Split character string
    1919           0 :        CALL STRREPL ( LINE, HCO_TAB, HCO_TAB )
    1920           0 :        CALL STRSPLIT( LINE, HCO_SPC, SUBSTR, N )
    1921             : 
    1922             :        ! Jump to next line if this line is empty
    1923           0 :        IF ( N <= 1 ) CYCLE
    1924             : 
    1925             :        ! Check if extension already exists, e.g. if this is a nested HEMCO configuration
    1926             :        ! file and the same extension has already been defined. In that case, use the
    1927             :        ! on/off toggle that has already been defined.
    1928           0 :        ExtNr = GetExtNr( HcoConfig%ExtList, TRIM(SUBSTR(2)) )
    1929             : 
    1930             :        ! Three possibilities:
    1931             :        ! - ExtNr is -999              --> extension does not yet exist
    1932             :        ! - ExtNr is a positive number --> extension exists and is enabled
    1933             :        ! - ExtNr is -1                --> extension exists and is disabled
    1934           0 :        IF ( ExtNr == -999 ) THEN
    1935             :           NewExt = .TRUE.
    1936           0 :        ELSEIF ( ExtNr >= 0 ) THEN
    1937           0 :           NewExt  = .FALSE.
    1938           0 :           Enabled = .TRUE.
    1939             :        ELSE
    1940           0 :           NewExt  = .FALSE.
    1941           0 :           Enabled = .FALSE.
    1942             :        ENDIF
    1943             : 
    1944             :        ! The following needs to be done for new extensions only
    1945             :        IF ( NewExt ) THEN
    1946             : 
    1947             :           ! Check for on-switch. This is either the
    1948             :           ! 3rd or the 4th substring, depending on the
    1949             :           ! location of the colon sign!
    1950           0 :           IF ( TRIM(SUBSTR(3)) /= ':' ) THEN
    1951             :              idx = 3
    1952             :           ELSE
    1953             :              idx = 4
    1954             :           ENDIF
    1955           0 :           CALL TRANLC( TRIM(SUBSTR(idx)) )
    1956           0 :           IF ( TRIM(SUBSTR(idx)) == 'on' ) THEN
    1957           0 :              Enabled = .TRUE.
    1958             :           ELSE
    1959           0 :              Enabled = .FALSE.
    1960             :           ENDIF
    1961             : 
    1962             :           ! Disable extension if EMISSIONS logical is false
    1963           0 :           IF ( .not. DoEmis ) THEN
    1964           0 :              Enabled = .FALSE.
    1965             :           ENDIF
    1966             : 
    1967             :           ! Register extension name, number and species
    1968             :           ! idx is the position of the species names
    1969           0 :           idx = idx+1
    1970           0 :           READ( SUBSTR(1), * ) ExtNr
    1971             :           CALL AddExt ( HcoConfig, TRIM(SUBSTR(2)), &
    1972           0 :                         ExtNr, Enabled, SUBSTR(idx), RC )
    1973           0 :           IF ( RC /= HCO_SUCCESS ) THEN
    1974           0 :               CALL HCO_ERROR( 'ERROR 32', RC, THISLOC=LOC )
    1975           0 :               RETURN
    1976             :           ENDIF
    1977             : 
    1978             :           ! Register species (specNames)
    1979           0 :           IF ( Enabled ) THEN
    1980             : 
    1981             :              CALL STRSPLIT( SUBSTR(idx), &
    1982           0 :                      HCO_GetOpt(HcoConfig%ExtList,'Separator'), SPECS, N )
    1983           0 :              IF ( N < 1 ) THEN
    1984           0 :                 CALL HCO_ERROR ( 'No species defined', RC, THISLOC=LOC )
    1985           0 :                 RETURN
    1986             :              ENDIF
    1987           0 :              DO I = 1, N
    1988           0 :                 CALL SpecName_Register ( HcoConfig, SPECS(I), RC )
    1989           0 :                 IF ( RC /= HCO_SUCCESS ) THEN
    1990           0 :                    msg = 'Error encountered in "SpecName_Register"!'
    1991           0 :                    CALL HCO_ERROR( msg, RC, thisLoc=LOC )
    1992           0 :                    RETURN
    1993             :                 ENDIF
    1994             :              ENDDO
    1995             :           ENDIF
    1996             :        ENDIF ! NextExt
    1997             :     ENDDO
    1998             : 
    1999             :     ! Leave w/ success
    2000             :     RC = HCO_SUCCESS
    2001             : 
    2002             :   END SUBROUTINE ExtSwitch2Buffer
    2003             : !EOC
    2004             : !------------------------------------------------------------------------------
    2005             : !                   Harmonized Emissions Component (HEMCO)                    !
    2006             : !------------------------------------------------------------------------------
    2007             : !BOP
    2008             : !
    2009             : ! !ROUTINE: ReadSettings
    2010             : !
    2011             : ! !DESCRIPTION: Subroutine ReadSettings reads the HEMCO settings,
    2012             : ! stores them as HEMCO core extension options, and also evaluates
    2013             : ! some of the values (e.g. to initialize the HEMCO error module).
    2014             : !\\
    2015             : !\\
    2016             : ! !INTERFACE:
    2017             : !
    2018           0 :   SUBROUTINE ReadSettings( HcoConfig, IU_HCO, EOF, RC )
    2019             : !
    2020             : ! !USES:
    2021             : !
    2022             :     USE HCO_EXTLIST_MOD,    ONLY : AddExtOpt, GetExtOpt, CoreNr
    2023             :     USE HCO_EXTLIST_MOD,    ONLY : HCO_SetDefaultToken
    2024             :     USE HCO_EXTLIST_MOD,    ONLY : HCO_GetOpt
    2025             :     USE HCO_CHARPAK_MOD,    ONLY : STRREPL, STRSPLIT, TRANLC
    2026             : !
    2027             : ! !INPUT PARAMETERS:
    2028             : !
    2029             :     TYPE(ConfigObj), POINTER       :: HcoConfig   ! Config obj
    2030             :     INTEGER,         INTENT(IN)    :: IU_HCO      ! HEMCO configfile LUN
    2031             : !
    2032             : ! !INPUT/OUTPUT PARAMETERS:
    2033             : !
    2034             :     LOGICAL,         INTENT(INOUT) :: EOF         ! End of file?
    2035             :     INTEGER,         INTENT(INOUT) :: RC          ! Success/failure
    2036             : !
    2037             : ! !REVISION HISTORY:
    2038             : !  17 Sep 2013 - C. Keller   - Initialization (update)
    2039             : !  See https://github.com/geoschem/hemco for complete history
    2040             : !EOP
    2041             : !------------------------------------------------------------------------------
    2042             : !BOC
    2043             : !
    2044             : ! !LOCAL VARIABLES:
    2045             : !
    2046             :     ! Scalars
    2047             :     LOGICAL               :: doVerbose, doVerboseOnRoot, found
    2048             :     INTEGER               :: I,         N,               POS
    2049             : 
    2050             :     ! Strings
    2051             :     CHARACTER(LEN=10)     :: onCores
    2052             :     CHARACTER(LEN=15)     :: verboseMsg
    2053             :     CHARACTER(LEN=255)    :: line
    2054             :     CHARACTER(LEN=255)    :: loc
    2055             :     CHARACTER(LEN=255)    :: LogFile
    2056             :     CHARACTER(LEN=255)    :: DiagnPrefix
    2057             :     CHARACTER(LEN=255)    :: MetField
    2058             :     CHARACTER(LEN=255)    :: GridRes
    2059             :     CHARACTER(LEN=512)    :: msg
    2060             : 
    2061             :     !======================================================================
    2062             :     ! ReadSettings begins here
    2063             :     !======================================================================
    2064             : 
    2065             :     ! Enter
    2066           0 :     Loc = 'ReadSettings (hco_config_mod.F90)'
    2067             : 
    2068             : 
    2069             :     !-----------------------------------------------------------------------
    2070             :     ! Read settings and add them as options to core extensions
    2071             :     !-----------------------------------------------------------------------
    2072             : 
    2073             :     ! Do until exit
    2074             :     DO
    2075             : 
    2076             :        ! Read line
    2077           0 :        CALL HCO_ReadLine ( IU_HCO, LINE, EOF, RC )
    2078           0 :        IF ( RC /= HCO_SUCCESS ) THEN
    2079           0 :           msg = 'Error in HEMCO_Config.rc @ line: ' // TRIM( Line )
    2080           0 :           CALL HCO_Error( msg, RC, thisLoc=loc )
    2081           0 :           RETURN
    2082             :        ENDIF
    2083             : 
    2084             :        ! Return if EOF
    2085           0 :        IF ( EOF ) EXIT
    2086             : 
    2087             :        ! Exit here if end of section encountered
    2088           0 :        IF ( INDEX ( LINE, 'END SECTION' ) > 0 ) EXIT
    2089             : 
    2090             :        ! Jump to next line if line is commented out
    2091           0 :        IF ( LINE(1:1) == HCO_CMT ) CYCLE
    2092             : 
    2093             :        ! Ignore empty lines
    2094           0 :        IF ( TRIM(LINE) == '' ) CYCLE
    2095             : 
    2096             :        ! Add this option to HEMCO core
    2097             :        CALL AddExtOpt ( HcoConfig, TRIM(LINE), &
    2098           0 :                         CoreNr, RC, IgnoreIfExist=.TRUE. )
    2099           0 :        IF ( RC /= HCO_SUCCESS ) THEN
    2100           0 :           msg = 'Error in HEMCO_Config.rc @ line: ' // TRIM( Line )
    2101           0 :           CALL HCO_Error( msg, RC, thisLoc=loc )
    2102           0 :           RETURN
    2103             :        ENDIF
    2104             : 
    2105             :     ENDDO
    2106             : 
    2107             : #ifndef MODEL_GEOS
    2108             : #ifndef MODEL_WRF
    2109             : #ifndef MODEL_CESM
    2110             : #ifndef ESMF_
    2111             :     !=======================================================================
    2112             :     ! Look for met field and grid resolution.  When running the HEMCO
    2113             :     ! standalone these will need to be read from the configuration file.
    2114             :     ! Otherwise, HEMCO will inherit the met field and grid resolution
    2115             :     ! of the parent model (GC-Classic, GCHP, etc.)
    2116             :     !
    2117             :     ! NOTE: Only do this check if not using GEOS-Chem in an external ESM!
    2118             :     !=======================================================================
    2119             : 
    2120             :     ! Look for met field
    2121             :     CALL GetExtOpt( HcoConfig, CoreNr, 'MET', &
    2122             :                     OptValChar=MetField, FOUND=FOUND, RC=RC )
    2123             :     IF ( FOUND ) THEN
    2124             :        HcoConfig%MetField = TRIM( MetField )
    2125             :     ENDIF
    2126             : 
    2127             :     ! Look for grid resolution
    2128             :     ! Make sure resolution string is in the proper FlexGrid format
    2129             :     CALL GetExtOpt( HcoConfig, CoreNr, 'RES', &
    2130             :                     OptValChar=GridRes, FOUND=FOUND, RC=RC )
    2131             :     IF ( FOUND ) THEN
    2132             :        SELECT CASE( TRIM( GridRes ) )
    2133             :           CASE( '4x5' )
    2134             :              GridRes = '4.0x5.0'
    2135             :           CASE( '2x25', '2x2.5' )
    2136             :              GridRes = '2.0x2.5'
    2137             :           CASE( '05x0625', '0.5x0.625' )
    2138             :              GridRes = '0.5x0.625'
    2139             :           CASE( '025x03125', '0.25x0.3125' )
    2140             :              GridRes = '0.25x0.3125'
    2141             :           CASE DEFAULT
    2142             :              Msg = 'Improperly formatted grid resolution: ' // TRIM( GridRes )
    2143             :              CALL HCO_Error( Msg, RC, Loc )
    2144             :              RETURN
    2145             :        END SELECT
    2146             :        HcoConfig%GridRes = TRIM( GridRes )
    2147             :     ENDIF
    2148             : #endif
    2149             : #endif
    2150             : #endif
    2151             : #endif
    2152             : 
    2153             :     !-----------------------------------------------------------------------
    2154             :     ! Initialize error object if needed.
    2155             :     ! Extract values to initialize error module and set some further
    2156             :     ! HEMCO variables. Only the first time the settings are read (settings
    2157             :     ! can be read multiple times if nested HEMCO configuration files are
    2158             :     ! used)
    2159             :     !-----------------------------------------------------------------------
    2160           0 :     IF ( .NOT. ASSOCIATED(HcoConfig%Err) ) THEN
    2161             : 
    2162             :        ! Initialize
    2163           0 :        doVerbose       = .FALSE.
    2164           0 :        doVerboseOnRoot = .FALSE.
    2165           0 :        onCores         = ''
    2166             : 
    2167             :        ! First look for Verbose
    2168             :        CALL GetExtOpt( HcoConfig,            CoreNr,      'Verbose',         &
    2169           0 :                        OptValBool=doVerbose, found=found,  RC=RC            )
    2170           0 :        IF ( RC /= HCO_SUCCESS ) THEN
    2171           0 :           msg = 'Error looking for "Verbose" in HEMCO_Config.rc!'
    2172           0 :           CALL HCO_Error( msg, RC, thisLoc=loc )
    2173           0 :           RETURN
    2174             :        ENDIF
    2175             : 
    2176             :        ! First look for Verbose (logical).  This is now the default
    2177             :        ! inthe HEMCO_Config.rc file for HEMCO 3.7.0 and later.
    2178             :        CALL GetExtOpt( HcoConfig,          CoreNr,      'VerboseOnCores',    &
    2179           0 :                        OptValChar=onCores, found=found,  RC=RC              )
    2180           0 :        IF ( RC /= HCO_SUCCESS ) THEN
    2181           0 :           msg = 'Error looking for "VerboseOnCores in HEMCO_Config.rc!'
    2182           0 :           CALL HCO_Error( msg, RC, thisLoc=loc )
    2183           0 :           RETURN
    2184             :        ENDIF
    2185             : 
    2186             :        ! Set a flag if Verbose output is to be done on the root core only
    2187             :        ! (if false, it will be done on all cores)
    2188           0 :        CALL TranLC( onCores )
    2189           0 :        doVerboseOnRoot = ( TRIM( onCores ) == "root" )
    2190             : 
    2191             :        ! Print status message
    2192           0 :        IF ( doVerbose ) THEN
    2193           0 :           msg = NEW_LINE( 'A' ) // 'HEMCO verbose output is ON '
    2194           0 :           IF ( doVerboseOnRoot ) THEN
    2195           0 :              msg = TRIM( msg ) // ' (root core only)'
    2196             :           ELSE
    2197           0 :              msg = TRIM( msg ) // ' (all cores)'
    2198             :           ENDIF
    2199             :        ELSE
    2200           0 :           msg = NEW_LINE( 'A' ) // 'HEMCO verbose output is OFF'
    2201             :        ENDIF
    2202           0 :        IF ( HcoConfig%amIRoot ) CALL HCO_Msg( msg, verb=.TRUE. )
    2203             : 
    2204             :        ! Logfile to write into
    2205             :        CALL GetExtOpt( HcoConfig, CoreNr, 'Logfile', &
    2206           0 :                        OptValChar=Logfile, FOUND=FOUND, RC=RC )
    2207           0 :        IF ( RC /= HCO_SUCCESS ) THEN
    2208           0 :           msg = 'Error looking for "Logfile" in HEMCO_Config.rc!'
    2209           0 :           CALL HCO_Error( msg, RC, thisLoc=loc )
    2210           0 :           RETURN
    2211             :        ENDIF
    2212           0 :        IF ( .NOT. FOUND ) THEN
    2213           0 :           LogFile = 'HEMCO.log'
    2214           0 :           WRITE(*,*) 'Setting `Logfile` not found in HEMCO logfile - use `HEMCO.log`'
    2215             :        ENDIF
    2216             : 
    2217             :        ! Initialize (standard) HEMCO tokens
    2218           0 :        CALL HCO_SetDefaultToken( HcoConfig, RC )
    2219           0 :        IF ( RC /= HCO_SUCCESS ) THEN
    2220           0 :           msg = 'Error encountered in routine "HCO_SetDefaultToken"!'
    2221           0 :           CALL HCO_Error( msg, RC, thisLoc=loc )
    2222           0 :           RETURN
    2223             :        ENDIF
    2224             : 
    2225             :        ! If LogFile is equal to wildcard character, set LogFile to asterik
    2226             :        ! character. This will ensure that all output is written to standard
    2227             :        ! output!
    2228           0 :        IF ( TRIM(LogFile) == HCO_GetOpt(HcoConfig%ExtList,'Wildcard') )      &
    2229           0 :             LogFile = '*'
    2230             : 
    2231             :        ! We should now have everything to define the HEMCO error settings
    2232             :        CALL HCO_ERROR_SET( HcoConfig%amIRoot, HcoConfig%Err,   LogFile,      &
    2233           0 :                            doVerbose,         doVerboseOnRoot, RC           )
    2234           0 :        IF ( RC /= HCO_SUCCESS ) THEN
    2235           0 :           msg = 'Error encountered in routine "Hco_Error_Set"!'
    2236           0 :           CALL HCO_Error( msg, RC, thisLoc=loc )
    2237           0 :           RETURN
    2238             :        ENDIF
    2239             : 
    2240             :     ENDIF
    2241             : 
    2242             :     ! Leave w/ success
    2243           0 :     RC = HCO_SUCCESS
    2244             : 
    2245             :   END SUBROUTINE ReadSettings
    2246             : !EOC
    2247             : !------------------------------------------------------------------------------
    2248             : !                   Harmonized Emissions Component (HEMCO)                    !
    2249             : !------------------------------------------------------------------------------
    2250             : !BOP
    2251             : !
    2252             : ! !IROUTINE: RegisterPrepare
    2253             : !
    2254             : ! !DESCRIPTION: Subroutine RegisterPrepare extracts the spatial
    2255             : ! coverages of all mask fields as well as the HEMCO species IDs of
    2256             : ! all base emissions.
    2257             : !\\
    2258             : !\\
    2259             : ! The species IDs are determined by matching the species name read
    2260             : ! from the configuration file (in ConfigList) and the species names
    2261             : ! defined in the HEMCO state object HcoState.
    2262             : !\\
    2263             : !\\
    2264             : ! Mask coverages are defined based upon the passed horizontal grid
    2265             : ! extensions on this CPU (xrng and yrng).
    2266             : !\\
    2267             : !\\
    2268             : ! !INTERFACE:
    2269             : !
    2270           0 :   SUBROUTINE RegisterPrepare( HcoState, RC )
    2271             : !
    2272             : ! !USES:
    2273             : !
    2274             :     USE HCO_EXTLIST_MOD,  ONLY : ExtNrInUse
    2275             :     USE HCO_STATE_Mod,    ONLY : HCO_GetHcoID
    2276             :     USE HCO_DATACONT_MOD, ONLY : ListCont_NextCont
    2277             : !
    2278             : ! !INPUT PARAMETERS:
    2279             : !
    2280             :     TYPE(HCO_State),  POINTER       :: HcoState   ! HEMCO state obj.
    2281             : !
    2282             : ! !OUTPUT PARAMETERS:
    2283             : !
    2284             :     INTEGER,          INTENT(INOUT) :: RC
    2285             : !
    2286             : ! !REVISION HISTORY:
    2287             : !  18 Sep 2013 - C. Keller - Initial version (update)
    2288             : !  See https://github.com/geoschem/hemco for complete history
    2289             : !EOP
    2290             : !------------------------------------------------------------------------------
    2291             : !BOC
    2292             : !
    2293             : ! !LOCAL VARIABLES:
    2294             : !
    2295             :     TYPE(ListCont), POINTER      :: Lct
    2296             :     INTEGER                      :: ThisCover, ThisHcoID, FLAG
    2297             :     INTEGER                      :: lon1, lon2, lat1, lat2
    2298             :     INTEGER                      :: cpux1, cpux2, cpuy1, cpuy2
    2299             :     CHARACTER(LEN=255)           :: loc
    2300             :     CHARACTER(LEN=512)           :: msg
    2301             : 
    2302             :     !=================================================================
    2303             :     ! RegisterPrepare begins here!
    2304             :     !=================================================================
    2305           0 :     loc = 'RegisterPrepare (HCO_CONFIG_MOD.F90)'
    2306             : 
    2307             :     ! Enter
    2308           0 :     CALL HCO_ENTER ( HcoState%Config%Err, LOC, RC )
    2309           0 :     IF ( RC /= HCO_SUCCESS ) THEN
    2310           0 :        msg = 'Error encountered in routine "HCO_Enter"!'
    2311           0 :        CALL HCO_Error( msg, RC, thisLoc=loc )
    2312           0 :        RETURN
    2313             :     ENDIF
    2314             : 
    2315             :     ! Initialize
    2316           0 :     Lct => NULL()
    2317             : 
    2318             :     ! Grid boundaries on this CPU. Will be needed to calculate
    2319             :     ! coverages.
    2320             :     ! NOTE: Use midpoints here because only those become defined in
    2321             :     ! the ESMF environment (xedge and yedge are not used anywhere
    2322             :     ! else in ESMF!).
    2323           0 :     cpux1 = FLOOR(MINVAL(HcoState%Grid%XMID%Val))
    2324           0 :     cpux2 = FLOOR(MAXVAL(HcoState%Grid%XMID%Val))
    2325           0 :     cpuy1 = CEILING(MINVAL(HcoState%Grid%YMID%Val))
    2326           0 :     cpuy2 = CEILING(MAXVAL(HcoState%Grid%YMID%Val))
    2327             : 
    2328             :     ! Make sure values are within -180.0 to 180.0
    2329           0 :     IF ( cpux1 >= 180 ) cpux1 = cpux1 - 360
    2330           0 :     IF ( cpux2 >= 180 ) cpux2 = cpux2 - 360
    2331             : 
    2332             :     ! verbose
    2333           0 :     IF ( HCO_IsVerb(HcoState%Config%Err ) ) THEN
    2334           0 :        WRITE(MSG,*) 'Start to prepare fields for registering!'
    2335           0 :        CALL HCO_MSG(HcoState%Config%Err,MSG)
    2336           0 :        WRITE(MSG,*) 'This CPU x-range: ', cpux1, cpux2
    2337           0 :        CALL HCO_MSG(HcoState%Config%Err,MSG)
    2338           0 :        WRITE(MSG,*) 'This CPU y-range: ', cpuy1, cpuy2
    2339           0 :        CALL HCO_MSG(HcoState%Config%Err,MSG)
    2340             :     ENDIF
    2341             : 
    2342             :     ! Get next (first) line of ConfigList
    2343           0 :     CALL ListCont_NextCont ( HcoState%Config%ConfigList, Lct, FLAG )
    2344             : 
    2345             :     ! Loop over all lines
    2346           0 :     DO WHILE ( FLAG == HCO_SUCCESS )
    2347             : 
    2348             :        ! Check if data container defined
    2349           0 :        IF ( .NOT. ASSOCIATED(Lct%Dct) ) THEN
    2350           0 :           CALL ListCont_NextCont ( HcoState%Config%ConfigList, Lct, FLAG )
    2351           0 :           CYCLE
    2352             :        ENDIF
    2353             : 
    2354             :        ! verbose
    2355           0 :        IF ( HCO_IsVerb(HcoState%Config%Err ) ) THEN
    2356           0 :           WRITE(MSG,*) 'Prepare ', TRIM(Lct%Dct%cName)
    2357           0 :           CALL HCO_MSG(HcoState%Config%Err,MSG)
    2358             :        ENDIF
    2359             : 
    2360             :        ! For base fields or data fields used in one of the HEMCO
    2361             :        ! extensions:
    2362           0 :        IF ( Lct%Dct%DctType == HCO_DCTTYPE_BASE ) THEN
    2363             : 
    2364             :           ! Only do for entries that will be used!
    2365           0 :           IF ( ExtNrInUse( HcoState%Config%ExtList, Lct%Dct%ExtNr ) ) THEN
    2366             : 
    2367             :              ! Extract HEMCO species ID. This will return -1 for
    2368             :              ! undefined species and 0 for wildcard character.
    2369           0 :              ThisHcoID     = HCO_GetHcoID( Lct%Dct%SpcName, HcoState )
    2370           0 :              Lct%Dct%HcoID = ThisHcoID
    2371             : 
    2372             :              ! verbose
    2373           0 :              IF ( HCO_IsVerb(HcoState%Config%Err ) ) THEN
    2374           0 :                 WRITE(MSG,*) 'Assigned HEMCO species ID: ', Lct%Dct%HcoID
    2375           0 :                 CALL HCO_MSG(HcoState%Config%Err,MSG)
    2376             :              ENDIF
    2377             : 
    2378             :           ! Else: assign default value. These containers will be
    2379             :           ! removed in the next step!
    2380             :           ELSE
    2381           0 :              Lct%Dct%HcoID = -999
    2382             :           ENDIF
    2383             : 
    2384             :        ! Calculate coverage for masks
    2385           0 :        ELSE IF ( Lct%Dct%DctType   == HCO_DCTTYPE_MASK .AND. &
    2386             :                  Lct%Dct%Dta%Cover == -999                   ) THEN
    2387             : 
    2388             :           ! The mask coverage calculation (which only has three values)
    2389             :           ! is used to simplify I/O and CPU operations in code below.
    2390             :           !
    2391             :           ! However, there are two distinct bugs related to this:
    2392             :           !
    2393             :           ! (1)
    2394             :           ! There appear to be some issues with full masks coverages
    2395             :           ! when working in an MPI environment. Specifically, masks
    2396             :           ! can be seen as fully covering a given CPU even though in
    2397             :           ! reality it may only cover parts of it. Thus, in ESMF mode
    2398             :           ! always set coverage to zero or partial (ckeller, 3/17/16).
    2399             :           !
    2400             :           ! This appears to be related to masking for two inventories
    2401             :           ! with overlapping temporal coverage. For example, if inventory
    2402             :           ! A is 2013-2015, and B is 2010-2018 with higher hierarchy,
    2403             :           ! but not the same mask (maybe A covers regions that B does not).
    2404             :           ! If both masks are set to ThisCover == 1 (full coverage), because
    2405             :           ! a certain CPU might be overlapped by lon1/lat1/lon2/lat2 even
    2406             :           ! though the actual netCDF shape of the mask is different,
    2407             :           ! then a simulation running 2013-2015 will see inventory B on that CPU
    2408             :           ! decide it has full coverage (only through lon1/..), and skip
    2409             :           ! inventory A altogether, resulting in missing emissions.
    2410             :           ! This behavior is in the line
    2411             :           ! IF ( (tmpLct%Dct%Hier > Hier) .AND. (tmpCov==1) ) THEN below.
    2412             :           !
    2413             :           ! (2)
    2414             :           ! Another artifact caused by MPI environments:
    2415             :           ! where lon1/lat1/... is set too small, resulting in certain CPUs not
    2416             :           ! having overlap (defined by cpux/y) with lon1/lat1/..., and thus
    2417             :           ! skipping the base inventory as a bug. This behavior is in the line
    2418             :           ! IF ( (mskLct%Dct%DctType  == HCO_DCTTYPE_MASK ) .AND. &
    2419             :           ! (mskLct%Dct%Dta%Cover == 0 )        ) THEN
    2420             :           !
    2421             :           ! Because the code only distinguishes between full/partial and zero
    2422             :           ! coverage, and skips reading the base field if coverage is zero,
    2423             :           ! this may cause issues with MPI environments in WRF and CESM where
    2424             :           ! the mask lon1/lat1/lon2/lat2 boundaries are set too small compared
    2425             :           ! to the mask, and result in the base field being skipped over small
    2426             :           ! CPU decompositions where it should not have been. The above fix
    2427             :           ! does not fix the issue where ThisCover == 0, which is the root
    2428             :           ! cause in WRF and CESM. Thus, always set to partial coverage
    2429             :           ! (hplin, 8/19/22)
    2430             :           !
    2431             :           ! Thus, the following fix needs to be applied for ESMF environments,
    2432             :           ! skipping a lot of the calculations below.
    2433             : #if defined ( ESMF_ ) || defined( MODEL_WRF ) || defined( MODEL_CESM )
    2434           0 :           ThisCover = -1
    2435             : #else
    2436             :           ! Get mask edges
    2437             :           lon1 = Lct%Dct%Dta%ncYrs(1)
    2438             :           lat1 = Lct%Dct%Dta%ncYrs(2)
    2439             :           lon2 = Lct%Dct%Dta%ncMts(1)
    2440             :           lat2 = Lct%Dct%Dta%ncMts(2)
    2441             : 
    2442             :           ! If ncFile is passed as the lon1/lat1/lon2/lat2 instead
    2443             :           ! of netCDF file name, then set ncRead to false, so that
    2444             :           ! HEMCO won't try to read a file from disk.  Also set the
    2445             :           ! IsLocTime flag to TRUE.  This should fix Github issue
    2446             :           ! https://github.com/geoschem/HEMCO/issues/153.
    2447             :           !  -- Bob Yantosca (12 Jul 2022)
    2448             :           !
    2449             :           ! Also allow for the .$NC replaceable token, see:
    2450             :           ! https://github.com/geoschem/HEMCO/issues/204
    2451             :           !  -- Melissa Sulprizio & Bob Yantosca (11 Apr 2023)
    2452             :           IF ( INDEX( Lct%Dct%Dta%ncFile,   ".nc" ) == 0 ) THEN
    2453             :              IF ( INDEX( Lct%Dct%Dta%ncFile, ".$NC" ) == 0 ) THEN
    2454             :                 Lct%Dct%Dta%ncRead    = .FALSE.
    2455             :                 Lct%Dct%Dta%IsLocTime = .TRUE.
    2456             :              ENDIF
    2457             :           ENDIF
    2458             : 
    2459             :           ThisCover = CALC_COVERAGE( lon1,  lon2,  lat1,  lat2,              &
    2460             :                                      cpux1, cpux2, cpuy1, cpuy2             )
    2461             : #endif
    2462             : 
    2463             :           ! Update container information
    2464           0 :           Lct%Dct%Dta%Cover    = ThisCover
    2465           0 :           Lct%Dct%Dta%ncYrs(:) = -999
    2466           0 :           Lct%Dct%Dta%ncMts(:) = -999
    2467             : 
    2468           0 :           IF ( HCO_IsVerb(HcoSTate%Config%Err ) ) THEN
    2469           0 :              WRITE(MSG,*) 'Coverage: ', Lct%Dct%Dta%Cover
    2470           0 :              CALL HCO_MSG( HcoState%Config%Err, msg )
    2471             :           ENDIF
    2472             :        ENDIF
    2473             : 
    2474             :        ! Advance to next line
    2475           0 :        CALL ListCont_NextCont ( HcoState%Config%ConfigList, Lct, FLAG )
    2476             :     ENDDO
    2477             : 
    2478             :     ! Cleanup
    2479           0 :     Lct => NULL()
    2480             : 
    2481             :     ! Return w/ success
    2482           0 :     CALL HCO_LEAVE ( HcoState%Config%Err, RC )
    2483             : 
    2484             :   END SUBROUTINE RegisterPrepare
    2485             : !EOC
    2486             : !------------------------------------------------------------------------------
    2487             : !                   Harmonized Emissions Component (HEMCO)                    !
    2488             : !------------------------------------------------------------------------------
    2489             : !BOP
    2490             : !
    2491             : ! !IROUTINE: Register_Base
    2492             : !
    2493             : ! !DESCRIPTION: Subroutine Register\_Base registers all base emission
    2494             : ! data and writes out all associated scale factor IDs.
    2495             : !\\
    2496             : !\\
    2497             : ! !INTERFACE:
    2498             : !
    2499           0 :   SUBROUTINE Register_Base( HcoState, RC )
    2500             : !
    2501             : ! !USES:
    2502             : !
    2503             :     USE HCO_READLIST_Mod,      ONLY : ReadList_Set
    2504             :     USE HCO_DATACONT_Mod,      ONLY : DataCont_Cleanup
    2505             :     USE HCO_DATACONT_MOD,      ONLY : ListCont_NextCont
    2506             : !
    2507             : ! !INPUT/OUTPUT PARAMETERS:
    2508             : !
    2509             :     TYPE(HCO_State),  POINTER       :: HcoState    ! HEMCO state object
    2510             : !
    2511             : ! !INPUT/OUTPUT PARAMETERS:
    2512             : !
    2513             :     INTEGER,          INTENT(INOUT) :: RC          ! Success or failure
    2514             : !
    2515             : ! !REVISION HISTORY:
    2516             : !  18 Jun 2013 - C. Keller: Initialization
    2517             : !  See https://github.com/geoschem/hemco for complete history
    2518             : !EOP
    2519             : !------------------------------------------------------------------------------
    2520             : !BOC
    2521             : !
    2522             : ! !LOCAL VARIABLES:
    2523             : !
    2524             :     ! Pointers
    2525             :     TYPE(ListCont), POINTER   :: Lct
    2526             : 
    2527             :     ! Scalars
    2528             :     INTEGER               :: N, cID, HcoID
    2529             :     INTEGER               :: targetID, FLAG
    2530             :     LOGICAL               :: Ignore, Add
    2531             :     CHARACTER(LEN=255)    :: LOC
    2532             :     CHARACTER(LEN=512)    :: msg
    2533             : 
    2534             :     !======================================================================
    2535             :     ! Register_Base begins here
    2536             :     !======================================================================
    2537           0 :     loc = 'Register_Base (HCO_CONFIG_MOD.F90)'
    2538             : 
    2539             :     ! Enter
    2540           0 :     CALL HCO_ENTER ( HcoState%Config%Err, loc, RC )
    2541           0 :     IF ( RC /= HCO_SUCCESS ) THEN
    2542           0 :        msg = 'Error encountered in routine "HCO_Enter"!'
    2543           0 :        CALL HCO_Error( msg, RC, thisLoc=loc )
    2544           0 :        RETURN
    2545             :     ENDIF
    2546             : 
    2547             :     ! Initialize
    2548           0 :     Lct => NULL()
    2549             : 
    2550             :     ! Point to next (first) line in ConfigList
    2551           0 :     CALL ListCont_NextCont ( HcoState%Config%ConfigList, Lct, FLAG )
    2552             : 
    2553             :     ! Loop over temporary arrays
    2554           0 :     DO WHILE ( FLAG == HCO_SUCCESS )
    2555             : 
    2556             :        ! Reset ignore flag
    2557           0 :        Ignore = .FALSE.
    2558             : 
    2559             :        ! Skip entry if data container not defined
    2560           0 :        IF ( .NOT. ASSOCIATED(Lct%Dct) ) THEN
    2561           0 :           CALL ListCont_NextCont ( HcoState%Config%ConfigList, Lct, FLAG )
    2562           0 :           CYCLE
    2563             :        ENDIF
    2564             : 
    2565             :        ! Skip entry if it's not a base field
    2566           0 :        IF ( (Lct%Dct%DctType /= HCO_DCTTYPE_BASE) ) THEN
    2567           0 :           CALL ListCont_NextCont ( HcoState%Config%ConfigList, Lct, FLAG )
    2568           0 :           CYCLE
    2569             :        ENDIF
    2570             : 
    2571             :        ! If this base field is not used (either because it belongs to
    2572             :        ! an extension that is not enabled or because its HEMCO or
    2573             :        ! model species ID is undefined), we don't need this container
    2574             :        ! any more. Hence remove it.
    2575             :        ! Note: Routine RegisterPrepare assigns negative HcoID's to all
    2576             :        ! base fields with invalid ExtNr's, so it is ok to check only
    2577             :        ! for HcoID here. If data is used in one of the HEMCO extensions
    2578             :        ! and has a species flag of '*' (= always read), its species ID
    2579             :        ! becomes set to 0 in RegisterPrepare.
    2580           0 :        HcoID = Lct%Dct%HcoID
    2581           0 :        IF ( HcoID < 0 ) THEN
    2582             :           Ignore = .TRUE.
    2583           0 :        ELSE IF ( HcoID > 0 ) THEN
    2584           0 :           IF ( HcoState%Spc(HcoID)%ModID < 0 ) Ignore = .TRUE.
    2585             :        ENDIF
    2586             : 
    2587             :        IF ( Ignore ) THEN
    2588           0 :           IF ( HCO_IsVerb(HcoState%Config%Err ) ) THEN
    2589             :              WRITE(MSG,*) &
    2590           0 :                   'Register_Base: Ignore (and remove) base field ', &
    2591           0 :                   TRIM(Lct%Dct%cName)
    2592           0 :              CALL HCO_MSG(HcoState%Config%Err,MSG,SEP1='-')
    2593             :           ENDIF
    2594             : 
    2595             :           ! Remove data container from list.
    2596           0 :           CALL DataCont_Cleanup ( Lct%Dct )
    2597           0 :           Lct%Dct => NULL()
    2598           0 :           CALL ListCont_NextCont ( HcoState%Config%ConfigList, Lct, FLAG )
    2599           0 :           CYCLE
    2600             :        ENDIF
    2601             : 
    2602             :        ! Verbose mode
    2603           0 :        IF ( HCO_IsVerb(HcoState%Config%Err ) ) THEN
    2604           0 :           WRITE(MSG,*) 'Register_Base: Checking ', TRIM(Lct%Dct%cName)
    2605           0 :           CALL HCO_MSG(HcoState%Config%Err,MSG,SEP1='-')
    2606             :        ENDIF
    2607             : 
    2608             :        ! -------------------------------------------------------------
    2609             :        ! Extract vector of scale factor container IDs to be applied
    2610             :        ! to this base field (vector Scal_cID). For now, this container
    2611             :        ! contains the scale factor IDs, hence need to convert to
    2612             :        ! container IDs. Beforehand, add scale factor IDs to internal
    2613             :        ! list of used scale factors (UnqScalIDs).
    2614           0 :        CALL ScalID_Register ( Lct%Dct, HcoState%Config, RC )
    2615           0 :        IF ( RC /= HCO_SUCCESS ) THEN
    2616           0 :           PRINT *,'Error in ScaleID_Register called from Register_Base'
    2617           0 :           RETURN
    2618             :        ENDIF
    2619             : 
    2620             :        ! Get target ID of this container. The targetID corresponds
    2621             :        ! to the container ID cID into which emissions data of the
    2622             :        ! current container (Lct) will be added to. Typically,
    2623             :        ! targetID is equal to cID, i.e. a container holds the data
    2624             :        ! array corresponding to its source data information. In
    2625             :        ! cases where multiple base emissions have same properties,
    2626             :        ! however, we can merge these fields prior to emission
    2627             :        ! calculation to save some calculation operations.
    2628             :        ! Requirement is that these base emissions have same species
    2629             :        ! ID, emission category and hierarchy, ext. number, scale
    2630             :        ! factors, and update frequency.
    2631           0 :        CALL Get_targetID( HcoState, Lct, targetID, RC)
    2632           0 :        IF ( RC /= HCO_SUCCESS ) THEN
    2633           0 :           PRINT *,'Error in Get_targetID called from Register_Base'
    2634           0 :           RETURN
    2635             :        ENDIF
    2636             : 
    2637             :        ! verbose
    2638           0 :        IF ( HCO_IsVerb(HcoState%Config%Err ) ) THEN
    2639           0 :           WRITE(MSG,*) 'Container ID     : ', Lct%Dct%cID
    2640           0 :           CALL HCO_MSG( HcoState%Config%Err, msg )
    2641           0 :           WRITE(MSG,*) 'Assigned targetID: ', targetID
    2642           0 :           CALL HCO_MSG( HcoState%Config%Err, msg )
    2643             :        ENDIF
    2644             : 
    2645             :        ! Negative targetID is assigned to base data that doesn't need
    2646             :        ! to be considered either because it's a regional inventory
    2647             :        ! with no spatial overlap with the region domain on this CPU,
    2648             :        ! or because there exist another inventory with higher
    2649             :        ! priority (and same category) that will overwrite these
    2650             :        ! emissions data anyway!
    2651           0 :        IF ( targetID <= 0 ) THEN
    2652           0 :           CALL DataCont_Cleanup ( Lct%Dct )
    2653           0 :           Lct%Dct => NULL()
    2654           0 :           CALL ListCont_NextCont ( HcoState%Config%ConfigList, Lct, FLAG )
    2655           0 :           CYCLE
    2656             :        ENDIF
    2657             : 
    2658             :        ! Pass targetID to container
    2659           0 :        Lct%Dct%targetID = targetID
    2660             : 
    2661             :        ! Register container in ReadList. Containers will be listed
    2662             :        ! in the reading lists sorted by cID.
    2663           0 :        CALL ReadList_Set( HcoState, Lct%Dct, RC )
    2664           0 :        IF ( RC /= HCO_SUCCESS ) THEN
    2665           0 :           msg = 'Error encountered in routine "ReadList_Set"!'
    2666           0 :           CALL HCO_Error( msg, RC, thisLoc=loc )
    2667           0 :           RETURN
    2668             :        ENDIF
    2669             : 
    2670             :        ! Print some information if verbose mode is on
    2671           0 :        IF ( HCO_IsVerb(HcoState%Config%Err ) ) THEN
    2672           0 :           WRITE(MSG,*) 'Base field registered: ', TRIM(Lct%Dct%cName)
    2673           0 :           CALL HCO_MSG( HcoState%Config%Err, msg )
    2674             :        ENDIF
    2675             : 
    2676             :        ! Advance to next line
    2677           0 :        CALL ListCont_NextCont ( HcoState%Config%ConfigList, Lct, FLAG )
    2678             :     ENDDO
    2679             : 
    2680             :     ! Cleanup
    2681           0 :     Lct => NULL()
    2682             : 
    2683             :     ! Return w/ success
    2684           0 :     CALL HCO_LEAVE( HcoState%Config%Err, RC )
    2685             : 
    2686             :   END SUBROUTINE Register_Base
    2687             : !EOC
    2688             : !------------------------------------------------------------------------------
    2689             : !                   Harmonized Emissions Component (HEMCO)                    !
    2690             : !------------------------------------------------------------------------------
    2691             : !BOP
    2692             : !
    2693             : ! !IROUTINE: Register_Scal
    2694             : !
    2695             : ! !DESCRIPTION: Subroutine Register\_Scal registers all scale factors.
    2696             : !\\
    2697             : !\\
    2698             : ! !INTERFACE:
    2699             : !
    2700           0 :   SUBROUTINE Register_Scal( HcoState, RC )
    2701             : !
    2702             : ! !USES:
    2703             : !
    2704             :     USE HCO_ReadList_Mod,      ONLY : ReadList_Set
    2705             :     USE HCO_DATACONT_MOD,      ONLY : ListCont_NextCont
    2706             : 
    2707             : !
    2708             : ! !INPUT PARAMETERS:
    2709             : !
    2710             :     TYPE(HCO_State),  POINTER       :: HcoState    ! HEMCO state object
    2711             : !
    2712             : ! !INPUT/OUTPUT PARAMETERS:
    2713             : !
    2714             :     INTEGER,          INTENT(INOUT) :: RC          ! Success or failure
    2715             : !
    2716             : ! !REVISION HISTORY:
    2717             : !  18 Jun 2013 - C. Keller - Initialization
    2718             : !  See https://github.com/geoschem/hemco for complete history
    2719             : !EOP
    2720             : !------------------------------------------------------------------------------
    2721             : !BOC
    2722             : !
    2723             : ! !LOCAL VARIABLES:
    2724             : !
    2725             :     ! Pointers
    2726             :     TYPE(ListCont),   POINTER :: Lct
    2727             :     TYPE(ScalIDCont), POINTER :: TmpScalIDCont
    2728             : 
    2729             :     ! Scalars
    2730             :     INTEGER                   :: cID, FLAG
    2731             :     CHARACTER(LEN=255)        :: LOC
    2732             :     CHARACTER(LEN=512)        :: msg
    2733             :     CHARACTER(LEN=  5)        :: strID
    2734             :     INTEGER                   :: ThisScalID
    2735             : 
    2736             :     !======================================================================
    2737             :     ! Register_Scal begins here
    2738             :     !======================================================================
    2739           0 :     loc = 'Register_Scal (HCO_CONFIG_MOD.F90)'
    2740             : 
    2741             :     ! Enter
    2742           0 :     CALL HCO_ENTER ( HcoState%Config%Err, loc, RC )
    2743           0 :     IF ( RC /= HCO_SUCCESS ) THEN
    2744           0 :        msg = 'Error encountered in routine "HCO_Enter"!'
    2745           0 :        CALL HCO_Error( msg, RC, thisLoc=loc )
    2746           0 :        RETURN
    2747             :     ENDIF
    2748             : 
    2749             :     ! Loop over all scale factor ids
    2750           0 :     Lct           => NULL()
    2751           0 :     TmpScalIDCont => HcoState%Config%ScalIDList
    2752           0 :     DO WHILE ( ASSOCIATED( TmpScalIDCont ) )
    2753             : 
    2754             :        ! Extract this scale factor ID
    2755           0 :        ThisScalID = TmpScalIDCont%ScalID
    2756             : 
    2757             :        ! Make ThisLine point to first element of ConfigList
    2758           0 :        Lct => NULL()
    2759           0 :        CALL ListCont_NextCont ( HcoState%Config%ConfigList, Lct, FLAG )
    2760             : 
    2761             :        ! Loop over all lines in input file and find the one with the
    2762             :        ! correct scale factor ID
    2763           0 :        DO WHILE ( FLAG == HCO_SUCCESS )
    2764             : 
    2765             :           ! Leave if this is the wanted container.
    2766           0 :           IF ( ASSOCIATED(Lct%Dct)) THEN
    2767           0 :              IF ( Lct%Dct%ScalID == ThisScalID ) EXIT
    2768             :           ENDIF
    2769             : 
    2770             :           ! Advance to next line otherwise
    2771           0 :           CALL ListCont_NextCont ( HcoState%Config%ConfigList, Lct, FLAG )
    2772             :        ENDDO
    2773             : 
    2774             :        ! Return error if scale factor ID not found
    2775           0 :        IF ( .NOT. ASSOCIATED(Lct) ) THEN
    2776           0 :           WRITE ( strID, * ) ThisScalID
    2777           0 :           msg = 'Container ID not found: ' // strID
    2778           0 :           CALL HCO_Error( msg, RC, thisLoc=loc )
    2779           0 :           RETURN
    2780             :        ENDIF
    2781             : 
    2782             :        ! Return w/ error if container not scale factor or mask
    2783           0 :        IF ( Lct%Dct%DctType == HCO_DCTTYPE_BASE ) THEN
    2784           0 :           WRITE ( strID, * ) ThisScalID
    2785           0 :           MSG = 'Container ID belongs to base field: ' // strID
    2786           0 :           CALL HCO_Error( msg, RC, thisLoc=loc )
    2787           0 :           RETURN
    2788             :        ENDIF
    2789             : 
    2790             :        ! Check if this scale factor has a mask field assigned to
    2791             :        ! it, in which case we have to make sure that the mask field
    2792             :        ! becomes registered in the scale factor list ScalIDList.
    2793             :        ! We can do this while evaluating ScalIDList due to the dynamic
    2794             :        ! structure of the linked list with new containers simply being
    2795             :        ! added to the end of the list.
    2796           0 :        IF ( Lct%Dct%nScalID > 0 ) THEN
    2797           0 :           CALL ScalID_Register ( Lct%Dct, HcoState%Config, RC )
    2798           0 :           IF ( RC /= HCO_SUCCESS ) THEN
    2799           0 :              msg = 'Error encountered in routine "ScalID_Register"!'
    2800           0 :              CALL HCO_Error( msg, RC, thisLoc=loc )
    2801           0 :              RETURN
    2802             :           ENDIF
    2803             :        ENDIF
    2804             : 
    2805             :        ! Register container in ReadList. Containers will be listed
    2806             :        ! in the reading lists sorted by cID.
    2807           0 :        CALL ReadList_Set( HcoState, Lct%Dct, RC )
    2808           0 :        IF ( RC /= HCO_SUCCESS ) THEN
    2809           0 :           msg = 'Error encountered in "ReadList_Set"!'
    2810           0 :           CALL HCO_Error( msg, RC, thisLoc=loc )
    2811           0 :           RETURN
    2812             :        ENDIF
    2813             : 
    2814             :        ! Print some information if verbose mode is on
    2815           0 :        IF ( HCO_IsVerb(HcoState%Config%Err ) ) THEN
    2816           0 :           WRITE(MSG,*) 'Scale field registered: ', TRIM(Lct%Dct%cName)
    2817           0 :           CALL HCO_MSG( HcoState%Config%Err, msg )
    2818             :        ENDIF
    2819             : 
    2820             :        ! Advance
    2821           0 :        TmpScalIDCont => TmpScalIDCont%NEXT
    2822             : 
    2823             :     ENDDO
    2824             : 
    2825             :     ! Cleanup
    2826           0 :     Lct           => NULL()
    2827           0 :     TmpScalIDCont => NULL()
    2828             : 
    2829             :     ! Return w/ success
    2830           0 :     CALL HCO_LEAVE( HcoState%Config%Err, RC )
    2831             : 
    2832             :   END SUBROUTINE Register_Scal
    2833             : !EOC
    2834             : !------------------------------------------------------------------------------
    2835             : !                   Harmonized Emissions Component (HEMCO)                    !
    2836             : !------------------------------------------------------------------------------
    2837             : !BOP
    2838             : !
    2839             : ! !IROUTINE: Get_targetID
    2840             : !
    2841             : ! !DESCRIPTION: Subroutine Get\_targetID returns the target ID of a
    2842             : ! container. The target ID can point to the container ID (cID) of
    2843             : ! another base field if multiple emissions shall be added together
    2844             : ! prior to emission calculation, e.g. sectoral emissions data with
    2845             : ! same species ID, category, hierarchy, extension number, scale factors,
    2846             : ! etc.
    2847             : !\\
    2848             : !\\
    2849             : ! Target ID is set to -999 if there exists another inventory over
    2850             : ! the full spatial region covered by this CPU for this species but
    2851             : ! with higher hierarchy. In this case, we can ignore the current
    2852             : ! container from here onwards!
    2853             : !\\
    2854             : !\\
    2855             : ! !INTERFACE:
    2856             : !
    2857           0 :   SUBROUTINE Get_targetID( HcoState, Lct, targetID, RC )
    2858             : !
    2859             : ! !USES:
    2860             : !
    2861             :     USE HCO_DataCont_Mod, ONLY : ListCont_Find
    2862             :     USE HCO_DataCont_Mod, ONLY : ListCont_NextCont
    2863             : !
    2864             : ! !INPUT PARAMETERS:
    2865             : !
    2866             :     TYPE(HCO_State), POINTER       :: HcoState
    2867             :     TYPE(ListCont),  POINTER       :: Lct
    2868             : !
    2869             : ! !OUTPUT PARAMETERS:
    2870             : !
    2871             :     INTEGER,         INTENT(  OUT) :: targetID
    2872             : !
    2873             : ! !INPUT/OUTPUT PARAMETERS:
    2874             : !
    2875             :     INTEGER,         INTENT(INOUT) :: RC
    2876             : !
    2877             : ! !NOTE: If data from multiple containers are added, the target ID
    2878             : ! is always set to the lowest cID of all involved containers, i.e.
    2879             : ! data are added to the container with the lowest cID. This makes
    2880             : ! sure that data is not accidentally overwritten, e.g. when updating
    2881             : ! container contents!
    2882             : !
    2883             : ! !REVISION HISTORY:
    2884             : !  11 Apr 2013 - C. Keller - Initialization
    2885             : !  See https://github.com/geoschem/hemco for complete history
    2886             : !EOP
    2887             : !------------------------------------------------------------------------------
    2888             : !BOC
    2889             : !
    2890             : ! !LOCAL VARIABLES:
    2891             : !
    2892             :     ! Pointers
    2893             :     TYPE(ListCont), POINTER   :: tmpLct
    2894             :     TYPE(ListCont), POINTER   :: mskLct
    2895             : 
    2896             :     ! Scalars
    2897             :     INTEGER                   :: HcoID, Cat, Hier, Scal, ExtNr, cID
    2898             :     INTEGER                   :: tmpID
    2899             :     INTEGER                   :: I, J, FLAG1, tmpCov
    2900             :     LOGICAL                   :: found, sameCont
    2901             :     CHARACTER(LEN=255)        :: loc
    2902             :     CHARACTER(LEN=512)        :: msg
    2903             :     CHARACTER(LEN=  7)        :: strID
    2904             : 
    2905             :     !======================================================================
    2906             :     ! Get_targetID begins here
    2907             :     !======================================================================
    2908           0 :     loc = 'Get_targetID (HCO_CONFIG_MOD.F90)'
    2909             : 
    2910             :     ! Enter
    2911           0 :     CALL HCO_ENTER ( HcoState%Config%Err, LOC, RC )
    2912           0 :     IF ( RC /= HCO_SUCCESS ) THEN
    2913           0 :        msg = 'Error encountered in routine "HCO_Enter"!'
    2914           0 :        CALL HCO_ERROR( msg, RC, thisLoc=LOC )
    2915           0 :        RETURN
    2916             :     ENDIF
    2917             : 
    2918             :     ! Initialize
    2919           0 :     tmpLct => NULL()
    2920           0 :     mskLct => NULL()
    2921             : 
    2922             :     ! Get Tracer ID, category and hierarchy of entry to be checked
    2923           0 :     cID   = Lct%Dct%cID
    2924           0 :     ExtNr = Lct%Dct%ExtNr
    2925           0 :     Cat   = Lct%Dct%Cat
    2926           0 :     Hier  = Lct%Dct%Hier
    2927           0 :     HcoID = Lct%Dct%HcoID
    2928             : 
    2929             :     ! By default, set target ID to container ID
    2930           0 :     targetID = cID
    2931             : 
    2932             :     ! If ExtNr is -999, always read this field. ExtNr becomes zero
    2933             :     ! if the extension number entry in the configuration file is the
    2934             :     ! wildcard character
    2935           0 :     IF ( ExtNr == -999 ) THEN
    2936           0 :        CALL HCO_LEAVE( HcoState%Config%Err, RC )
    2937           0 :        RETURN
    2938             :     ENDIF
    2939             : 
    2940             :     ! If species ID is zero, always read this field as is, i.e. don't
    2941             :     ! skip it and don't add it to another field!
    2942             :     ! Species ID become zero if the species ID entry in the
    2943             :     ! configuration file is the wildcard character.
    2944           0 :     IF ( HcoID == 0 ) THEN
    2945           0 :        CALL HCO_LEAVE( HcoState%Config%Err, RC )
    2946           0 :        RETURN
    2947             :     ENDIF
    2948             : 
    2949             :     ! Check all scale factors of the current container to see if one
    2950             :     ! of them is a mask that has no valid entries over the domain of
    2951             :     ! this CPU. In this case we don't have to consider this field at
    2952             :     ! all!
    2953           0 :     IF ( Lct%Dct%nScalID > 0 ) THEN
    2954           0 :        DO I = 1, Lct%Dct%nScalID
    2955             : 
    2956             :           ! Check if it's a valid scale factor
    2957           0 :           IF ( Lct%Dct%Scal_cID(I) < 0 ) CYCLE
    2958             : 
    2959             :           ! Find container with this container ID
    2960             :           ! Note: this should always look up the container ID, but make
    2961             :           ! check for safety's sake.
    2962           0 :           tmpID = Lct%Dct%Scal_cID(I)
    2963           0 :           IF ( .NOT. Lct%Dct%Scal_cID_set ) THEN
    2964             :              CALL ListCont_Find ( HcoState%Config%ConfigList, &
    2965           0 :                                   tmpID, 1, FOUND, mskLct )
    2966             :           ELSE
    2967             :              CALL ListCont_Find ( HcoState%Config%ConfigList, &
    2968           0 :                                   tmpID, 0, FOUND, mskLct )
    2969             :           ENDIF
    2970             : 
    2971             :           ! Error if scale factor not found
    2972           0 :           IF ( .NOT. FOUND ) THEN
    2973           0 :              WRITE ( strID, * ) Lct%Dct%Scal_cID(I)
    2974           0 :              msg = 'No scale factor with cID: ' // TRIM(strID)
    2975           0 :              CALL HCO_Error( msg, RC, thisLoc=loc )
    2976           0 :              RETURN
    2977             :           ENDIF
    2978             : 
    2979             :           ! Check if this is a mask with zero coverage over this CPU, in
    2980             :           ! which case we don't need to consider the base field at all!
    2981           0 :           IF ( (mskLct%Dct%DctType  == HCO_DCTTYPE_MASK ) .AND. &
    2982           0 :                (mskLct%Dct%Dta%Cover == 0 )        ) THEN
    2983           0 :              targetID = -999
    2984           0 :              IF ( HCO_IsVerb(HcoState%Config%Err ) ) THEN
    2985             :                 WRITE(MSG,*) 'Data not defined over this CPU, skip ' // &
    2986           0 :                      TRIM(Lct%Dct%cName)
    2987           0 :                 CALL HCO_MSG( HcoState%Config%Err, msg )
    2988             :              ENDIF
    2989             : 
    2990             :              ! Return
    2991           0 :              CALL HCO_LEAVE( HcoState%Config%Err, RC )
    2992           0 :              RETURN
    2993             :           ENDIF
    2994             :        ENDDO ! I
    2995             :     ENDIF
    2996             : 
    2997             :     ! Now find out if there is another base field for the same species,
    2998             :     ! emission category and extension number, but higher hierarchy.
    2999             :     ! Such a field also needs to have full coverage over this CPU,
    3000             :     ! then we can ignore the current container.
    3001             : 
    3002             :     ! Initialize looping pointer
    3003           0 :     tmpLct => NULL()
    3004           0 :     CALL ListCont_NextCont ( HcoState%Config%ConfigList, tmpLct, FLAG1 )
    3005             : 
    3006             :     ! Loop over containers
    3007           0 :     DO WHILE ( FLAG1 == HCO_SUCCESS )
    3008             : 
    3009             :        ! Advance to next container if data container not defined
    3010           0 :        IF ( .NOT. ASSOCIATED(tmpLct%Dct) ) THEN
    3011           0 :           CALL ListCont_NextCont ( HcoState%Config%ConfigList, tmpLct, FLAG1 )
    3012           0 :           CYCLE
    3013             :        ENDIF
    3014             : 
    3015             :        ! Advance to next container if this is the current container
    3016           0 :        IF ( tmpLct%Dct%cID == cID ) THEN
    3017           0 :           CALL ListCont_NextCont ( HcoState%Config%ConfigList, tmpLct, FLAG1 )
    3018           0 :           CYCLE
    3019             :        ENDIF
    3020             : 
    3021             :        ! Advance to next container if this is not a base field
    3022           0 :        IF ( tmpLct%Dct%DctType /= HCO_DCTTYPE_BASE ) THEN
    3023           0 :           CALL ListCont_NextCont ( HcoState%Config%ConfigList, tmpLct, FLAG1 )
    3024           0 :           CYCLE
    3025             :        ENDIF
    3026             : 
    3027             :        ! Advance to next container if not the same extension nr
    3028           0 :        IF ( tmpLct%Dct%ExtNr /= ExtNr ) THEN
    3029           0 :           CALL ListCont_NextCont ( HcoState%Config%ConfigList, tmpLct, FLAG1 )
    3030           0 :           CYCLE
    3031             :        ENDIF
    3032             : 
    3033             :        ! Advance to next container if not the same species
    3034           0 :        IF ( tmpLct%Dct%HcoID /= HcoID ) THEN
    3035           0 :           CALL ListCont_NextCont ( HcoState%Config%ConfigList, tmpLct, FLAG1 )
    3036           0 :           CYCLE
    3037             :        ENDIF
    3038             : 
    3039             :        ! Advance to next container if not the same category
    3040           0 :        IF ( tmpLct%Dct%Cat /= Cat ) THEN
    3041           0 :           CALL ListCont_NextCont ( HcoState%Config%ConfigList, tmpLct, FLAG1 )
    3042           0 :           CYCLE
    3043             :        ENDIF
    3044             : 
    3045             :        ! Advance to next container if lower hierarchy
    3046           0 :        IF ( tmpLct%Dct%Hier < Hier ) THEN
    3047           0 :           CALL ListCont_NextCont ( HcoState%Config%ConfigList, tmpLct, FLAG1 )
    3048           0 :           CYCLE
    3049             :        ENDIF
    3050             : 
    3051             :        ! Advance to next container if this container has limited time
    3052             :        ! coverage. Emissions with limited time coverage may not be used
    3053             :        ! during all of the simulation time, so it's important to keep the
    3054             :        ! lower hierarchy emission fields in memory in case that those need
    3055             :        ! to be used instead (e.g. if EDGAR shall only be used between years
    3056             :        ! 2005 and 2013, we should keep GEIA in case that we are outside of
    3057             :        ! that time window).
    3058             :        IF ( ( tmpLct%Dct%Dta%CycleFlag == HCO_CFLAG_RANGE    ) .OR. &
    3059           0 :             ( tmpLct%Dct%Dta%CycleFlag == HCO_CFLAG_EXACT    ) .OR. &
    3060             :             ( tmpLct%Dct%Dta%CycleFlag == HCO_CFLAG_RANGEAVG )      ) THEN
    3061           0 :           CALL ListCont_NextCont ( HcoState%Config%ConfigList, tmpLct, FLAG1 )
    3062           0 :           CYCLE
    3063             :        ENDIF
    3064             : 
    3065             :        ! Check for coverage of tmpLct. Default = full coverage (1)
    3066           0 :        tmpCov = 1
    3067             : 
    3068             :        ! Check all scale factors of tmpLct to see if this base
    3069             :        ! field has full coverage over this CPU domain or not.
    3070           0 :        IF ( tmpLct%Dct%nScalID > 0 ) THEN
    3071           0 :           DO I = 1, tmpLct%Dct%nScalID
    3072             : 
    3073             :              ! Check if it's a valid scale factor
    3074           0 :              IF ( tmpLct%Dct%Scal_cID(I) < 0 ) CYCLE
    3075             : 
    3076           0 :              tmpID = tmpLct%Dct%Scal_cID(I)
    3077           0 :              IF ( .NOT. tmpLct%Dct%Scal_cID_set ) THEN
    3078             :                 CALL ListCont_Find ( HcoState%Config%ConfigList, &
    3079           0 :                                      tmpID, 1, FOUND, mskLct )
    3080             :              ELSE
    3081             :                 CALL ListCont_Find ( HcoState%Config%ConfigList, &
    3082           0 :                                      tmpID, 0, FOUND, mskLct )
    3083             :              ENDIF
    3084             : 
    3085             :              ! Error if container not found
    3086           0 :              IF ( .NOT. FOUND ) THEN
    3087           0 :                 WRITE(MSG,*) 'No scale factor with ID: ', tmpID
    3088           0 :                 CALL HCO_Error( msg, RC, thisLoc=loc )
    3089           0 :                 RETURN
    3090             :              ENDIF
    3091             : 
    3092             :              ! Write out coverage.
    3093             :              ! Note: If one mask has only partial coverage, retain that
    3094             :              ! value! If we encounter a mask with no coverage, set coverage
    3095             :              ! to zero and leave immediately.
    3096           0 :              IF ( (mskLct%Dct%DctType == HCO_DCTTYPE_MASK) ) THEN
    3097           0 :                 IF ( mskLct%Dct%Dta%Cover == -1 ) THEN
    3098             :                    tmpCov = -1
    3099           0 :                 ELSEIF ( mskLct%Dct%Dta%Cover == 0 ) THEN
    3100             :                    tmpCov = 0
    3101             :                    EXIT
    3102             :                 ENDIF
    3103             :              ENDIF
    3104             :           ENDDO ! I
    3105             :        ENDIF
    3106             : 
    3107             :        ! If tmpLct has no coverage, we can ignore this tmpLct as
    3108             :        ! it will never overwrite data of currCont
    3109           0 :        IF ( tmpCov == 0 ) THEN
    3110           0 :           CALL ListCont_NextCont ( HcoState%Config%ConfigList, tmpLct, FLAG1 )
    3111           0 :           CYCLE
    3112             :        ENDIF
    3113             : 
    3114             :        ! If we made it up to here and tmpLct has full coverage, then
    3115             :        ! tmpLct has the same species ID, category, ext. nr.,
    3116             :        ! and a higher (or the same) hierarchy as Lct.
    3117             : 
    3118             :        ! If hierarchy of tmpLct is higher than Lct and this
    3119             :          ! container has total coverage over this CPU, it will always
    3120             :          ! replace all values of Lct. Hence, set targetID to -999
    3121             :          ! (= ignore container) and return here.
    3122           0 :        IF ( (tmpLct%Dct%Hier > Hier) .AND. (tmpCov==1) ) THEN
    3123           0 :           IF ( HCO_IsVerb(HcoState%Config%Err ) ) THEN
    3124           0 :              WRITE(MSG,*) 'Skip container ', TRIM(Lct%Dct%cName), &
    3125           0 :                           ' because of ', TRIM(tmpLct%Dct%cName)
    3126           0 :              CALL HCO_MSG( HcoState%Config%Err, msg )
    3127             :           ENDIF
    3128             : 
    3129             :           ! Return
    3130           0 :           targetID = -999
    3131           0 :           CALL HCO_LEAVE( HcoState%Config%Err, RC )
    3132           0 :           RETURN
    3133             :        ENDIF
    3134             : 
    3135             :        ! If currCont and tmpLct have same hierarchy, scale factors,
    3136             :        ! and update frequencies, we may add the two fields together
    3137             :        ! in order to make emission calculation more efficient.
    3138             :        ! Thus, set target ID to the lower of the two container IDs.
    3139             :        ! This procedure will ensure that emission data are added
    3140             :        ! when registering/updating containers in the emissions list
    3141             :        ! (EmisList). Since containers are sorted in ReadList with
    3142             :        ! increasing cID, pick the lowest cID to make sure that all
    3143             :        ! fields are properly added.
    3144             :        ! Note: this option is currently disabled for ESMF applications.
    3145           0 :        IF ( tmpLct%Dct%Hier == Hier .AND. .NOT. HcoState%Options%isESMF ) THEN
    3146             : 
    3147             :           ! temporary flag
    3148           0 :           sameCont = .TRUE.
    3149             : 
    3150             :           ! Check for same scale factors
    3151           0 :           IF ( tmpLct%Dct%nScalID /= Lct%Dct%nScalID ) THEN
    3152             :              sameCont = .FALSE.
    3153             :           ELSE
    3154           0 :              DO I = 1, tmpLct%Dct%nScalID
    3155           0 :                 IF (  tmpLct%Dct%Scal_cID(I) /= &
    3156           0 :                      Lct%Dct%Scal_cID(I)     ) THEN
    3157             :                    sameCont = .FALSE.
    3158             :                    EXIT
    3159             :                 ENDIF
    3160             :              ENDDO
    3161             :           ENDIF
    3162             : 
    3163             :           ! Check for same update frequencies
    3164           0 :           IF ( sameCont ) THEN
    3165           0 :              IF    (tmpLct%Dct%Dta%ncYrs(1)/=Lct%Dct%Dta%ncYrs(1)) THEN
    3166             :                 sameCont = .FALSE.
    3167           0 :              ELSEIF(tmpLct%Dct%Dta%ncYrs(2)/=Lct%Dct%Dta%ncYrs(2)) THEN
    3168             :                 sameCont = .FALSE.
    3169           0 :              ELSEIF(tmpLct%Dct%Dta%ncMts(1)/=Lct%Dct%Dta%ncMts(1)) THEN
    3170             :                 sameCont = .FALSE.
    3171           0 :              ELSEIF(tmpLct%Dct%Dta%ncMts(2)/=Lct%Dct%Dta%ncMts(2)) THEN
    3172             :                 sameCont = .FALSE.
    3173           0 :              ELSEIF(tmpLct%Dct%Dta%ncDys(1)/=Lct%Dct%Dta%ncDys(1)) THEN
    3174             :                 sameCont = .FALSE.
    3175           0 :              ELSEIF(tmpLct%Dct%Dta%ncDys(2)/=Lct%Dct%Dta%ncDys(2)) THEN
    3176             :                 sameCont = .FALSE.
    3177           0 :              ELSEIF(tmpLct%Dct%Dta%ncHrs(1)/=Lct%Dct%Dta%ncHrs(1)) THEN
    3178             :                 sameCont = .FALSE.
    3179           0 :              ELSEIF(tmpLct%Dct%Dta%ncHrs(2)/=Lct%Dct%Dta%ncHrs(2)) THEN
    3180             :                 sameCont = .FALSE.
    3181             :              ENDIF
    3182             :           ENDIF
    3183             : 
    3184             :           ! Check for same emitted level
    3185             :           IF ( sameCont ) THEN
    3186             :              IF ( ( tmpLct%Dct%Dta%SpaceDim /= Lct%Dct%Dta%SpaceDim ) .OR. &
    3187             :                   ( tmpLct%Dct%Dta%Levels   /= Lct%Dct%Dta%Levels   ) .OR. &
    3188           0 :                   ( tmpLct%Dct%Dta%EmisL1   /= Lct%Dct%Dta%EmisL1   ) .OR. &
    3189             :                   ( tmpLct%Dct%Dta%EmisL2   /= Lct%Dct%Dta%EmisL2   ) ) THEN
    3190             :                 sameCont = .FALSE.
    3191             :              ENDIF
    3192             :           ENDIF
    3193             : 
    3194             :           ! Finally, check for "same" container names. This checks the
    3195             :           ! container names ignoring the name 'tags'.
    3196             :           IF ( sameCont ) THEN
    3197           0 :              sameCont = Check_ContNames( tmpLct, Lct )
    3198             :           ENDIF
    3199             : 
    3200             :           ! If "same" containers, set target ID to container ID of
    3201             :           ! tmpLct if this value is lower than current target ID.
    3202           0 :           IF ( sameCont ) THEN
    3203           0 :              targetID = MIN( targetID, tmpLct%Dct%cID )
    3204             :           ENDIF
    3205             : 
    3206             :        ENDIF
    3207             : 
    3208             :        ! Advance to next line
    3209             :        ! Don't return here, because it is still possible that there is
    3210             :        ! another inventory in the list coming up which overwrites this
    3211             :        ! inventory (or another field emissions shall be added to which
    3212             :        ! has lower container ID and hence needs to be the target
    3213             :        ! container!).
    3214           0 :        CALL ListCont_NextCont ( HcoState%Config%ConfigList, tmpLct, FLAG1 )
    3215             : 
    3216             :     ENDDO !Loop over all entries in ConfigList (tmpLct)
    3217             : 
    3218             :     ! Free pointers
    3219           0 :     tmpLct => NULL()
    3220           0 :     mskLct => NULL()
    3221             : 
    3222             :     ! Leave w/ success
    3223           0 :     CALL HCO_LEAVE( HcoState%Config%Err, RC )
    3224             : 
    3225             :   END SUBROUTINE Get_targetID
    3226             : !EOC
    3227             : !------------------------------------------------------------------------------
    3228             : !                   Harmonized Emissions Component (HEMCO)                    !
    3229             : !------------------------------------------------------------------------------
    3230             : !BOP
    3231             : !
    3232             : ! !IROUTINE: Calc_Coverage
    3233             : !
    3234             : ! !DESCRIPTION: Function Calc\_Coverage calculates the coverage of
    3235             : ! the specified lon/lat box with the area covered by the inventory.
    3236             : ! Returns 0 if no overlap, 1 if complete overlap, and -1 for partial
    3237             : ! overlap.
    3238             : !\\
    3239             : !\\
    3240             : ! !INTERFACE:
    3241             : !
    3242             :   FUNCTION Calc_Coverage( msk_x1, msk_x2, msk_y1, msk_y2,  &
    3243             :                           cpu_x1, cpu_x2, cpu_y1, cpu_y2 ) RESULT ( COVERAGE )
    3244             : !
    3245             : ! !INPUT PARAMETERS:
    3246             : !
    3247             :     INTEGER, INTENT(IN) :: msk_x1
    3248             :     INTEGER, INTENT(IN) :: msk_x2
    3249             :     INTEGER, INTENT(IN) :: msk_y1
    3250             :     INTEGER, INTENT(IN) :: msk_y2
    3251             :     INTEGER, INTENT(IN) :: cpu_x1
    3252             :     INTEGER, INTENT(IN) :: cpu_x2
    3253             :     INTEGER, INTENT(IN) :: cpu_y1
    3254             :     INTEGER, INTENT(IN) :: cpu_y2
    3255             : !
    3256             : ! !RETURN VALUE:
    3257             : !
    3258             :     INTEGER             :: COVERAGE
    3259             : !
    3260             : ! !REVISION HISTORY:
    3261             : !  11 Apr 2013 - C. Keller: Initialization
    3262             : !  See https://github.com/geoschem/hemco for complete history
    3263             : !EOP
    3264             : !------------------------------------------------------------------------------
    3265             : !BOC
    3266             : 
    3267             :     !======================================================================
    3268             :     ! CALC_COVERAGE begins here
    3269             :     !======================================================================
    3270             : 
    3271             :     ! Check if specified area does not overlap with inventory
    3272             :     COVERAGE = 1
    3273             :     IF ( (msk_x1 > cpu_x2) .OR. (msk_x2 < cpu_x1) .OR. &
    3274             :          (msk_y1 > cpu_y2) .OR. (msk_y2 < cpu_y1)        ) THEN
    3275             :        COVERAGE = 0
    3276             :        RETURN
    3277             :     ENDIF
    3278             : 
    3279             :     ! Check for partial coverage
    3280             :     IF ( (msk_x1 > cpu_x1) .OR. (msk_x2 < cpu_x2) .OR. &
    3281             :          (msk_y1 > cpu_y1) .OR. (msk_y2 < cpu_y2)        ) THEN
    3282             :        COVERAGE = -1
    3283             :     ENDIF
    3284             : 
    3285             :   END FUNCTION Calc_Coverage
    3286             : !EOC
    3287             : !------------------------------------------------------------------------------
    3288             : !                   Harmonized Emissions Component (HEMCO)                    !
    3289             : !------------------------------------------------------------------------------
    3290             : !BOP
    3291             : !
    3292             : ! !IROUTINE: ReadAndSplit_Line
    3293             : !
    3294             : ! !DESCRIPTION: Subroutine ReadAndSplit\_Line reads a line from the HEMCO
    3295             : ! config file and parses the specified columns into the passed integer
    3296             : ! and character variables.  If the optional argument inLine is provided,
    3297             : ! this line will be parsed, otherwise a new line will be read from the config
    3298             : ! file. If the optional argument outLine is provided, this variable will hold
    3299             : ! the parsed line.
    3300             : !\\
    3301             : !\\
    3302             : ! This routine splits the input line (or the next line of an open file with
    3303             : ! ID IU\_HCO), using the HEMCO separator (default: space) as separator. The
    3304             : ! resulting elements are then passed to the specified output characters and
    3305             : ! integers. For example, to pass the 5th element of a line to variable int1,
    3306             : ! set int1cl to 5, etc. An error will be returned (STAT=100) if any of the
    3307             : ! output columns exceeds the number of line elements. The optional argument
    3308             : ! optcl can be used to denote an optional value, e.g. no error is returned
    3309             : ! if the value at position optcl cannot be read. Only one optional value can
    3310             : ! be specified.
    3311             : !\\
    3312             : !\\
    3313             : ! !INTERFACE:
    3314             : !
    3315           0 :   SUBROUTINE ReadAndSplit_Line( HcoConfig, IU_HCO,  char1, chr1cl, &
    3316             :                                 char2,     chr2cl,  char3, chr3cl, &
    3317             :                                 char4,     chr4cl,  char5, chr5cl, &
    3318             :                                 char6,     chr6cl,  char7, chr7cl, &
    3319             :                                 char8,     chr8cl,  char9, chr9cl, &
    3320             :                                 char10,    chr10cl,                &
    3321             :                                 int1,      int1cl,  int2,  int2cl, &
    3322           0 :                                 int3,      int3cl,  STAT,  inLine, &
    3323           0 :                                 outLine,   optcl                    )
    3324             : !
    3325             : ! !USES:
    3326             : !
    3327             :     USE HCO_CHARPAK_Mod,    ONLY : STRREPL, STRSPLIT
    3328             : !
    3329             : ! !INPUT PARAMETERS:
    3330             : !
    3331             :     TYPE(ConfigObj),    POINTER                 :: HcoConfig
    3332             :     INTEGER,            INTENT(IN   )           :: IU_HCO
    3333             :     INTEGER,            INTENT(IN   )           :: chr1cl
    3334             :     INTEGER,            INTENT(IN   )           :: chr2cl
    3335             :     INTEGER,            INTENT(IN   )           :: chr3cl
    3336             :     INTEGER,            INTENT(IN   )           :: chr4cl
    3337             :     INTEGER,            INTENT(IN   )           :: chr5cl
    3338             :     INTEGER,            INTENT(IN   )           :: chr6cl
    3339             :     INTEGER,            INTENT(IN   )           :: chr7cl
    3340             :     INTEGER,            INTENT(IN   )           :: chr8cl
    3341             :     INTEGER,            INTENT(IN   )           :: chr9cl
    3342             :     INTEGER,            INTENT(IN   )           :: chr10cl
    3343             :     INTEGER,            INTENT(IN   )           :: int1cl
    3344             :     INTEGER,            INTENT(IN   )           :: int2cl
    3345             :     INTEGER,            INTENT(IN   )           :: int3cl
    3346             :     CHARACTER(LEN=255), INTENT(IN   ), OPTIONAL :: inLINE
    3347             :     INTEGER,            INTENT(IN   ), OPTIONAL :: optcl
    3348             : !
    3349             : ! !OUTPUT PARAMETERS:
    3350             : !
    3351             :     CHARACTER(LEN=*),   INTENT(INOUT)           :: char1
    3352             :     CHARACTER(LEN=*),   INTENT(INOUT)           :: char2
    3353             :     CHARACTER(LEN=*),   INTENT(INOUT)           :: char3
    3354             :     CHARACTER(LEN=*),   INTENT(INOUT)           :: char4
    3355             :     CHARACTER(LEN=*),   INTENT(INOUT)           :: char5
    3356             :     CHARACTER(LEN=*),   INTENT(INOUT)           :: char6
    3357             :     CHARACTER(LEN=*),   INTENT(INOUT)           :: char7
    3358             :     CHARACTER(LEN=*),   INTENT(INOUT)           :: char8
    3359             :     CHARACTER(LEN=*),   INTENT(INOUT)           :: char9
    3360             :     CHARACTER(LEN=*),   INTENT(INOUT)           :: char10
    3361             :     INTEGER,            INTENT(INOUT)           :: int1
    3362             :     INTEGER,            INTENT(INOUT)           :: int2
    3363             :     INTEGER,            INTENT(INOUT)           :: int3
    3364             :     CHARACTER(LEN=255), INTENT(  OUT), OPTIONAL :: outLINE
    3365             : !
    3366             : ! !INPUT/OUTPUT PARAMETERS:
    3367             : !
    3368             :     INTEGER,            INTENT(INOUT)           :: STAT
    3369             : !
    3370             : ! !REVISION HISTORY:
    3371             : !  28 Aug 2013 - C. Keller - Initial version
    3372             : !  See https://github.com/geoschem/hemco for complete history
    3373             : !EOP
    3374             : !------------------------------------------------------------------------------
    3375             : !BOC
    3376             : !
    3377             : ! !LOCAL VARIABLES:
    3378             : !
    3379             :     INTEGER               :: N, OPT, STRLEN, RC
    3380             :     CHARACTER(LEN=255)    :: LINE
    3381             :     CHARACTER(LEN=255)    :: SUBSTR(255)
    3382             :     LOGICAL               :: EOF
    3383             : 
    3384             :     !======================================================================
    3385             :     ! ReadAndSplit_Line begins here
    3386             :     !======================================================================
    3387             : 
    3388             :     ! Output status
    3389           0 :     STAT = 0
    3390             : 
    3391             :     ! ---------------------------------------------------------------------
    3392             :     ! Read line and split column
    3393             :     ! ---------------------------------------------------------------------
    3394           0 :     IF ( PRESENT(inLINE) ) THEN
    3395           0 :        LINE = inLINE
    3396             :     ELSE
    3397             :        ! Read line
    3398           0 :        CALL HCO_READLINE( IU_HCO, LINE, EOF, RC )
    3399             : 
    3400             :        ! Return w/ error
    3401           0 :        IF ( RC /= HCO_SUCCESS ) THEN
    3402           0 :           STAT = 999
    3403           0 :           RETURN
    3404             :        ENDIF
    3405             : 
    3406             :        ! End of file
    3407           0 :        IF ( EOF ) THEN
    3408           0 :           STAT = -999
    3409           0 :           RETURN
    3410             :        ENDIF
    3411             :     ENDIF
    3412             : 
    3413             :     ! Check for output line
    3414           0 :     IF ( PRESENT(outLINE) ) outLINE = LINE
    3415             : 
    3416             :     ! Return here with flag = 10 if line starts with 'END SECTION'.
    3417           0 :     IF ( INDEX ( LINE, 'END SECTION' ) > 0 ) THEN
    3418           0 :        STAT = 10
    3419           0 :        RETURN
    3420             :     ENDIF
    3421             : 
    3422             :     ! Return here with flag = 1 if line is commented
    3423           0 :     IF ( LINE(1:1) == HCO_CMT ) THEN
    3424           0 :        STAT = 1
    3425           0 :        RETURN
    3426             :     ENDIF
    3427             : 
    3428             :     ! Get string length
    3429           0 :     STRLEN = LEN(TRIM(LINE))
    3430             : 
    3431             :     ! Return here with flag = 5 is line is opening a (shortcut) bracket.
    3432           0 :     IF ( STRLEN > 3 ) THEN
    3433           0 :        IF ( LINE(1:3) == '(((' ) THEN
    3434           0 :           STAT = 5
    3435           0 :           RETURN
    3436             :        ENDIF
    3437             : 
    3438             :        ! Return here with flag = 6 is line is opening a (shortcut) bracket.
    3439           0 :        IF ( LINE(1:3) == ')))' ) THEN
    3440           0 :           STAT = 6
    3441           0 :           RETURN
    3442             :        ENDIF
    3443             :     ENDIF
    3444             : 
    3445             :     ! Return with flag = 1000 if this is a link to an include file.
    3446           0 :     IF ( STRLEN > 11 ) THEN
    3447           0 :        IF ( LINE(1:10) == '>>>include' ) THEN
    3448           0 :           IF ( PRESENT(outLINE) ) outLINE = outLINE(12:STRLEN)
    3449           0 :           STAT = 1000
    3450           0 :           RETURN
    3451             :        ENDIF
    3452             :     ENDIF
    3453             : 
    3454             :     ! Split line into columns
    3455           0 :     CALL STRREPL ( LINE, HCO_TAB, HCO_SPC )
    3456           0 :     CALL STRSPLIT( LINE, HCO_SPC, SUBSTR, N )
    3457             : 
    3458             :     ! Also ignore empty lines
    3459           0 :     IF ( N <= 1 ) THEN
    3460           0 :        STAT = 1
    3461           0 :        RETURN
    3462             :     ENDIF
    3463             : 
    3464             :     ! Are there any optional lines?
    3465           0 :     IF ( PRESENT(optcl) ) THEN
    3466           0 :        OPT = optcl
    3467             :     ELSE
    3468           0 :        OPT = -1
    3469             :     ENDIF
    3470             : 
    3471             :     ! ---------------------------------------------------------------------
    3472             :     ! Read characters as specified and write them into given variables
    3473             :     ! ---------------------------------------------------------------------
    3474             : 
    3475           0 :     CALL READCHAR( LINE, SUBSTR, N, chr1cl,  char1,  OPT, STAT )
    3476           0 :     IF ( STAT == 100 ) RETURN
    3477           0 :     CALL READCHAR( LINE, SUBSTR, N, chr2cl,  char2,  OPT, STAT )
    3478           0 :     IF ( STAT == 100 ) RETURN
    3479           0 :     CALL READCHAR( LINE, SUBSTR, N, chr3cl,  char3,  OPT, STAT )
    3480           0 :     IF ( STAT == 100 ) RETURN
    3481           0 :     CALL READCHAR( LINE, SUBSTR, N, chr4cl,  char4,  OPT, STAT )
    3482           0 :     IF ( STAT == 100 ) RETURN
    3483           0 :     CALL READCHAR( LINE, SUBSTR, N, chr5cl,  char5,  OPT, STAT )
    3484           0 :     IF ( STAT == 100 ) RETURN
    3485           0 :     CALL READCHAR( LINE, SUBSTR, N, chr6cl,  char6,  OPT, STAT )
    3486           0 :     IF ( STAT == 100 ) RETURN
    3487           0 :     CALL READCHAR( LINE, SUBSTR, N, chr7cl,  char7,  OPT, STAT )
    3488           0 :     IF ( STAT == 100 ) RETURN
    3489           0 :     CALL READCHAR( LINE, SUBSTR, N, chr8cl,  char8,  OPT, STAT )
    3490           0 :     IF ( STAT == 100 ) RETURN
    3491           0 :     CALL READCHAR( LINE, SUBSTR, N, chr9cl,  char9,  OPT, STAT )
    3492           0 :     IF ( STAT == 100 ) RETURN
    3493           0 :     CALL READCHAR( LINE, SUBSTR, N, chr10cl, char10, OPT, STAT )
    3494           0 :     IF ( STAT == 100 ) RETURN
    3495             : 
    3496             :     ! ---------------------------------------------------------------------
    3497             :     ! Read integers as specified and write them into given variables.
    3498             :     ! Value -999 is returned for wildcard characters.
    3499             :     ! ---------------------------------------------------------------------
    3500             : 
    3501           0 :     CALL READINT( HcoConfig%ExtList, LINE, SUBSTR, N, int1cl, int1, OPT, STAT )
    3502           0 :     IF ( STAT == 100 ) RETURN
    3503           0 :     CALL READINT( HcoConfig%ExtList, LINE, SUBSTR, N, int2cl, int2, OPT, STAT )
    3504           0 :     IF ( STAT == 100 ) RETURN
    3505           0 :     CALL READINT( HcoConfig%ExtList, LINE, SUBSTR, N, int3cl, int3, OPT, STAT )
    3506           0 :     IF ( STAT == 100 ) RETURN
    3507             : 
    3508             :   END SUBROUTINE ReadAndSplit_Line
    3509             : !EOC
    3510             : !------------------------------------------------------------------------------
    3511             : !                   Harmonized Emissions Component (HEMCO)                    !
    3512             : !------------------------------------------------------------------------------
    3513             : !BOP
    3514             : !
    3515             : ! !IROUTINE: READCHAR
    3516             : !
    3517             : ! !DESCRIPTION: Subroutine READCHAR is a helper routine to read character
    3518             : ! values from the HEMCO configuration file.
    3519             : !\\
    3520             : !\\
    3521             : ! !INTERFACE:
    3522             : !
    3523           0 :   SUBROUTINE READCHAR ( LINE, SUBSTR, N, chrcl, charout, OPT, STAT )
    3524             : !
    3525             : ! !INPUT PARAMETERS:
    3526             : !
    3527             :     CHARACTER(LEN=255), INTENT(IN   )    :: LINE
    3528             :     CHARACTER(LEN=255), INTENT(IN   )    :: SUBSTR(255)
    3529             :     INTEGER,            INTENT(IN   )    :: N
    3530             :     INTEGER,            INTENT(IN   )    :: chrcl
    3531             :     INTEGER,            INTENT(IN   )    :: OPT
    3532             : !
    3533             : ! !INPUT/OUTPUT PARAMETERS:
    3534             : !
    3535             :     CHARACTER(LEN=*),   INTENT(INOUT)    :: charout
    3536             :     INTEGER,            INTENT(INOUT)    :: STAT
    3537             : !
    3538             : ! !REVISION HISTORY:
    3539             : !  29 Dec 2014 - C. Keller   - Initial version
    3540             : !  See https://github.com/geoschem/hemco for complete history
    3541             : !EOP
    3542             : !------------------------------------------------------------------------------
    3543             : !BOC
    3544             : !
    3545           0 :     IF ( chrcl > 0 ) THEN
    3546           0 :        IF ( chrcl > N ) THEN
    3547           0 :           IF ( chrcl /= OPT ) THEN
    3548           0 :              WRITE(*,*) 'Not enough elements in: '//TRIM(LINE)
    3549           0 :              STAT = 100
    3550           0 :              RETURN
    3551             :           ELSE
    3552           0 :              charout = ''
    3553             :           ENDIF
    3554             :        ELSE
    3555           0 :           READ( SUBSTR(chrcl), '(a)' ) charout
    3556             :        ENDIF
    3557             :     ENDIF
    3558           0 :     charout = ADJUSTL(charout)
    3559             : 
    3560           0 :   END SUBROUTINE READCHAR
    3561             : !EOC
    3562             : !------------------------------------------------------------------------------
    3563             : !                   Harmonized Emissions Component (HEMCO)                    !
    3564             : !------------------------------------------------------------------------------
    3565             : !BOP
    3566             : !
    3567             : ! !IROUTINE: READINT
    3568             : !
    3569             : ! !DESCRIPTION: Subroutine READINT is a helper routine to read integer
    3570             : ! values from the HEMCO configuration file.
    3571             : !\\
    3572             : !\\
    3573             : ! !INTERFACE:
    3574             : !
    3575           0 :   SUBROUTINE READINT ( ExtList, LINE, SUBSTR, N, intcl, intout, OPT, STAT )
    3576             : !
    3577             : ! !USES:
    3578             : !
    3579             :     USE HCO_EXTLIST_MOD, ONLY : HCO_GetOpt
    3580             : !
    3581             : ! !INPUT PARAMETERS:
    3582             : !
    3583             :     TYPE(Ext),          POINTER          :: ExtList
    3584             :     CHARACTER(LEN=255), INTENT(IN   )    :: LINE
    3585             :     CHARACTER(LEN=255), INTENT(IN   )    :: SUBSTR(255)
    3586             :     INTEGER,            INTENT(IN   )    :: N
    3587             :     INTEGER,            INTENT(IN   )    :: intcl
    3588             :     INTEGER,            INTENT(IN   )    :: OPT
    3589             : !
    3590             : ! !INPUT/OUTPUT PARAMETERS:
    3591             : !
    3592             :     INTEGER,            INTENT(INOUT)    :: intout
    3593             :     INTEGER,            INTENT(INOUT)    :: STAT
    3594             : !
    3595             : ! !REVISION HISTORY:
    3596             : !  29 Dec 2014 - C. Keller   - Initial version
    3597             : !  See https://github.com/geoschem/hemco for complete history
    3598             : !EOP
    3599             : !------------------------------------------------------------------------------
    3600             : !BOC
    3601             : !
    3602           0 :     IF ( intcl > 0 ) THEN
    3603           0 :        IF ( intcl > N ) THEN
    3604           0 :           IF ( intcl /= OPT ) THEN
    3605           0 :              WRITE(*,*) 'Not enough elements in: '//TRIM(LINE)
    3606           0 :              STAT = 100
    3607           0 :              RETURN
    3608             :           ELSE
    3609           0 :              intout = -999
    3610             :           ENDIF
    3611             :        ELSE
    3612             :           ! Check for wildcard
    3613           0 :           IF ( SUBSTR(intcl) == TRIM(HCO_GetOpt(ExtList,'Wildcard')) ) THEN
    3614           0 :              intout = -999
    3615             :           ELSE
    3616           0 :              READ( SUBSTR(intcl), * ) intout
    3617             :           ENDIF
    3618             :        ENDIF
    3619             :     ENDIF
    3620             : 
    3621             :   END SUBROUTINE READINT
    3622             : !EOC
    3623             : !------------------------------------------------------------------------------
    3624             : !                   Harmonized Emissions Component (HEMCO)                    !
    3625             : !------------------------------------------------------------------------------
    3626             : !BOP
    3627             : !
    3628             : ! !IROUTINE: Get_cID
    3629             : !
    3630             : ! !DESCRIPTION: Subroutine Get\_cID searches the whole ConfigList for an entry
    3631             : ! with the given ScalID and returns the corresponding container ID cID.
    3632             : !\\
    3633             : !\\
    3634             : ! !INTERFACE:
    3635             : !
    3636           0 :   SUBROUTINE Get_cID( ScalID, HcoConfig, cID, RC )
    3637             : !
    3638             : ! !INPUT PARAMETERS:
    3639             : !
    3640             :     INTEGER, INTENT(IN   )   :: scalID
    3641             :     TYPE(ConfigObj), POINTER :: HcoConfig
    3642             : !
    3643             : ! !OUTPUT PARAMETERS:
    3644             : !
    3645             :     INTEGER, INTENT(  OUT)   :: cID
    3646             : !
    3647             : ! !INPUT/OUTPUTP PARAMETERS:
    3648             : !
    3649             :     INTEGER, INTENT(INOUT)   :: RC
    3650             : !
    3651             : ! !REVISION HISTORY:
    3652             : !  18 Sep 2013 - C. Keller   - Initial version
    3653             : !  See https://github.com/geoschem/hemco for complete history
    3654             : !EOP
    3655             : !------------------------------------------------------------------------------
    3656             : !BOC
    3657             : !
    3658             : ! !LOCAL VARIABLES:
    3659             : !
    3660             :     ! Pointers
    3661             :     TYPE(ListCont), POINTER  :: Lct
    3662             : 
    3663             :     ! Scalars
    3664             :     CHARACTER(LEN=255)       :: MSG, LOC
    3665             :     CHARACTER(LEN= 31)       :: strID
    3666             : 
    3667             :     ! Enter
    3668           0 :     LOC = 'Get_cID (hco_config_mod.F90)'
    3669           0 :     cID = -999
    3670             : 
    3671             :     ! Loop over all containers
    3672           0 :     Lct => HcoConfig%ConfigList
    3673           0 :     DO WHILE ( ASSOCIATED ( Lct ) )
    3674             : 
    3675             :        ! Skip if data container not defined
    3676           0 :        IF ( .NOT. ASSOCIATED(Lct%Dct) ) THEN
    3677           0 :           Lct => Lct%NextCont
    3678           0 :           CYCLE
    3679             :        ENDIF
    3680             : 
    3681             :        ! Check if this container has desired scalID
    3682           0 :        IF ( Lct%Dct%ScalID == ScalID ) THEN
    3683           0 :           cID = Lct%Dct%cID
    3684           0 :           EXIT
    3685             :        ENDIF
    3686             : 
    3687             :        ! Move to archived next line
    3688           0 :        Lct => Lct%NextCont
    3689             :     ENDDO
    3690             : 
    3691             :     ! Free pointer
    3692           0 :     Lct => NULL()
    3693             : 
    3694             :     ! cID must be positive!
    3695           0 :     IF ( cID <= 0 ) THEN
    3696           0 :        WRITE ( strID, * ) ScalID
    3697           0 :        MSG = 'Cannot find ScalID' // TRIM(strID)
    3698           0 :        PRINT *,'cID negative in HEMCO Get_cID'
    3699           0 :        PRINT *, TRIM(MSG)
    3700           0 :        RETURN
    3701             :     ENDIF
    3702             : 
    3703             :     ! Leave w/ success
    3704           0 :     RC = HCO_SUCCESS
    3705             : 
    3706             :   END SUBROUTINE Get_cID
    3707             : !EOC
    3708             : !------------------------------------------------------------------------------
    3709             : !                   Harmonized Emissions Component (HEMCO)                    !
    3710             : !------------------------------------------------------------------------------
    3711             : !BOP
    3712             : !
    3713             : ! !IROUTINE: ConfigList_AddCont
    3714             : !
    3715             : ! !DESCRIPTION: Subroutine ConfigList\_AddCont adds a new (blank) container to
    3716             : ! the ConfigList list.
    3717             : !\\
    3718             : !\\
    3719             : ! !INTERFACE:
    3720             : !
    3721           0 :   SUBROUTINE ConfigList_AddCont( Lct, List )
    3722             : !
    3723             : ! !USES:
    3724             : !
    3725             :     USE HCO_DATACONT_Mod, ONLY : DataCont_Init
    3726             :     USE HCO_DATACONT_Mod, ONLY : ListCont_Length
    3727             : !
    3728             : ! !INPUT/OUTPUT PARAMETERS:
    3729             : !
    3730             :     TYPE(ListCont), POINTER       :: Lct
    3731             :     TYPE(ListCont), POINTER       :: List
    3732             : !
    3733             : ! !REVISION HISTORY:
    3734             : !  17 Sep 2013 - C. Keller: Initialization (update)
    3735             : !  See https://github.com/geoschem/hemco for complete history
    3736             : !EOP
    3737             : !------------------------------------------------------------------------------
    3738             : !BOC
    3739             : !
    3740             : ! !LOCAL VARIABLES:
    3741             : !
    3742             :     INTEGER :: cID
    3743             : 
    3744             :     !======================================================================
    3745             :     ! ConfigList_AddCont begins here
    3746             :     !======================================================================
    3747             : 
    3748             :     ! Allocate container and create data structure.
    3749             :     ! The DataCont_Init call creates a new data container (type DataCont)
    3750             :     ! All HEMCO lists (ConfigList, ReadList, EmisList) point to this
    3751             :     ! container!
    3752           0 :     ALLOCATE ( Lct )
    3753           0 :     Lct%Dct      => NULL()
    3754           0 :     Lct%NextCont => NULL()
    3755             : 
    3756             :     ! Get # of containers in list. Set new container ID (cID) to # of
    3757             :     ! containers + 1.
    3758           0 :     cID = ListCont_Length( List )
    3759           0 :     cID = cID + 1
    3760           0 :     CALL DataCont_Init ( Lct%Dct, cID )
    3761             : 
    3762             :     ! Connect blank container with ConfigList list.
    3763           0 :     Lct%NextCont => List
    3764           0 :     List         => Lct
    3765             : 
    3766             : 
    3767           0 :   END SUBROUTINE ConfigList_AddCont
    3768             : !EOC
    3769             : !------------------------------------------------------------------------------
    3770             : !                   Harmonized Emissions Component (HEMCO)                    !
    3771             : !------------------------------------------------------------------------------
    3772             : !BOP
    3773             : !
    3774             : ! !IROUTINE: ScalID_Register
    3775             : !
    3776             : ! !DESCRIPTION: Subroutine ScalID\_Register adds the scale factor IDs ScalIDs
    3777             : ! to the list of scale factor IDs.
    3778             : !\\
    3779             : !\\
    3780             : ! !INTERFACE:
    3781             : !
    3782           0 :   SUBROUTINE ScalID_Register( Dct, HcoConfig, RC )
    3783             : !
    3784             : ! !INPUT PARAMETERS:
    3785             : !
    3786             :     TYPE(DataCont),  POINTER :: Dct
    3787             :     TYPE(ConfigObj), POINTER :: HcoConfig
    3788             : !
    3789             : ! !INPUT/OUTPUT PARAMETERS:
    3790             : !
    3791             :     INTEGER,  INTENT(INOUT)  :: RC
    3792             : !
    3793             : ! !REVISION HISTORY:
    3794             : !  10 Jan 2014 - C. Keller: Initialization (update)
    3795             : !  See https://github.com/geoschem/hemco for complete history
    3796             : !EOP
    3797             : !------------------------------------------------------------------------------
    3798             : !BOC
    3799             : !
    3800             : ! !LOCAL VARIABLES:
    3801             : !
    3802             :     ! Scalars
    3803             :     INTEGER                    :: N, cID
    3804             : 
    3805             :     !======================================================================
    3806             :     ! ScalID_Register begins here
    3807             :     !======================================================================
    3808             : 
    3809             :     ! Check for every element of ScalIDs, if this scale factor ID is
    3810             :     ! already a member of ScalIDList. If not, add it.
    3811           0 :     DO N = 1, Dct%nScalID
    3812           0 :        IF ( Dct%Scal_cID(N) < 0 ) CYCLE
    3813             : 
    3814           0 :        CALL ScalID2List( HcoConfig%ScalIDList, Dct%Scal_cID(N), RC )
    3815           0 :        IF ( RC /= HCO_SUCCESS ) THEN
    3816           0 :           PRINT *,'Error in ScaleID2List called from HEMCO ScalID_Register (1)'
    3817           0 :           RETURN
    3818             :        ENDIF
    3819             : 
    3820             :        ! Replace scale factor ID with container ID.
    3821           0 :        CALL Get_cID ( Dct%Scal_cID(N), HcoConfig, cID, RC )
    3822           0 :        IF ( RC /= HCO_SUCCESS ) THEN
    3823           0 :           PRINT *,'Error in Get_cID called from HEMCO ScalID_Register (1)'
    3824           0 :           RETURN
    3825             :        ENDIF
    3826           0 :        Dct%Scal_cID(N) = cID
    3827             : 
    3828             :     ENDDO
    3829             : 
    3830             :     ! Also check for level scale factor IDs
    3831           0 :     IF ( Dct%levScalID1 > 0 ) THEN
    3832           0 :        CALL ScalID2List( HcoConfig%ScalIDList, Dct%levScalID1, RC )
    3833           0 :        IF ( RC /= HCO_SUCCESS ) THEN
    3834           0 :           PRINT *,'Error in ScalID2List called from HEMCO ScalID_Register (2)'
    3835           0 :           RETURN
    3836             :        ENDIF
    3837           0 :        CALL Get_cID ( Dct%levScalID1, HcoConfig, cID, RC )
    3838           0 :        IF ( RC /= HCO_SUCCESS ) THEN
    3839           0 :           PRINT *,'Error in Get_cID called from HEMCO ScalID_Register (2)'
    3840           0 :           RETURN
    3841             :        ENDIF
    3842           0 :        Dct%levScalID1 = cID
    3843             :     ENDIF
    3844           0 :     IF ( Dct%levScalID2 > 0 ) THEN
    3845           0 :        CALL ScalID2List( HcoConfig%ScalIDList, Dct%levScalID2, RC )
    3846           0 :        IF ( RC /= HCO_SUCCESS ) THEN
    3847           0 :           PRINT *,'Error in ScaleID2List called from HEMCO ScalID_Register (3)'
    3848           0 :           RETURN
    3849             :        ENDIF
    3850           0 :        CALL Get_cID ( Dct%levScalID2, HcoConfig, cID, RC )
    3851           0 :        IF ( RC /= HCO_SUCCESS ) THEN
    3852           0 :           PRINT *,'Error in Get_cID called from HEMCO ScalID_Register (3)'
    3853           0 :           RETURN
    3854             :        ENDIF
    3855           0 :        Dct%levScalID2 = cID
    3856             :     ENDIF
    3857             : 
    3858             :     ! Vector Scal_cID of this container now points to cIDs
    3859           0 :     Dct%Scal_cID_Set = .TRUE.
    3860             : 
    3861             :     ! Leave w/ success
    3862           0 :     RC = HCO_SUCCESS
    3863             : 
    3864             :   END SUBROUTINE ScalID_Register
    3865             : !EOC
    3866             : !------------------------------------------------------------------------------
    3867             : !                   Harmonized Emissions Component (HEMCO)                    !
    3868             : !------------------------------------------------------------------------------
    3869             : !BOP
    3870             : !
    3871             : ! !IROUTINE: ScalID2List
    3872             : !
    3873             : ! !DESCRIPTION: Subroutine ScalID2List adds the scale factor IDs ScalIDs
    3874             : ! to the list of scale factor IDs.
    3875             : !\\
    3876             : !\\
    3877             : ! !INTERFACE:
    3878             : !
    3879           0 :   SUBROUTINE ScalID2List( ScalIDList, ID, RC )
    3880             : !
    3881             : ! !INPUT PARAMETERS:
    3882             : !
    3883             :     TYPE(ScalIDCont),   POINTER        :: ScalIDList
    3884             :     INTEGER,            INTENT(IN   )  :: ID
    3885             : !
    3886             : ! !INPUT/OUTPUT PARAMETERS:
    3887             : !
    3888             :     INTEGER,            INTENT(INOUT)  :: RC
    3889             : !
    3890             : ! !REVISION HISTORY:
    3891             : !  10 Jan 2014 - C. Keller: Initialization (update)
    3892             : !  See https://github.com/geoschem/hemco for complete history
    3893             : !EOP
    3894             : !------------------------------------------------------------------------------
    3895             : !BOC
    3896             : !
    3897             : ! !LOCAL VARIABLES:
    3898             : !
    3899             :     ! Pointers
    3900             :     TYPE(ScalIDCont), POINTER  :: NewScalIDCont
    3901             :     TYPE(ScalIDCont), POINTER  :: TmpScalIDCont
    3902             :     TYPE(ScalIDCont), POINTER  :: PrvScalIDCont
    3903             : 
    3904             :     ! Scalars
    3905             :     LOGICAL                    :: IsInList
    3906             : 
    3907             :     !======================================================================
    3908             :     ! ScalID2List begins here
    3909             :     !======================================================================
    3910             : 
    3911             :     ! Initialize
    3912           0 :     NewScalIDCont => NULL()
    3913           0 :     TmpScalIDCont => NULL()
    3914           0 :     PrvScalIDCont => NULL()
    3915             : 
    3916             :     ! Check for every element of ScalIDs, if this scale factor ID is
    3917             :     ! already a member of ScalIDList. If not, add it.
    3918             : 
    3919             :     ! Check if already in list
    3920           0 :     IsInList = .FALSE.
    3921           0 :     TmpScalIDCont => ScalIDList
    3922           0 :     PrvScalIDCont => TmpScalIDCont
    3923           0 :     DO WHILE ( ASSOCIATED(TmpScalIDCont) )
    3924           0 :        IF ( TmpScalIDCont%ScalID == ID ) THEN
    3925             :           IsInList = .TRUE.
    3926             :           EXIT
    3927             :        ENDIF
    3928           0 :        PrvScalIDCont => TmpScalIDCont
    3929           0 :        TmpScalIDCont => TmpScalIDCont%NEXT
    3930             :     ENDDO
    3931             : 
    3932             :     ! Add new container w/ this scal ID to (end of) list
    3933           0 :     IF ( .NOT. IsInList ) THEN
    3934           0 :        ALLOCATE ( NewScalIDCont )
    3935           0 :        NewScalIDCont%ScalID =  ID
    3936           0 :        NewScalIDCont%NEXT   => NULL()
    3937           0 :        IF ( .NOT. ASSOCIATED(PrvScalIDCont) ) THEN
    3938           0 :           ScalIDList => NewScalIDCont
    3939             :        ELSE
    3940           0 :           PrvScalIDCont%NEXT => NewScalIDCont
    3941             :        ENDIF
    3942             : !       NewScalIDCont%NEXT   => ScalIDList
    3943             : !       ScalIDList           => NewScalIDCont
    3944             : !       NewScalIDCont        => NULL()
    3945             :     ENDIF
    3946             : 
    3947             :     ! Cleanup
    3948           0 :     TmpScalIDCont => NULL()
    3949             : 
    3950             :     ! Leave w/ success
    3951           0 :     RC = HCO_SUCCESS
    3952             : 
    3953           0 :   END SUBROUTINE ScalID2List
    3954             : !EOC
    3955             : !------------------------------------------------------------------------------
    3956             : !                   Harmonized Emissions Component (HEMCO)                    !
    3957             : !------------------------------------------------------------------------------
    3958             : !BOP
    3959             : !
    3960             : ! !IROUTINE: ScalID_Cleanup
    3961             : !
    3962             : ! !DESCRIPTION: Subroutine ScalID\_Cleanup cleans up the internal ScalID
    3963             : ! list.
    3964             : !\\
    3965             : !\\
    3966             : ! !INTERFACE:
    3967             : !
    3968           0 :   SUBROUTINE ScalID_Cleanup( ScalIDList )
    3969             : !
    3970             : ! !INPUT ARGUMENTS:
    3971             : !
    3972             :   TYPE(ScalIDCont),   POINTER  :: ScalIDList
    3973             : !
    3974             : ! !REVISION HISTORY:
    3975             : !  10 Jan 2014 - C. Keller: Initialization (update)
    3976             : !  See https://github.com/geoschem/hemco for complete history
    3977             : !EOP
    3978             : !------------------------------------------------------------------------------
    3979             : !BOC
    3980             : !
    3981             : ! !LOCAL VARIABLES:
    3982             : !
    3983             :     ! Pointers
    3984             :     TYPE(ScalIDCont), POINTER  :: TmpScalIDCont
    3985             :     TYPE(ScalIDCont), POINTER  :: NxtScalIDCont
    3986             : 
    3987             :     !======================================================================
    3988             :     ! ScalID_Cleanup begins here
    3989             :     !======================================================================
    3990             : 
    3991             :     ! Walk through list and remove each element
    3992           0 :     NxtScalIDCont => NULL()
    3993           0 :     TmpScalIDCont => ScalIDList
    3994           0 :     DO WHILE ( ASSOCIATED(TmpScalIDCont) )
    3995             : 
    3996           0 :        NxtScalIDCont      => TmpScalIDCont%NEXT
    3997           0 :        TmpScalIDCont%NEXT => NULL()
    3998           0 :        DEALLOCATE ( TmpScalIDCont )
    3999             : 
    4000           0 :        TmpScalIDCont => NxtScalIDCont
    4001             :     ENDDO
    4002             : 
    4003             :     ! Exit
    4004           0 :     TmpScalIDCont => NULL()
    4005           0 :     NxtScalIDCont => NULL()
    4006           0 :     ScalIDList    => NULL()
    4007             : 
    4008           0 :   END SUBROUTINE ScalID_Cleanup
    4009             : !EOC
    4010             : !------------------------------------------------------------------------------
    4011             : !                   Harmonized Emissions Component (HEMCO)                    !
    4012             : !------------------------------------------------------------------------------
    4013             : !BOP
    4014             : !
    4015             : ! !IROUTINE: SpecName_Register
    4016             : !
    4017             : ! !DESCRIPTION: Subroutine SpecName\_Register adds the species name SpecName
    4018             : ! to the list of species names.
    4019             : !\\
    4020             : !\\
    4021             : ! !INTERFACE:
    4022             : !
    4023           0 :   SUBROUTINE SpecName_Register( HcoConfig, SpecName, RC )
    4024             : !
    4025             : ! !USES:
    4026             : !
    4027             :     USE HCO_EXTLIST_MOD, ONLY : HCO_GetOpt
    4028             : !
    4029             : ! !INPUT PARAMETERS:
    4030             : !
    4031             :     TYPE(ConfigObj),    POINTER       :: HcoConfig
    4032             :     CHARACTER(LEN=*),   INTENT(IN   ) :: SpecName
    4033             : !
    4034             : ! !INPUT/OUTPUT PARAMETERS:
    4035             : !
    4036             :     INTEGER,          INTENT(INOUT)   :: RC
    4037             : !
    4038             : ! !REVISION HISTORY:
    4039             : !  10 Jan 2014 - C. Keller: Initialization (update)
    4040             : !  See https://github.com/geoschem/hemco for complete history
    4041             : !EOP
    4042             : !------------------------------------------------------------------------------
    4043             : !BOC
    4044             : !
    4045             : ! !LOCAL ARGUMENTS:
    4046             : !
    4047             :     TYPE(SpecNameCont), POINTER  :: NewSpecNameCont
    4048             :     TYPE(SpecNameCont), POINTER  :: TmpSpecNameCont
    4049             :     LOGICAL                      :: IsInList
    4050             : 
    4051             :     !======================================================================
    4052             :     ! SpecName_Register begins here
    4053             :     !======================================================================
    4054             : 
    4055             :     ! Ignore if wildcard character. These fields will always be used!
    4056           0 :     IF ( TRIM(SpecName) == TRIM(HCO_GetOpt(HcoConfig%ExtList,'Wildcard')) ) THEN
    4057           0 :        RC = HCO_SUCCESS
    4058           0 :        RETURN
    4059             :     ENDIF
    4060             : 
    4061             :     ! Initialize
    4062           0 :     NewSpecNameCont => NULL()
    4063           0 :     TmpSpecNameCont => NULL()
    4064             : 
    4065             :     ! Check if already in list
    4066           0 :     IsInList = .FALSE.
    4067           0 :     TmpSpecNameCont => HcoConfig%SpecNameList
    4068           0 :     DO WHILE ( ASSOCIATED(TmpSpecNameCont) )
    4069           0 :        IF ( TRIM(TmpSpecNameCont%SpecName) == TRIM(SpecName) ) THEN
    4070           0 :           IsInList = .TRUE.
    4071           0 :           EXIT
    4072             :        ENDIF
    4073           0 :        TmpSpecNameCont => TmpSpecNameCont%NEXT
    4074             :     ENDDO
    4075             : 
    4076             :     ! Add new container w/ this scal ID to (beginning) of list
    4077             :     IF ( .NOT. IsInList ) THEN
    4078           0 :        ALLOCATE ( NewSpecNameCont )
    4079           0 :        NewSpecNameCont%SpecName =  SpecName
    4080           0 :        NewSpecNameCont%NEXT     => HcoConfig%SpecNameList
    4081           0 :        HcoConfig%SpecNameList   => NewSpecNameCont
    4082           0 :        NewSpecNameCont          => NULL()
    4083             :     ENDIF
    4084             : 
    4085             :     ! Cleanup
    4086           0 :     TmpSpecNameCont => NULL()
    4087             : 
    4088             :     ! Leave w/ success
    4089           0 :     RC = HCO_SUCCESS
    4090             : 
    4091           0 :   END SUBROUTINE SpecName_Register
    4092             : !EOC
    4093             : !------------------------------------------------------------------------------
    4094             : !                   Harmonized Emissions Component (HEMCO)                    !
    4095             : !------------------------------------------------------------------------------
    4096             : !BOP
    4097             : !
    4098             : ! !IROUTINE: SpecName_Cleanup
    4099             : !
    4100             : ! !DESCRIPTION: Subroutine SpecName\_Cleanup cleans up the internal SpecName
    4101             : ! list.
    4102             : !\\
    4103             : !\\
    4104             : ! !INTERFACE:
    4105             : !
    4106           0 :   SUBROUTINE SpecName_Cleanup ( SpecNameList )
    4107             : !
    4108             : ! !INPUT/OUTPUT ARGUMENT:
    4109             : !
    4110             :     TYPE(SpecNameCont), POINTER       :: SpecNameList
    4111             : !
    4112             : ! !REVISION HISTORY:
    4113             : !  10 Jan 2014 - C. Keller: Initialization (update)
    4114             : !  See https://github.com/geoschem/hemco for complete history
    4115             : !EOP
    4116             : !------------------------------------------------------------------------------
    4117             : !BOC
    4118             : !
    4119             : ! !LOCAL ARGUMENTS:
    4120             : !
    4121             :     ! Pointers
    4122             :     TYPE(SpecNameCont), POINTER  :: TmpSpecNameCont
    4123             :     TYPE(SpecNameCont), POINTER  :: NxtSpecNameCont
    4124             : 
    4125             :     !======================================================================
    4126             :     ! SpecName_Cleanup begins here
    4127             :     !======================================================================
    4128             : 
    4129             :     ! Initialize
    4130           0 :     TmpSpecNameCont => NULL()
    4131           0 :     NxtSpecNameCont => NULL()
    4132             : 
    4133             :     ! Walk through list and remove each element
    4134           0 :     TmpSpecNameCont => SpecNameList
    4135           0 :     DO WHILE ( ASSOCIATED(TmpSpecNameCont) )
    4136             : 
    4137           0 :        NxtSpecNameCont      => TmpSpecNameCont%NEXT
    4138           0 :        TmpSpecNameCont%NEXT => NULL()
    4139           0 :        DEALLOCATE ( TmpSpecNameCont )
    4140             : 
    4141           0 :        TmpSpecNameCont => NxtSpecNameCont
    4142             :     ENDDO
    4143             : 
    4144             :     ! Exit
    4145           0 :     TmpSpecNameCont => NULL()
    4146           0 :     NxtSpecNameCont => NULL()
    4147           0 :     SpecNameList    => NULL()
    4148             : 
    4149           0 :   END SUBROUTINE SpecName_Cleanup
    4150             : !EOC
    4151             : !------------------------------------------------------------------------------
    4152             : !                   Harmonized Emissions Component (HEMCO)                    !
    4153             : !------------------------------------------------------------------------------
    4154             : !BOP
    4155             : !
    4156             : ! !IROUTINE: Config_GetnSpecies
    4157             : !
    4158             : ! !DESCRIPTION: Function Config\_GetnSpecies is a wrapper function to
    4159             : ! get the number of (unique) species names in SpecNameList.
    4160             : !\\
    4161             : !\\
    4162             : ! !INTERFACE:
    4163             : !
    4164           0 :   FUNCTION Config_GetnSpecies( HcoConfig ) RESULT( nSpecies )
    4165             : !
    4166             : ! !INPUT ARGUMENT:
    4167             : !
    4168             :     TYPE(ConfigObj), POINTER       :: HcoConfig
    4169             : !
    4170             : ! !RETURN VALUE:
    4171             : !
    4172             :     INTEGER :: nSpecies
    4173             : !
    4174             : ! !REVISION HISTORY:
    4175             : !  10 Jan 2014 - C. Keller: Initialization (update)
    4176             : !  See https://github.com/geoschem/hemco for complete history
    4177             : !EOP
    4178             : !------------------------------------------------------------------------------
    4179             : !BOC
    4180             : !
    4181             : ! !LOCAL VARIABLES:
    4182             : !
    4183             :     INTEGER :: THISRC
    4184             : 
    4185             :     !======================================================================
    4186             :     ! Config_GetnSpecies begins here
    4187             :     !======================================================================
    4188             : 
    4189           0 :     CALL Config_GetSpecAttr( HcoConfig, N=nSpecies, RC = THISRC )
    4190             : 
    4191           0 :   END FUNCTION Config_GetnSpecies
    4192             : !EOC
    4193             : !------------------------------------------------------------------------------
    4194             : !                   Harmonized Emissions Component (HEMCO)                    !
    4195             : !------------------------------------------------------------------------------
    4196             : !BOP
    4197             : !
    4198             : ! !IROUTINE: Config_GetSpecNames
    4199             : !
    4200             : ! !DESCRIPTION: Subroutine Config\_GetSpecNames is a wrapper routine to
    4201             : ! obtain the list of (unique) species names defined in SpecNameList.
    4202             : !\\
    4203             : !\\
    4204             : ! !INTERFACE:
    4205             : !
    4206           0 :   SUBROUTINE Config_GetSpecNames( HcoConfig, SpecNames, nSpecies, RC )
    4207             : !
    4208             : ! !INPUT ARGUMENT:
    4209             : !
    4210             :     TYPE(ConfigObj), POINTER          :: HcoConfig
    4211             : !
    4212             : ! !OUTPUT PARAMTERS:
    4213             : !
    4214             :     CHARACTER(LEN=*), POINTER         :: SpecNames(:)
    4215             : !
    4216             : ! !INPUT/OUTPUT PARAMETERS:
    4217             : !
    4218             :     INTEGER,          INTENT(INOUT)   :: nSpecies
    4219             :     INTEGER,          INTENT(INOUT)   :: RC
    4220             : !
    4221             : ! !REVISION HISTORY:
    4222             : !  10 Jan 2014 - C. Keller: Initialization (update)
    4223             : !  See https://github.com/geoschem/hemco for complete history
    4224             : !EOP
    4225             : !------------------------------------------------------------------------------
    4226             : !BOC
    4227             :     !======================================================================
    4228             :     ! Config_GetSpecNames begins here
    4229             :     !======================================================================
    4230             : 
    4231           0 :     CALL Config_GetSpecAttr( HcoConfig, N=nSpecies, SpecNames=SpecNames, RC=RC )
    4232             : 
    4233           0 :   END SUBROUTINE Config_GetSpecNames
    4234             : !EOC
    4235             : !------------------------------------------------------------------------------
    4236             : !                   Harmonized Emissions Component (HEMCO)                    !
    4237             : !------------------------------------------------------------------------------
    4238             : !BOP
    4239             : !
    4240             : ! !IROUTINE: Config_getSpecAttr
    4241             : !
    4242             : ! !DESCRIPTION: Subroutine Config\_GetSpecAttr returns the number of
    4243             : ! species names N and the vector of species names SpecNames.
    4244             : ! SpecNames must be of length nnSpecs, i.e. in order to obtain
    4245             : ! SpecNames, Config\_getSpecAttr has to be called twice:
    4246             : ! N = 0
    4247             : ! CALL Config\_getSpecAttr ( N=N, RC=RC )
    4248             : ! ALLOCATE(SpecNames(N))
    4249             : ! CALL Config\_getSpecAttr ( N=N, SpecNames=SpecNames, RC=RC )
    4250             : !\\
    4251             : !\\
    4252             : ! !INTERFACE:
    4253             : !
    4254           0 :   SUBROUTINE Config_GetSpecAttr( HcoConfig, N, SpecNames, RC )
    4255             : !
    4256             : ! !INPUT ARGUMENT:
    4257             : !
    4258             :     TYPE(ConfigObj),    POINTER                    :: HcoConfig
    4259             : !
    4260             : ! !INPUT/OUTPUT PARAMETERS:
    4261             : !
    4262             :     INTEGER,            INTENT(INOUT)              :: N
    4263             :     INTEGER,            INTENT(INOUT)              :: RC
    4264             : !
    4265             : ! !OUTPUT PARAMETERS:
    4266             : !
    4267             :     CHARACTER(LEN=*),   POINTER,       OPTIONAL    :: SpecNames(:)
    4268             : !
    4269             : ! !REVISION HISTORY:
    4270             : !  10 Jan 2014 - C. Keller: Initialization (update)
    4271             : !  See https://github.com/geoschem/hemco for complete history
    4272             : !EOP
    4273             : !------------------------------------------------------------------------------
    4274             : !BOC
    4275             : !
    4276             : ! !LOCAL VARIABLES:
    4277             : !
    4278             :     TYPE(SpecNameCont), POINTER   :: TmpSpecNameCont
    4279             :     INTEGER                       :: AS
    4280             :     CHARACTER(LEN=255), PARAMETER :: &
    4281             :          LOC = 'Config_GetSpecAttr (hco_config_mod.F90)'
    4282             :     CHARACTER(LEN=512)            :: errMsg
    4283             : 
    4284             :     !======================================================================
    4285             :     ! Config_GetSpecAttr begins here
    4286             :     !======================================================================
    4287             : 
    4288             :     ! Initialize
    4289           0 :     TmpSpecNameCont => NULL()
    4290             : 
    4291             :     ! Eventually allocate pointer
    4292           0 :     IF ( PRESENT(SpecNames) ) THEN
    4293           0 :        IF ( .NOT. ASSOCIATED(SpecNames) ) THEN
    4294           0 :           IF ( N <= 0 ) THEN
    4295           0 :              errMsg = 'Cannot allocate SpecNames - N is size 0 or smaller'
    4296           0 :              CALL HCO_Error( errMsg, RC, thisLoc=LOC )
    4297           0 :              RETURN
    4298             :           ENDIF
    4299           0 :           ALLOCATE(SpecNames(N), STAT=AS )
    4300           0 :           IF ( AS/= 0 ) THEN
    4301           0 :              errMsg = 'Could not allocate the SpcNames array!'
    4302           0 :              CALL HCO_Error( errMsg, RC, thisLoc=LOC )
    4303           0 :              RETURN
    4304             :           ENDIF
    4305           0 :           SpecNames(:) = ''
    4306           0 :        ELSEIF ( SIZE(SpecNames) /= N ) THEN
    4307           0 :           errMsg = 'Size(SpecNames) does not match the passed N argument!'
    4308           0 :           CALL HCO_Error( errMsg, RC, thisLoc=LOC )
    4309           0 :           RETURN
    4310             :        ENDIF
    4311             :     ENDIF
    4312             : 
    4313             :     ! Init
    4314           0 :     N = 0
    4315             : 
    4316             :     ! Loop over entire list. Count number of containers and eventually
    4317             :     ! write out the species names.
    4318           0 :     TmpSpecNameCont => HcoConfig%SpecNameList
    4319           0 :     DO WHILE ( ASSOCIATED(TmpSpecNameCont) )
    4320           0 :        N = N + 1
    4321           0 :        IF ( PRESENT(SpecNames) ) THEN
    4322           0 :           SpecNames(N) = TRIM(TmpSpecNameCont%SpecName)
    4323             :        ENDIF
    4324           0 :        TmpSpecNameCont => TmpSpecNameCont%NEXT
    4325             :     ENDDO
    4326             : 
    4327             :     ! Cleanup and return w/ success
    4328           0 :     TmpSpecNameCont => NULL()
    4329             : 
    4330           0 :     RC = HCO_SUCCESS
    4331             : 
    4332           0 :   END SUBROUTINE Config_GetSpecAttr
    4333             : !EOC
    4334             : !------------------------------------------------------------------------------
    4335             : !                   Harmonized Emissions Component (HEMCO)                    !
    4336             : !------------------------------------------------------------------------------
    4337             : !BOP
    4338             : !
    4339             : ! !IROUTINE: Check_ContNames
    4340             : !
    4341             : ! !DESCRIPTION: Function Check\_Contnames compares the container names of
    4342             : ! two containers, ignoring the name 'tags', i.e. ignoring everything that
    4343             : ! follows double underscore (\_\_). For example, two containers with names
    4344             : ! "EDGAR\_NOX\_\_PNT" and "EDGAR\_NOX\_\_MOB" are considered equal, while
    4345             : ! "EDGAR\_NOX\_PNT" and "EDGAR\_NOX\_MOB" are not.
    4346             : !\\
    4347             : !\\
    4348             : ! !INTERFACE:
    4349             : !
    4350           0 :   FUNCTION Check_ContNames( Lct1, Lct2 ) RESULT( SameName )
    4351             : !
    4352             : ! !INPUT/OUTPUT PARAMETERS:
    4353             : !
    4354             :     TYPE(ListCont), POINTER :: Lct1
    4355             :     TYPE(ListCont), POINTER :: Lct2
    4356             : !
    4357             : ! !RETURN VALUE:
    4358             : !
    4359             :     LOGICAL                 :: SameName
    4360             : !
    4361             : ! !REVISION HISTORY:
    4362             : !  10 Jan 2014 - C. Keller: Initialization (update)
    4363             : !  See https://github.com/geoschem/hemco for complete history
    4364             : !EOP
    4365             : !------------------------------------------------------------------------------
    4366             : !BOC
    4367             : !
    4368             : ! !LOCAL VARIABLES:
    4369             : !
    4370             :     CHARACTER(LEN=63)  :: name1, name2
    4371             :     INTEGER            :: idx
    4372             : 
    4373             :     !======================================================================
    4374             :     ! Check_ContNames begins here!
    4375             :     !======================================================================
    4376             : 
    4377           0 :     SameName = .FALSE.
    4378           0 :     name1 = 'a'
    4379           0 :     name2 = 'b'
    4380             : 
    4381           0 :     idx = INDEX( TRIM(Lct1%Dct%cName), '__' )
    4382           0 :     IF ( idx > 0 ) THEN
    4383           0 :        name1 = Lct1%Dct%cName(1:idx)
    4384             :     ELSE
    4385           0 :        name1 = Lct1%Dct%cName
    4386             :     ENDIF
    4387             : 
    4388           0 :     idx = INDEX( TRIM(Lct2%Dct%cName), '__' )
    4389           0 :     IF ( idx > 0 ) THEN
    4390           0 :        name2 = Lct2%Dct%cName(1:idx)
    4391             :     ELSE
    4392           0 :        name2 = Lct2%Dct%cName
    4393             :     ENDIF
    4394             : 
    4395           0 :     IF ( TRIM(name1) == TRIM(name2) ) THEN
    4396             :        SameName = .TRUE.
    4397             :     ELSE
    4398           0 :        SameName = .FALSE.
    4399             :     ENDIF
    4400             : 
    4401           0 :   END FUNCTION Check_ContNames
    4402             : !EOC
    4403             : !------------------------------------------------------------------------------
    4404             : !                   Harmonized Emissions Component (HEMCO)                    !
    4405             : !------------------------------------------------------------------------------
    4406             : !BOP
    4407             : !
    4408             : ! !IROUTINE: ExtractSrcDim
    4409             : !
    4410             : ! !DESCRIPTION: Subroutine ExtractSrcDim extracts the source dimension
    4411             : ! attribute. Specifically, it checks if the field is expected to be 2D
    4412             : ! (xy) or 3D. Default 3D data is xyz, but it is also possible to explicitly
    4413             : ! define the number of vertical levels to be read, as well as the reading
    4414             : ! direction (up or down). For example, 'xy1' will be interpreted as reading
    4415             : ! only the first level, and 'xy27' will only read the first 27 levels. To
    4416             : ! reverse the vertical axis, use e.g. 'xy-1' to read only the top level,
    4417             : ! or 'xy-27' to read the top 27 levels, with the topmost level being put
    4418             : ! into the surface level.
    4419             : !\\
    4420             : !\\
    4421             : ! !INTERFACE:
    4422             : !
    4423           0 :   SUBROUTINE ExtractSrcDim( HcoConfig, SrcDim, Dta, Lscal1, Lscal2, RC )
    4424             : !
    4425             : ! !INPUT PARAMETERS:
    4426             : !
    4427             :     TYPE(ConfigObj),  POINTER         :: HcoConfig
    4428             :     CHARACTER(LEN=*), INTENT(IN   )   :: SrcDim
    4429             :     TYPE(FileData),   POINTER         :: Dta
    4430             : !
    4431             : ! !OUTPUT PARAMETERS:
    4432             : !
    4433             :     INTEGER,          INTENT(  OUT)   :: Lscal1
    4434             :     INTEGER,          INTENT(  OUT)   :: Lscal2
    4435             : !
    4436             : ! !INPUT/OUTPUT PARAMETERS:
    4437             : !
    4438             :     INTEGER,          INTENT(INOUT)  :: RC
    4439             : !
    4440             : ! !REVISION HISTORY:
    4441             : !  20 May 2015 - C. Keller   - Initial version
    4442             : !  See https://github.com/geoschem/hemco for complete history
    4443             : !EOP
    4444             : !------------------------------------------------------------------------------
    4445             : !BOC
    4446             : !
    4447             : ! !LOCAL VARIABLES:
    4448             : !
    4449             :     INTEGER            :: i, idx, idx2
    4450             :     INTEGER            :: strLen
    4451             :     INTEGER            :: EmisUnit
    4452             :     REAL(hp)           :: EmisL
    4453             :     CHARACTER(LEN=255) :: str1, str2, tmpstr
    4454             :     CHARACTER(LEN=255) :: MSG
    4455             :     CHARACTER(LEN=255) :: LOC = 'ExtractSrcDim (hco_config_mod.F90)'
    4456             : 
    4457             :     !======================================================================
    4458             :     ! ExtractSrcDim begins here
    4459             :     !======================================================================
    4460             : 
    4461             :     msg = 'Illegal source dimension ' // TRIM(srcDim) // &
    4462             :           ' for file ' // TRIM(Dta%ncFile) // &
    4463           0 :           '. Valid entries are e.g. xy or xyz.'
    4464             : 
    4465             :     ! Init output
    4466           0 :     Lscal1 = -1
    4467           0 :     Lscal2 = -1
    4468             : 
    4469             :     ! See if there is an arbitrary additional dimension. This must be added
    4470             :     ! at the end of the string and be separated by a '+' sign
    4471           0 :     idx = INDEX( TRIM(srcDim), '+' )
    4472           0 :     IF ( idx > 0 ) THEN
    4473           0 :        str1 = srcDim(1:(idx-1))
    4474           0 :        str2 = srcDim((idx+1):LEN(srcDim))
    4475             :     ELSE
    4476           0 :        str1 = srcDim
    4477           0 :        str2 = ''
    4478             :     ENDIF
    4479             : 
    4480             :     ! 2D data:
    4481           0 :     IF ( TRIM(str1) == 'xy' .OR. TRIM(str1) == '-' ) THEN
    4482           0 :        Dta%SpaceDim = 2
    4483             : 
    4484             :     ! All other cases
    4485             :     ELSE
    4486             :        ! Character length
    4487           0 :        strLen = LEN(TRIM(str1))
    4488             : 
    4489             :        ! There must be at least 3 characters (e.g. xyz)
    4490           0 :        IF ( strLen < 3 ) THEN
    4491           0 :           CALL HCO_Error( msg, RC, thisLoc=LOC )
    4492           0 :           RETURN
    4493             :        ENDIF
    4494             : 
    4495             :        ! First two entries must be xy
    4496           0 :        IF ( str1(1:2) /= 'xy' ) THEN
    4497           0 :           CALL HCO_Error( msg, RC, thisLoc=LOC )
    4498           0 :           RETURN
    4499             :        ENDIF
    4500             : 
    4501             :        ! If third entry is 'L', this means we have 2D data that shall be put
    4502             :        ! into a particular level, e.g. xyL4 will cause the 2D data to be
    4503             :        ! emitted into level 4.
    4504           0 :        IF ( str1(3:3) == 'L' .OR. str1(3:3) == 'l' ) THEN
    4505           0 :           IF ( strLen < 4 ) THEN
    4506           0 :              CALL HCO_Error( msg, RC, thisLoc=LOC )
    4507           0 :              RETURN
    4508             :           ENDIF
    4509           0 :           Dta%SpaceDim = 2
    4510           0 :           Dta%EmisLmode  = 1 ! Dilute emissions vertically
    4511             : 
    4512             :           ! Read levels to put emissions into:
    4513           0 :           i=4
    4514           0 :           IF ( str1(i:i) == '=' ) i = i + 1
    4515             : 
    4516             :           ! Reduce to data to be read
    4517           0 :           tmpstr = str1(i:strLen)
    4518             : 
    4519             :           ! Check if range of levels is provided, i.e. xyL=1:5
    4520           0 :           idx = INDEX( TRIM(tmpstr), ':' )
    4521             : 
    4522             :           ! If multiple levels are provided (e.g. xyL=1:5)
    4523           0 :           IF ( idx > 0 ) THEN
    4524             : 
    4525             :              ! Check for PBL flag. It is possible to emit stuff
    4526             :              ! from the PBL up to e.g. level 30 (xyL=PBL:30)
    4527             :              ! The call to ParseEmisL now returns three arguments: the emission
    4528             :              ! level, the emission unit, and the emission scale factor. Ignore
    4529             :              ! emission level and unit if scale factor is given.
    4530           0 :              CALL ParseEmisL( tmpstr(1:(idx-1)), EmisL, EmisUnit, Lscal1 )
    4531           0 :              Dta%EmisL1     = EmisL
    4532           0 :              Dta%EmisL1Unit = EmisUnit
    4533           0 :              CALL ParseEmisL( tmpstr((idx+1):LEN(tmpstr)), EmisL, EmisUnit, Lscal2 )
    4534           0 :              Dta%EmisL2     = EmisL
    4535           0 :              Dta%EmisL2Unit = EmisUnit
    4536           0 :              Dta%EmisLmode  = 1
    4537             : 
    4538             :           ! If only one value is provided (e.g. xyL5, xyL=5, xyL*)
    4539             :           ELSE
    4540             : 
    4541             :              ! Check if wildcard provided, i.e. xyL*
    4542           0 :              idx = INDEX( TRIM(tmpstr), '*' )
    4543             : 
    4544             :              ! Wildcard tells HEMCO to emit same value to all emission levels
    4545             :              ! A scale factor should be applied to distribute the emissions
    4546             :              ! vertically
    4547           0 :              IF ( idx > 0 ) THEN
    4548             : 
    4549           0 :                 Dta%EmisL1     = 1.0_hp
    4550           0 :                 Dta%EmisL1Unit = HCO_EMISL_LEV
    4551           0 :                 Dta%EmisL2     = 0.0_hp
    4552           0 :                 Dta%EmisL2Unit = HCO_EMISL_TOP
    4553           0 :                 Dta%EmisLmode  = 2 ! Copy data to all levels
    4554             : 
    4555             :              ! Emissions are allocated to one level
    4556             :              ELSE
    4557             : 
    4558           0 :                 CALL ParseEmisL( tmpstr, EmisL, EmisUnit, Lscal1 )
    4559           0 :                 Dta%EmisL1     = EmisL
    4560           0 :                 Dta%EmisL1Unit = EmisUnit
    4561           0 :                 Lscal2         = Lscal1
    4562           0 :                 Dta%EmisL2     = Dta%EmisL1
    4563           0 :                 Dta%EmisL2Unit = Dta%EmisL1Unit
    4564             : 
    4565             :              ENDIF
    4566             :           ENDIF
    4567             :        ELSE
    4568             : 
    4569             :           ! If we get to here, it's 3D data
    4570           0 :           Dta%SpaceDim = 3
    4571             : 
    4572             :           ! The third entry determines the vertical dimension.
    4573             :           ! This can be 'z' (standard) or a number to explicitly define
    4574             :           ! the vertical extension and direction.
    4575           0 :           IF ( str1(3:3) /= 'z' ) THEN
    4576           0 :              READ(str1(3:strLen),*) Dta%Levels
    4577             :           ENDIF
    4578             :        ENDIF
    4579             :     ENDIF
    4580             : 
    4581             :     ! Eventually set additional dimension name and value
    4582           0 :     IF ( TRIM(str2) /= '' ) THEN
    4583             :        MSG = 'Cannot extract arbitrary dimension from ' &
    4584             :            // TRIM(srcDim) // ' for file ' // TRIM(Dta%ncFile) &
    4585             :            // ' - arbitrary dimensions must follow a `+` sign ' &
    4586           0 :            // 'and contain the name/value pair, e.g. xyz+"ens"=3'
    4587           0 :        idx = INDEX( TRIM(str2), '=' )
    4588           0 :        IF ( idx <= 0 ) THEN
    4589           0 :           CALL HCO_Error( msg, RC, thisLoc=LOC )
    4590           0 :           RETURN
    4591             :        ENDIF
    4592             : 
    4593             :        ! Extract dimension name. Eventually remove '"' character at
    4594             :        ! beginning
    4595           0 :        IF ( str2(1:1) == '"' .OR. &
    4596             :             str2(1:1) == '`'       ) THEN
    4597           0 :           Dta%ArbDimName = str2(2:(idx-1))
    4598             :        ELSE
    4599           0 :           Dta%ArbDimName = str2(1:(idx-1))
    4600             :        ENDIF
    4601             : 
    4602             :        ! Extract dimension value. Eventually remove trailing '"'
    4603             :        ! character. The string value itself will be evaluated when
    4604             :        ! reading the file (in hcoio_dataread_mod.F90).
    4605           0 :        strlen = LEN(TRIM(str2))
    4606           0 :        IF ( str2(strlen:strlen) == '"' .OR. &
    4607             :             str2(strlen:strlen) == '`'       ) THEN
    4608           0 :           Dta%ArbDimVal = str2((idx+1):(strlen-1))
    4609             :        ELSE
    4610           0 :           Dta%ArbDimVal = str2((idx+1):(strlen))
    4611             :        ENDIF
    4612             : 
    4613             :        ! Verbose
    4614           0 :        IF ( HcoConfig%amIRoot .AND. HCO_IsVerb(HcoConfig%Err ) ) THEN
    4615           0 :           WRITE(MSG,*) 'Will use additional dimension on file ', &
    4616           0 :              TRIM(Dta%ncFile), ': ', TRIM(Dta%ArbDimName), ' = ', &
    4617           0 :              TRIM(Dta%ArbDimVal)
    4618           0 :           CALL HCO_Msg( HcoConfig%Err, msg )
    4619             :        ENDIF
    4620             :     ENDIF
    4621             : 
    4622             :     ! Leave w/ success
    4623           0 :     RC = HCO_SUCCESS
    4624             : 
    4625           0 :   END SUBROUTINE ExtractSrcDim
    4626             : !EOC
    4627             : !------------------------------------------------------------------------------
    4628             : !                   Harmonized Emissions Component (HEMCO)                    !
    4629             : !------------------------------------------------------------------------------
    4630             : !BOP
    4631             : !
    4632             : ! !IROUTINE: ConfigInit
    4633             : !
    4634             : ! !DESCRIPTION: Subroutine ConfigInit is a wrapper routine to initialize the
    4635             : !  HEMCO configuration object.
    4636             : !\\
    4637             : !\\
    4638             : ! !INTERFACE:
    4639             : !
    4640           0 :   SUBROUTINE ConfigInit ( HcoConfig, RC, nModelSpecies )
    4641             : !
    4642             : ! !INPUT PARAMETERS:
    4643             : !
    4644             :     INTEGER, INTENT(IN), OPTIONAL  :: nModelSpecies  ! # model species
    4645             : !
    4646             : ! !INPUT/OUTPUT PARAMETERS:
    4647             : !
    4648             :     TYPE(ConfigObj), POINTER       :: HcoConfig
    4649             :     INTEGER,         INTENT(INOUT) :: RC             ! Success/fail
    4650             : !
    4651             : ! !REVISION HISTORY:
    4652             : !  16 Feb 2016 - C. Keller: Initialization (update)
    4653             : !  See https://github.com/geoschem/hemco for complete history
    4654             : !EOP
    4655             : !------------------------------------------------------------------------------
    4656             : !BOC
    4657             : !
    4658             : ! !LOCAL VARIABLES:
    4659             : !
    4660             :     INTEGER            :: I, AS
    4661             :     CHARACTER(LEN=255) :: thisLoc
    4662             :     CHARACTER(LEN=512) :: errMsg
    4663             : 
    4664             :     !=====================================================================
    4665             :     ! ConfigInit begins here!
    4666             :     !=====================================================================
    4667             : 
    4668           0 :     ALLOCATE(HcoConfig)
    4669           0 :     HcoConfig%ConfigFileName = ''
    4670           0 :     HcoConfig%ROOT           = ''
    4671           0 :     HcoConfig%ConfigFileRead = .FALSE.
    4672           0 :     HcoConfig%ConfigList     => NULL()
    4673           0 :     HcoConfig%ScalIDList     => NULL()
    4674           0 :     HcoConfig%SpecNameList   => NULL()
    4675           0 :     HcoConfig%ExtList        => NULL()
    4676           0 :     HcoConfig%Err            => NULL()
    4677             : 
    4678           0 :     IF ( PRESENT( nModelSpecies ) ) THEN
    4679             : 
    4680             :        ! Initialize strings
    4681           0 :        errMsg  = ''
    4682           0 :        thisLoc = 'ConfigInit (in module hco_config_mod.F90)'
    4683             : 
    4684             :        ! Initialize vector w/ species information
    4685           0 :        HcoConfig%nModelSpc = nModelSpecies
    4686           0 :        IF ( nModelSpecies > 0 ) THEN
    4687           0 :           ALLOCATE ( HcoConfig%ModelSpc( nModelSpecies ), STAT=AS )
    4688           0 :           IF ( AS /= 0 ) THEN
    4689           0 :              errMsg = 'Could not allocate "ModelSpecies" array!'
    4690           0 :              CALL HCO_Error( errMsg, RC, thisLoc )
    4691           0 :              RETURN
    4692             :           ENDIF
    4693             : 
    4694             :           ! Initalize species information. The effective values for species
    4695             :           ! names, model IDs, etc. are set in the HEMCO-model interface
    4696             :           ! routine.
    4697           0 :           DO I = 1, nModelSpecies
    4698           0 :              HcoConfig%ModelSpc(I)%HcoID      = I
    4699           0 :              HcoConfig%ModelSpc(I)%ModID      = -1
    4700           0 :              HcoConfig%ModelSpc(I)%SpcName    = ''
    4701             :           ENDDO
    4702             :        ENDIF
    4703             : 
    4704             :     ENDIF
    4705             : 
    4706             :   END SUBROUTINE ConfigInit
    4707             : !EOC
    4708             : !------------------------------------------------------------------------------
    4709             : !                   Harmonized Emissions Component (HEMCO)                    !
    4710             : !------------------------------------------------------------------------------
    4711             : !BOP
    4712             : !
    4713             : ! !IROUTINE: ParseEmisL
    4714             : !
    4715             : ! !DESCRIPTION: parses the emission level.
    4716             : !\\
    4717             : !\\
    4718             : ! !INTERFACE:
    4719             : !
    4720           0 :   SUBROUTINE ParseEmisL ( str, EmisL, EmisUnit, ScalID )
    4721             : !
    4722             : ! !INPUT PARAMETERS:
    4723             : !
    4724             :     CHARACTER(LEN=*),  INTENT(IN ) :: str
    4725             : !
    4726             : ! !INPUT/OUTPUT PARAMETERS:
    4727             : !
    4728             :     REAL(hp),          INTENT(OUT) :: EmisL
    4729             :     INTEGER,           INTENT(OUT) :: EmisUnit
    4730             :     INTEGER,           INTENT(OUT) :: ScalID
    4731             : !
    4732             : ! !REVISION HISTORY:
    4733             : !  09 May 2016 - C. Keller: Intial version.
    4734             : !  See https://github.com/geoschem/hemco for complete history
    4735             : !EOP
    4736             : !------------------------------------------------------------------------------
    4737             : !BOC
    4738             : !
    4739             : ! !LOCAL VARIABLES:
    4740             : !
    4741             :     INTEGER  :: nchar, idx
    4742             : 
    4743             :     !======================================================================
    4744             :     ! ParseEmisL begins here!
    4745             :     !======================================================================
    4746             : 
    4747             :     ! Init
    4748           0 :     EmisUnit = HCO_EMISL_LEV
    4749           0 :     ScalID   = -1
    4750             : 
    4751           0 :     IF ( TRIM(str) == 'PBL' ) THEN
    4752           0 :        EmisL    = 0.0_hp
    4753           0 :        EmisUnit = HCO_EMISL_PBL
    4754             :     ELSE
    4755             :        ! extract scale factor if string starts with 'SCAL' or 'scal'
    4756           0 :        nchar = LEN(str)
    4757           0 :        IF ( nchar > 4 ) THEN
    4758           0 :           IF ( str(1:4)=='SCAL' .OR. str(1:4)=='scal' ) THEN
    4759           0 :              READ(str(5:nchar),*) ScalID
    4760           0 :              EmisUnit = -1
    4761           0 :              EmisL    = -1.0
    4762             :           ENDIF
    4763             :        ENDIF
    4764             : 
    4765             :        ! check for elevation unit flag (e.g. 1000m)
    4766           0 :        IF ( ScalID < 0 ) THEN
    4767           0 :           idx = INDEX(TRIM(str),'m')
    4768           0 :           IF ( idx > 0 ) THEN
    4769           0 :              READ(str(1:(idx-1)),*) EmisL
    4770           0 :              EmisUnit = HCO_EMISL_M
    4771             :           ELSE
    4772           0 :              READ(str,*) EmisL
    4773             :           ENDIF
    4774             :        ENDIF
    4775             :     ENDIF
    4776             : 
    4777           0 :   END SUBROUTINE ParseEmisL
    4778             : !EOC
    4779             : !------------------------------------------------------------------------------
    4780             : !                   Harmonized Emissions Component (HEMCO)                    !
    4781             : !------------------------------------------------------------------------------
    4782             : !BOP
    4783             : !
    4784             : ! !IROUTINE: CheckForDuplicateName
    4785             : !
    4786             : ! !DESCRIPTION: Subroutine CheckForDuplicateName checks if there is a
    4787             : ! container in the container linked list that has the same name as the
    4788             : ! name given as input argument.
    4789             : !\\
    4790             : !\\
    4791             : ! !INTERFACE:
    4792             : !
    4793           0 :   Subroutine CheckForDuplicateName( HcoConfig, cName, RC )
    4794             : !
    4795             : ! !INPUT ARGUMENT:
    4796             : !
    4797             :     TYPE(ConfigObj) , POINTER    :: HcoConfig  ! HEMCO config obj
    4798             :     CHARACTER(LEN=*), INTENT(IN) :: cName
    4799             : !
    4800             : ! !OUTPUT ARGUMENT:
    4801             : !
    4802             :     INTEGER, INTENT(INOUT)  :: RC
    4803             : !
    4804             : ! !REVISION HISTORY:
    4805             : !  20 Jul 2018 - C. Keller: Initial version
    4806             : !  See https://github.com/geoschem/hemco for complete history
    4807             : !EOP
    4808             : !------------------------------------------------------------------------------
    4809             : !BOC
    4810             : !
    4811             : ! !LOCAL VARIABLES:
    4812             : !
    4813             :     TYPE(ListCont), POINTER :: ThisLct => NULL()
    4814             :     LOGICAL                 :: Duplicate
    4815             :     CHARACTER(LEN=255)      :: tmpName, thisLoc
    4816             :     CHARACTER(LEN=512)      :: errMsg
    4817             : 
    4818             :     !======================================================================
    4819             :     ! CheckForDuplicateName begins here!
    4820             :     !======================================================================
    4821             : 
    4822             :     ! Init
    4823           0 :     RC        = HCO_SUCCESS
    4824           0 :     errMsg    = ''
    4825           0 :     thisLoc   = 'CheckForDuplicateName (in module hco_config_mod.F90)'
    4826           0 :     Duplicate = .FALSE.
    4827             : 
    4828             :     ! Pass name to clear spaces
    4829           0 :     tmpName = ADJUSTL(cName)
    4830             : 
    4831             :     ! Walk through list and check for duplicate. Exit if found
    4832           0 :     ThisLct => HcoConfig%ConfigList
    4833           0 :     DO WHILE ( ASSOCIATED ( ThisLct ) )
    4834             : 
    4835             :        ! Skip if data container not defined
    4836           0 :        IF ( .NOT. ASSOCIATED(ThisLct%Dct) ) THEN
    4837           0 :           ThisLct => ThisLct%NextCont
    4838           0 :           CYCLE
    4839             :        ENDIF
    4840             : 
    4841             :        ! Check if this container has desired scalID
    4842           0 :        IF ( TRIM(ThisLct%Dct%cName) == TRIM(tmpName) ) THEN
    4843           0 :           Duplicate = .TRUE.
    4844           0 :           EXIT
    4845             :        ENDIF
    4846             : 
    4847             :        ! Move to next container
    4848           0 :        ThisLct => ThisLct%NextCont
    4849             :     ENDDO
    4850             : 
    4851             :     IF ( Duplicate ) THEN
    4852           0 :        errMsg = 'Error: HEMCO field already exists:'//TRIM(cName)
    4853           0 :        CALL HCO_Error( errMsg, RC, thisLoc )
    4854           0 :        RETURN
    4855             :     ENDIF
    4856             : 
    4857           0 :   END SUBROUTINE CheckForDuplicateName
    4858             :   !EOC
    4859             : !------------------------------------------------------------------------------
    4860             : !                  GEOS-Chem Global Chemical Transport Model                  !
    4861             : !------------------------------------------------------------------------------
    4862             : !BOP
    4863             : !
    4864             : ! !IROUTINE: Hco_GetTagInfo
    4865             : !
    4866             : ! !DESCRIPTION: Subroutine HCO\_GETTAGINFO retrieves basic information about
    4867             : ! tags given a wildcard string.
    4868             : !\\
    4869             : !\\
    4870             : ! !INTERFACE:
    4871             : !
    4872           0 :   SUBROUTINE Hco_GetTagInfo( tagID, HcoConfig, Found, &
    4873           0 :                              RC,    N,         tagName,  nTags            )
    4874             : !
    4875             : ! !USES:
    4876             : !
    4877             : !
    4878             : ! !INPUT PARAMETERS:
    4879             : !
    4880             :     CHARACTER(LEN=*),   INTENT(IN)  :: tagID       ! ID of tag (e.g. wildcard)
    4881             :     TYPE(ConfigObj),    POINTER     :: HcoConfig   ! HEMCO Config object
    4882             :     INTEGER,            OPTIONAL    :: N           ! index (1 to # tags)
    4883             : !
    4884             : ! !OUTPUT PARAMETERS:
    4885             : !
    4886             :     LOGICAL,            INTENT(OUT) :: Found       ! Item found?
    4887             :     INTEGER,            INTENT(OUT) :: RC          ! Return code
    4888             :     CHARACTER(LEN=255), OPTIONAL    :: tagName     ! tag name for index N
    4889             :     INTEGER,            OPTIONAL    :: nTags       ! # tags
    4890             : !
    4891             : ! !REMARKS:
    4892             : !
    4893             : ! !REVISION HISTORY:
    4894             : !  23 Oct 2018 - M. Sulprizio- Initial version based on routine Get_TagInfo in
    4895             : !                              GEOS-Chem's Headers/state_diag_mod.F90
    4896             : !  See https://github.com/geoschem/hemco for complete history
    4897             : !EOP
    4898             : !------------------------------------------------------------------------------
    4899             : !BOC
    4900             : !
    4901             : ! !LOCAL VARIABLES:
    4902             : !
    4903             :     ! Scalars
    4904             :     INTEGER            :: D,         numTags
    4905             :     LOGICAL            :: isNumTags, isTagName, isN
    4906             : 
    4907             :     ! Strings
    4908             :     CHARACTER(LEN=255) :: thisLoc,   Nstr
    4909             :     CHARACTER(LEN=512) :: errMsg
    4910             : 
    4911             :     !=======================================================================
    4912             :     ! Hco_GetTagInfo begins here
    4913             :     !=======================================================================
    4914             : 
    4915             :     ! Initialize
    4916           0 :     errMsg     = ''
    4917           0 :     thisLoc    = 'Hco_Get_TagInfo (in module hco_config_mod.F90)'
    4918           0 :     Found      = .TRUE.
    4919           0 :     numTags    = 0
    4920             : 
    4921             :     ! Optional arguments present?
    4922           0 :     isN        = PRESENT( N       )
    4923           0 :     isTagName  = PRESENT( TagName )
    4924           0 :     isNumTags  = PRESENT( nTags   )
    4925             : 
    4926             :     ! Exit with error if getting tag name but index not specified
    4927           0 :     IF ( isTagName .AND. .NOT. isN ) THEN
    4928           0 :        ErrMsg = 'Index must be specified if retrieving an individual tag name'
    4929           0 :        CALL HCO_Error( errMsg, RC, thisLoc )
    4930           0 :        RETURN
    4931             :     ENDIF
    4932             : 
    4933             :     !=======================================================================
    4934             :     ! Get number of tags
    4935             :     !=======================================================================
    4936           0 :     SELECT CASE( TRIM( tagId ) )
    4937             :        CASE( 'ALL'     )
    4938           0 :           numTags = HcoConfig%nModelSpc
    4939             :        CASE( 'ADV'     )
    4940           0 :           numTags = HcoConfig%nModelAdv
    4941             :        CASE DEFAULT
    4942           0 :           FOUND = .FALSE.
    4943             :           ErrMsg = 'Handling of tagId ' // TRIM(tagId) // &
    4944           0 :                    ' is not implemented for getting number of tags'
    4945           0 :           CALL HCO_Error( errMsg, RC, thisLoc )
    4946           0 :           RETURN
    4947             :     END SELECT
    4948             : 
    4949             :     !=======================================================================
    4950             :     ! Sanity checks -- exit under certain conditions
    4951             :     !=======================================================================
    4952             : 
    4953             :     ! If not getting tag name then set nTags and exit
    4954           0 :     IF ( .NOT. isTagName ) THEN
    4955           0 :        nTags = numTags
    4956           0 :        RETURN
    4957             :     ENDIF
    4958             : 
    4959             :     ! Exit with error if index exceeds number of tags for this wildcard
    4960             :     IF ( isTagName .AND. .NOT. isN ) THEN
    4961             :        errMsg =                                                              &
    4962             :             'Index must be greater than total number of tags for wildcard'   &
    4963             :              // TRIM(tagId)
    4964             :        CALL HCO_Error( errMsg, RC, thisLoc )
    4965             :        RETURN
    4966             :     ENDIF
    4967             : 
    4968             :     !=======================================================================
    4969             :     ! Get mapping index
    4970             :     !=======================================================================
    4971           0 :     SELECT CASE( TRIM( tagID ) )
    4972             :        CASE( 'ALL', 'ADV' )
    4973           0 :           D = N
    4974             :        CASE DEFAULT
    4975           0 :           FOUND = .FALSE.
    4976             :           errMsg = 'Handling of tagId ' // TRIM( tagId ) // &
    4977           0 :                    ' is not implemented for getting tag name'
    4978           0 :           CALL HCO_Error( errMsg, RC, thisLoc )
    4979           0 :           RETURN
    4980             :     END SELECT
    4981             : 
    4982             :     !=======================================================================
    4983             :     ! Return the tag name
    4984             :     !=======================================================================
    4985           0 :     tagName = HcoConfig%ModelSpc(D)%SpcName
    4986             : 
    4987             :   END SUBROUTINE Hco_GetTagInfo
    4988             : !EOC
    4989             : !------------------------------------------------------------------------------
    4990             : !                  GEOS-Chem Global Chemical Transport Model                  !
    4991             : !------------------------------------------------------------------------------
    4992             : !BOP
    4993             : !
    4994             : ! !IROUTINE: UpdateDtaProperties
    4995             : !
    4996             : ! !DESCRIPTION: Updates metdata about the current data container that is
    4997             : !  being created (e.g. time cycle information, level information, etc.)
    4998             : !\\
    4999             : !\\
    5000             : ! !INTERFACE:
    5001             : !
    5002           0 :   SUBROUTINE UpdateDtaProperties( char1,     char2,     dctType,  int3,       &
    5003             :                                   separator, srcDim,    tagCName, tmCycle,    &
    5004             :                                   wildCard,  HcoConfig, Lct,      Dta,        &
    5005             :                                   RC                                         )
    5006             : !
    5007             : ! !INPUT PARAMETERS:
    5008             : !
    5009             :     CHARACTER(LEN=*), INTENT(IN)  :: char1      !
    5010             :     CHARACTER(LEN=1), INTENT(IN)  :: char2      !
    5011             :     INTEGER,          INTENT(IN)  :: dctType    ! 1=base; 2=scale; 3=mask
    5012             :     INTEGER,          INTENT(IN)  :: int3       !
    5013             :     CHARACTER(LEN=*), INTENT(IN)  :: separator  ! Separator character
    5014             :     CHARACTER(LEN=*), INTENT(IN)  :: srcDim     ! e.g. "xyz", "xy", etc.
    5015             :     CHARACTER(LEN=*), INTENT(IN)  :: tagCName   ! Contaniner name
    5016             :     CHARACTER(LEN=*), INTENT(IN)  :: tmCycle    ! Tioe cycle flag setting
    5017             :     CHARACTER(LEN=*), INTENT(IN)  :: wildCard   ! Wild card character
    5018             :     TYPE(ConfigObj),  POINTER     :: HcoConfig  ! HEMCO configuration object
    5019             : !
    5020             : ! !INPUT/OUTPUT PARAMETERS:
    5021             : !
    5022             :     TYPE(ListCont),   POINTER     :: Lct        ! List container object
    5023             :     TYPE(FileData),   POINTER     :: Dta        ! Data container object
    5024             : !
    5025             : ! !OUTPUT PARAMETERS:
    5026             : !
    5027             :     INTEGER,          INTENT(OUT) :: RC         ! Success or failure
    5028             : !
    5029             : ! !REMARKS:
    5030             : !  Abstracted from routine Config_ReadCont.
    5031             : !EOP
    5032             : !------------------------------------------------------------------------------
    5033             : !BOC
    5034             : !
    5035             : ! !LOCAL VARIABLES:
    5036             : !
    5037             :     ! Scalars
    5038             :     INTEGER            :: levScal1
    5039             :     INTEGER            :: levScal2
    5040             :     INTEGER            :: nEdges
    5041             : 
    5042             :     ! Arrays
    5043             :     INTEGER            :: splitInts(255)
    5044             : 
    5045             :     ! Strings
    5046             :     CHARACTER(LEN=255) :: thisLoc
    5047             :     CHARACTER(LEN=512) :: errMsg
    5048             : 
    5049             :     ! String arrays
    5050             :     CHARACTER(LEN=255) :: SubStrs(255)
    5051             : 
    5052             :     !========================================================================
    5053             :     ! UpdateDtaProperties begins here!
    5054             :     !========================================================================
    5055             : 
    5056             :     ! Initialize
    5057           0 :     RC        = HCO_SUCCESS
    5058           0 :     levScal1  = 0
    5059           0 :     levScal2  = 0
    5060           0 :     nEdges    = 0
    5061           0 :     splitInts = 0
    5062           0 :     errMsg    = ''
    5063             :     thisLoc   = &
    5064           0 :     ' -> at UpdateDtaProperties (in module HEMCO/src/Core/hco_config_mod.F90)'
    5065             : 
    5066             :     !========================================================================
    5067             :     ! Set time cycling behaviour. Possible values are:
    5068             :     ! - "C"   : cycling <-- DEFAULT
    5069             :     ! - "CS"  : cycling, skip if not exist
    5070             :     ! - "CY"  : cycling, always use simulation year
    5071             :     ! - "CYS" : cycling, always use simulation yr, skip if not exist
    5072             :     ! - "R"   : range
    5073             :     ! - "RA"  : range, average outside
    5074             :     ! - "RF"  : range, forced (error if not in range)
    5075             :     ! - "RFY" : range, forced, always use simulation year
    5076             :     ! - "RFY3 : range, forced, always use simulation year, 3-hourly
    5077             :     ! - "RY"  : range, always use simulation year
    5078             :     ! - "E"   : exact, read/query once
    5079             :     ! - "EF"  : exact, forced (error if not exist), read/query once
    5080             :     ! - "EFY" : exact, forced, always use sim year
    5081             :     ! - "EFYO": exact, forced, always use sim year, read once
    5082             :     ! - "EC"  : exact, read/query continuously (e.g. for ESMF interface)
    5083             :     ! - "ECF" : exact, forced, read/query continuously
    5084             :     ! - "EY"  : exact, always use simulation year, read/query once
    5085             :     ! - "A"   : average
    5086             :     ! - "I"   : interpolate
    5087             :     ! - "ID"  : interpolate, discontinuous dataset
    5088             :     !========================================================================
    5089             : 
    5090             :     ! Zero logical fields of Dta for safety's sake
    5091           0 :     Dta%MustFind      = .FALSE.
    5092           0 :     Dta%UseSimYear    = .FALSE.
    5093           0 :     Dta%Discontinuous = .FALSE.
    5094             : 
    5095             :     ! Look for time cycle values
    5096           0 :     SELECT CASE( TRIM( TmCycle ) )
    5097             :        CASE( "C" )
    5098           0 :           Dta%CycleFlag     = HCO_CFLAG_CYCLE
    5099           0 :           Dta%MustFind      = .TRUE.
    5100             :        CASE( "CS" )
    5101           0 :           Dta%CycleFlag     = HCO_CFLAG_CYCLE
    5102           0 :           Dta%MustFind      = .FALSE.
    5103             :        CASE( "CY" )
    5104           0 :           Dta%CycleFlag     = HCO_CFLAG_CYCLE
    5105           0 :           Dta%MustFind      = .TRUE.
    5106           0 :           Dta%UseSimYear    = .TRUE.
    5107             :        CASE( "CYS" )
    5108           0 :           Dta%CycleFlag     = HCO_CFLAG_CYCLE
    5109           0 :           Dta%MustFind      = .FALSE.
    5110           0 :           Dta%UseSimYear    = .TRUE.
    5111             :        CASE( "R" )
    5112           0 :           Dta%CycleFlag     = HCO_CFLAG_RANGE
    5113             :        CASE( "RA" )
    5114           0 :           Dta%CycleFlag     = HCO_CFLAG_RANGEAVG
    5115             :        CASE( "RF" )
    5116           0 :           Dta%CycleFlag     = HCO_CFLAG_RANGE
    5117           0 :           Dta%MustFind      = .TRUE.
    5118             :        CASE( "RFY" )
    5119           0 :           Dta%CycleFlag     = HCO_CFLAG_RANGE
    5120           0 :           Dta%MustFind      = .TRUE.
    5121           0 :           Dta%UseSimYear    = .TRUE.
    5122             :        CASE( "RFY3" )
    5123           0 :           Dta%CycleFlag     = HCO_CFLAG_RANGE
    5124           0 :           Dta%MustFind      = .TRUE.
    5125           0 :           Dta%UseSimYear    = .TRUE.
    5126           0 :           Dta%UpdtFlag      = HCO_UFLAG_3HR
    5127             :        CASE( "RY" )
    5128           0 :           Dta%CycleFlag     = HCO_CFLAG_RANGE
    5129           0 :           Dta%UseSimYear    = .TRUE.
    5130             :        CASE( "E" )
    5131           0 :           Dta%CycleFlag     = HCO_CFLAG_EXACT
    5132           0 :           Dta%UpdtFlag      = HCO_UFLAG_ONCE
    5133             :        CASE( "EF" )
    5134           0 :           Dta%CycleFlag     = HCO_CFLAG_EXACT
    5135           0 :           Dta%UpdtFlag      = HCO_UFLAG_ONCE
    5136           0 :           Dta%MustFind      = .TRUE.
    5137             :        CASE( "EFY" )
    5138           0 :           Dta%CycleFlag     = HCO_CFLAG_EXACT
    5139           0 :           Dta%MustFind      = .TRUE.
    5140           0 :           Dta%UseSimYear    = .TRUE.
    5141             :        CASE( "EFYO" )
    5142           0 :           Dta%CycleFlag     = HCO_CFLAG_EXACT
    5143           0 :           Dta%UpdtFlag      = HCO_UFLAG_ONCE
    5144           0 :           Dta%MustFind      = .TRUE.
    5145           0 :           Dta%UseSimYear    = .TRUE.
    5146             :        CASE( "EC" )
    5147           0 :           Dta%CycleFlag     = HCO_CFLAG_EXACT
    5148             :        CASE( "ECF" )
    5149           0 :           Dta%CycleFlag     = HCO_CFLAG_EXACT
    5150           0 :           Dta%MustFind      = .TRUE.
    5151             :        CASE( "EY" )
    5152           0 :           Dta%CycleFlag     = HCO_CFLAG_EXACT
    5153           0 :           Dta%UpdtFlag      = HCO_UFLAG_ONCE
    5154           0 :           Dta%UseSimYear    = .TRUE.
    5155             :        CASE( "A" )
    5156           0 :           Dta%CycleFlag     = HCO_CFLAG_AVERG
    5157             :        CASE( "I" )
    5158           0 :           Dta%CycleFlag     = HCO_CFLAG_INTER
    5159             :        CASE( "ID" )
    5160           0 :           Dta%CycleFlag     = HCO_CFLAG_INTER
    5161           0 :           Dta%Discontinuous = .TRUE.
    5162             :        CASE( "-" )
    5163           0 :           Dta%CycleFlag     = HCO_CFLAG_CYCLE
    5164             :        CASE DEFAULT
    5165             :           errMsg = 'Invalid time cycling attribute: ' // tmCycle          // &
    5166           0 :                    ' - in '                           // tagcName
    5167           0 :           CALL HCO_Error( errMsg, RC, thisLoc )
    5168           0 :           RETURN
    5169             :     END SELECT
    5170             : 
    5171             :     !========================================================================
    5172             :     ! Set space dimension. This will determine the dimension of the
    5173             :     ! data array vector, i.e. 3D or 2D. Different time slices will
    5174             :     ! be stored as different vector elements.
    5175             :     ! For 3D data, it is now possible to explicitly set the number
    5176             :     ! of vertical levels to be used, as well as the 'reading
    5177             :     ! direction' (up or down). These information is also extracted
    5178             :     ! from srcDim and will be stored in variable Dta%Levels.
    5179             :     ! (ckeller, 5/20/15)
    5180             :     ! ExtractSrcDim now also returns possible scale factors for the
    5181             :     ! injection level, which will be stored in container variable
    5182             :     ! levScalID1 (bottom level) and levScalID2 (top level).
    5183             :     !========================================================================
    5184           0 :     CALL ExtractSrcDim( HcoConfig, srcDim, Dta, levScal1, levScal2, RC       )
    5185           0 :     IF ( RC /= HCO_SUCCESS ) THEN
    5186           0 :        errMsg = 'Error encountered in routine "ExtractSrcDim"!'
    5187           0 :        CALL HCO_Error( errMsg, RC, thisLoc )
    5188           0 :        RETURN
    5189             :     ENDIF
    5190             : 
    5191             :     ! Set level scale factor index
    5192           0 :     IF ( levScal1 > 0 ) Lct%Dct%levScalID1 = levScal1
    5193           0 :     IF ( levScal2 > 0 ) Lct%Dct%levScalID2 = levScal2
    5194             : 
    5195             :     !========================================================================
    5196             :     ! For scale factors: check if a mask is assigned to this scale factor.
    5197             :     ! In this case, pass mask ID to first slot of Scal_cID vector. This
    5198             :     ! value will be set to the container ID of the corresponding mask
    5199             :     ! field later on.
    5200             :     !========================================================================
    5201           0 :     IF ( DctType == HCO_DCTTYPE_SCAL .AND. Int3 > 0 ) THEN
    5202           0 :        ALLOCATE ( Lct%Dct%Scal_cID(1) )
    5203           0 :        Lct%Dct%Scal_cID(1) = Int3
    5204           0 :        Lct%Dct%nScalID     = 1
    5205             :     ENDIF
    5206             : 
    5207             :     !========================================================================
    5208             :     ! For masks: extract grid box edges. These will be used later on to
    5209             :     ! determine if emissions have to be considered by this CPU.
    5210             :     !========================================================================
    5211           0 :     IF ( DctType == HCO_DCTTYPE_MASK ) THEN
    5212             : 
    5213             :        ! Extract grid box edges. Need to be four values.
    5214             :        CALL HCO_CharSplit( char1,     separator, wildcard,                   &
    5215           0 :                            splitInts, nEdges,    RC                         )
    5216           0 :        IF ( RC /= HCO_SUCCESS ) THEN
    5217           0 :           errMsg = 'Error encountered in routine "HCO_CharSplit"!'
    5218           0 :           CALL HCO_Error( errMsg, RC, thisLoc )
    5219           0 :           RETURN
    5220             :        ENDIF
    5221           0 :        IF ( nEdges /= 4 ) THEN
    5222             :           errMsg = 'Cannot properly read mask coverage: '                 // &
    5223           0 :                    TRIM( Lct%Dct%cName )
    5224           0 :           CALL HCO_Error( errMsg, RC, thisLoc )
    5225           0 :           RETURN
    5226             :        ENDIF
    5227             : 
    5228             :        ! Save temporarily in year and month range. Will be
    5229             :        ! reset lateron.
    5230           0 :        Dta%ncYrs(1) = splitInts(1)
    5231           0 :        Dta%ncYrs(2) = splitInts(2)
    5232           0 :        Dta%ncMts(1) = splitInts(3)
    5233           0 :        Dta%ncMts(2) = splitInts(4)
    5234             : 
    5235             :        ! Make sure that masks are always being read if specified so.
    5236           0 :        IF ( char2 == 'y' .OR. char2 == 'Y' ) THEN
    5237           0 :           CALL ScalID2List( HcoConfig%ScalIDList, Lct%Dct%ScalID, RC )
    5238           0 :           IF ( RC /= HCO_SUCCESS ) THEN
    5239           0 :              errMsg = 'Error encountered in routine "ScalID2List"!'
    5240           0 :              CALL HCO_Error( errMsg, RC, thisLoc )
    5241           0 :              RETURN
    5242             :           ENDIF
    5243             :        ENDIF
    5244             :     ENDIF
    5245             : 
    5246           0 :   END SUBROUTINE UpdateDtaProperties
    5247             : !EOC
    5248             : END MODULE HCO_Config_Mod

Generated by: LCOV version 1.14