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: 2025-01-13 21:54:50 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