Line data Source code
1 : !BOC
2 : #if defined ( MODEL_GCCLASSIC ) || defined( MODEL_WRF ) || defined( MODEL_CESM ) || defined( HEMCO_STANDALONE )
3 : ! The 'standard' HEMCO I/O module is used for:
4 : ! - HEMCO Standalone (HEMCO_STANDALONE)
5 : ! - GEOS-Chem 'Classic' (MODEL_GCCLASSIC)
6 : ! - WRF-GC (MODEL_WRF)
7 : ! - CESM-GC and CAM-Chem / HEMCO-CESM (MODEL_CESM)
8 : !EOC
9 : !------------------------------------------------------------------------------
10 : ! Harmonized Emissions Component (HEMCO) !
11 : !------------------------------------------------------------------------------
12 : !BOP
13 : !
14 : ! !MODULE: hcoio_read_std_mod.F90
15 : !
16 : ! !DESCRIPTION: Module HCOIO\_read\_mod controls data processing
17 : ! (file reading, unit conversion, regridding) for HEMCO in the
18 : ! 'standard' environment (i.e. non-ESMF).
19 : !
20 : ! This module implements the 'standard' environment (i.e. non-ESMF).
21 : !\\
22 : !\\
23 : ! !INTERFACE:
24 : !
25 : MODULE HCOIO_Read_Mod
26 : !
27 : ! !USES:
28 : !
29 : USE HCO_Types_Mod
30 : USE HCO_Error_Mod
31 : USE HCO_CharTools_Mod
32 : USE HCO_State_Mod, ONLY : Hco_State
33 : USE HCOIO_Util_Mod
34 :
35 : IMPLICIT NONE
36 : PRIVATE
37 : !
38 : ! !PUBLIC MEMBER FUNCTIONS:
39 : !
40 : PUBLIC :: HCOIO_Read
41 : PUBLIC :: HCOIO_CloseAll
42 : !
43 : ! !REMARKS:
44 : ! Beginning with HEMCO 3.0.0, all I/O modules use the same module names,
45 : ! and their compilation depends on pre-processor flags defined at the top
46 : ! of the file.
47 : !
48 : ! This is to streamline the implementation of one unified Data Input Layer,
49 : ! that can be switched in and out at compile time, and reduce branching of
50 : ! code paths elsewhere.
51 : !
52 : ! !REVISION HISTORY:
53 : ! 22 Aug 2013 - C. Keller - Initial version
54 : ! See https://github.com/geoschem/hemco for complete history
55 : !EOP
56 : !------------------------------------------------------------------------------
57 : !BOC
58 : !
59 : ! !DEFINED PARAMETERS
60 : !
61 : ! Parameter used for difference testing of floating points
62 : REAL(dp), PRIVATE, PARAMETER :: EPSILON = 1.0e-5_dp
63 :
64 : #if defined( MODEL_CESM ) || defined( MODEL_WRF )
65 : REAL(hp), PRIVATE :: GC_72_EDGE_SIGMA(73) = (/ &
66 : 1.000000E+00, 9.849998E-01, 9.699136E-01, 9.548285E-01, 9.397434E-01, 9.246593E-01, &
67 : 9.095741E-01, 8.944900E-01, 8.794069E-01, 8.643237E-01, 8.492406E-01, 8.341584E-01, &
68 : 8.190762E-01, 7.989697E-01, 7.738347E-01, 7.487007E-01, 7.235727E-01, 6.984446E-01, &
69 : 6.733175E-01, 6.356319E-01, 5.979571E-01, 5.602823E-01, 5.226252E-01, 4.849751E-01, &
70 : 4.473417E-01, 4.097261E-01, 3.721392E-01, 3.345719E-01, 2.851488E-01, 2.420390E-01, &
71 : 2.055208E-01, 1.746163E-01, 1.484264E-01, 1.261653E-01, 1.072420E-01, 9.115815E-02, &
72 : 7.748532E-02, 6.573205E-02, 5.565063E-02, 4.702097E-02, 3.964964E-02, 3.336788E-02, &
73 : 2.799704E-02, 2.341969E-02, 1.953319E-02, 1.624180E-02, 1.346459E-02, 1.112953E-02, &
74 : 9.171478E-03, 7.520355E-03, 6.135702E-03, 4.981002E-03, 4.023686E-03, 3.233161E-03, &
75 : 2.585739E-03, 2.057735E-03, 1.629410E-03, 1.283987E-03, 1.005675E-03, 7.846040E-04, &
76 : 6.089317E-04, 4.697755E-04, 3.602270E-04, 2.753516E-04, 2.082408E-04, 1.569208E-04, &
77 : 1.184308E-04, 8.783617E-05, 6.513694E-05, 4.737232E-05, 3.256847E-05, 1.973847E-05, &
78 : 9.869233E-06/)
79 : #endif
80 :
81 : CONTAINS
82 : !EOC
83 : !------------------------------------------------------------------------------
84 : ! Harmonized Emissions Component (HEMCO) !
85 : !------------------------------------------------------------------------------
86 : !BOP
87 : !
88 : ! !IROUTINE: HCOIO_Read
89 : !
90 : ! !DESCRIPTION: Reads a netCDF file and returns the regridded array in proper
91 : ! units. This routine uses the HEMCO generic data reading and regridding
92 : ! routines.
93 : !\\
94 : !\\
95 : ! Two different regridding algorithm are used: NCREGRID for 3D data with
96 : ! vertical regridding, and map\_a2a for all other data. map\_a2a also
97 : ! supports index-based remapping, while this feature is currently not
98 : ! possible in combination with NCREGRID.
99 : !\\
100 : !\\
101 : ! 3D data is vertically regridded onto the simulation grid on the sigma
102 : ! interface levels. In order to calculate these levels correctly, the netCDF
103 : ! vertical coordinate description must adhere to the CF - conventions. See
104 : ! routine NC\_Get\_Sigma\_Levels in Ncdf\_Mod for more details.
105 : !\\
106 : !\\
107 : ! A simpler vertical interpolation scheme is used if (a) the number of
108 : ! vertical levels of the input data corresponds to the number of levels
109 : ! on the simulation grid (direct mapping, no remapping), (b) the vertical
110 : ! level variable name (long\_name) contains the word "GEOS-Chem level". In
111 : ! the latter case, the vertical levels of the input data is interpreted as
112 : ! GEOS vertical levels and mapped onto the simulation grid using routine
113 : ! ModelLev\_Interpolate.
114 : !\\
115 : !\\
116 : ! !INTERFACE:
117 : !
118 0 : SUBROUTINE HCOIO_Read( HcoState, Lct, RC )
119 : !
120 : ! !USES:
121 : !
122 : USE HCO_Ncdf_Mod, ONLY : NC_Open
123 : USE HCO_Ncdf_Mod, ONLY : NC_Close
124 : USE HCO_Ncdf_Mod, ONLY : NC_Read_Var
125 : USE HCO_Ncdf_Mod, ONLY : NC_Read_Arr
126 : USE HCO_Ncdf_Mod, ONLY : NC_Get_Grid_Edges
127 : USE HCO_Ncdf_Mod, ONLY : NC_Get_Sigma_Levels
128 : USE HCO_Ncdf_Mod, ONLY : NC_IsModelLevel
129 : USE HCO_Ncdf_Mod, ONLY : NC_IsSigmaLevel
130 : USE HCO_CHARPAK_MOD, ONLY : TRANLC
131 : USE HCO_Unit_Mod, ONLY : HCO_Unit_Change
132 : USE HCO_Unit_Mod, ONLY : HCO_Unit_ScalCheck
133 : USE HCO_Unit_Mod, ONLY : HCO_IsUnitless
134 : USE HCO_Unit_Mod, ONLY : HCO_IsIndexData
135 : USE HCO_Unit_Mod, ONLY : HCO_UnitTolerance
136 : USE HCO_GeoTools_Mod, ONLY : HCO_ValidateLon
137 : USE HCO_FileData_Mod, ONLY : FileData_ArrCheck
138 : USE HCO_FileData_Mod, ONLY : FileData_ArrInit
139 : USE HCO_FileData_Mod, ONLY : FileData_Cleanup
140 : USE HCOIO_MESSY_MOD, ONLY : HCO_MESSY_REGRID
141 : USE HCO_INTERP_MOD, ONLY : REGRID_MAPA2A
142 : USE HCO_INTERP_MOD, ONLY : ModelLev_Check
143 : USE HCO_CLOCK_MOD, ONLY : HcoClock_Get
144 : USE HCO_DIAGN_MOD, ONLY : Diagn_Update
145 : USE HCO_EXTLIST_MOD, ONLY : HCO_GetOpt
146 : USE HCO_TIDX_MOD, ONLY : tIDx_IsInRange
147 :
148 : include "netcdf.inc"
149 : !
150 : ! !INPUT PARAMETERS:
151 : !
152 : TYPE(HCO_State), POINTER :: HcoState ! HEMCO state object
153 : TYPE(ListCont), POINTER :: Lct ! HEMCO list container
154 : !
155 : ! !INPUT/OUTPUT PARAMETERS:
156 : !
157 : INTEGER, INTENT(INOUT) :: RC ! Success or failure?
158 : !
159 : ! !REVISION HISTORY:
160 : ! 13 Mar 2013 - C. Keller - Initial version
161 : ! See https://github.com/geoschem/hemco for complete history
162 : !EOP
163 : !------------------------------------------------------------------------------
164 : !BOC
165 : !
166 : ! !LOCAL VARIABLES:
167 : !
168 : CHARACTER(LEN=255) :: thisUnit, LevUnit, LevName
169 : CHARACTER(LEN=1023) :: MSG, LOC
170 : CHARACTER(LEN=1023) :: srcFile, srcFile2
171 : INTEGER :: NX, NY
172 : INTEGER :: NCRC, Flag, AS
173 : INTEGER :: ncLun, ncLun2
174 : INTEGER :: ierr, v_id
175 : INTEGER :: nlon, nlat, nlev, nTime
176 : INTEGER :: lev1, lev2, dir
177 : INTEGER :: tidx1, tidx2, ncYr, ncMt
178 : INTEGER :: tidx1b, tidx2b, ncYr2, ncMt2
179 : INTEGER :: HcoID
180 : INTEGER :: ArbIdx
181 : INTEGER :: nlatEdge, nlonEdge
182 : INTEGER :: Direction
183 : REAL(hp) :: MW_g
184 : REAL(sp) :: wgt1, wgt2
185 0 : REAL(sp), POINTER :: ncArr(:,:,:,:)
186 0 : REAL(sp), POINTER :: ncArr2(:,:,:,:)
187 0 : REAL(hp), POINTER :: SigEdge(:,:,:)
188 0 : REAL(hp), POINTER :: SigLev (:,:,:)
189 0 : REAL(hp), POINTER :: LonMid (:)
190 0 : REAL(hp), POINTER :: LatMid (:)
191 0 : REAL(hp), POINTER :: LevMid (:)
192 0 : REAL(hp), POINTER :: LonEdge (:)
193 0 : REAL(hp), POINTER :: LatEdge (:)
194 : REAL(hp) :: UnitFactor
195 : LOGICAL :: KeepSpec
196 : LOGICAL :: FOUND
197 : LOGICAL :: IsModelLevel
198 : LOGICAL :: DoReturn
199 : INTEGER :: UnitTolerance
200 : INTEGER :: AreaFlag, TimeFlag
201 : REAL(dp) :: YMDhma, YMDhmb, YMDhm1
202 : REAL(dp) :: oYMDhm1, oYMDhm2
203 : INTEGER :: cYr, cMt, cDy, cHr, Yr1, Yr2
204 : INTEGER :: nYears, iYear
205 : INTEGER :: I, J
206 :
207 : ! Use MESSy regridding routines?
208 : LOGICAL :: UseMESSy
209 :
210 : ! SAVEd scalars
211 : LOGICAL, SAVE :: doPrintWarning = .TRUE.
212 :
213 : !=================================================================
214 : ! HCOIO_READ begins here
215 : !=================================================================
216 0 : LOC = 'HCOIO_READ (HCOIO_READ_STD_MOD.F90)'
217 :
218 : ! Enter
219 0 : CALL HCO_ENTER( HcoState%Config%Err, LOC, RC )
220 0 : IF ( RC /= HCO_SUCCESS ) THEN
221 0 : CALL HCO_ERROR( 'ERROR 0', RC, THISLOC=LOC )
222 0 : RETURN
223 : ENDIF
224 :
225 : ! Initialize pointers
226 0 : ncArr => NULL()
227 0 : ncArr2 => NULL()
228 0 : SigEdge => NULL()
229 0 : SigLev => NULL()
230 0 : LonMid => NULL()
231 0 : LatMid => NULL()
232 0 : LevMid => NULL()
233 0 : LonEdge => NULL()
234 0 : LatEdge => NULL()
235 :
236 : ! Zero local variables for safety's sake
237 0 : dir = 0
238 0 : lev1 = 0
239 0 : lev2 = 0
240 0 : ncYr = 0
241 0 : ncMt = 0
242 0 : ncYr2 = 0
243 0 : ncMt2 = 0
244 0 : nLon = 0
245 0 : nLat = 0
246 0 : nLev = 0
247 0 : nTime = 0
248 0 : tIdx1 = 0
249 0 : tIdx2 = 0
250 0 : tidx1b = 0
251 0 : tidx2b = 0
252 0 : wgt1 = 0.0_sp
253 0 : wgt2 = 0.0_sp
254 :
255 : ! Get unit tolerance set in configuration file
256 0 : UnitTolerance = HCO_UnitTolerance( HcoState%Config )
257 :
258 : ! For convenience, copy horizontal grid dimensions from HEMCO
259 : ! state object
260 0 : NX = HcoState%NX
261 0 : NY = HcoState%NY
262 :
263 : ! Verbose
264 0 : IF ( HCO_IsVerb(HcoState%Config%Err,2) ) THEN
265 0 : WRITE(MSG,*) 'Processing container: ', TRIM(Lct%Dct%cName)
266 0 : CALL HCO_MSG( HcoState%Config%Err, MSG, SEP1='-' )
267 : ENDIF
268 :
269 : ! If the file has cycle flag "E" (e.g. it's a restart file), then we will
270 : ! read it only once and then never again. If the file has already been
271 : ! read on a previous call, then don't call HCOIO_READ. (bmy, 10/4/18)
272 : !
273 : ! Moved this handling from hcoio_dataread_mod, as it is non-MAPL specific
274 : ! (hplin, 4/5/21)
275 : IF ( Lct%Dct%Dta%CycleFlag == HCO_CFLAG_EXACT .and. &
276 0 : Lct%Dct%Dta%UpdtFlag == HCO_UFLAG_ONCE .and. &
277 : Lct%Dct%Dta%isTouched ) THEN
278 :
279 : ! Print a warning message only once
280 0 : IF ( doPrintWarning ) THEN
281 0 : doPrintWarning = .FALSE.
282 : MSG = 'No further attempts will be made to read file: ' // &
283 0 : TRIM( Lct%Dct%Dta%NcFile )
284 0 : CALL HCO_WARNING ( HcoState%Config%Err, MSG, RC, WARNLEV=1 )
285 : ENDIF
286 :
287 : ! Return without reading
288 0 : CALL HCO_LEAVE( HcoState%Config%Err, RC )
289 0 : RETURN
290 : ENDIF
291 :
292 : ! ----------------------------------------------------------------
293 : ! Parse source file name. This will replace all tokens ($ROOT,
294 : ! ($YYYY), etc., with valid values.
295 : ! ----------------------------------------------------------------
296 0 : CALL SrcFile_Parse( HcoState, Lct, srcFile, FOUND, RC )
297 0 : IF ( RC /= HCO_SUCCESS ) THEN
298 : MSG = 'Error encountered in routine "SrcFile_Parse", located ' // &
299 0 : 'module src/Core/hcoio_read_std_mod.F90!'
300 0 : CALL HCO_ERROR( MSG, RC )
301 0 : RETURN
302 : ENDIF
303 :
304 : ! Handle found or not in the standard way if HEMCO is in regular run mode.
305 0 : IF ( .NOT. HcoState%Options%isDryRun ) THEN
306 :
307 : !====================================================================
308 : ! HEMCO is in regular simulation mode (not dry-run)!
309 : !====================================================================
310 :
311 : ! If file not found, return w/ error. No error if cycling attribute is
312 : ! select to range. In that case, just make sure that array is empty.
313 0 : IF ( .NOT. FOUND ) THEN
314 0 : IF ( ( Lct%Dct%Dta%CycleFlag == HCO_CFLAG_RANGE ) .OR. &
315 : ( Lct%Dct%Dta%CycleFlag == HCO_CFLAG_EXACT ) ) THEN
316 :
317 : ! If MustFind flag is enabled, return with error if field is not
318 : ! found
319 0 : IF ( Lct%Dct%Dta%MustFind ) THEN
320 : MSG = 'Cannot find file for current simulation time: ' // &
321 : TRIM(srcFile) // ' - Cannot get field ' // &
322 : TRIM(Lct%Dct%cName) // '. Please check file name ' // &
323 0 : 'and time (incl. time range flag) in the config. file'
324 0 : CALL HCO_ERROR( MSG, RC )
325 0 : RETURN
326 :
327 : ! If MustFind flag is not enabled, ignore this field and return
328 : ! with a warning.
329 : ELSE
330 0 : CALL FileData_Cleanup( Lct%Dct%Dta, DeepClean=.FALSE. )
331 : MSG = 'No valid file found for current simulation time - data '// &
332 0 : 'will be ignored for time being - ' // TRIM(Lct%Dct%cName)
333 0 : CALL HCO_WARNING ( HcoState%Config%Err, MSG, RC, WARNLEV=3 )
334 0 : CALL HCO_LEAVE ( HcoState%Config%Err, RC )
335 0 : RETURN
336 : ENDIF
337 :
338 : ELSE
339 : MSG = 'Cannot find file for current simulation time: ' // &
340 : TRIM(srcFile) // ' - Cannot get field ' // &
341 : TRIM(Lct%Dct%cName) // '. Please check file name ' // &
342 0 : 'and time (incl. time range flag) in the config. file'
343 0 : CALL HCO_ERROR( MSG, RC )
344 0 : RETURN
345 : ENDIF
346 : ENDIF
347 :
348 : ELSE
349 :
350 : !====================================================================
351 : ! HEMCO is in a "dry-run" mode!
352 : !====================================================================
353 :
354 : ! Simulate file read buffer
355 0 : IF ( TRIM(HcoState%ReadLists%FileInArchive) == TRIM(srcFile) ) THEN
356 0 : CALL HCO_LEAVE ( HcoState%Config%Err, RC )
357 0 : RETURN
358 : ENDIF
359 :
360 : ! If file exists, print the result. If NOT, then handle accordingly
361 : ! But NEVER error out (HCO_ERROR), as we want to get a list of all
362 : ! files. (hplin, 11/2/19)
363 0 : IF ( .NOT. FOUND ) THEN
364 0 : IF ( ( Lct%Dct%Dta%CycleFlag == HCO_CFLAG_RANGE ) .OR. &
365 : ( Lct%Dct%Dta%CycleFlag == HCO_CFLAG_EXACT ) ) THEN
366 :
367 : ! If MustFind flag is enabled, return with error if field is not
368 : ! found
369 0 : IF ( Lct%Dct%Dta%MustFind ) THEN
370 : MSG = 'Cannot find file for current simulation time: ' // &
371 : TRIM(srcFile) // ' - Cannot get field ' // &
372 : TRIM(Lct%Dct%cName) // '. Please check file name ' // &
373 0 : 'and time (incl. time range flag) in the config. file'
374 0 : CALL HCO_Warning( HcoState%Config%Err, MSG, RC, WARNLEV=3 )
375 :
376 : ! Write a msg to stdout (NOT FOUND)
377 0 : WRITE( 6, 300 ) TRIM( srcFile )
378 : 300 FORMAT( 'HEMCO: REQUIRED FILE NOT FOUND ', a )
379 :
380 : ! If MustFind flag is not enabled, ignore this field and return
381 : ! with a warning.
382 : ELSE
383 0 : CALL FileData_Cleanup( Lct%Dct%Dta, DeepClean=.FALSE. )
384 : MSG = 'No valid file found for current simulation time - '// &
385 : 'data will be ignored for time being - ' // &
386 0 : TRIM(Lct%Dct%cName)
387 0 : CALL HCO_WARNING ( HcoState%Config%Err, MSG, RC, WARNLEV=3 )
388 :
389 : ! Write a msg to stdout (OPTIONAL)
390 0 : WRITE( 6, 310 ) TRIM( srcFile )
391 : 310 FORMAT( 'HEMCO: OPTIONAL FILE NOT FOUND ', a )
392 :
393 : ENDIF
394 :
395 : ! Not range or exact
396 : ELSE
397 : MSG = 'Cannot find file for current simulation time: ' // &
398 : TRIM(srcFile) // ' - Cannot get field ' // &
399 : TRIM(Lct%Dct%cName) // '. Please check file name ' // &
400 0 : 'and time (incl. time range flag) in the config. file'
401 0 : CALL HCO_WARNING ( HcoState%Config%Err, MSG, RC, WARNLEV=3 )
402 :
403 : ! Write a msg to stdout (NOT FOUND)
404 0 : WRITE( 6, 300 ) TRIM(srcFile)
405 :
406 : ENDIF
407 : ELSE
408 :
409 : ! Write a mesage to stdout (HEMCO: Opening...)
410 0 : WRITE( 6, 100 ) TRIM( srcFile )
411 :
412 : ENDIF
413 :
414 : ! It is safe to leave now, we do not need to handle opening the file.
415 : ! This may be changed in the future if the "dry-run" mode requires
416 : ! a check of the file contents... this may be beyond the scope for now.
417 :
418 : ! Simulate the "reading" in netCDF to prevent duplicate entries
419 : ! in the log
420 0 : HcoState%ReadLists%FileInArchive = TRIM(srcFile)
421 :
422 : ! Skip further processing
423 0 : CALL HCO_LEAVE ( HcoState%Config%Err, RC )
424 0 : RETURN
425 : ENDIF ! End of dry-run mode else clause
426 :
427 : ! ----------------------------------------------------------------
428 : ! Open netCDF
429 : ! ----------------------------------------------------------------
430 :
431 : ! Check if file is already in buffer. In that case use existing
432 : ! open stream. Otherwise open new file. At any given time there
433 : ! can only be one file in buffer.
434 0 : ncLun = -1
435 0 : IF ( HcoState%ReadLists%FileLun > 0 ) THEN
436 0 : IF ( TRIM(HcoState%ReadLists%FileInArchive) == TRIM(srcFile) ) THEN
437 0 : ncLun = HcoState%ReadLists%FileLun
438 : ELSE
439 0 : CALL NC_CLOSE ( HcoState%ReadLists%FileLun )
440 0 : HcoState%ReadLists%FileLun = -1
441 : ENDIF
442 : ENDIF
443 :
444 : ! To read from existing stream:
445 0 : IF ( ncLun > 0 ) THEN
446 :
447 : ! Verbose mode
448 0 : IF ( HCO_IsVerb(HcoState%Config%Err,2) ) THEN
449 0 : WRITE(MSG,*) 'Reading from existing stream: ', TRIM(srcFile)
450 0 : CALL HCO_MSG( HcoState%Config%Err, MSG )
451 : ENDIF
452 :
453 : ! To open a new file:
454 : ELSE
455 0 : CALL NC_OPEN ( TRIM(srcFile), ncLun )
456 :
457 : ! Verbose mode
458 0 : IF ( HCO_IsVerb(HcoState%Config%Err,1) ) THEN
459 0 : WRITE(MSG,*) 'Opening file: ', TRIM(srcFile)
460 0 : CALL HCO_MSG( HcoState%Config%Err, MSG )
461 : ENDIF
462 :
463 : ! Also write to standard output
464 0 : WRITE( 6, 100 ) TRIM( srcFile )
465 : 100 FORMAT( 'HEMCO: Opening ', a )
466 :
467 : ! This is now the file in archive
468 0 : HcoState%ReadLists%FileInArchive = TRIM(srcFile)
469 0 : HcoState%ReadLists%FileLun = ncLun
470 : ENDIF
471 :
472 : ! ----------------------------------------------------------------
473 : ! Extract time slice information
474 : ! This determines the lower and upper time slice index (tidx1
475 : ! and tidx2) to be read based upon the time slice information
476 : ! extracted from the file and the time stamp settings set in the
477 : ! HEMCO configuration file. Multiple time slices are only selected
478 : ! for weekdaily data or for 'autodetected' hourly data (using the
479 : ! wildcard character in the configuration file time attribute) or
480 : ! if data shall be interpolated between two (consecutive) time
481 : ! slices. The weights to be assigned to those two time slices is
482 : ! also calculated in GET_TIMEIDX and returned as variables wgt1
483 : ! and wgt2, respectively.
484 : ! ----------------------------------------------------------------
485 : CALL GET_TIMEIDX ( HcoState, Lct, &
486 : ncLun, tidx1, tidx2, &
487 : wgt1, wgt2, oYMDhm1, &
488 0 : YMDhma, YMDhm1, RC )
489 0 : IF ( RC /= HCO_SUCCESS ) THEN
490 0 : CALL HCO_ERROR( 'ERROR 1', RC, THISLOC=LOC )
491 0 : RETURN
492 : ENDIF
493 :
494 : !-----------------------------------------------------------------
495 : ! Check for negative tidx1. tidx1 can still be negative if:
496 : ! (a) CycleFlag is set to range and the current simulation
497 : ! time is outside of the data time range. In this case, we
498 : ! prompt a warning and make sure that there is no data
499 : ! associated with this FileData container.
500 : ! (b) CycleFlag is set to exact and none of the data time
501 : ! stamps matches the current simulation time exactly. Return
502 : ! with error!
503 : !-----------------------------------------------------------------
504 0 : IF ( tidx1 < 0 ) THEN
505 0 : DoReturn = .FALSE.
506 0 : IF ( Lct%Dct%Dta%CycleFlag == HCO_CFLAG_CYCLE ) THEN
507 0 : MSG = 'Invalid time index in ' // TRIM(srcFile)
508 0 : CALL HCO_ERROR( MSG, RC )
509 : DoReturn = .TRUE.
510 0 : ELSEIF ( ( Lct%Dct%Dta%CycleFlag == HCO_CFLAG_RANGE ) .OR. &
511 : ( Lct%Dct%Dta%CycleFlag == HCO_CFLAG_EXACT ) ) THEN
512 0 : IF ( Lct%Dct%Dta%MustFind ) THEN
513 : MSG = 'Cannot find field with valid time stamp in ' // &
514 : TRIM(srcFile) // ' - Cannot get field ' // &
515 : TRIM(Lct%Dct%cName) // '. Please check file name ' // &
516 0 : 'and time (incl. time range flag) in the config. file'
517 0 : CALL HCO_ERROR( MSG, RC )
518 : DoReturn = .TRUE.
519 : ELSE
520 0 : CALL FileData_Cleanup( Lct%Dct%Dta, DeepClean=.FALSE.)
521 : MSG = 'Simulation time is outside of time range provided for '//&
522 0 : TRIM(Lct%Dct%cName) // ' - field is ignored for the time being!'
523 0 : CALL HCO_WARNING ( HcoState%Config%Err, MSG, RC, WARNLEV=3 )
524 0 : DoReturn = .TRUE.
525 0 : CALL HCO_LEAVE ( HcoState%Config%Err, RC )
526 : ENDIF
527 : ENDIF
528 :
529 : ! Eventually return here
530 : IF ( DoReturn ) THEN
531 0 : RETURN
532 : ENDIF
533 : ENDIF
534 :
535 : ! ----------------------------------------------------------------
536 : ! Check if variable is in file
537 : ! ----------------------------------------------------------------
538 0 : ierr = Nf_Inq_Varid( ncLun, Lct%Dct%Dta%ncPara, v_id )
539 0 : IF ( ierr /= NF_NOERR ) THEN
540 :
541 : ! If MustFind flag is enabled, return with error if field is not
542 : ! found
543 0 : IF ( Lct%Dct%Dta%MustFind ) THEN
544 : MSG = 'Cannot find field ' // TRIM(Lct%Dct%cName) // &
545 0 : '. Please check variable name in the config. file'
546 0 : CALL HCO_ERROR( MSG, RC )
547 0 : RETURN
548 :
549 : ! If MustFind flag is not enabled, ignore this field and return
550 : ! with a warning.
551 : ELSE
552 0 : CALL FileData_Cleanup( Lct%Dct%Dta, DeepClean=.FALSE. )
553 : MSG = 'Cannot find field ' // TRIM(Lct%Dct%cName) // &
554 0 : '. Will be ignored for time being.'
555 0 : CALL HCO_WARNING ( HcoState%Config%Err, MSG, RC, WARNLEV=3 )
556 0 : CALL HCO_LEAVE ( HcoState%Config%Err, RC )
557 0 : RETURN
558 : ENDIF
559 : ENDIF
560 :
561 : ! ----------------------------------------------------------------
562 : ! Read grid
563 : ! ----------------------------------------------------------------
564 :
565 : ! Extract longitude midpoints
566 0 : CALL NC_READ_VAR ( ncLun, 'lon', nlon, thisUnit, LonMid, NCRC )
567 0 : IF ( NCRC /= 0 ) THEN
568 0 : CALL HCO_ERROR( 'NC_READ_VAR: lon', RC )
569 0 : RETURN
570 : ENDIF
571 :
572 0 : IF ( nlon == 0 ) THEN
573 0 : CALL NC_READ_VAR ( ncLun, 'longitude', nlon, thisUnit, LonMid, NCRC )
574 : ENDIF
575 0 : IF ( NCRC /= 0 ) THEN
576 0 : CALL HCO_ERROR( 'NC_READ_VAR: longitude', RC )
577 0 : RETURN
578 : ENDIF
579 :
580 0 : IF ( nlon == 0 ) THEN
581 0 : CALL NC_READ_VAR ( ncLun, 'Longitude', nlon, thisUnit, LonMid, NCRC )
582 : ENDIF
583 0 : IF ( NCRC /= 0 ) THEN
584 0 : CALL HCO_ERROR( 'NC_READ_LON: Longitude', RC )
585 0 : RETURN
586 : ENDIF
587 :
588 0 : IF ( nlon == 0 ) THEN
589 : MSG = 'Cannot find longitude variable in ' // TRIM(srcFile) // &
590 0 : ' - Must be one of `lon`, `longitude`, `Longitude`'
591 0 : CALL HCO_ERROR( MSG, RC )
592 0 : RETURN
593 : ENDIF
594 :
595 : ! Unit must be degrees_east
596 0 : CALL TRANLC( thisUnit)
597 0 : IF ( INDEX( thisUnit, 'degrees_east' ) == 0 ) THEN
598 : MSG = 'illegal longitude unit in ' // TRIM(srcFile) // &
599 0 : ' - Must be `degrees_east`.'
600 0 : CALL HCO_ERROR( MSG, RC )
601 0 : RETURN
602 : ENDIF
603 :
604 : ! Make sure longitude is steadily increasing.
605 0 : CALL HCO_ValidateLon( HcoState, nlon, LonMid, RC )
606 0 : IF ( RC /= HCO_SUCCESS ) THEN
607 0 : CALL HCO_ERROR( 'ERROR 2', RC, THISLOC=LOC )
608 0 : RETURN
609 : ENDIF
610 :
611 : ! Extract latitude midpoints
612 0 : CALL NC_READ_VAR ( ncLun, 'lat', nlat, thisUnit, LatMid, NCRC )
613 0 : IF ( NCRC /= 0 ) THEN
614 0 : CALL HCO_ERROR( 'NC_READ_LON: lat', RC )
615 0 : RETURN
616 : ENDIF
617 :
618 0 : IF ( nlat == 0 ) THEN
619 0 : CALL NC_READ_VAR ( ncLun, 'latitude', nlat, thisUnit, LatMid, NCRC )
620 : ENDIF
621 0 : IF ( NCRC /= 0 ) THEN
622 0 : CALL HCO_ERROR( 'NC_READ_LON: latitude', RC )
623 0 : RETURN
624 : ENDIF
625 :
626 0 : IF ( nlat == 0 ) THEN
627 0 : CALL NC_READ_VAR ( ncLun, 'Latitude', nlat, thisUnit, LatMid, NCRC )
628 : ENDIF
629 0 : IF ( NCRC /= 0 ) THEN
630 0 : CALL HCO_ERROR( 'NC_READ_LON: Latitude', RC )
631 0 : RETURN
632 : ENDIF
633 :
634 0 : IF ( nlat == 0 ) THEN
635 : MSG = 'Cannot find latitude variable in ' // TRIM(srcFile) // &
636 0 : ' - Must be one of `lat`, `latitude`, `Latitude`'
637 0 : CALL HCO_ERROR( MSG, RC )
638 0 : RETURN
639 : ENDIF
640 :
641 : ! Unit must be degrees_north
642 0 : CALL TRANLC( thisUnit)
643 0 : IF ( INDEX( thisUnit, 'degrees_north' ) == 0 ) THEN
644 : MSG = 'illegal latitude unit in ' // TRIM(srcFile) // &
645 0 : ' - Must be `degrees_north`.'
646 0 : CALL HCO_ERROR( MSG, RC )
647 0 : RETURN
648 : ENDIF
649 :
650 : ! Get level index if we are dealing with 3D data
651 0 : IF ( Lct%Dct%Dta%SpaceDim == 3 ) THEN
652 :
653 : ! Try to extract level midpoints
654 0 : LevName = 'lev'
655 0 : CALL NC_READ_VAR ( ncLun, LevName, nlev, LevUnit, LevMid, NCRC )
656 0 : IF ( NCRC /= 0 ) THEN
657 0 : CALL HCO_ERROR( 'NC_READ_VAR: lev', RC )
658 0 : RETURN
659 : ENDIF
660 0 : IF ( nlev == 0 ) THEN
661 0 : LevName = 'height'
662 0 : CALL NC_READ_VAR ( ncLun, LevName, nlev, LevUnit, LevMid, NCRC )
663 0 : IF ( NCRC /= 0 ) THEN
664 0 : CALL HCO_ERROR( 'NC_READ_VAR: height', RC )
665 0 : RETURN
666 : ENDIF
667 : ENDIF
668 0 : IF ( nlev == 0 ) THEN
669 0 : LevName = 'level'
670 0 : CALL NC_READ_VAR ( ncLun, LevName, nlev, LevUnit, LevMid, NCRC )
671 0 : IF ( NCRC /= 0 ) THEN
672 0 : CALL HCO_ERROR( 'NC_READ_VAR: level', RC )
673 0 : RETURN
674 : ENDIF
675 : ENDIF
676 :
677 : ! Error check
678 0 : IF ( nlev == 0 ) THEN
679 : MSG = 'Cannot find vertical coordinate variable in ' // &
680 0 : TRIM(SrcFile) // ' - Must be one of `lev`, `level`, `height`.'
681 0 : CALL HCO_ERROR( MSG, RC )
682 0 : RETURN
683 : ENDIF
684 :
685 : ! Are these model levels? This will only return true if the long
686 : ! name of the level variable contains "GEOS-Chem level".
687 : ! For now, we assume levels are already on model levels if the
688 : ! number of levels to be read is explicitly set in the configuration
689 : ! file (ckeller, 5/20/15).
690 0 : IF ( Lct%Dct%Dta%Levels == 0 ) THEN
691 :
692 : ! Check if vertical coordinate is GEOS-Chem levels
693 0 : IsModelLevel = NC_IsModelLevel( ncLun, LevName )
694 :
695 : ! Further check if the given number of vertical levels should be
696 : ! treated as model levels. This is the case if e.g. the nuber of
697 : ! levels found on the file exactly matches the number of vertical
698 : ! levels of the grid. Some of these assumptions are rather arbitrary.
699 : ! IsModelLev will stay True if is was set so in NC_ISMODELLEVEL
700 : ! above. (ckeller, 9/29/15)
701 0 : CALL ModelLev_Check( HcoState, nlev, IsModelLevel, RC )
702 0 : IF ( RC /= HCO_SUCCESS ) THEN
703 0 : CALL HCO_ERROR( 'ERROR 3', RC, THISLOC=LOC )
704 0 : RETURN
705 : ENDIF
706 :
707 : ! Override IsModelLevel if the long_name contains
708 : ! "atmospheric_hybrid_sigma_pressure_coordinate"
709 0 : IsModelLevel = ( .not. NC_IsSigmaLevel( ncLun, LevName ) )
710 :
711 : ! Set level indeces to be read
712 0 : lev1 = 1
713 0 : lev2 = nlev
714 :
715 : ! If levels are explicitly given:
716 : ELSE
717 :
718 : ! If long_name is "atmospheric_hybrid_sigma_pressure_coordinate",
719 : ! then treat it as sigma levels; otherwise assume model levels.
720 0 : IsModelLevel = ( .not. NC_IsSigmaLevel( ncLun, LevName ) )
721 :
722 : ! Number of levels to be read must be smaller or equal to total
723 : ! number of available levels
724 0 : IF ( ABS(Lct%Dct%Dta%Levels) > nlev ) THEN
725 0 : WRITE(MSG,*) Lct%Dct%Dta%Levels, ' levels requested but file ', &
726 0 : 'has only ', nlev, ' levels: ', TRIM(Lct%Dct%cName)
727 0 : CALL HCO_ERROR( MSG, RC )
728 0 : RETURN
729 : ENDIF
730 :
731 : ! Set levels to be read
732 0 : IF ( Lct%Dct%Dta%Levels > 0 ) THEN
733 0 : lev1 = 1
734 0 : lev2 = Lct%Dct%Dta%Levels
735 :
736 : ! Reverse axis!
737 : ELSE
738 0 : lev1 = nlev
739 0 : lev2 = nlev + Lct%Dct%Dta%Levels + 1
740 : ENDIF
741 :
742 : ENDIF
743 :
744 : ! Verbose
745 0 : IF ( HCO_IsVerb(HcoState%Config%Err,2) ) THEN
746 0 : WRITE(MSG,*) 'Will read vertical levels ', lev1, ' to ', lev2
747 0 : CALL HCO_MSG(HcoState%Config%Err,MSG)
748 : ENDIF
749 :
750 : ! For 2D data, set lev1 and lev2 to zero. This will ignore
751 : ! the level dimension in the netCDF reading call that follows.
752 : ELSE
753 0 : nlev = 0
754 0 : lev1 = 0
755 0 : lev2 = 0
756 0 : IsModelLevel = .FALSE.
757 : ENDIF
758 :
759 : ! ----------------------------------------------------------------
760 : ! Check for arbitrary additional dimension. Will return -1 if not
761 : ! set.
762 : ! ----------------------------------------------------------------
763 0 : CALL GetArbDimIndex( HcoState, ncLun, Lct, ArbIdx, RC )
764 0 : IF ( RC /= HCO_SUCCESS ) THEN
765 0 : CALL HCO_ERROR( 'ERROR 4', RC, THISLOC=LOC )
766 0 : RETURN
767 : ENDIF
768 :
769 : ! ----------------------------------------------------------------
770 : ! Read data
771 : ! ----------------------------------------------------------------
772 :
773 : ! Verbose mode
774 0 : IF ( HCO_IsVerb(HcoState%Config%Err,2) ) THEN
775 0 : WRITE(MSG,*) 'Reading variable ', TRIM(Lct%Dct%Dta%ncPara)
776 0 : CALL HCO_MSG(HcoState%Config%Err,MSG)
777 : ENDIF
778 :
779 : CALL NC_READ_ARR( fID = ncLun, &
780 : ncVar = Lct%Dct%Dta%ncPara, &
781 : lon1 = 1, &
782 : lon2 = nlon, &
783 : lat1 = 1, &
784 : lat2 = nlat, &
785 : lev1 = lev1, &
786 : lev2 = lev2, &
787 : time1 = tidx1, &
788 : time2 = tidx2, &
789 : ncArr = ncArr, &
790 : varUnit = thisUnit, &
791 : wgt1 = wgt1, &
792 : wgt2 = wgt2, &
793 : MissVal = HCO_MISSVAL, &
794 : ArbIdx = ArbIdx, &
795 0 : RC = NCRC )
796 :
797 0 : IF ( NCRC /= 0 ) THEN
798 0 : CALL HCO_ERROR( 'NC_READ_ARRAY', RC )
799 0 : RETURN
800 : ENDIF
801 :
802 : ! Check for missing values: set base emissions and masks to 0, and
803 : ! scale factors to 1. This will make sure that these entries will
804 : ! be ignored.
805 : !!! CALL CheckMissVal ( Lct, ncArr )
806 :
807 : !-----------------------------------------------------------------
808 : ! Eventually do interpolation between files. This is a pretty
809 : ! crude implementation for data interpolation between different
810 : ! files. It is only applied to data that is marked as interpolated
811 : ! data and if no appropriate interpolation date could be found in
812 : ! the first file. This will only be the case if the preferred date-
813 : ! time is outside the file range.
814 : !-----------------------------------------------------------------
815 0 : IF ( Lct%Dct%Dta%CycleFlag == HCO_CFLAG_INTER .AND. wgt1 < 0.0_sp ) THEN
816 :
817 : ! No need to read another file if the previous file had exactly the
818 : ! time stamp we were looking for.
819 0 : IF ( oYMDhm1 == YMDhma ) THEN
820 0 : FOUND = .FALSE.
821 : ELSE
822 : ! Check if there exists another file for a future/previous date
823 : ! oYMDhm1 is the originally preferred date, YMDhma is the date read
824 : ! from the file. If YMDhma is in the future, we need to look for a
825 : ! file in the past. Else, need to look for a file in the future.
826 0 : IF ( oYMDhm1 < YMDhma ) THEN
827 0 : Direction = -1
828 : ELSE
829 0 : Direction = +1
830 : ENDIF
831 : CALL SrcFile_Parse ( HcoState, Lct, srcFile2, &
832 0 : FOUND, RC, Direction = Direction )
833 0 : IF ( RC /= HCO_SUCCESS ) THEN
834 0 : CALL HCO_ERROR( 'ERROR 5', RC, THISLOC=LOC )
835 0 : RETURN
836 : ENDIF
837 : ENDIF
838 :
839 : ! If found, read data. Assume that all meta-data is the same.
840 0 : IF ( FOUND ) THEN
841 :
842 : ! Open file
843 0 : CALL NC_OPEN ( TRIM(srcFile2), ncLun2 )
844 :
845 : ! Define time stamp to be read. Use this call only
846 : ! to get the datetime of the first time slice (YMDhm1).
847 : ! All other values will be ignored and reset below.
848 : CALL GET_TIMEIDX ( HcoState, Lct, &
849 : ncLun2, tidx1, tidx2, &
850 : wgt1, wgt2, oYMDhm2, &
851 0 : YMDhmb, YMDhm1, RC )
852 0 : IF ( RC /= HCO_SUCCESS ) THEN
853 0 : CALL HCO_ERROR( 'ERROR 6', RC, THISLOC=LOC )
854 0 : RETURN
855 : ENDIF
856 :
857 : ! Always read first time slice
858 0 : tidx1 = 1
859 0 : tidx2 = 1
860 0 : wgt1 = -1.0_sp
861 0 : wgt2 = -1.0_sp
862 :
863 : ! Read data and write into array ncArr2
864 : CALL NC_READ_ARR( fID = ncLun2, &
865 : ncVar = Lct%Dct%Dta%ncPara, &
866 : lon1 = 1, &
867 : lon2 = nlon, &
868 : lat1 = 1, &
869 : lat2 = nlat, &
870 : lev1 = lev1, &
871 : lev2 = lev2, &
872 : time1 = tidx1, &
873 : time2 = tidx2, &
874 : ncArr = ncArr2, &
875 : varUnit = thisUnit, &
876 : wgt1 = wgt1, &
877 : wgt2 = wgt2, &
878 : MissVal = HCO_MISSVAL, &
879 : ArbIdx = ArbIdx, &
880 0 : RC = NCRC )
881 0 : IF ( NCRC /= 0 ) THEN
882 0 : CALL HCO_ERROR( 'NC_READ_ARRAY (2)', RC )
883 0 : RETURN
884 : ENDIF
885 :
886 : ! Eventually fissing values
887 : !!! CALL CheckMissVal ( Lct, ncArr2 )
888 :
889 : ! Calculate weights to be applied to ncArr2 and ncArr1. These
890 : ! weights are calculated based on the originally preferred
891 : ! datetime oYMDh1 and the selected datetime of file 1 (YMDhma)
892 : ! and file 2 (YMDhm1)
893 : ! If date on file 1 < date on file 2:
894 0 : IF ( YMDhma < YMDhm1 ) THEN
895 0 : CALL GetWeights ( YMDhma, YMDhm1, oYMDhm1, wgt1, wgt2 )
896 : ! If date on file 1 > date on file 2:
897 0 : ELSEIF ( YMDhma > YMDhm1 ) THEN
898 0 : CALL GetWeights ( YMDhm1, YMDhma, oYMDhm1, wgt2, wgt1 )
899 : ! If both datetimes are for some reason the same (this should
900 : ! not happen!)
901 : ELSE
902 0 : wgt1 = 0.5_sp
903 0 : wgt2 = 0.5_sp
904 : ENDIF
905 :
906 : ! Apply weights
907 0 : ncArr = (wgt1 * ncArr) + (wgt2 * ncArr2)
908 :
909 : ! Verbose
910 0 : IF ( HCO_IsVerb(HcoState%Config%Err,2) ) THEN
911 0 : MSG = 'Interpolated data between two files:'
912 0 : CALL HCO_MSG(HcoState%Config%Err,MSG)
913 0 : MSG = '- File 1: ' // TRIM(srcFile)
914 0 : CALL HCO_MSG(HcoState%Config%Err,MSG)
915 0 : WRITE(MSG,*) ' Time stamp used: ', YMDhma
916 0 : CALL HCO_MSG(HcoState%Config%Err,MSG)
917 0 : WRITE(MSG,*) ' Applied weight: ', wgt1
918 0 : CALL HCO_MSG(HcoState%Config%Err,MSG)
919 0 : MSG = '- File 2: ' // TRIM(srcFile2)
920 0 : CALL HCO_MSG(HcoState%Config%Err,MSG)
921 0 : WRITE(MSG,*) ' Time stamp used: ', YMDhm1
922 0 : CALL HCO_MSG(HcoState%Config%Err,MSG)
923 0 : WRITE(MSG,*) ' Applied weight: ', wgt2
924 0 : CALL HCO_MSG(HcoState%Config%Err,MSG)
925 : ENDIF
926 :
927 : ! Cleanup
928 0 : IF ( ASSOCIATED(ncArr2) ) DEALLOCATE(ncArr2)
929 :
930 : ! Close file
931 0 : CALL NC_CLOSE ( ncLun2 )
932 : ENDIF !FOUND
933 :
934 : !-----------------------------------------------------------------
935 : ! Eventually calculate averages. Currently, averages are only
936 : ! calculated on the year dimension, e.g. over years.
937 : !-----------------------------------------------------------------
938 0 : ELSEIF ( Lct%Dct%Dta%CycleFlag == HCO_CFLAG_AVERG .OR. &
939 : Lct%Dct%Dta%CycleFlag == HCO_CFLAG_RANGEAVG ) THEN
940 :
941 : ! cYr is the current simulation year
942 : CALL HcoClock_Get( HcoState%Clock, cYYYY=cYr, cMM=cMt, cDD=cDy, &
943 0 : cH=cHr, RC=RC )
944 0 : IF ( RC /= HCO_SUCCESS ) THEN
945 0 : CALL HCO_ERROR( 'ERROR 7', RC, THISLOC=LOC )
946 0 : RETURN
947 : ENDIF
948 :
949 : ! Determine year range to be read:
950 : ! By default, we would like to average between the year range given
951 : ! in the time attribute
952 0 : Yr1 = Lct%Dct%Dta%ncYrs(1)
953 0 : Yr2 = Lct%Dct%Dta%ncYrs(2)
954 :
955 : ! If averaging shall only be performed if outside the given
956 : ! range, check if current simulation date is within the range
957 : ! provied in the configuration file. If so, set year range to
958 : ! be read to current year only.
959 0 : IF ( ( Lct%Dct%Dta%CycleFlag == HCO_CFLAG_RANGEAVG ) ) THEN
960 0 : IF ( tIDx_IsInRange(Lct,cYr,cMt,cDy,cHr) ) THEN
961 0 : Yr1 = cYr
962 0 : Yr2 = cYr
963 : ENDIF
964 : ENDIF
965 :
966 : ! Total number of years to be read
967 0 : nYears = Yr2 - Yr1 + 1
968 :
969 : ! Read and add annual data if there is more than one year to be
970 : ! used.
971 0 : IF ( nYears > 1 ) THEN
972 :
973 : ! Cleanup ncArr. This is refilled again
974 0 : ncArr = 0.0_sp
975 :
976 0 : DO iYear = Yr1, Yr2
977 :
978 : ! Get file name for this year
979 : CALL SrcFile_Parse ( HcoState, Lct, srcFile2, &
980 0 : FOUND, RC, Year=iYear )
981 0 : IF ( RC /= HCO_SUCCESS ) THEN
982 0 : CALL HCO_ERROR( 'ERROR 8', RC, THISLOC=LOC )
983 0 : RETURN
984 : ENDIF
985 :
986 : ! If found, read data. Assume that all meta-data is the same.
987 0 : IF ( .NOT. FOUND ) THEN
988 0 : WRITE(MSG,*) 'Cannot find file for year ', iYear, ' - needed ', &
989 0 : 'to perform time-averaging on file ', TRIM(Lct%Dct%Dta%ncFile)
990 0 : CALL HCO_ERROR( MSG, RC )
991 0 : RETURN
992 : ENDIF
993 :
994 : ! Open file
995 0 : CALL NC_OPEN ( TRIM(srcFile2), ncLun2 )
996 :
997 : ! Define time stamp to be read.
998 : CALL GET_TIMEIDX ( HcoState, Lct, &
999 : ncLun2, tidx1, tidx2, &
1000 : wgt1, wgt2, oYMDhm2, &
1001 : YMDhmb, YMDhm1, RC, &
1002 0 : Year=iYear )
1003 0 : IF ( RC /= HCO_SUCCESS ) THEN
1004 0 : CALL HCO_ERROR( 'ERROR 9', RC, THISLOC=LOC )
1005 0 : RETURN
1006 : ENDIF
1007 :
1008 : ! Do not perform weights
1009 0 : wgt1 = -1.0_sp
1010 0 : wgt2 = -1.0_sp
1011 :
1012 : ! Read data and write into array ncArr2
1013 : CALL NC_READ_ARR( fID = ncLun2, &
1014 : ncVar = Lct%Dct%Dta%ncPara, &
1015 : lon1 = 1, &
1016 : lon2 = nlon, &
1017 : lat1 = 1, &
1018 : lat2 = nlat, &
1019 : lev1 = lev1, &
1020 : lev2 = lev2, &
1021 : time1 = tidx1, &
1022 : time2 = tidx2, &
1023 : ncArr = ncArr2, &
1024 : varUnit = thisUnit, &
1025 : wgt1 = wgt1, &
1026 : wgt2 = wgt2, &
1027 : MissVal = HCO_MISSVAL, &
1028 : ArbIdx = ArbIdx, &
1029 0 : RC = NCRC )
1030 0 : IF ( NCRC /= 0 ) THEN
1031 0 : CALL HCO_ERROR( 'NC_READ_ARRAY (3)', RC )
1032 0 : RETURN
1033 : ENDIF
1034 :
1035 : ! Eventually fissing values
1036 : !!! CALL CheckMissVal ( Lct, ncArr2 )
1037 :
1038 : ! Add all values to ncArr
1039 0 : ncArr = ncArr + ncArr2
1040 :
1041 : ! Cleanup
1042 0 : IF ( ASSOCIATED(ncArr2) ) DEALLOCATE(ncArr2)
1043 :
1044 : ! Close file
1045 0 : CALL NC_CLOSE ( ncLun2 )
1046 :
1047 : ENDDO !iYear
1048 :
1049 : ! Now calculate average
1050 0 : ncArr = ncArr / REAL(nYears,sp)
1051 :
1052 : ! Verbose
1053 0 : IF ( HcoState%amIRoot .AND. HCO_IsVerb(HcoState%Config%Err,1) ) THEN
1054 0 : WRITE(MSG,110) TRIM(Lct%Dct%cName), Yr1, Yr2
1055 0 : CALL HCO_MSG(HcoState%Config%Err,MSG)
1056 : ENDIF
1057 : 110 FORMAT( 'Field ', a, ': Average data over years ', I4.4, ' to ', I4.4 )
1058 :
1059 : ENDIF !nYears>1
1060 : ENDIF !Averaging
1061 :
1062 : !-----------------------------------------------------------------
1063 : ! Convert to HEMCO units
1064 : ! HEMCO data are all in kg/m2/s for fluxes and kg/m3 for
1065 : ! concentrations. Unit conversion is performed based on the
1066 : ! unit on the input file and the srcUnit attribute given in the
1067 : ! configuration file. By default, HEMCO will attempt to convert
1068 : ! the units found in the input file to the standard quantities
1069 : ! for mass (kg), area (m2 or m3), and time (s). For instance,
1070 : ! g/cm2/hr will be converted to kg/m2/s. The exceptions to this
1071 : ! rule are:
1072 : ! 1. If srcUnit is set to '1', the input data are expected to
1073 : ! be unitless. If the units string on the input file is none
1074 : ! of the units recognized by HEMCO as unitless, an error is
1075 : ! returned if the unit tolerance setting is set to zero, or
1076 : ! a warning is prompted if unit tolerance is greater than zero.
1077 : ! 2. If srcUnit is set to 'count', no unit conversion is performed
1078 : ! and data will be treated as 'index' data, e.g. regridding will
1079 : ! preserve the absolute values.
1080 : !-----------------------------------------------------------------
1081 :
1082 : ! If OrigUnit is set to wildcard character: use unit from source file
1083 0 : IF ( TRIM(Lct%Dct%Dta%OrigUnit) == &
1084 : TRIM(HCO_GetOpt(HcoState%Config%ExtList,'Wildcard')) ) THEN
1085 0 : Lct%Dct%Dta%OrigUnit = TRIM(thisUnit)
1086 : ENDIF
1087 :
1088 : ! If OrigUnit is set to '1' or to 'count', perform no unit
1089 : ! conversion.
1090 0 : IF ( HCO_IsUnitLess(Lct%Dct%Dta%OrigUnit) .OR. &
1091 : HCO_IsIndexData(Lct%Dct%Dta%OrigUnit) ) THEN
1092 :
1093 : ! Check if file unit is also unitless. This will return 0 for
1094 : ! unitless, 1 for HEMCO emission unit, 2 for HEMCO conc. unit,
1095 : ! -1 otherwise.
1096 0 : Flag = HCO_UNIT_SCALCHECK( thisUnit )
1097 :
1098 : ! Return with error if: (1) thisUnit is recognized as HEMCO unit and
1099 : ! unit tolerance is set to zero; (2) thisUnit is neither unitless nor
1100 : ! a HEMCO unit and unit tolerance is set to zero or one.
1101 : ! The unit tolerance is defined in the configuration file.
1102 0 : IF ( Flag /= 0 .AND. UnitTolerance == 0 ) THEN
1103 : MSG = 'Illegal unit: ' // TRIM(thisUnit) // '. File: ' // &
1104 0 : TRIM(srcFile)
1105 0 : CALL HCO_ERROR( MSG, RC )
1106 0 : RETURN
1107 : ENDIF
1108 :
1109 : ! Prompt a warning if thisUnit is not recognized as unitless.
1110 0 : IF ( Flag /= 0 ) THEN
1111 : MSG = 'Data is treated as unitless, but file attribute suggests ' // &
1112 0 : 'it is not: ' // TRIM(thisUnit) // '. File: ' // TRIM(srcFile)
1113 0 : CALL HCO_WARNING( HcoState%Config%Err, MSG, RC, WARNLEV=1 )
1114 : ENDIF
1115 :
1116 : ! Verbose mode
1117 0 : IF ( HCO_IsVerb(HcoState%Config%Err,2) ) THEN
1118 0 : WRITE(MSG,*) 'Based on srcUnit attribute (', TRIM(Lct%Dct%Dta%OrigUnit), &
1119 0 : '), no unit conversion is performed.'
1120 0 : CALL HCO_MSG(HcoState%Config%Err,MSG)
1121 : ENDIF
1122 :
1123 : ! Convert to HEMCO units in all other cases.
1124 : ELSE
1125 :
1126 : ! For zero unit tolerance, make sure that thisUnit matches
1127 : ! with unit set in configuration file. For higher unit
1128 : ! tolerances, prompt a level 3 warning.
1129 0 : IF ( TRIM(Lct%Dct%Dta%OrigUnit) /= TRIM(thisUnit) ) THEN
1130 : MSG = 'File units do not match: ' // TRIM(thisUnit) // &
1131 : ' vs. ' // TRIM(Lct%Dct%Dta%OrigUnit) // &
1132 0 : '. File: ' // TRIM(srcFile)
1133 :
1134 0 : IF ( UnitTolerance == 0 ) THEN
1135 0 : CALL HCO_ERROR( MSG, RC )
1136 0 : RETURN
1137 : ELSE
1138 0 : CALL HCO_WARNING( HcoState%Config%Err, MSG, RC, WARNLEV=3 )
1139 : ENDIF
1140 : ENDIF
1141 :
1142 : ! Shadow species properties needed for unit conversion
1143 0 : HcoID = Lct%Dct%HcoID
1144 0 : IF ( HcoID > 0 ) THEN
1145 0 : MW_g = HcoState%Spc(HcoID)%MW_g
1146 : ELSE
1147 0 : MW_g = -999.0_hp
1148 : ENDIF
1149 :
1150 : ! Now convert to HEMCO units. This attempts to convert mass,
1151 : ! area/volume and time to HEMCO standards (kg, m2/m3, s).
1152 0 : ncYr = FLOOR( MOD( oYMDhm1, 1.0e12_dp ) / 1.0e8_dp )
1153 0 : ncMt = FLOOR( MOD( oYMDhm1, 1.0e8_dp ) / 1.0e6_dp )
1154 :
1155 0 : IF ( ncYr == 0 ) THEN
1156 0 : CALL HcoClock_Get( HcoState%Clock, cYYYY = ncYr, RC=RC )
1157 0 : IF ( RC /= HCO_SUCCESS ) THEN
1158 0 : CALL HCO_ERROR( 'ERROR 10', RC, THISLOC=LOC )
1159 0 : RETURN
1160 : ENDIF
1161 : ENDIF
1162 0 : IF ( ncMt == 0 ) THEN
1163 0 : CALL HcoClock_Get( HcoState%Clock, cMM = ncMt, RC=RC )
1164 0 : IF ( RC /= HCO_SUCCESS ) THEN
1165 0 : CALL HCO_ERROR( 'ERROR 11', RC, THISLOC=LOC )
1166 0 : RETURN
1167 : ENDIF
1168 : ENDIF
1169 :
1170 : ! Verbose mode
1171 0 : IF ( HcoState%amIRoot .and. HCO_IsVerb(HcoState%Config%Err,3) ) THEN
1172 0 : WRITE(MSG,*) 'Unit conversion settings: '
1173 0 : CALL HCO_MSG(HcoState%Config%Err,MSG)
1174 0 : WRITE(MSG,*) '- Year, month : ', ncYr, ncMt
1175 0 : CALL HCO_MSG(HcoState%Config%Err,MSG)
1176 : ENDIF
1177 :
1178 : CALL HCO_UNIT_CHANGE( &
1179 : HcoConfig = HcoState%Config, &
1180 : Array = ncArr, &
1181 : Units = thisUnit, &
1182 : MW = MW_g, &
1183 : YYYY = ncYr, &
1184 : MM = ncMt, &
1185 : AreaFlag = AreaFlag, &
1186 : TimeFlag = TimeFlag, &
1187 : FACT = UnitFactor, &
1188 0 : RC = RC )
1189 0 : IF ( RC /= HCO_SUCCESS ) THEN
1190 0 : MSG = 'Cannot convert units for ' // TRIM(Lct%Dct%cName)
1191 0 : CALL HCO_ERROR( MSG , RC )
1192 0 : RETURN
1193 : ENDIF
1194 :
1195 : ! Verbose mode
1196 0 : IF ( UnitFactor /= 1.0_hp ) THEN
1197 0 : IF ( HCO_IsVerb(HcoState%Config%Err,1) ) THEN
1198 0 : WRITE(MSG,*) 'Data was in units of ', TRIM(thisUnit), &
1199 0 : ' - converted to HEMCO units by applying ', &
1200 0 : 'scale factor ', UnitFactor
1201 0 : CALL HCO_MSG(HcoState%Config%Err,MSG)
1202 : ENDIF
1203 : ELSE
1204 0 : IF ( HCO_IsVerb(HcoState%Config%Err,2) ) THEN
1205 0 : WRITE(MSG,*) 'Data was in units of ', TRIM(thisUnit), &
1206 0 : ' - unit conversion factor is ', UnitFactor
1207 0 : CALL HCO_MSG(HcoState%Config%Err,MSG)
1208 : ENDIF
1209 : ENDIF
1210 :
1211 : ! Check for valid unit combinations, i.e. emissions must be kg/m2/s,
1212 : ! concentrations kg/m3. Eventually multiply by emission time step
1213 : ! or divide by area to obtain those values.
1214 :
1215 : ! Concentration data
1216 0 : IF ( AreaFlag == 3 .AND. TimeFlag == 0 ) THEN
1217 0 : Lct%Dct%Dta%IsConc = .TRUE.
1218 :
1219 : ! If concentration data is per second (kg/m3/s), multiply by emission
1220 : ! time step to get concentration (kg/m3).
1221 0 : ELSEIF ( AreaFlag == 3 .AND. TimeFlag == 1 ) THEN
1222 0 : Lct%Dct%Dta%IsConc = .TRUE.
1223 :
1224 0 : ncArr = ncArr * HcoState%TS_EMIS
1225 : MSG = 'Data converted from kg/m3/s to kg/m3: ' // &
1226 0 : TRIM(Lct%Dct%cName) // ': ' // TRIM(thisUnit)
1227 0 : CALL HCO_WARNING( HcoState%Config%Err, MSG, RC, WARNLEV=1 )
1228 :
1229 : ! Unitless data
1230 0 : ELSEIF ( AreaFlag == -1 .AND. TimeFlag == -1 ) THEN
1231 : ! nothing do to
1232 :
1233 : ! Emission data
1234 0 : ELSEIF ( AreaFlag == 2 .AND. TimeFlag == 1 ) THEN
1235 : ! nothing do to
1236 :
1237 : ! Emission data that is not per time (kg/m2): convert to kg/m2/s
1238 0 : ELSEIF ( AreaFlag == 2 .AND. TimeFlag == 0 ) THEN
1239 0 : ncArr = ncArr / HcoState%TS_EMIS
1240 : MSG = 'Data converted from kg/m2 to kg/m2/s: ' // &
1241 0 : TRIM(Lct%Dct%cName) // ': ' // TRIM(thisUnit)
1242 0 : CALL HCO_WARNING( HcoState%Config%Err, MSG, RC, WARNLEV=1 )
1243 :
1244 : ! Emission data that is not per area (i.e. kg/s) needs to be converted
1245 : ! to per area manually.
1246 0 : ELSEIF ( AreaFlag == 0 .AND. TimeFlag == 1 ) THEN
1247 :
1248 : ! Get lat edges: those are read from file if possible, otherwise
1249 : ! calculated from the lat midpoints.
1250 : ! ==> Sine of lat is needed. Do conversion right here.
1251 : CALL NC_GET_GRID_EDGES ( ncLun, 2, LatMid, nlat, &
1252 0 : LatEdge, nlatEdge, NCRC )
1253 0 : IF ( NCRC /= 0 ) THEN
1254 0 : MSG = 'Cannot read lat edge of ' // TRIM(srcFile)
1255 0 : CALL HCO_ERROR( MSG, RC )
1256 0 : RETURN
1257 : ENDIF
1258 :
1259 : ! Now normalize data by area calculated from lat edges.
1260 : CALL NORMALIZE_AREA( HcoState, ncArr, nlon, &
1261 0 : LatEdge, srcFile, RC )
1262 0 : IF ( RC /= HCO_SUCCESS ) THEN
1263 0 : CALL HCO_ERROR( 'ERROR 12', RC, THISLOC=LOC )
1264 0 : RETURN
1265 : ENDIF
1266 :
1267 : ! All other combinations are invalid
1268 : ELSE
1269 : MSG = 'Unit must be unitless, emission or concentration: ' // &
1270 0 : TRIM(Lct%Dct%cName) // ': ' // TRIM(thisUnit)
1271 0 : CALL HCO_ERROR( MSG, RC )
1272 0 : RETURN
1273 : ENDIF
1274 : ENDIF ! Unit conversion
1275 :
1276 : !-----------------------------------------------------------------
1277 : ! Get horizontal grid edges
1278 : !-----------------------------------------------------------------
1279 :
1280 : ! Get longitude edges and make sure they are steadily increasing.
1281 : CALL NC_GET_GRID_EDGES ( ncLun, 1, LonMid, nlon, &
1282 0 : LonEdge, nlonEdge, NCRC )
1283 0 : IF ( NCRC /= 0 ) THEN
1284 0 : MSG = 'Cannot read lon edge of ' // TRIM(srcFile)
1285 0 : CALL HCO_ERROR( MSG, RC )
1286 0 : RETURN
1287 : ENDIF
1288 0 : CALL HCO_ValidateLon( HcoState, nlonEdge, LonEdge, RC )
1289 0 : IF ( RC /= HCO_SUCCESS ) THEN
1290 0 : CALL HCO_ERROR( 'ERROR 13', RC, THISLOC=LOC )
1291 0 : RETURN
1292 : ENDIF
1293 :
1294 : ! Get latitude edges (only if they have not been read yet
1295 : ! for unit conversion)
1296 0 : IF ( .NOT. ASSOCIATED( LatEdge ) ) THEN
1297 : CALL NC_GET_GRID_EDGES ( ncLun, 2, LatMid, nlat, &
1298 0 : LatEdge, nlatEdge, NCRC )
1299 0 : IF ( NCRC /= 0 ) THEN
1300 0 : MSG = 'Cannot read lat edge of ' // TRIM(srcFile)
1301 0 : CALL HCO_ERROR( MSG, RC )
1302 0 : RETURN
1303 : ENDIF
1304 : ENDIF
1305 :
1306 : !-----------------------------------------------------------------
1307 : ! Determine regridding algorithm to be applied: use NCREGRID from
1308 : ! MESSy only if we need to regrid vertical levels. For all other
1309 : ! fields, use the much faster map_a2a.
1310 : ! Perform no vertical regridding if the vertical levels are model
1311 : ! levels. Model levels are assumed to start at the surface, i.e.
1312 : ! the first input level must correspond to the surface level. The
1313 : ! total number of vertical levels must not match the number of
1314 : ! vertical levels on the simulation grid. Data is not extrapolated
1315 : ! beyond the existing levels.
1316 : ! Vertical regridding based on NCREGRID will always map the input
1317 : ! data onto the entire simulation grid (no extrapolation beyond
1318 : ! the vertical input coordinates).
1319 : ! Index-based remapping can currently not be done with the MESSy
1320 : ! routines, i.e. it is not possible to vertically regrid index-
1321 : ! based data.
1322 : !-----------------------------------------------------------------
1323 :
1324 0 : UseMESSy = .FALSE.
1325 0 : IF ( nlev > 1 .AND. .NOT. IsModelLevel ) THEN
1326 0 : UseMESSy = .TRUE.
1327 : ENDIF
1328 :
1329 : #if defined( MODEL_CESM ) || defined( MODEL_WRF )
1330 : ! If in WRF or the CESM environment, the vertical grid is arbitrary.
1331 : ! MESSy regridding ALWAYS has to be used.
1332 0 : IF ( nlev > 1 ) THEN
1333 0 : UseMESSy = .TRUE.
1334 :
1335 0 : IF ( HCO_IsVerb(HcoState%Config%Err,2) ) THEN
1336 0 : WRITE(MSG,*) ' ==> WRF/CESM: Always forcing MESSy regridding for number of verticals', nlev, IsModelLevel
1337 0 : CALL HCO_MSG(HcoState%Config%Err,MSG)
1338 : ENDIF
1339 : ENDIF
1340 : #endif
1341 :
1342 0 : IF ( HCO_IsIndexData(Lct%Dct%Dta%OrigUnit) .AND. UseMESSy ) THEN
1343 : MSG = 'Cannot do MESSy regridding for index data: ' // &
1344 0 : TRIM(srcFile)
1345 0 : CALL HCO_ERROR( MSG, RC )
1346 0 : RETURN
1347 : ENDIF
1348 :
1349 : !-----------------------------------------------------------------
1350 : ! Use MESSy regridding
1351 : !-----------------------------------------------------------------
1352 0 : IF ( UseMESSy ) THEN
1353 0 : IF ( HCO_IsVerb(HcoState%Config%Err,2) ) THEN
1354 0 : WRITE(MSG,*) ' ==> Use MESSy regridding (NCREGRID)'
1355 0 : CALL HCO_MSG(HcoState%Config%Err,MSG)
1356 : ENDIF
1357 :
1358 : #if !defined( MODEL_CESM ) && !defined( MODEL_WRF )
1359 : ! If we do MESSy regridding, we can only do one time step
1360 : ! at a time at the moment!
1361 : IF ( tidx1 /= tidx2 ) THEN
1362 : MSG = 'Cannot do MESSy regridding for more than one time step; ' &
1363 : // TRIM(srcFile)
1364 : CALL HCO_ERROR( MSG, RC )
1365 : RETURN
1366 : ENDIF
1367 :
1368 : ! Note: This seems to be a soft restriction - removing this
1369 : ! does not conflict with MESSy regridding. Need to check (hplin, 5/30/20)
1370 : ! This has to be used for WRF-GC and HEMCO_CESM so ifdefd out
1371 : #endif
1372 :
1373 : #if defined( MODEL_WRF ) || defined( MODEL_CESM )
1374 : !--------------------------------------------------------------
1375 : ! Eventually get sigma levels
1376 : ! For files that have hardcoded GEOS-Chem "index"-based levels,
1377 : ! translate these levels back into a sigma representation
1378 : ! of the GEOS-Chem levels (sigma = p/ps on INTERFACE)
1379 : !
1380 : ! There are caveats with this. This is essentially a copy of the
1381 : ! hardcoded hPa lists from
1382 : ! http://wiki.seas.harvard.edu/geos-chem/index.php/GEOS-Chem_vertical_grids
1383 : ! hard-coded by hand, and we only assume that the data is either
1384 : ! 47-levels or 72-levels.
1385 : !
1386 : ! Parse the 72 list using regex like so: ^ ?\d{1,2} then remove the lines
1387 : ! Then you have the 73 edges.
1388 : !
1389 : ! psfc = PEDGE(0) = 1013.250 hPa
1390 : !
1391 : ! Ported from the original WRF-GC implementation (hplin, 5/27/20)
1392 : !--------------------------------------------------------------
1393 0 : IF ( nlev > 1 .AND. IsModelLevel ) THEN
1394 0 : IF ( HCO_IsVerb(HcoState%Config%Err,2) ) THEN
1395 0 : WRITE(MSG,*) ' ==> WRF/CESM: Writing in fixed sigma coordinates for GEOS-Chem levels', nlon, nlat
1396 0 : CALL HCO_MSG(HcoState%Config%Err,MSG)
1397 : ENDIF
1398 :
1399 0 : ALLOCATE(SigEdge(nlon, nlat, nlev))
1400 :
1401 0 : DO I = 1, nlon
1402 0 : DO J = 1, nlat
1403 : ! Fill with pre-defined, hard coded sigma levels computed.
1404 0 : SigEdge(I, J, :) = GC_72_EDGE_SIGMA(1:nlev)
1405 : ENDDO
1406 : ENDDO
1407 : ENDIF
1408 : #endif
1409 :
1410 : !--------------------------------------------------------------
1411 : ! Eventually get sigma levels
1412 : ! Vertical regridding is performed on sigma interface levels:
1413 : ! sigma(i,j,l) = p(i,j,l) / ps(i,j)
1414 : ! NC_Get_Sigma_Levels attempts to create the sigma levels from
1415 : ! the content of the netCDF file.
1416 : ! For now, it is assumed that all input data is on vertical
1417 : ! mid-point levels, and the interface values are calculated
1418 : ! by linear interpolation of the mid-point values in a second
1419 : ! step.
1420 : ! For model levels, the sigma levels don't need to be known
1421 : ! as vertical interpolation will be done based on subroutine
1422 : ! ModelLev_Interpolate (within HCO_MESSY_REGRID).
1423 : !--------------------------------------------------------------
1424 0 : IF ( nlev > 1 .AND. .NOT. IsModelLevel ) THEN
1425 :
1426 : ! Get sigma levels
1427 : CALL NC_Get_Sigma_Levels ( fID = ncLun, &
1428 : ncFile = srcFile, &
1429 : levName = LevName, &
1430 : lon1 = 1, &
1431 : lon2 = nlon, &
1432 : lat1 = 1, &
1433 : lat2 = nlat, &
1434 : lev1 = 1, &
1435 : lev2 = nlev, &
1436 : time = tidx1, &
1437 : SigLev = SigLev, &
1438 : Dir = dir, &
1439 0 : RC = NCRC )
1440 0 : IF ( NCRC /= 0 ) THEN
1441 0 : CALL HCO_ERROR( 'Cannot read sigma levels of '//TRIM(srcFile), RC )
1442 0 : RETURN
1443 : ENDIF
1444 :
1445 : ! Interpolate onto edges
1446 0 : CALL SigmaMidToEdges ( HcoState, SigLev, SigEdge, RC )
1447 0 : IF ( RC /= HCO_SUCCESS ) THEN
1448 0 : CALL HCO_ERROR( 'ERROR 14', RC, THISLOC=LOC )
1449 0 : RETURN
1450 : ENDIF
1451 :
1452 : ! Sigma levels are not needed anymore
1453 0 : IF ( ASSOCIATED(SigLev) ) DEALLOCATE(SigLev)
1454 :
1455 : !-----------------------------------------------------------
1456 : ! Flip vertical axis if positive axis is 'down', i.e. level
1457 : ! index 1 is the top of the atmosphere
1458 : !-----------------------------------------------------------
1459 0 : IF ( dir == -1 ) THEN
1460 0 : SigEdge(:,:,: ) = SigEdge(:,:,nlev+1:1:-1 )
1461 0 : NcArr (:,:,:,:) = NcArr (:,:,nlev :1:-1,:)
1462 : ENDIF
1463 :
1464 : ENDIF ! nlev>1
1465 :
1466 : #if defined( MODEL_WRF ) || defined( MODEL_CESM )
1467 : ! Input data is "never" on model levels because model levels can change! (hplin, 5/29/20)
1468 0 : IsModelLevel = .false.
1469 : #endif
1470 :
1471 : ! Now do the regridding
1472 : CALL HCO_MESSY_REGRID ( HcoState, NcArr, &
1473 : LonEdge, LatEdge, SigEdge, &
1474 0 : Lct, IsModelLevel, RC )
1475 0 : IF ( RC /= HCO_SUCCESS ) THEN
1476 0 : CALL HCO_ERROR( 'ERROR 15', RC, THISLOC=LOC )
1477 0 : RETURN
1478 : ENDIF
1479 :
1480 : ! Cleanup
1481 0 : IF ( ASSOCIATED(SigEdge) ) DEALLOCATE(SigEdge)
1482 :
1483 : !-----------------------------------------------------------------
1484 : ! Use map_a2a regridding
1485 : !-----------------------------------------------------------------
1486 : ELSE
1487 0 : IF ( HCO_IsVerb(HcoState%Config%Err,2) ) THEN
1488 0 : WRITE(MSG,*) ' ==> Use map_a2a regridding'
1489 0 : CALL HCO_MSG(HcoState%Config%Err,MSG)
1490 : ENDIF
1491 :
1492 0 : CALL REGRID_MAPA2A ( HcoState, NcArr, LonEdge, LatEdge, Lct, RC )
1493 0 : IF ( RC /= HCO_SUCCESS ) THEN
1494 0 : CALL HCO_ERROR( 'ERROR 16', RC, THISLOC=LOC )
1495 0 : RETURN
1496 : ENDIF
1497 :
1498 : ENDIF
1499 :
1500 : !-----------------------------------------------------------------
1501 : ! Add to diagnostics (if it exists)
1502 : !-----------------------------------------------------------------
1503 0 : IF ( HcoState%Options%Field2Diagn ) THEN
1504 0 : IF ( Lct%Dct%Dta%SpaceDim == 3 .AND. ASSOCIATED(Lct%Dct%Dta%V3) ) THEN
1505 0 : IF ( ASSOCIATED(Lct%Dct%Dta%V3(1)%Val) ) THEN
1506 : CALL Diagn_Update ( HcoState, cName=TRIM(Lct%Dct%cName), &
1507 0 : Array3D=Lct%Dct%Dta%V3(1)%Val, COL=-1, RC=RC )
1508 0 : IF ( RC /= HCO_SUCCESS ) THEN
1509 0 : CALL HCO_ERROR( 'ERROR 17', RC, THISLOC=LOC )
1510 0 : RETURN
1511 : ENDIF
1512 : ENDIF
1513 0 : ELSEIF ( Lct%Dct%Dta%SpaceDim == 2 .AND. ASSOCIATED(Lct%Dct%Dta%V2) ) THEN
1514 0 : IF ( ASSOCIATED(Lct%Dct%Dta%V2(1)%Val) ) THEN
1515 : CALL Diagn_Update ( HcoState, cName=TRIM(Lct%Dct%cName), &
1516 0 : Array2D=Lct%Dct%Dta%V2(1)%Val, COL=-1, RC=RC )
1517 0 : IF ( RC /= HCO_SUCCESS ) THEN
1518 0 : CALL HCO_ERROR( 'ERROR 18', RC, THISLOC=LOC )
1519 0 : RETURN
1520 : ENDIF
1521 : ENDIF
1522 : ENDIF
1523 : ENDIF
1524 :
1525 : !-----------------------------------------------------------------
1526 : ! Cleanup and leave
1527 : !-----------------------------------------------------------------
1528 0 : IF ( ASSOCIATED ( ncArr ) ) DEALLOCATE ( ncArr )
1529 0 : IF ( ASSOCIATED ( LonMid ) ) DEALLOCATE ( LonMid )
1530 0 : IF ( ASSOCIATED ( LatMid ) ) DEALLOCATE ( LatMid )
1531 0 : IF ( ASSOCIATED ( LevMid ) ) DEALLOCATE ( LevMid )
1532 0 : IF ( ASSOCIATED ( LonEdge ) ) DEALLOCATE ( LonEdge )
1533 0 : IF ( ASSOCIATED ( LatEdge ) ) DEALLOCATE ( LatEdge )
1534 :
1535 : ! Return w/ success
1536 0 : CALL HCO_LEAVE ( HcoState%Config%Err, RC )
1537 :
1538 0 : END SUBROUTINE HCOIO_Read
1539 : !EOC
1540 : !------------------------------------------------------------------------------
1541 : ! Harmonized Emissions Component (HEMCO) !
1542 : !------------------------------------------------------------------------------
1543 : !BOP
1544 : !
1545 : ! !IROUTINE: HCOIO_CloseAll
1546 : !
1547 : ! !DESCRIPTION: Subroutine HCOIO\_CloseAll makes sure that there is no open
1548 : ! netCDF file left in the stream.
1549 : !\\
1550 : !\\
1551 : ! !INTERFACE:
1552 : !
1553 0 : SUBROUTINE HCOIO_CloseAll( HcoState, RC )
1554 : !
1555 : ! !USES:
1556 : !
1557 : USE HCO_Ncdf_Mod, ONLY : NC_CLOSE
1558 : !
1559 : ! !INPUT PARAMTERS:
1560 : !
1561 : TYPE(HCO_State), POINTER :: HcoState ! HEMCO state
1562 : !
1563 : ! !INPUT/OUTPUT PARAMETERS:
1564 : !
1565 : INTEGER, INTENT(INOUT) :: RC
1566 : !
1567 : ! !REVISION HISTORY:
1568 : ! 24 Mar 2016 - C. Keller: Initial version
1569 : ! See https://github.com/geoschem/hemco for complete history
1570 : !EOP
1571 : !------------------------------------------------------------------------------
1572 : !BOC
1573 : !
1574 : ! !LOCAL VARIABLES:
1575 : !
1576 : !======================================================================
1577 : ! HCOIO_CloseAll begins here
1578 : !======================================================================
1579 0 : IF ( HcoState%ReadLists%FileLun > 0 ) THEN
1580 0 : CALL NC_CLOSE( HcoState%ReadLists%FileLun )
1581 0 : HcoState%ReadLists%FileLun = -1
1582 : ENDIF
1583 :
1584 : ! Return w/ success
1585 0 : RC = HCO_SUCCESS
1586 :
1587 0 : END SUBROUTINE HCOIO_CloseAll
1588 : !EOC
1589 : END MODULE HCOIO_Read_Mod
1590 : #endif
|