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
|