Line data Source code
1 : !===============================================================================
2 : ! Modal Aerosol Model
3 : !===============================================================================
4 : module aero_model
5 : use shr_kind_mod, only: r8 => shr_kind_r8
6 : use constituents, only: pcnst, cnst_name, cnst_get_ind
7 : use ppgrid, only: pcols, pver, pverp
8 : use phys_control, only: phys_getopts, cam_physpkg_is
9 : use cam_abortutils, only: endrun
10 : use cam_logfile, only: iulog
11 : use perf_mod, only: t_startf, t_stopf
12 : use camsrfexch, only: cam_in_t, cam_out_t
13 : use aerodep_flx, only: aerodep_flx_prescribed
14 : use physics_types, only: physics_state, physics_ptend, physics_ptend_init
15 : use physics_buffer, only: physics_buffer_desc
16 : use physics_buffer, only: pbuf_get_field, pbuf_get_index, pbuf_set_field
17 : use physconst, only: gravit, rair, rhoh2o
18 : use spmd_utils, only: masterproc
19 : use infnan, only: nan, assignment(=)
20 :
21 : use cam_history, only: outfld, fieldname_len
22 : use chem_mods, only: gas_pcnst, adv_mass
23 : use mo_tracname, only: solsym
24 :
25 : use modal_aero_data,only: cnst_name_cw, lptr_so4_cw_amode
26 : use modal_aero_data,only: ntot_amode, modename_amode, nspec_max
27 :
28 : use ref_pres, only: top_lev => clim_modal_aero_top_lev
29 :
30 : use modal_aero_wateruptake, only: modal_strat_sulfate
31 : use mo_setsox, only: setsox, has_sox
32 :
33 : implicit none
34 : private
35 :
36 : public :: aero_model_readnl
37 : public :: aero_model_register
38 : public :: aero_model_init
39 : public :: aero_model_gasaerexch ! create, grow, change, and shrink aerosols.
40 : public :: aero_model_drydep ! aerosol dry deposition and sediment
41 : public :: aero_model_wetdep ! aerosol wet removal
42 : public :: aero_model_emissions ! aerosol emissions
43 : public :: aero_model_surfarea ! tropopspheric aerosol wet surface area for chemistry
44 : public :: aero_model_strat_surfarea ! stratospheric aerosol wet surface area for chemistry
45 :
46 : public :: calc_1_impact_rate
47 : public :: nimptblgrow_mind, nimptblgrow_maxd
48 :
49 : ! Accessor functions
50 : public :: get_scavimptblvol, get_scavimptblnum, get_dlndg_nimptblgrow
51 :
52 : ! Misc private data
53 :
54 : ! number of modes
55 : integer :: nmodes
56 : integer :: pblh_idx = 0
57 : integer :: dgnum_idx = 0
58 : integer :: dgnumwet_idx = 0
59 : integer :: rate1_cw2pr_st_idx = 0
60 :
61 : integer :: wetdens_ap_idx = 0
62 : integer :: qaerwat_idx = 0
63 :
64 : integer :: fracis_idx = 0
65 : integer :: prain_idx = 0
66 : integer :: rprddp_idx = 0
67 : integer :: rprdsh_idx = 0
68 : integer :: nevapr_shcu_idx = 0
69 : integer :: nevapr_dpcu_idx = 0
70 :
71 : integer :: sulfeq_idx = -1
72 :
73 : integer :: nh3_ndx = 0
74 : integer :: nh4_ndx = 0
75 :
76 : ! variables for table lookup of aerosol impaction/interception scavenging rates
77 : integer, parameter :: nimptblgrow_mind=-7, nimptblgrow_maxd=12
78 : real(r8) :: dlndg_nimptblgrow
79 : real(r8),allocatable :: scavimptblnum(:,:)
80 : real(r8),allocatable :: scavimptblvol(:,:)
81 :
82 : ! for surf_area_dens
83 : integer,allocatable :: num_idx(:)
84 : integer,allocatable :: index_tot_mass(:,:)
85 : integer,allocatable :: index_chm_mass(:,:)
86 :
87 : integer :: ndx_h2so4
88 : character(len=fieldname_len), allocatable :: dgnum_name(:), dgnumwet_name(:)
89 :
90 : ! Namelist variables
91 : character(len=16) :: wetdep_list(pcnst) = ' '
92 : character(len=16) :: drydep_list(pcnst) = ' '
93 : real(r8) :: sol_facti_cloud_borne = 1._r8
94 : real(r8) :: sol_factb_interstitial = 0.1_r8
95 : real(r8) :: sol_factic_interstitial = 0.4_r8
96 : real(r8) :: seasalt_emis_scale
97 :
98 : integer :: ndrydep = 0
99 : integer,allocatable :: drydep_indices(:)
100 : integer :: nwetdep = 0
101 : integer,allocatable :: wetdep_indices(:)
102 : logical :: drydep_lq(pcnst)
103 : logical :: wetdep_lq(pcnst)
104 :
105 : logical :: modal_accum_coarse_exch = .false.
106 :
107 : logical :: convproc_do_aer
108 :
109 : contains
110 :
111 : !=============================================================================
112 : ! reads aerosol namelist options
113 : !=============================================================================
114 1536 : subroutine aero_model_readnl(nlfile)
115 :
116 : use namelist_utils, only: find_group_name
117 : use units, only: getunit, freeunit
118 : use mpishorthand
119 : use modal_aero_convproc, only: ma_convproc_readnl
120 :
121 : character(len=*), intent(in) :: nlfile ! filepath for file containing namelist input
122 :
123 : ! Local variables
124 : integer :: unitn, ierr
125 : character(len=*), parameter :: subname = 'aero_model_readnl'
126 :
127 : ! Namelist variables
128 : character(len=16) :: aer_wetdep_list(pcnst) = ' '
129 : character(len=16) :: aer_drydep_list(pcnst) = ' '
130 :
131 : namelist /aerosol_nl/ aer_wetdep_list, aer_drydep_list, sol_facti_cloud_borne, &
132 : sol_factb_interstitial, sol_factic_interstitial, modal_strat_sulfate, modal_accum_coarse_exch, seasalt_emis_scale
133 :
134 : !-----------------------------------------------------------------------------
135 :
136 : ! Read namelist
137 1536 : if (masterproc) then
138 2 : unitn = getunit()
139 2 : open( unitn, file=trim(nlfile), status='old' )
140 2 : call find_group_name(unitn, 'aerosol_nl', status=ierr)
141 2 : if (ierr == 0) then
142 2 : read(unitn, aerosol_nl, iostat=ierr)
143 2 : if (ierr /= 0) then
144 0 : call endrun(subname // ':: ERROR reading namelist')
145 : end if
146 : end if
147 2 : close(unitn)
148 2 : call freeunit(unitn)
149 : end if
150 :
151 : #ifdef SPMD
152 : ! Broadcast namelist variables
153 1536 : call mpibcast(aer_wetdep_list, len(aer_wetdep_list(1))*pcnst, mpichar, 0, mpicom)
154 1536 : call mpibcast(aer_drydep_list, len(aer_drydep_list(1))*pcnst, mpichar, 0, mpicom)
155 1536 : call mpibcast(sol_facti_cloud_borne, 1, mpir8, 0, mpicom)
156 1536 : call mpibcast(sol_factb_interstitial, 1, mpir8, 0, mpicom)
157 1536 : call mpibcast(sol_factic_interstitial, 1, mpir8, 0, mpicom)
158 1536 : call mpibcast(modal_strat_sulfate, 1, mpilog, 0, mpicom)
159 1536 : call mpibcast(seasalt_emis_scale, 1, mpir8, 0, mpicom)
160 1536 : call mpibcast(modal_accum_coarse_exch, 1, mpilog, 0, mpicom)
161 : #endif
162 :
163 64512 : wetdep_list = aer_wetdep_list
164 64512 : drydep_list = aer_drydep_list
165 :
166 1536 : call ma_convproc_readnl(nlfile)
167 :
168 1536 : end subroutine aero_model_readnl
169 :
170 : !=============================================================================
171 : !=============================================================================
172 1536 : subroutine aero_model_register()
173 1536 : use modal_aero_data, only: modal_aero_data_reg
174 :
175 1536 : call modal_aero_data_reg()
176 :
177 1536 : end subroutine aero_model_register
178 :
179 : !=============================================================================
180 : !=============================================================================
181 1536 : subroutine aero_model_init( pbuf2d )
182 :
183 : use mo_chem_utls, only: get_inv_ndx
184 : use cam_history, only: addfld, add_default, horiz_only
185 1536 : use mo_chem_utls, only: get_spc_ndx
186 : use modal_aero_data, only: cnst_name_cw
187 : use modal_aero_data, only: modal_aero_data_init
188 : use rad_constituents,only: rad_cnst_get_info
189 : use dust_model, only: dust_init, dust_names, dust_active, dust_nbin, dust_nnum
190 : use seasalt_model, only: seasalt_init, seasalt_names, seasalt_active,seasalt_nbin
191 : use aer_drydep_mod, only: inidrydep
192 : use wetdep, only: wetdep_init
193 :
194 : use modal_aero_calcsize, only: modal_aero_calcsize_init
195 : use modal_aero_coag, only: modal_aero_coag_init
196 : use modal_aero_deposition, only: modal_aero_deposition_init
197 : use modal_aero_gasaerexch, only: modal_aero_gasaerexch_init
198 : use modal_aero_newnuc, only: modal_aero_newnuc_init
199 : use modal_aero_rename, only: modal_aero_rename_init
200 : use modal_aero_convproc, only: ma_convproc_init
201 :
202 : ! args
203 : type(physics_buffer_desc), pointer :: pbuf2d(:,:)
204 :
205 : ! local vars
206 : character(len=*), parameter :: subrname = 'aero_model_init'
207 : integer :: m, n, id
208 : character(len=20) :: dummy
209 :
210 : logical :: history_aerosol ! Output MAM or SECT aerosol tendencies
211 : logical :: history_chemistry, history_cesm_forcing, history_dust
212 :
213 : integer :: l
214 : character(len=6) :: test_name
215 : character(len=64) :: errmes
216 :
217 : character(len=2) :: unit_basename ! Units 'kg' or '1'
218 : integer :: errcode
219 : character(len=fieldname_len) :: field_name
220 :
221 : character(len=32) :: spec_name
222 : character(len=32) :: spec_type
223 : character(len=32) :: mode_type
224 : integer :: nspec
225 :
226 1536 : dgnum_idx = pbuf_get_index('DGNUM')
227 1536 : dgnumwet_idx = pbuf_get_index('DGNUMWET')
228 1536 : fracis_idx = pbuf_get_index('FRACIS')
229 1536 : prain_idx = pbuf_get_index('PRAIN')
230 1536 : rprddp_idx = pbuf_get_index('RPRDDP')
231 1536 : rprdsh_idx = pbuf_get_index('RPRDSH')
232 1536 : nevapr_shcu_idx = pbuf_get_index('NEVAPR_SHCU')
233 1536 : nevapr_dpcu_idx = pbuf_get_index('NEVAPR_DPCU')
234 1536 : sulfeq_idx = pbuf_get_index('MAMH2SO4EQ',errcode)
235 :
236 : call phys_getopts(history_aerosol_out = history_aerosol, &
237 : history_chemistry_out=history_chemistry, &
238 : history_cesm_forcing_out=history_cesm_forcing, &
239 : history_dust_out=history_dust, &
240 1536 : convproc_do_aer_out = convproc_do_aer)
241 :
242 1536 : call rad_cnst_get_info(0, nmodes=nmodes)
243 :
244 1536 : call modal_aero_data_init(pbuf2d)
245 1536 : call modal_aero_bcscavcoef_init()
246 :
247 1536 : call modal_aero_rename_init( modal_accum_coarse_exch )
248 : ! calcsize call must follow rename call
249 1536 : call modal_aero_calcsize_init( pbuf2d )
250 1536 : call modal_aero_gasaerexch_init
251 : ! coag call must follow gasaerexch call
252 1536 : call modal_aero_coag_init
253 1536 : call modal_aero_newnuc_init
254 :
255 : ! call modal_aero_deposition_init only if the user has not specified
256 : ! prescribed aerosol deposition fluxes
257 1536 : if (.not.aerodep_flx_prescribed()) then
258 1536 : call modal_aero_deposition_init
259 : endif
260 :
261 1536 : if (convproc_do_aer) then
262 1536 : call ma_convproc_init()
263 : endif
264 :
265 1536 : call dust_init()
266 1536 : call seasalt_init(seasalt_emis_scale)
267 1536 : call wetdep_init()
268 :
269 1536 : nwetdep = 0
270 1536 : ndrydep = 0
271 :
272 64512 : count_species: do m = 1,pcnst
273 62976 : if ( len_trim(wetdep_list(m)) /= 0 ) then
274 29184 : nwetdep = nwetdep+1
275 : endif
276 64512 : if ( len_trim(drydep_list(m)) /= 0 ) then
277 29184 : ndrydep = ndrydep+1
278 : endif
279 : enddo count_species
280 :
281 1536 : if (nwetdep>0) &
282 4608 : allocate(wetdep_indices(nwetdep))
283 1536 : if (ndrydep>0) &
284 4608 : allocate(drydep_indices(ndrydep))
285 :
286 30720 : do m = 1,ndrydep
287 29184 : call cnst_get_ind ( drydep_list(m), id, abort=.false. )
288 29184 : if (id>0) then
289 29184 : drydep_indices(m) = id
290 : else
291 0 : call endrun(subrname//': invalid drydep species: '//trim(drydep_list(m)) )
292 : endif
293 :
294 30720 : if (masterproc) then
295 38 : write(iulog,*) subrname//': '//drydep_list(m)//' will have drydep applied'
296 : endif
297 : enddo
298 30720 : do m = 1,nwetdep
299 29184 : call cnst_get_ind ( wetdep_list(m), id, abort=.false. )
300 29184 : if (id>0) then
301 29184 : wetdep_indices(m) = id
302 : else
303 0 : call endrun(subrname//': invalid wetdep species: '//trim(wetdep_list(m)) )
304 : endif
305 :
306 30720 : if (masterproc) then
307 38 : write(iulog,*) subrname//': '//wetdep_list(m)//' will have wet removal'
308 : endif
309 : enddo
310 :
311 1536 : if (ndrydep>0) then
312 :
313 1536 : call inidrydep(rair, gravit)
314 :
315 1536 : dummy = 'RAM1'
316 1536 : call addfld (dummy,horiz_only, 'A','frac','RAM1')
317 1536 : if ( history_aerosol ) then
318 0 : call add_default (dummy, 1, ' ')
319 : endif
320 1536 : dummy = 'airFV'
321 1536 : call addfld (dummy,horiz_only, 'A','frac','FV')
322 1536 : if ( history_aerosol ) then
323 0 : call add_default (dummy, 1, ' ')
324 : endif
325 :
326 : endif
327 :
328 1536 : if (dust_active) then
329 : ! emissions diagnostics ....
330 :
331 10752 : do m = 1, dust_nbin+dust_nnum
332 9216 : dummy = trim(dust_names(m)) // 'SF'
333 9216 : call addfld (dummy,horiz_only, 'A','kg/m2/s',trim(dust_names(m))//' dust surface emission')
334 10752 : if (history_aerosol.or.history_chemistry) then
335 9216 : call add_default (dummy, 1, ' ')
336 : endif
337 : enddo
338 :
339 1536 : dummy = 'DSTSFMBL'
340 1536 : call addfld (dummy,horiz_only, 'A','kg/m2/s','Mobilization flux at surface')
341 1536 : if (history_aerosol .or. history_dust) then
342 0 : call add_default (dummy, 1, ' ')
343 : endif
344 :
345 1536 : dummy = 'LND_MBL'
346 1536 : call addfld (dummy,horiz_only, 'A','frac','Soil erodibility factor')
347 1536 : if (history_aerosol) then
348 0 : call add_default (dummy, 1, ' ')
349 : endif
350 :
351 : endif
352 :
353 1536 : if (seasalt_active) then
354 :
355 1536 : dummy = 'SSTSFMBL'
356 1536 : call addfld (dummy,horiz_only, 'A','kg/m2/s','Mobilization flux at surface')
357 1536 : if (history_aerosol) then
358 0 : call add_default (dummy, 1, ' ')
359 : endif
360 :
361 6144 : do m = 1, seasalt_nbin
362 4608 : dummy = trim(seasalt_names(m)) // 'SF'
363 4608 : call addfld (dummy,horiz_only, 'A','kg/m2/s',trim(seasalt_names(m))//' seasalt surface emission')
364 6144 : if (history_aerosol.or.history_chemistry) then
365 4608 : call add_default (dummy, 1, ' ')
366 : endif
367 : enddo
368 :
369 : endif
370 :
371 :
372 : ! set flags for drydep tendencies
373 1536 : drydep_lq(:) = .false.
374 30720 : do m=1,ndrydep
375 29184 : id = drydep_indices(m)
376 30720 : drydep_lq(id) = .true.
377 : enddo
378 :
379 : ! set flags for wetdep tendencies
380 1536 : wetdep_lq(:) = .false.
381 30720 : do m=1,nwetdep
382 29184 : id = wetdep_indices(m)
383 30720 : wetdep_lq(id) = .true.
384 : enddo
385 :
386 1536 : wetdens_ap_idx = pbuf_get_index('WETDENS_AP')
387 1536 : qaerwat_idx = pbuf_get_index('QAERWAT')
388 1536 : pblh_idx = pbuf_get_index('pblh')
389 :
390 1536 : rate1_cw2pr_st_idx = pbuf_get_index('RATE1_CW2PR_ST')
391 1536 : call pbuf_set_field(pbuf2d, rate1_cw2pr_st_idx, 0.0_r8)
392 :
393 30720 : do m = 1,ndrydep
394 :
395 : ! units
396 29184 : if (drydep_list(m)(1:3) == 'num') then
397 6144 : unit_basename = ' 1'
398 : else
399 23040 : unit_basename = 'kg'
400 : endif
401 :
402 : call addfld (trim(drydep_list(m))//'DDF', horiz_only, 'A',unit_basename//'/m2/s ', &
403 29184 : trim(drydep_list(m))//' dry deposition flux at bottom (grav + turb)')
404 : call addfld (trim(drydep_list(m))//'TBF', horiz_only, 'A',unit_basename//'/m2/s', &
405 29184 : trim(drydep_list(m))//' turbulent dry deposition flux')
406 : call addfld (trim(drydep_list(m))//'GVF', horiz_only, 'A',unit_basename//'/m2/s ', &
407 29184 : trim(drydep_list(m))//' gravitational dry deposition flux')
408 : call addfld (trim(drydep_list(m))//'DTQ', (/ 'lev' /), 'A',unit_basename//'/kg/s ', &
409 58368 : trim(drydep_list(m))//' dry deposition')
410 : call addfld (trim(drydep_list(m))//'DDV', (/ 'lev' /), 'A','m/s', &
411 58368 : trim(drydep_list(m))//' deposition velocity')
412 :
413 29184 : if ( history_aerosol.or.history_chemistry ) then
414 29184 : call add_default (trim(drydep_list(m))//'DDF', 1, ' ')
415 : endif
416 30720 : if ( history_aerosol ) then
417 0 : call add_default (trim(drydep_list(m))//'TBF', 1, ' ')
418 0 : call add_default (trim(drydep_list(m))//'GVF', 1, ' ')
419 : endif
420 :
421 : enddo
422 :
423 30720 : do m = 1,nwetdep
424 :
425 : ! units
426 29184 : if (wetdep_list(m)(1:3) == 'num') then
427 6144 : unit_basename = ' 1'
428 : else
429 23040 : unit_basename = 'kg'
430 : endif
431 :
432 : call addfld (trim(wetdep_list(m))//'SFWET', &
433 29184 : horiz_only, 'A',unit_basename//'/m2/s ','Wet deposition flux at surface')
434 : call addfld (trim(wetdep_list(m))//'SFSIC', &
435 29184 : horiz_only, 'A',unit_basename//'/m2/s ','Wet deposition flux (incloud, convective) at surface')
436 : call addfld (trim(wetdep_list(m))//'SFSIS', &
437 29184 : horiz_only, 'A',unit_basename//'/m2/s ','Wet deposition flux (incloud, stratiform) at surface')
438 : call addfld (trim(wetdep_list(m))//'SFSBC', &
439 29184 : horiz_only, 'A',unit_basename//'/m2/s ','Wet deposition flux (belowcloud, convective) at surface')
440 : call addfld (trim(wetdep_list(m))//'SFSBS', &
441 29184 : horiz_only, 'A',unit_basename//'/m2/s ','Wet deposition flux (belowcloud, stratiform) at surface')
442 :
443 29184 : if (convproc_do_aer) then
444 : call addfld (trim(wetdep_list(m))//'SFSES', &
445 29184 : horiz_only, 'A','kg/m2/s','Wet deposition flux (precip evap, stratiform) at surface')
446 : call addfld (trim(wetdep_list(m))//'SFSBD', &
447 29184 : horiz_only, 'A','kg/m2/s','Wet deposition flux (belowcloud, deep convective) at surface')
448 : end if
449 :
450 58368 : call addfld (trim(wetdep_list(m))//'WET',(/ 'lev' /), 'A',unit_basename//'/kg/s ','wet deposition tendency')
451 : call addfld (trim(wetdep_list(m))//'SIC',(/ 'lev' /), 'A',unit_basename//'/kg/s ', &
452 58368 : trim(wetdep_list(m))//' ic wet deposition')
453 : call addfld (trim(wetdep_list(m))//'SIS',(/ 'lev' /), 'A',unit_basename//'/kg/s ', &
454 58368 : trim(wetdep_list(m))//' is wet deposition')
455 : call addfld (trim(wetdep_list(m))//'SBC',(/ 'lev' /), 'A',unit_basename//'/kg/s ', &
456 58368 : trim(wetdep_list(m))//' bc wet deposition')
457 : call addfld (trim(wetdep_list(m))//'SBS',(/ 'lev' /), 'A',unit_basename//'/kg/s ', &
458 58368 : trim(wetdep_list(m))//' bs wet deposition')
459 :
460 29184 : if ( history_aerosol .or. history_chemistry ) then
461 29184 : call add_default (trim(wetdep_list(m))//'SFWET', 1, ' ')
462 : endif
463 30720 : if ( history_aerosol ) then
464 0 : call add_default (trim(wetdep_list(m))//'SFSIC', 1, ' ')
465 0 : call add_default (trim(wetdep_list(m))//'SFSIS', 1, ' ')
466 0 : call add_default (trim(wetdep_list(m))//'SFSBC', 1, ' ')
467 0 : call add_default (trim(wetdep_list(m))//'SFSBS', 1, ' ')
468 0 : if (convproc_do_aer) then
469 0 : call add_default (trim(wetdep_list(m))//'SFSES', 1, ' ')
470 0 : call add_default (trim(wetdep_list(m))//'SFSBD', 1, ' ')
471 : end if
472 : endif
473 :
474 : enddo
475 :
476 49152 : do m = 1,gas_pcnst
477 :
478 47616 : if ( solsym(m)(1:3) == 'num') then
479 6144 : unit_basename = ' 1' ! Units 'kg' or '1'
480 : else
481 41472 : unit_basename = 'kg' ! Units 'kg' or '1'
482 : end if
483 :
484 : call addfld( 'GS_'//trim(solsym(m)),horiz_only, 'A', unit_basename//'/m2/s ', &
485 47616 : trim(solsym(m))//' gas chemistry/wet removal (for gas species)')
486 : call addfld( 'AQ_'//trim(solsym(m)),horiz_only, 'A', unit_basename//'/m2/s ', &
487 47616 : trim(solsym(m))//' aqueous chemistry (for gas species)')
488 49152 : if ( history_aerosol ) then
489 0 : call add_default( 'AQ_'//trim(solsym(m)), 1, ' ')
490 : endif
491 :
492 : enddo
493 64512 : do n = 1,pcnst
494 64512 : if( .not. (cnst_name_cw(n) == ' ') ) then
495 :
496 29184 : if (cnst_name_cw(n)(1:3) == 'num') then
497 6144 : unit_basename = ' 1'
498 : else
499 23040 : unit_basename = 'kg'
500 : endif
501 :
502 : call addfld( cnst_name_cw(n), (/ 'lev' /), 'A', unit_basename//'/kg ', &
503 58368 : trim(cnst_name_cw(n))//' in cloud water')
504 29184 : call addfld (trim(cnst_name_cw(n))//'SFWET', horiz_only, 'A', unit_basename//'/m2/s ', &
505 58368 : trim(cnst_name_cw(n))//' wet deposition flux at surface')
506 29184 : call addfld (trim(cnst_name_cw(n))//'SFSIC', horiz_only, 'A', unit_basename//'/m2/s ', &
507 58368 : trim(cnst_name_cw(n))//' wet deposition flux (incloud, convective) at surface')
508 29184 : call addfld (trim(cnst_name_cw(n))//'SFSIS', horiz_only, 'A', unit_basename//'/m2/s ', &
509 58368 : trim(cnst_name_cw(n))//' wet deposition flux (incloud, stratiform) at surface')
510 29184 : call addfld (trim(cnst_name_cw(n))//'SFSBC', horiz_only, 'A', unit_basename//'/m2/s ', &
511 58368 : trim(cnst_name_cw(n))//' wet deposition flux (belowcloud, convective) at surface')
512 29184 : call addfld (trim(cnst_name_cw(n))//'SFSBS', horiz_only, 'A', unit_basename//'/m2/s ', &
513 58368 : trim(cnst_name_cw(n))//' wet deposition flux (belowcloud, stratiform) at surface')
514 29184 : call addfld (trim(cnst_name_cw(n))//'DDF', horiz_only, 'A', unit_basename//'/m2/s ', &
515 58368 : trim(cnst_name_cw(n))//' dry deposition flux at bottom (grav + turb)')
516 29184 : call addfld (trim(cnst_name_cw(n))//'TBF', horiz_only, 'A', unit_basename//'/m2/s ', &
517 58368 : trim(cnst_name_cw(n))//' turbulent dry deposition flux')
518 29184 : call addfld (trim(cnst_name_cw(n))//'GVF', horiz_only, 'A', unit_basename//'/m2/s ', &
519 58368 : trim(cnst_name_cw(n))//' gravitational dry deposition flux')
520 :
521 29184 : if (convproc_do_aer) then
522 29184 : call addfld (trim(cnst_name_cw(n))//'SFSEC', &
523 58368 : horiz_only, 'A','kg/m2/s','Wet deposition flux (precip evap, convective) at surface')
524 29184 : call addfld (trim(cnst_name_cw(n))//'SFSES', &
525 58368 : horiz_only, 'A','kg/m2/s','Wet deposition flux (precip evap, stratiform) at surface')
526 29184 : call addfld (trim(cnst_name_cw(n))//'SFSBD', &
527 58368 : horiz_only, 'A','kg/m2/s','Wet deposition flux (belowcloud, deep convective) at surface')
528 : end if
529 :
530 :
531 29184 : if ( history_aerosol.or. history_chemistry ) then
532 29184 : call add_default( cnst_name_cw(n), 1, ' ' )
533 29184 : call add_default (trim(cnst_name_cw(n))//'SFWET', 1, ' ')
534 : endif
535 29184 : if ( history_aerosol ) then
536 0 : call add_default (trim(cnst_name_cw(n))//'GVF', 1, ' ')
537 0 : call add_default (trim(cnst_name_cw(n))//'TBF', 1, ' ')
538 0 : call add_default (trim(cnst_name_cw(n))//'DDF', 1, ' ')
539 0 : call add_default (trim(cnst_name_cw(n))//'SFSBS', 1, ' ')
540 0 : call add_default (trim(cnst_name_cw(n))//'SFSIC', 1, ' ')
541 0 : call add_default (trim(cnst_name_cw(n))//'SFSBC', 1, ' ')
542 0 : call add_default (trim(cnst_name_cw(n))//'SFSIS', 1, ' ')
543 0 : if (convproc_do_aer) then
544 0 : call add_default (trim(cnst_name_cw(n))//'SFSEC', 1, ' ')
545 0 : call add_default (trim(cnst_name_cw(n))//'SFSES', 1, ' ')
546 0 : call add_default (trim(cnst_name_cw(n))//'SFSBD', 1, ' ')
547 : end if
548 : endif
549 : endif
550 : enddo
551 :
552 6144 : allocate(dgnum_name(ntot_amode), dgnumwet_name(ntot_amode))
553 7680 : do n=1,ntot_amode
554 6144 : dgnum_name(n) = ' '
555 6144 : dgnumwet_name(n) = ' '
556 6144 : write(dgnum_name(n),fmt='(a,i1)') 'dgnum',n
557 6144 : write(dgnumwet_name(n),fmt='(a,i1)') 'dgnumwet',n
558 12288 : call addfld( dgnum_name(n), (/ 'lev' /), 'I', 'm', 'Aerosol mode dry diameter' )
559 12288 : call addfld( dgnumwet_name(n), (/ 'lev' /), 'I', 'm', 'Aerosol mode wet diameter' )
560 6144 : if ( history_aerosol ) then
561 0 : call add_default( dgnum_name(n), 1, ' ' )
562 0 : call add_default( dgnumwet_name(n), 1, ' ' )
563 : endif
564 6144 : if ( history_cesm_forcing .and. n<4 ) then
565 0 : call add_default( dgnumwet_name(n), 8, ' ' )
566 : endif
567 :
568 7680 : if (modal_strat_sulfate) then
569 0 : field_name = ' '
570 0 : write(field_name,fmt='(a,i1)') 'wtpct_a',n
571 0 : call addfld( field_name, (/ 'lev' /), 'I', '%', 'Aerosol mode weight percent H2SO4' )
572 0 : if ( history_aerosol ) then
573 0 : call add_default (field_name, 0, 'I')
574 : endif
575 :
576 0 : field_name = ' '
577 0 : write(field_name,fmt='(a,i1)') 'sulfeq_a',n
578 0 : call addfld( field_name, (/ 'lev' /), 'I', 'kg/kg', 'H2SO4 equilibrium mixing ratio' )
579 0 : if ( history_aerosol ) then
580 0 : call add_default (field_name, 0, 'I')
581 : endif
582 :
583 0 : field_name = ' '
584 0 : write(field_name,fmt='(a,i1)') 'sulden_a',n
585 0 : call addfld( field_name, (/ 'lev' /), 'I', 'g/cm3', 'Sulfate aerosol particle mass density' )
586 0 : if ( history_aerosol ) then
587 0 : call add_default (field_name, 0, 'I')
588 : endif
589 :
590 : end if
591 : end do
592 :
593 1536 : ndx_h2so4 = get_spc_ndx('H2SO4')
594 1536 : nh3_ndx = get_spc_ndx('NH3')
595 1536 : nh4_ndx = get_spc_ndx('NH4')
596 :
597 4608 : allocate(num_idx(ntot_amode))
598 7680 : num_idx = -1
599 :
600 : ! for aero_model_surfarea called from mo_usrrxt
601 7680 : do l=1,ntot_amode
602 6144 : test_name = ' '
603 6144 : write(test_name,fmt='(a5,i1)') 'num_a',l
604 6144 : num_idx(l) = get_spc_ndx( trim(test_name) )
605 7680 : if (num_idx(l) < 0) then
606 0 : write(errmes,fmt='(a,i1)') 'usrrxt_inti: cannot find MAM num_idx ',l
607 0 : write(iulog,*) errmes
608 0 : call endrun(errmes)
609 : endif
610 : end do
611 :
612 6144 : allocate(index_tot_mass(nmodes,nspec_max))
613 4608 : allocate(index_chm_mass(nmodes,nspec_max))
614 47616 : index_tot_mass = -1
615 47616 : index_chm_mass = -1
616 :
617 : ! for surf_area_dens
618 : ! define indices associated with the various aerosol types
619 7680 : do n = 1,nmodes
620 6144 : call rad_cnst_get_info(0, n, mode_type=mode_type, nspec=nspec)
621 7680 : if ( trim(mode_type) /= 'primary_carbon') then ! ignore the primary_carbon mode
622 24576 : do l = 1, nspec
623 19968 : call rad_cnst_get_info(0, n, l, spec_type=spec_type, spec_name=spec_name)
624 19968 : index_tot_mass(n,l) = get_spc_ndx(spec_name)
625 : if ( trim(spec_type) == 'sulfate' .or. &
626 : trim(spec_type) == 's-organic' .or. &
627 : trim(spec_type) == 'p-organic' .or. &
628 19968 : trim(spec_type) == 'black-c' .or. &
629 4608 : trim(spec_type) == 'ammonium') then
630 10752 : index_chm_mass(n,l) = get_spc_ndx(spec_name)
631 : endif
632 : enddo
633 : endif
634 : enddo
635 :
636 1536 : if (has_sox) then
637 7680 : do m = 1, ntot_amode
638 :
639 6144 : l = lptr_so4_cw_amode(m)
640 7680 : if (l > 0) then
641 : call addfld (&
642 4608 : trim(cnst_name_cw(l))//'AQSO4',horiz_only, 'A','kg/m2/s', &
643 9216 : trim(cnst_name_cw(l))//' aqueous phase chemistry')
644 : call addfld (&
645 4608 : trim(cnst_name_cw(l))//'AQH2SO4',horiz_only, 'A','kg/m2/s', &
646 9216 : trim(cnst_name_cw(l))//' aqueous phase chemistry')
647 4608 : if ( history_aerosol ) then
648 0 : call add_default (trim(cnst_name_cw(l))//'AQSO4', 1, ' ')
649 0 : call add_default (trim(cnst_name_cw(l))//'AQH2SO4', 1, ' ')
650 : endif
651 : end if
652 :
653 : end do
654 :
655 3072 : call addfld( 'XPH_LWC', (/ 'lev' /), 'A','kg/kg', 'pH value multiplied by lwc')
656 1536 : call addfld ('AQSO4_H2O2', horiz_only, 'A','kg/m2/s', 'SO4 aqueous phase chemistry due to H2O2')
657 1536 : call addfld ('AQSO4_O3', horiz_only, 'A','kg/m2/s', 'SO4 aqueous phase chemistry due to O3')
658 :
659 1536 : if ( history_aerosol ) then
660 0 : call add_default ('XPH_LWC', 1, ' ')
661 0 : call add_default ('AQSO4_H2O2', 1, ' ')
662 0 : call add_default ('AQSO4_O3', 1, ' ')
663 : endif
664 : endif
665 :
666 3072 : end subroutine aero_model_init
667 :
668 : !=============================================================================
669 : !=============================================================================
670 2529432 : subroutine aero_model_drydep ( state, pbuf, obklen, ustar, cam_in, dt, cam_out, ptend )
671 :
672 1536 : use dust_sediment_mod, only: dust_sediment_tend
673 : use aer_drydep_mod, only: d3ddflux, calcram
674 : use modal_aero_data, only: qqcw_get_field
675 : use modal_aero_data, only: cnst_name_cw
676 : use modal_aero_data, only: alnsg_amode
677 : use modal_aero_data, only: sigmag_amode
678 : use modal_aero_data, only: nspec_amode
679 : use modal_aero_data, only: numptr_amode
680 : use modal_aero_data, only: numptrcw_amode
681 : use modal_aero_data, only: lmassptr_amode
682 : use modal_aero_data, only: lmassptrcw_amode
683 : use modal_aero_deposition, only: set_srf_drydep
684 :
685 : ! args
686 : type(physics_state), intent(in) :: state ! Physics state variables
687 : real(r8), intent(in) :: obklen(:)
688 : real(r8), intent(in) :: ustar(:) ! sfc fric vel
689 : type(cam_in_t), target, intent(in) :: cam_in ! import state
690 : real(r8), intent(in) :: dt ! time step
691 : type(cam_out_t), intent(inout) :: cam_out ! export state
692 : type(physics_ptend), intent(out) :: ptend ! indivdual parameterization tendencies
693 : type(physics_buffer_desc), pointer :: pbuf(:)
694 :
695 : ! local vars
696 58824 : real(r8), pointer :: landfrac(:) ! land fraction
697 58824 : real(r8), pointer :: icefrac(:) ! ice fraction
698 58824 : real(r8), pointer :: ocnfrac(:) ! ocean fraction
699 58824 : real(r8), pointer :: fvin(:) !
700 58824 : real(r8), pointer :: ram1in(:) ! for dry dep velocities from land model for progseasalts
701 :
702 : real(r8) :: fv(pcols) ! for dry dep velocities, from land modified over ocean & ice
703 : real(r8) :: ram1(pcols) ! for dry dep velocities, from land modified over ocean & ice
704 :
705 : integer :: lchnk ! chunk identifier
706 : integer :: ncol ! number of atmospheric columns
707 : integer :: jvlc ! index for last dimension of vlc_xxx arrays
708 : integer :: lphase ! index for interstitial / cloudborne aerosol
709 : integer :: lspec ! index for aerosol number / chem-mass / water-mass
710 : integer :: m ! aerosol mode index
711 : integer :: mm ! tracer index
712 : integer :: i
713 :
714 : real(r8) :: tvs(pcols,pver)
715 : real(r8) :: rho(pcols,pver) ! air density in kg/m3
716 : real(r8) :: sflx(pcols) ! deposition flux
717 : real(r8) :: dep_trb(pcols) !kg/m2/s
718 : real(r8) :: dep_grv(pcols) !kg/m2/s (total of grav and trb)
719 : real(r8) :: pvmzaer(pcols,pverp) ! sedimentation velocity in Pa
720 : real(r8) :: dqdt_tmp(pcols,pver) ! temporary array to hold tendency for 1 species
721 :
722 : real(r8) :: rad_drop(pcols,pver)
723 : real(r8) :: dens_drop(pcols,pver)
724 : real(r8) :: sg_drop(pcols,pver)
725 : real(r8) :: rad_aer(pcols,pver)
726 : real(r8) :: dens_aer(pcols,pver)
727 : real(r8) :: sg_aer(pcols,pver)
728 :
729 : real(r8) :: vlc_dry(pcols,pver,4) ! dep velocity
730 : real(r8) :: vlc_grv(pcols,pver,4) ! dep velocity
731 : real(r8):: vlc_trb(pcols,4) ! dep velocity
732 : real(r8) :: aerdepdryis(pcols,pcnst) ! aerosol dry deposition (interstitial)
733 : real(r8) :: aerdepdrycw(pcols,pcnst) ! aerosol dry deposition (cloud water)
734 58824 : real(r8), pointer :: fldcw(:,:)
735 58824 : real(r8), pointer :: dgncur_awet(:,:,:)
736 58824 : real(r8), pointer :: wetdens(:,:,:)
737 58824 : real(r8), pointer :: qaerwat(:,:,:)
738 :
739 58824 : landfrac => cam_in%landfrac(:)
740 58824 : icefrac => cam_in%icefrac(:)
741 58824 : ocnfrac => cam_in%ocnfrac(:)
742 58824 : fvin => cam_in%fv(:)
743 58824 : ram1in => cam_in%ram1(:)
744 :
745 58824 : lchnk = state%lchnk
746 58824 : ncol = state%ncol
747 :
748 : ! calc ram and fv over ocean and sea ice ...
749 : call calcram( ncol,landfrac,icefrac,ocnfrac,obklen,&
750 : ustar,ram1in,ram1,state%t(:,pver),state%pmid(:,pver),&
751 58824 : state%pdel(:,pver),fvin,fv)
752 :
753 58824 : call outfld( 'airFV', fv(:), pcols, lchnk )
754 58824 : call outfld( 'RAM1', ram1(:), pcols, lchnk )
755 :
756 : ! note that tendencies are not only in sfc layer (because of sedimentation)
757 : ! and that ptend is updated within each subroutine for different species
758 :
759 58824 : call physics_ptend_init(ptend, state%psetcols, 'aero_model_drydep', lq=drydep_lq)
760 :
761 235296 : call pbuf_get_field(pbuf, dgnumwet_idx, dgncur_awet, start=(/1,1,1/), kount=(/pcols,pver,nmodes/) )
762 235296 : call pbuf_get_field(pbuf, wetdens_ap_idx, wetdens, start=(/1,1,1/), kount=(/pcols,pver,nmodes/) )
763 235296 : call pbuf_get_field(pbuf, qaerwat_idx, qaerwat, start=(/1,1,1/), kount=(/pcols,pver,nmodes/) )
764 :
765 91405656 : tvs(:ncol,:) = state%t(:ncol,:)!*(1+state%q(:ncol,k)
766 91405656 : rho(:ncol,:)= state%pmid(:ncol,:)/(rair*state%t(:ncol,:))
767 :
768 : !
769 : ! calc settling/deposition velocities for cloud droplets (and cloud-borne aerosols)
770 : !
771 : ! *** mean drop radius should eventually be computed from ndrop and qcldwtr
772 93059568 : rad_drop(:,:) = 5.0e-6_r8
773 93059568 : dens_drop(:,:) = rhoh2o
774 93059568 : sg_drop(:,:) = 1.46_r8
775 58824 : jvlc = 3
776 : call modal_aero_depvel_part( ncol,state%t(:,:), state%pmid(:,:), ram1, fv, &
777 : vlc_dry(:,:,jvlc), vlc_trb(:,jvlc), vlc_grv(:,:,jvlc), &
778 58824 : rad_drop(:,:), dens_drop(:,:), sg_drop(:,:), 0, lchnk)
779 58824 : jvlc = 4
780 : call modal_aero_depvel_part( ncol,state%t(:,:), state%pmid(:,:), ram1, fv, &
781 : vlc_dry(:,:,jvlc), vlc_trb(:,jvlc), vlc_grv(:,:,jvlc), &
782 58824 : rad_drop(:,:), dens_drop(:,:), sg_drop(:,:), 3, lchnk)
783 :
784 :
785 :
786 294120 : do m = 1, ntot_amode ! main loop over aerosol modes
787 :
788 764712 : do lphase = 1, 2 ! loop over interstitial / cloud-borne forms
789 :
790 470592 : if (lphase == 1) then ! interstial aerosol - calc settling/dep velocities of mode
791 :
792 : ! rad_aer = volume mean wet radius (m)
793 : ! dgncur_awet = geometric mean wet diameter for number distribution (m)
794 470592 : rad_aer(1:ncol,:) = 0.5_r8*dgncur_awet(1:ncol,:,m) &
795 366093216 : *exp(1.5_r8*(alnsg_amode(m)**2))
796 : ! dens_aer(1:ncol,:) = wet density (kg/m3)
797 365622624 : dens_aer(1:ncol,:) = wetdens(1:ncol,:,m)
798 365622624 : sg_aer(1:ncol,:) = sigmag_amode(m)
799 :
800 235296 : jvlc = 1
801 : call modal_aero_depvel_part( ncol, state%t(:,:), state%pmid(:,:), ram1, fv, &
802 : vlc_dry(:,:,jvlc), vlc_trb(:,jvlc), vlc_grv(:,:,jvlc), &
803 235296 : rad_aer(:,:), dens_aer(:,:), sg_aer(:,:), 0, lchnk)
804 235296 : jvlc = 2
805 : call modal_aero_depvel_part( ncol, state%t(:,:), state%pmid(:,:), ram1, fv, &
806 : vlc_dry(:,:,jvlc), vlc_trb(:,jvlc), vlc_grv(:,:,jvlc), &
807 235296 : rad_aer(:,:), dens_aer(:,:), sg_aer(:,:), 3, lchnk)
808 : end if
809 :
810 3411792 : do lspec = 0, nspec_amode(m)+1 ! loop over number + constituents + water
811 :
812 2705904 : if (lspec == 0) then ! number
813 470592 : if (lphase == 1) then
814 235296 : mm = numptr_amode(m)
815 235296 : jvlc = 1
816 : else
817 235296 : mm = numptrcw_amode(m)
818 235296 : jvlc = 3
819 : endif
820 2235312 : else if (lspec <= nspec_amode(m)) then ! non-water mass
821 1764720 : if (lphase == 1) then
822 882360 : mm = lmassptr_amode(lspec,m)
823 882360 : jvlc = 2
824 : else
825 882360 : mm = lmassptrcw_amode(lspec,m)
826 882360 : jvlc = 4
827 : endif
828 : else ! water mass
829 : ! bypass dry deposition of aerosol water
830 : cycle
831 : if (lphase == 1) then
832 : mm = 0
833 : ! mm = lwaterptr_amode(m)
834 : jvlc = 2
835 : else
836 : mm = 0
837 : jvlc = 4
838 : endif
839 : endif
840 :
841 :
842 2235312 : if (mm <= 0) cycle
843 :
844 : ! if (lphase == 1) then
845 2705904 : if ((lphase == 1) .and. (lspec <= nspec_amode(m))) then
846 1117656 : ptend%lq(mm) = .TRUE.
847 :
848 : ! use pvprogseasalts instead (means making the top level 0)
849 18662256 : pvmzaer(:ncol,1)=0._r8
850 1736707464 : pvmzaer(:ncol,2:pverp) = vlc_dry(:ncol,:,jvlc)
851 :
852 1117656 : call outfld( trim(cnst_name(mm))//'DDV', pvmzaer(:,2:pverp), pcols, lchnk )
853 :
854 : if(.true.) then ! use phil's method
855 : ! convert from meters/sec to pascals/sec
856 : ! pvprogseasalts(:,1) is assumed zero, use density from layer above in conversion
857 1736707464 : pvmzaer(:ncol,2:pverp) = pvmzaer(:ncol,2:pverp) * rho(:ncol,:)*gravit
858 :
859 : ! calculate the tendencies and sfc fluxes from the above velocities
860 : call dust_sediment_tend( &
861 : ncol, dt, state%pint(:,:), state%pmid, state%pdel, state%t , &
862 1117656 : state%q(:,:,mm), pvmzaer, ptend%q(:,:,mm), sflx )
863 : else !use charlie's method
864 : call d3ddflux( ncol, vlc_dry(:,:,jvlc), state%q(:,:,mm), state%pmid, &
865 : state%pdel, tvs, sflx, ptend%q(:,:,mm), dt )
866 : endif
867 :
868 : ! apportion dry deposition into turb and gravitational settling for tapes
869 1117656 : dep_trb = 0._r8
870 1117656 : dep_grv = 0._r8
871 18662256 : do i=1,ncol
872 18662256 : if (vlc_dry(i,pver,jvlc) /= 0._r8) then
873 17544600 : dep_trb(i)=sflx(i)*vlc_trb(i,jvlc)/vlc_dry(i,pver,jvlc)
874 17544600 : dep_grv(i)=sflx(i)*vlc_grv(i,pver,jvlc)/vlc_dry(i,pver,jvlc)
875 : end if
876 : enddo
877 :
878 1117656 : call outfld( trim(cnst_name(mm))//'DDF', sflx, pcols, lchnk)
879 1117656 : call outfld( trim(cnst_name(mm))//'TBF', dep_trb, pcols, lchnk )
880 1117656 : call outfld( trim(cnst_name(mm))//'GVF', dep_grv, pcols, lchnk )
881 1117656 : call outfld( trim(cnst_name(mm))//'DTQ', ptend%q(:,:,mm), pcols, lchnk)
882 18662256 : aerdepdryis(:ncol,mm) = sflx(:ncol)
883 :
884 1117656 : else if ((lphase == 1) .and. (lspec == nspec_amode(m)+1)) then ! aerosol water
885 : ! use pvprogseasalts instead (means making the top level 0)
886 0 : pvmzaer(:ncol,1)=0._r8
887 0 : pvmzaer(:ncol,2:pverp) = vlc_dry(:ncol,:,jvlc)
888 :
889 : if(.true.) then ! use phil's method
890 : ! convert from meters/sec to pascals/sec
891 : ! pvprogseasalts(:,1) is assumed zero, use density from layer above in conversion
892 0 : pvmzaer(:ncol,2:pverp) = pvmzaer(:ncol,2:pverp) * rho(:ncol,:)*gravit
893 :
894 : ! calculate the tendencies and sfc fluxes from the above velocities
895 : call dust_sediment_tend( &
896 : ncol, dt, state%pint(:,:), state%pmid, state%pdel, state%t , &
897 0 : qaerwat(:,:,mm), pvmzaer, dqdt_tmp(:,:), sflx )
898 : else !use charlie's method
899 : call d3ddflux( ncol, vlc_dry(:,:,jvlc), qaerwat(:,:,mm), state%pmid, &
900 : state%pdel, tvs, sflx, dqdt_tmp(:,:), dt )
901 : endif
902 :
903 : ! apportion dry deposition into turb and gravitational settling for tapes
904 0 : dep_trb = 0._r8
905 0 : dep_grv = 0._r8
906 0 : do i=1,ncol
907 0 : if (vlc_dry(i,pver,jvlc) /= 0._r8) then
908 0 : dep_trb(i)=sflx(i)*vlc_trb(i,jvlc)/vlc_dry(i,pver,jvlc)
909 0 : dep_grv(i)=sflx(i)*vlc_grv(i,pver,jvlc)/vlc_dry(i,pver,jvlc)
910 : end if
911 : enddo
912 :
913 0 : qaerwat(1:ncol,:,mm) = qaerwat(1:ncol,:,mm) + dqdt_tmp(1:ncol,:) * dt
914 :
915 : else ! lphase == 2
916 : ! use pvprogseasalts instead (means making the top level 0)
917 18662256 : pvmzaer(:ncol,1)=0._r8
918 1736707464 : pvmzaer(:ncol,2:pverp) = vlc_dry(:ncol,:,jvlc)
919 1117656 : fldcw => qqcw_get_field(pbuf, mm,lchnk)
920 :
921 : if(.true.) then ! use phil's method
922 : ! convert from meters/sec to pascals/sec
923 : ! pvprogseasalts(:,1) is assumed zero, use density from layer above in conversion
924 1736707464 : pvmzaer(:ncol,2:pverp) = pvmzaer(:ncol,2:pverp) * rho(:ncol,:)*gravit
925 :
926 : ! calculate the tendencies and sfc fluxes from the above velocities
927 : call dust_sediment_tend( &
928 : ncol, dt, state%pint(:,:), state%pmid, state%pdel, state%t , &
929 1117656 : fldcw(:,:), pvmzaer, dqdt_tmp(:,:), sflx )
930 : else !use charlie's method
931 : call d3ddflux( ncol, vlc_dry(:,:,jvlc), fldcw(:,:), state%pmid, &
932 : state%pdel, tvs, sflx, dqdt_tmp(:,:), dt )
933 : endif
934 :
935 : ! apportion dry deposition into turb and gravitational settling for tapes
936 1117656 : dep_trb = 0._r8
937 1117656 : dep_grv = 0._r8
938 18662256 : do i=1,ncol
939 18662256 : if (vlc_dry(i,pver,jvlc) /= 0._r8) then
940 17544600 : dep_trb(i)=sflx(i)*vlc_trb(i,jvlc)/vlc_dry(i,pver,jvlc)
941 17544600 : dep_grv(i)=sflx(i)*vlc_grv(i,pver,jvlc)/vlc_dry(i,pver,jvlc)
942 : end if
943 : enddo
944 :
945 1736707464 : fldcw(1:ncol,:) = fldcw(1:ncol,:) + dqdt_tmp(1:ncol,:) * dt
946 :
947 1117656 : call outfld( trim(cnst_name_cw(mm))//'DDF', sflx, pcols, lchnk)
948 1117656 : call outfld( trim(cnst_name_cw(mm))//'TBF', dep_trb, pcols, lchnk )
949 1117656 : call outfld( trim(cnst_name_cw(mm))//'GVF', dep_grv, pcols, lchnk )
950 18662256 : aerdepdrycw(:ncol,mm) = sflx(:ncol)
951 :
952 : endif
953 :
954 : enddo ! lspec = 0, nspec_amode(m)+1
955 : enddo ! lphase = 1, 2
956 : enddo ! m = 1, ntot_amode
957 :
958 : ! if the user has specified prescribed aerosol dep fluxes then
959 : ! do not set cam_out dep fluxes according to the prognostic aerosols
960 58824 : if (.not.aerodep_flx_prescribed()) then
961 58824 : call set_srf_drydep(aerdepdryis, aerdepdrycw, cam_out)
962 : endif
963 :
964 117648 : endsubroutine aero_model_drydep
965 :
966 : !=============================================================================
967 : !=============================================================================
968 2529432 : subroutine aero_model_wetdep( state, dt, dlf, cam_out, ptend, pbuf)
969 :
970 58824 : use modal_aero_deposition, only: set_srf_wetdep
971 : use wetdep, only: wetdepa_v2, wetdep_inputs_set, wetdep_inputs_t
972 : use modal_aero_data
973 : use modal_aero_calcsize, only: modal_aero_calcsize_sub
974 : use modal_aero_wateruptake,only: modal_aero_wateruptake_dr
975 : use modal_aero_convproc, only: deepconv_wetdep_history, ma_convproc_intr, convproc_do_evaprain_atonce
976 :
977 : ! args
978 :
979 : type(physics_state), intent(in) :: state ! Physics state variables
980 : real(r8), intent(in) :: dt ! time step
981 : real(r8), intent(in) :: dlf(:,:) ! shallow+deep convective detrainment [kg/kg/s]
982 : type(cam_out_t), intent(inout) :: cam_out ! export state
983 : type(physics_ptend), intent(out) :: ptend ! indivdual parameterization tendencies
984 : type(physics_buffer_desc), pointer :: pbuf(:)
985 :
986 : ! local vars
987 :
988 : integer :: m ! tracer index
989 :
990 : integer :: lchnk ! chunk identifier
991 : integer :: ncol ! number of atmospheric columns
992 :
993 : real(r8) :: iscavt(pcols, pver)
994 :
995 : integer :: mm
996 : integer :: i,k
997 :
998 : real(r8) :: icscavt(pcols, pver)
999 : real(r8) :: isscavt(pcols, pver)
1000 : real(r8) :: bcscavt(pcols, pver)
1001 : real(r8) :: bsscavt(pcols, pver)
1002 : real(r8) :: sol_factb, sol_facti
1003 : real(r8) :: sol_factic(pcols,pver)
1004 :
1005 : real(r8) :: sflx(pcols) ! deposition flux
1006 :
1007 : integer :: jnv ! index for scavcoefnv 3rd dimension
1008 : integer :: lphase ! index for interstitial / cloudborne aerosol
1009 : integer :: strt_loop, end_loop, stride_loop !loop indices for the lphase loop
1010 : integer :: lspec ! index for aerosol number / chem-mass / water-mass
1011 : integer :: lcoardust, lcoarnacl ! indices for coarse mode dust and seasalt masses
1012 : real(r8) :: dqdt_tmp(pcols,pver) ! temporary array to hold tendency for 1 species
1013 : real(r8) :: f_act_conv(pcols,pver) ! prescribed aerosol activation fraction for convective cloud ! rce 2010/05/01
1014 : real(r8) :: f_act_conv_coarse(pcols,pver) ! similar but for coarse mode ! rce 2010/05/02
1015 : real(r8) :: f_act_conv_coarse_dust, f_act_conv_coarse_nacl ! rce 2010/05/02
1016 : real(r8) :: fracis_cw(pcols,pver)
1017 : real(r8) :: hygro_sum_old(pcols,pver) ! before removal [sum of (mass*hydro/dens)]
1018 : real(r8) :: hygro_sum_del(pcols,pver) ! removal change to [sum of (mass*hydro/dens)]
1019 : real(r8) :: hygro_sum_old_ik, hygro_sum_new_ik
1020 : real(r8) :: prec(pcols) ! precipitation rate
1021 : real(r8) :: q_tmp(pcols,pver) ! temporary array to hold "most current" mixing ratio for 1 species
1022 : real(r8) :: scavcoefnv(pcols,pver,0:2) ! Dana and Hales coefficient (/mm) for
1023 : ! cloud-borne num & vol (0),
1024 : ! interstitial num (1), interstitial vol (2)
1025 : real(r8) :: tmpa, tmpb
1026 : real(r8) :: tmpdust, tmpnacl
1027 : real(r8) :: water_old, water_new ! temporary old/new aerosol water mix-rat
1028 : logical :: isprx(pcols,pver) ! true if precipation
1029 : real(r8) :: aerdepwetis(pcols,pcnst) ! aerosol wet deposition (interstitial)
1030 : real(r8) :: aerdepwetcw(pcols,pcnst) ! aerosol wet deposition (cloud water)
1031 :
1032 : ! For unified convection scheme
1033 : logical, parameter :: do_aero_water_removal = .false. ! True if aerosol water reduction by wet removal is to be calculated
1034 : ! (this has not been fully tested, so best to leave it off)
1035 : logical :: do_hygro_sum_del, do_lphase1, do_lphase2
1036 :
1037 58824 : real(r8), pointer :: rprddp(:,:) ! rain production, deep convection
1038 58824 : real(r8), pointer :: rprdsh(:,:) ! rain production, shallow convection
1039 58824 : real(r8), pointer :: evapcdp(:,:) ! Evaporation rate of deep convective precipitation >=0.
1040 58824 : real(r8), pointer :: evapcsh(:,:) ! Evaporation rate of shallow convective precipitation >=0.
1041 :
1042 : real(r8) :: rprddpsum(pcols)
1043 : real(r8) :: rprdshsum(pcols)
1044 : real(r8) :: evapcdpsum(pcols)
1045 : real(r8) :: evapcshsum(pcols)
1046 :
1047 : real(r8) :: tmp_resudp, tmp_resush
1048 :
1049 : real(r8) :: sflxec(pcols), sflxecdp(pcols) ! deposition flux
1050 : real(r8) :: sflxic(pcols), sflxicdp(pcols) ! deposition flux
1051 : real(r8) :: sflxbc(pcols), sflxbcdp(pcols) ! deposition flux
1052 : real(r8) :: rcscavt(pcols, pver)
1053 : real(r8) :: rsscavt(pcols, pver)
1054 117648 : real(r8) :: qqcw_in(pcols,pver), qqcw_sav(pcols,pver,0:nspec_max) ! temporary array to hold qqcw for the current mode
1055 117648 : real(r8) :: rtscavt(pcols, pver, 0:nspec_max)
1056 :
1057 : integer, parameter :: nsrflx_mzaer2cnvpr = 2
1058 : real(r8) :: qsrflx_mzaer2cnvpr(pcols,pcnst,nsrflx_mzaer2cnvpr)
1059 : ! End unified convection scheme
1060 :
1061 58824 : real(r8), pointer :: fldcw(:,:)
1062 :
1063 58824 : real(r8), pointer :: dgnumwet(:,:,:)
1064 58824 : real(r8), pointer :: qaerwat(:,:,:) ! aerosol water
1065 :
1066 58824 : real(r8), pointer :: fracis(:,:,:) ! fraction of transported species that are insoluble
1067 :
1068 : type(wetdep_inputs_t) :: dep_inputs
1069 :
1070 : real(r8) :: dcondt_resusp3d(2*pcnst,pcols, pver)
1071 :
1072 58824 : lchnk = state%lchnk
1073 58824 : ncol = state%ncol
1074 :
1075 58824 : dcondt_resusp3d(:,:,:) = 0._r8
1076 :
1077 58824 : call physics_ptend_init(ptend, state%psetcols, 'aero_model_wetdep', lq=wetdep_lq)
1078 :
1079 : ! Do calculations of mode radius and water uptake if:
1080 : ! 1) modal aerosols are affecting the climate, or
1081 : ! 2) prognostic modal aerosols are enabled
1082 :
1083 58824 : call t_startf('calcsize')
1084 : ! for prognostic modal aerosols the transfer of mass between aitken and accumulation
1085 : ! modes is done in conjunction with the dry radius calculation
1086 58824 : call modal_aero_calcsize_sub(state, ptend, dt, pbuf)
1087 58824 : call t_stopf('calcsize')
1088 :
1089 58824 : call t_startf('wateruptake')
1090 58824 : call modal_aero_wateruptake_dr(state, pbuf)
1091 58824 : call t_stopf('wateruptake')
1092 :
1093 58824 : if (nwetdep<1) return
1094 :
1095 58824 : call wetdep_inputs_set( state, pbuf, dep_inputs )
1096 :
1097 235296 : call pbuf_get_field(pbuf, dgnumwet_idx, dgnumwet, start=(/1,1,1/), kount=(/pcols,pver,nmodes/) )
1098 235296 : call pbuf_get_field(pbuf, qaerwat_idx, qaerwat, start=(/1,1,1/), kount=(/pcols,pver,nmodes/) )
1099 58824 : call pbuf_get_field(pbuf, fracis_idx, fracis, start=(/1,1,1/), kount=(/pcols, pver, pcnst/) )
1100 :
1101 982224 : prec(:ncol)=0._r8
1102 5529456 : do k=1,pver
1103 91346832 : where (prec(:ncol) >= 1.e-7_r8)
1104 : isprx(:ncol,k) = .true.
1105 : elsewhere
1106 5470632 : isprx(:ncol,k) = .false.
1107 : endwhere
1108 0 : prec(:ncol) = prec(:ncol) + (dep_inputs%prain(:ncol,k) + dep_inputs%cmfdqr(:ncol,k) - dep_inputs%evapr(:ncol,k)) &
1109 91405656 : *state%pdel(:ncol,k)/gravit
1110 : end do
1111 :
1112 58824 : if(convproc_do_aer) then
1113 58824 : qsrflx_mzaer2cnvpr(:,:,:) = 0.0_r8
1114 58824 : aerdepwetis(:,:) = 0.0_r8
1115 58824 : aerdepwetcw(:,:) = 0.0_r8
1116 : else
1117 0 : qsrflx_mzaer2cnvpr(:,:,:) = nan
1118 0 : aerdepwetis(:,:) = nan
1119 0 : aerdepwetcw(:,:) = nan
1120 : endif
1121 :
1122 : ! calculate the mass-weighted sol_factic for coarse mode species
1123 : ! sol_factic_coarse(:,:) = 0.30_r8 ! tuned 1/4
1124 93059568 : f_act_conv_coarse(:,:) = 0.60_r8 ! rce 2010/05/02
1125 58824 : f_act_conv_coarse_dust = 0.40_r8 ! rce 2010/05/02
1126 58824 : f_act_conv_coarse_nacl = 0.80_r8 ! rce 2010/05/02
1127 58824 : if (modeptr_coarse > 0) then
1128 58824 : lcoardust = lptr_dust_a_amode(modeptr_coarse)
1129 58824 : lcoarnacl = lptr_nacl_a_amode(modeptr_coarse)
1130 58824 : if ((lcoardust > 0) .and. (lcoarnacl > 0)) then
1131 5529456 : do k = 1, pver
1132 91405656 : do i = 1, ncol
1133 85876200 : tmpdust = max( 0.0_r8, state%q(i,k,lcoardust) + ptend%q(i,k,lcoardust)*dt )
1134 85876200 : tmpnacl = max( 0.0_r8, state%q(i,k,lcoarnacl) + ptend%q(i,k,lcoarnacl)*dt )
1135 91346832 : if ((tmpdust+tmpnacl) > 1.0e-30_r8) then
1136 : ! sol_factic_coarse(i,k) = (0.2_r8*tmpdust + 0.4_r8*tmpnacl)/(tmpdust+tmpnacl) ! tuned 1/6
1137 79839942 : f_act_conv_coarse(i,k) = (f_act_conv_coarse_dust*tmpdust &
1138 79839942 : + f_act_conv_coarse_nacl*tmpnacl)/(tmpdust+tmpnacl) ! rce 2010/05/02
1139 : end if
1140 : end do
1141 : end do
1142 : end if
1143 : end if
1144 :
1145 93059568 : scavcoefnv(:,:,0) = 0.0_r8 ! below-cloud scavcoef = 0.0 for cloud-borne species
1146 :
1147 : ! Counters for "without" unified convective treatment (i.e. default case)
1148 58824 : strt_loop = 1
1149 58824 : end_loop = 2
1150 58824 : stride_loop = 1
1151 58824 : if (convproc_do_aer) then
1152 : !Do cloudborne first for unified convection scheme so that the resuspension of cloudborne
1153 : !can be saved then applied to interstitial
1154 58824 : strt_loop = 2
1155 58824 : end_loop = 1
1156 58824 : stride_loop = -1
1157 : endif
1158 :
1159 294120 : do m = 1, ntot_amode ! main loop over aerosol modes
1160 :
1161 764712 : do lphase = strt_loop,end_loop, stride_loop ! loop over interstitial (1) and cloud-borne (2) forms
1162 :
1163 : ! sol_factb and sol_facti values
1164 : ! sol_factb - currently this is basically a tuning factor
1165 : ! sol_facti & sol_factic - currently has a physical basis, and reflects activation fraction
1166 : !
1167 : ! 2008-mar-07 rce - sol_factb (interstitial) changed from 0.3 to 0.1
1168 : ! - sol_factic (interstitial, dust modes) changed from 1.0 to 0.5
1169 : ! - sol_factic (cloud-borne, pcarb modes) no need to set it to 0.0
1170 : ! because the cloud-borne pcarbon == 0 (no activation)
1171 : !
1172 : ! rce 2010/05/02
1173 : ! prior to this date, sol_factic was used for convective in-cloud wet removal,
1174 : ! and its value reflected a combination of an activation fraction (which varied between modes)
1175 : ! and a tuning factor
1176 : ! from this date forward, two parameters are used for convective in-cloud wet removal
1177 : ! f_act_conv is the activation fraction
1178 : ! note that "non-activation" of aerosol in air entrained into updrafts should
1179 : ! be included here
1180 : ! eventually we might use the activate routine (with w ~= 1 m/s) to calculate
1181 : ! this, but there is still the entrainment issue
1182 : ! sol_factic is strictly a tuning factor
1183 : !
1184 470592 : if (lphase == 1) then ! interstial aerosol
1185 235296 : hygro_sum_old(:,:) = 0.0_r8
1186 235296 : hygro_sum_del(:,:) = 0.0_r8
1187 : call modal_aero_bcscavcoef_get( m, ncol, isprx, dgnumwet, &
1188 235296 : scavcoefnv(:,:,1), scavcoefnv(:,:,2) )
1189 :
1190 235296 : sol_factb = sol_factb_interstitial ! all below-cloud scav ON (0.1 "tuning factor")
1191 :
1192 235296 : sol_facti = 0.0_r8 ! strat in-cloud scav totally OFF for institial
1193 :
1194 372238272 : sol_factic = sol_factic_interstitial
1195 :
1196 235296 : if (m == modeptr_pcarbon) then
1197 : ! sol_factic = 0.0_r8 ! conv in-cloud scav OFF (0.0 activation fraction)
1198 58824 : f_act_conv = 0.0_r8 ! rce 2010/05/02
1199 176472 : else if ((m == modeptr_finedust) .or. (m == modeptr_coardust)) then
1200 : ! sol_factic = 0.2_r8 ! conv in-cloud scav ON (0.5 activation fraction) ! tuned 1/4
1201 0 : f_act_conv = 0.4_r8 ! rce 2010/05/02
1202 : else
1203 : ! sol_factic = 0.4_r8 ! conv in-cloud scav ON (1.0 activation fraction) ! tuned 1/4
1204 279178704 : f_act_conv = 0.8_r8 ! rce 2010/05/02
1205 : end if
1206 :
1207 : else ! cloud-borne aerosol (borne by stratiform cloud drops)
1208 :
1209 235296 : sol_factb = 0.0_r8 ! all below-cloud scav OFF (anything cloud-borne is located "in-cloud")
1210 235296 : sol_facti = sol_facti_cloud_borne ! strat in-cloud scav cloud-borne tuning factor
1211 235296 : sol_factic = 0.0_r8 ! conv in-cloud scav OFF (having this on would mean
1212 : ! that conv precip collects strat droplets)
1213 235296 : f_act_conv = 0.0_r8 ! conv in-cloud scav OFF (having this on would mean
1214 :
1215 : end if
1216 470592 : if (convproc_do_aer .and. lphase == 1) then
1217 : ! if modal aero convproc is turned on for aerosols, then
1218 : ! turn off the convective in-cloud removal for interstitial aerosols
1219 : ! (but leave the below-cloud on, as convproc only does in-cloud)
1220 : ! and turn off the outfld SFWET, SFSIC, SFSID, SFSEC, and SFSED calls
1221 : ! for (stratiform)-cloudborne aerosols, convective wet removal
1222 : ! (all forms) is zero, so no action is needed
1223 235296 : sol_factic = 0.0_r8
1224 : endif
1225 :
1226 : !
1227 : ! rce 2010/05/03
1228 : ! wetdepa has "sol_fact" parameters:
1229 : ! sol_facti, sol_factic, sol_factb for liquid cloud
1230 :
1231 3411792 : do lspec = 0, nspec_amode(m)+1 ! loop over number + chem constituents + water
1232 :
1233 2705904 : if (lspec == 0) then ! number
1234 470592 : if (lphase == 1) then
1235 235296 : mm = numptr_amode(m)
1236 235296 : jnv = 1
1237 : else
1238 235296 : mm = numptrcw_amode(m)
1239 235296 : jnv = 0
1240 : endif
1241 2235312 : else if (lspec <= nspec_amode(m)) then ! non-water mass
1242 1764720 : if (lphase == 1) then
1243 882360 : mm = lmassptr_amode(lspec,m)
1244 882360 : jnv = 2
1245 : else
1246 882360 : mm = lmassptrcw_amode(lspec,m)
1247 882360 : jnv = 0
1248 : endif
1249 : else ! water mass
1250 : ! bypass wet removal of aerosol water
1251 : if(convproc_do_aer) then
1252 : if ( .not. do_aero_water_removal ) cycle
1253 : else
1254 : cycle
1255 : endif
1256 : if (lphase == 1) then
1257 : mm = 0
1258 : ! mm = lwaterptr_amode(m)
1259 : jnv = 2
1260 : else
1261 : mm = 0
1262 : jnv = 0
1263 : endif
1264 : endif
1265 :
1266 2235312 : if (mm <= 0) cycle
1267 :
1268 :
1269 : ! set f_act_conv for interstitial (lphase=1) coarse mode species
1270 : ! for the convective in-cloud, we conceptually treat the coarse dust and seasalt
1271 : ! as being externally mixed, and apply f_act_conv = f_act_conv_coarse_dust/nacl to dust/seasalt
1272 : ! number and sulfate are conceptually partitioned to the dust and seasalt
1273 : ! on a mass basis, so the f_act_conv for number and sulfate are
1274 : ! mass-weighted averages of the values used for dust/seasalt
1275 2235312 : if ((lphase == 1) .and. (m == modeptr_coarse)) then
1276 : ! sol_factic = sol_factic_coarse
1277 235296 : f_act_conv = f_act_conv_coarse ! rce 2010/05/02
1278 235296 : if (lspec > 0) then
1279 176472 : if (lmassptr_amode(lspec,m) == lptr_dust_a_amode(m)) then
1280 : ! sol_factic = 0.2_r8 ! tuned 1/4
1281 93059568 : f_act_conv = f_act_conv_coarse_dust ! rce 2010/05/02
1282 117648 : else if (lmassptr_amode(lspec,m) == lptr_nacl_a_amode(m)) then
1283 : ! sol_factic = 0.4_r8 ! tuned 1/6
1284 93059568 : f_act_conv = f_act_conv_coarse_nacl ! rce 2010/05/02
1285 : end if
1286 : end if
1287 : end if
1288 :
1289 2705904 : if ((lphase == 1) .and. (lspec <= nspec_amode(m))) then
1290 1117656 : ptend%lq(mm) = .TRUE.
1291 1117656 : dqdt_tmp(:,:) = 0.0_r8
1292 : ! q_tmp reflects changes from modal_aero_calcsize and is the "most current" q
1293 1736707464 : q_tmp(1:ncol,:) = state%q(1:ncol,:,mm) + ptend%q(1:ncol,:,mm)*dt
1294 1117656 : if(convproc_do_aer) then
1295 : !Feed in the saved cloudborne mixing ratios from phase 2
1296 1768131792 : qqcw_in(:,:) = qqcw_sav(:,:,lspec)
1297 : else
1298 0 : fldcw => qqcw_get_field(pbuf, mm,lchnk)
1299 0 : qqcw_in(:,:) = fldcw(:,:)
1300 : endif
1301 :
1302 : call wetdepa_v2( state%pmid, state%q(:,:,1), state%pdel, &
1303 : dep_inputs%cldt, dep_inputs%cldcu, dep_inputs%cmfdqr, &
1304 : dep_inputs%evapc, dep_inputs%conicw, dep_inputs%prain, dep_inputs%qme, &
1305 : dep_inputs%evapr, dep_inputs%totcond, q_tmp, dt, &
1306 : dqdt_tmp, iscavt, dep_inputs%cldvcu, dep_inputs%cldvst, &
1307 : dlf, fracis(:,:,mm), sol_factb, ncol, &
1308 : scavcoefnv(:,:,jnv), &
1309 : is_strat_cloudborne=.false., &
1310 : qqcw=qqcw_in(:,:), &
1311 : f_act_conv=f_act_conv, &
1312 : icscavt=icscavt, isscavt=isscavt, bcscavt=bcscavt, bsscavt=bsscavt, &
1313 : convproc_do_aer=convproc_do_aer, rcscavt=rcscavt, rsscavt=rsscavt, &
1314 : sol_facti_in=sol_facti, sol_factic_in=sol_factic, &
1315 1117656 : convproc_do_evaprain_atonce_in=convproc_do_evaprain_atonce )
1316 :
1317 1117656 : do_hygro_sum_del = .false.
1318 1117656 : if ( lspec > 0 ) do_hygro_sum_del = .true.
1319 :
1320 1117656 : if(convproc_do_aer) then
1321 1117656 : do_hygro_sum_del = .false.
1322 : ! add resuspension of cloudborne species to dqdt of interstitial species
1323 1736707464 : dqdt_tmp(1:ncol,:) = dqdt_tmp(1:ncol,:) + rtscavt(1:ncol,:,lspec)
1324 : if ( (lspec > 0) .and. do_aero_water_removal ) then
1325 : do_hygro_sum_del = .true.
1326 : endif
1327 : endif
1328 :
1329 1736707464 : ptend%q(1:ncol,:,mm) = ptend%q(1:ncol,:,mm) + dqdt_tmp(1:ncol,:)
1330 :
1331 1117656 : call outfld( trim(cnst_name(mm))//'WET', dqdt_tmp(:,:), pcols, lchnk)
1332 1117656 : call outfld( trim(cnst_name(mm))//'SIC', icscavt, pcols, lchnk)
1333 1117656 : call outfld( trim(cnst_name(mm))//'SIS', isscavt, pcols, lchnk)
1334 1117656 : call outfld( trim(cnst_name(mm))//'SBC', bcscavt, pcols, lchnk)
1335 1117656 : call outfld( trim(cnst_name(mm))//'SBS', bsscavt, pcols, lchnk)
1336 :
1337 1117656 : sflx(:)=0._r8
1338 105059664 : do k=1,pver
1339 1736707464 : do i=1,ncol
1340 1735589808 : sflx(i)=sflx(i)+dqdt_tmp(i,k)*state%pdel(i,k)/gravit
1341 : enddo
1342 : enddo
1343 1117656 : if (.not.convproc_do_aer) call outfld( trim(cnst_name(mm))//'SFWET', sflx, pcols, lchnk)
1344 18662256 : aerdepwetis(:ncol,mm) = sflx(:ncol)
1345 :
1346 1117656 : sflx(:)=0._r8
1347 105059664 : do k=1,pver
1348 1736707464 : do i=1,ncol
1349 1735589808 : sflx(i)=sflx(i)+icscavt(i,k)*state%pdel(i,k)/gravit
1350 : enddo
1351 : enddo
1352 1117656 : if (.not.convproc_do_aer) call outfld( trim(cnst_name(mm))//'SFSIC', sflx, pcols, lchnk)
1353 1117656 : if (convproc_do_aer) sflxic = sflx
1354 :
1355 1117656 : sflx(:)=0._r8
1356 105059664 : do k=1,pver
1357 1736707464 : do i=1,ncol
1358 1735589808 : sflx(i)=sflx(i)+isscavt(i,k)*state%pdel(i,k)/gravit
1359 : enddo
1360 : enddo
1361 1117656 : call outfld( trim(cnst_name(mm))//'SFSIS', sflx, pcols, lchnk)
1362 :
1363 1117656 : sflx(:)=0._r8
1364 105059664 : do k=1,pver
1365 1736707464 : do i=1,ncol
1366 1735589808 : sflx(i)=sflx(i)+bcscavt(i,k)*state%pdel(i,k)/gravit
1367 : enddo
1368 : enddo
1369 1117656 : call outfld( trim(cnst_name(mm))//'SFSBC', sflx, pcols, lchnk)
1370 1117656 : if (convproc_do_aer)sflxbc = sflx
1371 :
1372 1117656 : sflx(:)=0._r8
1373 105059664 : do k=1,pver
1374 1736707464 : do i=1,ncol
1375 1735589808 : sflx(i)=sflx(i)+bsscavt(i,k)*state%pdel(i,k)/gravit
1376 : enddo
1377 : enddo
1378 1117656 : call outfld( trim(cnst_name(mm))//'SFSBS', sflx, pcols, lchnk)
1379 :
1380 1117656 : if (convproc_do_aer) then
1381 :
1382 1117656 : sflx(:)=0._r8
1383 105059664 : do k=1,pver
1384 1736707464 : do i=1,ncol
1385 1735589808 : sflx(i)=sflx(i)+rcscavt(i,k)*state%pdel(i,k)/gravit
1386 : enddo
1387 : enddo
1388 1117656 : sflxec = sflx
1389 :
1390 1117656 : sflx(:)=0._r8
1391 105059664 : do k=1,pver
1392 1736707464 : do i=1,ncol
1393 1735589808 : sflx(i)=sflx(i)+rsscavt(i,k)*state%pdel(i,k)/gravit
1394 : enddo
1395 : enddo
1396 1117656 : call outfld( trim(cnst_name(mm))//'SFSES', sflx, pcols, lchnk)
1397 :
1398 : ! apportion convective surface fluxes to deep and shallow conv
1399 : ! this could be done more accurately in subr wetdepa
1400 : ! since deep and shallow rarely occur simultaneously, and these
1401 : ! fields are just diagnostics, this approximate method is adequate
1402 : ! only do this for interstitial aerosol, because conv clouds to not
1403 : ! affect the stratiform-cloudborne aerosol
1404 1117656 : if ( deepconv_wetdep_history) then
1405 :
1406 1117656 : call pbuf_get_field(pbuf, rprddp_idx, rprddp )
1407 1117656 : call pbuf_get_field(pbuf, rprdsh_idx, rprdsh )
1408 1117656 : call pbuf_get_field(pbuf, nevapr_dpcu_idx, evapcdp )
1409 1117656 : call pbuf_get_field(pbuf, nevapr_shcu_idx, evapcsh )
1410 :
1411 1117656 : rprddpsum(:) = 0.0_r8
1412 1117656 : rprdshsum(:) = 0.0_r8
1413 1117656 : evapcdpsum(:) = 0.0_r8
1414 1117656 : evapcshsum(:) = 0.0_r8
1415 :
1416 105059664 : do k = 1, pver
1417 1735589808 : rprddpsum(:ncol) = rprddpsum(:ncol) + rprddp(:ncol,k)*state%pdel(:ncol,k)/gravit
1418 1735589808 : rprdshsum(:ncol) = rprdshsum(:ncol) + rprdsh(:ncol,k)*state%pdel(:ncol,k)/gravit
1419 1735589808 : evapcdpsum(:ncol) = evapcdpsum(:ncol) + evapcdp(:ncol,k)*state%pdel(:ncol,k)/gravit
1420 1736707464 : evapcshsum(:ncol) = evapcshsum(:ncol) + evapcsh(:ncol,k)*state%pdel(:ncol,k)/gravit
1421 : end do
1422 :
1423 18662256 : do i = 1, ncol
1424 17544600 : rprddpsum(i) = max( rprddpsum(i), 1.0e-35_r8 )
1425 17544600 : rprdshsum(i) = max( rprdshsum(i), 1.0e-35_r8 )
1426 17544600 : evapcdpsum(i) = max( evapcdpsum(i), 0.1e-35_r8 )
1427 17544600 : evapcshsum(i) = max( evapcshsum(i), 0.1e-35_r8 )
1428 :
1429 : ! assume that in- and below-cloud removal are proportional to column precip production
1430 17544600 : tmpa = rprddpsum(i) / (rprddpsum(i) + rprdshsum(i))
1431 17544600 : tmpa = max( 0.0_r8, min( 1.0_r8, tmpa ) )
1432 17544600 : sflxicdp(i) = sflxic(i)*tmpa
1433 17544600 : sflxbcdp(i) = sflxbc(i)*tmpa
1434 :
1435 : ! assume that resuspension is proportional to (wet removal)*[(precip evap)/(precip production)]
1436 17544600 : tmp_resudp = tmpa * min( (evapcdpsum(i)/rprddpsum(i)), 1.0_r8 )
1437 17544600 : tmp_resush = (1.0_r8 - tmpa) * min( (evapcshsum(i)/rprdshsum(i)), 1.0_r8 )
1438 17544600 : tmpb = max( tmp_resudp, 1.0e-35_r8 ) / max( (tmp_resudp+tmp_resush), 1.0e-35_r8 )
1439 17544600 : tmpb = max( 0.0_r8, min( 1.0_r8, tmpb ) )
1440 18662256 : sflxecdp(i) = sflxec(i)*tmpb
1441 : end do
1442 1117656 : call outfld( trim(cnst_name(mm))//'SFSBD', sflxbcdp, pcols, lchnk)
1443 : else
1444 0 : sflxec(1:ncol) = 0.0_r8
1445 0 : sflxecdp(1:ncol) = 0.0_r8
1446 : end if
1447 :
1448 : ! when ma_convproc_intr is used, convective in-cloud wet removal is done there
1449 : ! the convective (total and deep) precip-evap-resuspension includes in- and below-cloud
1450 : ! contributions
1451 : ! so pass the below-cloud contribution to ma_convproc_intr
1452 18662256 : qsrflx_mzaer2cnvpr(1:ncol,mm,1) = sflxec( 1:ncol)
1453 18662256 : qsrflx_mzaer2cnvpr(1:ncol,mm,2) = sflxecdp(1:ncol)
1454 :
1455 : endif
1456 :
1457 1117656 : if (do_hygro_sum_del) then
1458 0 : tmpa = spechygro(lspec,m)/ &
1459 0 : specdens_amode(lspec,m)
1460 0 : tmpb = tmpa*dt
1461 0 : hygro_sum_old(1:ncol,:) = hygro_sum_old(1:ncol,:) &
1462 0 : + tmpa*q_tmp(1:ncol,:)
1463 : hygro_sum_del(1:ncol,:) = hygro_sum_del(1:ncol,:) &
1464 0 : + tmpb*dqdt_tmp(1:ncol,:)
1465 : end if
1466 :
1467 1117656 : else if ((lphase == 1) .and. (lspec == nspec_amode(m)+1)) then
1468 0 : do_lphase1 = .true.
1469 0 : if(convproc_do_aer) then
1470 : do_lphase1 = .false.
1471 : if(do_aero_water_removal)do_lphase1 = .true.
1472 : endif
1473 : if(do_lphase1) then
1474 : ! aerosol water -- because of how wetdepa treats evaporation of stratiform
1475 : ! precip, it is not appropriate to apply wetdepa to aerosol water
1476 : ! instead, "hygro_sum" = [sum of (mass*hygro/dens)] is calculated before and
1477 : ! after wet removal, and new water is calculated using
1478 : ! new_water = old_water*min(10,(hygro_sum_new/hygro_sum_old))
1479 : ! the "min(10,...)" is to avoid potential problems when hygro_sum_old ~= 0
1480 : ! also, individual wet removal terms (ic,is,bc,bs) are not output to history
1481 : ! ptend%lq(mm) = .TRUE.
1482 : ! dqdt_tmp(:,:) = 0.0_r8
1483 0 : do k = 1, pver
1484 0 : do i = 1, ncol
1485 : ! water_old = max( 0.0_r8, state%q(i,k,mm)+ptend%q(i,k,mm)*dt )
1486 0 : water_old = max( 0.0_r8, qaerwat(i,k,mm) )
1487 0 : hygro_sum_old_ik = max( 0.0_r8, hygro_sum_old(i,k) )
1488 0 : hygro_sum_new_ik = max( 0.0_r8, hygro_sum_old_ik+hygro_sum_del(i,k) )
1489 0 : if (hygro_sum_new_ik >= 10.0_r8*hygro_sum_old_ik) then
1490 0 : water_new = 10.0_r8*water_old
1491 : else
1492 0 : water_new = water_old*(hygro_sum_new_ik/hygro_sum_old_ik)
1493 : end if
1494 : ! dqdt_tmp(i,k) = (water_new - water_old)/dt
1495 0 : qaerwat(i,k,mm) = water_new
1496 : end do
1497 : end do
1498 :
1499 : ! ptend%q(1:ncol,:,mm) = ptend%q(1:ncol,:,mm) + dqdt_tmp(1:ncol,:)
1500 :
1501 : ! call outfld( trim(cnst_name(mm))
1502 :
1503 : ! sflx(:)=0._r8
1504 : ! do k=1,pver
1505 : ! do i=1,ncol
1506 : ! sflx(i)=sflx(i)+dqdt_tmp(i,k)*state%pdel(i,k)/gravit
1507 : ! enddo
1508 : ! enddo
1509 : ! call outfld( trim(cnst_name(mm))
1510 : endif
1511 :
1512 1117656 : elseif (lphase == 2) then
1513 :
1514 1117656 : do_lphase2 = .true.
1515 1117656 : if (convproc_do_aer) then
1516 1117656 : do_lphase2 = .false.
1517 1117656 : if (lspec <= nspec_amode(m)) do_lphase2 = .true.
1518 : endif
1519 :
1520 : if (do_lphase2) then
1521 :
1522 1117656 : dqdt_tmp(:,:) = 0.0_r8
1523 :
1524 1117656 : if (convproc_do_aer) then
1525 1117656 : fldcw => qqcw_get_field(pbuf,mm,lchnk)
1526 1736707464 : qqcw_sav(1:ncol,:,lspec) = fldcw(1:ncol,:)
1527 : else
1528 0 : fldcw => qqcw_get_field(pbuf, mm,lchnk)
1529 : endif
1530 :
1531 : call wetdepa_v2(state%pmid, state%q(:,:,1), state%pdel, &
1532 : dep_inputs%cldt, dep_inputs%cldcu, dep_inputs%cmfdqr, &
1533 : dep_inputs%evapc, dep_inputs%conicw, dep_inputs%prain, dep_inputs%qme, &
1534 : dep_inputs%evapr, dep_inputs%totcond, fldcw, dt, &
1535 : dqdt_tmp, iscavt, dep_inputs%cldvcu, dep_inputs%cldvst, &
1536 : dlf, fracis_cw, sol_factb, ncol, &
1537 : scavcoefnv(:,:,jnv), &
1538 : is_strat_cloudborne=.true., &
1539 : icscavt=icscavt, isscavt=isscavt, bcscavt=bcscavt, bsscavt=bsscavt, &
1540 : convproc_do_aer=convproc_do_aer, rcscavt=rcscavt, rsscavt=rsscavt, &
1541 : sol_facti_in=sol_facti, sol_factic_in=sol_factic, &
1542 : convproc_do_evaprain_atonce_in=convproc_do_evaprain_atonce, &
1543 1117656 : bergso_in=dep_inputs%bergso )
1544 :
1545 1117656 : if(convproc_do_aer) then
1546 : ! save resuspension of cloudborne species
1547 1736707464 : rtscavt(1:ncol,:,lspec) = rcscavt(1:ncol,:) + rsscavt(1:ncol,:)
1548 : ! wetdepa_v2 adds the resuspension of cloudborne to the dqdt of cloudborne (as a source)
1549 : ! undo this, so the resuspension of cloudborne can be added to the dqdt of interstitial (above)
1550 1736707464 : dqdt_tmp(1:ncol,:) = dqdt_tmp(1:ncol,:) - rtscavt(1:ncol,:,lspec)
1551 : endif
1552 :
1553 :
1554 1736707464 : fldcw(1:ncol,:) = fldcw(1:ncol,:) + dqdt_tmp(1:ncol,:) * dt
1555 :
1556 1117656 : sflx(:)=0._r8
1557 105059664 : do k=1,pver
1558 1736707464 : do i=1,ncol
1559 1735589808 : sflx(i)=sflx(i)+dqdt_tmp(i,k)*state%pdel(i,k)/gravit
1560 : enddo
1561 : enddo
1562 1117656 : call outfld( trim(cnst_name_cw(mm))//'SFWET', sflx, pcols, lchnk)
1563 18662256 : aerdepwetcw(:ncol,mm) = sflx(:ncol)
1564 :
1565 1117656 : sflx(:)=0._r8
1566 105059664 : do k=1,pver
1567 1736707464 : do i=1,ncol
1568 1735589808 : sflx(i)=sflx(i)+icscavt(i,k)*state%pdel(i,k)/gravit
1569 : enddo
1570 : enddo
1571 1117656 : call outfld( trim(cnst_name_cw(mm))//'SFSIC', sflx, pcols, lchnk)
1572 1117656 : sflx(:)=0._r8
1573 105059664 : do k=1,pver
1574 1736707464 : do i=1,ncol
1575 1735589808 : sflx(i)=sflx(i)+isscavt(i,k)*state%pdel(i,k)/gravit
1576 : enddo
1577 : enddo
1578 1117656 : call outfld( trim(cnst_name_cw(mm))//'SFSIS', sflx, pcols, lchnk)
1579 1117656 : sflx(:)=0._r8
1580 105059664 : do k=1,pver
1581 1736707464 : do i=1,ncol
1582 1735589808 : sflx(i)=sflx(i)+bcscavt(i,k)*state%pdel(i,k)/gravit
1583 : enddo
1584 : enddo
1585 1117656 : call outfld( trim(cnst_name_cw(mm))//'SFSBC', sflx, pcols, lchnk)
1586 1117656 : sflx(:)=0._r8
1587 105059664 : do k=1,pver
1588 1736707464 : do i=1,ncol
1589 1735589808 : sflx(i)=sflx(i)+bsscavt(i,k)*state%pdel(i,k)/gravit
1590 : enddo
1591 : enddo
1592 1117656 : call outfld( trim(cnst_name_cw(mm))//'SFSBS', sflx, pcols, lchnk)
1593 :
1594 1117656 : if(convproc_do_aer) then
1595 1117656 : sflx(:)=0.0_r8
1596 105059664 : do k=1,pver
1597 1736707464 : sflx(1:ncol)=sflx(1:ncol)+rcscavt(1:ncol,k)*state%pdel(1:ncol,k)/gravit
1598 : enddo
1599 1117656 : call outfld( trim(cnst_name_cw(mm))//'SFSEC', sflx, pcols, lchnk)
1600 :
1601 1117656 : sflx(:)=0.0_r8
1602 105059664 : do k=1,pver
1603 1736707464 : sflx(1:ncol)=sflx(1:ncol)+rsscavt(1:ncol,k)*state%pdel(1:ncol,k)/gravit
1604 : enddo
1605 1117656 : call outfld( trim(cnst_name_cw(mm))//'SFSES', sflx, pcols, lchnk)
1606 : endif
1607 : endif
1608 : endif
1609 :
1610 : enddo ! lspec = 0, nspec_amode(m)+1
1611 : enddo ! lphase = 1, 2
1612 : enddo ! m = 1, ntot_amode
1613 :
1614 58824 : if (convproc_do_aer) then
1615 58824 : call t_startf('ma_convproc')
1616 : call ma_convproc_intr( state, ptend, pbuf, dt, &
1617 : nsrflx_mzaer2cnvpr, qsrflx_mzaer2cnvpr, aerdepwetis, &
1618 58824 : dcondt_resusp3d)
1619 :
1620 58824 : if (convproc_do_evaprain_atonce) then
1621 294120 : do m = 1, ntot_amode ! main loop over aerosol modes
1622 764712 : do lphase = strt_loop,end_loop, stride_loop
1623 : ! loop over interstitial (1) and cloud-borne (2) forms
1624 3411792 : do lspec = 0, nspec_amode(m)+1 ! loop over number + chem constituents + water
1625 2705904 : if (lspec == 0) then ! number
1626 470592 : if (lphase == 1) then
1627 235296 : mm = numptr_amode(m)
1628 : else
1629 235296 : mm = numptrcw_amode(m)
1630 : endif
1631 2235312 : else if (lspec <= nspec_amode(m)) then ! non-water mass
1632 1764720 : if (lphase == 1) then
1633 882360 : mm = lmassptr_amode(lspec,m)
1634 : else
1635 882360 : mm = lmassptrcw_amode(lspec,m)
1636 : endif
1637 : endif
1638 3176496 : if (lphase == 2) then
1639 1352952 : fldcw => qqcw_get_field(pbuf, mm,lchnk)
1640 2102330088 : fldcw(:ncol,:) = fldcw(:ncol,:) + dcondt_resusp3d(mm,:ncol,:)*dt
1641 : end if
1642 : end do ! loop over number + chem constituents + water
1643 : end do ! lphase
1644 : end do ! m aerosol modes
1645 : end if
1646 :
1647 58824 : call t_stopf('ma_convproc')
1648 : endif
1649 :
1650 : ! if the user has specified prescribed aerosol dep fluxes then
1651 : ! do not set cam_out dep fluxes according to the prognostic aerosols
1652 58824 : if (.not. aerodep_flx_prescribed()) then
1653 58824 : call set_srf_wetdep(aerdepwetis, aerdepwetcw, cam_out)
1654 : endif
1655 :
1656 117648 : endsubroutine aero_model_wetdep
1657 :
1658 : !-------------------------------------------------------------------------
1659 : ! provides wet tropospheric aerosol surface area info for modal aerosols
1660 : ! called from mo_usrrxt
1661 : !-------------------------------------------------------------------------
1662 0 : subroutine aero_model_surfarea( &
1663 0 : mmr, radmean, relhum, pmid, temp, strato_sad, sulfate, rho, ltrop, &
1664 0 : dlat, het1_ndx, pbuf, ncol, sfc, dm_aer, sad_trop, reff_trop )
1665 :
1666 : ! dummy args
1667 : real(r8), intent(in) :: pmid(:,:)
1668 : real(r8), intent(in) :: temp(:,:)
1669 : real(r8), intent(in) :: mmr(:,:,:)
1670 : real(r8), intent(in) :: radmean ! mean radii in cm
1671 : real(r8), intent(in) :: strato_sad(:,:)
1672 : integer, intent(in) :: ncol
1673 : integer, intent(in) :: ltrop(:)
1674 : real(r8), intent(in) :: dlat(:) ! degrees latitude
1675 : integer, intent(in) :: het1_ndx
1676 : real(r8), intent(in) :: relhum(:,:)
1677 : real(r8), intent(in) :: rho(:,:) ! total atm density (/cm^3)
1678 : real(r8), intent(in) :: sulfate(:,:)
1679 : type(physics_buffer_desc), pointer :: pbuf(:)
1680 :
1681 : real(r8), intent(inout) :: sfc(:,:,:)
1682 : real(r8), intent(inout) :: dm_aer(:,:,:)
1683 : real(r8), intent(inout) :: sad_trop(:,:)
1684 : real(r8), intent(out) :: reff_trop(:,:)
1685 :
1686 : ! local vars
1687 0 : real(r8), pointer, dimension(:,:,:) :: dgnumwet
1688 0 : integer :: beglev(ncol)
1689 0 : integer :: endlev(ncol)
1690 : integer :: i,k
1691 :
1692 0 : call pbuf_get_field(pbuf, dgnumwet_idx, dgnumwet )
1693 :
1694 0 : beglev(:ncol)=ltrop(:ncol)+1
1695 0 : endlev(:ncol)=pver
1696 0 : call surf_area_dens( ncol, mmr, pmid, temp, dgnumwet, beglev, endlev, sad_trop, reff_trop, sfc=sfc )
1697 :
1698 0 : do i = 1,ncol
1699 0 : do k = ltrop(i)+1,pver
1700 0 : dm_aer(i,k,:) = dgnumwet(i,k,:) * 1.e2_r8 ! convert m to cm
1701 : enddo
1702 : enddo
1703 :
1704 58824 : end subroutine aero_model_surfarea
1705 :
1706 : !-------------------------------------------------------------------------
1707 : ! provides WET stratospheric aerosol surface area info for modal aerosols
1708 : ! if modal_strat_sulfate = TRUE -- called from mo_gas_phase_chemdr
1709 : !-------------------------------------------------------------------------
1710 0 : subroutine aero_model_strat_surfarea( ncol, mmr, pmid, temp, ltrop, pbuf, strato_sad, reff_strat )
1711 :
1712 : ! dummy args
1713 : integer, intent(in) :: ncol
1714 : real(r8), intent(in) :: mmr(:,:,:)
1715 : real(r8), intent(in) :: pmid(:,:)
1716 : real(r8), intent(in) :: temp(:,:)
1717 : integer, intent(in) :: ltrop(:) ! tropopause level indices
1718 : type(physics_buffer_desc), pointer :: pbuf(:)
1719 : real(r8), intent(out) :: strato_sad(:,:)
1720 : real(r8), intent(out) :: reff_strat(:,:)
1721 :
1722 : ! local vars
1723 0 : real(r8), pointer, dimension(:,:,:) :: dgnumwet
1724 0 : integer :: beglev(ncol)
1725 0 : integer :: endlev(ncol)
1726 :
1727 0 : reff_strat = 0._r8
1728 0 : strato_sad = 0._r8
1729 :
1730 0 : if (.not.modal_strat_sulfate) return
1731 :
1732 0 : call pbuf_get_field(pbuf, dgnumwet_idx, dgnumwet )
1733 :
1734 0 : beglev(:ncol)=top_lev
1735 0 : endlev(:ncol)=ltrop(:ncol)
1736 0 : call surf_area_dens( ncol, mmr, pmid, temp, dgnumwet, beglev, endlev, strato_sad, reff_strat )
1737 :
1738 0 : end subroutine aero_model_strat_surfarea
1739 :
1740 : !=============================================================================
1741 : !=============================================================================
1742 58824 : subroutine aero_model_gasaerexch( loffset, ncol, lchnk, troplev, delt, reaction_rates, &
1743 58824 : tfld, pmid, pdel, mbar, relhum, &
1744 117648 : zm, qh2o, cwat, cldfr, cldnum, &
1745 117648 : airdens, invariants, del_h2so4_gasprod, &
1746 58824 : vmr0, vmr, pbuf )
1747 :
1748 : use time_manager, only : get_nstep
1749 : use modal_aero_coag, only : modal_aero_coag_sub
1750 : use modal_aero_gasaerexch, only : modal_aero_gasaerexch_sub
1751 : use modal_aero_newnuc, only : modal_aero_newnuc_sub
1752 : use modal_aero_data, only : cnst_name_cw, qqcw_get_field
1753 :
1754 : !-----------------------------------------------------------------------
1755 : ! ... dummy arguments
1756 : !-----------------------------------------------------------------------
1757 : integer, intent(in) :: loffset ! offset applied to modal aero "pointers"
1758 : integer, intent(in) :: ncol ! number columns in chunk
1759 : integer, intent(in) :: lchnk ! chunk index
1760 : integer, intent(in) :: troplev(pcols)
1761 : real(r8), intent(in) :: delt ! time step size (sec)
1762 : real(r8), intent(in) :: reaction_rates(:,:,:) ! reaction rates
1763 : real(r8), intent(in) :: tfld(:,:) ! temperature (K)
1764 : real(r8), intent(in) :: pmid(:,:) ! pressure at model levels (Pa)
1765 : real(r8), intent(in) :: pdel(:,:) ! pressure thickness of levels (Pa)
1766 : real(r8), intent(in) :: mbar(:,:) ! mean wet atmospheric mass ( amu )
1767 : real(r8), intent(in) :: relhum(:,:) ! relative humidity
1768 : real(r8), intent(in) :: airdens(:,:) ! total atms density (molec/cm**3)
1769 : real(r8), intent(in) :: invariants(:,:,:)
1770 : real(r8), intent(in) :: del_h2so4_gasprod(:,:)
1771 : real(r8), intent(in) :: zm(:,:)
1772 : real(r8), intent(in) :: qh2o(:,:)
1773 : real(r8), intent(in) :: cwat(:,:) ! cloud liquid water content (kg/kg)
1774 : real(r8), intent(in) :: cldfr(:,:)
1775 : real(r8), intent(in) :: cldnum(:,:) ! droplet number concentration (#/kg)
1776 : real(r8), intent(in) :: vmr0(:,:,:) ! initial mixing ratios (before gas-phase chem changes)
1777 : real(r8), intent(inout) :: vmr(:,:,:) ! mixing ratios ( vmr )
1778 :
1779 : type(physics_buffer_desc), pointer :: pbuf(:)
1780 :
1781 : ! local vars
1782 :
1783 : integer :: n, m
1784 : integer :: i,k,l
1785 : integer :: nstep
1786 :
1787 117648 : real(r8) :: del_h2so4_aeruptk(ncol,pver)
1788 :
1789 58824 : real(r8), pointer :: dgnum(:,:,:), dgnumwet(:,:,:), wetdens(:,:,:)
1790 58824 : real(r8), pointer :: pblh(:) ! pbl height (m)
1791 :
1792 117648 : real(r8), dimension(ncol) :: wrk
1793 : character(len=32) :: name
1794 117648 : real(r8) :: dvmrcwdt(ncol,pver,gas_pcnst)
1795 117648 : real(r8) :: dvmrdt(ncol,pver,gas_pcnst)
1796 117648 : real(r8) :: vmrcw(ncol,pver,gas_pcnst) ! cloud-borne aerosol (vmr)
1797 :
1798 117648 : real(r8) :: aqso4(ncol,ntot_amode) ! aqueous phase chemistry
1799 117648 : real(r8) :: aqh2so4(ncol,ntot_amode) ! aqueous phase chemistry
1800 117648 : real(r8) :: aqso4_h2o2(ncol) ! SO4 aqueous phase chemistry due to H2O2
1801 117648 : real(r8) :: aqso4_o3(ncol) ! SO4 aqueous phase chemistry due to O3
1802 117648 : real(r8) :: xphlwc(ncol,pver) ! pH value multiplied by lwc
1803 117648 : real(r8) :: nh3_beg(ncol,pver)
1804 58824 : real(r8), pointer :: fldcw(:,:)
1805 58824 : real(r8), pointer :: sulfeq(:,:,:)
1806 :
1807 : logical :: is_spcam_m2005
1808 : !
1809 : ! ... initialize nh3
1810 : !
1811 58824 : if ( nh3_ndx > 0 ) then
1812 0 : nh3_beg = vmr(1:ncol,:,nh3_ndx)
1813 : end if
1814 : !
1815 58824 : is_spcam_m2005 = cam_physpkg_is('spcam_m2005')
1816 :
1817 58824 : call pbuf_get_field(pbuf, dgnum_idx, dgnum)
1818 58824 : call pbuf_get_field(pbuf, dgnumwet_idx, dgnumwet )
1819 58824 : call pbuf_get_field(pbuf, wetdens_ap_idx, wetdens )
1820 58824 : call pbuf_get_field(pbuf, pblh_idx, pblh)
1821 :
1822 294120 : do n=1,ntot_amode
1823 235296 : call outfld(dgnum_name(n), dgnum(1:ncol,1:pver,n), ncol, lchnk )
1824 294120 : call outfld(dgnumwet_name(n), dgnumwet(1:ncol,1:pver,n), ncol, lchnk )
1825 : end do
1826 :
1827 : ! do gas-aerosol exchange (h2so4, msa, nh3 condensation)
1828 :
1829 58824 : nstep = get_nstep()
1830 :
1831 : ! calculate tendency due to gas phase chemistry and processes
1832 2833634160 : dvmrdt(:ncol,:,:) = (vmr(:ncol,:,:) - vmr0(:ncol,:,:)) / delt
1833 1882368 : do m = 1, gas_pcnst
1834 30448944 : wrk(:) = 0._r8
1835 171413136 : do k = 1,pver
1836 2833575336 : wrk(:ncol) = wrk(:ncol) + dvmrdt(:ncol,k,m)*adv_mass(m)/mbar(:ncol,k)*pdel(:ncol,k)/gravit
1837 : end do
1838 1823544 : name = 'GS_'//trim(solsym(m))
1839 1882368 : call outfld( name, wrk(:ncol), ncol, lchnk )
1840 : enddo
1841 :
1842 : !
1843 : ! Aerosol processes ...
1844 : !
1845 58824 : call qqcw2vmr( lchnk, vmrcw, mbar, ncol, loffset, pbuf )
1846 :
1847 58824 : if (.not. is_spcam_m2005) then ! regular CAM
1848 2833634160 : dvmrdt(:ncol,:,:) = vmr(:ncol,:,:)
1849 2833634160 : dvmrcwdt(:ncol,:,:) = vmrcw(:ncol,:,:)
1850 :
1851 : ! aqueous chemistry ...
1852 :
1853 58824 : if( has_sox ) then
1854 : call setsox( &
1855 : ncol, &
1856 : lchnk, &
1857 : loffset, &
1858 : delt, &
1859 : pmid, &
1860 : pdel, &
1861 : tfld, &
1862 : mbar, &
1863 : cwat, &
1864 : cldfr, &
1865 : cldnum, &
1866 : airdens, &
1867 : invariants, &
1868 : vmrcw, &
1869 : vmr, &
1870 : xphlwc, &
1871 : aqso4, &
1872 : aqh2so4, &
1873 : aqso4_h2o2, &
1874 : aqso4_o3 &
1875 58824 : )
1876 :
1877 294120 : do n = 1, ntot_amode
1878 235296 : l = lptr_so4_cw_amode(n)
1879 294120 : if (l > 0) then
1880 176472 : call outfld( trim(cnst_name_cw(l))//'AQSO4', aqso4(:ncol,n), ncol, lchnk)
1881 176472 : call outfld( trim(cnst_name_cw(l))//'AQH2SO4', aqh2so4(:ncol,n), ncol, lchnk)
1882 : end if
1883 : end do
1884 :
1885 58824 : call outfld( 'AQSO4_H2O2', aqso4_h2o2(:ncol), ncol, lchnk)
1886 58824 : call outfld( 'AQSO4_O3', aqso4_o3(:ncol), ncol, lchnk)
1887 58824 : call outfld( 'XPH_LWC', xphlwc(:ncol,:), ncol, lchnk )
1888 :
1889 : endif
1890 :
1891 : ! Tendency due to aqueous chemistry
1892 2833692984 : dvmrdt = (vmr - dvmrdt) / delt
1893 2833634160 : dvmrcwdt = (vmrcw - dvmrcwdt) / delt
1894 1882368 : do m = 1, gas_pcnst
1895 30448944 : wrk(:) = 0._r8
1896 171413136 : do k = 1,pver
1897 2833575336 : wrk(:ncol) = wrk(:ncol) + dvmrdt(:ncol,k,m) * adv_mass(m)/mbar(:ncol,k)*pdel(:ncol,k)/gravit
1898 : end do
1899 1823544 : name = 'AQ_'//trim(solsym(m))
1900 1882368 : call outfld( name, wrk(:ncol), ncol, lchnk )
1901 : enddo
1902 :
1903 : else if (is_spcam_m2005) then ! SPCAM ECPP
1904 : ! when ECPP is used, aqueous chemistry is done in ECPP,
1905 : ! and not updated here.
1906 : ! Minghuai Wang, 2010-02 (Minghuai.Wang@pnl.gov)
1907 : !
1908 0 : dvmrdt = 0.0_r8
1909 0 : dvmrcwdt = 0.0_r8
1910 : endif
1911 :
1912 : ! do gas-aerosol exchange (h2so4, msa, nh3 condensation)
1913 :
1914 58824 : if (ndx_h2so4 > 0) then
1915 91405656 : del_h2so4_aeruptk(1:ncol,:) = vmr(1:ncol,:,ndx_h2so4)
1916 : else
1917 0 : del_h2so4_aeruptk(:,:) = 0.0_r8
1918 : endif
1919 :
1920 58824 : call t_startf('modal_gas-aer_exchng')
1921 :
1922 58824 : if ( sulfeq_idx>0 ) then
1923 0 : call pbuf_get_field( pbuf, sulfeq_idx, sulfeq )
1924 : else
1925 58824 : nullify( sulfeq )
1926 : endif
1927 :
1928 : call modal_aero_gasaerexch_sub( &
1929 : lchnk, ncol, nstep, &
1930 : loffset, delt, &
1931 : tfld, pmid, pdel, &
1932 : qh2o, troplev, &
1933 : vmr, vmrcw, &
1934 : dvmrdt, dvmrcwdt, &
1935 : dgnum, dgnumwet, &
1936 58824 : sulfeq )
1937 :
1938 58824 : if (ndx_h2so4 > 0) then
1939 91405656 : del_h2so4_aeruptk(1:ncol,:) = vmr(1:ncol,:,ndx_h2so4) - del_h2so4_aeruptk(1:ncol,:)
1940 : endif
1941 :
1942 58824 : call t_stopf('modal_gas-aer_exchng')
1943 :
1944 58824 : call t_startf('modal_nucl')
1945 :
1946 : ! do aerosol nucleation (new particle formation)
1947 : call modal_aero_newnuc_sub( &
1948 : lchnk, ncol, nstep, &
1949 : loffset, delt, &
1950 : tfld, pmid, pdel, &
1951 : zm, pblh, &
1952 : qh2o, cldfr, &
1953 : vmr, &
1954 21474864 : del_h2so4_gasprod, del_h2so4_aeruptk )
1955 :
1956 58824 : call t_stopf('modal_nucl')
1957 :
1958 58824 : call t_startf('modal_coag')
1959 :
1960 : ! do aerosol coagulation
1961 : call modal_aero_coag_sub( &
1962 : lchnk, ncol, nstep, &
1963 : loffset, delt, &
1964 : tfld, pmid, pdel, &
1965 : vmr, &
1966 : dgnum, dgnumwet, &
1967 58824 : wetdens )
1968 :
1969 58824 : call t_stopf('modal_coag')
1970 :
1971 58824 : call vmr2qqcw( lchnk, vmrcw, mbar, ncol, loffset, pbuf )
1972 :
1973 : ! diagnostics for cloud-borne aerosols...
1974 2470608 : do n = 1,pcnst
1975 2411784 : fldcw => qqcw_get_field(pbuf,n,lchnk,errorhandle=.true.)
1976 2470608 : if(associated(fldcw)) then
1977 1117656 : call outfld( cnst_name_cw(n), fldcw(:,:), pcols, lchnk )
1978 : endif
1979 : end do
1980 : !
1981 : ! ... put missing NH3 into NH4
1982 : !
1983 58824 : if ( nh3_ndx > 0 .and. nh4_ndx > 0 ) then
1984 0 : vmr(1:ncol,:,nh4_ndx) = vmr(1:ncol,:,nh4_ndx) + (nh3_beg-vmr(1:ncol,:,nh3_ndx))
1985 0 : vmr(1:ncol,:,nh4_ndx) = max(0._r8,vmr(1:ncol,:,nh4_ndx))
1986 : end if
1987 :
1988 117648 : end subroutine aero_model_gasaerexch
1989 :
1990 : !=============================================================================
1991 : !=============================================================================
1992 58824 : subroutine aero_model_emissions( state, cam_in )
1993 58824 : use seasalt_model, only: seasalt_emis, seasalt_names, seasalt_indices, seasalt_active,seasalt_nbin
1994 : use dust_model, only: dust_emis, dust_names, dust_indices, dust_active,dust_nbin, dust_nnum
1995 : use physics_types, only: physics_state
1996 :
1997 : ! Arguments:
1998 :
1999 : type(physics_state), intent(in) :: state ! Physics state variables
2000 : type(cam_in_t), intent(inout) :: cam_in ! import state
2001 :
2002 : ! local vars
2003 :
2004 : integer :: lchnk, ncol
2005 : integer :: m, mm
2006 : real(r8) :: soil_erod_tmp(pcols)
2007 : real(r8) :: sflx(pcols) ! accumulate over all bins for output
2008 : real(r8) :: u10cubed(pcols)
2009 : real (r8), parameter :: z0=0.0001_r8 ! m roughness length over oceans--from ocean model
2010 :
2011 58824 : lchnk = state%lchnk
2012 58824 : ncol = state%ncol
2013 :
2014 58824 : if (dust_active) then
2015 :
2016 58824 : call dust_emis( ncol, lchnk, cam_in%dstflx, cam_in%cflx, soil_erod_tmp )
2017 :
2018 : ! some dust emis diagnostics ...
2019 58824 : sflx(:)=0._r8
2020 411768 : do m=1,dust_nbin+dust_nnum
2021 352944 : mm = dust_indices(m)
2022 3123144 : if (m<=dust_nbin) sflx(:ncol)=sflx(:ncol)+cam_in%cflx(:ncol,mm)
2023 411768 : call outfld(trim(dust_names(m))//'SF',cam_in%cflx(:,mm),pcols, lchnk)
2024 : enddo
2025 58824 : call outfld('DSTSFMBL',sflx(:),pcols,lchnk)
2026 58824 : call outfld('LND_MBL',soil_erod_tmp(:),pcols, lchnk )
2027 : endif
2028 :
2029 58824 : if (seasalt_active) then
2030 982224 : u10cubed(:ncol)=sqrt(state%u(:ncol,pver)**2+state%v(:ncol,pver)**2)
2031 : ! move the winds to 10m high from the midpoint of the gridbox:
2032 : ! follows Tie and Seinfeld and Pandis, p.859 with math.
2033 :
2034 982224 : u10cubed(:ncol)=u10cubed(:ncol)*log(10._r8/z0)/log(state%zm(:ncol,pver)/z0)
2035 :
2036 : ! we need them to the 3.41 power, according to Gong et al., 1997:
2037 982224 : u10cubed(:ncol)=u10cubed(:ncol)**3.41_r8
2038 :
2039 58824 : sflx(:)=0._r8
2040 :
2041 58824 : call seasalt_emis( u10cubed, cam_in%sst, cam_in%ocnfrac, ncol, cam_in%cflx )
2042 :
2043 235296 : do m=1,seasalt_nbin
2044 176472 : mm = seasalt_indices(m)
2045 2946672 : sflx(:ncol)=sflx(:ncol)+cam_in%cflx(:ncol,mm)
2046 235296 : call outfld(trim(seasalt_names(m))//'SF',cam_in%cflx(:,mm),pcols,lchnk)
2047 : enddo
2048 58824 : call outfld('SSTSFMBL',sflx(:),pcols,lchnk)
2049 : endif
2050 :
2051 58824 : end subroutine aero_model_emissions
2052 :
2053 : !===============================================================================
2054 : ! private methods
2055 :
2056 :
2057 : !=============================================================================
2058 : !=============================================================================
2059 0 : subroutine surf_area_dens( ncol, mmr, pmid, temp, diam, beglev, endlev, sad, reff, sfc )
2060 58824 : use mo_constants, only : pi
2061 : use modal_aero_data, only : nspec_amode, alnsg_amode
2062 :
2063 : ! dummy args
2064 : integer, intent(in) :: ncol
2065 : real(r8), intent(in) :: mmr(:,:,:)
2066 : real(r8), intent(in) :: pmid(:,:)
2067 : real(r8), intent(in) :: temp(:,:)
2068 : real(r8), intent(in) :: diam(:,:,:)
2069 : integer, intent(in) :: beglev(:)
2070 : integer, intent(in) :: endlev(:)
2071 : real(r8), intent(out) :: sad(:,:)
2072 : real(r8), intent(out) :: reff(:,:)
2073 : real(r8),optional, intent(out) :: sfc(:,:,:)
2074 :
2075 : ! local vars
2076 0 : real(r8) :: sad_mode(pcols,pver,ntot_amode),radeff(pcols,pver)
2077 0 : real(r8) :: vol(pcols,pver),vol_mode(pcols,pver,ntot_amode)
2078 : real(r8) :: rho_air
2079 : integer :: i,k,l,m
2080 : real(r8) :: chm_mass, tot_mass
2081 :
2082 : !
2083 : ! Compute surface aero for each mode.
2084 : ! Total over all modes as the surface area for chemical reactions.
2085 : !
2086 :
2087 0 : sad = 0._r8
2088 0 : sad_mode = 0._r8
2089 0 : vol = 0._r8
2090 0 : vol_mode = 0._r8
2091 0 : reff = 0._r8
2092 :
2093 0 : do i = 1,ncol
2094 0 : do k = beglev(i),endlev(i)
2095 0 : rho_air = pmid(i,k)/(temp(i,k)*287.04_r8)
2096 0 : do l=1,ntot_amode
2097 : !
2098 : ! compute a mass weighting of the number
2099 : !
2100 0 : tot_mass = 0._r8
2101 0 : chm_mass = 0._r8
2102 0 : do m=1,nspec_amode(l)
2103 0 : if ( index_tot_mass(l,m) > 0 ) &
2104 0 : tot_mass = tot_mass + mmr(i,k,index_tot_mass(l,m))
2105 0 : if ( index_chm_mass(l,m) > 0 ) &
2106 0 : chm_mass = chm_mass + mmr(i,k,index_chm_mass(l,m))
2107 : end do
2108 0 : if ( tot_mass > 0._r8 ) then
2109 : ! surface area density
2110 0 : sad_mode(i,k,l) = chm_mass/tot_mass &
2111 0 : * mmr(i,k,num_idx(l))*rho_air*pi*diam(i,k,l)**2._r8 &
2112 0 : * exp(2._r8*alnsg_amode(l)**2._r8) ! m^2/m^3
2113 0 : sad_mode(i,k,l) = 1.e-2_r8 * sad_mode(i,k,l) ! cm^2/cm^3
2114 :
2115 : ! volume calculation, for use in effective radius calculation
2116 : vol_mode(i,k,l) = chm_mass/tot_mass &
2117 0 : * mmr(i,k,num_idx(l))*rho_air*pi/6._r8*diam(i,k,l)**3._r8 &
2118 0 : * exp(4.5_r8*alnsg_amode(l)**2._r8) ! m^3/m^3 = cm^3/cm^3
2119 : else
2120 0 : sad_mode(i,k,l) = 0._r8
2121 0 : vol_mode(i,k,l) = 0._r8
2122 : end if
2123 : end do
2124 0 : sad(i,k) = sum(sad_mode(i,k,:))
2125 0 : vol(i,k) = sum(vol_mode(i,k,:))
2126 0 : reff(i,k) = 3._r8*vol(i,k)/sad(i,k)
2127 :
2128 : enddo
2129 : enddo
2130 :
2131 0 : if (present(sfc)) then
2132 0 : sfc(:,:,:) = sad_mode(:,:,:)
2133 : endif
2134 :
2135 0 : end subroutine surf_area_dens
2136 :
2137 : !===============================================================================
2138 : !===============================================================================
2139 1536 : subroutine modal_aero_bcscavcoef_init
2140 : !-----------------------------------------------------------------------
2141 : !
2142 : ! Purpose:
2143 : ! Computes lookup table for aerosol impaction/interception scavenging rates
2144 : !
2145 : ! Authors: R. Easter
2146 : !
2147 : !-----------------------------------------------------------------------
2148 :
2149 0 : use shr_kind_mod, only: r8 => shr_kind_r8
2150 : use modal_aero_data
2151 : use cam_abortutils, only: endrun
2152 :
2153 : implicit none
2154 :
2155 :
2156 : ! local variables
2157 : integer nnfit_maxd
2158 : parameter (nnfit_maxd=27)
2159 :
2160 : integer i, jgrow, jdens, jpress, jtemp, mode, nnfit
2161 : integer lunerr
2162 :
2163 : real(r8) dg0, dg0_cgs, press, &
2164 : rhodryaero, rhowetaero, rhowetaero_cgs, rmserr, &
2165 : scavratenum, scavratevol, sigmag, &
2166 : temp, wetdiaratio, wetvolratio
2167 : real(r8) aafitnum(1), xxfitnum(1,nnfit_maxd), yyfitnum(nnfit_maxd)
2168 : real(r8) aafitvol(1), xxfitvol(1,nnfit_maxd), yyfitvol(nnfit_maxd)
2169 :
2170 4608 : allocate(scavimptblnum(nimptblgrow_mind:nimptblgrow_maxd, ntot_amode))
2171 3072 : allocate(scavimptblvol(nimptblgrow_mind:nimptblgrow_maxd, ntot_amode))
2172 :
2173 1536 : lunerr = 6
2174 1536 : dlndg_nimptblgrow = log( 1.25_r8 )
2175 :
2176 7680 : modeloop: do mode = 1, ntot_amode
2177 :
2178 6144 : sigmag = sigmag_amode(mode)
2179 :
2180 6144 : rhodryaero = specdens_amode(1,mode)
2181 :
2182 130560 : growloop: do jgrow = nimptblgrow_mind, nimptblgrow_maxd
2183 :
2184 122880 : wetdiaratio = exp( jgrow*dlndg_nimptblgrow )
2185 122880 : dg0 = dgnum_amode(mode)*wetdiaratio
2186 :
2187 : wetvolratio = exp( jgrow*dlndg_nimptblgrow*3._r8 )
2188 122880 : rhowetaero = 1.0_r8 + (rhodryaero-1.0_r8)/wetvolratio
2189 122880 : rhowetaero = min( rhowetaero, rhodryaero )
2190 :
2191 : !
2192 : ! compute impaction scavenging rates at 1 temp-press pair and save
2193 : !
2194 122880 : nnfit = 0
2195 :
2196 122880 : temp = 273.16_r8
2197 122880 : press = 0.75e6_r8 ! dynes/cm2
2198 122880 : rhowetaero = rhodryaero
2199 :
2200 122880 : dg0_cgs = dg0*1.0e2_r8 ! m to cm
2201 122880 : rhowetaero_cgs = rhowetaero*1.0e-3_r8 ! kg/m3 to g/cm3
2202 : call calc_1_impact_rate( &
2203 : dg0_cgs, sigmag, rhowetaero_cgs, temp, press, &
2204 122880 : scavratenum, scavratevol, lunerr )
2205 :
2206 122880 : nnfit = nnfit + 1
2207 : if (nnfit > nnfit_maxd) then
2208 : write(lunerr,9110)
2209 : call endrun()
2210 : end if
2211 : 9110 format( '*** subr. modal_aero_bcscavcoef_init -- nnfit too big' )
2212 :
2213 122880 : xxfitnum(1,nnfit) = 1._r8
2214 122880 : yyfitnum(nnfit) = log( scavratenum )
2215 :
2216 122880 : xxfitvol(1,nnfit) = 1._r8
2217 122880 : yyfitvol(nnfit) = log( scavratevol )
2218 :
2219 : 5900 continue
2220 :
2221 : !
2222 : ! skip mlinfit stuff because scav table no longer has dependencies on
2223 : ! air temp, air press, and particle wet density
2224 : ! just load the log( scavrate--- ) values
2225 : !
2226 : !!
2227 : !! do linear regression
2228 : !! log(scavrate) = a1 + a2*log(wetdens)
2229 : !!
2230 : ! call mlinft( xxfitnum, yyfitnum, aafitnum, nnfit, 1, 1, rmserr )
2231 : ! call mlinft( xxfitvol, yyfitvol, aafitvol, nnfit, 1, 1, rmserr )
2232 : !
2233 : ! scavimptblnum(jgrow,mode) = aafitnum(1)
2234 : ! scavimptblvol(jgrow,mode) = aafitvol(1)
2235 :
2236 122880 : scavimptblnum(jgrow,mode) = yyfitnum(1)
2237 129024 : scavimptblvol(jgrow,mode) = yyfitvol(1)
2238 :
2239 : enddo growloop
2240 : enddo modeloop
2241 1536 : return
2242 1536 : end subroutine modal_aero_bcscavcoef_init
2243 :
2244 : !===============================================================================
2245 : !===============================================================================
2246 588240 : subroutine modal_aero_depvel_part( ncol, t, pmid, ram1, fv, vlc_dry, vlc_trb, vlc_grv, &
2247 : radius_part, density_part, sig_part, moment, lchnk )
2248 :
2249 : ! calculates surface deposition velocity of particles
2250 : ! L. Zhang, S. Gong, J. Padro, and L. Barrie
2251 : ! A size-seggregated particle dry deposition scheme for an atmospheric aerosol module
2252 : ! Atmospheric Environment, 35, 549-560, 2001.
2253 : !
2254 : ! Authors: X. Liu
2255 :
2256 : !
2257 : ! !USES
2258 : !
2259 1536 : use physconst, only: pi,boltz, gravit, rair
2260 : use mo_drydep, only: n_land_type, fraction_landuse
2261 :
2262 : ! !ARGUMENTS:
2263 : !
2264 : implicit none
2265 : !
2266 : real(r8), intent(in) :: t(pcols,pver) !atm temperature (K)
2267 : real(r8), intent(in) :: pmid(pcols,pver) !atm pressure (Pa)
2268 : real(r8), intent(in) :: fv(pcols) !friction velocity (m/s)
2269 : real(r8), intent(in) :: ram1(pcols) !aerodynamical resistance (s/m)
2270 : real(r8), intent(in) :: radius_part(pcols,pver) ! mean (volume/number) particle radius (m)
2271 : real(r8), intent(in) :: density_part(pcols,pver) ! density of particle material (kg/m3)
2272 : real(r8), intent(in) :: sig_part(pcols,pver) ! geometric standard deviation of particles
2273 : integer, intent(in) :: moment ! moment of size distribution (0 for number, 2 for surface area, 3 for volume)
2274 : integer, intent(in) :: ncol
2275 : integer, intent(in) :: lchnk
2276 :
2277 : real(r8), intent(out) :: vlc_trb(pcols) !Turbulent deposn velocity (m/s)
2278 : real(r8), intent(out) :: vlc_grv(pcols,pver) !grav deposn velocity (m/s)
2279 : real(r8), intent(out) :: vlc_dry(pcols,pver) !dry deposn velocity (m/s)
2280 : !------------------------------------------------------------------------
2281 :
2282 : !------------------------------------------------------------------------
2283 : ! Local Variables
2284 : integer :: m,i,k,ix !indices
2285 : real(r8) :: rho !atm density (kg/m**3)
2286 : real(r8) :: vsc_dyn_atm(pcols,pver) ![kg m-1 s-1] Dynamic viscosity of air
2287 : real(r8) :: vsc_knm_atm(pcols,pver) ![m2 s-1] Kinematic viscosity of atmosphere
2288 : real(r8) :: shm_nbr ![frc] Schmidt number
2289 : real(r8) :: stk_nbr ![frc] Stokes number
2290 : real(r8) :: mfp_atm(pcols,pver) ![m] Mean free path of air
2291 : real(r8) :: dff_aer ![m2 s-1] Brownian diffusivity of particle
2292 : real(r8) :: slp_crc(pcols,pver) ![frc] Slip correction factor
2293 : real(r8) :: rss_trb ![s m-1] Resistance to turbulent deposition
2294 : real(r8) :: rss_lmn ![s m-1] Quasi-laminar layer resistance
2295 : real(r8) :: brownian ! collection efficiency for Browning diffusion
2296 : real(r8) :: impaction ! collection efficiency for impaction
2297 : real(r8) :: interception ! collection efficiency for interception
2298 : real(r8) :: stickfrac ! fraction of particles sticking to surface
2299 : real(r8) :: radius_moment(pcols,pver) ! median radius (m) for moment
2300 : real(r8) :: lnsig ! ln(sig_part)
2301 : real(r8) :: dispersion ! accounts for influence of size dist dispersion on bulk settling velocity
2302 : ! assuming radius_part is number mode radius * exp(1.5 ln(sigma))
2303 :
2304 : integer :: lt
2305 : real(r8) :: lnd_frc
2306 : real(r8) :: wrk1, wrk2, wrk3
2307 :
2308 : ! constants
2309 : real(r8) gamma(11) ! exponent of schmidt number
2310 : ! data gamma/0.54d+00, 0.56d+00, 0.57d+00, 0.54d+00, 0.54d+00, &
2311 : ! 0.56d+00, 0.54d+00, 0.54d+00, 0.54d+00, 0.56d+00, &
2312 : ! 0.50d+00/
2313 : data gamma/0.56e+00_r8, 0.54e+00_r8, 0.54e+00_r8, 0.56e+00_r8, 0.56e+00_r8, &
2314 : 0.56e+00_r8, 0.50e+00_r8, 0.54e+00_r8, 0.54e+00_r8, 0.54e+00_r8, &
2315 : 0.54e+00_r8/
2316 : save gamma
2317 :
2318 : real(r8) alpha(11) ! parameter for impaction
2319 : ! data alpha/50.00d+00, 0.95d+00, 0.80d+00, 1.20d+00, 1.30d+00, &
2320 : ! 0.80d+00, 50.00d+00, 50.00d+00, 2.00d+00, 1.50d+00, &
2321 : ! 100.00d+00/
2322 : data alpha/1.50e+00_r8, 1.20e+00_r8, 1.20e+00_r8, 0.80e+00_r8, 1.00e+00_r8, &
2323 : 0.80e+00_r8, 100.00e+00_r8, 50.00e+00_r8, 2.00e+00_r8, 1.20e+00_r8, &
2324 : 50.00e+00_r8/
2325 : save alpha
2326 :
2327 : real(r8) radius_collector(11) ! radius (m) of surface collectors
2328 : ! data radius_collector/-1.00d+00, 5.10d-03, 3.50d-03, 3.20d-03, 10.00d-03, &
2329 : ! 5.00d-03, -1.00d+00, -1.00d+00, 10.00d-03, 10.00d-03, &
2330 : ! -1.00d+00/
2331 : data radius_collector/10.00e-03_r8, 3.50e-03_r8, 3.50e-03_r8, 5.10e-03_r8, 2.00e-03_r8, &
2332 : 5.00e-03_r8, -1.00e+00_r8, -1.00e+00_r8, 10.00e-03_r8, 3.50e-03_r8, &
2333 : -1.00e+00_r8/
2334 : save radius_collector
2335 :
2336 : integer :: iwet(11) ! flag for wet surface = 1, otherwise = -1
2337 : ! data iwet/1, -1, -1, -1, -1, &
2338 : ! -1, -1, -1, 1, -1, &
2339 : ! 1/
2340 : data iwet/-1, -1, -1, -1, -1, &
2341 : -1, 1, -1, 1, -1, &
2342 : -1/
2343 : save iwet
2344 :
2345 :
2346 588240 : vlc_trb = 0._r8
2347 588240 : vlc_grv = 0._r8
2348 588240 : vlc_dry = 0._r8
2349 :
2350 : !------------------------------------------------------------------------
2351 55294560 : do k=top_lev,pver ! radius_part is not defined above top_lev
2352 914056560 : do i=1,ncol
2353 :
2354 858762000 : lnsig = log(sig_part(i,k))
2355 : ! use a maximum radius of 50 microns when calculating deposition velocity
2356 : radius_moment(i,k) = min(50.0e-6_r8,radius_part(i,k))* &
2357 858762000 : exp((float(moment)-1.5_r8)*lnsig*lnsig)
2358 858762000 : dispersion = exp(2._r8*lnsig*lnsig)
2359 :
2360 858762000 : rho=pmid(i,k)/rair/t(i,k)
2361 :
2362 : ! Quasi-laminar layer resistance: call rss_lmn_get
2363 : ! Size-independent thermokinetic properties
2364 : vsc_dyn_atm(i,k) = 1.72e-5_r8 * ((t(i,k)/273.0_r8)**1.5_r8) * 393.0_r8 / &
2365 858762000 : (t(i,k)+120.0_r8) ![kg m-1 s-1] RoY94 p. 102
2366 : mfp_atm(i,k) = 2.0_r8 * vsc_dyn_atm(i,k) / & ![m] SeP97 p. 455
2367 858762000 : (pmid(i,k)*sqrt(8.0_r8/(pi*rair*t(i,k))))
2368 858762000 : vsc_knm_atm(i,k) = vsc_dyn_atm(i,k) / rho ![m2 s-1] Kinematic viscosity of air
2369 :
2370 : slp_crc(i,k) = 1.0_r8 + mfp_atm(i,k) * &
2371 : (1.257_r8+0.4_r8*exp(-1.1_r8*radius_moment(i,k)/(mfp_atm(i,k)))) / &
2372 858762000 : radius_moment(i,k) ![frc] Slip correction factor SeP97 p. 464
2373 : vlc_grv(i,k) = (4.0_r8/18.0_r8) * radius_moment(i,k)*radius_moment(i,k)*density_part(i,k)* &
2374 858762000 : gravit*slp_crc(i,k) / vsc_dyn_atm(i,k) ![m s-1] Stokes' settling velocity SeP97 p. 466
2375 858762000 : vlc_grv(i,k) = vlc_grv(i,k) * dispersion
2376 :
2377 913468320 : vlc_dry(i,k)=vlc_grv(i,k)
2378 : enddo
2379 : enddo
2380 588240 : k=pver ! only look at bottom level for next part
2381 9822240 : do i=1,ncol
2382 9234000 : dff_aer = boltz * t(i,k) * slp_crc(i,k) / & ![m2 s-1]
2383 9234000 : (6.0_r8*pi*vsc_dyn_atm(i,k)*radius_moment(i,k)) !SeP97 p.474
2384 9234000 : shm_nbr = vsc_knm_atm(i,k) / dff_aer ![frc] SeP97 p.972
2385 :
2386 9234000 : wrk2 = 0._r8
2387 9234000 : wrk3 = 0._r8
2388 110808000 : do lt = 1,n_land_type
2389 101574000 : lnd_frc = fraction_landuse(i,lt,lchnk)
2390 110808000 : if ( lnd_frc /= 0._r8 ) then
2391 22542930 : brownian = shm_nbr**(-gamma(lt))
2392 22542930 : if (radius_collector(lt) > 0.0_r8) then
2393 : ! vegetated surface
2394 10266270 : stk_nbr = vlc_grv(i,k) * fv(i) / (gravit*radius_collector(lt))
2395 10266270 : interception = 2.0_r8*(radius_moment(i,k)/radius_collector(lt))**2.0_r8
2396 : else
2397 : ! non-vegetated surface
2398 12276660 : stk_nbr = vlc_grv(i,k) * fv(i) * fv(i) / (gravit*vsc_knm_atm(i,k)) ![frc] SeP97 p.965
2399 12276660 : interception = 0.0_r8
2400 : endif
2401 22542930 : impaction = (stk_nbr/(alpha(lt)+stk_nbr))**2.0_r8
2402 :
2403 22542930 : if (iwet(lt) > 0) then
2404 : stickfrac = 1.0_r8
2405 : else
2406 13968990 : stickfrac = exp(-sqrt(stk_nbr))
2407 13968990 : if (stickfrac < 1.0e-10_r8) stickfrac = 1.0e-10_r8
2408 : endif
2409 22542930 : rss_lmn = 1.0_r8 / (3.0_r8 * fv(i) * stickfrac * (brownian+interception+impaction))
2410 22542930 : rss_trb = ram1(i) + rss_lmn + ram1(i)*rss_lmn*vlc_grv(i,k)
2411 :
2412 22542930 : wrk1 = 1.0_r8 / rss_trb
2413 22542930 : wrk2 = wrk2 + lnd_frc*( wrk1 )
2414 22542930 : wrk3 = wrk3 + lnd_frc*( wrk1 + vlc_grv(i,k) )
2415 : endif
2416 : enddo ! n_land_type
2417 9234000 : vlc_trb(i) = wrk2
2418 9822240 : vlc_dry(i,k) = wrk3
2419 : enddo !ncol
2420 :
2421 588240 : return
2422 588240 : end subroutine modal_aero_depvel_part
2423 :
2424 : !===============================================================================
2425 470592 : subroutine modal_aero_bcscavcoef_get( m, ncol, isprx, dgn_awet, scavcoefnum, scavcoefvol )
2426 :
2427 588240 : use modal_aero_data
2428 : !-----------------------------------------------------------------------
2429 : implicit none
2430 :
2431 : integer,intent(in) :: m, ncol
2432 : logical,intent(in):: isprx(pcols,pver)
2433 : real(r8), intent(in) :: dgn_awet(pcols,pver,ntot_amode)
2434 : real(r8), intent(out) :: scavcoefnum(pcols,pver), scavcoefvol(pcols,pver)
2435 :
2436 : integer i, k, jgrow
2437 : real(r8) dumdgratio, xgrow, dumfhi, dumflo, scavimpvol, scavimpnum
2438 :
2439 :
2440 22117824 : do k = 1, pver
2441 365622624 : do i = 1, ncol
2442 :
2443 : ! do only if no precip
2444 365387328 : if ( isprx(i,k) ) then
2445 : !
2446 : ! interpolate table values using log of (actual-wet-size)/(base-dry-size)
2447 :
2448 56378516 : dumdgratio = dgn_awet(i,k,m)/dgnum_amode(m)
2449 :
2450 56378516 : if ((dumdgratio >= 0.99_r8) .and. (dumdgratio <= 1.01_r8)) then
2451 458255 : scavimpvol = scavimptblvol(0,m)
2452 458255 : scavimpnum = scavimptblnum(0,m)
2453 : else
2454 55920261 : xgrow = log( dumdgratio ) / dlndg_nimptblgrow
2455 55920261 : jgrow = int( xgrow )
2456 55920261 : if (xgrow < 0._r8) jgrow = jgrow - 1
2457 55920261 : if (jgrow < nimptblgrow_mind) then
2458 : jgrow = nimptblgrow_mind
2459 : xgrow = jgrow
2460 : else
2461 55920220 : jgrow = min( jgrow, nimptblgrow_maxd-1 )
2462 : end if
2463 :
2464 55920261 : dumfhi = xgrow - jgrow
2465 55920261 : dumflo = 1._r8 - dumfhi
2466 :
2467 0 : scavimpvol = dumflo*scavimptblvol(jgrow,m) + &
2468 55920261 : dumfhi*scavimptblvol(jgrow+1,m)
2469 0 : scavimpnum = dumflo*scavimptblnum(jgrow,m) + &
2470 55920261 : dumfhi*scavimptblnum(jgrow+1,m)
2471 :
2472 : end if
2473 :
2474 : ! impaction scavenging removal amount for volume
2475 56378516 : scavcoefvol(i,k) = exp( scavimpvol )
2476 : ! impaction scavenging removal amount to number
2477 56378516 : scavcoefnum(i,k) = exp( scavimpnum )
2478 :
2479 : ! scavcoef = impaction scav rate (1/h) for precip = 1 mm/h
2480 : ! scavcoef = impaction scav rate (1/s) for precip = pfx_inrain
2481 : ! (scavcoef/3600) = impaction scav rate (1/s) for precip = 1 mm/h
2482 : ! (pfx_inrain*3600) = in-rain-area precip rate (mm/h)
2483 : ! impactrate = (scavcoef/3600) * (pfx_inrain*3600)
2484 : else
2485 287126284 : scavcoefvol(i,k) = 0._r8
2486 287126284 : scavcoefnum(i,k) = 0._r8
2487 : end if
2488 :
2489 : end do
2490 : end do
2491 :
2492 235296 : return
2493 235296 : end subroutine modal_aero_bcscavcoef_get
2494 :
2495 : !===============================================================================
2496 122880 : subroutine calc_1_impact_rate( &
2497 : dg0, sigmag, rhoaero, temp, press, &
2498 : scavratenum, scavratevol, lunerr )
2499 : !
2500 : ! routine computes a single impaction scavenging rate
2501 : ! for precipitation rate of 1 mm/h
2502 : !
2503 : ! dg0 = geometric mean diameter of aerosol number size distrib. (cm)
2504 : ! sigmag = geometric standard deviation of size distrib.
2505 : ! rhoaero = density of aerosol particles (g/cm^3)
2506 : ! temp = temperature (K)
2507 : ! press = pressure (dyne/cm^2)
2508 : ! scavratenum = number scavenging rate (1/h)
2509 : ! scavratevol = volume or mass scavenging rate (1/h)
2510 : ! lunerr = logical unit for error message
2511 : !
2512 235296 : use shr_kind_mod, only: r8 => shr_kind_r8
2513 : use mo_constants, only: boltz_cgs, pi, rhowater => rhoh2o_cgs, &
2514 : gravity => gravity_cgs, rgas => rgas_cgs
2515 :
2516 : implicit none
2517 :
2518 : ! subr. parameters
2519 : integer lunerr
2520 : real(r8) dg0, sigmag, rhoaero, temp, press, scavratenum, scavratevol
2521 :
2522 : ! local variables
2523 : integer nrainsvmax
2524 : parameter (nrainsvmax=50)
2525 : real(r8) rrainsv(nrainsvmax), xnumrainsv(nrainsvmax),&
2526 : vfallrainsv(nrainsvmax)
2527 :
2528 : integer naerosvmax
2529 : parameter (naerosvmax=51)
2530 : real(r8) aaerosv(naerosvmax), &
2531 : ynumaerosv(naerosvmax), yvolaerosv(naerosvmax)
2532 :
2533 : integer i, ja, jr, na, nr
2534 : real(r8) a, aerodiffus, aeromass, ag0, airdynvisc, airkinvisc
2535 : real(r8) anumsum, avolsum, cair, chi
2536 : real(r8) d, dr, dum, dumfuchs, dx
2537 : real(r8) ebrown, eimpact, eintercept, etotal, freepath
2538 : real(r8) precip, precipmmhr, precipsum
2539 : real(r8) r, rainsweepout, reynolds, rhi, rhoair, rlo, rnumsum
2540 : real(r8) scavsumnum, scavsumnumbb
2541 : real(r8) scavsumvol, scavsumvolbb
2542 : real(r8) schmidt, sqrtreynolds, sstar, stokes, sx
2543 : real(r8) taurelax, vfall, vfallstp
2544 : real(r8) x, xg0, xg3, xhi, xlo, xmuwaterair
2545 :
2546 :
2547 122880 : rlo = .005_r8
2548 122880 : rhi = .250_r8
2549 122880 : dr = 0.005_r8
2550 122880 : nr = 1 + nint( (rhi-rlo)/dr )
2551 : if (nr > nrainsvmax) then
2552 : write(lunerr,9110)
2553 : call endrun()
2554 : end if
2555 :
2556 : 9110 format( '*** subr. calc_1_impact_rate -- nr > nrainsvmax' )
2557 :
2558 122880 : precipmmhr = 1.0_r8
2559 122880 : precip = precipmmhr/36000._r8
2560 :
2561 122880 : ag0 = dg0/2._r8
2562 122880 : sx = log( sigmag )
2563 122880 : xg0 = log( ag0 )
2564 122880 : xg3 = xg0 + 3._r8*sx*sx
2565 :
2566 122880 : xlo = xg3 - 4._r8*sx
2567 122880 : xhi = xg3 + 4._r8*sx
2568 122880 : dx = 0.2_r8*sx
2569 :
2570 122880 : dx = max( 0.2_r8*sx, 0.01_r8 )
2571 122880 : xlo = xg3 - max( 4._r8*sx, 2._r8*dx )
2572 122880 : xhi = xg3 + max( 4._r8*sx, 2._r8*dx )
2573 :
2574 122880 : na = 1 + nint( (xhi-xlo)/dx )
2575 122880 : if (na > naerosvmax) then
2576 0 : write(lunerr,9120)
2577 0 : call endrun()
2578 : end if
2579 :
2580 : 9120 format( '*** subr. calc_1_impact_rate -- na > naerosvmax' )
2581 :
2582 : ! air molar density
2583 122880 : cair = press/(rgas*temp)
2584 : ! air mass density
2585 122880 : rhoair = 28.966_r8*cair
2586 : ! molecular freepath
2587 122880 : freepath = 2.8052e-10_r8/cair
2588 : ! air dynamic viscosity
2589 : airdynvisc = 1.8325e-4_r8 * (416.16_r8/(temp+120._r8)) * &
2590 122880 : ((temp/296.16_r8)**1.5_r8)
2591 : ! air kinemaic viscosity
2592 122880 : airkinvisc = airdynvisc/rhoair
2593 : ! ratio of water viscosity to air viscosity (from Slinn)
2594 122880 : xmuwaterair = 60.0_r8
2595 :
2596 : !
2597 : ! compute rain drop number concentrations
2598 : ! rrainsv = raindrop radius (cm)
2599 : ! xnumrainsv = raindrop number concentration (#/cm^3)
2600 : ! (number in the bin, not number density)
2601 : ! vfallrainsv = fall velocity (cm/s)
2602 : !
2603 122880 : precipsum = 0._r8
2604 6266880 : do i = 1, nr
2605 6144000 : r = rlo + (i-1)*dr
2606 6144000 : rrainsv(i) = r
2607 6144000 : xnumrainsv(i) = exp( -r/2.7e-2_r8 )
2608 :
2609 6144000 : d = 2._r8*r
2610 6144000 : if (d <= 0.007_r8) then
2611 0 : vfallstp = 2.88e5_r8 * d**2._r8
2612 6144000 : else if (d <= 0.025_r8) then
2613 245760 : vfallstp = 2.8008e4_r8 * d**1.528_r8
2614 5898240 : else if (d <= 0.1_r8) then
2615 983040 : vfallstp = 4104.9_r8 * d**1.008_r8
2616 4915200 : else if (d <= 0.25_r8) then
2617 1843200 : vfallstp = 1812.1_r8 * d**0.638_r8
2618 : else
2619 3072000 : vfallstp = 1069.8_r8 * d**0.235_r8
2620 : end if
2621 :
2622 6144000 : vfall = vfallstp * sqrt(1.204e-3_r8/rhoair)
2623 6144000 : vfallrainsv(i) = vfall
2624 6266880 : precipsum = precipsum + vfall*(r**3)*xnumrainsv(i)
2625 : end do
2626 122880 : precipsum = precipsum*pi*1.333333_r8
2627 :
2628 122880 : rnumsum = 0._r8
2629 6266880 : do i = 1, nr
2630 6144000 : xnumrainsv(i) = xnumrainsv(i)*(precip/precipsum)
2631 6266880 : rnumsum = rnumsum + xnumrainsv(i)
2632 : end do
2633 :
2634 : !
2635 : ! compute aerosol concentrations
2636 : ! aaerosv = particle radius (cm)
2637 : ! fnumaerosv = fraction of total number in the bin (--)
2638 : ! fvolaerosv = fraction of total volume in the bin (--)
2639 : !
2640 : anumsum = 0._r8
2641 : avolsum = 0._r8
2642 5160960 : do i = 1, na
2643 5038080 : x = xlo + (i-1)*dx
2644 5038080 : a = exp( x )
2645 5038080 : aaerosv(i) = a
2646 5038080 : dum = (x - xg0)/sx
2647 5038080 : ynumaerosv(i) = exp( -0.5_r8*dum*dum )
2648 5038080 : yvolaerosv(i) = ynumaerosv(i)*1.3333_r8*pi*a*a*a
2649 5038080 : anumsum = anumsum + ynumaerosv(i)
2650 5160960 : avolsum = avolsum + yvolaerosv(i)
2651 : end do
2652 :
2653 5160960 : do i = 1, na
2654 5038080 : ynumaerosv(i) = ynumaerosv(i)/anumsum
2655 5160960 : yvolaerosv(i) = yvolaerosv(i)/avolsum
2656 : end do
2657 :
2658 :
2659 : !
2660 : ! compute scavenging
2661 : !
2662 : scavsumnum = 0._r8
2663 : scavsumvol = 0._r8
2664 : !
2665 : ! outer loop for rain drop radius
2666 : !
2667 6266880 : jr_loop: do jr = 1, nr
2668 :
2669 6144000 : r = rrainsv(jr)
2670 6144000 : vfall = vfallrainsv(jr)
2671 :
2672 6144000 : reynolds = r * vfall / airkinvisc
2673 6144000 : sqrtreynolds = sqrt( reynolds )
2674 :
2675 : !
2676 : ! inner loop for aerosol particle radius
2677 : !
2678 6144000 : scavsumnumbb = 0._r8
2679 6144000 : scavsumvolbb = 0._r8
2680 :
2681 258048000 : ja_loop: do ja = 1, na
2682 :
2683 251904000 : a = aaerosv(ja)
2684 :
2685 251904000 : chi = a/r
2686 :
2687 251904000 : dum = freepath/a
2688 251904000 : dumfuchs = 1._r8 + 1.246_r8*dum + 0.42_r8*dum*exp(-0.87_r8/dum)
2689 251904000 : taurelax = 2._r8*rhoaero*a*a*dumfuchs/(9._r8*rhoair*airkinvisc)
2690 :
2691 251904000 : aeromass = 4._r8*pi*a*a*a*rhoaero/3._r8
2692 251904000 : aerodiffus = boltz_cgs*temp*taurelax/aeromass
2693 :
2694 251904000 : schmidt = airkinvisc/aerodiffus
2695 251904000 : stokes = vfall*taurelax/r
2696 :
2697 : ebrown = 4._r8*(1._r8 + 0.4_r8*sqrtreynolds*(schmidt**0.3333333_r8)) / &
2698 251904000 : (reynolds*schmidt)
2699 :
2700 : dum = (1._r8 + 2._r8*xmuwaterair*chi) / &
2701 251904000 : (1._r8 + xmuwaterair/sqrtreynolds)
2702 251904000 : eintercept = 4._r8*chi*(chi + dum)
2703 :
2704 251904000 : dum = log( 1._r8 + reynolds )
2705 251904000 : sstar = (1.2_r8 + dum/12._r8) / (1._r8 + dum)
2706 251904000 : eimpact = 0._r8
2707 251904000 : if (stokes > sstar) then
2708 61905408 : dum = stokes - sstar
2709 61905408 : eimpact = (dum/(dum+0.6666667_r8)) ** 1.5_r8
2710 : end if
2711 :
2712 251904000 : etotal = ebrown + eintercept + eimpact
2713 251904000 : etotal = min( etotal, 1.0_r8 )
2714 :
2715 251904000 : rainsweepout = xnumrainsv(jr)*4._r8*pi*r*r*vfall
2716 :
2717 251904000 : scavsumnumbb = scavsumnumbb + rainsweepout*etotal*ynumaerosv(ja)
2718 258048000 : scavsumvolbb = scavsumvolbb + rainsweepout*etotal*yvolaerosv(ja)
2719 :
2720 : enddo ja_loop
2721 :
2722 6144000 : scavsumnum = scavsumnum + scavsumnumbb
2723 6266880 : scavsumvol = scavsumvol + scavsumvolbb
2724 :
2725 : enddo jr_loop
2726 :
2727 122880 : scavratenum = scavsumnum*3600._r8
2728 122880 : scavratevol = scavsumvol*3600._r8
2729 :
2730 122880 : return
2731 : end subroutine calc_1_impact_rate
2732 :
2733 : !=============================================================================
2734 : !=============================================================================
2735 117648 : subroutine qqcw2vmr(lchnk, vmr, mbar, ncol, im, pbuf)
2736 : use modal_aero_data, only : qqcw_get_field
2737 : use physics_buffer, only : physics_buffer_desc
2738 : !-----------------------------------------------------------------
2739 : ! ... Xfrom from mass to volume mixing ratio
2740 : !-----------------------------------------------------------------
2741 :
2742 : use chem_mods, only : adv_mass, gas_pcnst
2743 :
2744 : implicit none
2745 :
2746 : !-----------------------------------------------------------------
2747 : ! ... Dummy args
2748 : !-----------------------------------------------------------------
2749 : integer, intent(in) :: lchnk, ncol, im
2750 : real(r8), intent(in) :: mbar(ncol,pver)
2751 : real(r8), intent(inout) :: vmr(ncol,pver,gas_pcnst)
2752 : type(physics_buffer_desc), pointer :: pbuf(:)
2753 :
2754 : !-----------------------------------------------------------------
2755 : ! ... Local variables
2756 : !-----------------------------------------------------------------
2757 : integer :: k, m
2758 58824 : real(r8), pointer :: fldcw(:,:)
2759 :
2760 1882368 : do m=1,gas_pcnst
2761 1882368 : if( adv_mass(m) /= 0._r8 ) then
2762 1823544 : fldcw => qqcw_get_field(pbuf, m+im,lchnk,errorhandle=.true.)
2763 1823544 : if(associated(fldcw)) then
2764 105059664 : do k=1,pver
2765 1736707464 : vmr(:ncol,k,m) = mbar(:ncol,k) * fldcw(:ncol,k) / adv_mass(m)
2766 : end do
2767 : else
2768 1096867872 : vmr(:,:,m) = 0.0_r8
2769 : end if
2770 : end if
2771 : end do
2772 117648 : end subroutine qqcw2vmr
2773 :
2774 :
2775 : !=============================================================================
2776 : !=============================================================================
2777 117648 : subroutine vmr2qqcw( lchnk, vmr, mbar, ncol, im, pbuf )
2778 : !-----------------------------------------------------------------
2779 : ! ... Xfrom from volume to mass mixing ratio
2780 : !-----------------------------------------------------------------
2781 :
2782 58824 : use m_spc_id
2783 : use chem_mods, only : adv_mass, gas_pcnst
2784 : use modal_aero_data, only : qqcw_get_field
2785 : use physics_buffer, only : physics_buffer_desc
2786 :
2787 : implicit none
2788 :
2789 : !-----------------------------------------------------------------
2790 : ! ... Dummy args
2791 : !-----------------------------------------------------------------
2792 : integer, intent(in) :: lchnk, ncol, im
2793 : real(r8), intent(in) :: mbar(ncol,pver)
2794 : real(r8), intent(in) :: vmr(ncol,pver,gas_pcnst)
2795 : type(physics_buffer_desc), pointer :: pbuf(:)
2796 :
2797 : !-----------------------------------------------------------------
2798 : ! ... Local variables
2799 : !-----------------------------------------------------------------
2800 : integer :: k, m
2801 58824 : real(r8), pointer :: fldcw(:,:)
2802 : !-----------------------------------------------------------------
2803 : ! ... The non-group species
2804 : !-----------------------------------------------------------------
2805 1882368 : do m = 1,gas_pcnst
2806 1823544 : fldcw => qqcw_get_field(pbuf, m+im,lchnk,errorhandle=.true.)
2807 1882368 : if( adv_mass(m) /= 0._r8 .and. associated(fldcw)) then
2808 105059664 : do k = 1,pver
2809 1736707464 : fldcw(:ncol,k) = adv_mass(m) * vmr(:ncol,k,m) / mbar(:ncol,k)
2810 : end do
2811 : end if
2812 : end do
2813 :
2814 117648 : end subroutine vmr2qqcw
2815 :
2816 0 : function get_dlndg_nimptblgrow() result (dlndg_nimptblgrow_ret)
2817 : real(r8) :: dlndg_nimptblgrow_ret
2818 0 : dlndg_nimptblgrow_ret = dlndg_nimptblgrow
2819 58824 : end function get_dlndg_nimptblgrow
2820 :
2821 0 : function get_scavimptblvol() result (scavimptblvol_ret)
2822 : real(r8) :: scavimptblvol_ret(nimptblgrow_mind:nimptblgrow_maxd, ntot_amode)
2823 0 : scavimptblvol_ret = scavimptblvol
2824 0 : end function get_scavimptblvol
2825 :
2826 0 : function get_scavimptblnum() result (scavimptblnum_ret)
2827 : real(r8) :: scavimptblnum_ret(nimptblgrow_mind:nimptblgrow_maxd, ntot_amode)
2828 0 : scavimptblnum_ret = scavimptblnum
2829 0 : end function get_scavimptblnum
2830 :
2831 : end module aero_model
|