LCOV - code coverage report
Current view: | top level - hemco/HEMCO/src/Core - hco_unit_mod.F90 (source / functions) |  |  | Hit | Total | Coverage
Test: | coverage.info |  | Lines: | 0 | 155 | 0.0 %
Date: | 2024-12-17 17:57:11 |  | Functions: | 0 | 10 | 0.0 %

              Line data    Source code
           1             : !------------------------------------------------------------------------------
           2             : !                   Harmonized Emissions Component (HEMCO)                    !!
           3             : !------------------------------------------------------------------------------
           4             : !BOP
           5             : !
           6             : ! !MODULE: hco_unit_mod.F90
           7             : !
           8             : ! !DESCRIPTION: Module HCO\_Unit\_Mod contains routines to check/convert
           9             : ! units.
          10             : !\\
          11             : !\\
          12             : ! !INTERFACE:
          13             : !
          14             : MODULE HCO_Unit_Mod
          15             : !
          16             : ! !USES:
          17             : !
          18             :   USE HCO_Error_Mod
          19             :
          20             :   IMPLICIT NONE
          21             :   PRIVATE
          22             : !
          23             : ! !PUBLIC MEMBER FUNCTIONS:
          24             : !
          25             :   PUBLIC :: HCO_Unit_Change
          26             :   PUBLIC :: HCO_Unit_GetMassScal
          27             :   PUBLIC :: HCO_Unit_GetAreaScal
          28             :   PUBLIC :: HCO_Unit_GetTimeScal
          29             :   PUBLIC :: HCO_Unit_ScalCheck
          30             :   PUBLIC :: HCO_IsUnitLess
          31             :   PUBLIC :: HCO_IsIndexData
          32             :   PUBLIC :: HCO_UnitTolerance
          33             : !
          34             : ! !PRIVATE MEMBER FUNCTIONS:
          35             : !
          36             :   PRIVATE :: HCO_Unit_Change_SP
          37             :   PRIVATE :: HCO_Unit_Change_DP
          38             : !
          39             : ! !REVISION HISTORY:
          40             : !  15 May 2012 - C. Keller   - Initialization
          41             : !  See https://github.com/geoschem/hemco for complete history
          42             : !EOP
          43             : !------------------------------------------------------------------------------
          44             : !BOC
          45             : !
          46             : ! !DEFINED PARAMETERS:
          47             : !
          48             :   REAL(dp),  PARAMETER :: N_0             = 6.022140857e+23_dp
          49             :   REAL(hp),  PARAMETER :: SEC_IN_DAY      = 86400._hp
          50             :   REAL(hp),  PARAMETER :: SEC_IN_LEAPYEAR = SEC_IN_DAY * 366._hp
          51             :   REAL(hp),  PARAMETER :: SEC_IN_REGYEAR  = SEC_IN_DAY * 365._hp
          52             :
          53             :   ! Accepted units for unitless data. No unit conversion is applied to
          54             :   ! data with any of these units. The first entry represents the
          55             :   ! character that denotes unitless data in the HEMCO configuration
          56             :   ! file. The second entry represents the character that denotes
          57             :   ! index data. Different regridding algorithms are applied to
          58             :   ! index data compared to unitless data.
          59             :   ! All units listed below will not be converted by HEMCO. You can
          60             :   ! add more units if you don't want HEMCO to attempt to convert data
          61             :   ! in these units.
          62             :   ! All characters in this list should be lower case!
          63             :   INTEGER,           PARAMETER :: NUL = 38
          64             :   CHARACTER(LEN=15), PARAMETER :: UL(NUL) = (/ '1          ',   &
          65             :                                                'count      ',   &
          66             :                                                'unitless   ',   &
          67             :                                                'fraction   ',   &
          68             :                                                'factor     ',   &
          69             :                                                'scale      ',   &
          70             :                                                'hours      ',   &
          71             :                                                'mol/mol    ',   &
          72             :                                                'v/v        ',   &
          73             :                                                'v/v/s      ',   &
          74             :                                                's-1        ',   &
          75             :                                                's^-1       ',   &
          76             :                                                'm2/m2      ',   &
          77             :                                                'm2m-2      ',   &
          78             :                                                'kg/kg      ',   &
          79             :                                                'kgkg-1     ',   &
          80             :                                                'mg/m3      ',   &
          81             :                                                'mg/m2/d    ',   &
          82             :                                                'k          ',   &
          83             :                                                'w/m2       ',   &
          84             :                                                'wm-2       ',   &
          85             :                                                'pptv       ',   &
          86             :                                                'ppt        ',   &
          87             :                                                'ppbv       ',   &
          88             :                                                'ppb        ',   &
          89             :                                                'ppmv       ',   &
          90             :                                                'ppm        ',   &
          91             :                                                'm/s        ',   &
          92             :                                                'ms-1       ',   &
          93             :                                                'm          ',   &
          94             :                                                'cm2cm-2    ',   &
          95             :                                                'dobsons    ',   &
          96             :                                                'dobsons/day',   &
          97             :                                                'DU         ',   &
          98             :                                                'pa         ',   &
          99             :                                                'hpa        ',   &
         100             :                                                '%          ',   &
         101             :                                                'percent    '    /)
         102             :
         103             :   ! Accepted units for data on HEMCO standard units. No unit conversion
         104             :   ! is applied to data with any of these units.
         105             :   ! All characters in this list should be lower case!
         106             :
         107             :   ! Emission units
         108             :   INTEGER,           PARAMETER :: NHE = 2
         109             :   CHARACTER(LEN=15), PARAMETER :: HE(NHE) = (/ 'kg/m2/s    ',   &
         110             :                                                'kgm-2s-1   '  /)
         111             :   ! Concentration units
         112             :   INTEGER,           PARAMETER :: NHC = 3
         113             :   CHARACTER(LEN=15), PARAMETER :: HC(NHC) = (/ 'kg/m3 ',        &
         114             :                                                'kgm-3 ',        &
         115             :                                                'kgm^-3'       /)
         116             :
         117             :   ! Interfaces:
         118             :   INTERFACE HCO_UNIT_CHANGE
         119             :      MODULE PROCEDURE HCO_UNIT_CHANGE_SP
         120             :      MODULE PROCEDURE HCO_UNIT_CHANGE_DP
         121             :   END INTERFACE HCO_UNIT_CHANGE
         122             :
         123             : CONTAINS
         124             : !EOC
         125             : !------------------------------------------------------------------------------
         126             : !                   Harmonized Emissions Component (HEMCO)                    !
         127             : !------------------------------------------------------------------------------
         128             : !BOP
         129             : !
         130             : ! !IROUTINE: HCO_Unit_Change_sp
         131             : !
         132             : ! !DESCRIPTION: Subroutine HCO\_UNIT\_CHANGE\_SP is a wrapper routine to
         133             : ! convert the values of the passed single precision array to units of kg/m2/s.
         134             : !\\
         135             : !\\
         136             : ! !INTERFACE:
         137             : !
         138           0 :   SUBROUTINE HCO_Unit_Change_SP( HcoConfig, ARRAY, UNITS,    MW, &
         139             :                                  YYYY,      MM,    AreaFlag, &
         140             :                                  TimeFlag,  FACT,  RC )
         141             : !
         142             : ! !USES:
         143             : !
         144             :     USE HCO_TYPES_MOD,    ONLY : ConfigObj
         145             : !
         146             : ! !INPUT PARAMETERS:
         147             : !
         148             :     TYPE(ConfigObj),  POINTER                 :: HcoConfig
         149             :     CHARACTER(LEN=*), INTENT(IN )             :: UNITS          ! Data unit
         150             :     REAL(hp),         INTENT(IN )             :: MW             ! MW g/mol
         151             :     INTEGER,          INTENT(IN )             :: YYYY           ! Data year
         152             :     INTEGER,          INTENT(IN )             :: MM             ! Data month
         153             : !
         154             : ! !INPUT/OUTPUT PARAMETERS:
         155             : !
         156             :     INTEGER,          INTENT(INOUT)           :: AreaFlag       ! 2 if per area,
         157             :                                                                 ! 3 if per vol,
         158             :                                                                 ! 0 otherwise
         159             :     INTEGER,          INTENT(INOUT)           :: TimeFlag       ! 1 if per time,
         160             :                                                                 ! 0 otherwise
         161             :     REAL(sp),         POINTER                 :: ARRAY(:,:,:,:) ! Data
         162             :     INTEGER,          INTENT(INOUT)           :: RC
         163             : !
         164             : ! !OUTPUT PARAMETERS:
         165             : !
         166             :     REAL(hp),         INTENT(  OUT), OPTIONAL :: FACT           ! Applied factor
         167             : !
         168             : ! !REVISION HISTORY:
         169             : !  13 Aug 2014 - C. Keller - Initial Version
         170             : !  See https://github.com/geoschem/hemco for complete history
         171             : !EOP
         172             : !------------------------------------------------------------------------------
         173             : !BOC
         174             : !
         175             : ! LOCAL VARIABLES:
         176             : !
         177             :     REAL(hp)            :: Factor
         178             :     CHARACTER(LEN=255)  :: LOC
         179             :
         180             :     !=================================================================
         181             :     ! HCO_UNIT_CHANGE_SP begins here
         182             :     !=================================================================
         183           0 :     LOC = 'HCO_UNIT_CHANGE_SP (HCO_UNIT_MOD.F90)'
         184             :
         185             :     CALL HCO_Unit_Factor( HcoConfig, UNITS, MW, YYYY, MM, AreaFlag, TimeFlag, &
         186           0 :                           Factor, RC )
         187           0 :     IF ( RC /= HCO_SUCCESS ) THEN
         188           0 :         CALL HCO_ERROR( 'ERROR 0', RC, THISLOC=LOC )
         189           0 :         RETURN
         190             :     ENDIF
         191             :
         192             :     ! Apply correction factor
         193           0 :     IF ( Factor /= 1.0_hp ) THEN
         194           0 :        ARRAY(:,:,:,:) = ARRAY(:,:,:,:) * Factor
         195             :     ENDIF
         196             :
         197             :     ! Eventually return factor
         198           0 :     IF ( PRESENT(FACT) ) FACT = Factor
         199             :
         200             :     ! Leave
         201           0 :     RC = HCO_SUCCESS
         202             :
         203             :   END SUBROUTINE HCO_Unit_Change_SP
         204             : !EOC
         205             : !------------------------------------------------------------------------------
         206             : !                   Harmonized Emissions Component (HEMCO)                    !
         207             : !------------------------------------------------------------------------------
         208             : !BOP
         209             : !
         210             : ! !IROUTINE: HCO_Unit_Change_dp
         211             : !
         212             : ! !DESCRIPTION: Subroutine HCO\_UNIT\_CHANGE\_DP is a wrapper routine to
         213             : ! convert the values of the passed double precision array to units of kg/m2/s.
         214             : !\\
         215             : !\\
         216             : ! !INTERFACE:
         217             : !
         218           0 :   SUBROUTINE HCO_Unit_Change_DP( HcoConfig, ARRAY, UNITS,    MW, &
         219             :                                  YYYY,      MM,    AreaFlag, &
         220             :                                  TimeFlag,  FACT,  RC )
         221             : !
         222             : ! !USES:
         223             : !
         224             :     USE HCO_TYPES_MOD,    ONLY : ConfigObj
         225             : !
         226             : ! !INPUT PARAMETERS:
         227             : !
         228             :     TYPE(ConfigObj),  POINTER                 :: HcoConfig
         229             :     CHARACTER(LEN=*), INTENT(IN )             :: UNITS          ! Data unit
         230             :     REAL(hp),         INTENT(IN )             :: MW             ! MW g/mol
         231             :     INTEGER,          INTENT(IN )             :: YYYY           ! Data year
         232             :     INTEGER,          INTENT(IN )             :: MM             ! Data month
         233             : !
         234             : ! !INPUT/OUTPUT PARAMETERS:
         235             : !
         236             :     INTEGER,          INTENT(INOUT)           :: AreaFlag       ! 2 if per area,
         237             :                                                                 ! 3 if per vol,
         238             :                                                                 ! 0 otherwise
         239             :     INTEGER,          INTENT(INOUT)           :: TimeFlag       ! 1 if per time,
         240             :                                                                 ! 0 otherwise
         241             :     REAL(dp),         POINTER                 :: ARRAY(:,:,:,:) ! Data
         242             :     INTEGER,          INTENT(INOUT)           :: RC
         243             : !
         244             : ! !OUTPUT PARAMETERS:
         245             : !
         246             :     REAL(hp),         INTENT(  OUT), OPTIONAL :: FACT           ! Applied factor
         247             : !
         248             : ! !REVISION HISTORY:
         249             : !  13 Aug 2014 - C. Keller - Initial Version
         250             : !  See https://github.com/geoschem/hemco for complete history
         251             : !EOP
         252             : !------------------------------------------------------------------------------
         253             : !BOC
         254             : !
         255             : ! LOCAL VARIABLES:
         256             : !
         257             :     REAL(hp)            :: Factor
         258             :     CHARACTER(LEN=255)  :: LOC
         259             :
         260             :     !=================================================================
         261             :     ! HCO_UNIT_CHANGE_DP begins here
         262             :     !=================================================================
         263           0 :     LOC = 'HCO_UNIT_CHANGE_DP (HCO_UNIT_MOD.F90)'
         264             :
         265             :     CALL HCO_Unit_Factor( HcoConfig, UNITS, MW, YYYY, MM, AreaFlag, TimeFlag, &
         266           0 :                           Factor, RC )
         267           0 :     IF ( RC /= HCO_SUCCESS ) THEN
         268           0 :         CALL HCO_ERROR( 'ERROR 1', RC, THISLOC=LOC )
         269           0 :         RETURN
         270             :     ENDIF
         271             :
         272             :     ! Apply correction factor
         273           0 :     IF ( Factor /= 1.0_hp ) THEN
         274           0 :        ARRAY(:,:,:,:) = ARRAY(:,:,:,:) * Factor
         275             :     ENDIF
         276             :
         277             :     ! Eventually return factor
         278           0 :     IF ( PRESENT(FACT) ) FACT = Factor
         279             :
         280             :     ! Leave
         281           0 :     RC = HCO_SUCCESS
         282             :
         283             :   END SUBROUTINE HCO_Unit_Change_DP
         284             : !EOC
         285             : !------------------------------------------------------------------------------
         286             : !                   Harmonized Emissions Component (HEMCO)                    !
         287             : !------------------------------------------------------------------------------
         288             : !BOP
         289             : !
         290             : ! !IROUTINE: HCO_Unit_Factor
         291             : !
         292             : ! !DESCRIPTION: Subroutine HCO\_UNIT\_Factor calculates the conversion
         293             : ! factor needed to conver unit UNIT to HEMCO units.
         294             : !\\
         295             : !\\
         296             : ! The mass and area/volume conversion is always performed, but the time
         297             : ! conversion is only done if a valid time string is provided. For example,
         298             : ! if the input unit is kg/cm3 it will be converted to kg/m3, while
         299             : ! ug/m2/year is converted to kg/m2/s. If no (valid) area/volume is given in
         300             : ! the unit string, the return flag PerArea is set to False (True
         301             : ! otherwise).
         302             : !\\
         303             : !\\
         304             : ! The input argument UNITS refers to the unit of the input data.
         305             : ! Argument MW denotes the molecular weight of the species (g/mol).
         306             : !\\
         307             : !\\
         308             : ! Supported unit values:
         309             : !\\
         310             : !\\
         311             : ! MASSES:
         312             : ! \begin{itemize}
         313             : ! \item molec
         314             : ! \item atom or atoms
         315             : ! \item kg, g, mg, ug, ng
         316             : ! \end{itemize}
         317             : !
         318             : ! TIMES:
         319             : ! \begin{itemize}
         320             : ! \item s, sec, hr, hour, d, day, mt, month, y, year.
         321             : ! \item Valid formats: \/s, s-1, s\^-1.
         322             : ! \end{itemize}
         323             : !
         324             : ! VOLUMES/AREAS:
         325             : ! \begin{itemize}
         326             : ! \item cm2, m2, km2, cm3, dm3, m3, l.
         327             : ! \item Valid formats: \/cm3, cm-3, \/cm\^3, cm\^-3.
         328             : ! \end{itemize}
         329             : !
         330             : ! The following units will be ignored (no unit conversion is applied):
         331             : ! \begin{itemize}
         332             : ! \item unitless
         333             : ! \item fraction
         334             : ! \item factor
         335             : ! \item hours
         336             : ! \item degC
         337             : ! \item 1
         338             : ! \end{itemize}
         339             : !
         340             : ! !INTERFACE:
         341             : !
         342           0 :   SUBROUTINE HCO_Unit_Factor( HcoConfig, UNITS, MW, YYYY, MM, &
         343             :                               AreaFlag, TimeFlag, Factor, RC )
         344             : !
         345             : ! !USES:
         346             : !
         347             :     USE HCO_TYPES_MOD,    ONLY : ConfigObj
         348             :     USE HCO_CharPak_Mod,  ONLY : CStrip
         349             : !
         350             : ! !INPUT PARAMETERS:
         351             : !
         352             :     TYPE(ConfigObj),  POINTER               :: HcoConfig
         353             :     CHARACTER(LEN=*), INTENT(IN )           :: UNITS       ! Data unit
         354             :     REAL(hp),         INTENT(IN )           :: MW          ! MW g/mol
         355             :     INTEGER,          INTENT(IN )           :: YYYY        ! Data year
         356             :     INTEGER,          INTENT(IN )           :: MM          ! Data month
         357             : !
         358             : ! !OUTPUT PARAMETERS:
         359             : !
         360             :     INTEGER,          INTENT(  OUT)         :: AreaFlag
         361             :     INTEGER,          INTENT(  OUT)         :: TimeFlag
         362             :     REAL(hp),         INTENT(  OUT)         :: Factor      ! Conversion factor
         363             : !
         364             : ! !INPUT/OUTPUT PARAMETERS:
         365             : !
         366             :     INTEGER,          INTENT(INOUT)         :: RC
         367             : !
         368             : ! !REVISION HISTORY:
         369             : !  23 Oct 2012 - C. Keller - Initial Version
         370             : !  See https://github.com/geoschem/hemco for complete history
         371             : !EOP
         372             : !------------------------------------------------------------------------------
         373             : !BOC
         374             : !
         375             : ! LOCAL VARIABLES:
         376             : !
         377             :     INTEGER                       :: FLAG, CHECK
         378             :     REAL(hp)                      :: Coef1
         379             :     CHARACTER(LEN=31 )            :: unt
         380             :     CHARACTER(LEN=255)            :: MSG
         381             :     CHARACTER(LEN=255), PARAMETER :: LOC = 'HCO_UNIT_FACTOR (HCO_UNIT_MOD.F90)'
         382             :
         383             :     !=================================================================
         384             :     ! HCO_UNIT_FACTOR begins here
         385             :     !=================================================================
         386             :
         387             :     ! Init
         388           0 :     RC        = 0
         389           0 :     Factor    = 1.0_hp
         390           0 :     Coef1     = 1.0_hp
         391             :
         392             :     ! Get input data unit and strip all blanks.
         393           0 :     unt = TRIM(UNITS)
         394           0 :     CALL CSTRIP( unt )
         395             :
         396             :     !=================================================================
         397             :     ! For special case that data is unitless, a fraction or any other
         398             :     ! quantity that shall not be converted - or if it's already in
         399             :     ! units of kg/m2/s.
         400             :     !=================================================================
         401           0 :     CHECK = HCO_UNIT_SCALCHECK(unt)
         402             :
         403             :     ! unitless data
         404           0 :     IF ( CHECK == 0 ) THEN
         405             :
         406           0 :        AreaFlag = -1
         407           0 :        TimeFlag = -1
         408           0 :        RETURN
         409             :
         410             : !    ! emissions
         411             : !    ELSEIF ( CHECK == 1 ) THEN
         412             : !       AreaFlag = 2
         413             : !       TimeFlag = 1
         414             : !       RETURN
         415             : !
         416             : !    ! concentrations
         417             : !    ELSEIF ( CHECK == 2 ) THEN
         418             : !       AreaFlag = 3
         419             : !       TimeFlag = 0
         420             : !       RETURN
         421             :
         422             :     ENDIF
         423             :
         424             :     !=================================================================
         425             :     ! Get scale factor for mass. Force to be a valid factor.
         426             :     !=================================================================
         427           0 :     CALL HCO_UNIT_GetMassScal( HcoConfig, unt, MW, Coef1 )
         428             :
         429           0 :     IF ( Coef1 < 0.0_hp ) THEN
         430           0 :        MSG = 'cannot do unit conversion. Mass unit: ' // TRIM(unt)
         431           0 :        CALL HCO_ERROR( MSG, RC, ThisLoc = LOC )
         432           0 :        RETURN
         433             :     ENDIF
         434           0 :     Factor = Factor * Coef1
         435             :
         436             :     !=================================================================
         437             :     ! Get scale factor for time. Skip if invalid factor. This makes
         438             :     ! sure that concentrations (e.g. kg/m3) are supported!
         439             :     !=================================================================
         440           0 :     CALL HCO_UNIT_GetTimeScal( unt, MM, YYYY, Coef1, Flag )
         441           0 :     IF ( Flag > 0 ) Factor   = Factor * Coef1
         442           0 :     TimeFlag = Flag
         443             :
         444             :     !=================================================================
         445             :     ! Get scale factor for area/volume. If no area conversion
         446             :     ! factor can be determined, set PerArea flag to False.
         447             :     !=================================================================
         448           0 :     CALL HCO_UNIT_GetAreaScal( unt, Coef1, Flag )
         449           0 :     IF ( Flag > 0 ) Factor = Factor * Coef1
         450           0 :     AreaFlag = Flag
         451             :
         452             :     ! Leave
         453           0 :     RC = HCO_SUCCESS
         454             :
         455             :   END SUBROUTINE HCO_Unit_Factor
         456             : !EOC
         457             : !------------------------------------------------------------------------------
         458             : !                   Harmonized Emissions Component (HEMCO)                    !
         459             : !------------------------------------------------------------------------------
         460             : !BOP
         461             : !
         462             : ! !IROUTINE: HCO_Unit_GetMassScal
         463             : !
         464             : ! !DESCRIPTION: Returns the mass scale factors for the given unit.
         465             : ! This is the scale factor required to convert from input units to
         466             : ! HEMCO units (i.e. kg).
         467             : !\\
         468             : !\\
         469             : ! !INTERFACE:
         470             : !
         471           0 :   SUBROUTINE HCO_UNIT_GetMassScal( HcoConfig, unt, MW, Scal )
         472             : !
         473             : ! !USES:
         474             : !
         475             :     USE HCO_CharTools_Mod
         476             :     USE HCO_TYPES_MOD,    ONLY : ConfigObj
         477             : !
         478             : ! !INPUT PARAMETERS:
         479             : !
         480             :     TYPE(ConfigObj),  POINTER               :: HcoConfig
         481             :     CHARACTER(LEN=*), INTENT(IN)            :: unt         ! Input units
         482             :     REAL(hp),         INTENT(IN)            :: MW          ! MW g/mol
         483             : !
         484             : ! !OUTPUT PARAMETER:
         485             : !
         486             :     REAL(hp),         INTENT(OUT)           :: Scal        ! Scale factor
         487             : !
         488             : ! !REVISION HISTORY:
         489             : !  13 Mar 2013 - C. Keller - Initial version
         490             : !  See https://github.com/geoschem/hemco for complete history
         491             : !EOP
         492             : !------------------------------------------------------------------------------
         493             : !BOC
         494             : !
         495             : ! !LOCAL VARIABLES:
         496             : !
         497             :     CHARACTER(LEN=255)  :: MSG
         498             :
         499             :     !=================================================================
         500             :     ! HCO_UNIT_GetMassScal begins here
         501             :     !=================================================================
         502             :
         503             :     ! Init
         504           0 :     Scal = -999.0_hp
         505             :
         506             :     ! Mass unit of '1': keep as is. Note: this has to be the first
         507             :     ! entry of the unit string (e.g. 1/m2/s or 1 cm^-3). Don't
         508             :     ! accept any other ones (e.g. kg m^-2 s^-1)!
         509           0 :     IF ( unt(1:1) == '1' ) THEN
         510           0 :        Scal = 1.0_hp
         511           0 :        RETURN
         512             :     ENDIF
         513             :
         514             :     ! Error checks: all passed variables must be defined! If this is not
         515             :     ! the case, only accept kg as valid unit!
         516           0 :     IF ( MW <= 0.0_hp ) THEN
         517           0 :        IF ( IsInWord(unt,'kg') ) THEN
         518           0 :           Scal = 1.0_hp
         519           0 :           RETURN
         520             :        ELSE
         521             :           MSG = 'Cannot determine unit conversion factor for mass - ' // &
         522           0 :                 'species molecular weight is not defined!'
         523           0 :           CALL HCO_MSG(HcoConfig%Err,MSG)
         524           0 :           RETURN
         525             :        ENDIF
         526             :     ENDIF
         527             :
         528             :     ! Molecules / atoms of species: convert to kg output species.
         529           0 :     IF ( IsInWord(unt,'molec') .OR. IsInWord(unt,'atom') ) THEN
         530           0 :        Scal = MW * 1e-3_hp / N_0
         531             :
         532             :     ! Moles of species
         533           0 :     ELSEIF ( IsInWord(unt,'nmol') ) THEN
         534           0 :        Scal = 1e-9_hp * MW * 1e-3_hp
         535           0 :     ELSEIF ( IsInWord(unt,'umol') ) THEN
         536           0 :        Scal = 1e-6_hp * MW * 1e-3_hp
         537           0 :     ELSEIF ( IsInWord(unt,'mmol') ) THEN
         538           0 :        Scal = 1e-3_hp * MW * 1e-3_hp
         539           0 :     ELSEIF ( IsInWord(unt,'mol') ) THEN
         540           0 :        Scal = MW * 1e-3_hp
         541             :
         542             :     ! Mass of species
         543           0 :     ELSEIF ( IsInWord(unt,'ng') ) THEN
         544           0 :        Scal = 1e-12_hp
         545           0 :     ELSEIF ( IsInWord(unt,'ug') ) THEN
         546           0 :        Scal = 1e-9_hp
         547           0 :     ELSEIF ( IsInWord(unt,'mg') ) THEN
         548           0 :        Scal = 1e-6_hp
         549           0 :     ELSEIF ( IsInWord(unt,'kg') ) THEN
         550           0 :        Scal = 1.0_hp
         551           0 :     ELSEIF ( IsInWord(unt,'g') ) THEN
         552           0 :        Scal = 1e-3_hp
         553             :     ENDIF
         554             :
         555             :   END SUBROUTINE HCO_Unit_GetMassScal
         556             : !EOC
         557             : !------------------------------------------------------------------------------
         558             : !                   Harmonized Emissions Component (HEMCO)                    !
         559             : !------------------------------------------------------------------------------
         560             : !BOP
         561             : !
         562             : ! !IROUTINE: HCO_Unit_GetTimeScal
         563             : !
         564             : ! !DESCRIPTION: Returns the time scale factors for the given unit.
         565             : ! This is the scale factor required to convert from unit 'Unit' to
         566             : ! HEMCO units (i.e. per second).
         567             : !\\
         568             : !\\
         569             : ! !INTERFACE:
         570             : !
         571           0 :   SUBROUTINE HCO_Unit_GetTimeScal( unt, MM, YYYY, Scal, Flag )
         572             : !
         573             : ! !USES:
         574             : !
         575             :     USE HCO_CharTools_Mod
         576             : !
         577             : ! !INPUT PARAMETERS:
         578             : !
         579             :     CHARACTER(LEN=*), INTENT(IN)  :: unt   ! This unit
         580             :     INTEGER,          INTENT(IN)  :: MM    ! Current month
         581             :     INTEGER,          INTENT(IN)  :: YYYY  ! Current year
         582             : !
         583             : ! !OUTPUT PARAMETERS:
         584             : !
         585             :     REAL(hp),         INTENT(OUT) :: Scal  ! Scale factor
         586             :     INTEGER,          INTENT(OUT) :: Flag  ! 1=per time, 0 otherwise
         587             : !
         588             : ! !REVISION HISTORY:
         589             : !  13 Mar 2013 - C. Keller - Initial version
         590             : !  See https://github.com/geoschem/hemco for complete history
         591             : !EOP
         592             : !------------------------------------------------------------------------------
         593             : !BOC
         594             : !
         595             : ! !ROUTINE ARGUMENTS:
         596             : !
         597             :     INTEGER  :: Month, Year
         598             :     LOGICAL  :: IS_LEAPYEAR
         599             :     INTEGER  :: MONTHDAYS(12) = (/ 31, 28, 31, 30, 31, 30, &
         600             :                                    31, 31, 30, 31, 30, 31   /)
         601             :
         602             :     !=================================================================
         603             :     ! HCO_UNIT_GetTimeScal begins here
         604             :     !=================================================================
         605             :
         606             :     ! Init
         607           0 :     Scal = -999.0_hp
         608           0 :     Flag = 0
         609             :
         610             :     ! Is this a leap year?
         611           0 :     Year  = MAX(YYYY,1)
         612           0 :     IS_LEAPYEAR = ( (MOD(Year,4) == 0) .AND. (MOD(Year,400) /= 0) )
         613           0 :     IF ( IS_LEAPYEAR ) MONTHDAYS(2) = 29
         614             :
         615             :     ! second
         616             :     IF ( IsInWord(unt,'/s')   .OR. IsInWord(unt,'s-1') .OR. &
         617           0 :          IsInWord(unt,'s^-1') .OR. IsInWord(unt,'sec') ) THEN
         618           0 :        Scal = 1.0_hp
         619           0 :        Flag = 1
         620             :
         621             :     ! hour
         622           0 :     ELSEIF ( IsInWord(unt,'hr') .OR. IsInWord(unt,'hour') ) THEN
         623           0 :        Scal = 1.0_hp / 3600_hp
         624           0 :        Flag = 1
         625             :
         626             :     ! day
         627             :     ELSEIF ( IsInWord(unt,'/d')   .OR. IsInWord(unt,'d-1') .OR. &
         628           0 :              IsInWord(unt,'d^-1') .OR. IsInWord(unt,'day') ) THEN
         629           0 :        Scal = 1.0_hp / SEC_IN_DAY
         630           0 :        Flag = 1
         631             :
         632             :       ! month
         633           0 :     ELSEIF ( IsInWord(unt,'mt') .OR. IsInWord(unt,'month') ) THEN
         634           0 :        Month = MAX(MM,1)
         635           0 :        Scal  = 1.0_hp / MONTHDAYS(Month) / SEC_IN_DAY
         636           0 :        Flag  = 1
         637             :
         638             :     ! year
         639             :     ELSEIF ( IsInWord(unt,'/y')   .OR. IsInWord(unt,'y-1') .OR. &
         640           0 :              IsInWord(unt,'y^-1') .OR. IsInWord(unt,'yr')  .OR. &
         641             :              IsInWord(unt,'year') ) THEN
         642             :
         643           0 :        IF ( IS_LEAPYEAR ) THEN
         644           0 :           Scal = 1.0_hp / SEC_IN_LEAPYEAR
         645             :        ELSE
         646           0 :           Scal = 1.0_hp / SEC_IN_REGYEAR
         647             :        ENDIF
         648           0 :        Flag = 1
         649             :     ENDIF
         650             :
         651           0 :   END SUBROUTINE HCO_UNIT_GetTimeScal
         652             : !EOC
         653             : !------------------------------------------------------------------------------
         654             : !                   Harmonized Emissions Component (HEMCO)                    !
         655             : !------------------------------------------------------------------------------
         656             : !BOP
         657             : !
         658             : ! !IROUTINE: HCO_Unit_GetAreaScal
         659             : !
         660             : ! !DESCRIPTION: Returns the area/volume scale factors for the given unit.
         661             : ! This is the scale factor required to convert from unit 'Unit' to
         662             : ! HEMCO units (i.e. per m2 or per m3).
         663             : !\\
         664             : !\\
         665             : ! !INTERFACE:
         666             : !
         667           0 :   SUBROUTINE HCO_Unit_GetAreaScal( unt, Scal, Flag )
         668             : !
         669             : ! !USES:
         670             : !
         671             :     USE HCO_CharTools_Mod
         672             : !
         673             : ! !INPUT PARAMETERS:
         674             : !
         675             :     CHARACTER(LEN=*), INTENT(IN)  :: unt   ! This unit
         676             : !
         677             : ! !OUTPUT PARAMETERS:
         678             : !
         679             :     REAL(hp),         INTENT(OUT) :: Scal  ! scale factor
         680             :     INTEGER,          INTENT(OUT) :: Flag  ! 2=per area, 3= per volume, 0 otherwise
         681             : !
         682             : ! !REVISION HISTORY:
         683             : !  13 Mar 2013 - C. Keller - Initial version
         684             : !  See https://github.com/geoschem/hemco for complete history
         685             : !EOP
         686             : !------------------------------------------------------------------------------
         687             : !BOC
         688             :
         689             :     !=================================================================
         690             :     ! HCO_UNIT_GetAreaScal begins here
         691             :     !=================================================================
         692             :
         693             :     ! Init
         694           0 :     Scal = -999.0_hp
         695           0 :     Flag = 0
         696             :
         697             :     ! cm2
         698             :     IF ( IsInWord(unt,'/cm2' ) .OR. IsInWord(unt,'cm-2' ) .OR. &
         699           0 :          IsInWord(unt,'/cm^2') .OR. IsInWord(unt,'cm^-2')       ) THEN
         700           0 :        Scal = 1.0_hp / 1e-4_hp
         701           0 :        Flag = 2
         702             :
         703             :     ! km2
         704             :     ELSEIF ( IsInWord(unt,'/km2' ) .OR. IsInWord(unt,'km-2' ) .OR. &
         705           0 :              IsInWord(unt,'/km^2') .OR. IsInWord(unt,'km^-2')       ) THEN
         706           0 :        Scal = 1.0_hp / 1e6_hp
         707           0 :        Flag = 2
         708             :
         709             :     ! m2
         710             :     ELSEIF ( IsInWord(unt,'/m2' ) .OR. IsInWord(unt,'m-2' ) .OR. &
         711           0 :              IsInWord(unt,'/m^2') .OR. IsInWord(unt,'m^-2')       ) THEN
         712           0 :        Scal = 1.0_hp
         713           0 :        Flag = 2
         714             :
         715             :     !=================================================================
         716             :     ! Convert volume to m3
         717             :     !=================================================================
         718             :
         719             :     ! cm3
         720             :     ELSEIF ( IsInWord(unt,'/cm3')  .OR. IsInWord(unt,'cm-3' ) .OR. &
         721           0 :              IsInWord(unt,'/cm^3') .OR. IsInWord(unt,'cm^-3')       ) THEN
         722           0 :        Scal = 1.0_hp / 1e-6_hp
         723           0 :        Flag = 3
         724             :
         725             :     ! dm3
         726             :     ELSEIF ( IsInWord(unt,'/dm3')  .OR. IsInWord(unt,'dm-3' ) .OR. &
         727           0 :              IsInWord(unt,'/dm^3') .OR. IsInWord(unt,'dm^-3')       ) THEN
         728           0 :        Scal = 1.0_hp / 1e-3_hp
         729           0 :        Flag = 3
         730             :
         731             :     ! m3
         732             :     ELSEIF ( IsInWord(unt,'/m3')  .OR. IsInWord(unt,'m-3' ) .OR. &
         733           0 :              IsInWord(unt,'/m^3') .OR. IsInWord(unt,'m^-3')       ) THEN
         734           0 :        Scal = 1.0_hp
         735           0 :        Flag = 3
         736             :
         737             :     ! L
         738           0 :     ELSEIF ( IsInWord(unt,'/l') .OR. IsInWord(unt,'l-1') .OR. &
         739             :              IsInWord(unt,'l^-1')                              ) THEN
         740           0 :        Scal = 1.0_hp / 1e-3_hp
         741           0 :        Flag = 3
         742             :     ENDIF
         743             :
         744           0 :   END SUBROUTINE HCO_Unit_GetAreaScal
         745             : !EOC
         746             : !------------------------------------------------------------------------------
         747             : !                   Harmonized Emissions Component (HEMCO)                    !
         748             : !------------------------------------------------------------------------------
         749             : !BOP
         750             : !
         751             : ! !IROUTINE: HCO_Unit_ScalCheck
         752             : !
         753             : ! !DESCRIPTION: Check if the provided unit is unitless. Returns
         754             : ! 0 if Unit is unitless, 1 if it's not unitless but in correct
         755             : ! HEMCO emission units (i.e. kg/m2/s), 2 if it's in HEMCO concentration
         756             : ! units (kg/m3), -1 otherwise.
         757             : !\\
         758             : !\\
         759             : ! !INTERFACE:
         760             : !
         761           0 :   FUNCTION HCO_Unit_ScalCheck( Unit ) Result ( Flag )
         762             : !
         763             : ! !USES:
         764             : !
         765             :     USE HCO_CharPak_Mod, ONLY : TRANLC
         766             : !
         767             : ! !INPUT PARAMETERS:
         768             : !
         769             :     CHARACTER(LEN=*), INTENT(IN)  :: Unit
         770             : !
         771             : ! !OUTPUT PARAMETERS:
         772             : !
         773             :     INTEGER                       :: Flag  ! 0=ok, 1=warning, 2=error
         774             : !
         775             : ! !REVISION HISTORY:
         776             : !  13 Mar 2013 - C. Keller - Initial version
         777             : !  See https://github.com/geoschem/hemco for complete history
         778             : !EOP
         779             : !------------------------------------------------------------------------------
         780             : !BOC
         781             : !
         782             : ! !LOCAL VARIABLES:
         783             : !
         784             :     CHARACTER(LEN=31) :: tmpU
         785             :     INTEGER           :: I
         786             :
         787             :     !=================================================================
         788             :     ! HCO_UNIT_SCALCHECK begins here
         789             :     !=================================================================
         790             :
         791             :     ! Mirror
         792           0 :     tmpU = Unit
         793             :
         794             :     ! lower case
         795           0 :     CALL TRANLC( tmpU )
         796             :
         797             :     ! No recognized unit (default):
         798           0 :     Flag = -1
         799             :
         800             :     ! Check for unitless factors
         801           0 :     DO I = 1, NUL
         802           0 :        IF ( TRIM(tmpU) == TRIM(UL(I)) ) THEN
         803           0 :           Flag = 0
         804           0 :           RETURN
         805             :        ENDIF
         806             :     ENDDO
         807             :
         808             :     ! Check for HEMCO emissions units
         809           0 :     DO I = 1, NHE
         810           0 :        IF ( TRIM(tmpU) == TRIM(HE(I)) ) THEN
         811           0 :           Flag = 1
         812           0 :           RETURN
         813             :        ENDIF
         814             :     ENDDO
         815             :
         816             :     ! Check for HEMCO concentration units
         817           0 :     DO I = 1, NHC
         818           0 :        IF ( TRIM(tmpU) == TRIM(HC(I)) ) THEN
         819           0 :           Flag = 2
         820           0 :           RETURN
         821             :        ENDIF
         822             :     ENDDO
         823             :
         824           0 :   END FUNCTION HCO_Unit_ScalCheck
         825             : !EOC
         826             : !------------------------------------------------------------------------------
         827             : !                   Harmonized Emissions Component (HEMCO)                    !
         828             : !------------------------------------------------------------------------------
         829             : !BOP
         830             : !
         831             : ! !IROUTINE: HCO_IsUnitless
         832             : !
         833             : ! !DESCRIPTION: Returns TRUE if the passed string corresponds to the HEMCO
         834             : ! unitless data unit string.
         835             : !\\
         836             : !\\
         837             : ! !INTERFACE:
         838             : !
         839           0 :   FUNCTION HCO_IsUnitless( Unt ) Result ( Bool )
         840             : !
         841             : ! !INPUT PARAMETERS:
         842             : !
         843             :     CHARACTER(LEN=*), INTENT(IN)   :: Unt
         844             : !
         845             : ! !OUTPUT PARAMETERS:
         846             : !
         847             :     LOGICAL                        :: Bool
         848             : !
         849             : ! !REVISION HISTORY:
         850             : !  24 Jul 2014 - C. Keller - Initial version
         851             : !  See https://github.com/geoschem/hemco for complete history
         852             : !EOP
         853             : !------------------------------------------------------------------------------
         854             : !BOC
         855             :
         856           0 :     Bool = ( TRIM(Unt) == TRIM(UL(1)) )
         857             :
         858           0 :   END FUNCTION HCO_IsUnitless
         859             : !EOC
         860             : !------------------------------------------------------------------------------
         861             : !                   Harmonized Emissions Component (HEMCO)                    !
         862             : !------------------------------------------------------------------------------
         863             : !BOP
         864             : !
         865             : ! !IROUTINE: HCO_IsIndexData
         866             : !
         867             : ! !DESCRIPTION: Returns TRUE if the passed string corresponds to the HEMCO
         868             : ! index data unit string.
         869             : !\\
         870             : !\\
         871             : ! !INTERFACE:
         872             : !
         873           0 :   FUNCTION HCO_IsIndexData( Unt ) Result ( Bool )
         874             : !
         875             : ! !INPUT PARAMETERS:
         876             : !
         877             :     CHARACTER(LEN=*), INTENT(IN)   :: Unt
         878             : !
         879             : ! !OUTPUT PARAMETERS:
         880             : !
         881             :     LOGICAL                        :: Bool
         882             : !
         883             : ! !REVISION HISTORY:
         884             : !  24 Jul 2014 - C. Keller - Initial version
         885             : !  See https://github.com/geoschem/hemco for complete history
         886             : !EOP
         887             : !------------------------------------------------------------------------------
         888             : !BOC
         889             :
         890           0 :     Bool = ( TRIM(Unt) == TRIM(UL(2)) )
         891             :
         892           0 :   END FUNCTION HCO_IsIndexData
         893             : !EOC
         894             : !------------------------------------------------------------------------------
         895             : !                   Harmonized Emissions Component (HEMCO)                    !
         896             : !------------------------------------------------------------------------------
         897             : !BOP
         898             : !
         899             : ! !IROUTINE: HCO_UnitTolerance
         900             : !
         901             : ! !DESCRIPTION: Returns the HEMCO unit tolerance as defined in the HEMCO
         902             : ! configuration file (under settings). Returns a default value of 0 (no
         903             : ! tolerance) if no value is set in the configuration file.
         904             : !\\
         905             : !\\
         906             : ! !INTERFACE:
         907             : !
         908           0 :   FUNCTION HCO_UnitTolerance( HcoConfig ) Result ( UnitTolerance )
         909             : !
         910             : ! !USES:
         911             : !
         912             :     USE HCO_TYPES_MOD,    ONLY : ConfigObj
         913             :     USE HCO_EXTLIST_MOD,  ONLY : GetExtOpt, CoreNr
         914             : !
         915             : ! !INPUT PARAMETERS:
         916             : !
         917             :     TYPE(ConfigObj), POINTER       :: HcoConfig
         918             : !
         919             : ! !OUTPUT PARAMETERS:
         920             : !
         921             :     INTEGER                        :: UnitTolerance
         922             : !
         923             : ! !REVISION HISTORY:
         924             : !  24 Jul 2014 - C. Keller - Initial version
         925             : !  See https://github.com/geoschem/hemco for complete history
         926             : !EOP
         927             : !------------------------------------------------------------------------------
         928             : !BOC
         929             : !
         930             : ! !LOCAL VARIABLES:
         931             : !
         932             :     INTEGER, SAVE       :: Tolerance = -1
         933             :     LOGICAL             :: FOUND
         934             :     INTEGER             :: RC
         935             :     CHARACTER(LEN=255)  :: MSG
         936             :
         937             :     !=================================================================
         938             :     ! HCO_UnitTolerance begins here
         939             :     !=================================================================
         940             :
         941             :     ! On first call, try to get unit tolerance value from core settings.
         942             :     ! Use value of zero if not specified in the configuration file.
         943           0 :     IF ( Tolerance < 0 ) THEN
         944             :        CALL GetExtOpt ( HcoConfig, CoreNr, 'Unit tolerance', &
         945           0 :                         OptValInt=Tolerance, FOUND=FOUND, RC=RC )
         946           0 :        IF ( .NOT. FOUND ) Tolerance = 0
         947             :     ENDIF
         948             :
         949             :     ! Return
         950           0 :     UnitTolerance = Tolerance
         951             :
         952           0 :   END FUNCTION HCO_UnitTolerance
         953             : !EOC
         954             : END MODULE HCO_Unit_Mod

Generated by: LCOV version 1.14