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 : drydep_srf_file = ' '
426 :
427 1536 : if (masterproc) then
428 2 : unitn = getunit()
429 2 : open( unitn, file=trim(nlfile), status='old' )
430 2 : call find_group_name(unitn, 'chem_inparm', status=ierr)
431 2 : if (ierr == 0) then
432 2 : read(unitn, chem_inparm, iostat=ierr)
433 2 : if (ierr /= 0) then
434 0 : call endrun('chem_readnl: ERROR reading namelist')
435 : end if
436 : end if
437 2 : close(unitn)
438 2 : call freeunit(unitn)
439 : end if
440 :
441 : #ifdef SPMD
442 : ! Broadcast namelist variables
443 :
444 : ! control
445 :
446 1536 : call mpibcast (chem_freq, 1, mpiint, 0, mpicom)
447 :
448 1536 : call mpibcast (chem_rad_passive, 1, mpilog, 0, mpicom)
449 :
450 : ! ghg
451 :
452 1536 : call mpibcast (ghg_chem, 1, mpilog, 0, mpicom)
453 1536 : call mpibcast (bndtvg, len(bndtvg), mpichar, 0, mpicom)
454 1536 : call mpibcast (h2orates, len(h2orates), mpichar, 0, mpicom)
455 :
456 : ! photolysis
457 :
458 1536 : call mpibcast (rsf_file, len(rsf_file), mpichar, 0, mpicom)
459 1536 : call mpibcast (exo_coldens_file, len(exo_coldens_file), mpichar, 0, mpicom)
460 1536 : call mpibcast (xs_coef_file, len(xs_coef_file), mpichar, 0, mpicom)
461 1536 : call mpibcast (xs_short_file, len(xs_short_file), mpichar, 0, mpicom)
462 1536 : call mpibcast (xs_long_file, len(xs_long_file), mpichar, 0, mpicom)
463 1536 : call mpibcast (photo_max_zen, 1, mpir8, 0, mpicom)
464 1536 : call mpibcast (electron_file, len(electron_file), mpichar, 0, mpicom)
465 1536 : call mpibcast (euvac_file, len(euvac_file), mpichar, 0, mpicom)
466 :
467 : ! solar / geomag data
468 :
469 1536 : call mpibcast (photon_file, len(photon_file), mpichar, 0, mpicom)
470 :
471 : ! dry dep
472 :
473 1536 : call mpibcast (depvel_lnd_file, len(depvel_lnd_file), mpichar, 0, mpicom)
474 1536 : call mpibcast (drydep_srf_file, len(drydep_srf_file), mpichar, 0, mpicom)
475 :
476 : ! emis
477 :
478 1536 : call mpibcast (airpl_emis_file, len(airpl_emis_file), mpichar, 0, mpicom)
479 1536 : call mpibcast (srf_emis_specifier,len(srf_emis_specifier(1))*pcnst,mpichar, 0, mpicom)
480 1536 : call mpibcast (srf_emis_type, len(srf_emis_type), mpichar, 0, mpicom)
481 1536 : call mpibcast (srf_emis_cycle_yr, 1, mpiint, 0, mpicom)
482 1536 : call mpibcast (srf_emis_fixed_ymd,1, mpiint, 0, mpicom)
483 1536 : call mpibcast (srf_emis_fixed_tod,1, mpiint, 0, mpicom)
484 1536 : call mpibcast (ext_frc_specifier, len(ext_frc_specifier(1))*pcnst, mpichar, 0, mpicom)
485 1536 : call mpibcast (ext_frc_type, len(ext_frc_type), mpichar, 0, mpicom)
486 1536 : call mpibcast (ext_frc_cycle_yr, 1, mpiint, 0, mpicom)
487 1536 : call mpibcast (ext_frc_fixed_ymd, 1, mpiint, 0, mpicom)
488 1536 : call mpibcast (ext_frc_fixed_tod, 1, mpiint, 0, mpicom)
489 :
490 :
491 : ! fixed stratosphere
492 :
493 1536 : call mpibcast (fstrat_file, len(fstrat_file), mpichar, 0, mpicom)
494 1536 : call mpibcast (fstrat_list, len(fstrat_list(1))*pcnst, mpichar, 0, mpicom)
495 :
496 : ! prescribed chemical tracers
497 :
498 1536 : call mpibcast (tracer_cnst_specifier, len(tracer_cnst_specifier(1))*MAXTRCRS, mpichar, 0, mpicom)
499 1536 : call mpibcast (tracer_cnst_file, len(tracer_cnst_file), mpichar, 0, mpicom)
500 1536 : call mpibcast (tracer_cnst_filelist, len(tracer_cnst_filelist), mpichar, 0, mpicom)
501 1536 : call mpibcast (tracer_cnst_datapath, len(tracer_cnst_datapath), mpichar, 0, mpicom)
502 1536 : call mpibcast (tracer_cnst_type, len(tracer_cnst_type), mpichar, 0, mpicom)
503 1536 : call mpibcast (tracer_cnst_rmfile, 1, mpilog, 0, mpicom)
504 1536 : call mpibcast (tracer_cnst_cycle_yr, 1, mpiint, 0, mpicom)
505 1536 : call mpibcast (tracer_cnst_fixed_ymd, 1, mpiint, 0, mpicom)
506 1536 : call mpibcast (tracer_cnst_fixed_tod, 1, mpiint, 0, mpicom)
507 :
508 1536 : call mpibcast (tracer_srcs_specifier, len(tracer_srcs_specifier(1))*MAXTRCRS, mpichar, 0, mpicom)
509 1536 : call mpibcast (tracer_srcs_file, len(tracer_srcs_file), mpichar, 0, mpicom)
510 1536 : call mpibcast (tracer_srcs_filelist, len(tracer_srcs_filelist), mpichar, 0, mpicom)
511 1536 : call mpibcast (tracer_srcs_datapath, len(tracer_srcs_datapath), mpichar, 0, mpicom)
512 1536 : call mpibcast (tracer_srcs_type, len(tracer_srcs_type), mpichar, 0, mpicom)
513 1536 : call mpibcast (tracer_srcs_rmfile, 1, mpilog, 0, mpicom)
514 1536 : call mpibcast (tracer_srcs_cycle_yr, 1, mpiint, 0, mpicom)
515 1536 : call mpibcast (tracer_srcs_fixed_ymd, 1, mpiint, 0, mpicom)
516 1536 : call mpibcast (tracer_srcs_fixed_tod, 1, mpiint, 0, mpicom)
517 :
518 1536 : call mpibcast (chem_use_chemtrop,1, mpilog, 0, mpicom)
519 :
520 : #endif
521 :
522 : ! set the options
523 :
524 : call tracer_cnst_setopts( &
525 : tracer_cnst_file_in = tracer_cnst_file, &
526 : tracer_cnst_filelist_in = tracer_cnst_filelist, &
527 : tracer_cnst_datapath_in = tracer_cnst_datapath, &
528 : tracer_cnst_type_in = tracer_cnst_type, &
529 : tracer_cnst_specifier_in = tracer_cnst_specifier, &
530 : tracer_cnst_rmfile_in = tracer_cnst_rmfile, &
531 : tracer_cnst_cycle_yr_in = tracer_cnst_cycle_yr, &
532 : tracer_cnst_fixed_ymd_in = tracer_cnst_fixed_ymd, &
533 1536 : tracer_cnst_fixed_tod_in = tracer_cnst_fixed_tod )
534 : call tracer_srcs_setopts( &
535 : tracer_srcs_file_in = tracer_srcs_file, &
536 : tracer_srcs_filelist_in = tracer_srcs_filelist, &
537 : tracer_srcs_datapath_in = tracer_srcs_datapath, &
538 : tracer_srcs_type_in = tracer_srcs_type, &
539 : tracer_srcs_specifier_in = tracer_srcs_specifier, &
540 : tracer_srcs_rmfile_in = tracer_srcs_rmfile, &
541 : tracer_srcs_cycle_yr_in = tracer_srcs_cycle_yr, &
542 : tracer_srcs_fixed_ymd_in = tracer_srcs_fixed_ymd, &
543 1536 : tracer_srcs_fixed_tod_in = tracer_srcs_fixed_tod )
544 :
545 1536 : call aero_model_readnl(nlfile)
546 1536 : call dust_readnl(nlfile)
547 : !
548 1536 : call gas_wetdep_readnl(nlfile)
549 1536 : call gcr_ionization_readnl(nlfile)
550 1536 : call epp_ionization_readnl(nlfile)
551 1536 : call mee_ion_readnl(nlfile)
552 1536 : call mo_apex_readnl(nlfile)
553 1536 : call sulf_readnl(nlfile)
554 1536 : call species_sums_readnl(nlfile)
555 1536 : call ocean_emis_readnl(nlfile)
556 :
557 1536 : end subroutine chem_readnl
558 :
559 : !================================================================================================
560 :
561 1489176 : function chem_is_active()
562 : !-----------------------------------------------------------------------
563 : ! Purpose: return true if this package is active
564 : !-----------------------------------------------------------------------
565 : logical :: chem_is_active
566 : !-----------------------------------------------------------------------
567 1489176 : chem_is_active = is_active
568 1536 : end function chem_is_active
569 :
570 : !================================================================================================
571 :
572 0 : function chem_implements_cnst(name)
573 : !-----------------------------------------------------------------------
574 : !
575 : ! Purpose: return true if specified constituent is implemented by this package
576 : !
577 : ! Author: B. Eaton
578 : !
579 : !-----------------------------------------------------------------------
580 : use chem_mods, only : gas_pcnst, inv_lst, nfs
581 : use mo_tracname, only : solsym
582 :
583 : !-----------------------------------------------------------------------
584 : ! ... dummy arguments
585 : !-----------------------------------------------------------------------
586 : character(len=*), intent(in) :: name ! constituent name
587 : logical :: chem_implements_cnst ! return value
588 : !-----------------------------------------------------------------------
589 : ! ... local variables
590 : !-----------------------------------------------------------------------
591 : integer :: m
592 :
593 0 : chem_implements_cnst = .false.
594 0 : do m = 1,gas_pcnst
595 0 : if( trim(name) /= 'H2O' ) then
596 0 : if( trim(name) == solsym(m) ) then
597 0 : chem_implements_cnst = .true.
598 0 : exit
599 : end if
600 : end if
601 : end do
602 0 : do m = 1,nfs
603 0 : if( trim(name) /= 'H2O' ) then
604 0 : if( trim(name) == inv_lst(m) ) then
605 0 : chem_implements_cnst = .true.
606 0 : exit
607 : end if
608 : endif
609 : enddo
610 :
611 0 : end function chem_implements_cnst
612 :
613 3072 : subroutine chem_init(phys_state, pbuf2d)
614 :
615 : !-----------------------------------------------------------------------
616 : !
617 : ! Purpose: initialize parameterized greenhouse gas chemistry
618 : ! (declare history variables)
619 : !
620 : ! Method:
621 : ! <Describe the algorithm(s) used in the routine.>
622 : ! <Also include any applicable external references.>
623 : !
624 : ! Author: NCAR CMS
625 : !
626 : !-----------------------------------------------------------------------
627 : use physics_buffer, only : physics_buffer_desc, pbuf_get_index, pbuf_set_field
628 : use time_manager, only : is_first_step
629 : use constituents, only : cnst_get_ind
630 : use cam_history, only : addfld, add_default, horiz_only, fieldname_len
631 : use chem_mods, only : gas_pcnst
632 : use mo_chemini, only : chemini
633 : use mo_ghg_chem, only : ghg_chem_init
634 : use mo_tracname, only : solsym
635 : use cfc11star, only : init_cfc11star
636 : use phys_control, only : phys_getopts
637 : use chem_mods, only : adv_mass
638 : use infnan, only : nan, assignment(=)
639 : use mo_chem_utls, only : get_spc_ndx
640 : use cam_abortutils, only : endrun
641 : use aero_model, only : aero_model_init
642 : use mo_setsox, only : sox_inti
643 : use constituents, only : sflxnam
644 : use fire_emissions, only : fire_emissions_init
645 : use short_lived_species, only : short_lived_species_initic
646 : use ocean_emis, only : ocean_emis_init, ocean_emis_species
647 : use mo_srf_emissions, only : has_emis
648 :
649 : type(physics_buffer_desc), pointer :: pbuf2d(:,:)
650 : type(physics_state), intent(in):: phys_state(begchunk:endchunk)
651 :
652 :
653 : !-----------------------------------------------------------------------
654 : ! Local variables
655 : !-----------------------------------------------------------------------
656 : integer :: m ! tracer indicies
657 : character(len=fieldname_len) :: spc_name
658 : integer :: n, ii, ierr
659 : logical :: history_aerosol
660 : logical :: history_chemistry
661 : logical :: history_cesm_forcing
662 :
663 : character(len=2) :: unit_basename ! Units 'kg' or '1'
664 : logical :: history_budget ! output tendencies and state variables for CAM
665 : ! temperature, water vapor, cloud ice and cloud
666 : ! liquid budgets.
667 : integer :: history_budget_histfile_num ! output history file number for budget fields
668 :
669 : character(len=*), parameter :: prefix = 'chem_init: '
670 :
671 : call phys_getopts( cam_chempkg_out=chem_name, &
672 : history_aerosol_out=history_aerosol , &
673 : history_chemistry_out=history_chemistry , &
674 : history_budget_out = history_budget , &
675 : history_budget_histfile_num_out = history_budget_histfile_num, &
676 1536 : history_cesm_forcing_out = history_cesm_forcing )
677 :
678 : ! aqueous chem initialization
679 1536 : call sox_inti()
680 :
681 : ! Initialize aerosols
682 1536 : call aero_model_init( pbuf2d )
683 :
684 : !-----------------------------------------------------------------------
685 : ! Get liq and ice cloud water indicies
686 : !-----------------------------------------------------------------------
687 1536 : call cnst_get_ind( 'CLDLIQ', ixcldliq )
688 1536 : call cnst_get_ind( 'NUMLIQ', ixndrop, abort=.false. )
689 :
690 : !-----------------------------------------------------------------------
691 : ! get pbuf indicies
692 : !-----------------------------------------------------------------------
693 1536 : ndx_cld = pbuf_get_index('CLD')
694 1536 : ndx_cmfdqr = pbuf_get_index('RPRDTOT')
695 1536 : ndx_nevapr = pbuf_get_index('NEVAPR')
696 1536 : ndx_prain = pbuf_get_index('PRAIN')
697 1536 : ndx_cldtop = pbuf_get_index('CLDTOP')
698 1536 : ndx_pblh = pbuf_get_index('pblh')
699 1536 : ndx_fsds = pbuf_get_index('FSDS')
700 :
701 3072 : call addfld( 'HEIGHT', (/ 'ilev' /),'A','m', 'geopotential height above surface at interfaces (m)' )
702 3072 : call addfld( 'CT_H2O_GHG', (/ 'lev' /), 'A','kg/kg/s', 'ghg-chem h2o source/sink' )
703 :
704 : !-----------------------------------------------------------------------
705 : ! Initialize chemistry modules
706 : !-----------------------------------------------------------------------
707 : call chemini &
708 : ( euvac_file &
709 : , photon_file &
710 : , electron_file &
711 : , airpl_emis_file &
712 : , depvel_lnd_file &
713 : , xs_coef_file &
714 : , xs_short_file &
715 : , xs_long_file &
716 : , photo_max_zen &
717 : , rsf_file &
718 : , fstrat_file &
719 : , fstrat_list &
720 : , srf_emis_specifier &
721 : , srf_emis_type &
722 : , srf_emis_cycle_yr &
723 : , srf_emis_fixed_ymd &
724 : , srf_emis_fixed_tod &
725 : , ext_frc_specifier &
726 : , ext_frc_type &
727 : , ext_frc_cycle_yr &
728 : , ext_frc_fixed_ymd &
729 : , ext_frc_fixed_tod &
730 : , exo_coldens_file &
731 : , use_hemco &
732 : , pbuf2d &
733 1536 : )
734 :
735 1536 : if ( ghg_chem ) then
736 1536 : call ghg_chem_init(phys_state, bndtvg, h2orates)
737 : endif
738 :
739 1536 : call init_cfc11star(pbuf2d)
740 :
741 : ! MEGAN emissions initialize
742 1536 : if (shr_megan_mechcomps_n>0) then
743 :
744 4608 : allocate( megan_indices_map(shr_megan_mechcomps_n), stat=ierr)
745 1536 : if( ierr /= 0 ) then
746 0 : call endrun(prefix//'failed to allocate megan_indices_map')
747 : end if
748 4608 : allocate( megan_wght_factors(shr_megan_mechcomps_n), stat=ierr)
749 1536 : if( ierr /= 0 ) then
750 0 : call endrun(prefix//'failed to allocate megan_indices_map')
751 : end if
752 1536 : megan_wght_factors(:) = nan
753 :
754 3072 : do n=1,shr_megan_mechcomps_n
755 1536 : call cnst_get_ind (shr_megan_mechcomps(n)%name, megan_indices_map(n), abort=.false.)
756 1536 : ii = get_spc_ndx(shr_megan_mechcomps(n)%name)
757 1536 : if (ii>0) then
758 1536 : megan_wght_factors(n) = adv_mass(ii)*1.e-3_r8 ! kg/moles (to convert moles/m2/sec to kg/m2/sec)
759 : else
760 : call endrun( 'gas_phase_chemdr_inti: MEGAN compound not in chemistry mechanism : '&
761 0 : //trim(shr_megan_mechcomps(n)%name))
762 : endif
763 :
764 : ! MEGAN history fields
765 0 : call addfld( 'MEG_'//trim(shr_megan_mechcomps(n)%name),horiz_only,'A','kg/m2/sec',&
766 1536 : trim(shr_megan_mechcomps(n)%name)//' MEGAN emissions flux')
767 1536 : if (history_chemistry) then
768 1536 : call add_default('MEG_'//trim(shr_megan_mechcomps(n)%name), 1, ' ')
769 : endif
770 :
771 3072 : srf_emis_diag(megan_indices_map(n)) = .true.
772 : enddo
773 : endif
774 :
775 : ! Galatic Cosmic Rays ...
776 1536 : call gcr_ionization_init()
777 :
778 : ! Fire emissions ...
779 1536 : call fire_emissions_init()
780 :
781 1536 : call short_lived_species_initic()
782 :
783 1536 : call ocean_emis_init()
784 :
785 : !-----------------------------------------------------------------------
786 : ! Set names of chemistry variable tendencies and declare them as history variables
787 : !-----------------------------------------------------------------------
788 49152 : do m = 1,gas_pcnst
789 47616 : spc_name = solsym(m)
790 47616 : srcnam(m) = 'CT_' // spc_name ! chem tendancy (source/sink)
791 :
792 95232 : call addfld( srcnam(m), (/ 'lev' /), 'A', 'kg/kg/s', trim(spc_name)//' source/sink' )
793 47616 : call cnst_get_ind(solsym(m), n, abort=.false.)
794 :
795 49152 : if ( n>0 ) then
796 46080 : if (has_emis(m) .or. aero_has_emis(solsym(m)) .or. ocean_emis_species(solsym(m)) .or. srf_emis_diag(n)) then
797 26112 : srf_emis_diag(n) = .true.
798 :
799 26112 : if (sflxnam(n)(3:5) == 'num') then ! name is in the form of "SF****"
800 6144 : unit_basename = ' 1'
801 : else
802 19968 : unit_basename = 'kg'
803 : endif
804 :
805 26112 : call addfld (sflxnam(n),horiz_only, 'A', unit_basename//'/m2/s',trim(solsym(m))//' surface flux')
806 26112 : if ( history_aerosol .or. history_chemistry ) then
807 26112 : call add_default( sflxnam(n), 1, ' ' )
808 : endif
809 :
810 26112 : if ( history_cesm_forcing ) then
811 0 : if ( spc_name == 'NO' .or. spc_name == 'NH3' ) then
812 0 : call add_default( sflxnam(n), 1, ' ' )
813 : endif
814 : endif
815 :
816 : endif
817 : endif
818 : end do
819 :
820 : ! Add chemical tendency of water vapor to water budget output
821 1536 : if ( history_budget ) then
822 0 : call add_default ('CT_H2O' , history_budget_histfile_num, ' ')
823 : endif
824 :
825 : ! initialize srf ozone to zero
826 2304 : if (is_first_step() .and. srf_ozone_pbf_ndx>0) then
827 768 : call pbuf_set_field(pbuf2d, srf_ozone_pbf_ndx, 0._r8)
828 : end if
829 :
830 : contains
831 :
832 46080 : pure logical function aero_has_emis(spcname)
833 1536 : use seasalt_model, only: seasalt_names
834 : use dust_model, only: dust_names
835 :
836 : character(len=*),intent(in) :: spcname
837 :
838 534528 : aero_has_emis = any(seasalt_names(:) == spcname).or.any(dust_names(:) == spcname)
839 :
840 46080 : end function aero_has_emis
841 :
842 : end subroutine chem_init
843 :
844 : !================================================================================
845 : !================================================================================
846 1489176 : subroutine chem_emissions( state, cam_in, pbuf )
847 : use physics_buffer, only: physics_buffer_desc
848 : use aero_model, only: aero_model_emissions
849 : use camsrfexch, only: cam_in_t
850 : use constituents, only: sflxnam
851 : use cam_history, only: outfld
852 : use mo_srf_emissions, only: set_srf_emissions
853 : use hco_cc_emissions, only: hco_set_srf_emissions
854 : use fire_emissions, only: fire_emissions_srf
855 : use ocean_emis, only: ocean_emis_getflux
856 :
857 : ! Arguments:
858 :
859 : type(physics_state), intent(in) :: state ! Physics state variables
860 : type(cam_in_t), intent(inout) :: cam_in ! import state
861 : type(physics_buffer_desc), pointer :: pbuf(:) ! Physics buffer in chunk, for HEMCO
862 :
863 : ! local vars
864 :
865 : integer :: lchnk, ncol
866 : integer :: i, m,n
867 :
868 : real(r8) :: sflx(pcols,gas_pcnst)
869 : real(r8) :: megflx(pcols)
870 :
871 1489176 : lchnk = state%lchnk
872 1489176 : ncol = state%ncol
873 :
874 : ! initialize chemistry constituent surface fluxes to zero
875 61056216 : do m = 2,pcnst
876 59567040 : n = map2chm(m)
877 775860696 : if (n>0) cam_in%cflx(:,m) = 0._r8
878 : enddo
879 :
880 : ! aerosol emissions ...
881 1489176 : call aero_model_emissions( state, cam_in )
882 :
883 : ! MEGAN emissions ...
884 :
885 1489176 : if ( active_Fall_flxvoc .and. shr_megan_mechcomps_n>0 ) then
886 :
887 : ! set MEGAN fluxes
888 2978352 : do n = 1,shr_megan_mechcomps_n
889 24865776 : do i =1,ncol
890 23376600 : megflx(i) = -cam_in%meganflx(i,n) * megan_wght_factors(n)
891 24865776 : cam_in%cflx(i,megan_indices_map(n)) = cam_in%cflx(i,megan_indices_map(n)) + megflx(i)
892 : enddo
893 :
894 : ! output MEGAN emis fluxes to history
895 2978352 : call outfld('MEG_'//trim(shr_megan_mechcomps(n)%name), megflx(:ncol), ncol, lchnk)
896 : enddo
897 :
898 : endif
899 :
900 1489176 : if ( use_hemco ) then
901 : ! prescribed emissions from HEMCO ...
902 :
903 : !-----------------------------------------------------------------------
904 : ! ... Set surface emissions using HEMCO compatibility API
905 : !-----------------------------------------------------------------------
906 0 : call hco_set_srf_emissions( lchnk, ncol, sflx(:,:), pbuf )
907 : else
908 : ! prescribed emissions from file ...
909 :
910 : !-----------------------------------------------------------------------
911 : ! ... Set surface emissions
912 : !-----------------------------------------------------------------------
913 1489176 : call set_srf_emissions( lchnk, ncol, sflx(:,:) )
914 : endif
915 :
916 62545392 : do m = 1,pcnst
917 61056216 : n = map2chm(m)
918 62545392 : if ( n /= h2o_ndx .and. n > 0 ) then
919 745973280 : cam_in%cflx(:ncol,m) = cam_in%cflx(:ncol,m) + sflx(:ncol,n)
920 44675280 : if (srf_emis_diag(m)) then
921 25315992 : call outfld( sflxnam(m), cam_in%cflx(:ncol,m), ncol,lchnk )
922 : endif
923 : endif
924 : enddo
925 :
926 : ! fire surface emissions if not elevated forcing
927 1489176 : call fire_emissions_srf( lchnk, ncol, cam_in%fireflx, cam_in%cflx )
928 :
929 : ! air-sea exchange of trace gases
930 1489176 : call ocean_emis_getflux(lchnk, ncol, state, cam_in%u10, cam_in%sst, cam_in%ocnfrac, cam_in%icefrac, cam_in%cflx)
931 :
932 1489176 : end subroutine chem_emissions
933 :
934 : !================================================================================
935 :
936 0 : subroutine chem_init_cnst( name, latvals, lonvals, mask, q)
937 : !-----------------------------------------------------------------------
938 : !
939 : ! Purpose:
940 : ! Specify initial mass mixing ratios
941 : !
942 : !-----------------------------------------------------------------------
943 :
944 1489176 : use chem_mods, only : inv_lst
945 :
946 : use physconst, only : mwdry, mwch4, mwn2o, mwf11, mwf12
947 : use chem_surfvals, only : chem_surfvals_get
948 :
949 : implicit none
950 :
951 : !-----------------------------------------------------------------------
952 : ! Dummy arguments
953 : !-----------------------------------------------------------------------
954 : character(len=*), intent(in) :: name ! constituent name
955 : real(r8), intent(in) :: latvals(:) ! lat in degrees (ncol)
956 : real(r8), intent(in) :: lonvals(:) ! lon in degrees (ncol)
957 : logical, intent(in) :: mask(:) ! Only initialize where .true.
958 : real(r8), intent(out) :: q(:,:) ! kg tracer/kg dry air (gcol, plev
959 :
960 : !-----------------------------------------------------------------------
961 : ! Local variables
962 : !-----------------------------------------------------------------------
963 :
964 : real(r8) :: rmwn2o != mwn2o/mwdry ! ratio of mol weight n2o to dry air
965 : real(r8) :: rmwch4 != mwch4/mwdry ! ratio of mol weight ch4 to dry air
966 : real(r8) :: rmwf11 != mwf11/mwdry ! ratio of mol weight cfc11 to dry air
967 : real(r8) :: rmwf12 != mwf12/mwdry ! ratio of mol weight cfc12 to dry air
968 : integer :: ilev, nlev
969 :
970 : !-----------------------------------------------------------------------
971 : ! initialize local variables
972 : !-----------------------------------------------------------------------
973 :
974 0 : rmwn2o = mwn2o/mwdry
975 0 : rmwch4 = mwch4/mwdry
976 0 : rmwf11 = mwf11/mwdry
977 0 : rmwf12 = mwf12/mwdry
978 :
979 : !-----------------------------------------------------------------------
980 : ! Get initial mixing ratios
981 : !-----------------------------------------------------------------------
982 0 : nlev = size(q, 2)
983 0 : if ( any( inv_lst .eq. name ) ) then
984 0 : do ilev = 1, nlev
985 0 : where(mask)
986 0 : q(:,ilev) = 0.0_r8
987 : end where
988 : end do
989 : else
990 0 : do ilev = 1, nlev
991 0 : where(mask)
992 0 : q(:,ilev) = 1.e-38_r8
993 : end where
994 : end do
995 : endif
996 :
997 0 : if ( ghg_chem ) then
998 0 : do ilev = 1, nlev
999 0 : select case (name)
1000 : case ('N2O')
1001 0 : where(mask)
1002 0 : q(:,ilev) = rmwn2o * chem_surfvals_get('N2OVMR')
1003 : end where
1004 : case ('CH4')
1005 0 : where(mask)
1006 0 : q(:,ilev) = rmwch4 * chem_surfvals_get('CH4VMR')
1007 : end where
1008 : case ('CFC11')
1009 0 : where(mask)
1010 0 : q(:,ilev) = rmwf11 * chem_surfvals_get('F11VMR')
1011 : end where
1012 : case ('CFC12')
1013 0 : where(mask)
1014 0 : q(:,ilev) = rmwf12 * chem_surfvals_get('F12VMR')
1015 : end where
1016 : case ('CO2')
1017 0 : where(mask)
1018 0 : q(:,ilev) = chem_surfvals_get('CO2MMR')
1019 : end where
1020 : end select
1021 : end do
1022 : end if
1023 :
1024 0 : end subroutine chem_init_cnst
1025 :
1026 741888 : subroutine chem_timestep_init(phys_state,pbuf2d)
1027 :
1028 0 : use time_manager, only : get_nstep
1029 : use time_manager, only : get_curr_calday
1030 : use mo_srf_emissions, only : set_srf_emissions_time
1031 : use mo_sulf, only : set_sulf_time
1032 : use mo_extfrc, only : extfrc_timestep_init
1033 : use mo_flbc, only : flbc_chk
1034 : use tracer_cnst, only : tracer_cnst_adv
1035 : use tracer_srcs, only : tracer_srcs_adv
1036 : use mo_ghg_chem, only : ghg_chem_timestep_init
1037 :
1038 : use mo_aurora, only : aurora_timestep_init
1039 : use mo_photo, only : photo_timestep_init
1040 :
1041 : use cfc11star, only : update_cfc11star
1042 : use physics_buffer, only : physics_buffer_desc
1043 : use ocean_emis, only : ocean_emis_advance
1044 : use mee_fluxes, only : mee_fluxes_adv
1045 :
1046 : implicit none
1047 :
1048 : type(physics_state), intent(inout) :: phys_state(begchunk:endchunk)
1049 : type(physics_buffer_desc), pointer :: pbuf2d(:,:)
1050 :
1051 : !-----------------------------------------------------------------------
1052 : ! Local variables
1053 : !-----------------------------------------------------------------------
1054 : real(r8) :: calday
1055 : integer :: nstep
1056 :
1057 370944 : nstep = get_nstep()
1058 370944 : chem_step = mod( nstep, chem_freq ) == 0
1059 :
1060 370944 : if ( .not. chem_step ) return
1061 :
1062 : !-----------------------------------------------------------------------
1063 : ! get current calendar day of year
1064 : !-----------------------------------------------------------------------
1065 370944 : calday = get_curr_calday( )
1066 :
1067 : !-----------------------------------------------------------------------
1068 : ! Set emissions timing factors
1069 : !-----------------------------------------------------------------------
1070 370944 : call set_srf_emissions_time( pbuf2d, phys_state )
1071 :
1072 : !-----------------------------------------------------------------------
1073 : ! Set external forcings timing factors
1074 : !-----------------------------------------------------------------------
1075 370944 : call extfrc_timestep_init( pbuf2d, phys_state )
1076 :
1077 : !-----------------------------------------------------------------------
1078 : ! Set sulf timing factors
1079 : !-----------------------------------------------------------------------
1080 370944 : call set_sulf_time( pbuf2d, phys_state )
1081 :
1082 : !-----------------------------------------------------------------------
1083 : ! Set fixed lower boundary timing factors
1084 : !-----------------------------------------------------------------------
1085 370944 : call flbc_chk
1086 :
1087 : !-----------------------------------------------------------------------
1088 : ! Set fixed offline tracers
1089 : !-----------------------------------------------------------------------
1090 370944 : call tracer_cnst_adv(pbuf2d, phys_state)
1091 :
1092 : !-----------------------------------------------------------------------
1093 : ! Set fixed offline tracer sources
1094 : !-----------------------------------------------------------------------
1095 370944 : call tracer_srcs_adv(pbuf2d, phys_state)
1096 :
1097 370944 : if ( ghg_chem ) then
1098 370944 : call ghg_chem_timestep_init(phys_state)
1099 : endif
1100 :
1101 : !-----------------------------------------------------------------------
1102 : ! Set up aurora
1103 : !-----------------------------------------------------------------------
1104 370944 : call aurora_timestep_init
1105 :
1106 : !-----------------------------------------------------------------------------
1107 : ! ... setup the time interpolation for mo_photo
1108 : !-----------------------------------------------------------------------------
1109 370944 : call photo_timestep_init( calday )
1110 :
1111 370944 : call update_cfc11star( pbuf2d, phys_state )
1112 :
1113 : ! Galatic Cosmic Rays ...
1114 370944 : call gcr_ionization_adv( pbuf2d, phys_state )
1115 370944 : call epp_ionization_adv()
1116 :
1117 : ! medium energy electron flux data ...
1118 370944 : call mee_fluxes_adv()
1119 :
1120 370944 : call ocean_emis_advance( pbuf2d, phys_state )
1121 :
1122 370944 : end subroutine chem_timestep_init
1123 :
1124 62545392 : subroutine chem_timestep_tend( state, ptend, cam_in, cam_out, dt, pbuf, fh2o)
1125 :
1126 : !-----------------------------------------------------------------------
1127 : !
1128 : ! Purpose:
1129 : ! Interface to parameterized greenhouse gas chemisty (source/sink).
1130 : !
1131 : ! Method:
1132 : ! <Describe the algorithm(s) used in the routine.>
1133 : ! <Also include any applicable external references.>
1134 : !
1135 : ! Author: B.A. Boville
1136 : !
1137 : !-----------------------------------------------------------------------
1138 :
1139 370944 : use physics_buffer, only : physics_buffer_desc, pbuf_get_field, pbuf_old_tim_idx
1140 : use cam_history, only : outfld
1141 : use time_manager, only : get_curr_calday
1142 : use mo_gas_phase_chemdr, only : gas_phase_chemdr
1143 : use camsrfexch, only : cam_in_t, cam_out_t
1144 : use perf_mod, only : t_startf, t_stopf
1145 : use tropopause, only : tropopause_findChemTrop, tropopause_find_cam
1146 : use mo_drydep, only : drydep_update
1147 : use mo_neu_wetdep, only : neu_wetdep_tend
1148 : use aerodep_flx, only : aerodep_flx_prescribed
1149 : use short_lived_species, only : short_lived_species_writeic
1150 :
1151 : implicit none
1152 :
1153 : !-----------------------------------------------------------------------
1154 : ! Dummy arguments
1155 : !-----------------------------------------------------------------------
1156 : real(r8), intent(in) :: dt ! time step
1157 : type(physics_state), intent(in) :: state ! Physics state variables
1158 : type(physics_ptend), intent(out) :: ptend ! indivdual parameterization tendencies
1159 : type(cam_in_t), intent(inout) :: cam_in
1160 : type(cam_out_t), intent(inout) :: cam_out
1161 : real(r8), intent(out) :: fh2o(pcols) ! h2o flux to balance source from chemistry
1162 :
1163 :
1164 : type(physics_buffer_desc), pointer :: pbuf(:)
1165 :
1166 : !-----------------------------------------------------------------------
1167 : ! Local variables
1168 : !-----------------------------------------------------------------------
1169 : integer :: i, k, m, n ! indicies
1170 : integer :: lchnk ! chunk identifier
1171 : integer :: ncol ! number of atmospheric columns
1172 : real(r8) :: calday ! current calendar day of year
1173 : real(r8) :: cldw(pcols,pver) ! cloud water (kg/kg)
1174 : real(r8) :: chem_dt ! time step
1175 : real(r8) :: drydepflx(pcols,pcnst) ! dry deposition fluxes (kg/m2/s)
1176 : real(r8) :: wetdepflx(pcols,pcnst) ! wet deposition fluxes (kg/m2/s)
1177 : integer :: tropLev(pcols), tropLevChem(pcols)
1178 : real(r8) :: ncldwtr(pcols,pver) ! droplet number concentration (#/kg)
1179 1489176 : real(r8), pointer :: fsds(:) ! longwave down at sfc
1180 1489176 : real(r8), pointer :: pblh(:)
1181 1489176 : real(r8), pointer :: prain(:,:)
1182 1489176 : real(r8), pointer :: cldfr(:,:)
1183 1489176 : real(r8), pointer :: cmfdqr(:,:)
1184 1489176 : real(r8), pointer :: nevapr(:,:)
1185 1489176 : real(r8), pointer :: cldtop(:)
1186 : real(r8) :: nhx_nitrogen_flx(pcols)
1187 : real(r8) :: noy_nitrogen_flx(pcols)
1188 :
1189 : integer :: tim_ndx
1190 :
1191 : logical :: lq(pcnst)
1192 :
1193 1489176 : if ( .not. chem_step ) return
1194 :
1195 1489176 : chem_dt = chem_freq*dt
1196 :
1197 1489176 : lchnk = state%lchnk
1198 1489176 : ncol = state%ncol
1199 :
1200 1489176 : call short_lived_species_writeic( lchnk, pbuf )
1201 :
1202 1489176 : lq(:) = .false.
1203 62545392 : do n = 1,pcnst
1204 61056216 : m = map2chm(n)
1205 62545392 : if( m > 0 ) then
1206 46164456 : lq(n) = .true.
1207 : end if
1208 : end do
1209 1489176 : if ( ghg_chem ) lq(1) = .true.
1210 :
1211 1489176 : call physics_ptend_init(ptend, state%psetcols, 'chemistry', lq=lq)
1212 :
1213 1489176 : call drydep_update( state, cam_in )
1214 :
1215 : !-----------------------------------------------------------------------
1216 : ! get current calendar day of year
1217 : !-----------------------------------------------------------------------
1218 1489176 : calday = get_curr_calday()
1219 :
1220 : !-----------------------------------------------------------------------
1221 : ! get tropopause level
1222 : !-----------------------------------------------------------------------
1223 : !REMOVECAM - no longer need this when CAM is retired and pcols no longer exists
1224 1489176 : tropLev(:) = 0
1225 1489176 : tropLevChem(:) = 0
1226 : !REMOVECAM_END
1227 1489176 : if (.not.chem_use_chemtrop) then
1228 0 : call tropopause_find_cam(state,tropLev)
1229 0 : tropLevChem=tropLev
1230 : else
1231 1489176 : call tropopause_find_cam(state,tropLev)
1232 1489176 : call tropopause_findChemTrop(state, tropLevChem)
1233 : endif
1234 :
1235 1489176 : tim_ndx = pbuf_old_tim_idx()
1236 1489176 : call pbuf_get_field(pbuf, ndx_fsds, fsds)
1237 1489176 : call pbuf_get_field(pbuf, ndx_pblh, pblh)
1238 4467528 : call pbuf_get_field(pbuf, ndx_prain, prain, start=(/1,1/), kount=(/ncol,pver/))
1239 10424232 : call pbuf_get_field(pbuf, ndx_cld, cldfr, start=(/1,1,tim_ndx/), kount=(/ncol,pver,1/) )
1240 4467528 : call pbuf_get_field(pbuf, ndx_cmfdqr, cmfdqr, start=(/1,1/), kount=(/ncol,pver/))
1241 4467528 : call pbuf_get_field(pbuf, ndx_nevapr, nevapr, start=(/1,1/), kount=(/ncol,pver/))
1242 1489176 : call pbuf_get_field(pbuf, ndx_cldtop, cldtop )
1243 :
1244 : !-----------------------------------------------------------------------
1245 : ! call Neu wet dep scheme
1246 : !-----------------------------------------------------------------------
1247 : call neu_wetdep_tend(lchnk,ncol,state%q,state%pmid,state%pdel,state%zi,state%t,dt, &
1248 1489176 : prain, nevapr, cldfr, cmfdqr, ptend%q, wetdepflx)
1249 :
1250 : !-----------------------------------------------------------------------
1251 : ! compute tendencies and surface fluxes
1252 : !-----------------------------------------------------------------------
1253 1489176 : call t_startf( 'chemdr' )
1254 139982544 : do k = 1,pver
1255 2312517168 : cldw(:ncol,k) = state%q(:ncol,k,ixcldliq)
1256 138493368 : if (ixndrop>0) &
1257 2314006344 : ncldwtr(:ncol,k) = state%q(:ncol,k,ixndrop)
1258 : end do
1259 :
1260 : call gas_phase_chemdr(lchnk, ncol, imozart, state%q, &
1261 : state%phis, state%zm, state%zi, calday, &
1262 : state%t, state%pmid, state%pdel, state%pint, state%rpdel, state%rpdeldry, &
1263 : cldw, tropLev, tropLevChem, ncldwtr, state%u, state%v, chem_dt, state%ps, &
1264 : fsds, cam_in%ts, cam_in%asdir, cam_in%ocnfrac, cam_in%icefrac, &
1265 : cam_out%precc, cam_out%precl, cam_in%snowhland, ghg_chem, state%latmapback, &
1266 : drydepflx, wetdepflx, cam_in%cflx, cam_in%fireflx, cam_in%fireztop, &
1267 1489176 : nhx_nitrogen_flx, noy_nitrogen_flx, use_hemco, ptend%q, pbuf )
1268 1489176 : if (associated(cam_out%nhx_nitrogen_flx)) then
1269 24865776 : cam_out%nhx_nitrogen_flx(:ncol) = nhx_nitrogen_flx(:ncol)
1270 : endif
1271 1489176 : if (associated(cam_out%noy_nitrogen_flx)) then
1272 24865776 : cam_out%noy_nitrogen_flx(:ncol) = noy_nitrogen_flx(:ncol)
1273 : endif
1274 :
1275 1489176 : call t_stopf( 'chemdr' )
1276 :
1277 : !-----------------------------------------------------------------------
1278 : ! set flags for tracer tendencies (water and gas phase constituents)
1279 : ! record tendencies on history files
1280 : !-----------------------------------------------------------------------
1281 62545392 : do n = 1,pcnst
1282 61056216 : m = map2chm(n)
1283 61056216 : if( m > 0 ) then
1284 46164456 : call outfld( srcnam(m), ptend%q(:,:,n), pcols, lchnk )
1285 : end if
1286 :
1287 : ! if the user has specified prescribed aerosol dep fluxes then
1288 : ! do not set cam_out dep fluxes according to the prognostic aerosols
1289 62545392 : if (.not.aerodep_flx_prescribed()) then
1290 : ! set deposition fluxes in the export state
1291 122112432 : select case (trim(cnst_name(n)))
1292 : case('CB1')
1293 0 : do i = 1, ncol
1294 0 : cam_out%bcphodry(i) = max(drydepflx(i,n), 0._r8)
1295 : end do
1296 : case('CB2')
1297 0 : do i = 1, ncol
1298 0 : cam_out%bcphidry(i) = max(drydepflx(i,n), 0._r8)
1299 : end do
1300 : case('OC1')
1301 0 : do i = 1, ncol
1302 0 : cam_out%ocphodry(i) = max(drydepflx(i,n), 0._r8)
1303 : end do
1304 : case('OC2')
1305 122112432 : do i = 1, ncol
1306 0 : cam_out%ocphidry(i) = max(drydepflx(i,n), 0._r8)
1307 : end do
1308 : end select
1309 : endif
1310 : end do
1311 1489176 : if ( ghg_chem ) then
1312 1489176 : ptend%lq(1) = .true.
1313 1489176 : call outfld( 'CT_H2O_GHG', ptend%q(:,:,1), pcols, lchnk )
1314 : endif
1315 :
1316 549482856 : call outfld( 'HEIGHT', state%zi(:ncol,:), ncol, lchnk )
1317 :
1318 : !-----------------------------------------------------------------------
1319 : ! turn off water vapor tendency if radiatively passive
1320 : !-----------------------------------------------------------------------
1321 1489176 : if (chem_rad_passive) then
1322 0 : ptend%lq(1) = .false.
1323 0 : ptend%q(:ncol,:,1) = 0._r8
1324 : endif
1325 :
1326 : !-----------------------------------------------------------------------
1327 : ! Compute water vapor flux required to make conservation check
1328 : !-----------------------------------------------------------------------
1329 24865776 : fh2o(:ncol) = 0._r8
1330 139982544 : do k = 1,pver
1331 2314006344 : fh2o(:ncol) = fh2o(:ncol) + ptend%q(:ncol,k,1)*state%pdel(:ncol,k)/gravit
1332 : end do
1333 :
1334 2978352 : end subroutine chem_timestep_tend
1335 :
1336 : !-------------------------------------------------------------------
1337 : !-------------------------------------------------------------------
1338 1536 : subroutine chem_final()
1339 1489176 : use mee_ionization, only: mee_ion_final
1340 : use rate_diags, only: rate_diags_final
1341 : use species_sums_diags, only: species_sums_final
1342 : use short_lived_species, only: short_lived_species_final
1343 :
1344 1536 : call mee_ion_final()
1345 1536 : call rate_diags_final()
1346 1536 : call species_sums_final()
1347 1536 : call short_lived_species_final()
1348 :
1349 1536 : end subroutine chem_final
1350 :
1351 : !-------------------------------------------------------------------
1352 : !-------------------------------------------------------------------
1353 :
1354 1536 : subroutine chem_init_restart( File )
1355 1536 : use pio, only : file_desc_t
1356 : use tracer_cnst, only: init_tracer_cnst_restart
1357 : use tracer_srcs, only: init_tracer_srcs_restart
1358 : implicit none
1359 : type(file_desc_t),intent(inout) :: File ! pio File pointer
1360 :
1361 : !
1362 : ! data for offline tracers
1363 : !
1364 1536 : call init_tracer_cnst_restart(File)
1365 1536 : call init_tracer_srcs_restart(File)
1366 1536 : end subroutine chem_init_restart
1367 : !-------------------------------------------------------------------
1368 : !-------------------------------------------------------------------
1369 1536 : subroutine chem_write_restart( File )
1370 1536 : use tracer_cnst, only: write_tracer_cnst_restart
1371 : use tracer_srcs, only: write_tracer_srcs_restart
1372 : use pio, only : file_desc_t
1373 : implicit none
1374 : type(file_desc_t) :: File
1375 :
1376 : !
1377 : ! data for offline tracers
1378 : !
1379 1536 : call write_tracer_cnst_restart(File)
1380 1536 : call write_tracer_srcs_restart(File)
1381 1536 : end subroutine chem_write_restart
1382 :
1383 : !-------------------------------------------------------------------
1384 : !-------------------------------------------------------------------
1385 768 : subroutine chem_read_restart( File )
1386 1536 : use tracer_cnst, only: read_tracer_cnst_restart
1387 : use tracer_srcs, only: read_tracer_srcs_restart
1388 :
1389 : use pio, only : file_desc_t
1390 : implicit none
1391 : type(file_desc_t) :: File
1392 :
1393 : !
1394 : ! data for offline tracers
1395 : !
1396 768 : call read_tracer_cnst_restart(File)
1397 768 : call read_tracer_srcs_restart(File)
1398 768 : end subroutine chem_read_restart
1399 :
1400 : end module chemistry
|