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: hco_cam_convert_state_mod
9 : !
10 : ! !DESCRIPTION: Module HCO\_CAM\_Convert\_State\_Mod handles state conversion
11 : ! between the CAM meteorological fields and the HEMCO state.
12 : !
13 : !\\
14 : !\\
15 : ! !INTERFACE:
16 : !
17 : module hco_cam_convert_state_mod
18 : !
19 : ! !USES:
20 : !
21 : ! ESMF function wrappers
22 : use hco_esmf_wrappers
23 :
24 : ! MPI status in CESM
25 : use cam_abortutils, only: endrun ! fatal terminator
26 : use spmd_utils, only: iam, masterproc
27 : use cam_logfile, only: iulog
28 :
29 : ! Grid information
30 : ! Remember - if information is pulled from hco_esmf_grid, GLOBAL INDICES MUST BE USED!
31 : use hco_esmf_grid, only: my_IM, my_JM, LM
32 : use hco_esmf_grid, only: my_CE
33 : use hco_esmf_grid, only: my_IS, my_IE, my_JS, my_JE
34 : use hco_esmf_grid, only: HCO_Grid_CAM2HCO_2D, HCO_Grid_CAM2HCO_3D
35 : use hco_esmf_grid, only: HCO_Grid_HCO2CAM_2D
36 : use ppgrid, only: pcols, pver ! Cols, verts
37 : use ppgrid, only: begchunk, endchunk ! Chunk idxs
38 :
39 : ! HEMCO types
40 : use HCO_Error_Mod, only: sp, hp
41 : use HCO_State_Mod, only: HCO_State
42 : use HCOX_State_Mod, only: Ext_State
43 :
44 : ! Float types
45 : use ESMF, only: ESMF_KIND_R8, ESMF_KIND_I4, ESMF_SUCCESS
46 : use shr_kind_mod, only: r8 => shr_kind_r8
47 :
48 : ! Physics buffer
49 : use physics_buffer, only: pbuf_add_field, dtype_r8
50 :
51 : implicit none
52 : private
53 :
54 : !
55 : ! !PUBLIC MEMBER FUNCTIONS:
56 : !
57 : public :: HCOI_Allocate_All
58 : public :: CAM_GetBefore_HCOI
59 : public :: CAM_RegridSet_HCOI
60 : !
61 : ! !PRIVATE MEMBER FUNCTIONS:
62 : !
63 : ! private :: CAM_GC_ComputeMet
64 : !
65 : ! !REMARKS:
66 : ! The code here is structurally based on the WRF-GC coupler, but the actual
67 : ! conversion logic is from CESM-GC.
68 : !
69 : ! Note that there are unique constraints here:
70 : ! 1) the CAM data structures have to be retrieved outside the GridComp in
71 : ! HCOI_Chunk_Run phase two. Thus CAM_GetBefore_HCOI will populate the fields
72 : ! as a memory copy from CAM state into State_CAM_* here. These are PRIVATE types.
73 : ! 2) the regridder has to run within the GridComp. Thus they are regridded using
74 : ! another method CAM_RegridSet_HCOI and populates the PUBLIC, State_HCO_* data,
75 : ! which is usable on the HEMCO grid.
76 : !
77 : ! All indices are native, and all your base are belong to us. (hplin, 12/15/20)
78 : !
79 : !------------------------------------------------------------------------------
80 : ! LIST OF SUPPORTED MET FIELD CONVERSIONS
81 : !------------------------------------------------------------------------------
82 : ! HEMCO format
83 : ! ----------------------------------------------------------------------------
84 : ! AIR (airmass/AD)
85 : !
86 : ! ALBD
87 : ! F_OF_PBL
88 : ! FROCEAN, FRSEAICE (added 8/10/22)
89 : ! HNO3
90 : ! NO, NO2
91 : ! O3
92 : ! PBLH
93 : ! PSFC
94 : ! QV2M (added 8/10/22)
95 : ! SUNCOS
96 : ! T2M
97 : ! TK
98 : ! TSKIN
99 : ! USTAR (added 8/10/22)
100 : ! U10M
101 : ! V10M
102 : !
103 : ! For SeaFlux deposition:
104 : ! GEOS-Chem DMS/ACET /ALD2 /MENO3/ETNO3/MOH
105 : ! MOZART-T1 DMS/CH3COCH3/CH3CHO/-- /-- /CH3OH
106 : ! * Some species are only available in one particular mechanism.
107 : ! Species used for deposition are computed on the native CAM grid, and no regridding
108 : ! is thus performed.
109 : !
110 : ! STUBS
111 : ! ----------------------------------------------------------------------------
112 : ! GWETTOP = 0
113 : ! FRLANDIC = 0
114 : ! FRLAKE = 0
115 : !
116 : ! Disabled: AIRVOL
117 : !
118 : ! !REVISION HISTORY:
119 : ! 15 Dec 2020 - H.P. Lin - Initial version
120 : ! 04 Feb 2021 - H.P. Lin - Add State_GC_* for some GC-specific intermediate qtys
121 : ! 07 May 2021 - H.P. Lin - Add state fluxes on CAM grid for deposition computation
122 : ! 10 Aug 2022 - H.P. Lin - Update quantities QV2M, USTAR, FROCEAN, FRSEAICE
123 : ! 20 Jan 2023 - H.P. Lin - Remove WLI for HEMCO 3.6.0+; add FRLAND.
124 : !EOP
125 : !------------------------------------------------------------------------------
126 : !BOC
127 : !
128 : ! !PRIVATE TYPES:
129 : !
130 : ! Flag for supported features
131 : logical :: feat_JValues
132 :
133 : ! Indices for reactions (rxt) and pbuf fields
134 : integer :: index_rxt_jno2, index_rxt_joh, index_JNO2, index_JOH
135 :
136 : ! On the CAM grid (state%psetcols, pver) (LM, my_CE)
137 : ! Arrays are flipped in order (k, i) for the regridder
138 : real(r8), pointer, public :: State_CAM_t(:,:)
139 : real(r8), pointer, public :: State_CAM_ps(:)
140 : real(r8), pointer, public :: State_CAM_psdry(:)
141 : real(r8), pointer, public :: State_CAM_pblh(:)
142 :
143 : real(r8), pointer, public :: State_CAM_TS(:)
144 : real(r8), pointer, public :: State_CAM_SST(:)
145 : real(r8), pointer, public :: State_CAM_U10M(:)
146 : real(r8), pointer, public :: State_CAM_V10M(:)
147 : real(r8), pointer, public :: State_CAM_ALBD(:)
148 : real(r8), pointer, public :: State_CAM_USTAR(:)
149 :
150 : real(r8), pointer, public :: State_CAM_CSZA(:)
151 :
152 : real(r8), pointer, public :: State_CAM_AREAM2(:)
153 : real(r8), pointer, public :: State_CAM_AIRs (:)
154 : real(r8), pointer, public :: State_CAM_DELP_DRYs(:)
155 :
156 : ! Land fractions (converted to Olson) from CAM - 1D
157 : real(r8), pointer, public :: State_CAM_FRLAND (:)
158 : real(r8), pointer, public :: State_CAM_FROCEAN (:)
159 : real(r8), pointer, public :: State_CAM_FRSEAICE (:)
160 :
161 : ! Chem Constituents on CAM grid
162 : real(r8), pointer, public :: State_CAM_chmO3 (:,:)
163 : real(r8), pointer, public :: State_CAM_chmNO (:,:)
164 : real(r8), pointer, public :: State_CAM_chmNO2(:,:)
165 : real(r8), pointer, public :: State_CAM_chmHNO3(:,:)
166 :
167 : ! For surface dep calculation, only surface needs to be copied
168 : real(r8), pointer, public :: State_CAM_chmDMS(:)
169 : real(r8), pointer, public :: State_CAM_chmACET(:)
170 : real(r8), pointer, public :: State_CAM_chmALD2(:)
171 : real(r8), pointer, public :: State_CAM_chmMENO3(:)
172 : real(r8), pointer, public :: State_CAM_chmETNO3(:)
173 : real(r8), pointer, public :: State_CAM_chmMOH(:)
174 :
175 : ! J-values from chemistry (2-D only, on surface)
176 : real(r8), pointer, public :: State_CAM_JNO2(:)
177 : real(r8), pointer, public :: State_CAM_JOH (:)
178 :
179 : ! Q at 2m [kg H2O/kg air]
180 : real(r8), pointer, public :: State_CAM_QV2M(:)
181 :
182 : !------------------------------------------------------------------
183 : ! On the HEMCO grid (my_IM, my_JM, LM) or possibly LM+1
184 : ! HEMCO grid are set as POINTERs so it satisfies HEMCO which wants to point
185 : real(r8), pointer, public :: State_GC_PSC2_DRY(:,:) ! Dry pressure from PSC2_DRY
186 : real(r8), pointer, public :: State_GC_DELP_DRY(:,:,:)! Delta dry pressure
187 :
188 : real(r8), pointer, public :: State_HCO_AIR (:,:,:) ! GC_AD, mass of dry air in grid box [kg]
189 : real(r8), pointer, public :: State_HCO_AIRVOL(:,:,:) ! GC_AIRVOL, volume of grid box [m^3]
190 :
191 : real(r8), pointer, public :: State_HCO_TK (:,:,:)
192 : real(r8), pointer, public :: State_HCO_PSFC(:,:) ! Wet?
193 : real(r8), pointer, public :: State_HCO_PBLH(:,:) ! PBLH [m]
194 :
195 : real(r8), pointer, public :: State_HCO_TS(:,:)
196 : real(r8), pointer, public :: State_HCO_TSKIN(:,:)
197 : real(r8), pointer, public :: State_HCO_U10M(:,:)
198 : real(r8), pointer, public :: State_HCO_V10M(:,:)
199 : real(r8), pointer, public :: State_HCO_ALBD(:,:)
200 : real(r8), pointer, public :: State_HCO_USTAR(:,:)
201 : real(r8), pointer, public :: State_HCO_F_OF_PBL(:,:,:)
202 :
203 : real(r8), pointer, public :: State_HCO_CSZA(:,:)
204 :
205 : real(r8), pointer, public :: State_HCO_FRLAND (:,:)
206 : real(r8), pointer, public :: State_HCO_FRLANDIC(:,:)
207 : real(r8), pointer, public :: State_HCO_FROCEAN (:,:)
208 : real(r8), pointer, public :: State_HCO_FRSEAICE(:,:)
209 : real(r8), pointer, public :: State_HCO_FRLAKE (:,:)
210 :
211 : ! Chem Constituents on HEMCO grid
212 : real(r8), pointer, public :: State_HCO_chmO3 (:,:,:)
213 : real(r8), pointer, public :: State_HCO_chmNO (:,:,:)
214 : real(r8), pointer, public :: State_HCO_chmNO2(:,:,:)
215 : real(r8), pointer, public :: State_HCO_chmHNO3(:,:,:)
216 :
217 : ! J-values from chemistry (passed in reverse direction)
218 : real(r8), pointer, public :: State_HCO_JNO2(:,:)
219 : real(r8), pointer, public :: State_HCO_JOH (:,:)
220 :
221 :
222 : real(r8), pointer, public :: State_HCO_QV2M(:,:)
223 :
224 : ! constituent indices:
225 : integer :: id_O3, id_NO, id_NO2, id_HNO3
226 : integer :: id_H2O, id_Q
227 : integer :: id_DMS, id_ACET, id_ALD2, id_MENO3, id_ETNO3, id_MOH
228 :
229 : contains
230 : !EOC
231 : !------------------------------------------------------------------------------
232 : ! Harmonized Emissions Component (HEMCO) !
233 : !------------------------------------------------------------------------------
234 : !BOP
235 : !
236 : ! !IROUTINE: HCOI_Allocate_All
237 : !
238 : ! !DESCRIPTION: HCOI\_Allocate\_All allocates temporary met fields for use in
239 : ! HEMCO and performs initialization of pbuf fields for interfacing with chem.
240 : !\\
241 : !\\
242 : ! !INTERFACE:
243 : !
244 0 : subroutine HCOI_Allocate_All()
245 : !
246 : ! !USES:
247 : !
248 : use cam_logfile, only: iulog
249 : use spmd_utils, only: masterproc
250 :
251 : use HCO_ESMF_Grid, only: AREA_M2, HCO_Grid_HCO2CAM_2D
252 :
253 : ! Chemistry descriptor
254 : use chemistry, only: chem_is
255 : use mo_chem_utls, only: get_rxt_ndx
256 : !
257 : ! !REMARKS:
258 : ! Fields are allocated here after initialization of the hco\_esmf\_grid.
259 : ! They are regridded inside the gridcomp.
260 : ! A "state conversion" to convert CAM met fields to GEOSFP format will
261 : ! need to be coordinated with fritzt later down the road (hplin, 3/27/20)
262 : !
263 : ! Note that arrays in CAM format stored in the HEMCO interface are (k, i) idxd
264 : ! for the regridder
265 : !
266 : ! !REVISION HISTORY:
267 : ! 31 Mar 2020 - H.P. Lin - Initial version
268 : ! 10 Aug 2022 - H.P. Lin - Update FROCEAN, FRSEAICE for HEMCO 3.4.0+
269 : ! 02 Mar 2023 - H.P. Lin - Move initialization of pbuf for JOH, JNO2 here
270 : !EOP
271 : !------------------------------------------------------------------------------
272 : !BOC
273 : !
274 : ! !LOCAL VARIABLES:
275 : !
276 : character(len=*), parameter :: subname = 'HCOI_Allocate_All'
277 : integer :: RC ! ESMF return code
278 :
279 : ! Assume success
280 0 : RC = ESMF_SUCCESS
281 :
282 : ! Sanity check
283 : !if(masterproc) then
284 : ! write(iulog,*) "> HCOI_Allocate_All entering"
285 : !endif
286 :
287 : ! PBL height [m]
288 : ! Comes from pbuf
289 0 : allocate(State_CAM_pblh(my_CE), stat=RC)
290 0 : ASSERT_(RC==0)
291 :
292 0 : allocate(State_HCO_PBLH(my_IM, my_JM), stat=RC)
293 0 : ASSERT_(RC==0)
294 :
295 : ! Grid box area [m2]
296 : ! Used for calculation of deposition fluxes directly on CAM grid
297 0 : allocate(State_CAM_AREAM2(my_CE), stat=RC)
298 0 : ASSERT_(RC==0)
299 :
300 : ! Surface grid box weight [kg]
301 0 : allocate(State_CAM_AIRs(my_CE), stat=RC)
302 0 : ASSERT_(RC==0)
303 :
304 : ! Surface delta grid box pressure differential [hPa]
305 0 : allocate(State_CAM_DELP_DRYs(my_CE), stat=RC)
306 0 : ASSERT_(RC==0)
307 :
308 : ! Surface pressure (wet) [Pa]
309 0 : allocate(State_CAM_ps(my_CE), stat=RC)
310 0 : ASSERT_(RC==0)
311 :
312 0 : allocate(State_HCO_PSFC(my_IM, my_JM), stat=RC)
313 0 : ASSERT_(RC==0)
314 :
315 : ! Surface pressure (dry) [hPa]
316 0 : allocate(State_CAM_psdry(my_CE), stat=RC)
317 0 : ASSERT_(RC==0)
318 :
319 0 : allocate(State_GC_PSC2_DRY(my_IM, my_JM), stat=RC)
320 0 : ASSERT_(RC==0)
321 :
322 : ! T
323 0 : allocate(State_CAM_t (LM, my_CE), stat=RC)
324 0 : ASSERT_(RC==0)
325 :
326 0 : allocate(State_HCO_TK(my_IM, my_JM, LM), stat=RC)
327 0 : ASSERT_(RC==0)
328 :
329 :
330 : ! For HEMCO extensions...
331 0 : allocate(State_CAM_TS (my_CE), stat=RC)
332 0 : ASSERT_(RC==0)
333 0 : allocate(State_CAM_SST (my_CE), stat=RC)
334 0 : ASSERT_(RC==0)
335 0 : allocate(State_CAM_U10M (my_CE), stat=RC)
336 0 : ASSERT_(RC==0)
337 0 : allocate(State_CAM_V10M (my_CE), stat=RC)
338 0 : ASSERT_(RC==0)
339 0 : allocate(State_CAM_ALBD (my_CE), stat=RC)
340 0 : ASSERT_(RC==0)
341 0 : allocate(State_CAM_USTAR(my_CE), stat=RC)
342 0 : ASSERT_(RC==0)
343 0 : allocate(State_CAM_CSZA (my_CE), stat=RC)
344 0 : ASSERT_(RC==0)
345 0 : allocate(State_CAM_FRLAND(my_CE), stat=RC)
346 0 : ASSERT_(RC==0)
347 0 : allocate(State_CAM_FROCEAN(my_CE), stat=RC)
348 0 : ASSERT_(RC==0)
349 0 : allocate(State_CAM_FRSEAICE(my_CE), stat=RC)
350 0 : ASSERT_(RC==0)
351 :
352 : ! QV2M
353 0 : allocate(State_CAM_QV2M(my_CE), stat=RC)
354 0 : ASSERT_(RC==0)
355 :
356 0 : allocate(State_HCO_QV2M(my_IM, my_JM), stat=RC)
357 0 : ASSERT_(RC==0)
358 :
359 : ! Constituents
360 0 : allocate(State_CAM_chmO3(LM, my_CE), stat=RC)
361 0 : ASSERT_(RC==0)
362 :
363 0 : allocate(State_CAM_chmNO(LM, my_CE), stat=RC)
364 0 : ASSERT_(RC==0)
365 :
366 0 : allocate(State_CAM_chmNO2(LM, my_CE), stat=RC)
367 0 : ASSERT_(RC==0)
368 :
369 0 : allocate(State_CAM_chmHNO3(LM, my_CE), stat=RC)
370 0 : ASSERT_(RC==0)
371 :
372 : ! Constituents for deposition flux, copy sfc only
373 0 : allocate(State_CAM_chmDMS(my_CE), stat=RC)
374 0 : ASSERT_(RC==0)
375 0 : allocate(State_CAM_chmACET(my_CE), stat=RC)
376 0 : ASSERT_(RC==0)
377 0 : allocate(State_CAM_chmALD2(my_CE), stat=RC)
378 0 : ASSERT_(RC==0)
379 0 : allocate(State_CAM_chmMENO3(my_CE), stat=RC)
380 0 : ASSERT_(RC==0)
381 0 : allocate(State_CAM_chmETNO3(my_CE), stat=RC)
382 0 : ASSERT_(RC==0)
383 0 : allocate(State_CAM_chmMOH(my_CE), stat=RC)
384 0 : ASSERT_(RC==0)
385 :
386 : ! J-values
387 0 : allocate(State_CAM_JNO2 (my_CE), stat=RC)
388 0 : ASSERT_(RC==0)
389 0 : allocate(State_CAM_JOH (my_CE), stat=RC)
390 0 : ASSERT_(RC==0)
391 :
392 : ! On HEMCO grid
393 0 : allocate(State_HCO_AIR(my_IM, my_JM, LM), stat=RC)
394 0 : allocate(State_HCO_TS(my_IM, my_JM), stat=RC)
395 0 : allocate(State_HCO_TSKIN(my_IM, my_JM), stat=RC)
396 0 : allocate(State_HCO_U10M(my_IM, my_JM), stat=RC)
397 0 : allocate(State_HCO_V10M(my_IM, my_JM), stat=RC)
398 0 : allocate(State_HCO_ALBD(my_IM, my_JM), stat=RC)
399 0 : allocate(State_HCO_CSZA(my_IM, my_JM), stat=RC)
400 0 : allocate(State_HCO_USTAR(my_IM, my_JM), stat=RC)
401 0 : allocate(State_HCO_F_OF_PBL(my_IM, my_JM, LM), stat=RC)
402 0 : allocate(State_GC_DELP_DRY(my_IM, my_JM, LM), stat=RC)
403 :
404 0 : allocate(State_HCO_chmO3 (my_IM, my_JM, LM), stat=RC)
405 0 : allocate(State_HCO_chmNO (my_IM, my_JM, LM), stat=RC)
406 0 : allocate(State_HCO_chmNO2(my_IM, my_JM, LM), stat=RC)
407 0 : allocate(State_HCO_chmHNO3(my_IM, my_JM, LM), stat=RC)
408 :
409 0 : allocate(State_HCO_JOH (my_IM, my_JM), stat=RC)
410 0 : allocate(State_HCO_JNO2(my_IM, my_JM), stat=RC)
411 0 : allocate(State_HCO_FRLAND(my_IM, my_JM), stat=RC)
412 0 : allocate(State_HCO_FRLANDIC(my_IM, my_JM), stat=RC)
413 0 : allocate(State_HCO_FROCEAN(my_IM, my_JM), stat=RC)
414 0 : allocate(State_HCO_FRSEAICE(my_IM, my_JM), stat=RC)
415 0 : allocate(State_HCO_FRLAKE(my_IM, my_JM), stat=RC)
416 :
417 : ! Clear values
418 0 : State_HCO_AIR(:,:,:) = 0.0_r8
419 0 : State_HCO_PBLH(:,:) = 0.0_r8
420 0 : State_HCO_PSFC(:,:) = 0.0_r8
421 0 : State_GC_PSC2_DRY(:,:) = 0.0_r8
422 0 : State_HCO_TK(:,:,:) = 0.0_r8
423 0 : State_HCO_TS(:,:) = 0.0_r8
424 0 : State_HCO_TSKIN(:,:) = 0.0_r8
425 0 : State_HCO_U10M(:,:) = 0.0_r8
426 0 : State_HCO_V10M(:,:) = 0.0_r8
427 0 : State_HCO_ALBD(:,:) = 0.0_r8
428 0 : State_HCO_USTAR(:,:) = 0.0_r8
429 0 : State_HCO_CSZA(:,:) = 0.0_r8
430 0 : State_HCO_F_OF_PBL(:,:,:) = 0.0_r8
431 0 : State_GC_DELP_DRY(:,:,:) = 0.0_r8
432 :
433 0 : State_HCO_chmO3(:,:,:) = 0.0_r8
434 0 : State_HCO_chmNO(:,:,:) = 0.0_r8
435 0 : State_HCO_chmNO2(:,:,:) = 0.0_r8
436 0 : State_HCO_chmHNO3(:,:,:) = 0.0_r8
437 :
438 0 : State_HCO_QV2M(:,:) = 0.0_r8
439 :
440 0 : State_CAM_chmDMS(:) = 0.0_r8
441 0 : State_CAM_chmACET(:) = 0.0_r8
442 0 : State_CAM_chmALD2(:) = 0.0_r8
443 0 : State_CAM_chmMENO3(:) = 0.0_r8
444 0 : State_CAM_chmETNO3(:) = 0.0_r8
445 0 : State_CAM_chmMOH(:) = 0.0_r8
446 :
447 0 : State_CAM_JNO2(:) = 0.0_r8
448 0 : State_CAM_JOH (:) = 0.0_r8
449 0 : State_CAM_QV2M(:) = 0.0_r8
450 0 : State_CAM_USTAR(:) = 0.0_r8
451 :
452 0 : State_HCO_JNO2(:,:) = 0.0_r8
453 0 : State_HCO_JOH(:,:) = 0.0_r8
454 :
455 : ! Unsupported fields in CESM are directly assigned to zero.
456 : ! These, if ever available, will be updated along with chemistry.F90
457 : ! under src/chemistry/geoschem. (hplin, 1/20/23)
458 0 : State_HCO_FRLANDIC(:,:) = 0.0_r8
459 0 : State_HCO_FRLAKE(:,:) = 0.0_r8
460 :
461 : ! Populate persistent values
462 0 : call HCO_Grid_HCO2CAM_2D(AREA_M2, State_CAM_AREAM2)
463 :
464 : ! Perform pbuf initialization for interfacing with CAM-chem (hplin, 3/2/23)
465 0 : if(.not. chem_is('GEOS-Chem')) then
466 0 : index_rxt_jno2 = get_rxt_ndx('jno2')
467 0 : index_rxt_joh = get_rxt_ndx('jo3_b')
468 :
469 : ! If they both exist, then create the pbuf fields... (hplin, 3/2/23)
470 0 : if(index_rxt_jno2 > 0 .and. index_rxt_joh > 0) then
471 0 : call pbuf_add_field('HCO_IN_JNO2', 'global', dtype_r8, (/pcols/), index_JNO2)
472 0 : call pbuf_add_field('HCO_IN_JOH', 'global', dtype_r8, (/pcols/), index_JOH )
473 : endif
474 : endif
475 :
476 0 : end subroutine HCOI_Allocate_All
477 : !EOC
478 : !------------------------------------------------------------------------------
479 : ! Harmonized Emissions Component (HEMCO) !
480 : !------------------------------------------------------------------------------
481 : !BOP
482 : !
483 : ! !IROUTINE: CAM_GetBefore_HCOI
484 : !
485 : ! !DESCRIPTION: CAM\_GetBefore\_HCOI populates the internal copy of CAM state
486 : ! within the conversion module to prepare for regridding within the gridcomp.
487 : !\\
488 : !\\
489 : ! !INTERFACE:
490 : !
491 0 : subroutine CAM_GetBefore_HCOI(cam_in, phys_state, pbuf2d, phase, HcoState, ExtState)
492 : !
493 : ! !USES:
494 : !
495 : ! Pbuf wrappers by hplin
496 0 : use hco_cam_exports,only: HCO_Export_Pbuf_QueryField
497 :
498 : ! Type descriptors
499 : use camsrfexch, only: cam_in_t
500 : use physics_types, only: physics_state
501 : use physics_buffer, only: physics_buffer_desc
502 :
503 : ! Physics grid
504 : use phys_grid, only: get_ncols_p
505 : use phys_grid, only: get_rlon_all_p, get_rlat_all_p
506 :
507 : use ppgrid, only: pcols ! max. # of columns in chunk
508 :
509 : ! CAM physics buffer (some fields are here and some are in phys state)
510 : use physics_buffer, only: pbuf_get_chunk, pbuf_get_field
511 : use physics_buffer, only: pbuf_get_index
512 :
513 : ! Time description and zenith angle data
514 : use orbit, only: zenith
515 : use time_manager, only: get_curr_calday
516 :
517 : ! Constituent information to retrieve from physics state
518 : use constituents, only: cnst_get_ind
519 :
520 : ! Output and mpi
521 : use cam_logfile, only: iulog
522 : use spmd_utils, only: masterproc, mpicom, masterprocid, iam
523 : !
524 : ! !INPUT PARAMETERS:
525 : !
526 : type(cam_in_t), intent(inout) :: cam_in(begchunk:endchunk)
527 : type(physics_state), intent(inout) :: phys_state(begchunk:endchunk)
528 : type(physics_buffer_desc), pointer :: pbuf2d(:,:)
529 : integer, intent(in) :: phase ! 1, 2
530 :
531 : type(HCO_State), pointer :: HcoState
532 : type(Ext_State), pointer :: ExtState
533 : !
534 : ! !REMARKS:
535 : ! Note that arrays in CAM format stored in the HEMCO interface are (k, i) idxd
536 : ! for the regridder
537 : !
538 : ! Also needs HEMCO and HEMCO extensions state information in order to check
539 : ! whether we actually need to populate required meteorology fields
540 : !
541 : ! Note for CSZA:
542 : ! - We do not have access to the state here, so we need to get geo data and zenith
543 : ! using a different method, by looping through all chunks.
544 : !
545 : ! !REVISION HISTORY:
546 : ! 16 Dec 2020 - H.P. Lin - Initial version
547 : ! 04 Feb 2021 - H.P. Lin - Add CSZA calculation with geographical data
548 : !EOP
549 : !------------------------------------------------------------------------------
550 : !BOC
551 : !
552 : ! !LOCAL VARIABLES:
553 : !
554 : character(len=*), parameter :: subname = 'CAM_GetBefore_HCOI'
555 : integer :: RC ! ESMF return code
556 :
557 : integer :: I, J, K, lchnk ! Loop idx
558 : integer :: ncol
559 :
560 0 : type(physics_buffer_desc), pointer :: pbuf_chnk(:) ! slice of pbuf
561 :
562 : ! temp 2-D data slice (pcol), points to raw
563 0 : real(r8), pointer :: pbuf_tmp_pblh(:)
564 0 : real(r8), pointer :: pbuf_tmp_JNO2(:), pbuf_tmp_JOH(:)
565 :
566 : ! pbuf indices:
567 : integer :: index_pblh, index_JNO2, index_JOH
568 :
569 : ! Temporary geographical indices, allocated to max size (pcols)
570 : ! need to use actual column # ncol = get_ncols_p to fill to my_CE, which is exact
571 : real(r8) :: lchnk_rlats(1:pcols), lchnk_rlons(1:pcols)
572 : real(r8) :: lchnk_zenith(1:pcols)
573 :
574 : ! Current calday for SZA
575 : real(r8) :: calday
576 :
577 : ! is this first timestep? skip reading pbuf from certain data if so
578 : logical, save :: FIRST = .true.
579 :
580 : !----------------------------------------------------
581 : ! Assume success
582 0 : RC = ESMF_SUCCESS
583 :
584 0 : if(masterproc .and. FIRST) then
585 0 : write(iulog,*) "> CAM_GetBefore_HCOI entering"
586 : endif
587 :
588 : ! Regrid necessary physics quantities from the CAM grid to the HEMCO grid
589 : ! Phase 0: Prepare necessary pbuf indices to retrieve data from the buffer...
590 :
591 : ! TODO: This prep phase might possibly be better moved into initialization.
592 : ! Keeping it here for now but later can be optimized (hplin, 3/31/20)
593 0 : index_pblh = pbuf_get_index('pblh')
594 :
595 0 : index_JNO2 = pbuf_get_index('HCO_IN_JNO2', RC)
596 0 : index_JOH = pbuf_get_index('HCO_IN_JOH', RC)
597 0 : RC = ESMF_SUCCESS ! dummy
598 0 : feat_Jvalues = .false.
599 :
600 0 : if(index_JNO2 > 0 .and. index_JOH > 0) then
601 0 : feat_Jvalues = .true.
602 : endif
603 :
604 0 : if(masterproc .and. FIRST) write(iulog,*) "feat_JValues:", feat_JValues
605 :
606 : ! Get calday for cosza (current time, not midpoint of dt)
607 0 : calday = get_curr_calday()
608 :
609 : ! TODO: Move constituent index calculation (which only needs to be initialized once)
610 : ! to a place where it only runs once ...
611 : ! Setup constituent indices so their concentrations can be retrieved
612 : ! from state%q (MMR)
613 0 : call cnst_get_ind('O3', id_O3)
614 0 : call cnst_get_ind('NO', id_NO)
615 0 : call cnst_get_ind('NO2', id_NO2)
616 0 : call cnst_get_ind('HNO3', id_HNO3)
617 :
618 : ! Get constitutent index for specific humidity
619 0 : call cnst_get_ind('Q', id_Q)
620 : ! call cnst_get_ind('H2O', id_H2O)
621 : ! id_H2O not used for now, and also not present in CAM-chem. hplin, 9/9/22
622 :
623 : ! Retrieve optional - for deposition - constituent IDs
624 0 : call cnst_get_ind('DMS', id_DMS, abort=.False.)
625 0 : call cnst_get_ind('MENO3', id_MENO3, abort=.False.)
626 0 : call cnst_get_ind('ETNO3', id_ETNO3, abort=.False.)
627 0 : call cnst_get_ind('ACET', id_ACET, abort=.False.)
628 0 : if(id_ACET <= 0) then
629 0 : call cnst_get_ind('CH3COCH3', id_ACET, abort=.False.)
630 : endif
631 0 : call cnst_get_ind('ALD2', id_ALD2, abort=.False.)
632 0 : if(id_ALD2 <= 0) then
633 0 : call cnst_get_ind('CH3CHO', id_ALD2, abort=.False.)
634 : endif
635 0 : call cnst_get_ind('MOH', id_MOH, abort=.False.)
636 0 : if(id_MOH <= 0) then
637 0 : call cnst_get_ind('CH3OH', id_MOH, abort=.False.)
638 : endif
639 :
640 : ! Phase 1: Store the fields in hemco_interface (copy)
641 0 : I = 0
642 0 : do lchnk = begchunk, endchunk ! loop over all chunks in the physics grid
643 0 : ncol = get_ncols_p(lchnk) ! columns per chunk
644 0 : pbuf_chnk => pbuf_get_chunk(pbuf2d, lchnk) ! get pbuf for this chunk...
645 :
646 : ! Gather geographical information
647 : ! if(masterproc) write(iulog,*) "* hplin debug in lchnk = ", lchnk, ", ncol = ", ncol, " (max pcols = ", pcols, "), my_CE = ", my_CE
648 0 : call get_rlat_all_p(lchnk, ncol, lchnk_rlats)
649 0 : call get_rlon_all_p(lchnk, ncol, lchnk_rlons)
650 :
651 : ! Compute zenith for chunk
652 : ! (could also do it all at once but it would require a separate buffer to store ll...)
653 : ! FIXME hplin: this slicing might be a little inefficient
654 0 : call zenith(calday, lchnk_rlats(1:ncol), lchnk_rlons(1:ncol), lchnk_zenith(1:ncol), ncol)
655 :
656 : ! Gather data from pbuf before we proceed
657 : ! 2-D Fields: Write directly to pointer (does not need alloc).
658 0 : call pbuf_get_field(pbuf_chnk, index_pblh, pbuf_tmp_pblh)
659 :
660 0 : if(feat_JValues) then
661 0 : call pbuf_get_field(pbuf_chnk, index_JNO2, pbuf_tmp_JNO2)
662 0 : call pbuf_get_field(pbuf_chnk, index_JOH, pbuf_tmp_JOH )
663 : endif
664 :
665 : ! Loop through the chunks and levs now
666 : ! Sanity check: Left indices should be I, and r.h.s. should be J!!!
667 : ! If it differs, you are likely wrong and reading out of bounds.
668 : ! Two hours of debugging a 1.5GPa surface pressure entry has resulted
669 : ! in the above comments. (hplin, 3/31/20)
670 0 : do J = 1, ncol ! loop over columns in the chunk
671 0 : I = I + 1 ! advance one column
672 :
673 : ! 3-D Fields
674 0 : do K = 1, LM ! chunk col, lev
675 0 : State_CAM_t(K,I) = phys_state(lchnk)%t(J,K)
676 :
677 : ! FIXME: hplin, check if indices actually exist!!
678 : ! Chemical concentrations should be in MMR [kg/kg air]
679 0 : State_CAM_chmO3(K,I) = phys_state(lchnk)%q(J,K,id_O3)
680 0 : State_CAM_chmNO(K,I) = phys_state(lchnk)%q(J,K,id_NO)
681 0 : State_CAM_chmNO2(K,I) = phys_state(lchnk)%q(J,K,id_NO2)
682 0 : State_CAM_chmHNO3(K,I) = phys_state(lchnk)%q(J,K,id_HNO3)
683 : enddo
684 :
685 : ! Verify and retrieve surface fluxes for deposition, if available (hplin, 5/7/21)
686 0 : if(id_DMS > 0) State_CAM_chmDMS (I) = phys_state(lchnk)%q(J,LM,id_DMS )
687 0 : if(id_MENO3 > 0) State_CAM_chmMENO3(I) = phys_state(lchnk)%q(J,LM,id_MENO3)
688 0 : if(id_ETNO3 > 0) State_CAM_chmETNO3(I) = phys_state(lchnk)%q(J,LM,id_ETNO3)
689 0 : if(id_ACET > 0) State_CAM_chmACET(I) = phys_state(lchnk)%q(J,LM,id_ACET)
690 0 : if(id_ALD2 > 0) State_CAM_chmALD2(I) = phys_state(lchnk)%q(J,LM,id_ALD2)
691 0 : if(id_MOH > 0) State_CAM_chmMOH (I) = phys_state(lchnk)%q(J,LM,id_MOH )
692 :
693 : !----------------------------------------
694 : ! 2-D Fields
695 : !----------------------------------------
696 :
697 : ! DEBUG: Write to CSZA as a test for latitude to make sure we are doing correctly
698 : ! State_CAM_CSZA(I) = lchnk_rlats(J)
699 :
700 : ! QV2M [kg H2O/kg air] (MMR -- this is converted to VMR by *MWdry/18 in SeaSalt)
701 : ! at 2M, roughly surface ~ LM (1 is TOA)
702 : ! (hplin, 8/10/22)
703 0 : State_CAM_QV2M(I) = phys_state(lchnk)%q(J,LM,id_Q)
704 :
705 : ! PBLH [m]
706 0 : State_CAM_pblh(I) = pbuf_tmp_pblh(J)
707 :
708 : ! COSZA Cosine of zenith angle [1]
709 0 : State_CAM_CSZA(I) = lchnk_zenith(J)
710 :
711 : ! USTAR Friction velocity [m/s]
712 0 : State_CAM_USTAR(I) = cam_in(lchnk)%fv(J) * cam_in(lchnk)%landFrac(J) + cam_in(lchnk)%uStar(J) * (1.0_r8 - cam_in(lchnk)%landFrac(J))
713 :
714 : ! Sea level pressure [Pa] (note difference in units!!)
715 0 : State_CAM_ps(I) = phys_state(lchnk)%ps(J)
716 :
717 : ! Dry pressure [hPa] (Pa -> hPa, x0.01)
718 0 : State_CAM_psdry(I) = phys_state(lchnk)%psdry(J) * 0.01_r8
719 :
720 : ! Surface temperature [K]
721 0 : if(ExtState%T2M%DoUse) then
722 0 : State_CAM_TS(I) = cam_in(lchnk)%TS(J)
723 : endif
724 :
725 : ! Sea surface temperature [K]
726 : ! DO NOT use TS - the definition in CESM-GC is wrong and will give wrong SST values
727 : ! which are too high, and the ocean being too warm will cause huge issues with Iodine emis.
728 0 : if(ExtState%TSKIN%DoUse) then
729 0 : State_CAM_SST(I) = cam_in(lchnk)%sst(J)
730 : endif
731 :
732 : ! 10M E/W and N/S wind speed [m/s] (fixme: use pver?)
733 0 : if(ExtState%U10M%DoUse) then
734 0 : State_CAM_U10M(I) = phys_state(lchnk)%U(J, pver)
735 0 : State_CAM_V10M(I) = phys_state(lchnk)%V(J, pver)
736 : endif
737 :
738 : ! Visible surface albedo [1]
739 0 : if(ExtState%ALBD%DoUse) then
740 0 : State_CAM_ALBD(I) = cam_in(lchnk)%asdir(J)
741 : endif
742 :
743 : ! Converted-to-Olson land fractions [1] (hplin, 8/10/22)
744 0 : if(ExtState%FRLAND%DoUse) then
745 0 : State_CAM_FRLAND(I) = cam_in(lchnk)%landFrac(J)
746 : endif
747 :
748 : ! FRLANDIC unsupported
749 :
750 0 : if(ExtState%FROCEAN%DoUse) then
751 0 : State_CAM_FROCEAN(I) = cam_in(lchnk)%ocnFrac(J) + cam_in(lchnk)%iceFrac(J)
752 : endif
753 :
754 0 : if(ExtState%FRSEAICE%DoUse) then
755 0 : State_CAM_FRSEAICE(I) = cam_in(lchnk)%iceFrac(J)
756 : endif
757 :
758 : ! FRLAKE unsupported
759 : ! FRSNO unsupported
760 :
761 : ! J-values (from CESM-GC only, at the moment. Added to CAM-chem/mozart 5/16/21)
762 0 : if(feat_JValues .and. .not. FIRST) then
763 0 : State_CAM_JNO2(I) = pbuf_tmp_JNO2(J)
764 0 : State_CAM_JOH (I) = pbuf_tmp_JOH (J)
765 : ! write(6,*) "hplin debug***: jno2, joh j-v", I,J, pbuf_tmp_JNO2(J), pbuf_tmp_JOH(J)
766 : endif
767 : enddo
768 : enddo
769 :
770 : ! The below are stubs and are not regridded or processed for now due to lack of data
771 :
772 0 : if(FIRST) then
773 0 : FIRST = .false.
774 :
775 0 : if(masterproc) then
776 0 : write(iulog,*) "> CAM_GetBefore_HCOI finished, feat_JValues = ", feat_JValues
777 : endif
778 : endif
779 :
780 0 : end subroutine CAM_GetBefore_HCOI
781 : !EOC
782 : !------------------------------------------------------------------------------
783 : ! Harmonized Emissions Component (HEMCO) !
784 : !------------------------------------------------------------------------------
785 : !BOP
786 : !
787 : ! !IROUTINE: CAM_RegridSet_HCOI
788 : !
789 : ! !DESCRIPTION: CAM\_GetBefore\_HCOI populates the internal copy of CAM state
790 : ! within the conversion module to prepare for regridding within the gridcomp.
791 : !\\
792 : !\\
793 : ! !INTERFACE:
794 : !
795 0 : subroutine CAM_RegridSet_HCOI(HcoState, ExtState, Phase)
796 : !
797 : ! !USES:
798 : !
799 : ! Type descriptors
800 0 : use camsrfexch, only: cam_in_t
801 : use physics_types, only: physics_state
802 : use physics_buffer, only: physics_buffer_desc
803 :
804 : ! Physics grid
805 : use phys_grid, only: get_ncols_p
806 :
807 : ! CAM physics buffer (some fields are here and some are in phys state)
808 : use physics_buffer, only: pbuf_get_chunk, pbuf_get_field
809 : use physics_buffer, only: pbuf_get_index
810 :
811 : ! Output and mpi
812 : use cam_logfile, only: iulog
813 : use spmd_utils, only: masterproc, mpicom, masterprocid, iam
814 :
815 : ! HEMCO output container state
816 : USE HCOX_State_Mod, only: ExtDat_Set
817 :
818 : ! Vertical grid specification
819 : use HCO_ESMF_Grid, only: Ap, Bp, AREA_M2
820 :
821 : ! HEMCO utilities
822 : use HCO_GeoTools_Mod, only: HCO_GetSUNCOS
823 : !
824 : ! !INPUT PARAMETERS:
825 : !
826 :
827 : type(HCO_State), pointer :: HcoState
828 : type(Ext_State), pointer :: ExtState
829 : integer :: Phase
830 :
831 : !
832 : ! !REMARKS:
833 : ! Note that arrays in CAM format stored in the HEMCO interface are (k, i) idxd
834 : ! for the regridder
835 : !
836 : ! Also the vertical does not need to be handled here, the CAM2HCO_3D will handle
837 : ! it very nicely for you.
838 : !
839 : ! !REVISION HISTORY:
840 : ! 16 Dec 2020 - H.P. Lin - Initial version
841 : ! 21 Dec 2020 - H.P. Lin - Now also sets ExtState fields appropriately
842 : ! 04 Feb 2021 - H.P. Lin - Also compute air quantities (might have to move to separate later)
843 : ! 03 Mar 2021 - H.P. Lin - Now also computes PBL quantities
844 : ! 03 Mar 2021 - H.P. Lin - Now split into two phases
845 : !EOP
846 : !------------------------------------------------------------------------------
847 : !BOC
848 : !
849 : ! !LOCAL VARIABLES:
850 : !
851 : character(len=*), parameter :: subname = 'CAM_GetBefore_HCOI'
852 : integer :: RC ! ESMF return code
853 :
854 : logical, save :: FIRST = .true.
855 : integer, save :: nCalls = 0
856 :
857 : integer :: I, J, L ! Loop index
858 :
859 : ! Temporary quantities needed for PBL computation
860 : real(r8) :: BLTOP, BLTHIK, DELP
861 : integer :: LTOP
862 :
863 : ! Physical constants from physconstants.F90 (from GEOS-Chem)
864 : ! TODO: Verify consistency with CAM model! (hplin, 3/3/21)
865 : real(r8), parameter :: G0_100 = 100.e+0_r8 / 9.80665e+0_r8
866 : real(r8), parameter :: SCALE_HEIGHT = 7600.0_r8
867 :
868 : ! Assume success
869 0 : RC = ESMF_SUCCESS
870 :
871 0 : nCalls = nCalls + 1
872 :
873 0 : if(masterproc .and. nCalls < 10) then
874 0 : write(iulog,*) "> CAM_RegridSet_HCOI entering", phase
875 : endif
876 :
877 : !-----------------------------------------------------------------------
878 : ! Regrid necessary physics quantities from the CAM grid to the HEMCO grid
879 : ! Phase 1: Regrid
880 : !-----------------------------------------------------------------------
881 0 : if(Phase == 1) then
882 0 : call HCO_Grid_CAM2HCO_2D(State_CAM_ps, State_HCO_PSFC )
883 0 : call HCO_Grid_CAM2HCO_2D(State_CAM_psdry, State_GC_PSC2_DRY)
884 0 : call HCO_Grid_CAM2HCO_2D(State_CAM_pblh, State_HCO_PBLH )
885 0 : call HCO_Grid_CAM2HCO_3D(State_CAM_t, State_HCO_TK )
886 :
887 0 : if(masterproc .and. nCalls < 10) then
888 0 : write(iulog,*) "> CAM_RegridSet_HCOI exiting phase 1"
889 : endif
890 :
891 : return
892 : endif
893 :
894 : ! Below only Phase 2...
895 :
896 : !-----------------------------------------------------------------------
897 : ! Compute air quantities (hplin, 2/4/21)
898 : !-----------------------------------------------------------------------
899 :
900 : ! Unified loop 1 (LJI)
901 0 : do L = 1, LM
902 0 : do J = 1, my_JM
903 0 : do I = 1, my_IM
904 : ! Calculate DELP_DRY (from pressure_mod)
905 0 : State_GC_DELP_DRY(I,J,L) = (Ap(L) + (Bp(L) * State_GC_PSC2_DRY(I,J))) - &
906 0 : (Ap(L+1) + (Bp(L+1) * State_GC_PSC2_DRY(I,J)))
907 :
908 : ! Calculate AD (AIR mass)
909 : ! Note that AREA_M2 are GLOBAL indices so you need to perform offsetting!!
910 : !
911 : ! DELP_DRY is in [hPa]. G0_100 is 100/g, converts to [Pa], and divides by [m/s2] (accel to kg)
912 0 : State_HCO_AIR(I,J,L) = State_GC_DELP_DRY(I,J,L) * G0_100 * AREA_M2(my_IS+I-1,my_JS+J-1)
913 : enddo
914 : enddo
915 : enddo
916 :
917 : ! Populate CAM information equivalent
918 0 : call HCO_Grid_HCO2CAM_2D(State_GC_DELP_DRY(:,:,1), State_CAM_DELP_DRYs)
919 0 : call HCO_Grid_HCO2CAM_2D(State_HCO_AIR(:,:,1), State_CAM_AIRs)
920 :
921 : !-----------------------------------------------------------------------
922 : ! Surface temperature [K] - use both for T2M and TSKIN for now according to CESM-GC,
923 : ! hplin 12/21/2020
924 0 : if(ExtState%T2M%DoUse) then
925 0 : call HCO_Grid_CAM2HCO_2D(State_CAM_TS, State_HCO_TS )
926 :
927 : call ExtDat_Set(HcoState, ExtState%T2M, 'T2M_FOR_EMIS', &
928 0 : RC, FIRST, State_HCO_TS)
929 : endif
930 :
931 : ! Sea surface temperature [K] (hplin 3/20/23)
932 0 : if(ExtState%TSKIN%DoUse) then
933 0 : call HCO_Grid_CAM2HCO_2D(State_CAM_SST, State_HCO_TSKIN)
934 :
935 : call ExtDat_Set(HcoState, ExtState%TSKIN, 'TSKIN_FOR_EMIS', &
936 0 : RC, FIRST, State_HCO_TSKIN)
937 : endif
938 :
939 : ! 10M E/W and N/S wind speed [m/s] (fixme: use pver?)
940 0 : if(ExtState%U10M%DoUse) then
941 0 : call HCO_Grid_CAM2HCO_2D(State_CAM_U10M, State_HCO_U10M)
942 0 : call HCO_Grid_CAM2HCO_2D(State_CAM_V10M, State_HCO_V10M)
943 :
944 : call ExtDat_Set(HcoState, ExtState%U10M, 'U10M_FOR_EMIS', &
945 0 : RC, FIRST, State_HCO_U10M)
946 :
947 : call ExtDat_Set(HcoState, ExtState%V10M, 'V10M_FOR_EMIS', &
948 0 : RC, FIRST, State_HCO_V10M)
949 : endif
950 :
951 : ! Cos of Zenith Angle [1]
952 0 : if(ExtState%SUNCOS%DoUse) then
953 : ! call HCO_Grid_CAM2HCO_2D(State_CAM_CSZA, State_HCO_CSZA)
954 :
955 : ! Use native CSZA from HEMCO for consistency?
956 0 : call HCO_GetSUNCOS(HcoState, State_HCO_CSZA, 0, RC)
957 :
958 : call ExtDat_Set(HcoState, ExtState%SUNCOS,'SUNCOS_FOR_EMIS', &
959 0 : RC, FIRST, State_HCO_CSZA)
960 : endif
961 :
962 : ! Visible surface albedo [1]
963 0 : if(ExtState%ALBD%DoUse) then
964 0 : call HCO_Grid_CAM2HCO_2D(State_CAM_ALBD, State_HCO_ALBD)
965 :
966 : call ExtDat_Set(HcoState, ExtState%ALBD, 'ALBD_FOR_EMIS', &
967 0 : RC, FIRST, State_HCO_ALBD)
968 : endif
969 :
970 : ! Friction velocity
971 0 : if(ExtState%USTAR%DoUse) then
972 0 : call HCO_Grid_CAM2HCO_2D(State_CAM_USTAR, State_HCO_USTAR)
973 :
974 : call ExtDat_Set(HcoState, ExtState%USTAR, 'USTAR_FOR_EMIS', &
975 0 : RC, FIRST, State_HCO_USTAR)
976 : endif
977 :
978 : ! Air mass [kg]
979 0 : if(ExtState%AIR%DoUse) then
980 : ! This is computed above using GC routines for air quantities, so
981 : ! it does not necessitate a regrid from CAM.
982 :
983 : call ExtDat_Set(HcoState, ExtState%AIR, 'AIRMASS_FOR_EMIS', &
984 0 : RC, FIRST, State_HCO_AIR)
985 : endif
986 :
987 : ! Constituents [MMR]
988 0 : if(ExtState%O3%DoUse) then
989 0 : call HCO_Grid_CAM2HCO_3D(State_CAM_chmO3, State_HCO_chmO3)
990 :
991 : call ExtDat_Set(HcoState, ExtState%O3, 'HEMCO_O3_FOR_EMIS', &
992 0 : RC, FIRST, State_HCO_chmO3)
993 : endif
994 :
995 0 : if(ExtState%NO2%DoUse) then
996 0 : call HCO_Grid_CAM2HCO_3D(State_CAM_chmNO2, State_HCO_chmNO2)
997 :
998 : call ExtDat_Set(HcoState, ExtState%NO2, 'HEMCO_NO2_FOR_EMIS', &
999 0 : RC, FIRST, State_HCO_chmNO2)
1000 : endif
1001 :
1002 0 : if(ExtState%NO%DoUse) then
1003 0 : call HCO_Grid_CAM2HCO_3D(State_CAM_chmNO, State_HCO_chmNO)
1004 :
1005 : call ExtDat_Set(HcoState, ExtState%NO, 'HEMCO_NO_FOR_EMIS', &
1006 0 : RC, FIRST, State_HCO_chmNO)
1007 : endif
1008 :
1009 : ! MMR of H2O at 2m [kg H2O/kg air] (2-D only)
1010 0 : if(ExtState%QV2M%DoUse) then
1011 0 : call HCO_Grid_CAM2HCO_2D(State_CAM_QV2M, State_HCO_QV2M)
1012 :
1013 : call ExtDat_Set(HcoState, ExtState%QV2M, 'QV2M_FOR_EMIS', &
1014 0 : RC, FIRST, State_HCO_QV2M)
1015 : endif
1016 :
1017 : ! hplin 3/3/21: Disabling HNO3 for now - not actually used by HEMCO,
1018 : ! not even in ParaNOx (code is commented out)
1019 :
1020 : ! if(ExtState%HNO3%DoUse) then
1021 : ! call HCO_Grid_CAM2HCO_3D(State_CAM_chmHNO3, State_HCO_chmHNO3)
1022 :
1023 : ! call ExtDat_Set(HcoState, ExtState%HNO3, 'HEMCO_HNO3_FOR_EMIS', &
1024 : ! RC, FIRST, State_HCO_chmHNO3)
1025 : ! endif
1026 :
1027 : !-------------------------------------------------------
1028 : ! Compute the PBL fraction (on HEMCO grid) so we avoid an extra regrid.
1029 : ! This code largely ported from GeosCore/pbl_mix_mod.F90
1030 : ! (hplin, 3/3/21)
1031 : !
1032 : ! Note that L = 1 is now surface, since in HEMCO grid the atmos
1033 : ! has already been inverted from the CAM approach (1 as TOA)
1034 : !
1035 : ! Some temporary quantities are needed:
1036 : !
1037 : ! BLTOP = Pressure at PBL top [hPa]
1038 : ! BLTHIK = PBL thickness [hPa]
1039 : ! DELP = Thickness of grid box (I,J,L) [hPa]
1040 : ! LTOP = Level of PBL top [nlev]
1041 : !
1042 : !
1043 : ! Unified Loop 2 (JI, L)
1044 : ! Again, note that loop indices I, J are 1~my_*M because the indices
1045 : ! are not global here (we are in the HEMCO decomp at this point)
1046 : !
1047 : ! Remember, ONLY HCO_ESMF_GRID quantities are GLOBAL indices. Otherwise,
1048 : ! there is a separate HEMCO index for each PE.
1049 : !
1050 : ! TODO: OMP parallel do default(shared) private(i, j, l, bltop, blthik, ltop, delp)
1051 :
1052 0 : do J = 1, my_JM
1053 0 : do I = 1, my_IM
1054 : ! use barometric law for pressure at PBL top
1055 0 : BLTOP = HcoState%Grid%PEDGE%Val(I,J,1) * EXP(-State_HCO_PBLH(I, J)/SCALE_HEIGHT)
1056 :
1057 : ! PBL thickness [hPa]
1058 0 : BLTHIK = HcoState%Grid%PEDGE%Val(I,J,1) - BLTOP
1059 :
1060 : ! Now, find the PBL top level
1061 0 : do L = 1, LM
1062 0 : if(BLTOP > HcoState%Grid%PEDGE%Val(I,J,L+1)) then
1063 : LTOP = L
1064 : exit
1065 : endif
1066 : enddo
1067 :
1068 : ! Find the fraction of grid box (I,J,L) within the PBL
1069 0 : do L = 1, LM
1070 0 : DELP = HcoState%Grid%PEDGE%Val(I,J,L) - HcoState%Grid%PEDGE%Val(I,J,L+1)
1071 : ! ...again, PEDGE goes up to LM+1
1072 :
1073 0 : if(L < LTOP) then
1074 : ! grid cell lies completely below the PBL top
1075 0 : State_HCO_F_OF_PBL(I,J,L) = DELP / BLTHIK
1076 0 : else if(L == LTOP) then
1077 : ! grid cell straddles PBL top
1078 0 : State_HCO_F_OF_PBL(I,J,L) = (HcoState%Grid%PEDGE%Val(I,J,L) - BLTOP) / BLTHIK
1079 : else
1080 : ! grid cells lies completely above the PBL top
1081 0 : State_HCO_F_OF_PBL(I,J,L) = 0.0
1082 : endif
1083 :
1084 : ! write(6,*) "I,J/L", I, J, L, ": F_OF_PBL", State_HCO_F_OF_PBL(I,J,L)
1085 : enddo
1086 : enddo
1087 : enddo
1088 :
1089 0 : if(ExtState%FRAC_OF_PBL%DoUse) then
1090 : call ExtDat_Set(HcoState, ExtState%FRAC_OF_PBL, 'FRAC_OF_PBL_FOR_EMIS', &
1091 0 : RC, FIRST, State_HCO_F_OF_PBL)
1092 : endif
1093 :
1094 : ! J-values - if supported
1095 0 : if(ExtState%JOH%DoUse .or. ExtState%JNO2%DoUse) then
1096 0 : if(feat_JValues) then
1097 0 : call HCO_Grid_CAM2HCO_2D(State_CAM_JOH, State_HCO_JOH)
1098 :
1099 : call ExtDat_Set(HcoState, ExtState%JOH, 'JOH_FOR_EMIS', &
1100 0 : RC, FIRST, State_HCO_JOH)
1101 :
1102 0 : call HCO_Grid_CAM2HCO_2D(State_CAM_JNO2, State_HCO_JNO2)
1103 :
1104 : call ExtDat_Set(HcoState, ExtState%JNO2, 'JNO2_FOR_EMIS', &
1105 0 : RC, FIRST, State_HCO_JNO2)
1106 : else
1107 0 : call endrun('hco_cam_convert_state_mod: requested J-values fields but J-value field unsupported, check chem or disable ParaNOx')
1108 : endif
1109 : endif
1110 :
1111 0 : if(ExtState%FRLAND%DoUse) then
1112 0 : call HCO_Grid_CAM2HCO_2D(State_CAM_FRLAND, State_HCO_FRLAND)
1113 : call ExtDat_Set(HcoState, ExtState%FRLAND, 'FRLAND_FOR_EMIS', &
1114 0 : RC, FIRST, State_HCO_FRLAND)
1115 : endif
1116 :
1117 0 : if(ExtState%FRLANDIC%DoUse) then
1118 : ! Unsupported - State_HCO_FRLANDIC is always zero
1119 : call ExtDat_Set(HcoState, ExtState%FRLANDIC, 'FRLANDIC_FOR_EMIS', &
1120 0 : RC, FIRST, State_HCO_FRLANDIC)
1121 : endif
1122 :
1123 0 : if(ExtState%FROCEAN%DoUse) then
1124 0 : call HCO_Grid_CAM2HCO_2D(State_CAM_FROCEAN, State_HCO_FROCEAN)
1125 : call ExtDat_Set(HcoState, ExtState%FROCEAN, 'FROCEAN_FOR_EMIS', &
1126 0 : RC, FIRST, State_HCO_FROCEAN)
1127 : endif
1128 :
1129 0 : if(ExtState%FRSEAICE%DoUse) then
1130 0 : call HCO_Grid_CAM2HCO_2D(State_CAM_FRSEAICE, State_HCO_FRSEAICE)
1131 : call ExtDat_Set(HcoState, ExtState%FRSEAICE, 'FRSEAICE_FOR_EMIS', &
1132 0 : RC, FIRST, State_HCO_FRSEAICE)
1133 : endif
1134 :
1135 0 : if(ExtState%FRLAKE%DoUse) then
1136 : ! Unsupported - State_HCO_FRLAKE is always zero
1137 : call ExtDat_Set(HcoState, ExtState%FRLAKE, 'FRLAKE_FOR_EMIS', &
1138 0 : RC, FIRST, State_HCO_FRLAKE)
1139 : endif
1140 :
1141 0 : if(FIRST) then
1142 0 : FIRST = .false.
1143 : endif
1144 :
1145 0 : if(masterproc .and. nCalls < 10) then
1146 0 : write(iulog,*) "> CAM_RegridSet_HCOI finished"
1147 : endif
1148 :
1149 : ! Debugging code
1150 : ! write(6,*) "HCO - PBLH(:,:), min, max", minval(State_HCO_PBLH(:,:)), maxval(State_HCO_PBLH(:,:))
1151 : ! write(6,*) State_HCO_PBLH(:,:)
1152 :
1153 : ! write(6,*) "CAM - PBLH(:,:), min, max", minval(State_CAM_pblh(:)), maxval(State_CAM_pblh(:))
1154 : ! write(6,*) State_CAM_pblh(:)
1155 :
1156 : ! write(6,*) "HCO - PSFC(:,:), min, max", minval(State_HCO_PSFC(:,:)), maxval(State_HCO_PSFC(:,:))
1157 : ! write(6,*) State_HCO_PSFC(:,:)
1158 :
1159 : ! write(6,*) "CAM - ps(:,:), min, max", minval(State_CAM_ps(:)), maxval(State_CAM_ps(:))
1160 : ! write(6,*) State_CAM_ps(:)
1161 :
1162 : ! write(6,*) "HCO - TK(:,:,1), min, max (gl)", minval(State_HCO_TK(:,:,:)), maxval(State_HCO_TK(:,:,:))
1163 : ! write(6,*) State_HCO_TK(:,:,1)
1164 :
1165 : ! write(6,*) "CAM - TK(:,:), min, max", minval(State_CAM_t(1,:)), maxval(State_CAM_t(1,:))
1166 : ! write(6,*) State_CAM_t(1,:)
1167 0 : end subroutine CAM_RegridSet_HCOI
1168 : !EOC
1169 : end module hco_cam_convert_state_mod
|