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