Line data Source code
1 : module chemistry
2 :
3 : !---------------------------------------------------------------------------------
4 : ! "Interactive" gas phase module
5 : !---------------------------------------------------------------------------------
6 :
7 : use shr_kind_mod, only : r8 => shr_kind_r8, shr_kind_cl
8 : use ppgrid, only : pcols, pver, begchunk, endchunk
9 : use physconst, only : gravit
10 : use constituents, only : pcnst, cnst_add, cnst_name, cnst_fixed_ubc
11 : use chem_mods, only : gas_pcnst
12 : use cam_history, only : fieldname_len
13 : use physics_types, only : physics_state, physics_ptend, physics_ptend_init
14 : use spmd_utils, only : masterproc
15 : use cam_logfile, only : iulog
16 : use mo_gas_phase_chemdr, only : map2chm
17 : use shr_megan_mod, only : shr_megan_mechcomps, shr_megan_mechcomps_n
18 : use srf_field_check, only : active_Fall_flxvoc
19 : use tracer_data, only : MAXTRCRS
20 : use gcr_ionization, only : gcr_ionization_readnl, gcr_ionization_init, gcr_ionization_adv
21 : use epp_ionization, only : epp_ionization_readnl, epp_ionization_adv
22 : use mee_ionization, only : mee_ion_readnl
23 : use mo_apex, only : mo_apex_readnl
24 : use ref_pres, only : ptop_ref
25 : use phys_control, only : waccmx_is ! WACCM-X switch query function
26 : use phys_control, only : use_hemco ! HEMCO switch logical
27 :
28 : implicit none
29 : private
30 : save
31 :
32 : !---------------------------------------------------------------------------------
33 : ! Public interfaces
34 : !---------------------------------------------------------------------------------
35 : public :: chem_is ! identify which chemistry is being used
36 : public :: chem_register ! register consituents
37 : public :: chem_readnl ! read chem namelist
38 : public :: chem_is_active ! returns true
39 : public :: chem_implements_cnst ! returns true if consituent is implemented by this package
40 : public :: chem_init_cnst ! initialize mixing ratios if not read from initial file
41 : public :: chem_init ! initialize (history) variables
42 : public :: chem_timestep_init ! per timestep initializations
43 : public :: chem_timestep_tend ! interface to tendency computation
44 : public :: chem_final
45 : public :: chem_write_restart
46 : public :: chem_read_restart
47 : public :: chem_init_restart
48 : public :: chem_emissions
49 :
50 : integer, public :: imozart = -1 ! index of 1st constituent
51 :
52 : ! Namelist variables
53 :
54 : ! control
55 :
56 : integer :: chem_freq = 1 ! time steps
57 :
58 : ! ghg
59 :
60 : character(len=shr_kind_cl) :: bndtvg = ' ' ! pathname for greenhouse gas loss rate
61 : character(len=shr_kind_cl) :: h2orates = ' ' ! pathname for greenhouse gas (lyman-alpha H2O loss)
62 :
63 : ! photolysis
64 :
65 : character(len=shr_kind_cl) :: rsf_file = 'rsf_file'
66 : character(len=shr_kind_cl) :: exo_coldens_file = ''
67 : character(len=shr_kind_cl) :: xs_coef_file = 'xs_coef_file'
68 : character(len=shr_kind_cl) :: xs_short_file = 'xs_short_file'
69 : character(len=shr_kind_cl) :: xs_long_file = 'xs_long_file'
70 : character(len=shr_kind_cl) :: electron_file = 'electron_file'
71 : character(len=shr_kind_cl) :: euvac_file = 'NONE'
72 : real(r8) :: photo_max_zen=-huge(1._r8)
73 :
74 : ! solar / geomag data
75 :
76 : character(len=shr_kind_cl) :: photon_file = 'photon_file'
77 :
78 : ! dry dep
79 :
80 : character(len=shr_kind_cl) :: depvel_lnd_file = 'depvel_lnd_file'
81 :
82 : ! emis
83 : integer, parameter :: max_num_emis_files = max(100,2*pcnst)
84 : character(len=shr_kind_cl) :: airpl_emis_file = '' ! airplane emissions
85 : character(len=shr_kind_cl) :: srf_emis_specifier(max_num_emis_files) = ''
86 : character(len=shr_kind_cl) :: ext_frc_specifier(max_num_emis_files) = ''
87 :
88 : character(len=24) :: srf_emis_type = 'CYCLICAL' ! 'CYCLICAL' | 'SERIAL' | 'INTERP_MISSING_MONTHS'
89 : integer :: srf_emis_cycle_yr = 0
90 : integer :: srf_emis_fixed_ymd = 0
91 : integer :: srf_emis_fixed_tod = 0
92 :
93 : character(len=24) :: ext_frc_type = 'CYCLICAL' ! 'CYCLICAL' | 'SERIAL' | 'INTERP_MISSING_MONTHS'
94 : integer :: ext_frc_cycle_yr = 0
95 : integer :: ext_frc_fixed_ymd = 0
96 : integer :: ext_frc_fixed_tod = 0
97 :
98 : ! fixed stratosphere
99 :
100 : character(len=shr_kind_cl) :: fstrat_file = 'fstrat_file'
101 : character(len=16) :: fstrat_list(pcnst) = ''
102 :
103 : !---------------------------------------------------------------------------------
104 : ! dummy values for specific heats at constant pressure
105 : !---------------------------------------------------------------------------------
106 : real(r8), parameter :: cptmp = 666._r8
107 :
108 : character(len=fieldname_len) :: srcnam(gas_pcnst) ! names of source/sink tendencies
109 :
110 : integer :: ixcldliq ! index of liquid cloud water
111 : integer :: ndx_cld
112 : integer :: ndx_cmfdqr
113 : integer :: ndx_nevapr
114 : integer :: ndx_prain
115 : integer :: ndx_cldtop
116 : integer :: h2o_ndx
117 : integer :: ixndrop ! cloud droplet number index
118 : integer :: ndx_pblh
119 : integer :: ndx_fsds
120 :
121 : logical :: ghg_chem = .false. ! .true. => use ghg chem package
122 : logical :: chem_step = .true.
123 : logical :: is_active = .false.
124 :
125 : character(len=32) :: chem_name = 'NONE'
126 : logical :: chem_rad_passive = .false.
127 :
128 : ! for MEGAN emissions
129 : integer, allocatable :: megan_indices_map(:)
130 : real(r8),allocatable :: megan_wght_factors(:)
131 :
132 : logical :: chem_use_chemtrop = .false.
133 :
134 : integer :: srf_ozone_pbf_ndx = -1
135 : logical :: srf_emis_diag(pcnst) = .false.
136 :
137 : !================================================================================================
138 : contains
139 : !================================================================================================
140 :
141 768 : logical function chem_is (name)
142 : use phys_control, only : cam_chempkg_is
143 :
144 : character(len=*), intent(in) :: name
145 0 : chem_is = cam_chempkg_is(name)
146 :
147 0 : end function chem_is
148 :
149 : !================================================================================================
150 :
151 1536 : subroutine chem_register
152 : !-----------------------------------------------------------------------
153 : !
154 : ! Purpose: register advected constituents and physics buffer fields
155 : !
156 : !-----------------------------------------------------------------------
157 :
158 : use mo_sim_dat, only : set_sim_dat
159 : use chem_mods, only : gas_pcnst, adv_mass
160 : use mo_tracname, only : solsym
161 : use mo_chem_utls, only : get_spc_ndx, get_inv_ndx
162 : use short_lived_species, only : slvd_index, short_lived_map=>map, register_short_lived_species
163 : use cfc11star, only : register_cfc11star
164 : use mo_photo, only : photo_register
165 : use mo_aurora, only : aurora_register
166 : use aero_model, only : aero_model_register
167 : use physics_buffer, only : pbuf_add_field, dtype_r8
168 : use upper_bc, only : ubc_fixed_conc
169 :
170 : implicit none
171 :
172 : !-----------------------------------------------------------------------
173 : ! Local variables
174 : !-----------------------------------------------------------------------
175 : integer :: m, n ! tracer index
176 : real(r8) :: qmin ! min value
177 : logical :: ic_from_cam2 ! wrk variable for initial cond input
178 : logical :: has_fixed_ubc ! wrk variable for upper bndy cond
179 : logical :: has_fixed_ubflx ! wrk variable for upper bndy flux
180 : integer :: ch4_ndx, n2o_ndx, o3_ndx, o3_inv_ndx, ndx
181 : integer :: cfc11_ndx, cfc12_ndx, o2_1s_ndx, o2_1d_ndx, o2_ndx
182 : integer :: n_ndx, no_ndx, h_ndx, h2_ndx, o_ndx, e_ndx, np_ndx
183 : integer :: op_ndx, o1d_ndx, n2d_ndx, nop_ndx, n2p_ndx, o2p_ndx
184 : integer :: hf_ndx, f_ndx
185 :
186 : character(len=128) :: lng_name ! variable long name
187 : logical :: cam_outfld
188 : character(len=128) :: mixtype
189 : character(len=128) :: molectype
190 : integer :: islvd
191 :
192 : !-----------------------------------------------------------------------
193 : ! Set the simulation chemistry variables
194 : !-----------------------------------------------------------------------
195 1536 : call set_sim_dat
196 :
197 1536 : o3_ndx = get_spc_ndx('O3')
198 1536 : o3_inv_ndx= get_inv_ndx('O3')
199 1536 : ch4_ndx = get_spc_ndx('CH4')
200 1536 : n2o_ndx = get_spc_ndx('N2O')
201 :
202 1536 : cfc11_ndx = get_spc_ndx('CFC11')
203 1536 : cfc12_ndx = get_spc_ndx('CFC12')
204 1536 : o2_1s_ndx = get_spc_ndx('O2_1S')
205 1536 : o2_1d_ndx = get_spc_ndx('O2_1D')
206 1536 : o2_ndx = get_spc_ndx('O2')
207 : n_ndx = get_spc_ndx('N')
208 : no_ndx = get_spc_ndx('NO')
209 1536 : h_ndx = get_spc_ndx('H')
210 : h2_ndx = get_spc_ndx('H2')
211 1536 : o_ndx = get_spc_ndx('O')
212 1536 : e_ndx = get_spc_ndx('e')
213 1536 : np_ndx = get_spc_ndx('Np')
214 1536 : op_ndx = get_spc_ndx('Op')
215 1536 : o1d_ndx = get_spc_ndx('O1D')
216 1536 : n2d_ndx = get_spc_ndx('N2D')
217 1536 : n2p_ndx = get_spc_ndx('N2p')
218 1536 : nop_ndx = get_spc_ndx('NOp')
219 1536 : h2o_ndx = get_spc_ndx('H2O')
220 1536 : o2p_ndx = get_spc_ndx('O2p')
221 :
222 : f_ndx = get_spc_ndx('F')
223 : hf_ndx = get_spc_ndx('HF')
224 :
225 1536 : if (o3_ndx>0 .or. o3_inv_ndx>0) then
226 1536 : call pbuf_add_field('SRFOZONE','global',dtype_r8,(/pcols/),srf_ozone_pbf_ndx)
227 : endif
228 :
229 : !-----------------------------------------------------------------------
230 : ! Set names of diffused variable tendencies and declare them as history variables
231 : !-----------------------------------------------------------------------
232 : !----------------------------------------------------------------------------------
233 : ! For WACCM-X, change variable has_fixed_ubc from .true. to .false. which is a flag
234 : ! used later to check for a fixed upper boundary condition for species.
235 : !----------------------------------------------------------------------------------
236 49152 : do m = 1,gas_pcnst
237 : ! setting of these variables is for registration of transported species
238 47616 : ic_from_cam2 = .true.
239 47616 : has_fixed_ubc = ubc_fixed_conc(solsym(m))
240 47616 : has_fixed_ubflx = .false.
241 47616 : lng_name = trim( solsym(m) )
242 47616 : molectype = 'minor'
243 :
244 47616 : qmin = 1.e-36_r8
245 :
246 47616 : if ( lng_name(1:5) .eq. 'num_a' ) then ! aerosol number density
247 6144 : qmin = 1.e-5_r8
248 41472 : else if ( m == o3_ndx ) then
249 0 : qmin = 1.e-12_r8
250 41472 : else if ( m == ch4_ndx ) then
251 1536 : qmin = 1.e-12_r8
252 39936 : else if ( m == n2o_ndx ) then
253 1536 : qmin = 1.e-15_r8
254 38400 : else if( m == cfc11_ndx .or. m == cfc12_ndx ) then
255 3072 : qmin = 1.e-20_r8
256 35328 : else if( m == o2_1s_ndx .or. m == o2_1d_ndx ) then
257 0 : ic_from_cam2 = .false.
258 0 : if( m == o2_1d_ndx ) then
259 0 : lng_name = 'O2(1-delta)'
260 : else
261 0 : lng_name = 'O2(1-sigma)'
262 : end if
263 35328 : else if ( m==o2_ndx .or. m==o_ndx .or. m==h_ndx ) then
264 0 : if ( waccmx_is('ionosphere') .or. waccmx_is('neutral') ) then
265 0 : if ( m == h_ndx ) has_fixed_ubflx = .true. ! fixed flux value for H at UB
266 0 : if ( m == o2_ndx .or. m == o_ndx ) molectype = 'major'
267 : endif
268 35328 : else if( m == e_ndx ) then
269 0 : lng_name = 'electron concentration'
270 35328 : else if( m == np_ndx ) then
271 0 : lng_name = 'N+'
272 35328 : else if( m == op_ndx ) then
273 0 : lng_name = 'O+'
274 35328 : else if( m == o1d_ndx ) then
275 0 : lng_name = 'O(1D)'
276 35328 : else if( m == n2d_ndx ) then
277 0 : lng_name = 'N(2D)'
278 35328 : else if( m == o2p_ndx ) then
279 0 : lng_name = 'O2+'
280 35328 : else if( m == n2p_ndx ) then
281 0 : lng_name = 'N2+'
282 35328 : else if( m == nop_ndx ) then
283 0 : lng_name = 'NO+'
284 35328 : else if( m == h2o_ndx ) then
285 1536 : map2chm(1) = m
286 1536 : cycle
287 : endif
288 :
289 46080 : cam_outfld=.false.
290 46080 : is_active = .true.
291 46080 : mixtype = 'dry'
292 :
293 46080 : islvd = slvd_index(solsym(m))
294 :
295 47616 : if ( islvd > 0 ) then
296 0 : short_lived_map(islvd) = m
297 : else
298 : call cnst_add( solsym(m), adv_mass(m), cptmp, qmin, n, readiv=ic_from_cam2, cam_outfld=cam_outfld, &
299 : mixtype=mixtype, molectype=molectype, fixed_ubc=has_fixed_ubc, fixed_ubflx=has_fixed_ubflx, &
300 46080 : longname=trim(lng_name) )
301 :
302 46080 : if( imozart == -1 ) then
303 1536 : imozart = n
304 : end if
305 46080 : map2chm(n) = m
306 : endif
307 :
308 : end do
309 :
310 1536 : call register_short_lived_species()
311 1536 : call register_cfc11star()
312 :
313 1536 : if ( waccmx_is('ionosphere') ) then
314 0 : call photo_register()
315 0 : call aurora_register()
316 : endif
317 :
318 : ! add fields to pbuf needed by aerosol models
319 1536 : call aero_model_register()
320 :
321 1536 : end subroutine chem_register
322 :
323 : !================================================================================================
324 :
325 1536 : subroutine chem_readnl(nlfile)
326 :
327 : ! Read chem namelist group.
328 :
329 1536 : use cam_abortutils, only: endrun
330 : use namelist_utils, only: find_group_name
331 : use units, only: getunit, freeunit
332 : use mpishorthand
333 :
334 : use tracer_cnst, only: tracer_cnst_defaultopts, tracer_cnst_setopts
335 : use tracer_srcs, only: tracer_srcs_defaultopts, tracer_srcs_setopts
336 : use aero_model, only: aero_model_readnl
337 : use dust_model, only: dust_readnl
338 : use gas_wetdep_opts, only: gas_wetdep_readnl
339 : use mo_drydep, only: drydep_srf_file
340 : use mo_sulf, only: sulf_readnl
341 : use species_sums_diags,only: species_sums_readnl
342 : use ocean_emis, only: ocean_emis_readnl
343 :
344 : ! args
345 :
346 : character(len=*), intent(in) :: nlfile ! filepath for file containing namelist input
347 :
348 : ! local vars
349 : integer :: unitn, ierr
350 :
351 : ! trop_mozart prescribed constituent concentratons
352 : character(len=shr_kind_cl) :: tracer_cnst_file ! prescribed data file
353 : character(len=shr_kind_cl) :: tracer_cnst_filelist ! list of prescribed data files (series of files)
354 : character(len=shr_kind_cl) :: tracer_cnst_datapath ! absolute path of prescribed data files
355 : character(len=24) :: tracer_cnst_type ! 'INTERP_MISSING_MONTHS' | 'CYCLICAL' | 'SERIAL' (default)
356 : character(len=shr_kind_cl) :: tracer_cnst_specifier(MAXTRCRS) ! string array where each
357 : logical :: tracer_cnst_rmfile ! remove data file from local disk (default .false.)
358 : integer :: tracer_cnst_cycle_yr
359 : integer :: tracer_cnst_fixed_ymd
360 : integer :: tracer_cnst_fixed_tod
361 :
362 : ! trop_mozart prescribed constituent sourrces/sinks
363 : character(len=shr_kind_cl) :: tracer_srcs_file ! prescribed data file
364 : character(len=shr_kind_cl) :: tracer_srcs_filelist ! list of prescribed data files (series of files)
365 : character(len=shr_kind_cl) :: tracer_srcs_datapath ! absolute path of prescribed data files
366 : character(len=24) :: tracer_srcs_type ! 'INTERP_MISSING_MONTHS' | 'CYCLICAL' | 'SERIAL' (default)
367 : character(len=shr_kind_cl) :: tracer_srcs_specifier(MAXTRCRS) ! string array where each
368 : logical :: tracer_srcs_rmfile ! remove data file from local disk (default .false.)
369 : integer :: tracer_srcs_cycle_yr
370 : integer :: tracer_srcs_fixed_ymd
371 : integer :: tracer_srcs_fixed_tod
372 :
373 : namelist /chem_inparm/ chem_freq, airpl_emis_file, &
374 : euvac_file, photon_file, electron_file, &
375 : xs_coef_file, xs_short_file, &
376 : exo_coldens_file, &
377 : xs_long_file, rsf_file, photo_max_zen, &
378 : depvel_lnd_file, drydep_srf_file, &
379 : srf_emis_type, srf_emis_cycle_yr, srf_emis_fixed_ymd, srf_emis_fixed_tod, srf_emis_specifier, &
380 : fstrat_file, fstrat_list, &
381 : ext_frc_specifier, ext_frc_type, ext_frc_cycle_yr, ext_frc_fixed_ymd, ext_frc_fixed_tod
382 :
383 : namelist /chem_inparm/ chem_rad_passive
384 :
385 : ! ghg chem
386 :
387 : namelist /chem_inparm/ bndtvg, h2orates, ghg_chem
388 :
389 : ! prescribed chem tracers
390 :
391 : namelist /chem_inparm/ &
392 : tracer_cnst_file, tracer_cnst_filelist, tracer_cnst_datapath, &
393 : tracer_cnst_type, tracer_cnst_specifier, &
394 : tracer_srcs_file, tracer_srcs_filelist, tracer_srcs_datapath, &
395 : tracer_srcs_type, tracer_srcs_specifier, &
396 : tracer_cnst_rmfile, tracer_cnst_cycle_yr, tracer_cnst_fixed_ymd, tracer_cnst_fixed_tod, &
397 : tracer_srcs_rmfile, tracer_srcs_cycle_yr, tracer_srcs_fixed_ymd, tracer_srcs_fixed_tod
398 :
399 : ! tropopause level control
400 : namelist /chem_inparm/ chem_use_chemtrop
401 :
402 : ! get the default settings
403 :
404 : call tracer_cnst_defaultopts( &
405 : tracer_cnst_file_out = tracer_cnst_file, &
406 : tracer_cnst_filelist_out = tracer_cnst_filelist, &
407 : tracer_cnst_datapath_out = tracer_cnst_datapath, &
408 : tracer_cnst_type_out = tracer_cnst_type, &
409 : tracer_cnst_specifier_out = tracer_cnst_specifier, &
410 : tracer_cnst_rmfile_out = tracer_cnst_rmfile, &
411 : tracer_cnst_cycle_yr_out = tracer_cnst_cycle_yr, &
412 : tracer_cnst_fixed_ymd_out = tracer_cnst_fixed_ymd, &
413 1536 : tracer_cnst_fixed_tod_out = tracer_cnst_fixed_tod )
414 : call tracer_srcs_defaultopts( &
415 : tracer_srcs_file_out = tracer_srcs_file, &
416 : tracer_srcs_filelist_out = tracer_srcs_filelist, &
417 : tracer_srcs_datapath_out = tracer_srcs_datapath, &
418 : tracer_srcs_type_out = tracer_srcs_type, &
419 : tracer_srcs_specifier_out = tracer_srcs_specifier, &
420 : tracer_srcs_rmfile_out = tracer_srcs_rmfile, &
421 : tracer_srcs_cycle_yr_out = tracer_srcs_cycle_yr, &
422 : tracer_srcs_fixed_ymd_out = tracer_srcs_fixed_ymd, &
423 1536 : tracer_srcs_fixed_tod_out = tracer_srcs_fixed_tod )
424 :
425 1536 : if (masterproc) then
426 2 : unitn = getunit()
427 2 : open( unitn, file=trim(nlfile), status='old' )
428 2 : call find_group_name(unitn, 'chem_inparm', status=ierr)
429 2 : if (ierr == 0) then
430 2 : read(unitn, chem_inparm, iostat=ierr)
431 2 : if (ierr /= 0) then
432 0 : call endrun('chem_readnl: ERROR reading namelist')
433 : end if
434 : end if
435 2 : close(unitn)
436 2 : call freeunit(unitn)
437 : end if
438 :
439 : #ifdef SPMD
440 : ! Broadcast namelist variables
441 :
442 : ! control
443 :
444 1536 : call mpibcast (chem_freq, 1, mpiint, 0, mpicom)
445 :
446 1536 : call mpibcast (chem_rad_passive, 1, mpilog, 0, mpicom)
447 :
448 : ! ghg
449 :
450 1536 : call mpibcast (ghg_chem, 1, mpilog, 0, mpicom)
451 1536 : call mpibcast (bndtvg, len(bndtvg), mpichar, 0, mpicom)
452 1536 : call mpibcast (h2orates, len(h2orates), mpichar, 0, mpicom)
453 :
454 : ! photolysis
455 :
456 1536 : call mpibcast (rsf_file, len(rsf_file), mpichar, 0, mpicom)
457 1536 : call mpibcast (exo_coldens_file, len(exo_coldens_file), mpichar, 0, mpicom)
458 1536 : call mpibcast (xs_coef_file, len(xs_coef_file), mpichar, 0, mpicom)
459 1536 : call mpibcast (xs_short_file, len(xs_short_file), mpichar, 0, mpicom)
460 1536 : call mpibcast (xs_long_file, len(xs_long_file), mpichar, 0, mpicom)
461 1536 : call mpibcast (photo_max_zen, 1, mpir8, 0, mpicom)
462 1536 : call mpibcast (electron_file, len(electron_file), mpichar, 0, mpicom)
463 1536 : call mpibcast (euvac_file, len(euvac_file), mpichar, 0, mpicom)
464 :
465 : ! solar / geomag data
466 :
467 1536 : call mpibcast (photon_file, len(photon_file), mpichar, 0, mpicom)
468 :
469 : ! dry dep
470 :
471 1536 : call mpibcast (depvel_lnd_file, len(depvel_lnd_file), mpichar, 0, mpicom)
472 1536 : call mpibcast (drydep_srf_file, len(drydep_srf_file), mpichar, 0, mpicom)
473 :
474 : ! emis
475 :
476 1536 : call mpibcast (airpl_emis_file, len(airpl_emis_file), mpichar, 0, mpicom)
477 1536 : call mpibcast (srf_emis_specifier,len(srf_emis_specifier(1))*pcnst,mpichar, 0, mpicom)
478 1536 : call mpibcast (srf_emis_type, len(srf_emis_type), mpichar, 0, mpicom)
479 1536 : call mpibcast (srf_emis_cycle_yr, 1, mpiint, 0, mpicom)
480 1536 : call mpibcast (srf_emis_fixed_ymd,1, mpiint, 0, mpicom)
481 1536 : call mpibcast (srf_emis_fixed_tod,1, mpiint, 0, mpicom)
482 1536 : call mpibcast (ext_frc_specifier, len(ext_frc_specifier(1))*pcnst, mpichar, 0, mpicom)
483 1536 : call mpibcast (ext_frc_type, len(ext_frc_type), mpichar, 0, mpicom)
484 1536 : call mpibcast (ext_frc_cycle_yr, 1, mpiint, 0, mpicom)
485 1536 : call mpibcast (ext_frc_fixed_ymd, 1, mpiint, 0, mpicom)
486 1536 : call mpibcast (ext_frc_fixed_tod, 1, mpiint, 0, mpicom)
487 :
488 :
489 : ! fixed stratosphere
490 :
491 1536 : call mpibcast (fstrat_file, len(fstrat_file), mpichar, 0, mpicom)
492 1536 : call mpibcast (fstrat_list, len(fstrat_list(1))*pcnst, mpichar, 0, mpicom)
493 :
494 : ! prescribed chemical tracers
495 :
496 1536 : call mpibcast (tracer_cnst_specifier, len(tracer_cnst_specifier(1))*MAXTRCRS, mpichar, 0, mpicom)
497 1536 : call mpibcast (tracer_cnst_file, len(tracer_cnst_file), mpichar, 0, mpicom)
498 1536 : call mpibcast (tracer_cnst_filelist, len(tracer_cnst_filelist), mpichar, 0, mpicom)
499 1536 : call mpibcast (tracer_cnst_datapath, len(tracer_cnst_datapath), mpichar, 0, mpicom)
500 1536 : call mpibcast (tracer_cnst_type, len(tracer_cnst_type), mpichar, 0, mpicom)
501 1536 : call mpibcast (tracer_cnst_rmfile, 1, mpilog, 0, mpicom)
502 1536 : call mpibcast (tracer_cnst_cycle_yr, 1, mpiint, 0, mpicom)
503 1536 : call mpibcast (tracer_cnst_fixed_ymd, 1, mpiint, 0, mpicom)
504 1536 : call mpibcast (tracer_cnst_fixed_tod, 1, mpiint, 0, mpicom)
505 :
506 1536 : call mpibcast (tracer_srcs_specifier, len(tracer_srcs_specifier(1))*MAXTRCRS, mpichar, 0, mpicom)
507 1536 : call mpibcast (tracer_srcs_file, len(tracer_srcs_file), mpichar, 0, mpicom)
508 1536 : call mpibcast (tracer_srcs_filelist, len(tracer_srcs_filelist), mpichar, 0, mpicom)
509 1536 : call mpibcast (tracer_srcs_datapath, len(tracer_srcs_datapath), mpichar, 0, mpicom)
510 1536 : call mpibcast (tracer_srcs_type, len(tracer_srcs_type), mpichar, 0, mpicom)
511 1536 : call mpibcast (tracer_srcs_rmfile, 1, mpilog, 0, mpicom)
512 1536 : call mpibcast (tracer_srcs_cycle_yr, 1, mpiint, 0, mpicom)
513 1536 : call mpibcast (tracer_srcs_fixed_ymd, 1, mpiint, 0, mpicom)
514 1536 : call mpibcast (tracer_srcs_fixed_tod, 1, mpiint, 0, mpicom)
515 :
516 1536 : call mpibcast (chem_use_chemtrop,1, mpilog, 0, mpicom)
517 :
518 : #endif
519 :
520 : ! set the options
521 :
522 : call tracer_cnst_setopts( &
523 : tracer_cnst_file_in = tracer_cnst_file, &
524 : tracer_cnst_filelist_in = tracer_cnst_filelist, &
525 : tracer_cnst_datapath_in = tracer_cnst_datapath, &
526 : tracer_cnst_type_in = tracer_cnst_type, &
527 : tracer_cnst_specifier_in = tracer_cnst_specifier, &
528 : tracer_cnst_rmfile_in = tracer_cnst_rmfile, &
529 : tracer_cnst_cycle_yr_in = tracer_cnst_cycle_yr, &
530 : tracer_cnst_fixed_ymd_in = tracer_cnst_fixed_ymd, &
531 1536 : tracer_cnst_fixed_tod_in = tracer_cnst_fixed_tod )
532 : call tracer_srcs_setopts( &
533 : tracer_srcs_file_in = tracer_srcs_file, &
534 : tracer_srcs_filelist_in = tracer_srcs_filelist, &
535 : tracer_srcs_datapath_in = tracer_srcs_datapath, &
536 : tracer_srcs_type_in = tracer_srcs_type, &
537 : tracer_srcs_specifier_in = tracer_srcs_specifier, &
538 : tracer_srcs_rmfile_in = tracer_srcs_rmfile, &
539 : tracer_srcs_cycle_yr_in = tracer_srcs_cycle_yr, &
540 : tracer_srcs_fixed_ymd_in = tracer_srcs_fixed_ymd, &
541 1536 : tracer_srcs_fixed_tod_in = tracer_srcs_fixed_tod )
542 :
543 1536 : call aero_model_readnl(nlfile)
544 1536 : call dust_readnl(nlfile)
545 : !
546 1536 : call gas_wetdep_readnl(nlfile)
547 1536 : call gcr_ionization_readnl(nlfile)
548 1536 : call epp_ionization_readnl(nlfile)
549 1536 : call mee_ion_readnl(nlfile)
550 1536 : call mo_apex_readnl(nlfile)
551 1536 : call sulf_readnl(nlfile)
552 1536 : call species_sums_readnl(nlfile)
553 1536 : call ocean_emis_readnl(nlfile)
554 :
555 1536 : end subroutine chem_readnl
556 :
557 : !================================================================================================
558 :
559 58824 : function chem_is_active()
560 : !-----------------------------------------------------------------------
561 : ! Purpose: return true if this package is active
562 : !-----------------------------------------------------------------------
563 : logical :: chem_is_active
564 : !-----------------------------------------------------------------------
565 58824 : chem_is_active = is_active
566 1536 : end function chem_is_active
567 :
568 : !================================================================================================
569 :
570 0 : function chem_implements_cnst(name)
571 : !-----------------------------------------------------------------------
572 : !
573 : ! Purpose: return true if specified constituent is implemented by this package
574 : !
575 : ! Author: B. Eaton
576 : !
577 : !-----------------------------------------------------------------------
578 : use chem_mods, only : gas_pcnst, inv_lst, nfs
579 : use mo_tracname, only : solsym
580 :
581 : !-----------------------------------------------------------------------
582 : ! ... dummy arguments
583 : !-----------------------------------------------------------------------
584 : character(len=*), intent(in) :: name ! constituent name
585 : logical :: chem_implements_cnst ! return value
586 : !-----------------------------------------------------------------------
587 : ! ... local variables
588 : !-----------------------------------------------------------------------
589 : integer :: m
590 :
591 0 : chem_implements_cnst = .false.
592 0 : do m = 1,gas_pcnst
593 0 : if( trim(name) /= 'H2O' ) then
594 0 : if( trim(name) == solsym(m) ) then
595 0 : chem_implements_cnst = .true.
596 0 : exit
597 : end if
598 : end if
599 : end do
600 0 : do m = 1,nfs
601 0 : if( trim(name) /= 'H2O' ) then
602 0 : if( trim(name) == inv_lst(m) ) then
603 0 : chem_implements_cnst = .true.
604 0 : exit
605 : end if
606 : endif
607 : enddo
608 :
609 0 : end function chem_implements_cnst
610 :
611 3072 : subroutine chem_init(phys_state, pbuf2d)
612 :
613 : !-----------------------------------------------------------------------
614 : !
615 : ! Purpose: initialize parameterized greenhouse gas chemistry
616 : ! (declare history variables)
617 : !
618 : ! Method:
619 : ! <Describe the algorithm(s) used in the routine.>
620 : ! <Also include any applicable external references.>
621 : !
622 : ! Author: NCAR CMS
623 : !
624 : !-----------------------------------------------------------------------
625 : use physics_buffer, only : physics_buffer_desc, pbuf_get_index, pbuf_set_field
626 : use time_manager, only : is_first_step
627 : use constituents, only : cnst_get_ind
628 : use cam_history, only : addfld, add_default, horiz_only, fieldname_len
629 : use chem_mods, only : gas_pcnst
630 : use mo_chemini, only : chemini
631 : use mo_ghg_chem, only : ghg_chem_init
632 : use mo_tracname, only : solsym
633 : use cfc11star, only : init_cfc11star
634 : use phys_control, only : phys_getopts
635 : use chem_mods, only : adv_mass
636 : use infnan, only : nan, assignment(=)
637 : use mo_chem_utls, only : get_spc_ndx
638 : use cam_abortutils, only : endrun
639 : use aero_model, only : aero_model_init
640 : use mo_setsox, only : sox_inti
641 : use constituents, only : sflxnam
642 : use fire_emissions, only : fire_emissions_init
643 : use short_lived_species, only : short_lived_species_initic
644 : use ocean_emis, only : ocean_emis_init, ocean_emis_species
645 : use mo_srf_emissions, only : has_emis
646 :
647 : type(physics_buffer_desc), pointer :: pbuf2d(:,:)
648 : type(physics_state), intent(in):: phys_state(begchunk:endchunk)
649 :
650 :
651 : !-----------------------------------------------------------------------
652 : ! Local variables
653 : !-----------------------------------------------------------------------
654 : integer :: m ! tracer indicies
655 : character(len=fieldname_len) :: spc_name
656 : integer :: n, ii, ierr
657 : logical :: history_aerosol
658 : logical :: history_chemistry
659 : logical :: history_cesm_forcing
660 :
661 : character(len=2) :: unit_basename ! Units 'kg' or '1'
662 : logical :: history_budget ! output tendencies and state variables for CAM
663 : ! temperature, water vapor, cloud ice and cloud
664 : ! liquid budgets.
665 : integer :: history_budget_histfile_num ! output history file number for budget fields
666 :
667 : character(len=*), parameter :: prefix = 'chem_init: '
668 :
669 : call phys_getopts( cam_chempkg_out=chem_name, &
670 : history_aerosol_out=history_aerosol , &
671 : history_chemistry_out=history_chemistry , &
672 : history_budget_out = history_budget , &
673 : history_budget_histfile_num_out = history_budget_histfile_num, &
674 1536 : history_cesm_forcing_out = history_cesm_forcing )
675 :
676 : ! aqueous chem initialization
677 1536 : call sox_inti()
678 :
679 : ! Initialize aerosols
680 1536 : call aero_model_init( pbuf2d )
681 :
682 : !-----------------------------------------------------------------------
683 : ! Get liq and ice cloud water indicies
684 : !-----------------------------------------------------------------------
685 1536 : call cnst_get_ind( 'CLDLIQ', ixcldliq )
686 1536 : call cnst_get_ind( 'NUMLIQ', ixndrop, abort=.false. )
687 :
688 : !-----------------------------------------------------------------------
689 : ! get pbuf indicies
690 : !-----------------------------------------------------------------------
691 1536 : ndx_cld = pbuf_get_index('CLD')
692 1536 : ndx_cmfdqr = pbuf_get_index('RPRDTOT')
693 1536 : ndx_nevapr = pbuf_get_index('NEVAPR')
694 1536 : ndx_prain = pbuf_get_index('PRAIN')
695 1536 : ndx_cldtop = pbuf_get_index('CLDTOP')
696 1536 : ndx_pblh = pbuf_get_index('pblh')
697 1536 : ndx_fsds = pbuf_get_index('FSDS')
698 :
699 3072 : call addfld( 'HEIGHT', (/ 'ilev' /),'A','m', 'geopotential height above surface at interfaces (m)' )
700 3072 : call addfld( 'CT_H2O_GHG', (/ 'lev' /), 'A','kg/kg/s', 'ghg-chem h2o source/sink' )
701 :
702 : !-----------------------------------------------------------------------
703 : ! Initialize chemistry modules
704 : !-----------------------------------------------------------------------
705 : call chemini &
706 : ( euvac_file &
707 : , photon_file &
708 : , electron_file &
709 : , airpl_emis_file &
710 : , depvel_lnd_file &
711 : , xs_coef_file &
712 : , xs_short_file &
713 : , xs_long_file &
714 : , photo_max_zen &
715 : , rsf_file &
716 : , fstrat_file &
717 : , fstrat_list &
718 : , srf_emis_specifier &
719 : , srf_emis_type &
720 : , srf_emis_cycle_yr &
721 : , srf_emis_fixed_ymd &
722 : , srf_emis_fixed_tod &
723 : , ext_frc_specifier &
724 : , ext_frc_type &
725 : , ext_frc_cycle_yr &
726 : , ext_frc_fixed_ymd &
727 : , ext_frc_fixed_tod &
728 : , exo_coldens_file &
729 : , use_hemco &
730 : , pbuf2d &
731 1536 : )
732 :
733 1536 : if ( ghg_chem ) then
734 1536 : call ghg_chem_init(phys_state, bndtvg, h2orates)
735 : endif
736 :
737 1536 : call init_cfc11star(pbuf2d)
738 :
739 : ! MEGAN emissions initialize
740 1536 : if (shr_megan_mechcomps_n>0) then
741 :
742 4608 : allocate( megan_indices_map(shr_megan_mechcomps_n), stat=ierr)
743 1536 : if( ierr /= 0 ) then
744 0 : call endrun(prefix//'failed to allocate megan_indices_map')
745 : end if
746 4608 : allocate( megan_wght_factors(shr_megan_mechcomps_n), stat=ierr)
747 1536 : if( ierr /= 0 ) then
748 0 : call endrun(prefix//'failed to allocate megan_indices_map')
749 : end if
750 1536 : megan_wght_factors(:) = nan
751 :
752 3072 : do n=1,shr_megan_mechcomps_n
753 1536 : call cnst_get_ind (shr_megan_mechcomps(n)%name, megan_indices_map(n), abort=.false.)
754 1536 : ii = get_spc_ndx(shr_megan_mechcomps(n)%name)
755 1536 : if (ii>0) then
756 1536 : megan_wght_factors(n) = adv_mass(ii)*1.e-3_r8 ! kg/moles (to convert moles/m2/sec to kg/m2/sec)
757 : else
758 : call endrun( 'gas_phase_chemdr_inti: MEGAN compound not in chemistry mechanism : '&
759 0 : //trim(shr_megan_mechcomps(n)%name))
760 : endif
761 :
762 : ! MEGAN history fields
763 0 : call addfld( 'MEG_'//trim(shr_megan_mechcomps(n)%name),horiz_only,'A','kg/m2/sec',&
764 1536 : trim(shr_megan_mechcomps(n)%name)//' MEGAN emissions flux')
765 1536 : if (history_chemistry) then
766 1536 : call add_default('MEG_'//trim(shr_megan_mechcomps(n)%name), 1, ' ')
767 : endif
768 :
769 3072 : srf_emis_diag(megan_indices_map(n)) = .true.
770 : enddo
771 : endif
772 :
773 : ! Galatic Cosmic Rays ...
774 1536 : call gcr_ionization_init()
775 :
776 : ! Fire emissions ...
777 1536 : call fire_emissions_init()
778 :
779 1536 : call short_lived_species_initic()
780 :
781 1536 : call ocean_emis_init()
782 :
783 : !-----------------------------------------------------------------------
784 : ! Set names of chemistry variable tendencies and declare them as history variables
785 : !-----------------------------------------------------------------------
786 49152 : do m = 1,gas_pcnst
787 47616 : spc_name = solsym(m)
788 47616 : srcnam(m) = 'CT_' // spc_name ! chem tendancy (source/sink)
789 :
790 95232 : call addfld( srcnam(m), (/ 'lev' /), 'A', 'kg/kg/s', trim(spc_name)//' source/sink' )
791 47616 : call cnst_get_ind(solsym(m), n, abort=.false.)
792 :
793 49152 : if ( n>0 ) then
794 46080 : if (has_emis(m) .or. aero_has_emis(solsym(m)) .or. ocean_emis_species(solsym(m)) .or. srf_emis_diag(n)) then
795 26112 : srf_emis_diag(n) = .true.
796 :
797 26112 : if (sflxnam(n)(3:5) == 'num') then ! name is in the form of "SF****"
798 6144 : unit_basename = ' 1'
799 : else
800 19968 : unit_basename = 'kg'
801 : endif
802 :
803 26112 : call addfld (sflxnam(n),horiz_only, 'A', unit_basename//'/m2/s',trim(solsym(m))//' surface flux')
804 26112 : if ( history_aerosol .or. history_chemistry ) then
805 26112 : call add_default( sflxnam(n), 1, ' ' )
806 : endif
807 :
808 26112 : if ( history_cesm_forcing ) then
809 0 : if ( spc_name == 'NO' .or. spc_name == 'NH3' ) then
810 0 : call add_default( sflxnam(n), 1, ' ' )
811 : endif
812 : endif
813 :
814 : endif
815 : endif
816 : end do
817 :
818 : ! Add chemical tendency of water vapor to water budget output
819 1536 : if ( history_budget ) then
820 0 : call add_default ('CT_H2O' , history_budget_histfile_num, ' ')
821 : endif
822 :
823 : ! initialize srf ozone to zero
824 2304 : if (is_first_step() .and. srf_ozone_pbf_ndx>0) then
825 768 : call pbuf_set_field(pbuf2d, srf_ozone_pbf_ndx, 0._r8)
826 : end if
827 :
828 : contains
829 :
830 46080 : pure logical function aero_has_emis(spcname)
831 1536 : use seasalt_model, only: seasalt_names
832 : use dust_model, only: dust_names
833 :
834 : character(len=*),intent(in) :: spcname
835 :
836 534528 : aero_has_emis = any(seasalt_names(:) == spcname).or.any(dust_names(:) == spcname)
837 :
838 46080 : end function aero_has_emis
839 :
840 : end subroutine chem_init
841 :
842 : !================================================================================
843 : !================================================================================
844 58824 : subroutine chem_emissions( state, cam_in, pbuf )
845 : use physics_buffer, only: physics_buffer_desc
846 : use aero_model, only: aero_model_emissions
847 : use camsrfexch, only: cam_in_t
848 : use constituents, only: sflxnam
849 : use cam_history, only: outfld
850 : use mo_srf_emissions, only: set_srf_emissions
851 : use hco_cc_emissions, only: hco_set_srf_emissions
852 : use fire_emissions, only: fire_emissions_srf
853 : use ocean_emis, only: ocean_emis_getflux
854 :
855 : ! Arguments:
856 :
857 : type(physics_state), intent(in) :: state ! Physics state variables
858 : type(cam_in_t), intent(inout) :: cam_in ! import state
859 : type(physics_buffer_desc), pointer :: pbuf(:) ! Physics buffer in chunk, for HEMCO
860 :
861 : ! local vars
862 :
863 : integer :: lchnk, ncol
864 : integer :: i, m,n
865 :
866 : real(r8) :: sflx(pcols,gas_pcnst)
867 : real(r8) :: megflx(pcols)
868 :
869 58824 : lchnk = state%lchnk
870 58824 : ncol = state%ncol
871 :
872 : ! initialize chemistry constituent surface fluxes to zero
873 2411784 : do m = 2,pcnst
874 2352960 : n = map2chm(m)
875 30647304 : if (n>0) cam_in%cflx(:,m) = 0._r8
876 : enddo
877 :
878 : ! aerosol emissions ...
879 58824 : call aero_model_emissions( state, cam_in )
880 :
881 : ! MEGAN emissions ...
882 :
883 58824 : if ( active_Fall_flxvoc .and. shr_megan_mechcomps_n>0 ) then
884 :
885 : ! set MEGAN fluxes
886 117648 : do n = 1,shr_megan_mechcomps_n
887 982224 : do i =1,ncol
888 923400 : megflx(i) = -cam_in%meganflx(i,n) * megan_wght_factors(n)
889 982224 : cam_in%cflx(i,megan_indices_map(n)) = cam_in%cflx(i,megan_indices_map(n)) + megflx(i)
890 : enddo
891 :
892 : ! output MEGAN emis fluxes to history
893 117648 : call outfld('MEG_'//trim(shr_megan_mechcomps(n)%name), megflx(:ncol), ncol, lchnk)
894 : enddo
895 :
896 : endif
897 :
898 58824 : if ( use_hemco ) then
899 : ! prescribed emissions from HEMCO ...
900 :
901 : !-----------------------------------------------------------------------
902 : ! ... Set surface emissions using HEMCO compatibility API
903 : !-----------------------------------------------------------------------
904 0 : call hco_set_srf_emissions( lchnk, ncol, sflx(:,:), pbuf )
905 : else
906 : ! prescribed emissions from file ...
907 :
908 : !-----------------------------------------------------------------------
909 : ! ... Set surface emissions
910 : !-----------------------------------------------------------------------
911 58824 : call set_srf_emissions( lchnk, ncol, sflx(:,:) )
912 : endif
913 :
914 2470608 : do m = 1,pcnst
915 2411784 : n = map2chm(m)
916 2470608 : if ( n /= h2o_ndx .and. n > 0 ) then
917 29466720 : cam_in%cflx(:ncol,m) = cam_in%cflx(:ncol,m) + sflx(:ncol,n)
918 1764720 : if (srf_emis_diag(m)) then
919 1000008 : call outfld( sflxnam(m), cam_in%cflx(:ncol,m), ncol,lchnk )
920 : endif
921 : endif
922 : enddo
923 :
924 : ! fire surface emissions if not elevated forcing
925 58824 : call fire_emissions_srf( lchnk, ncol, cam_in%fireflx, cam_in%cflx )
926 :
927 : ! air-sea exchange of trace gases
928 58824 : call ocean_emis_getflux(lchnk, ncol, state, cam_in%u10, cam_in%sst, cam_in%ocnfrac, cam_in%icefrac, cam_in%cflx)
929 :
930 58824 : end subroutine chem_emissions
931 :
932 : !================================================================================
933 :
934 0 : subroutine chem_init_cnst( name, latvals, lonvals, mask, q)
935 : !-----------------------------------------------------------------------
936 : !
937 : ! Purpose:
938 : ! Specify initial mass mixing ratios
939 : !
940 : !-----------------------------------------------------------------------
941 :
942 58824 : use chem_mods, only : inv_lst
943 :
944 : use physconst, only : mwdry, mwch4, mwn2o, mwf11, mwf12
945 : use chem_surfvals, only : chem_surfvals_get
946 :
947 : implicit none
948 :
949 : !-----------------------------------------------------------------------
950 : ! Dummy arguments
951 : !-----------------------------------------------------------------------
952 : character(len=*), intent(in) :: name ! constituent name
953 : real(r8), intent(in) :: latvals(:) ! lat in degrees (ncol)
954 : real(r8), intent(in) :: lonvals(:) ! lon in degrees (ncol)
955 : logical, intent(in) :: mask(:) ! Only initialize where .true.
956 : real(r8), intent(out) :: q(:,:) ! kg tracer/kg dry air (gcol, plev
957 :
958 : !-----------------------------------------------------------------------
959 : ! Local variables
960 : !-----------------------------------------------------------------------
961 :
962 : real(r8) :: rmwn2o != mwn2o/mwdry ! ratio of mol weight n2o to dry air
963 : real(r8) :: rmwch4 != mwch4/mwdry ! ratio of mol weight ch4 to dry air
964 : real(r8) :: rmwf11 != mwf11/mwdry ! ratio of mol weight cfc11 to dry air
965 : real(r8) :: rmwf12 != mwf12/mwdry ! ratio of mol weight cfc12 to dry air
966 : integer :: ilev, nlev
967 :
968 : !-----------------------------------------------------------------------
969 : ! initialize local variables
970 : !-----------------------------------------------------------------------
971 :
972 0 : rmwn2o = mwn2o/mwdry
973 0 : rmwch4 = mwch4/mwdry
974 0 : rmwf11 = mwf11/mwdry
975 0 : rmwf12 = mwf12/mwdry
976 :
977 : !-----------------------------------------------------------------------
978 : ! Get initial mixing ratios
979 : !-----------------------------------------------------------------------
980 0 : nlev = size(q, 2)
981 0 : if ( any( inv_lst .eq. name ) ) then
982 0 : do ilev = 1, nlev
983 0 : where(mask)
984 0 : q(:,ilev) = 0.0_r8
985 : end where
986 : end do
987 : else
988 0 : do ilev = 1, nlev
989 0 : where(mask)
990 0 : q(:,ilev) = 1.e-38_r8
991 : end where
992 : end do
993 : endif
994 :
995 0 : if ( ghg_chem ) then
996 0 : do ilev = 1, nlev
997 0 : select case (name)
998 : case ('N2O')
999 0 : where(mask)
1000 0 : q(:,ilev) = rmwn2o * chem_surfvals_get('N2OVMR')
1001 : end where
1002 : case ('CH4')
1003 0 : where(mask)
1004 0 : q(:,ilev) = rmwch4 * chem_surfvals_get('CH4VMR')
1005 : end where
1006 : case ('CFC11')
1007 0 : where(mask)
1008 0 : q(:,ilev) = rmwf11 * chem_surfvals_get('F11VMR')
1009 : end where
1010 : case ('CFC12')
1011 0 : where(mask)
1012 0 : q(:,ilev) = rmwf12 * chem_surfvals_get('F12VMR')
1013 : end where
1014 : case ('CO2')
1015 0 : where(mask)
1016 0 : q(:,ilev) = chem_surfvals_get('CO2MMR')
1017 : end where
1018 : end select
1019 : end do
1020 : end if
1021 :
1022 0 : end subroutine chem_init_cnst
1023 :
1024 32256 : subroutine chem_timestep_init(phys_state,pbuf2d)
1025 :
1026 0 : use time_manager, only : get_nstep
1027 : use time_manager, only : get_curr_calday
1028 : use mo_srf_emissions, only : set_srf_emissions_time
1029 : use mo_sulf, only : set_sulf_time
1030 : use mo_extfrc, only : extfrc_timestep_init
1031 : use mo_flbc, only : flbc_chk
1032 : use tracer_cnst, only : tracer_cnst_adv
1033 : use tracer_srcs, only : tracer_srcs_adv
1034 : use mo_ghg_chem, only : ghg_chem_timestep_init
1035 :
1036 : use mo_aurora, only : aurora_timestep_init
1037 : use mo_photo, only : photo_timestep_init
1038 :
1039 : use cfc11star, only : update_cfc11star
1040 : use physics_buffer, only : physics_buffer_desc
1041 : use ocean_emis, only : ocean_emis_advance
1042 : use mee_fluxes, only : mee_fluxes_adv
1043 :
1044 : implicit none
1045 :
1046 : type(physics_state), intent(inout) :: phys_state(begchunk:endchunk)
1047 : type(physics_buffer_desc), pointer :: pbuf2d(:,:)
1048 :
1049 : !-----------------------------------------------------------------------
1050 : ! Local variables
1051 : !-----------------------------------------------------------------------
1052 : real(r8) :: calday
1053 : integer :: nstep
1054 :
1055 16128 : nstep = get_nstep()
1056 16128 : chem_step = mod( nstep, chem_freq ) == 0
1057 :
1058 16128 : if ( .not. chem_step ) return
1059 :
1060 : !-----------------------------------------------------------------------
1061 : ! get current calendar day of year
1062 : !-----------------------------------------------------------------------
1063 16128 : calday = get_curr_calday( )
1064 :
1065 : !-----------------------------------------------------------------------
1066 : ! Set emissions timing factors
1067 : !-----------------------------------------------------------------------
1068 16128 : call set_srf_emissions_time( pbuf2d, phys_state )
1069 :
1070 : !-----------------------------------------------------------------------
1071 : ! Set external forcings timing factors
1072 : !-----------------------------------------------------------------------
1073 16128 : call extfrc_timestep_init( pbuf2d, phys_state )
1074 :
1075 : !-----------------------------------------------------------------------
1076 : ! Set sulf timing factors
1077 : !-----------------------------------------------------------------------
1078 16128 : call set_sulf_time( pbuf2d, phys_state )
1079 :
1080 : !-----------------------------------------------------------------------
1081 : ! Set fixed lower boundary timing factors
1082 : !-----------------------------------------------------------------------
1083 16128 : call flbc_chk
1084 :
1085 : !-----------------------------------------------------------------------
1086 : ! Set fixed offline tracers
1087 : !-----------------------------------------------------------------------
1088 16128 : call tracer_cnst_adv(pbuf2d, phys_state)
1089 :
1090 : !-----------------------------------------------------------------------
1091 : ! Set fixed offline tracer sources
1092 : !-----------------------------------------------------------------------
1093 16128 : call tracer_srcs_adv(pbuf2d, phys_state)
1094 :
1095 16128 : if ( ghg_chem ) then
1096 16128 : call ghg_chem_timestep_init(phys_state)
1097 : endif
1098 :
1099 : !-----------------------------------------------------------------------
1100 : ! Set up aurora
1101 : !-----------------------------------------------------------------------
1102 16128 : call aurora_timestep_init
1103 :
1104 : !-----------------------------------------------------------------------------
1105 : ! ... setup the time interpolation for mo_photo
1106 : !-----------------------------------------------------------------------------
1107 16128 : call photo_timestep_init( calday )
1108 :
1109 16128 : call update_cfc11star( pbuf2d, phys_state )
1110 :
1111 : ! Galatic Cosmic Rays ...
1112 16128 : call gcr_ionization_adv( pbuf2d, phys_state )
1113 16128 : call epp_ionization_adv()
1114 :
1115 : ! medium energy electron flux data ...
1116 16128 : call mee_fluxes_adv()
1117 :
1118 16128 : call ocean_emis_advance( pbuf2d, phys_state )
1119 :
1120 16128 : end subroutine chem_timestep_init
1121 :
1122 2470608 : subroutine chem_timestep_tend( state, ptend, cam_in, cam_out, dt, pbuf, fh2o)
1123 :
1124 : !-----------------------------------------------------------------------
1125 : !
1126 : ! Purpose:
1127 : ! Interface to parameterized greenhouse gas chemisty (source/sink).
1128 : !
1129 : ! Method:
1130 : ! <Describe the algorithm(s) used in the routine.>
1131 : ! <Also include any applicable external references.>
1132 : !
1133 : ! Author: B.A. Boville
1134 : !
1135 : !-----------------------------------------------------------------------
1136 :
1137 16128 : use physics_buffer, only : physics_buffer_desc, pbuf_get_field, pbuf_old_tim_idx
1138 : use cam_history, only : outfld
1139 : use time_manager, only : get_curr_calday
1140 : use mo_gas_phase_chemdr, only : gas_phase_chemdr
1141 : use camsrfexch, only : cam_in_t, cam_out_t
1142 : use perf_mod, only : t_startf, t_stopf
1143 : use tropopause, only : tropopause_findChemTrop, tropopause_find
1144 : use mo_drydep, only : drydep_update
1145 : use mo_neu_wetdep, only : neu_wetdep_tend
1146 : use aerodep_flx, only : aerodep_flx_prescribed
1147 : use short_lived_species, only : short_lived_species_writeic
1148 :
1149 : implicit none
1150 :
1151 : !-----------------------------------------------------------------------
1152 : ! Dummy arguments
1153 : !-----------------------------------------------------------------------
1154 : real(r8), intent(in) :: dt ! time step
1155 : type(physics_state), intent(in) :: state ! Physics state variables
1156 : type(physics_ptend), intent(out) :: ptend ! indivdual parameterization tendencies
1157 : type(cam_in_t), intent(inout) :: cam_in
1158 : type(cam_out_t), intent(inout) :: cam_out
1159 : real(r8), intent(out) :: fh2o(pcols) ! h2o flux to balance source from chemistry
1160 :
1161 :
1162 : type(physics_buffer_desc), pointer :: pbuf(:)
1163 :
1164 : !-----------------------------------------------------------------------
1165 : ! Local variables
1166 : !-----------------------------------------------------------------------
1167 : integer :: i, k, m, n ! indicies
1168 : integer :: lchnk ! chunk identifier
1169 : integer :: ncol ! number of atmospheric columns
1170 : real(r8) :: calday ! current calendar day of year
1171 : real(r8) :: cldw(pcols,pver) ! cloud water (kg/kg)
1172 : real(r8) :: chem_dt ! time step
1173 : real(r8) :: drydepflx(pcols,pcnst) ! dry deposition fluxes (kg/m2/s)
1174 : real(r8) :: wetdepflx(pcols,pcnst) ! wet deposition fluxes (kg/m2/s)
1175 : integer :: tropLev(pcols), tropLevChem(pcols)
1176 : real(r8) :: ncldwtr(pcols,pver) ! droplet number concentration (#/kg)
1177 58824 : real(r8), pointer :: fsds(:) ! longwave down at sfc
1178 58824 : real(r8), pointer :: pblh(:)
1179 58824 : real(r8), pointer :: prain(:,:)
1180 58824 : real(r8), pointer :: cldfr(:,:)
1181 58824 : real(r8), pointer :: cmfdqr(:,:)
1182 58824 : real(r8), pointer :: nevapr(:,:)
1183 58824 : real(r8), pointer :: cldtop(:)
1184 : real(r8) :: nhx_nitrogen_flx(pcols)
1185 : real(r8) :: noy_nitrogen_flx(pcols)
1186 :
1187 : integer :: tim_ndx
1188 :
1189 : logical :: lq(pcnst)
1190 :
1191 58824 : if ( .not. chem_step ) return
1192 :
1193 58824 : chem_dt = chem_freq*dt
1194 :
1195 58824 : lchnk = state%lchnk
1196 58824 : ncol = state%ncol
1197 :
1198 58824 : call short_lived_species_writeic( lchnk, pbuf )
1199 :
1200 58824 : lq(:) = .false.
1201 2470608 : do n = 1,pcnst
1202 2411784 : m = map2chm(n)
1203 2470608 : if( m > 0 ) then
1204 1823544 : lq(n) = .true.
1205 : end if
1206 : end do
1207 58824 : if ( ghg_chem ) lq(1) = .true.
1208 :
1209 58824 : call physics_ptend_init(ptend, state%psetcols, 'chemistry', lq=lq)
1210 :
1211 58824 : call drydep_update( state, cam_in )
1212 :
1213 : !-----------------------------------------------------------------------
1214 : ! get current calendar day of year
1215 : !-----------------------------------------------------------------------
1216 58824 : calday = get_curr_calday()
1217 :
1218 : !-----------------------------------------------------------------------
1219 : ! get tropopause level
1220 : !-----------------------------------------------------------------------
1221 58824 : if (.not.chem_use_chemtrop) then
1222 0 : call tropopause_find(state,tropLev)
1223 0 : tropLevChem=tropLev
1224 : else
1225 58824 : call tropopause_find(state,tropLev)
1226 58824 : call tropopause_findChemTrop(state, tropLevChem)
1227 : endif
1228 :
1229 58824 : tim_ndx = pbuf_old_tim_idx()
1230 58824 : call pbuf_get_field(pbuf, ndx_fsds, fsds)
1231 58824 : call pbuf_get_field(pbuf, ndx_pblh, pblh)
1232 176472 : call pbuf_get_field(pbuf, ndx_prain, prain, start=(/1,1/), kount=(/ncol,pver/))
1233 411768 : call pbuf_get_field(pbuf, ndx_cld, cldfr, start=(/1,1,tim_ndx/), kount=(/ncol,pver,1/) )
1234 176472 : call pbuf_get_field(pbuf, ndx_cmfdqr, cmfdqr, start=(/1,1/), kount=(/ncol,pver/))
1235 176472 : call pbuf_get_field(pbuf, ndx_nevapr, nevapr, start=(/1,1/), kount=(/ncol,pver/))
1236 58824 : call pbuf_get_field(pbuf, ndx_cldtop, cldtop )
1237 :
1238 : !-----------------------------------------------------------------------
1239 : ! call Neu wet dep scheme
1240 : !-----------------------------------------------------------------------
1241 : call neu_wetdep_tend(lchnk,ncol,state%q,state%pmid,state%pdel,state%zi,state%t,dt, &
1242 58824 : prain, nevapr, cldfr, cmfdqr, ptend%q, wetdepflx)
1243 :
1244 : !-----------------------------------------------------------------------
1245 : ! compute tendencies and surface fluxes
1246 : !-----------------------------------------------------------------------
1247 58824 : call t_startf( 'chemdr' )
1248 5529456 : do k = 1,pver
1249 91346832 : cldw(:ncol,k) = state%q(:ncol,k,ixcldliq)
1250 5470632 : if (ixndrop>0) &
1251 91405656 : ncldwtr(:ncol,k) = state%q(:ncol,k,ixndrop)
1252 : end do
1253 :
1254 : call gas_phase_chemdr(lchnk, ncol, imozart, state%q, &
1255 : state%phis, state%zm, state%zi, calday, &
1256 : state%t, state%pmid, state%pdel, state%pint, state%rpdel, state%rpdeldry, &
1257 : cldw, tropLev, tropLevChem, ncldwtr, state%u, state%v, chem_dt, state%ps, &
1258 : fsds, cam_in%ts, cam_in%asdir, cam_in%ocnfrac, cam_in%icefrac, &
1259 : cam_out%precc, cam_out%precl, cam_in%snowhland, ghg_chem, state%latmapback, &
1260 : drydepflx, wetdepflx, cam_in%cflx, cam_in%fireflx, cam_in%fireztop, &
1261 58824 : nhx_nitrogen_flx, noy_nitrogen_flx, use_hemco, ptend%q, pbuf )
1262 58824 : if (associated(cam_out%nhx_nitrogen_flx)) then
1263 982224 : cam_out%nhx_nitrogen_flx(:ncol) = nhx_nitrogen_flx(:ncol)
1264 : endif
1265 58824 : if (associated(cam_out%noy_nitrogen_flx)) then
1266 982224 : cam_out%noy_nitrogen_flx(:ncol) = noy_nitrogen_flx(:ncol)
1267 : endif
1268 :
1269 58824 : call t_stopf( 'chemdr' )
1270 :
1271 : !-----------------------------------------------------------------------
1272 : ! set flags for tracer tendencies (water and gas phase constituents)
1273 : ! record tendencies on history files
1274 : !-----------------------------------------------------------------------
1275 2470608 : do n = 1,pcnst
1276 2411784 : m = map2chm(n)
1277 2411784 : if( m > 0 ) then
1278 1823544 : call outfld( srcnam(m), ptend%q(:,:,n), pcols, lchnk )
1279 : end if
1280 :
1281 : ! if the user has specified prescribed aerosol dep fluxes then
1282 : ! do not set cam_out dep fluxes according to the prognostic aerosols
1283 2470608 : if (.not.aerodep_flx_prescribed()) then
1284 : ! set deposition fluxes in the export state
1285 4823568 : select case (trim(cnst_name(n)))
1286 : case('CB1')
1287 0 : do i = 1, ncol
1288 0 : cam_out%bcphodry(i) = max(drydepflx(i,n), 0._r8)
1289 : end do
1290 : case('CB2')
1291 0 : do i = 1, ncol
1292 0 : cam_out%bcphidry(i) = max(drydepflx(i,n), 0._r8)
1293 : end do
1294 : case('OC1')
1295 0 : do i = 1, ncol
1296 0 : cam_out%ocphodry(i) = max(drydepflx(i,n), 0._r8)
1297 : end do
1298 : case('OC2')
1299 4823568 : do i = 1, ncol
1300 0 : cam_out%ocphidry(i) = max(drydepflx(i,n), 0._r8)
1301 : end do
1302 : end select
1303 : endif
1304 : end do
1305 58824 : if ( ghg_chem ) then
1306 58824 : ptend%lq(1) = .true.
1307 58824 : call outfld( 'CT_H2O_GHG', ptend%q(:,:,1), pcols, lchnk )
1308 : endif
1309 :
1310 21705144 : call outfld( 'HEIGHT', state%zi(:ncol,:), ncol, lchnk )
1311 :
1312 : !-----------------------------------------------------------------------
1313 : ! turn off water vapor tendency if radiatively passive
1314 : !-----------------------------------------------------------------------
1315 58824 : if (chem_rad_passive) then
1316 0 : ptend%lq(1) = .false.
1317 0 : ptend%q(:ncol,:,1) = 0._r8
1318 : endif
1319 :
1320 : !-----------------------------------------------------------------------
1321 : ! Compute water vapor flux required to make conservation check
1322 : !-----------------------------------------------------------------------
1323 982224 : fh2o(:ncol) = 0._r8
1324 5529456 : do k = 1,pver
1325 91405656 : fh2o(:ncol) = fh2o(:ncol) + ptend%q(:ncol,k,1)*state%pdel(:ncol,k)/gravit
1326 : end do
1327 :
1328 117648 : end subroutine chem_timestep_tend
1329 :
1330 : !-------------------------------------------------------------------
1331 : !-------------------------------------------------------------------
1332 1536 : subroutine chem_final()
1333 58824 : use mee_ionization, only: mee_ion_final
1334 : use rate_diags, only: rate_diags_final
1335 : use species_sums_diags, only: species_sums_final
1336 : use short_lived_species, only: short_lived_species_final
1337 :
1338 1536 : call mee_ion_final()
1339 1536 : call rate_diags_final()
1340 1536 : call species_sums_final()
1341 1536 : call short_lived_species_final()
1342 :
1343 1536 : end subroutine chem_final
1344 :
1345 : !-------------------------------------------------------------------
1346 : !-------------------------------------------------------------------
1347 :
1348 1536 : subroutine chem_init_restart( File )
1349 1536 : use pio, only : file_desc_t
1350 : use tracer_cnst, only: init_tracer_cnst_restart
1351 : use tracer_srcs, only: init_tracer_srcs_restart
1352 : implicit none
1353 : type(file_desc_t),intent(inout) :: File ! pio File pointer
1354 :
1355 : !
1356 : ! data for offline tracers
1357 : !
1358 1536 : call init_tracer_cnst_restart(File)
1359 1536 : call init_tracer_srcs_restart(File)
1360 1536 : end subroutine chem_init_restart
1361 : !-------------------------------------------------------------------
1362 : !-------------------------------------------------------------------
1363 1536 : subroutine chem_write_restart( File )
1364 1536 : use tracer_cnst, only: write_tracer_cnst_restart
1365 : use tracer_srcs, only: write_tracer_srcs_restart
1366 : use pio, only : file_desc_t
1367 : implicit none
1368 : type(file_desc_t) :: File
1369 :
1370 : !
1371 : ! data for offline tracers
1372 : !
1373 1536 : call write_tracer_cnst_restart(File)
1374 1536 : call write_tracer_srcs_restart(File)
1375 1536 : end subroutine chem_write_restart
1376 :
1377 : !-------------------------------------------------------------------
1378 : !-------------------------------------------------------------------
1379 768 : subroutine chem_read_restart( File )
1380 1536 : use tracer_cnst, only: read_tracer_cnst_restart
1381 : use tracer_srcs, only: read_tracer_srcs_restart
1382 :
1383 : use pio, only : file_desc_t
1384 : implicit none
1385 : type(file_desc_t) :: File
1386 :
1387 : !
1388 : ! data for offline tracers
1389 : !
1390 768 : call read_tracer_cnst_restart(File)
1391 768 : call read_tracer_srcs_restart(File)
1392 768 : end subroutine chem_read_restart
1393 :
1394 : end module chemistry
|