Line data Source code
1 : #define VERIFY_(A) if(.not.HCO_ESMF_VRFY(A,subname,__LINE__)) stop -1
2 : #define ASSERT_(A) if(.not.HCO_ESMF_ASRT(A,subname,__LINE__)) stop -1
3 : !------------------------------------------------------------------------------
4 : ! Harmonized Emissions Component (HEMCO) !
5 : !------------------------------------------------------------------------------
6 : !BOP
7 : !
8 : ! !MODULE: hemco_interface
9 : !
10 : ! !DESCRIPTION: Module HEMCO\_INTERFACE is the HEMCO-CESM interface module.
11 : ! CESM operates on chunks thus the interface is called HCOI\_Chunk.
12 : ! Internally it uses a gridded component to interact with the CAM
13 : ! physics grid; these functions are internal and called HCO\_GC...
14 : !\\
15 : !\\
16 : ! !INTERFACE:
17 : !
18 : module hemco_interface
19 : !
20 : ! !USES:
21 : !
22 : ! ESMF function wrappers
23 : use hco_esmf_wrappers, only: HCO_ESMF_VRFY, HCO_ESMF_ASRT
24 :
25 : ! HEMCO ESMF Grid helpers and properties
26 : use hco_esmf_grid, only: HCO_Grid_Init, HCO_Grid_UpdateRegrid
27 : use hco_esmf_grid, only: HCO_Grid_HCO2CAM_2D, HCO_Grid_HCO2CAM_3D
28 : use hco_esmf_grid, only: HCO_Grid_CAM2HCO_2D, HCO_Grid_CAM2HCO_3D
29 : use hco_esmf_grid, only: IM, JM, LM
30 : use hco_esmf_grid, only: XMid, XEdge, YMid, YEdge, YEdge_R, YSin, AREA_M2, Ap, Bp
31 : use hco_esmf_grid, only: my_IM, my_JM
32 : use hco_esmf_grid, only: my_IS, my_IE, my_JS, my_JE, my_CE
33 :
34 : ! CAM export helpers
35 : use hco_cam_exports, only: HCO_Exports_Init
36 : use hco_cam_exports, only: HCO_Export_Pbuf_AddField
37 : use hco_cam_exports, only: HCO_Export_History_CAM2D, HCO_Export_History_CAM3D
38 : use hco_cam_exports, only: HCO_Export_Pbuf_CAM2D, HCO_Export_Pbuf_CAM3D
39 : use hco_cam_exports, only: hco_pbuf2d ! Allow for pbuf handler to be passed to exports component.
40 :
41 : ! CAM import helpers
42 : use hco_cam_convert_state_mod,only: HCOI_Allocate_All, CAM_GetBefore_HCOI, CAM_RegridSet_HCOI
43 :
44 : ! Controls
45 : use cam_abortutils, only: endrun ! fatal terminator
46 : use cam_logfile, only: iulog ! output log handle
47 :
48 : ! Species information
49 : use constituents, only: pcnst ! # of species
50 : use constituents, only: cnst_name ! species names
51 : use constituents, only: cnst_mw ! advected mass
52 : use mo_chem_utls, only: get_spc_ndx ! IND_ equivalent
53 :
54 : ! Check chemistry option
55 : use chemistry, only: chem_is
56 :
57 : ! Grid
58 : use ppgrid, only: pcols, pver ! Cols, verts
59 : use ppgrid, only: begchunk, endchunk ! Chunk idxs
60 :
61 : ! Time
62 : use time_manager, only: get_curr_time, get_prev_time, get_curr_date
63 : use time_manager, only: get_step_size
64 :
65 : ! ESMF types
66 : use ESMF, only: ESMF_State, ESMF_Clock, ESMF_GridComp
67 : use ESMF, only: ESMF_KIND_R8, ESMF_KIND_I4, ESMF_SUCCESS
68 :
69 : ! HEMCO types
70 : use HCO_Error_Mod, only: hp ! HEMCO precision
71 : use HCO_Error_Mod, only: sp ! HEMCO single precision used for Ptrs
72 : use HCO_Error_Mod, only: HCO_SUCCESS, HCO_FAIL, HCO_VERSION
73 : use HCO_State_Mod, only: HCO_State
74 : use HCOX_State_Mod, only: Ext_State
75 : use HCO_Types_Mod, only: ConfigObj
76 :
77 : use shr_kind_mod, only: r8 => shr_kind_r8
78 :
79 : implicit none
80 : private
81 : !
82 : ! !PRIVATE MEMBER FUNCTIONS:
83 : !
84 : private :: HCO_GC_Init
85 : private :: HCO_GC_SetServices
86 : private :: HCO_GC_Run
87 : private :: HCO_GC_Final
88 :
89 : private :: HCOI_Initialize_Pbuf
90 : !
91 : ! !PUBLIC MEMBER FUNCTIONS:
92 : !
93 : public :: hemco_readnl
94 : public :: HCOI_Chunk_Init
95 : public :: HCOI_Chunk_Run
96 : public :: HCOI_Chunk_Final
97 : !
98 : ! !REMARKS:
99 : ! This file is both the interface of HEMCO component to CAM and the manager of the
100 : ! underlying HEMCO gridded component (HCO\_GC\_*).
101 : !
102 : ! The whole file is getting a little long in the tooth, though. It might be reorg-
103 : ! anized in the future to service hemco_init/run/final which manages the gridded
104 : ! components, which in turn call the HEMCO chunk interface (HCOI\_Chunk\_*).
105 : !
106 : ! For now, the HEMCO chunk interfaces (HCOI\_Chunk\_*) are called in directly from
107 : ! CAM cam_control.F90. I am not in the mood of writing a wrapper for now, but this
108 : ! could be abstracted in the future. (hplin, 3/29/20)
109 : !
110 : ! On a side note, this is the 8th day of living in the 2019-nCoV scare. I miss
111 : ! matcha tea and would die to eat some sweets.
112 : !
113 : ! It is now October 29 and COVID-19 is still raging across the globe; it feels
114 : ! like time has frozen itself since March 21, and we've all been "on one long Zoom call"
115 : ! ever since.
116 : !
117 : ! All I hope for 2021, is that the world does not pull a "You can now play as Luigi" on me.
118 : !
119 : ! Updated 2/24/21 from T. Fritz: Now uses constituents list, since short-term species are
120 : ! not emitted. See PR: https://github.com/jimmielin/HEMCO_CESM/pull/5
121 : !
122 : ! It is now May 15, 2021 and I am vaccinated. Can we visit other peoples homes now?
123 : ! ref: xkcd.com/2454
124 : !
125 : ! !REVISION HISTORY:
126 : ! 29 Jan 2020 - H.P. Lin - Initial version
127 : !EOP
128 : !------------------------------------------------------------------------------
129 : !BOC
130 : !
131 : ! !PRIVATE TYPES:
132 : !
133 : type(ESMF_GridComp) :: HCO_GridComp ! HEMCO GridComp
134 : type(ESMF_State) :: HCO_GridCompState ! HEMCO GridComp Import/Export State
135 :
136 : character(len=256) :: HcoRoot ! HEMCO data root path
137 : character(len=256) :: HcoConfigFile ! HEMCO configuration file path
138 : character(len=256) :: HcoDiagnFile ! HEMCO diagnostics config file path
139 : type(ConfigObj), pointer :: HcoConfig => NULL()
140 :
141 : type(HCO_State), pointer, public :: HcoState => NULL()
142 : type(Ext_State), pointer, public :: ExtState => NULL()
143 :
144 : ! HEMCO internal grid parameters
145 : integer :: HcoGridIM ! # of lons
146 : integer :: HcoGridJM ! # of lats
147 :
148 : ! HEMCO configuration parameters that are set by namelist in CESM
149 : integer :: HcoFixYY ! if > 0, force 'Emission year'
150 :
151 : ! Last execution times for the HEMCO component. We are assuming that time
152 : ! flows unidirectionally (and forwards, for now). (hplin, 3/30/20)
153 : integer :: last_HCO_day, last_HCO_second
154 :
155 : ! Meteorological fields used by HEMCO to be regridded to the HEMCO grid (hplin, 3/31/20)
156 : ! We have to store the fields because the regridding can only take place within the GridComp.
157 : ! Fields are allocated after the internal grid is initialized (so my_* are avail)
158 : !
159 : ! Moved to hco_cam_convert_state_mod, 12/16/20
160 :
161 : contains
162 : !EOC
163 : !------------------------------------------------------------------------------
164 : ! Harmonized Emissions Component (HEMCO) !
165 : !------------------------------------------------------------------------------
166 : !BOP
167 : !
168 : ! !IROUTINE: hemco_readnl
169 : !
170 : ! !DESCRIPTION: Reads the namelist from cam/src/control/runtime_opts.
171 : !\\
172 : !\\
173 : ! !INTERFACE:
174 : !
175 1536 : subroutine hemco_readnl( nlfile )
176 : !
177 : ! !USES:
178 : !
179 : use namelist_utils, only: find_group_name
180 : use units, only: getunit, freeunit
181 : use spmd_utils, only: mpi_real8, mpi_logical, mpi_integer, mpi_character
182 : use spmd_utils, only: masterproc, mpicom, masterprocid
183 : !
184 : ! !INPUT PARAMETERS:
185 : !
186 : character(len=*), intent(in) :: nlfile ! namelist file
187 : !
188 : ! !REVISION HISTORY:
189 : ! 31 Jan 2020 - H.P. Lin - Initial version
190 : !EOP
191 : !------------------------------------------------------------------------------
192 : !BOC
193 : !
194 : ! !LOCAL VARIABLES:
195 : !
196 : integer :: unitn, ierr
197 : character(len=*), parameter :: subname = 'hemco_readnl'
198 : character(len=256) :: hemco_data_root = ''
199 : character(len=256) :: hemco_config_file = 'HEMCO_Config.rc'
200 : character(len=256) :: hemco_diagn_file = 'HEMCO_Diagn.rc'
201 : integer :: hemco_grid_xdim = 0
202 : integer :: hemco_grid_ydim = 0
203 : integer :: hemco_emission_year = -1
204 :
205 : namelist /hemco_nl/ hemco_data_root, hemco_config_file, hemco_diagn_file, hemco_grid_xdim, hemco_grid_ydim, hemco_emission_year
206 :
207 : ! Read namelist on master proc
208 : ! ...
209 1536 : if(masterproc) then
210 2 : unitn = getunit()
211 2 : open(unitn, file=trim(nlfile), status='old')
212 2 : call find_group_name(unitn, 'hemco_nl', status=ierr)
213 2 : if(ierr == 0) then
214 0 : read(unitn, hemco_nl, iostat=ierr)
215 0 : if(ierr /= 0) then
216 0 : call endrun(subname // ':: ERROR reading namelist')
217 : endif
218 : endif
219 2 : close(unitn)
220 2 : call freeunit(unitn)
221 :
222 2 : write(iulog,*) "hemco_readnl: hemco data root is at = ", trim(hemco_data_root)
223 2 : write(iulog,*) "hemco_readnl: hemco config file = ", trim(hemco_config_file)
224 2 : write(iulog,*) "hemco_readnl: hemco diagn file = ", trim(hemco_diagn_file)
225 2 : write(iulog,*) "hemco_readnl: hemco internal grid dimensions will be ", hemco_grid_xdim, " x ", hemco_grid_ydim
226 :
227 2 : if(hemco_emission_year .gt. 0) then
228 0 : write(iulog,*) "hemco_readnl: hemco will force emissions year at = ", hemco_emission_year
229 : else
230 2 : write(iulog,*) "hemco_readnl: hemco will use emissions from the CESM clock"
231 : endif
232 : endif
233 :
234 : ! MPI Broadcast Namelist variables
235 1536 : call mpi_bcast(hemco_data_root, len(hemco_data_root), mpi_character, masterprocid, mpicom, ierr)
236 1536 : call mpi_bcast(hemco_config_file, len(hemco_config_file), mpi_character, masterprocid, mpicom, ierr)
237 1536 : call mpi_bcast(hemco_diagn_file, len(hemco_diagn_file), mpi_character, masterprocid, mpicom, ierr)
238 1536 : call mpi_bcast(hemco_grid_xdim, 1, mpi_integer, masterprocid, mpicom, ierr)
239 1536 : call mpi_bcast(hemco_grid_ydim, 1, mpi_integer, masterprocid, mpicom, ierr)
240 1536 : call mpi_bcast(hemco_emission_year, 1, mpi_integer, masterprocid, mpicom, ierr)
241 :
242 : ! Save this to the module information
243 1536 : HcoRoot = hemco_data_root
244 1536 : HcoConfigFile = hemco_config_file
245 1536 : HcoDiagnFile = hemco_diagn_file
246 1536 : HcoGridIM = hemco_grid_xdim
247 1536 : HcoGridJM = hemco_grid_ydim
248 1536 : HcoFixYY = hemco_emission_year
249 1536 : end subroutine hemco_readnl
250 : !EOC
251 : !------------------------------------------------------------------------------
252 : ! Harmonized Emissions Component (HEMCO) !
253 : !------------------------------------------------------------------------------
254 : !BOP
255 : !
256 : ! !IROUTINE: HCOI_Chunk_Init
257 : !
258 : ! !DESCRIPTION: HCOI\_Chunk\_Init is the initialization method for the CAM
259 : ! interface to HEMCO.
260 : !\\
261 : !\\
262 : ! !INTERFACE:
263 : !
264 0 : subroutine HCOI_Chunk_Init()
265 : !
266 : ! !USES:
267 : !
268 : use cam_logfile, only: iulog
269 : use spmd_utils, only: masterproc, mpicom, masterprocid
270 : use spmd_utils, only: npes, iam
271 : use perf_mod, only: t_startf, t_stopf
272 :
273 : use mpi, only: MPI_INTEGER
274 : use ESMF, only: ESMF_VM, ESMF_VMGetCurrent, ESMF_VMGet
275 : use ESMF, only: ESMF_GridCompCreate, ESMF_GridCompInitialize
276 : use ESMF, only: ESMF_GridCompSetServices
277 : use ESMF, only: ESMF_StateCreate
278 :
279 : use ESMF, only: ESMF_Initialize, ESMF_LOGKIND_MULTI
280 :
281 : ! CAM instance information
282 : use cam_instance, only: inst_index, inst_name
283 :
284 : ! CAM history output (to be moved somewhere later)
285 : use cam_history, only: addfld, add_default, horiz_only
286 :
287 : ! Get extfrc list check for 3-D emissions capability
288 : use mo_chem_utls, only: get_extfrc_ndx
289 :
290 : ! HEMCO Initialization
291 : use HCO_Config_Mod, only: Config_ReadFile, ConfigInit
292 : use HCO_Driver_Mod, only: HCO_Init
293 : use HCO_Error_Mod, only: HCO_LOGFILE_OPEN
294 : use HCO_LogFile_Mod, only: HCO_Spec2Log
295 : use HCO_State_Mod, only: HcoState_Init
296 : use HCO_Types_Mod, only: ConfigObj
297 : use HCO_Types_Mod, only: ListCont
298 : use HCO_VertGrid_Mod, only: HCO_VertGrid_Define
299 :
300 : ! For some overriding work in HEMCO configuration
301 : use HCO_ExtList_Mod, only: CoreNr
302 : use HCO_Types_Mod, only: Opt, Ext
303 :
304 : ! HEMCO extensions initialization
305 : use HCOX_Driver_Mod, only: HCOX_Init
306 : !
307 : ! !REMARKS:
308 : ! None currently.
309 : !
310 : ! !REVISION HISTORY:
311 : ! 06 Feb 2020 - H.P. Lin - Initial version
312 : ! 15 Dec 2020 - H.P. Lin - Implement HEMCO extensions that do require met
313 : ! 23 Mar 2021 - H.P. Lin - Now export for diagnostics too
314 : ! 12 Jan 2023 - H.P. Lin - Optimize memory usage by only allocating 2-D/3-D as needed
315 : ! 15 Jun 2023 - H.P. Lin - Now override HEMCO_Diagn.rc file path and ROOT path in CESM env.
316 : !EOP
317 : !------------------------------------------------------------------------------
318 : !BOC
319 : !
320 : ! !LOCAL VARIABLES:
321 : !
322 : character(len=*), parameter :: subname = 'HCOI_Chunk_Init'
323 : integer :: RC ! ESMF return code
324 : integer :: HMRC ! HEMCO return code
325 :
326 : integer :: N ! Loop idx
327 :
328 : ! Gridded component properties.
329 : ! Note that while edyn_grid_comp initializes the GridComp directly using
330 : ! cam_instance's inst_name, I think this may cause namespace clashing.
331 : ! So I'll be prefixing this with hco_ just incase.
332 : character(len=32) :: HCO_GC_InstName = ''
333 : type(ESMF_VM) :: hco_esmf_vm
334 :
335 : ! MPI stuff
336 : integer :: localPET, PETcount
337 0 : integer, allocatable :: PETlist(:) ! PETs for each instance of the physics grid
338 :
339 : ! HEMCO properties
340 : integer :: nHcoSpc
341 :
342 : ! Temporary string for species naming in exports
343 : character(len=128) :: exportName, exportDesc
344 : character(len=128) :: exportNameTmp
345 :
346 : ! Timing properties
347 : integer :: year, month, day, tod
348 : integer :: hour, minute, second, dt
349 : integer :: prev_day, prev_s, now_day, now_s
350 : integer :: stepsize_tmp
351 :
352 : ! Temporaries
353 : logical :: IsExtfrc3DEmis
354 :
355 : ! Temporaries for HEMCO cycling
356 : logical :: OptFound
357 : type(Ext), pointer :: ThisExt
358 : type(Opt), pointer :: ThisOpt
359 :
360 : !-----------------------------------------------------------------------
361 :
362 0 : call t_startf('HCOI_Chunk_Init')
363 :
364 0 : if(masterproc) then
365 0 : write(iulog,*) "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
366 0 : write(iulog,*) "HEMCO: Harmonized Emissions Component"
367 0 : write(iulog,*) "https://doi.org/10.5194/gmd-14-5487-2021 (Lin et al., 2021)"
368 0 : write(iulog,*) "HEMCO_CESM interface version 2.0.0"
369 0 : write(iulog,*) "You are using HEMCO version ", ADJUSTL(HCO_VERSION)
370 0 : write(iulog,*) "ROOT: ", HcoRoot
371 0 : write(iulog,*) "Config File: ", HcoConfigFile
372 0 : write(iulog,*) "Diagn File: ", HcoDiagnFile
373 0 : write(iulog,*) "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
374 : endif
375 :
376 : ! Assume success
377 0 : RC = ESMF_SUCCESS
378 0 : HMRC = HCO_SUCCESS
379 :
380 : !-----------------------------------------------------------------------
381 : ! Get time properties
382 : !-----------------------------------------------------------------------
383 0 : call get_prev_time(prev_day, prev_s) ! 0 0
384 0 : call get_curr_time(now_day, now_s) ! 0 0
385 0 : call get_curr_date(year, month, day, tod) ! 2005 1 1 0
386 :
387 : ! In order to allow first timestep to be ran, set last HEMCO day and hour to
388 : ! negative at initialization. prev_time from ESMF is always zero.
389 0 : last_HCO_day = -1
390 0 : last_HCO_second = -1
391 0 : write(iulog,*) "HEMCO debug: prev_day, prev_s, now_day, now_s, y, m, d, tod", prev_day, prev_s, now_day, now_s, year, month, day, tod
392 :
393 : !-----------------------------------------------------------------------
394 : ! Setup ESMF wrapper gridded component
395 : ! Adapted from edyn_grid_comp_init
396 : !-----------------------------------------------------------------------
397 0 : call ESMF_VMGetCurrent(hco_esmf_vm, rc=RC)
398 0 : ASSERT_(RC==ESMF_SUCCESS)
399 :
400 0 : call ESMF_VMGet(hco_esmf_vm, localPet=localPET, petCount=PETcount, rc=RC)
401 0 : ASSERT_(RC==ESMF_SUCCESS)
402 :
403 : ! Allocate and collect PETs for each instance of the physics grid
404 0 : allocate(PETlist(npes))
405 : ! sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm, ierror
406 0 : call mpi_allgather(localPET, 1, MPI_INTEGER, PETlist, 1, MPI_INTEGER, mpicom, RC)
407 :
408 : ! Create ESMF gridded component
409 : ! This gridded component's IRF routines are defined in hemco_interface::HCO_GC_SetServices
410 : ! See there for more information. (hplin, 2/6/20)
411 0 : HCO_GC_InstName = 'HCO_' // trim(inst_name)
412 0 : HCO_GridComp = ESMF_GridCompCreate(name=trim(HCO_GC_InstName), petList=PETlist, rc=RC)
413 0 : ASSERT_(RC==ESMF_SUCCESS)
414 :
415 : ! Create a dummy import / export state.
416 0 : call ESMF_GridCompSetServices(HCO_GridComp, HCO_GC_SetServices, rc=RC)
417 0 : ASSERT_(RC==ESMF_SUCCESS)
418 :
419 0 : HCO_GridCompState = ESMF_StateCreate(name='HEMCO GridComp State', rc=RC)
420 0 : ASSERT_(RC==ESMF_SUCCESS)
421 :
422 0 : call ESMF_GridCompInitialize(HCO_GridComp, importState=HCO_GridCompState, exportState=HCO_GridCompState, rc=RC)
423 0 : ASSERT_(RC==ESMF_SUCCESS)
424 :
425 : !if(masterproc) then
426 : ! write(iulog,*) "> Initialized ESMF environment successfully! localPET, PETcount", localPET, PETcount
427 : ! write(iulog,*) "> iam, npes", iam, npes
428 : ! write(iulog,*) "> PETlist", PETlist
429 : !endif
430 :
431 : !-----------------------------------------------------------------------
432 : ! Setup a lat-lon "HEMCO" intermediate grid
433 : !-----------------------------------------------------------------------
434 : ! TODO: For now, # of PEs to use for HEMCO will be total # of PEs.
435 : ! These will all have to be specified in the HEMCO namelist later on.
436 :
437 : ! The number of grid dimensions can be specified in atm namelist for
438 : ! hemco_grid_xdim, hemco_grid_ydim. note that half-sized polar boxes are made
439 : ! so increase the y-dim by one.
440 : ! 288x201 = 0.9x1.25
441 : ! 144x91 = 2.0x2.5
442 :
443 : ! Verify that the grid is in a reasonable state
444 0 : if(HcoGridIM .le. 1 .or. HcoGridJM .le. 1) then
445 0 : call endrun("Invalid HEMCO grid parameters - too small - in &hemco namelist. Specify hemco_grid_xdim and hemco_grid_ydim as # of grid boxes in each dimension")
446 : endif
447 :
448 0 : if(mod(HcoGridJM, 2) .ne. 1) then
449 0 : call endrun("Invalid HEMCO grid parameters - hemco_grid_ydim needs to be odd - in &hemco namelist. This is because y-dim has half-sized polar boxes.")
450 : endif
451 :
452 : ! Initialize the HEMCO intermediate grid
453 0 : call HCO_Grid_Init (IM_in = HcoGridIM, JM_in = HcoGridJM, nPET_in = npes, RC=RC)
454 0 : ASSERT_(RC==ESMF_SUCCESS)
455 :
456 0 : if(masterproc) then
457 0 : write(iulog,*) "> Initialized HEMCO Grid environment successfully!"
458 0 : write(iulog,*) "> Global Dimensions: ", HcoGridIM, HcoGridJM, LM
459 0 : write(iulog,*) "> my_IM, my_JM, LM, my_CE", my_IM, my_JM, LM, my_CE
460 : endif
461 :
462 : !-----------------------------------------------------------------------
463 : ! Update HEMCO regrid descriptors for the first time.
464 : !-----------------------------------------------------------------------
465 0 : call HCO_Grid_UpdateRegrid(RC=RC)
466 0 : ASSERT_(RC==ESMF_SUCCESS)
467 :
468 0 : if(masterproc) then
469 0 : write(iulog,*) "> First refresh of HEMCO Regrid descriptors"
470 : endif
471 :
472 : !-----------------------------------------------------------------------
473 : ! Allocate HEMCO meteorological objects
474 : ! We are allocating globally for the whole HEMCO component here. This may
475 : ! clash if my_CE changes (multiple CAM instances). To be verified.
476 : ! Should be a easy fix regardless, simply allocate and dealloc in the run
477 : ! (hplin, 3/31/20)
478 : !-----------------------------------------------------------------------
479 0 : call HCOI_Allocate_All()
480 :
481 0 : if(masterproc) then
482 0 : write(iulog,*) "> Allocated HEMCO temporary met fields"
483 : endif
484 :
485 : !-----------------------------------------------------------------------
486 : ! Initialize CAM export component
487 : !-----------------------------------------------------------------------
488 0 : call HCO_Exports_Init()
489 :
490 0 : if(masterproc) then
491 0 : write(iulog,*) "> Initialize HEMCO/CAM exports component"
492 : endif
493 :
494 : ! Test only hplin 3/3/20: add a dummy history field in CAM to test HEMCO
495 : ! grid is correctly reflected.
496 : ! HCO_TEST outputs in the physics mesh.
497 : ! AvgFlag: (cam_history) A mean, B mean00z, I instant, X max, M min, S stddev
498 : !
499 : ! This call should eventually be reflected elsewhere?
500 : call addfld("DIAG_CAM_TEST", (/'lev'/), 'I', '1', &
501 : 'HEMCO Debug, PETID written on CAM', &
502 0 : gridname="physgrid")
503 :
504 : ! Enable default for debugging:
505 : ! call add_default("DIAG_CAM_TEST", 2, 'I') ! Make this field always ON
506 :
507 : call addfld("DIAG_HCO_TEST", (/'lev'/), 'I', '1', &
508 : 'HEMCO Debug Data', &
509 0 : gridname="physgrid")
510 :
511 : ! Enable default for debugging:
512 : ! call add_default("DIAG_HCO_TEST", 2, 'I') ! Make this field always ON
513 :
514 : !-----------------------------------------------------------------------
515 : ! Initialize the HEMCO configuration object...
516 : !-----------------------------------------------------------------------
517 : !if(masterproc) write(iulog,*) "> Initializing HCO configuration object"
518 :
519 : ! We are using pcnst here, which is # of constituents.
520 0 : nHcoSpc = pcnst ! # of hco species?
521 :
522 0 : call ConfigInit(HcoConfig, HMRC, nModelSpecies=nHcoSpc)
523 0 : ASSERT_(HMRC==HCO_SUCCESS)
524 :
525 0 : HcoConfig%amIRoot = masterproc
526 : ! HcoConfig%amIRoot = .true. ! for debug only so verbosity is higher
527 :
528 0 : HcoConfig%MetField = 'MERRA2'
529 0 : HcoConfig%GridRes = ''
530 :
531 : !-----------------------------------------------------------------------
532 : ! Retrieve the species list and register exports
533 : !-----------------------------------------------------------------------
534 : ! Below we directly use nHcoSpc which corresponds to the number of constituents
535 : ! (nHcoSpc = pcnst). Only constituents may be advected.
536 0 : HcoConfig%nModelSpc = nHcoSpc
537 0 : HcoConfig%nModelAdv = nHcoSpc ! # of adv spc?
538 :
539 : !if(masterproc) write(iulog,*) "> Initializing HCO species list!"
540 :
541 0 : do N = 1, nHcoSpc
542 0 : HcoConfig%ModelSpc(N)%ModID = N ! model id
543 :
544 0 : HcoConfig%ModelSpc(N)%SpcName = trim(cnst_name(N)) ! only constituents can be emitted
545 :
546 : !----------------------------------------------
547 : ! Register export properties.
548 : !----------------------------------------------
549 : ! History output (this will be moved to hco_cam_exports soon hopefully)
550 0 : exportName = 'HCO_' // trim(HcoConfig%ModelSpc(N)%SpcName)
551 :
552 : !if(masterproc) write(iulog,*) "Exported exportName " // trim(exportName) // " to history"
553 :
554 : ! Physics buffer
555 : ! Note that _AddField will prepend HCO_, so do not add it here
556 : !
557 : ! Update hplin 1/13/23: Verify if part of extfrc_lst. If yes,
558 : ! then allocate as 3-D. Otherwise, this field can be allocated
559 : ! as 2-D. This scan is somewhat intensive as it uses get_extfrc_ndx
560 : ! which loops through extcnt in extfrc_lst.
561 0 : IsExtfrc3DEmis = (get_extfrc_ndx(trim(HcoConfig%ModelSpc(N)%SpcName)) .gt. 0)
562 :
563 0 : if(masterproc) write(iulog,*) "Setting up HEMCO exportName " // trim(exportName), IsExtfrc3DEmis
564 0 : if(IsExtfrc3DEmis) then
565 : ! 3-D emissions are supported
566 0 : HcoConfig%ModelSpc(N)%DimMax = 3
567 :
568 0 : exportDesc = "HEMCO 3-D Emissions Species " // trim(HcoConfig%ModelSpc(N)%SpcName)
569 : call addfld(exportName, (/'lev'/), 'I', 'kg/m2/s', &
570 : trim(exportDesc), &
571 0 : gridname='physgrid')
572 0 : call HCO_Export_Pbuf_AddField(HcoConfig%ModelSpc(N)%SpcName, 3, hcoID=N)
573 : else
574 : ! 2-D emissions only
575 0 : HcoConfig%ModelSpc(N)%DimMax = 2
576 :
577 0 : exportDesc = "HEMCO 2-D Emissions Species " // trim(HcoConfig%ModelSpc(N)%SpcName)
578 : call addfld(exportName, horiz_only, 'I', 'kg/m2/s', &
579 : trim(exportDesc), &
580 0 : gridname='physgrid')
581 0 : call HCO_Export_Pbuf_AddField(HcoConfig%ModelSpc(N)%SpcName, 2, hcoID=N)
582 : endif
583 : enddo
584 :
585 : !-----------------------------------------------------------------------
586 : ! Read HEMCO configuration file from HcoConfigFile (location in CAM namelist)
587 : !-----------------------------------------------------------------------
588 : !if(masterproc) write(iulog,*) "> Reading HEMCO configuration file..."
589 :
590 : ! FIXME: Not implementing "Dry-run" functionality in HEMCO_CESM. (hplin, 3/27/20)
591 : ! Phase: 0 = all, 1 = sett and switches only, 2 = fields only
592 0 : call Config_ReadFile(HcoConfig%amIRoot, HcoConfig, HcoConfigFile, 1, HMRC, IsDryRun=.false.)
593 0 : if(masterproc .and. HMRC /= HCO_SUCCESS) then
594 0 : write(iulog,*) "******************************************"
595 0 : write(iulog,*) "HEMCO_CESM: Config_ReadFile has failed (1)! "
596 0 : write(iulog,*) "THIS ERROR ORIGINATED WITHIN HEMCO! "
597 0 : write(iulog,*) "HEMCO configuration file could not be read."
598 0 : write(iulog,*) "This may be due to misconfiguration of the"
599 0 : write(iulog,*) "hemco_config_file namelist variable, or a"
600 0 : write(iulog,*) "misformatted HEMCO configuration file."
601 0 : write(iulog,*) "Please refer to the HEMCO.log log file in your"
602 0 : write(iulog,*) "case run directory or as configured in HEMCO_Config.rc"
603 0 : write(iulog,*) "for more information."
604 0 : write(iulog,*) "******************************************"
605 : endif
606 0 : ASSERT_(HMRC==HCO_SUCCESS)
607 :
608 : ! Open the log file
609 0 : if(masterproc) then
610 0 : call HCO_LOGFILE_OPEN(HcoConfig%Err, RC=HMRC)
611 0 : ASSERT_(HMRC==HCO_SUCCESS)
612 : endif
613 :
614 0 : call Config_ReadFile(HcoConfig%amIRoot, HcoConfig, HcoConfigFile, 2, HMRC, IsDryRun=.false.)
615 0 : if(masterproc .and. HMRC /= HCO_SUCCESS) then
616 0 : write(iulog,*) "******************************************"
617 0 : write(iulog,*) "HEMCO_CESM: Config_ReadFile has failed (2)! "
618 0 : write(iulog,*) "THIS ERROR ORIGINATED WITHIN HEMCO! "
619 0 : write(iulog,*) "HEMCO configuration file could not be read."
620 0 : write(iulog,*) "This may be due to misconfiguration of the"
621 0 : write(iulog,*) "hemco_config_file namelist variable, or a"
622 0 : write(iulog,*) "misformatted HEMCO configuration file."
623 0 : write(iulog,*) "Please refer to the HEMCO.log log file in your"
624 0 : write(iulog,*) "case run directory or as configured in HEMCO_Config.rc"
625 0 : write(iulog,*) "for more information."
626 0 : write(iulog,*) "******************************************"
627 : endif
628 0 : ASSERT_(HMRC==HCO_SUCCESS)
629 :
630 : !if(masterproc) write(iulog,*) "> Read HEMCO configuration file OK!"
631 :
632 : !-----------------------------------------------------------------------
633 : ! Initialize the HEMCO state object
634 : !-----------------------------------------------------------------------
635 0 : call HcoState_Init(HcoState, HcoConfig, nHcoSpc, HMRC)
636 0 : ASSERT_(HMRC==HCO_SUCCESS)
637 :
638 : !if(masterproc) write(iulog,*) "> Initialize HEMCO state obj OK!"
639 :
640 : ! Emissions, chemistry and dynamics timestep [s]
641 : ! Assume 0.5h until given actual time in HCO_GC_Run!
642 :
643 0 : stepsize_tmp = get_step_size()
644 0 : if(masterproc) write(iulog,*) "> HEMCO_CESM: Step size is ", stepsize_tmp
645 :
646 0 : HcoState%TS_EMIS = stepsize_tmp * 1.0
647 0 : HcoState%TS_CHEM = stepsize_tmp * 1.0
648 0 : HcoState%TS_DYN = stepsize_tmp * 1.0
649 :
650 : ! Not a MAPL simulation. isESMF is deceiving.
651 0 : HcoState%Options%isESMF = .false.
652 :
653 : ! Deposition length scale. Used for computing dry deposition frequencies
654 : ! over the entire PBL or the first model layer. Hardcoded for now,
655 : ! should load Input_Opt%PBL_DRYDEP from GEOS-Chem-CESM (hplin, 3/29/20)
656 : ! !FIXME
657 0 : HcoState%Options%PBL_DRYDEP = .false.
658 :
659 : ! Don't support DryRun option (for now)
660 0 : HcoState%Options%IsDryRun = .false.
661 :
662 : !if(masterproc) write(iulog,*) "> Set basic HEMCO state obj OK!"
663 :
664 : !-----------------------------------------------------------------------
665 : ! Register HEMCO species information (HEMCO state object)
666 : !-----------------------------------------------------------------------
667 0 : do N = 1, nHcoSpc
668 0 : HcoState%Spc(N)%ModID = N ! model id
669 0 : HcoState%Spc(N)%SpcName = trim(cnst_name(N)) ! species name
670 0 : HcoState%Spc(N)%MW_g = cnst_mw(N) ! mol. weight [g/mol]
671 :
672 : ! !!! We don't set Henry's law coefficients in HEMCO_CESM !!!
673 : ! they are mostly used in HCOX_SeaFlux_Mod, but HCOX are unsupported (for now)
674 : ! (hplin, 3/29/20)
675 :
676 : ! If is CESM-GC, then set Henry's law constants for SeaFlux
677 : ! KLUDGE by hplin: 1/3/21
678 : ! For defined species, hard code the Henry* values for now so we can work
679 : ! with SeaFlux. This fragmentation will cause issues down the road, FIXME
680 0 : if(HcoState%Spc(N)%SpcName .eq. "CH3I") then
681 : ! 101.325_r8
682 0 : HcoState%Spc(N)%HenryK0 = 0.20265_r8 ! [M/atm]
683 0 : HcoState%Spc(N)%HenryCR = 3.6e+3_r8 ! [K]
684 0 : HcoState%Spc(N)%HenryPKA = -999e+0_r8 ! [1] (missing_r8 from species_mod)
685 : endif
686 :
687 0 : if(HcoState%Spc(N)%SpcName .eq. "DMS") then
688 : ! 101.325_r8
689 0 : HcoState%Spc(N)%HenryK0 = 4.80e-1_r8 ! [M/atm]
690 0 : HcoState%Spc(N)%HenryCR = 3100.0_r8 ! [K]
691 0 : HcoState%Spc(N)%HenryPKA = -999e+0_r8 ! [1] (missing_r8 from species_mod)
692 : endif
693 :
694 0 : if(HcoState%Spc(N)%SpcName .eq. "ACET") then
695 : ! 101.325_r8. using new henry constants
696 0 : HcoState%Spc(N)%HenryK0 = 2.74e+1_r8 ! [M/atm]
697 0 : HcoState%Spc(N)%HenryCR = 5500.0_r8 ! [K]
698 0 : HcoState%Spc(N)%HenryPKA = -999e+0_r8 ! [1] (missing_r8 from species_mod)
699 : endif
700 :
701 0 : if(HcoState%Spc(N)%SpcName .eq. "MOH") then
702 : ! 101.325_r8
703 0 : HcoState%Spc(N)%HenryK0 = 2.03e+2_r8 ! [M/atm]
704 0 : HcoState%Spc(N)%HenryCR = 5600.0_r8 ! [K]
705 0 : HcoState%Spc(N)%HenryPKA = -999e+0_r8 ! [1] (missing_r8 from species_mod)
706 : endif
707 :
708 0 : if(HcoState%Spc(N)%SpcName .eq. "ALD2") then
709 : ! 101.325_r8. using new henry constants
710 0 : HcoState%Spc(N)%HenryK0 = 1.30e-01_r8 * 101.325_r8 ! [M/atm]
711 0 : HcoState%Spc(N)%HenryCR = 5900.0_r8 ! [K]
712 0 : HcoState%Spc(N)%HenryPKA = -999e+0_r8 ! [1] (missing_r8 from species_mod)
713 : endif
714 :
715 0 : if(HcoState%Spc(N)%SpcName .eq. "MENO3") then
716 : ! 101.325_r8
717 0 : HcoState%Spc(N)%HenryK0 = 1.1e+1_r8 ! [M/atm]
718 0 : HcoState%Spc(N)%HenryCR = 4700.0_r8 ! [K]
719 0 : HcoState%Spc(N)%HenryPKA = -999e+0_r8 ! [1] (missing_r8 from species_mod)
720 : endif
721 :
722 0 : if(HcoState%Spc(N)%SpcName .eq. "ETNO3") then
723 : ! 101.325_r8
724 0 : HcoState%Spc(N)%HenryK0 = 1.6_r8 ! [M/atm]
725 0 : HcoState%Spc(N)%HenryCR = 5400.0_r8 ! [K]
726 0 : HcoState%Spc(N)%HenryPKA = -999e+0_r8 ! [1] (missing_r8 from species_mod)
727 : endif
728 :
729 : ! HcoState%Spc(N)%HenryK0 ! [M/atm]
730 : ! HcoState%Spc(N)%HenryCR ! [K]
731 : ! HcoState%Spc(N)%HenryPKA ! [1]
732 :
733 : ! Write to log too
734 0 : if(masterproc) then
735 : !write(iulog,*) ">> Spc", N, " = ", cnst_name(N), "MW_g", cnst_mw(N)
736 0 : call HCO_Spec2Log(HcoState, N)
737 : endif
738 : enddo
739 :
740 : !if(masterproc) write(iulog,*) "> Set HEMCO species info OK!"
741 :
742 : !-----------------------------------------------------------------------
743 : ! Register HEMCO Grid information
744 : !-----------------------------------------------------------------------
745 : ! Note that HEMCO running in the CAM environment is entirely MPI and
746 : ! we use the grid dimensions of the local PET. Thus, remember that all
747 : ! data and fields are sized my_* and NOT the global indices, although
748 : ! all PETs are aware. This is similar to ids, ide, jds, jde ... versus
749 : ! its, ite, jts, jte ... in WRF, but here we use my_IS, my_IE, my_JS...
750 : !
751 : ! The vertical dimension is not decomposed and follows the CAM vertical,
752 : ! whatever that is. This information is all abstracted and propagated within
753 : ! HCO_ESMF_Grid. (hplin, 3/29/20)
754 :
755 0 : HcoState%NX = my_IM
756 0 : HcoState%NY = my_JM
757 0 : HcoState%NZ = LM
758 :
759 : ! Pass Ap, Bp values, units [Pa], [unitless]
760 : ! later remove masterproc
761 : call HCO_VertGrid_Define(HcoState%Config, &
762 : zGrid = HcoState%Grid%zGrid, &
763 : nz = HcoState%NZ, &
764 : Ap = Ap, &
765 : Bp = Bp, &
766 0 : RC = HMRC)
767 0 : ASSERT_(HMRC==HCO_SUCCESS)
768 :
769 : ! Point to grid variables
770 0 : HcoState%Grid%XMID%Val => XMid (my_IS:my_IE , my_JS:my_JE )
771 0 : HcoState%Grid%YMID%Val => YMid (my_IS:my_IE , my_JS:my_JE )
772 0 : HcoState%Grid%XEdge%Val => XEdge (my_IS:my_IE+1, my_JS:my_JE )
773 0 : HcoState%Grid%YEdge%Val => YEdge (my_IS:my_IE , my_JS:my_JE+1)
774 0 : HcoState%Grid%YSin%Val => YSin (my_IS:my_IE , my_JS:my_JE+1)
775 0 : HcoState%Grid%AREA_M2%Val => AREA_M2(my_IS:my_IE , my_JS:my_JE )
776 :
777 : ! Debug
778 : ! write(6,*) "HCOI_Chunk_Init XMid, YMid(1,1)", HcoState%Grid%XMid%Val(1,1), &
779 : ! HcoState%Grid%YMid%Val(1,1), &
780 : ! HcoState%Grid%Area_m2%Val(1,1)
781 :
782 : !if(masterproc) write(iulog,*) "> Set HEMCO PET-local grid info OK!"
783 :
784 : !-----------------------------------------------------------------------
785 : ! Override HEMCO diagnostic file and root file paths in CESM environment
786 : ! This is so that the configuration file $ROOT and $DiagnFile do not
787 : ! have to contain hard-coded paths and can be distributed by cesmdata
788 : ! agnostically of the running environment. (hplin, 6/15/23)
789 : !-----------------------------------------------------------------------
790 : ! ROOT property. This is retrieved in several forms within the HEMCO code:
791 : ! hco_extlist_mod::HCO_ROOT(HcoConfig) --> HcoConfig%ROOT (populated by HCO_SetDefaultToken)
792 : ! hco_extlist_mod::HCO_GetOpt(ExtList, 'ROOT', -1) --> extension opt linked list
793 : ! looks like most of HEMCO convention will use HcoConfig%ROOT which is good.
794 : ! the $ROOT token replacement happens in hco_chartools_mod which uses HCO_ROOT().
795 : !
796 : ! the property has to be updated right after HCO_SetDefaultToken and values
797 : ! appropriately updated so that retrieval will use the overridden property.
798 : ! This means it has to go right after Config_ReadFile.
799 :
800 : ! This might not be sufficient to update the configuration within the extlist -1.
801 0 : HcoConfig%ROOT = HcoRoot
802 :
803 : ! DiagnFile property. This is part of the extension options and we replicate
804 : ! some of the functionality in order to override it here. Maybe this work could
805 : ! be done upstream.
806 0 : OptFound = .false.
807 0 : ThisOpt => NULL()
808 0 : ThisExt => NULL()
809 0 : ThisExt => HcoConfig%ExtList
810 0 : do while(associated(ThisExt))
811 0 : if(ThisExt%ExtNr /= CoreNr) then ! Looking for the core extension.
812 0 : ThisExt => ThisExt%NextExt
813 0 : cycle
814 : endif
815 :
816 0 : ThisOpt => ThisExt%Opts
817 0 : do while(associated(ThisOpt))
818 0 : if(trim(ThisOpt%OptName) == "DiagnFile") then
819 0 : ThisOpt%OptValue = HcoDiagnFile
820 0 : OptFound = .true.
821 0 : exit
822 : endif
823 :
824 0 : ThisOpt => ThisOpt%NextOpt
825 : enddo
826 :
827 0 : if(OptFound) then
828 : ThisExt => NULL()
829 : else
830 0 : ThisExt => ThisExt%NextExt
831 : endif
832 : enddo
833 :
834 0 : ThisOpt => NULL()
835 0 : ThisExt => NULL()
836 :
837 : !-----------------------------------------------------------------------
838 : ! Initialize HEMCO!
839 : ! The following actions happen during initialization:
840 : ! 1) time slice pointers (tIDx_Init)
841 : ! 2) clock initialization (HcoClock_Init populates HcoState%Clock)
842 : ! 3) HEMCO diagnostic containers are initialized (HcoDiagn_Init)
843 : ! 4) configuration file initializes ReadList
844 : ! 5) universal scale factor for each HEMCO species (Hco_ScaleInit)
845 : !-----------------------------------------------------------------------
846 0 : call t_startf('HCO_HCOX_Init')
847 0 : call HCO_Init(HcoState, HMRC)
848 0 : if(masterproc .and. HMRC /= HCO_SUCCESS) then
849 0 : write(iulog,*) "******************************************"
850 0 : write(iulog,*) "HEMCO_CESM: HCO_Init has failed!"
851 0 : write(iulog,*) "THIS ERROR ORIGINATED WITHIN HEMCO!"
852 0 : write(iulog,*) "HEMCO could not be initialized."
853 0 : write(iulog,*) "This may be due to misconfiguration of the"
854 0 : write(iulog,*) "HEMCO configuration file."
855 0 : write(iulog,*) "Please refer to the HEMCO.log log file and"
856 0 : write(iulog,*) "the cesm.log. log files in your case run directory"
857 0 : write(iulog,*) "for more information."
858 0 : write(iulog,*) "******************************************"
859 : endif
860 0 : ASSERT_(HMRC==HCO_SUCCESS)
861 :
862 0 : if(masterproc) write(iulog,*) "> HEMCO initialized successfully!"
863 :
864 : !-----------------------------------------------------------------------
865 : ! Initialize HEMCO Extensions!
866 : !-----------------------------------------------------------------------
867 0 : call HCOX_Init(HcoState, ExtState, HMRC)
868 0 : ASSERT_(HMRC==HCO_SUCCESS)
869 :
870 0 : if(masterproc) write(iulog,*) "> HEMCO extensions initialized successfully!"
871 0 : call t_stopf('HCO_HCOX_Init')
872 :
873 : !-----------------------------------------------------------------------
874 : ! Additional exports: Verify if additional diagnostic quantities
875 : ! for HEMCO extensions need to be provisioned.
876 : ! (hplin, 3/21/21)
877 : !-----------------------------------------------------------------------
878 : ! ParaNOx: Ship NO emissions
879 : ! Due to the length limit this is a non-standard name, the HEMCO names are
880 : ! PARANOX_O3_DEPOSITION_FLUX and PARANOX_HNO3_DEPOSITION_FLUX
881 0 : if(ExtState%ParaNOx > 0) then
882 0 : write(exportnameTmp, '(a)') 'PAR_O3_DEP'
883 0 : exportName = 'HCO_' // trim(exportNameTmp)
884 0 : exportDesc = "HEMCO Deposition Flux Name " // trim(exportNameTmp)
885 :
886 : call addfld(exportName, horiz_only, 'I', '1', &
887 : trim(exportDesc), &
888 0 : gridname='physgrid')
889 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
890 :
891 0 : write(exportnameTmp, '(a)') 'PAR_HNO3_DEP'
892 0 : exportName = 'HCO_' // trim(exportNameTmp)
893 0 : exportDesc = "HEMCO Deposition Flux Name " // trim(exportNameTmp)
894 :
895 : call addfld(exportName, horiz_only, 'I', '1', &
896 : trim(exportDesc), &
897 0 : gridname='physgrid')
898 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
899 :
900 0 : if(masterproc) write(iulog,*) "> HEMCO ParaNOx extension exports (PAR_O3_DEP, PAR_HNO3_DEP) initialized successfully"
901 : endif
902 :
903 : !-----------------------------------------------------------------------
904 : ! Additional exports: Verify if we need to add additional exports
905 : ! for integration with CESM-GC. (hplin, 4/15/20)
906 : !-----------------------------------------------------------------------
907 :
908 : ! Do additional exports!
909 : ! Removed debug into history output because it does not seem necessary (hplin, 9/23/22)
910 0 : if(chem_is('GEOS-Chem')) then
911 0 : do N = 0, 72
912 : ! LANDTYPExx
913 0 : write(exportNameTmp, '(a,i2.2)') 'LANDTYPE', N
914 0 : exportName = 'HCO_' // trim(exportNameTmp)
915 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
916 :
917 : ! XLAIxx
918 0 : write(exportNameTmp, '(a,i2.2)') 'XLAI', N
919 0 : exportName = 'HCO_' // trim(exportNameTmp)
920 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
921 : enddo
922 :
923 : ! VMR_CH3CL
924 0 : write(exportnameTmp, '(a)') 'VMR_CH3CL'
925 0 : exportName = 'HCO_' // trim(exportNameTmp)
926 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
927 :
928 : ! VMR_CH2CL2
929 0 : write(exportnameTmp, '(a)') 'VMR_CH2CL2'
930 0 : exportName = 'HCO_' // trim(exportNameTmp)
931 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
932 :
933 : ! VMR_CHCL3
934 0 : write(exportnameTmp, '(a)') 'VMR_CHCL3'
935 0 : exportName = 'HCO_' // trim(exportNameTmp)
936 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
937 :
938 : ! VMR_CH3BR
939 0 : write(exportnameTmp, '(a)') 'VMR_CH3BR'
940 0 : exportName = 'HCO_' // trim(exportNameTmp)
941 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
942 :
943 : ! VMR_CCL4
944 0 : write(exportnameTmp, '(a)') 'VMR_CCL4'
945 0 : exportName = 'HCO_' // trim(exportNameTmp)
946 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
947 :
948 : ! VMR_CFC113
949 0 : write(exportnameTmp, '(a)') 'VMR_CFC113'
950 0 : exportName = 'HCO_' // trim(exportNameTmp)
951 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
952 :
953 : ! VMR_CFC114
954 0 : write(exportnameTmp, '(a)') 'VMR_CFC114'
955 0 : exportName = 'HCO_' // trim(exportNameTmp)
956 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
957 :
958 : ! VMR_CFC115
959 0 : write(exportnameTmp, '(a)') 'VMR_CFC115'
960 0 : exportName = 'HCO_' // trim(exportNameTmp)
961 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
962 :
963 : ! VMR_CFC11
964 0 : write(exportnameTmp, '(a)') 'VMR_CFC11'
965 0 : exportName = 'HCO_' // trim(exportNameTmp)
966 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
967 :
968 : ! VMR_CFC12
969 0 : write(exportnameTmp, '(a)') 'VMR_CFC12'
970 0 : exportName = 'HCO_' // trim(exportNameTmp)
971 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
972 :
973 : ! VMR_CH3CCL3
974 0 : write(exportnameTmp, '(a)') 'VMR_CH3CCL3'
975 0 : exportName = 'HCO_' // trim(exportNameTmp)
976 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
977 :
978 : ! VMR_H1211
979 0 : write(exportnameTmp, '(a)') 'VMR_H1211'
980 0 : exportName = 'HCO_' // trim(exportNameTmp)
981 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
982 :
983 : ! VMR_H1301
984 0 : write(exportnameTmp, '(a)') 'VMR_H1301'
985 0 : exportName = 'HCO_' // trim(exportNameTmp)
986 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
987 :
988 : ! VMR_H2402
989 0 : write(exportnameTmp, '(a)') 'VMR_H2402'
990 0 : exportName = 'HCO_' // trim(exportNameTmp)
991 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
992 :
993 : ! VMR_HCFC141b
994 0 : write(exportnameTmp, '(a)') 'VMR_HCFC141B'
995 0 : exportName = 'HCO_' // trim(exportNameTmp)
996 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
997 :
998 : ! VMR_HCFC142B
999 0 : write(exportnameTmp, '(a)') 'VMR_HCFC142B'
1000 0 : exportName = 'HCO_' // trim(exportNameTmp)
1001 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
1002 :
1003 : ! VMR_HCFC22
1004 0 : write(exportnameTmp, '(a)') 'VMR_HCFC22'
1005 0 : exportName = 'HCO_' // trim(exportNameTmp)
1006 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
1007 :
1008 : ! VMR_N2O
1009 0 : write(exportnameTmp, '(a)') 'VMR_N2O'
1010 0 : exportName = 'HCO_' // trim(exportNameTmp)
1011 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
1012 :
1013 : ! VMR_OCS
1014 0 : write(exportnameTmp, '(a)') 'VMR_OCS'
1015 0 : exportName = 'HCO_' // trim(exportNameTmp)
1016 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
1017 :
1018 : ! VMR_H2
1019 0 : write(exportnameTmp, '(a)') 'VMR_H2'
1020 0 : exportName = 'HCO_' // trim(exportNameTmp)
1021 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
1022 :
1023 : ! UVALBEDO
1024 0 : write(exportnameTmp, '(a)') 'UV_ALBEDO'
1025 0 : exportName = 'HCO_' // trim(exportNameTmp)
1026 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
1027 :
1028 : ! SURF_IODIDE
1029 0 : write(exportnameTmp, '(a)') 'iodide'
1030 0 : exportName = 'HCO_' // trim(exportNameTmp)
1031 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
1032 :
1033 : ! SURF_SALINITY
1034 0 : write(exportnameTmp, '(a)') 'salinity'
1035 0 : exportName = 'HCO_' // trim(exportNameTmp)
1036 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
1037 :
1038 : ! OMOC_DJF
1039 0 : write(exportnameTmp, '(a)') 'OMOC_DJF'
1040 0 : exportName = 'HCO_' // trim(exportNameTmp)
1041 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
1042 :
1043 : ! OMOC_MAM
1044 0 : write(exportnameTmp, '(a)') 'OMOC_MAM'
1045 0 : exportName = 'HCO_' // trim(exportNameTmp)
1046 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
1047 :
1048 : ! OMOC_JJA
1049 0 : write(exportnameTmp, '(a)') 'OMOC_JJA'
1050 0 : exportName = 'HCO_' // trim(exportNameTmp)
1051 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
1052 :
1053 : ! OMOC_SON
1054 0 : write(exportnameTmp, '(a)') 'OMOC_SON'
1055 0 : exportName = 'HCO_' // trim(exportNameTmp)
1056 0 : call HCO_Export_Pbuf_AddField(exportNameTmp, 2)
1057 :
1058 0 : if ( masterproc ) then
1059 0 : write(iulog,*) "> HEMCO additional exports for CESM2-GC initialized!"
1060 : endif
1061 : endif
1062 :
1063 0 : call t_stopf('HCOI_Chunk_Init')
1064 0 : end subroutine HCOI_Chunk_Init
1065 : !EOC
1066 : !------------------------------------------------------------------------------
1067 : ! Harmonized Emissions Component (HEMCO) !
1068 : !------------------------------------------------------------------------------
1069 : !BOP
1070 : !
1071 : ! !IROUTINE: HCOI_Initialize_Pbuf
1072 : !
1073 : ! !DESCRIPTION: HCOI\_Initialize\_Pbuf resets the physics buffer.
1074 : !\\
1075 : !\\
1076 : ! !INTERFACE:
1077 : !
1078 0 : subroutine HCOI_Initialize_Pbuf()
1079 : !
1080 : ! !USES:
1081 : !
1082 0 : use cam_logfile, only: iulog
1083 : use spmd_utils, only: masterproc
1084 : !
1085 : ! !REVISION HISTORY:
1086 : ! 14 Dec 2020 - H.P. Lin - Initial version
1087 : ! 16 Jan 2023 - H.P. Lin - Need to reset this after pbuf fields are now 3-D or 2-D.
1088 : ! Approximately 16 hours of debugging stack corruptions
1089 : ! were needed to realize I wrote this routine.
1090 : !EOP
1091 : !------------------------------------------------------------------------------
1092 : !BOC
1093 : !
1094 : ! !LOCAL VARIABLES:
1095 : !
1096 : character(len=*), parameter :: subname = 'HCOI_Initialize_Pbuf'
1097 : integer :: RC ! ESMF return code
1098 :
1099 : integer :: spcID
1100 0 : real(ESMF_KIND_R8) :: zeroFldCAM_3D(1:LM, 1:my_CE)
1101 0 : real(ESMF_KIND_R8) :: zeroFldCAM_2D(1:my_CE)
1102 :
1103 : ! Zero out quantities first
1104 0 : zeroFldCAM_3D(:,:) = 0.0_r8
1105 0 : zeroFldCAM_2D(: ) = 0.0_r8
1106 :
1107 : ! Reset for each species
1108 0 : do spcID = 1, HcoConfig%nModelSpc
1109 : ! Write to physics buffer (pass model name)
1110 0 : if(HcoConfig%ModelSpc(spcID)%DimMax .eq. 3) then
1111 : call HCO_Export_Pbuf_CAM3D(HcoConfig%ModelSpc(spcID)%SpcName, spcID, zeroFldCAM_3D)
1112 0 : elseif(HcoConfig%ModelSpc(spcID)%DimMax .eq. 2) then
1113 : call HCO_Export_Pbuf_CAM2D(HcoConfig%ModelSpc(spcID)%SpcName, spcID, zeroFldCAM_2D)
1114 : else
1115 0 : ASSERT_(.false.)
1116 : endif
1117 : enddo
1118 :
1119 0 : end subroutine HCOI_Initialize_Pbuf
1120 : !EOC
1121 : !------------------------------------------------------------------------------
1122 : ! Harmonized Emissions Component (HEMCO) !
1123 : !------------------------------------------------------------------------------
1124 : !BOP
1125 : !
1126 : ! !IROUTINE: HCOI_Chunk_Run
1127 : !
1128 : ! !DESCRIPTION: HCOI\_Chunk\_Run is the run method for the CAM interface to HEMCO.
1129 : !\\
1130 : !\\
1131 : ! !INTERFACE:
1132 : !
1133 0 : subroutine HCOI_Chunk_Run(cam_in, phys_state, pbuf2d, phase)
1134 : !
1135 : ! !USES:
1136 : !
1137 : ! Type descriptors
1138 : use camsrfexch, only: cam_in_t
1139 : use physics_types, only: physics_state
1140 : use physics_buffer, only: physics_buffer_desc
1141 :
1142 : ! Physics grid
1143 : use phys_grid, only: get_ncols_p
1144 :
1145 : ! CAM physics buffer (some fields are here and some are in phys state)
1146 : use physics_buffer, only: pbuf_get_chunk, pbuf_get_field
1147 : use physics_buffer, only: pbuf_get_index
1148 :
1149 : ! Output and mpi
1150 : use cam_logfile, only: iulog
1151 : use spmd_utils, only: masterproc, mpicom, masterprocid, iam
1152 :
1153 : ! Performance timers
1154 : use perf_mod, only: t_startf, t_stopf
1155 :
1156 : ! ESMF
1157 : use ESMF, only: ESMF_GridCompRun
1158 :
1159 : !
1160 : ! !INPUT PARAMETERS:
1161 : !
1162 : type(cam_in_t), intent(inout) :: cam_in(begchunk:endchunk)
1163 : type(physics_state), intent(inout) :: phys_state(begchunk:endchunk)
1164 : type(physics_buffer_desc), pointer :: pbuf2d(:,:)
1165 : integer, intent(in) :: phase ! 1, 2
1166 : !
1167 : ! !REVISION HISTORY:
1168 : ! 06 Feb 2020 - H.P. Lin - Initial version
1169 : !EOP
1170 : !------------------------------------------------------------------------------
1171 : !BOC
1172 : !
1173 : ! !LOCAL VARIABLES:
1174 : !
1175 : character(len=*), parameter :: subname = 'HCOI_Chunk_Run'
1176 : integer :: RC ! Return code
1177 :
1178 : logical, save :: FIRST = .true.
1179 :
1180 0 : call t_startf('HCOI_Chunk_Run')
1181 :
1182 0 : if(masterproc) then
1183 0 : write(iulog,*) "HEMCO_CESM: Running HCOI_Chunk_Run phase", phase
1184 : endif
1185 :
1186 : ! We only run the gridded components on Phase 2 per recommendations
1187 : ! from Steve, but this can be easily extended.
1188 : !
1189 : ! In edyn_grid_comp, the ionosphere interface runs on run1 and run2
1190 : ! and uses a global variable to control the gridded component's
1191 : ! run stage. This is not needed for HEMCO right now but we can always
1192 : ! implement this in the future.
1193 : !
1194 : ! HEMCO also has two stages, but the distinction is not necessary
1195 : ! in the CAM interface. For more information, look at the actual
1196 : ! run routine in the gridded component HCO_GC_Run.
1197 : ! (hplin, 2/6/20)
1198 0 : if(phase == 2) then
1199 : ! Only need to do this once to save time.
1200 : ! reset all the physics buffer contents
1201 : ! to prevent trash data being read by other components.
1202 : ! (hplin, 12/15/20)
1203 0 : if(FIRST) then
1204 :
1205 : ! Pass the pbuf to the hco_cam_exports component so she has it...
1206 0 : hco_pbuf2d => pbuf2d
1207 :
1208 0 : call HCOI_Initialize_Pbuf()
1209 :
1210 : ! No longer first call
1211 0 : FIRST = .false.
1212 :
1213 : endif
1214 :
1215 : ! Pass the pbuf to the hco_cam_exports component so she has it...
1216 : ! hco_pbuf2d => pbuf2d
1217 :
1218 : ! Set fields from CAM state before run
1219 0 : call t_startf('HCO_CAM_GetBefore_HCOI')
1220 : call CAM_GetBefore_HCOI(cam_in, phys_state, pbuf2d, phase, &
1221 0 : HcoState, ExtState)
1222 0 : call t_stopf('HCO_CAM_GetBefore_HCOI')
1223 :
1224 : ! Run the gridded component.
1225 0 : call t_startf('HCO_GridCompRun')
1226 0 : call ESMF_GridCompRun(HCO_GridComp, rc=RC)!importState=HCO_GridCompState, &
1227 : !exportState=HCO_GridCompState, &
1228 : !rc=RC)
1229 0 : call t_stopf('HCO_GridCompRun')
1230 :
1231 0 : ASSERT_(RC==ESMF_SUCCESS)
1232 : endif
1233 :
1234 0 : if(masterproc) then
1235 0 : write(iulog,*) "HEMCO_CESM: Leaving HCOI_Chunk_Run"
1236 : endif
1237 :
1238 0 : call t_stopf('HCOI_Chunk_Run')
1239 0 : end subroutine HCOI_Chunk_Run
1240 : !EOC
1241 : !------------------------------------------------------------------------------
1242 : ! Harmonized Emissions Component (HEMCO) !
1243 : !------------------------------------------------------------------------------
1244 : !BOP
1245 : !
1246 : ! !IROUTINE: HCOI_Chunk_Final
1247 : !
1248 : ! !DESCRIPTION: HCOI\_Chunk\_Final cleans up the CAM interface to HEMCO.
1249 : !\\
1250 : !\\
1251 : ! !INTERFACE:
1252 : !
1253 0 : subroutine HCOI_Chunk_Final()
1254 : ! Stub...
1255 0 : end subroutine HCOI_Chunk_Final
1256 : !-----------------------------------------------------------------------
1257 : ! H E M C O W R A P P E R G R I D C O M P !
1258 : !-----------------------------------------------------------------------
1259 : ! Below code includes internal routines used to wrap a ESMF gridded !
1260 : ! component around the HEMCO interface, so ESMF can handle all the !
1261 : ! interaction with the physics mesh. !
1262 : ! !
1263 : ! This is largely based on edyn_grid_comp.F90 from ionosphere/waccmx !
1264 : ! Thanks to Steve Goldhaber for the example !
1265 : ! !
1266 : ! (hplin, 1/31/20) !
1267 : !-----------------------------------------------------------------------
1268 : !EOC
1269 : !------------------------------------------------------------------------------
1270 : ! Harmonized Emissions Component (HEMCO) !
1271 : !------------------------------------------------------------------------------
1272 : !BOP
1273 : !
1274 : ! !IROUTINE: HCO_GC_Run
1275 : !
1276 : ! !DESCRIPTION: HCO\_GC\_Run is an internal method in the HEMCO gridded component
1277 : ! in CAM. It runs the main routines of HEMCO and is called by ESMF.
1278 : ! The routines inside the GridComp operate on the HEMCO grid and are responsible
1279 : ! to run regridding routines to return data into the physics mesh.
1280 : ! In short, code goes here.
1281 : !\\
1282 : !\\
1283 : ! !INTERFACE:
1284 : !
1285 0 : subroutine HCO_GC_Run(GC, IMPORT, EXPORT, Clock, RC)
1286 : !
1287 : ! !USES:
1288 : !
1289 : use cam_logfile, only: iulog
1290 : use spmd_utils, only: masterproc, iam
1291 :
1292 : ! Performance timers
1293 : use perf_mod, only: t_startf, t_stopf
1294 :
1295 : ! HEMCO
1296 : use HCO_Interface_Common, only: GetHcoVal, GetHcoDiagn
1297 : use HCO_Clock_Mod, only: HcoClock_Set, HcoClock_Get
1298 : use HCO_Clock_Mod, only: HcoClock_EmissionsDone
1299 : use HCO_Diagn_Mod, only: HcoDiagn_AutoUpdate
1300 : use HCO_Driver_Mod, only: HCO_Run
1301 : use HCO_EmisList_Mod, only: Hco_GetPtr
1302 : use HCO_Calc_Mod, only: Hco_EvalFld
1303 : use HCO_FluxArr_Mod, only: HCO_FluxArrReset
1304 : use HCO_GeoTools_Mod, only: HCO_CalcVertGrid, HCO_SetPBLm
1305 :
1306 : use HCO_State_Mod, only: HCO_GetHcoId
1307 :
1308 : ! HEMCO Extensions
1309 : use HCOX_Driver_Mod, only: HCOX_Run
1310 :
1311 : ! Physical constants
1312 : use physconst, only: mwdry
1313 :
1314 : ! Necessary imported properties for physics calculations
1315 : use hco_cam_convert_state_mod, only: State_HCO_PSFC, State_HCO_TK, State_HCO_PBLH, State_CAM_chmDMS
1316 : use hco_cam_convert_state_mod, only: State_CAM_chmACET, State_CAM_chmALD2, State_CAM_chmMOH, State_CAM_chmMENO3, State_CAM_DELP_DRYs, State_CAM_chmETNO3
1317 :
1318 : !
1319 : ! !INPUT/OUTPUT PARAMETERS:
1320 : !
1321 : type(ESMF_GridComp) :: GC
1322 : type(ESMF_State) :: IMPORT
1323 : type(ESMF_State) :: EXPORT
1324 : type(ESMF_Clock) :: Clock
1325 : integer, intent(out) :: RC
1326 : !
1327 : ! !REMARKS:
1328 : ! All the input/output parameters here are dummies.
1329 : !
1330 : ! !REVISION HISTORY:
1331 : ! 06 Feb 2020 - H.P. Lin - Initial version
1332 : ! 09 Mar 2023 - H.P. Lin - Allow for FixYY in HEMCO clock for climo runs
1333 : !EOP
1334 : !------------------------------------------------------------------------------
1335 : !BOC
1336 : !
1337 : ! !LOCAL VARIABLES:
1338 : !
1339 : character(len=*), parameter :: subname = 'HCO_GC_Run'
1340 :
1341 : ! Parameters
1342 : real(r8), parameter :: G0_100 = 100.e+0_r8 / 9.80665e+0_r8
1343 :
1344 : integer :: I, J, K
1345 : integer :: HI, HJ, HL
1346 :
1347 : ! Temporaries for exports
1348 : real(ESMF_KIND_R8) :: TMP
1349 : logical :: FND
1350 : character(len=128) :: exportName, exportNameTmp
1351 : integer :: spcID, N
1352 :
1353 : ! For grabbing data from HEMCO Ptrs (uses HEMCO single-precision)
1354 0 : real(sp), pointer :: Ptr2D(:,:)
1355 : real(sp), pointer :: Ptr3D(:,:,:)
1356 :
1357 : ! Temporaries used for export
1358 0 : real(ESMF_KIND_R8) :: exportFldHco(my_IS:my_IE, my_JS:my_JE, 1:LM)
1359 0 : real(ESMF_KIND_R8) :: exportFldCAM(1:LM, 1:my_CE)
1360 : real(ESMF_KIND_R8) :: scratchFldCAM(1:LM, 1:my_CE)
1361 : real(ESMF_KIND_R8) :: scratchFldCAM2(1:my_CE)
1362 :
1363 : ! Temporaries used for export (2-D data)
1364 0 : real(ESMF_KIND_R8) :: exportFldHco2(my_IS:my_IE, my_JS:my_JE)
1365 0 : real(ESMF_KIND_R8) :: exportFldCAM2(1:my_CE)
1366 0 : real(ESMF_KIND_R8) :: exportFldHcoDep(my_IS:my_IE, my_JS:my_JE)
1367 0 : real(ESMF_KIND_R8) :: exportFldCAMDep(1:my_CE)
1368 :
1369 : ! For debug dummies
1370 0 : real(ESMF_KIND_R8) :: dummy_0_CAM(1:LM, 1:my_CE)
1371 : real(ESMF_KIND_R8) :: dummy_1(my_IS:my_IE, my_JS:my_JE, 1:LM)
1372 0 : real(ESMF_KIND_R8) :: dummy_1_CAM(1:LM, 1:my_CE)
1373 : real(ESMF_KIND_R8) :: dummy_2(my_IS:my_IE, my_JS:my_JE)
1374 :
1375 : ! Timing properties
1376 : integer :: year, month, day, tod
1377 : integer :: hour, minute, second
1378 : integer :: prev_day, prev_s, now_day, now_s
1379 : integer :: tmp_currTOD
1380 :
1381 : ! HEMCO vertical grid property pointers
1382 : ! NOTE: Hco_CalcVertGrid expects pointer-based arguments, so we must
1383 : ! make PEDGE be a pointer and allocate/deallocate it on each call.
1384 0 : real(hp), pointer :: BXHEIGHT(:,:,:) ! Grid box height [m ]
1385 0 : real(hp), pointer :: PEDGE (:,:,:) ! Pressure @ lvl edges [Pa]
1386 0 : real(hp), pointer :: ZSFC (:,: ) ! Surface geopotential [m ]
1387 :
1388 :
1389 : real(hp), pointer :: PBLM (:,: ) ! PBL height [m ]
1390 0 : real(hp), pointer :: PSFC (:,: ) ! Surface pressure [Pa]
1391 0 : real(hp), pointer :: TK (:,:,:) ! Temperature [K ]
1392 :
1393 : ! HEMCO return code
1394 : integer :: HMRC
1395 :
1396 : logical, save :: FIRST = .True.
1397 : logical :: doExport = .False.
1398 : integer, save :: nCalls = 0
1399 :
1400 : ! Assume success
1401 0 : RC = ESMF_SUCCESS
1402 0 : HMRC = HCO_SUCCESS
1403 :
1404 0 : nCalls = nCalls + 1
1405 :
1406 : !-----------------------------------------------------------------------
1407 : ! Update regridding file handles as necessary
1408 : !-----------------------------------------------------------------------
1409 0 : call HCO_Grid_UpdateRegrid(RC=RC)
1410 0 : ASSERT_(RC==ESMF_SUCCESS)
1411 :
1412 : !if(masterproc) then
1413 : ! write(iulog,*) "HEMCO_CESM: Reload (if necessary) of HEMCO Regrid descriptors"
1414 : !endif
1415 :
1416 : !-----------------------------------------------------------------------
1417 : ! Allow for year forcing in climatological runs. (hplin, 3/9/23)
1418 : ! This is set if HcoFixYY is set in this module and is > 0
1419 : !
1420 : ! This is set in the run routine because HEMCO clock is initialized at
1421 : ! HCO_INIT -> HcoClock_Init, so it was not available until very late in
1422 : ! the Init phase. But maybe it could be moved up as well.
1423 : !-----------------------------------------------------------------------
1424 0 : if(HcoFixYY .gt. 0) then
1425 : ! Override the HEMCO clock FixYY property
1426 0 : HcoState%Clock%FixYY = HcoFixYY
1427 : endif
1428 :
1429 : !-----------------------------------------------------------------------
1430 : ! Get time properties
1431 : !-----------------------------------------------------------------------
1432 0 : call get_prev_time(prev_day, prev_s)
1433 0 : call get_curr_time(now_day, now_s)
1434 0 : call get_curr_date(year, month, day, tod)
1435 :
1436 : !if(masterproc) then
1437 : ! write(iulog,*) "hco year,month,day,tod", year, month, day, tod
1438 : ! write(iulog,*) "hco prev_day, prev_s", prev_day, prev_s
1439 : ! write(iulog,*) "hco now_day, now_s", now_day, now_s
1440 : !endif
1441 : ! 2005 1 1 1800 | 0 0 | 0 1800
1442 : ! 2005 1 1 3600 | 0 1800 | 0 3600
1443 : ! 2005 1 1 5400 | 0 3600 | 0 5400
1444 : ! ...
1445 :
1446 : ! Check if we have run HEMCO for this time step already. If yes can exit
1447 0 : if(last_HCO_day * 86400.0 + last_HCO_second .ge. now_day * 86400.0 + now_s) then
1448 : ! The first timestep should not be skipped. A fix is made during initialization (hplin, 6/11/24)
1449 0 : if(masterproc) then
1450 0 : write(iulog,*) "HEMCO_CESM: HEMCO already ran for this time, check timestep mgr (now day, s; last day, s)", now_day, now_s, last_HCO_day, last_HCO_second
1451 : endif
1452 :
1453 : return
1454 : endif
1455 :
1456 : ! Timestep no longer needs to be updated by diff calculation because it can be
1457 : ! reliably retrieved from time_manager stepsize. (hplin, 6/11/24)
1458 :
1459 : ! Compute hour, minute, second (borrowed from tfritz)
1460 0 : tmp_currTOD = tod
1461 0 : hour = 0
1462 0 : minute = 0
1463 0 : do while(tmp_currTOD >= 3600)
1464 0 : tmp_currTOD = tmp_currTOD - 3600
1465 0 : hour = hour + 1
1466 : enddo
1467 :
1468 0 : do while(tmp_currTOD >= 60)
1469 0 : tmp_currTOD = tmp_currTOD - 60
1470 0 : minute = minute + 1
1471 : enddo
1472 0 : second = tmp_currTOD
1473 :
1474 : ! Update HEMCO clock
1475 : ! using HcoClock_Set and not common SetHcoTime because we don't have DOY
1476 : ! and we want HEMCO to do the math for us. oh well
1477 0 : if(masterproc) then
1478 0 : write(iulog,'(A,I4,A,I2.2,A,I2.2,A,I4.4)') "HEMCO_CESM: Internally HEMCO was at (Sim H:M:S:nStep) ", HcoState%Clock%SimHour, ":", HcoState%Clock%SimMin, ":", HcoState%Clock%SimSec, " x", HcoState%Clock%nSteps
1479 0 : write(iulog,'(A,I4,A,I2.2,A,I2.2,A,I2.2,A,I2.2,A,I2.2)') "HEMCO_CESM: Updating HEMCO clock to set (Y-M-D H:I:S) ", year, "-", month, "-", day, " ", hour, ":", minute, ":", second
1480 : endif
1481 :
1482 : call HCOClock_Set(HcoState, year, month, day, &
1483 0 : hour, minute, second, IsEmisTime=.true., RC=HMRC)
1484 0 : ASSERT_(HMRC==HCO_SUCCESS)
1485 :
1486 : !-----------------------------------------------------------------------
1487 : ! Continue setting up HEMCO
1488 : !-----------------------------------------------------------------------
1489 :
1490 : ! Reset all emission and deposition values.
1491 0 : call HCO_FluxArrReset(HcoState, HMRC)
1492 0 : ASSERT_(HMRC==HCO_SUCCESS)
1493 :
1494 : !-----------------------------------------------------------------------
1495 : ! Regrid necessary meteorological quantities (Phase 1)
1496 : ! Computes the absolute minimum (PSFC and TK) necessary for HEMCO
1497 : ! to define its grid.
1498 : !-----------------------------------------------------------------------
1499 0 : call CAM_RegridSet_HCOI(HcoState, ExtState, Phase=1)
1500 :
1501 0 : if(masterproc .and. nCalls < 10) then
1502 0 : write(iulog,*) "HEMCO_CESM: Finished regridding CAM met fields to HEMCO (1)"
1503 : endif
1504 :
1505 : !-----------------------------------------------------------------------
1506 : ! Get grid properties
1507 : !-----------------------------------------------------------------------
1508 : ! Calculate HEMCO vertical grid properties, e.g. PEDGE,
1509 : ! then PHIS, BXHEIGHT, T, ..., from GridEdge_Set
1510 : !
1511 : ! The below conversions mostly borrowed from tfritz's CESM2-GC.
1512 : ! HEMCO CalcVertGrid can approximate all quantities. We provide them with
1513 : ! PSFC (surface pressure), TK (temperature)
1514 : ! in the form of allocated pointers. The rest can be inferred from Ap, Bp
1515 0 : PSFC => State_HCO_PSFC
1516 0 : TK => State_HCO_TK
1517 :
1518 0 : call HCO_CalcVertGrid(HcoState, PSFC, ZSFC, TK, BXHEIGHT, PEDGE, HMRC)
1519 0 : ASSERT_(HMRC==HCO_SUCCESS)
1520 :
1521 : ! Pass boundary layer height to HEMCO (PBLm = PBL mixing height) [m]
1522 : call HCO_SetPBLm(HcoState, PBLM=State_HCO_PBLH, &
1523 : DefVal=1000.0_hp, & ! default value
1524 0 : RC=HMRC)
1525 0 : ASSERT_(HMRC==HCO_SUCCESS)
1526 :
1527 : !-----------------------------------------------------------------------
1528 : ! Regrid necessary meteorological quantities (Phase 2)
1529 : ! Has to be below grid properties because vertical grid needs to be defined
1530 : ! for quantities to be computed!
1531 : !-----------------------------------------------------------------------
1532 0 : call CAM_RegridSet_HCOI(HcoState, ExtState, Phase=2)
1533 :
1534 0 : if(masterproc .and. nCalls < 10) then
1535 0 : write(iulog,*) "HEMCO_CESM: Finished regridding CAM met fields to HEMCO (2)"
1536 :
1537 : ! As a test... maybe we also need to flip in the vertical
1538 : ! write(iulog,*) State_HCO_TK(1,1,:)
1539 : ! write(iulog,*) "PSFC(1:2,:)"
1540 : ! write(iulog,*) State_HCO_PSFC(1:2,:)
1541 :
1542 : !write(iulog,*) "cam state%ps dump"
1543 : !write(iulog,*) State_CAM_ps
1544 :
1545 : ! TK: 288 283 277 271 266 261 ... 250 251 252
1546 : ! Seems like the vertical is OK for now
1547 : endif
1548 :
1549 : !-----------------------------------------------------------------------
1550 : ! Set HEMCO options
1551 : !-----------------------------------------------------------------------
1552 : ! Range of species and emission categories.
1553 : ! Set Extension number ExtNr to 0, indicating that the core
1554 : ! module shall be executed.
1555 0 : HcoState%Options%SpcMin = 1
1556 0 : HcoState%Options%SpcMax = -1
1557 0 : HcoState%Options%CatMin = 1
1558 0 : HcoState%Options%CatMax = -1
1559 0 : HcoState%Options%ExtNr = 0
1560 :
1561 : ! Use temporary array?
1562 0 : HcoState%Options%FillBuffer = .FALSE.
1563 :
1564 : !-----------------------------------------------------------------------
1565 : ! Run HEMCO!
1566 : !-----------------------------------------------------------------------
1567 :
1568 0 : call t_startf('HCO_HCOX_Run')
1569 :
1570 : ! Run HCO core module
1571 : ! Pass phase as argument. Phase 1 will update the emissions list,
1572 : ! phase 2 will calculate the emissions. Emissions will be written into
1573 : ! the corresponding flux arrays in HcoState.
1574 : !
1575 : ! FIXME: hplin - setting false as last timestep of simulation. maybe see
1576 : ! if we can figure out from CAM if we are at run end and set to true
1577 0 : call HCO_Run( HcoState, 1, HMRC, IsEndStep=.false. )
1578 0 : if(masterproc .and. HMRC /= HCO_SUCCESS) then
1579 0 : write(iulog,*) "******************************************"
1580 0 : write(iulog,*) "HEMCO_CESM: HCO_Run Phase 1 has failed! "
1581 0 : write(iulog,*) "THIS ERROR ORIGINATED WITHIN HEMCO! "
1582 0 : write(iulog,*) "A critical component in HEMCO failed to run."
1583 0 : write(iulog,*) "This may be due to misconfiguration, or a bug."
1584 0 : write(iulog,*) "Please refer to the HEMCO.log log file in your"
1585 0 : write(iulog,*) "case run directory or as configured in HEMCO_Config.rc"
1586 0 : write(iulog,*) "for more information."
1587 0 : write(iulog,*) "******************************************"
1588 : endif
1589 0 : ASSERT_(HMRC==HCO_SUCCESS)
1590 :
1591 0 : if(masterproc .and. nCalls < 10) write(iulog,*) "HEMCO_CESM: HCO_Run Phase 1"
1592 :
1593 0 : call HCO_Run( HcoState, 2, HMRC, IsEndStep=.false. )
1594 0 : if(masterproc .and. HMRC /= HCO_SUCCESS) then
1595 0 : write(iulog,*) "******************************************"
1596 0 : write(iulog,*) "HEMCO_CESM: HCO_Run Phase 2 has failed! "
1597 0 : write(iulog,*) "THIS ERROR ORIGINATED WITHIN HEMCO! "
1598 0 : write(iulog,*) "A critical component in HEMCO failed to run."
1599 0 : write(iulog,*) "This may be due to misconfiguration, or a bug."
1600 0 : write(iulog,*) "Please refer to the HEMCO.log log file in your"
1601 0 : write(iulog,*) "case run directory or as configured in HEMCO_Config.rc"
1602 0 : write(iulog,*) "for more information."
1603 0 : write(iulog,*) "******************************************"
1604 : endif
1605 0 : ASSERT_(HMRC==HCO_SUCCESS)
1606 :
1607 0 : if(masterproc .and. nCalls < 10) write(iulog,*) "HEMCO_CESM: HCO_Run Phase 2"
1608 :
1609 : !-----------------------------------------------------------------------
1610 : ! Run HEMCO Extensions!
1611 : !-----------------------------------------------------------------------
1612 0 : call HCOX_Run(HcoState, ExtState, HMRC)
1613 0 : if(masterproc .and. HMRC /= HCO_SUCCESS) then
1614 0 : write(iulog,*) "******************************************"
1615 0 : write(iulog,*) "HEMCO_CESM: HCOX_Run (extensions) has failed!"
1616 0 : write(iulog,*) "THIS ERROR ORIGINATED WITHIN HEMCO!"
1617 0 : write(iulog,*) "A critical component in HEMCO failed to run."
1618 0 : write(iulog,*) "This may be due to misconfiguration, or a bug."
1619 0 : write(iulog,*) "Please refer to the HEMCO.log log file in your"
1620 0 : write(iulog,*) "case run directory or as configured in HEMCO_Config.rc"
1621 0 : write(iulog,*) "for more information."
1622 0 : write(iulog,*) "******************************************"
1623 : endif
1624 0 : ASSERT_(HMRC==HCO_SUCCESS)
1625 :
1626 0 : if(masterproc .and. nCalls < 10) write(iulog,*) "HEMCO_CESM: HCOX_Run"
1627 :
1628 0 : call t_stopf('HCO_HCOX_Run')
1629 :
1630 : !-----------------------------------------------------------------------
1631 : ! Update "autofill" diagnostics.
1632 : ! Update all 'AutoFill' diagnostics. This makes sure that all
1633 : ! diagnostics fields with the 'AutoFill' flag are up-to-date. The
1634 : ! AutoFill flag is specified when creating a diagnostics container
1635 : ! (Diagn_Create).
1636 : !-----------------------------------------------------------------------
1637 0 : call HcoDiagn_AutoUpdate(HcoState, HMRC)
1638 0 : ASSERT_(HMRC==HCO_SUCCESS)
1639 :
1640 : !if(masterproc .and. nCalls < 10) write(iulog,*) "HEMCO_CESM: HcoDiagn_AutoUpdate"
1641 :
1642 : !-----------------------------------------------------------------------
1643 : ! Tell HEMCO we are done for this timestep...
1644 : !-----------------------------------------------------------------------
1645 0 : call HcoClock_EmissionsDone(HcoState%Clock, HMRC)
1646 0 : ASSERT_(HMRC==HCO_SUCCESS)
1647 :
1648 : !if(masterproc .and. nCalls < 10) write(iulog,*) "HEMCO_CESM: HcoClock_EmissionsDone"
1649 :
1650 : !-----------------------------------------------------------------------
1651 : ! Do some testing and write emissions to the tape
1652 : !-----------------------------------------------------------------------
1653 :
1654 : ! HCO Index boundaries
1655 0 : HI = my_IE - my_IS + 1
1656 0 : HJ = my_JE - my_JS + 1
1657 0 : HL = LM
1658 :
1659 : ! For each species...
1660 0 : do spcID = 1, HcoConfig%nModelSpc
1661 :
1662 : ! TODO: Eventually convert aerosol number emissions from mass fluxes
1663 : ! directly rather than using scale factors for num_ax (1/12/23, hplin)
1664 :
1665 : ! Build history / pbuf field name (HCO_NO, HCO_CO, etc.)
1666 0 : exportName = 'HCO_' // trim(HcoConfig%ModelSpc(spcID)%SpcName)
1667 0 : doExport = (FIRST .or. associated(HcoState%Spc(spcID)%Emis%Val))
1668 : ! if(masterproc) write(iulog,*) "HEMCO_CESM: Begin exporting " // trim(exportName)
1669 :
1670 : ! Get HEMCO emissions flux [kg/m2/s].
1671 : ! For performance optimization ... tap into HEMCO structure directly (ugly ugly)
1672 : ! No need to flip vertical here. The regridder will do it for us
1673 0 : if(associated(HcoState%Spc(spcID)%Emis%Val)) then
1674 0 : if(HcoConfig%ModelSpc(spcID)%DimMax .eq. 3) then
1675 : ! Zero out quantities first
1676 0 : exportFldHco(:,:,:) = 0.0_r8
1677 0 : exportFldCAM(:,:) = 0.0_r8
1678 :
1679 : ! Retrieve flux from HEMCO...
1680 0 : exportFldHco(my_IS:my_IE,my_JS:my_JE,1:LM) = HcoState%Spc(spcID)%Emis%Val(1:HI,1:HJ,1:LM)
1681 :
1682 : ! Regrid exportFldHco to CAM grid...
1683 0 : call HCO_Grid_HCO2CAM_3D(exportFldHco, exportFldCAM)
1684 :
1685 : ! Debug only: Output data for debug and comparing against logs
1686 : ! if(masterproc) write(iulog, *) "HEMCO_CESM debug ", trim(exportName), " HCO min max sum ", minval(exportFldHco(my_IS:my_IE,my_JS:my_JE,1:LM)), maxval(exportFldHco(my_IS:my_IE,my_JS:my_JE,1:LM)), sum(exportFldHco(my_IS:my_IE,my_JS:my_JE,1:LM))
1687 : ! if(masterproc) write(iulog, *) "HEMCO_CESM debug ", trim(exportName), " CAM min max sum ", minval(exportFldCAM), maxval(exportFldCAM), sum(exportFldCAM)
1688 0 : elseif(HcoConfig%ModelSpc(spcID)%DimMax .eq. 2) then
1689 : ! Zero out quantities first
1690 0 : exportFldHco2(:,:) = 0.0_r8
1691 0 : exportFldCAM2(:) = 0.0_r8
1692 :
1693 : ! Retrieve flux from HEMCO...
1694 : ! Only surface emissions are supported here. Note, HEMCO emissions are with 1 = surface and LM = TOA. Use index 1. (hplin, 1/12/23)
1695 0 : exportFldHco2(my_IS:my_IE,my_JS:my_JE) = HcoState%Spc(spcID)%Emis%Val(1:HI,1:HJ,1)
1696 :
1697 : ! Regrid exportFldHco to CAM grid...
1698 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
1699 :
1700 : ! Debug only: Output data for debug and comparing against logs
1701 : ! if(masterproc) write(iulog, *) "HEMCO_CESM debug ", trim(exportName), " HCO min max sum ", minval(exportFldHco2(my_IS:my_IE,my_JS:my_JE)), maxval(exportFldHco2(my_IS:my_IE,my_JS:my_JE)), sum(exportFldHco2(my_IS:my_IE,my_JS:my_JE))
1702 : ! if(masterproc) write(iulog, *) "HEMCO_CESM debug ", trim(exportName), " CAM min max sum ", minval(exportFldCAM2), maxval(exportFldCAM2), sum(exportFldCAM2)
1703 : else
1704 0 : ASSERT_(.false.)
1705 : endif
1706 :
1707 : !if(masterproc) write(iulog,*) "HEMCO_CESM: Retrieved from HCO " // trim(exportName)
1708 : else
1709 : ! No emission value. No need to run regrid, instead populate with zeros as needed
1710 : ! Why not populate at top, you ask? Because zeroing out arrays is expensive, and
1711 : ! we do not want to be doing twice the work.
1712 0 : if(HcoConfig%ModelSpc(spcID)%DimMax .eq. 3) then
1713 0 : exportFldCAM(:,:) = 0.0_r8
1714 0 : elseif(HcoConfig%ModelSpc(spcID)%DimMax .eq. 2) then
1715 0 : exportFldCAM2(:) = 0.0_r8
1716 : else
1717 0 : ASSERT_(.false.)
1718 : endif
1719 : endif
1720 :
1721 : ! Handle deposition flux from deposition velocity [1/s]
1722 : ! This can be performed on the CAM grid. (hplin, 5/7/21)
1723 : ! GEOS-Chem: (from v/v dry)
1724 : ! Step 1)
1725 : ! dflx(I,J,NA) = dflx(I,J,NA) &
1726 : ! + ( dep * spc(I,J,NA) / (AIRMW / ThisSpc%MW_g) )
1727 : ! for kg/kg dry, no conversion is needed:
1728 : ! Step 1a) dflx = dflx + dep * spc
1729 : !
1730 : ! Step 2) Convert to 1/s
1731 : ! dflx(I,J,:) = dflx(I,J,:) * State_Met%AD(I,J,1) &
1732 : ! / State_Grid%Area_M2(I,J)
1733 : !
1734 : ! Note that, AD is actually DELP_DRY * G0_100 * AREA_M2, thus the final expression is
1735 : ! just multiplied by DELP_DRY * G0_100, unit: kg/m2 (delp_dry is hPa, g0_100 is 100 Pa/hPa * s2/m --> unit = Pa*m/s2 = kg/m/s2*s2/m = kg/m2)
1736 : ! Multiplied by 1/s, this gives kg/m2/s
1737 : !
1738 : ! We retrieve the concentration flux read from the convert state module
1739 : ! (on the CAM grid) and loop through it to apply deposition fluxes.
1740 0 : if(associated(HcoState%Spc(spcID)%Depv%Val)) then
1741 : ! Check if species is available for deposition (hard-coded)
1742 : ! FIXME: hplin 5/7/21
1743 0 : if(trim(HcoConfig%ModelSpc(spcID)%SpcName) == "DMS" .or. &
1744 0 : trim(HcoConfig%ModelSpc(spcID)%SpcName) == "ACET" .or. &
1745 0 : trim(HcoConfig%ModelSpc(spcID)%SpcName) == "CH3COCH3" .or. &
1746 0 : trim(HcoConfig%ModelSpc(spcID)%SpcName) == "ALD2" .or. &
1747 0 : trim(HcoConfig%ModelSpc(spcID)%SpcName) == "CH3CHO" .or. &
1748 0 : trim(HcoConfig%ModelSpc(spcID)%SpcName) == "MENO3" .or. &
1749 0 : trim(HcoConfig%ModelSpc(spcID)%SpcName) == "ETNO3" .or. &
1750 0 : trim(HcoConfig%ModelSpc(spcID)%SpcName) == "MOH" .or. &
1751 0 : trim(HcoConfig%ModelSpc(spcID)%SpcName) == "CH3OH") then
1752 :
1753 : ! Clear data
1754 0 : exportFldCAMDep(:) = 0.0_r8
1755 :
1756 : ! Regrid deposition flux HCO to CAM
1757 0 : exportFldHcoDep(my_IS:my_IE,my_JS:my_JE) = HcoState%Spc(spcID)%Depv%Val(1:HI,1:HJ)
1758 0 : call HCO_Grid_HCO2CAM_2D(exportFldHcoDep, exportFldCAMDep)
1759 :
1760 : ! dbg:
1761 : ! if(trim(HcoConfig%ModelSpc(spcID)%SpcName) == "DMS") then
1762 : ! dummy_2(:,:) = exportFldHco2(:,:)
1763 : ! endif
1764 : endif
1765 :
1766 : ! Perform handling: Note species-specific State_CAM_* data
1767 : ! Note handling is for surface (idx LM for CAM inverted-atm)
1768 0 : if(trim(HcoConfig%ModelSpc(spcID)%SpcName) == "DMS") then
1769 0 : if(HcoConfig%ModelSpc(spcID)%DimMax .eq. 3) then
1770 0 : exportFldCAM(LM,:) = exportFldCAM(LM,:) - exportFldCAMDep(:) * State_CAM_chmDMS(:) * State_CAM_DELP_DRYs(:) * G0_100
1771 0 : elseif(HcoConfig%ModelSpc(spcID)%DimMax .eq. 2) then
1772 0 : exportFldCAM2(:) = exportFldCAM2(:) - exportFldCAMDep(:) * State_CAM_chmDMS(:) * State_CAM_DELP_DRYs(:) * G0_100
1773 : else
1774 0 : ASSERT_(.false.)
1775 : endif
1776 : elseif( &
1777 0 : trim(HcoConfig%ModelSpc(spcID)%SpcName) == "ACET" .or. &
1778 0 : trim(HcoConfig%ModelSpc(spcID)%SpcName) == "CH3COCH3") then
1779 0 : if(HcoConfig%ModelSpc(spcID)%DimMax .eq. 3) then
1780 0 : exportFldCAM(LM,:) = exportFldCAM(LM,:) - exportFldCAMDep(:) * State_CAM_chmACET(:) * State_CAM_DELP_DRYs(:) * G0_100
1781 0 : elseif(HcoConfig%ModelSpc(spcID)%DimMax .eq. 2) then
1782 0 : exportFldCAM2(:) = exportFldCAM2(:) - exportFldCAMDep(:) * State_CAM_chmACET(:) * State_CAM_DELP_DRYs(:) * G0_100
1783 : else
1784 0 : ASSERT_(.false.)
1785 : endif
1786 : elseif( &
1787 0 : trim(HcoConfig%ModelSpc(spcID)%SpcName) == "ALD2" .or. &
1788 0 : trim(HcoConfig%ModelSpc(spcID)%SpcName) == "CH3CHO") then
1789 0 : if(HcoConfig%ModelSpc(spcID)%DimMax .eq. 3) then
1790 0 : exportFldCAM(LM,:) = exportFldCAM(LM,:) - exportFldCAMDep(:) * State_CAM_chmALD2(:) * State_CAM_DELP_DRYs(:) * G0_100
1791 0 : elseif(HcoConfig%ModelSpc(spcID)%DimMax .eq. 2) then
1792 0 : exportFldCAM2(:) = exportFldCAM2(:) - exportFldCAMDep(:) * State_CAM_chmALD2(:) * State_CAM_DELP_DRYs(:) * G0_100
1793 : else
1794 0 : ASSERT_(.false.)
1795 : endif
1796 : elseif( &
1797 0 : trim(HcoConfig%ModelSpc(spcID)%SpcName) == "MOH" .or. &
1798 0 : trim(HcoConfig%ModelSpc(spcID)%SpcName) == "CH3OH") then
1799 0 : if(HcoConfig%ModelSpc(spcID)%DimMax .eq. 3) then
1800 0 : exportFldCAM(LM,:) = exportFldCAM(LM,:) - exportFldCAMDep(:) * State_CAM_chmMOH(:) * State_CAM_DELP_DRYs(:) * G0_100
1801 0 : elseif(HcoConfig%ModelSpc(spcID)%DimMax .eq. 2) then
1802 0 : exportFldCAM2(:) = exportFldCAM2(:) - exportFldCAMDep(:) * State_CAM_chmMOH(:) * State_CAM_DELP_DRYs(:) * G0_100
1803 : else
1804 0 : ASSERT_(.false.)
1805 : endif
1806 0 : elseif(trim(HcoConfig%ModelSpc(spcID)%SpcName) == "MENO3") then
1807 0 : if(HcoConfig%ModelSpc(spcID)%DimMax .eq. 3) then
1808 0 : exportFldCAM(LM,:) = exportFldCAM(LM,:) - exportFldCAMDep(:) * State_CAM_chmMENO3(:) * State_CAM_DELP_DRYs(:) * G0_100
1809 0 : elseif(HcoConfig%ModelSpc(spcID)%DimMax .eq. 2) then
1810 0 : exportFldCAM2(:) = exportFldCAM2(:) - exportFldCAMDep(:) * State_CAM_chmMENO3(:) * State_CAM_DELP_DRYs(:) * G0_100
1811 : else
1812 0 : ASSERT_(.false.)
1813 : endif
1814 0 : elseif(trim(HcoConfig%ModelSpc(spcID)%SpcName) == "ETNO3") then
1815 0 : if(HcoConfig%ModelSpc(spcID)%DimMax .eq. 3) then
1816 0 : exportFldCAM(LM,:) = exportFldCAM(LM,:) - exportFldCAMDep(:) * State_CAM_chmETNO3(:) * State_CAM_DELP_DRYs(:) * G0_100
1817 0 : elseif(HcoConfig%ModelSpc(spcID)%DimMax .eq. 2) then
1818 0 : exportFldCAM2(:) = exportFldCAM2(:) - exportFldCAMDep(:) * State_CAM_chmETNO3(:) * State_CAM_DELP_DRYs(:) * G0_100
1819 : else
1820 0 : ASSERT_(.false.)
1821 : endif
1822 : endif
1823 : endif
1824 :
1825 0 : if(doExport) then
1826 0 : if(HcoConfig%ModelSpc(spcID)%DimMax .eq. 3) then
1827 : ! Write to history on CAM mesh
1828 0 : call HCO_Export_History_CAM3D(exportName, exportFldCAM)
1829 :
1830 : ! Write to physics buffer (pass model name)
1831 0 : call HCO_Export_Pbuf_CAM3D(HcoConfig%ModelSpc(spcID)%SpcName, spcID, exportFldCAM)
1832 0 : elseif(HcoConfig%ModelSpc(spcID)%DimMax .eq. 2) then
1833 : ! Write to history on CAM mesh
1834 0 : call HCO_Export_History_CAM2D(exportName, exportFldCAM2)
1835 :
1836 : ! Write to physics buffer (pass model name)
1837 0 : call HCO_Export_Pbuf_CAM2D(HcoConfig%ModelSpc(spcID)%SpcName, spcID, exportFldCAM2)
1838 : else
1839 0 : ASSERT_(.false.)
1840 : endif
1841 : endif
1842 :
1843 : enddo
1844 :
1845 :
1846 : !-----------------------------------------------------------------------
1847 : ! Update aerosol number emissions with correct parameters
1848 : ! for CAM-chem and CESM2-GC
1849 : !
1850 : ! TODO: Implement later. Now using HEMCO config file method (hplin, 5/7/21)
1851 : !-----------------------------------------------------------------------
1852 : ! call HCO_Calc_Aero_Emis ( ... )
1853 :
1854 : !-----------------------------------------------------------------------
1855 : ! Handle special diagnostics for some extensions
1856 : !-----------------------------------------------------------------------
1857 :
1858 : ! Reset pointers first. Always do this beforehand
1859 0 : Ptr2D => NULL()
1860 :
1861 : ! Eventually save necessary deposition FLUXES from extensions.
1862 0 : if(ExtState%ParaNOx > 0) then
1863 : ! PAR_O3_DEP, PAR_HNO3_DEP
1864 0 : exportName = 'HCO_PAR_O3_DEP'
1865 0 : exportNameTmp = 'PAR_O3_DEP'
1866 : call GetHcoDiagn(HcoState, ExtState, DiagnName='PARANOX_O3_DEPOSITION_FLUX', &
1867 0 : StopIfNotFound=.false., Ptr2D=Ptr2D, RC=HMRC)
1868 :
1869 0 : if(.not. associated(Ptr2D)) then
1870 0 : write(6,*) "hplin debug err: cannot find paranox o3 dep flux"
1871 : endif
1872 :
1873 0 : exportFldHco2(:,:) = 0.0_r8
1874 0 : exportFldCAM2(:) = 0.0_r8
1875 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. associated(Ptr2D)))
1876 0 : if(HMRC == HCO_SUCCESS .and. associated(Ptr2D)) then
1877 0 : exportFldHco2(:,:) = Ptr2D(:,:)
1878 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
1879 : endif
1880 :
1881 0 : if(doExport) then
1882 0 : call HCO_Export_History_CAM2D(exportName, exportFldCAM2)
1883 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
1884 : endif
1885 0 : Ptr2D => NULL()
1886 :
1887 0 : exportName = 'HCO_PAR_HNO3_DEP'
1888 0 : exportNameTmp = 'PAR_HNO3_DEP'
1889 : call GetHcoDiagn(HcoState, ExtState, DiagnName='PARANOX_HNO3_DEPOSITION_FLUX', &
1890 0 : StopIfNotFound=.false., Ptr2D=Ptr2D, RC=HMRC)
1891 :
1892 0 : exportFldHco2(:,:) = 0.0_r8
1893 0 : exportFldCAM2(:) = 0.0_r8
1894 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. associated(Ptr2D)))
1895 0 : if(HMRC == HCO_SUCCESS .and. associated(Ptr2D)) then
1896 0 : exportFldHco2(:,:) = Ptr2D(:,:)
1897 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
1898 : endif
1899 :
1900 0 : if(doExport) then
1901 0 : call HCO_Export_History_CAM2D(exportName, exportFldCAM2)
1902 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
1903 : endif
1904 0 : Ptr2D => NULL()
1905 : endif
1906 :
1907 : !-----------------------------------------------------------------------
1908 : ! Do we need to do additional exports for CESM-GC?
1909 : !-----------------------------------------------------------------------
1910 :
1911 0 : if(chem_is('GEOS-Chem')) then
1912 0 : if(masterproc) write(iulog,*) "HEMCO_CESM: starting exports to GEOS-Chem"
1913 0 : do N = 0, 72
1914 : ! Assume success
1915 0 : HMRC = HCO_SUCCESS
1916 :
1917 : ! LANDTYPExx
1918 0 : write(exportNameTmp, '(a,i2.2)') 'LANDTYPE', N
1919 0 : exportName = 'HCO_' // trim(exportNameTmp)
1920 :
1921 0 : exportFldCAM2(:) = 0.0_r8
1922 :
1923 : ! Grab the pointer if available
1924 0 : call HCO_GetPtr(HcoState, exportNameTmp, Ptr2D, HMRC, FOUND=FND)
1925 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
1926 0 : if(HMRC == HCO_SUCCESS .and. FND) then
1927 0 : exportFldHco2(:,:) = Ptr2D(:,:) ! Have to promote precision
1928 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
1929 : endif
1930 :
1931 0 : if(doExport) then
1932 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
1933 : endif
1934 0 : Ptr2D => NULL()
1935 :
1936 : ! XLAIxx
1937 0 : write(exportNameTmp, '(a,i2.2)') 'XLAI', N
1938 0 : exportName = 'HCO_' // trim(exportNameTmp)
1939 :
1940 0 : exportFldCAM2(:) = 0.0_r8
1941 :
1942 : ! Grab the pointer if available
1943 0 : call HCO_GetPtr(HcoState, exportNameTmp, Ptr2D, HMRC, FOUND=FND)
1944 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
1945 0 : if(HMRC == HCO_SUCCESS .and. FND) then
1946 0 : exportFldHco2(:,:) = Ptr2D(:,:) ! Have to promote precision
1947 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
1948 : endif
1949 :
1950 0 : if(doExport) then
1951 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
1952 : endif
1953 0 : Ptr2D => NULL()
1954 : enddo
1955 :
1956 : ! VMR_CH3CL
1957 0 : write(exportNameTmp, '(a)') 'VMR_CH3CL'
1958 :
1959 0 : exportName = 'HCO_' // trim(exportNameTmp)
1960 0 : exportFldCAM2(:) = 0.0_r8
1961 :
1962 0 : call HCO_EvalFld(HcoState, 'SfcVMR_CH3CL', exportFldHco2, HMRC, FOUND=FND)
1963 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
1964 0 : if(HMRC == HCO_SUCCESS .and. FND) then
1965 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
1966 : endif
1967 0 : if(doExport) then
1968 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
1969 : endif
1970 :
1971 : ! VMR_CH2CL2
1972 0 : write(exportNameTmp, '(a)') 'VMR_CH2CL2'
1973 :
1974 0 : exportName = 'HCO_' // trim(exportNameTmp)
1975 0 : exportFldCAM2(:) = 0.0_r8
1976 :
1977 0 : call HCO_EvalFld(HcoState, 'SfcVMR_CH2CL2', exportFldHco2, HMRC, FOUND=FND)
1978 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
1979 0 : if(HMRC == HCO_SUCCESS .and. FND) then
1980 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
1981 : endif
1982 0 : if(doExport) then
1983 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
1984 : endif
1985 :
1986 : ! VMR_CHCL3
1987 0 : write(exportNameTmp, '(a)') 'VMR_CHCL3'
1988 :
1989 0 : exportName = 'HCO_' // trim(exportNameTmp)
1990 0 : exportFldCAM2(:) = 0.0_r8
1991 :
1992 0 : call HCO_EvalFld(HcoState, 'SfcVMR_CHCL3', exportFldHco2, HMRC, FOUND=FND)
1993 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
1994 0 : if(HMRC == HCO_SUCCESS .and. FND) then
1995 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
1996 : endif
1997 0 : if(doExport) then
1998 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
1999 : endif
2000 :
2001 : ! VMR_CH3BR
2002 0 : write(exportNameTmp, '(a)') 'VMR_CH3BR'
2003 :
2004 0 : exportName = 'HCO_' // trim(exportNameTmp)
2005 0 : exportFldCAM2(:) = 0.0_r8
2006 :
2007 0 : call HCO_EvalFld(HcoState, 'SfcVMR_CH3BR', exportFldHco2, HMRC, FOUND=FND)
2008 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
2009 0 : if(HMRC == HCO_SUCCESS .and. FND) then
2010 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
2011 : endif
2012 0 : if(doExport) then
2013 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
2014 : endif
2015 :
2016 : ! VMR_CCL4
2017 0 : write(exportNameTmp, '(a)') 'VMR_CCL4'
2018 :
2019 0 : exportName = 'HCO_' // trim(exportNameTmp)
2020 0 : exportFldCAM2(:) = 0.0_r8
2021 :
2022 0 : call HCO_EvalFld(HcoState, 'SfcVMR_CCL4', exportFldHco2, HMRC, FOUND=FND)
2023 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
2024 0 : if(HMRC == HCO_SUCCESS .and. FND) then
2025 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
2026 : endif
2027 0 : if(doExport) then
2028 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
2029 : endif
2030 :
2031 : ! VMR_CFC113
2032 0 : write(exportNameTmp, '(a)') 'VMR_CFC113'
2033 :
2034 0 : exportName = 'HCO_' // trim(exportNameTmp)
2035 0 : exportFldCAM2(:) = 0.0_r8
2036 :
2037 0 : call HCO_EvalFld(HcoState, 'SfcVMR_CFC113', exportFldHco2, HMRC, FOUND=FND)
2038 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
2039 0 : if(HMRC == HCO_SUCCESS .and. FND) then
2040 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
2041 : endif
2042 0 : if(doExport) then
2043 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
2044 : endif
2045 :
2046 : ! VMR_CFC114
2047 0 : write(exportNameTmp, '(a)') 'VMR_CFC114'
2048 :
2049 0 : exportName = 'HCO_' // trim(exportNameTmp)
2050 0 : exportFldCAM2(:) = 0.0_r8
2051 :
2052 0 : call HCO_EvalFld(HcoState, 'SfcVMR_CFC114', exportFldHco2, HMRC, FOUND=FND)
2053 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
2054 0 : if(HMRC == HCO_SUCCESS .and. FND) then
2055 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
2056 : endif
2057 0 : if(doExport) then
2058 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
2059 : endif
2060 :
2061 : ! VMR_CFC115
2062 0 : write(exportNameTmp, '(a)') 'VMR_CFC115'
2063 :
2064 0 : exportName = 'HCO_' // trim(exportNameTmp)
2065 0 : exportFldCAM2(:) = 0.0_r8
2066 :
2067 0 : call HCO_EvalFld(HcoState, 'SfcVMR_CFC115', exportFldHco2, HMRC, FOUND=FND)
2068 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
2069 0 : if(HMRC == HCO_SUCCESS .and. FND) then
2070 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
2071 : endif
2072 0 : if(doExport) then
2073 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
2074 : endif
2075 :
2076 : ! VMR_CFC11
2077 0 : write(exportNameTmp, '(a)') 'VMR_CFC11'
2078 :
2079 0 : exportName = 'HCO_' // trim(exportNameTmp)
2080 0 : exportFldCAM2(:) = 0.0_r8
2081 :
2082 0 : call HCO_EvalFld(HcoState, 'SfcVMR_CFC11', exportFldHco2, HMRC, FOUND=FND)
2083 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
2084 0 : if(HMRC == HCO_SUCCESS .and. FND) then
2085 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
2086 : endif
2087 0 : if(doExport) then
2088 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
2089 : endif
2090 :
2091 : ! VMR_CFC12
2092 0 : write(exportNameTmp, '(a)') 'VMR_CFC12'
2093 :
2094 0 : exportName = 'HCO_' // trim(exportNameTmp)
2095 0 : exportFldCAM2(:) = 0.0_r8
2096 :
2097 0 : call HCO_EvalFld(HcoState, 'SfcVMR_CFC12', exportFldHco2, HMRC, FOUND=FND)
2098 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
2099 0 : if(HMRC == HCO_SUCCESS .and. FND) then
2100 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
2101 : endif
2102 0 : if(doExport) then
2103 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
2104 : endif
2105 :
2106 : ! VMR_CH3CCL3
2107 0 : write(exportNameTmp, '(a)') 'VMR_CH3CCL3'
2108 :
2109 0 : exportName = 'HCO_' // trim(exportNameTmp)
2110 0 : exportFldCAM2(:) = 0.0_r8
2111 :
2112 0 : call HCO_EvalFld(HcoState, 'SfcVMR_CH3CCL3', exportFldHco2, HMRC, FOUND=FND)
2113 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
2114 0 : if(HMRC == HCO_SUCCESS .and. FND) then
2115 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
2116 : endif
2117 0 : if(doExport) then
2118 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
2119 : endif
2120 :
2121 : ! VMR_H1211
2122 0 : write(exportNameTmp, '(a)') 'VMR_H1211'
2123 :
2124 0 : exportName = 'HCO_' // trim(exportNameTmp)
2125 0 : exportFldCAM2(:) = 0.0_r8
2126 :
2127 0 : call HCO_EvalFld(HcoState, 'SfcVMR_H1211', exportFldHco2, HMRC, FOUND=FND)
2128 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
2129 0 : if(HMRC == HCO_SUCCESS .and. FND) then
2130 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
2131 : endif
2132 0 : if(doExport) then
2133 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
2134 : endif
2135 :
2136 : ! VMR_H1301
2137 0 : write(exportNameTmp, '(a)') 'VMR_H1301'
2138 :
2139 0 : exportName = 'HCO_' // trim(exportNameTmp)
2140 0 : exportFldCAM2(:) = 0.0_r8
2141 :
2142 0 : call HCO_EvalFld(HcoState, 'SfcVMR_H1301', exportFldHco2, HMRC, FOUND=FND)
2143 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
2144 0 : if(HMRC == HCO_SUCCESS .and. FND) then
2145 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
2146 : endif
2147 0 : if(doExport) then
2148 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
2149 : endif
2150 :
2151 : ! VMR_H2402
2152 0 : write(exportNameTmp, '(a)') 'VMR_H2402'
2153 :
2154 0 : exportName = 'HCO_' // trim(exportNameTmp)
2155 0 : exportFldCAM2(:) = 0.0_r8
2156 :
2157 0 : call HCO_EvalFld(HcoState, 'SfcVMR_H2402', exportFldHco2, HMRC, FOUND=FND)
2158 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
2159 0 : if(HMRC == HCO_SUCCESS .and. FND) then
2160 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
2161 : endif
2162 0 : if(doExport) then
2163 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
2164 : endif
2165 :
2166 : ! VMR_HCFC141B
2167 0 : write(exportNameTmp, '(a)') 'VMR_HCFC141B'
2168 :
2169 0 : exportName = 'HCO_' // trim(exportNameTmp)
2170 0 : exportFldCAM2(:) = 0.0_r8
2171 :
2172 0 : call HCO_EvalFld(HcoState, 'SfcVMR_HCFC141B', exportFldHco2, HMRC, FOUND=FND)
2173 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
2174 0 : if(HMRC == HCO_SUCCESS .and. FND) then
2175 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
2176 : endif
2177 0 : if(doExport) then
2178 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
2179 : endif
2180 :
2181 : ! VMR_HCFC142B
2182 0 : write(exportNameTmp, '(a)') 'VMR_HCFC142B'
2183 :
2184 0 : exportName = 'HCO_' // trim(exportNameTmp)
2185 0 : exportFldCAM2(:) = 0.0_r8
2186 :
2187 0 : call HCO_EvalFld(HcoState, 'SfcVMR_HCFC142B', exportFldHco2, HMRC, FOUND=FND)
2188 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
2189 0 : if(HMRC == HCO_SUCCESS .and. FND) then
2190 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
2191 : endif
2192 0 : if(doExport) then
2193 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
2194 : endif
2195 :
2196 : ! VMR_HCFC22
2197 0 : write(exportNameTmp, '(a)') 'VMR_HCFC22'
2198 :
2199 0 : exportName = 'HCO_' // trim(exportNameTmp)
2200 0 : exportFldCAM2(:) = 0.0_r8
2201 :
2202 0 : call HCO_EvalFld(HcoState, 'SfcVMR_HCFC22', exportFldHco2, HMRC, FOUND=FND)
2203 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
2204 0 : if(HMRC == HCO_SUCCESS .and. FND) then
2205 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
2206 : endif
2207 0 : if(doExport) then
2208 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
2209 : endif
2210 :
2211 : ! VMR_N2O
2212 0 : write(exportNameTmp, '(a)') 'VMR_N2O'
2213 :
2214 0 : exportName = 'HCO_' // trim(exportNameTmp)
2215 0 : exportFldCAM2(:) = 0.0_r8
2216 :
2217 0 : call HCO_EvalFld(HcoState, 'SfcVMR_N2O', exportFldHco2, HMRC, FOUND=FND)
2218 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
2219 0 : if(HMRC == HCO_SUCCESS .and. FND) then
2220 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
2221 : endif
2222 0 : if(doExport) then
2223 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
2224 : endif
2225 :
2226 : ! VMR_OCS
2227 0 : write(exportNameTmp, '(a)') 'VMR_OCS'
2228 :
2229 0 : exportName = 'HCO_' // trim(exportNameTmp)
2230 0 : exportFldCAM2(:) = 0.0_r8
2231 :
2232 0 : call HCO_EvalFld(HcoState, 'SfcVMR_OCS', exportFldHco2, HMRC, FOUND=FND)
2233 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
2234 0 : if(HMRC == HCO_SUCCESS .and. FND) then
2235 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
2236 : endif
2237 0 : if(doExport) then
2238 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
2239 : endif
2240 :
2241 : ! VMR_H2
2242 0 : write(exportNameTmp, '(a)') 'VMR_H2'
2243 :
2244 0 : exportName = 'HCO_' // trim(exportNameTmp)
2245 0 : exportFldCAM2(:) = 0.0_r8
2246 :
2247 0 : call HCO_EvalFld(HcoState, 'SfcVMR_H2', exportFldHco2, HMRC, FOUND=FND)
2248 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
2249 0 : if(HMRC == HCO_SUCCESS .and. FND) then
2250 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
2251 : endif
2252 0 : if(doExport) then
2253 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
2254 : endif
2255 :
2256 : ! UVALBEDO
2257 : ! Warning: Keep these exportNameTmp as it allows for reuse of
2258 : ! code below. (hplin, 2/28/21)
2259 0 : write(exportNameTmp, '(a)') 'UV_ALBEDO'
2260 :
2261 : ! Reusable code templating below.
2262 0 : exportName = 'HCO_' // trim(exportNameTmp)
2263 :
2264 : ! Reset data for safe export at first time step
2265 0 : exportFldCAM2(:) = 0.0_r8
2266 :
2267 0 : call HCO_GetPtr(HcoState, exportNameTmp, Ptr2D, HMRC, FOUND=FND)
2268 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
2269 0 : if(HMRC == HCO_SUCCESS .and. FND) then
2270 0 : exportFldHco2(:,:) = Ptr2D(:,:)
2271 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
2272 : endif
2273 0 : if(doExport) then
2274 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
2275 : endif
2276 0 : Ptr2D => NULL()
2277 :
2278 : ! SURF_SALINITY
2279 : ! Note: the name is too long, reduce to HCO_salinity, HCO_iodide
2280 0 : write(exportNameTmp, '(a)') 'salinity'
2281 0 : exportName = 'HCO_' // trim(exportNameTmp)
2282 :
2283 : ! Reset data for safe export at first time step
2284 0 : exportFldCAM2(:) = 0.0_r8
2285 :
2286 0 : call HCO_GetPtr(HcoState, 'surf_salinity', Ptr2D, HMRC, FOUND=FND)
2287 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
2288 0 : if(HMRC == HCO_SUCCESS .and. FND) then
2289 0 : exportFldHco2(:,:) = Ptr2D(:,:)
2290 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
2291 : endif
2292 0 : if(doExport) then
2293 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
2294 : endif
2295 0 : Ptr2D => NULL()
2296 :
2297 : ! SURF_IODIDE
2298 0 : write(exportNameTmp, '(a)') 'iodide'
2299 0 : exportName = 'HCO_' // trim(exportNameTmp)
2300 :
2301 : ! Reset data for safe export at first time step
2302 0 : exportFldCAM2(:) = 0.0_r8
2303 :
2304 0 : call HCO_GetPtr(HcoState, 'surf_iodide', Ptr2D, HMRC, FOUND=FND)
2305 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
2306 0 : if(HMRC == HCO_SUCCESS .and. FND) then
2307 0 : exportFldHco2(:,:) = Ptr2D(:,:)
2308 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
2309 : endif
2310 0 : if(doExport) then
2311 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
2312 : endif
2313 0 : Ptr2D => NULL()
2314 :
2315 : ! OMOC_DJF
2316 0 : write(exportNameTmp, '(a)') 'OMOC_DJF'
2317 0 : exportName = 'HCO_' // trim(exportNameTmp)
2318 :
2319 : ! Reset data for safe export at first time step
2320 0 : exportFldCAM2(:) = 0.0_r8
2321 :
2322 0 : call HCO_GetPtr(HcoState, exportNameTmp, Ptr2D, HMRC, FOUND=FND)
2323 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
2324 0 : if(HMRC == HCO_SUCCESS .and. FND) then
2325 0 : exportFldHco2(:,:) = Ptr2D(:,:)
2326 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
2327 : endif
2328 0 : if(doExport) then
2329 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
2330 : endif
2331 0 : Ptr2D => NULL()
2332 :
2333 : ! OMOC_MAM
2334 0 : write(exportNameTmp, '(a)') 'OMOC_MAM'
2335 0 : exportName = 'HCO_' // trim(exportNameTmp)
2336 :
2337 : ! Reset data for safe export at first time step
2338 0 : exportFldCAM2(:) = 0.0_r8
2339 :
2340 0 : call HCO_GetPtr(HcoState, exportNameTmp, Ptr2D, HMRC, FOUND=FND)
2341 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
2342 0 : if(HMRC == HCO_SUCCESS .and. FND) then
2343 0 : exportFldHco2(:,:) = Ptr2D(:,:)
2344 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
2345 : endif
2346 0 : if(doExport) then
2347 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
2348 : endif
2349 0 : Ptr2D => NULL()
2350 :
2351 : ! OMOC_JJA
2352 0 : write(exportNameTmp, '(a)') 'OMOC_JJA'
2353 0 : exportName = 'HCO_' // trim(exportNameTmp)
2354 :
2355 : ! Reset data for safe export at first time step
2356 0 : exportFldCAM2(:) = 0.0_r8
2357 :
2358 0 : call HCO_GetPtr(HcoState, exportNameTmp, Ptr2D, HMRC, FOUND=FND)
2359 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
2360 0 : if(HMRC == HCO_SUCCESS .and. FND) then
2361 0 : exportFldHco2(:,:) = Ptr2D(:,:)
2362 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
2363 : endif
2364 0 : if(doExport) then
2365 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
2366 : endif
2367 0 : Ptr2D => NULL()
2368 :
2369 : ! OMOC_SON
2370 0 : write(exportNameTmp, '(a)') 'OMOC_SON'
2371 0 : exportName = 'HCO_' // trim(exportNameTmp)
2372 :
2373 : ! Reset data for safe export at first time step
2374 0 : exportFldCAM2(:) = 0.0_r8
2375 :
2376 0 : call HCO_GetPtr(HcoState, exportNameTmp, Ptr2D, HMRC, FOUND=FND)
2377 0 : doExport = (FIRST .or. (HMRC == HCO_SUCCESS .and. FND))
2378 0 : if(HMRC == HCO_SUCCESS .and. FND) then
2379 0 : exportFldHco2(:,:) = Ptr2D(:,:)
2380 0 : call HCO_Grid_HCO2CAM_2D(exportFldHco2, exportFldCAM2)
2381 : endif
2382 0 : if(doExport) then
2383 0 : call HCO_Export_Pbuf_CAM2D(exportNameTmp, -1, exportFldCAM2)
2384 : endif
2385 0 : Ptr2D => NULL()
2386 :
2387 0 : if(masterproc .and. nCalls < 10) write(iulog,*) "HEMCO_CESM: done with exports to GEOS-Chem"
2388 : endif
2389 :
2390 : ! dummy_0_CAM(:,:) = iam * 1.0_r8
2391 :
2392 : ! dummy_1(:,:,:) = iam * 1.0_r8
2393 :
2394 : ! test data, but on the CAM grid... note vertical is inverted
2395 : ! dummy_0_CAM sizes 16384x512. remember dummy_CAM is K, I idx
2396 : ! my_CE: 512, pver: 32
2397 : ! write(6,*) "hplin debug: sizes dummy", size(dummy_0_CAM, 1), size(dummy_0_CAM, 2), &
2398 : ! size(State_CAM_ps, 1), my_CE, pver
2399 :
2400 0 : dummy_0_CAM(:,:) = 0.0_r8
2401 : ! dummy_0_CAM(1,:) = State_CAM_TS
2402 : ! dummy_0_CAM(2,:) = State_CAM_U10M
2403 : ! dummy_0_CAM(3,:) = State_CAM_V10M
2404 : ! dummy_0_CAM(4,:) = State_CAM_ALBD
2405 : ! dummy_0_CAM(5,:) = State_CAM_LWI
2406 : ! dummy_0_CAM(6,:) = State_CAM_ps
2407 : ! dummy_0_CAM(7,:) = State_CAM_pblh
2408 : ! dummy_0_CAM(8,:) = State_CAM_CSZA
2409 : ! dummy_0_CAM(9,:) = State_CAM_psdry
2410 : ! dummy_0_CAM(10,:) = State_CAM_chmO3(LM,:)
2411 : ! dummy_0_CAM(11,:) = State_CAM_JNO2
2412 : ! dummy_0_CAM(12,:) = State_CAM_JOH
2413 : ! dummy_0_CAM(13,:) = scratchFldCAM2
2414 :
2415 : ! fill with some test data, but clean the data first!
2416 : !dummy_1(:,:,:) = 0.0_r8
2417 0 : dummy_1_CAM(:,:) = 0.0_r8
2418 : ! dummy_1(:,:,1) = State_HCO_TS
2419 : ! dummy_1(:,:,2) = State_HCO_U10M
2420 : ! dummy_1(:,:,3) = State_HCO_V10M
2421 : ! dummy_1(:,:,4) = State_HCO_ALBD
2422 : ! dummy_1(:,:,5) = State_HCO_WLI
2423 : ! dummy_1(:,:,6) = State_HCO_PSFC
2424 : ! dummy_1(:,:,7) = State_HCO_PBLH
2425 : ! dummy_1(:,:,8) = State_HCO_CSZA
2426 : ! dummy_1(:,:,9) = State_HCO_AIR(:,:,1)
2427 : ! dummy_1(:,:,10) = State_HCO_AIR(:,:,2)
2428 : ! dummy_1(:,:,11) = Area_M2(my_IS:my_IE,my_JS:my_JE)
2429 : ! dummy_1(:,:,12) = State_HCO_chmO3(:,:,1)
2430 : ! dummy_1(:,:,13) = State_HCO_chmNO(:,:,1)
2431 :
2432 : ! dummy_1(:,:,14) = HcoState%Grid%BXHEIGHT_M%Val(:,:,1)
2433 : ! dummy_1(:,:,15) = HcoState%Grid%BXHEIGHT_M%Val(:,:,2)
2434 : ! dummy_1(:,:,16) = State_HCO_F_OF_PBL(:,:,1)
2435 : ! dummy_1(:,:,17) = State_HCO_F_OF_PBL(:,:,2)
2436 : ! dummy_1(:,:,18) = dummy_2(:,:)
2437 :
2438 : ! Regrid to CAM physics mesh!
2439 : !call HCO_Grid_HCO2CAM_3D(dummy_1, dummy_1_CAM)
2440 :
2441 : ! Write to history on CAM mesh
2442 : !call HCO_Export_History_CAM3D("DIAG_HCO_TEST", dummy_1_CAM)
2443 : !call HCO_Export_History_CAM3D("DIAG_CAM_TEST", dummy_0_CAM)
2444 :
2445 0 : if(masterproc .and. nCalls < 10) then
2446 0 : write(iulog,*) "HEMCO_CESM: Exports completed for this timestep!"
2447 : endif
2448 :
2449 : !-----------------------------------------------------------------------
2450 : ! Finished!
2451 : !-----------------------------------------------------------------------
2452 : ! Update last execution time
2453 0 : last_HCO_day = now_day
2454 0 : last_HCO_second = now_s
2455 :
2456 0 : IF ( FIRST ) FIRST = .False.
2457 :
2458 0 : RC = ESMF_SUCCESS
2459 :
2460 0 : end subroutine HCO_GC_Run
2461 :
2462 : !---------------------------------------------------------------------
2463 : ! Every HEMCO GridComp routine below likely will be just boilerplate
2464 : ! that does not need extensive maintenance
2465 : !---------------------------------------------------------------------
2466 :
2467 : ! Init routine for the Gridded Component
2468 : ! Largely based off edyn_grid_comp::edyn_gcomp_init
2469 0 : subroutine HCO_GC_Init(GC, IMPORT, EXPORT, Clock, RC)
2470 0 : use spmd_utils, only: masterproc
2471 : use cam_logfile, only: iulog
2472 :
2473 : ! Dummy arguments
2474 : type(ESMF_GridComp) :: GC
2475 : type(ESMF_State) :: IMPORT
2476 : type(ESMF_State) :: EXPORT
2477 : type(ESMF_Clock) :: Clock
2478 : integer, intent(out) :: RC
2479 :
2480 : ! Local variables
2481 : character(len=*), parameter :: subname = 'HCO_GC_Init'
2482 :
2483 : ! Note hplin 2/17/20: It seems like the physics mesh is re-created in
2484 : ! edyn_esmf through edyn_create_physmesh. It may be redundant to do
2485 : ! the CAM_DistGrid and CAM_PhysMesh maneuvers here and do this in
2486 : ! HCO_ESMF_Grid::HCO_Grid_ESMF_CreateCAM instead.
2487 :
2488 0 : RC = ESMF_SUCCESS
2489 :
2490 0 : end subroutine HCO_GC_Init
2491 :
2492 : ! Finalize Gridded Component
2493 0 : subroutine HCO_GC_Final(GC, IMPORT, EXPORT, Clock, RC)
2494 : ! use ESMF, only: ESMF_MeshDestroy
2495 :
2496 : ! Dummy arguments
2497 : type(ESMF_GridComp) :: GC
2498 : type(ESMF_State) :: IMPORT
2499 : type(ESMF_State) :: EXPORT
2500 : type(ESMF_Clock) :: Clock
2501 : integer, intent(out) :: RC
2502 :
2503 : ! Local variables
2504 : character(len=*), parameter :: subname = 'HCO_GC_Final'
2505 :
2506 : ! call ESMF_MeshDestroy(CAM_PhysMesh, rc=RC)
2507 : ! ASSERT_(RC==ESMF_SUCCESS)
2508 :
2509 0 : RC = ESMF_SUCCESS
2510 :
2511 0 : end subroutine HCO_GC_Final
2512 :
2513 0 : subroutine HCO_GC_SetServices(GC, RC)
2514 : use ESMF, only: ESMF_GridCompSetEntryPoint
2515 : use ESMF, only: ESMF_METHOD_INITIALIZE
2516 : use ESMF, only: ESMF_METHOD_RUN
2517 : use ESMF, only: ESMF_METHOD_FINALIZE
2518 :
2519 : type(ESMF_GridComp) :: GC
2520 : integer, intent(out) :: RC
2521 : character(len=*), parameter :: subname = 'HCO_GC_SetServices'
2522 :
2523 : ! Set the IRF methods as follows:
2524 : ! HEMCO Gridded Component dummy
2525 : ! > Init: hemco_interface::HCO_GC_Init
2526 : ! > Run: hemco_interface::HCO_GC_Run
2527 : ! > Final: hemco_interface::HCO_GC_Final
2528 : !
2529 : ! Note from Steve: " all the actual regridding will have to happen inside the gridded component's run method."
2530 :
2531 0 : call ESMF_GridCompSetEntryPoint(GC, ESMF_METHOD_INITIALIZE, userRoutine=HCO_GC_Init, rc=RC)
2532 0 : ASSERT_(RC==ESMF_SUCCESS)
2533 :
2534 0 : call ESMF_GridCompSetEntryPoint(GC, ESMF_METHOD_RUN, userRoutine=HCO_GC_Run, rc=RC)
2535 0 : ASSERT_(RC==ESMF_SUCCESS)
2536 :
2537 0 : call ESMF_GridCompSetEntryPoint(GC, ESMF_METHOD_FINALIZE, userRoutine=HCO_GC_Final, rc=RC)
2538 0 : ASSERT_(RC==ESMF_SUCCESS)
2539 0 : end subroutine HCO_GC_SetServices
2540 : !EOC
2541 : end module hemco_interface
|