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