1 ! Updated to CESM1.0.3 (CAM5.1.01) by Balwinder.Singh@pnnl.gov
4 module mz_aerosols_intr
6 use shr_kind_mod,only: r8 => shr_kind_r8
8 use spmd_utils, only: masterproc
9 use pmgrid, only: plev, plevp
10 use ppgrid, only: pcols, pver
11 use constituents,only: pcnst, cnst_name, cnst_get_ind
12 use phys_control,only: phys_getopts
13 use abortutils, only: endrun
15 use module_cam_support, only: masterproc, pcnst =>pcnst_runtime, pcols, pver, endrun
16 use constituents,only: cnst_name, cnst_get_ind
19 use modal_aero_data, only: ntot_amode
22 use cam_logfile, only: iulog
24 use module_cam_support, only: iulog
29 private ! Make default type private to the module
37 public :: mz_aero_initialize
38 public :: mz_aero_wet_intr ! interface to wet deposition
40 public :: mz_aero_setopts
41 public :: mz_aero_defaultopts
43 public :: aer_wetdep_list
44 public :: do_cam_sulfchem
47 public :: mz_aero_dry_intr ! interface to dry deposition
48 public :: aer_drydep_list
50 public :: modal_aero_bcscavcoef_init ! initialize impaction scavenging table
51 public :: modal_aero_bcscavcoef_get ! get impaction scavenging coefficients
54 public :: mz_prescribed_dust ! return true if MOZART code provides prescribed dust
57 integer :: num_mz_aerosols
58 integer, allocatable :: mz_aerosol_ids(:) ! (/ id_cb2, id_oc2, id_so4, id_sa1, id_sa2, id_sa3, id_sa4 /)
60 character(len=16), dimension(pcnst) :: aer_wetdep_list = ' '
62 character(len=16), allocatable, dimension(:) :: aer_wetdep_list
64 logical :: use_cam_sulfchem = .false.
65 logical :: do_cam_sulfchem
66 logical :: inv_o3, inv_oh, inv_no3, inv_ho2
67 integer, pointer :: id_so2, id_so4, id_dms, id_o3, id_h2o2, id_oh, id_no3, id_ho2
68 integer, target :: spc_ids(8)
72 character(len=16), dimension(pcnst) :: aer_drydep_list = ''
74 character(len=16), allocatable,dimension(:) :: aer_drydep_lis
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) scavimptblnum(nimptblgrow_mind:nimptblgrow_maxd, ntot_amode)
80 real(r8) scavimptblvol(nimptblgrow_mind:nimptblgrow_maxd, ntot_amode)
85 !===============================================================================
87 subroutine mz_aero_defaultopts( aer_wetdep_list_out, aer_drydep_list_out, use_cam_sulfchem_out )
89 subroutine mz_aero_defaultopts( aer_wetdep_list_out, use_cam_sulfchem_out )
92 character(len=*), intent(out), optional :: aer_wetdep_list_out(:)
94 character(len=*), intent(out), optional :: aer_drydep_list_out(:)
96 logical, intent(out), optional :: use_cam_sulfchem_out
99 if ( present(aer_drydep_list_out) ) then
100 aer_drydep_list_out(:) = aer_drydep_list(:)
103 if ( present(aer_wetdep_list_out) ) then
104 aer_wetdep_list_out(:) = aer_wetdep_list(:)
106 if ( present(use_cam_sulfchem_out) ) then
107 use_cam_sulfchem_out = use_cam_sulfchem
110 end subroutine mz_aero_defaultopts
112 !===============================================================================
114 subroutine mz_aero_setopts( aer_wetdep_list_in, aer_drydep_list_in, use_cam_sulfchem_in )
116 subroutine mz_aero_setopts( aer_wetdep_list_in, use_cam_sulfchem_in )
119 character(len=*), intent(in), optional :: aer_wetdep_list_in(:)
121 character(len=*), intent(in), optional :: aer_drydep_list_in(:)
123 logical, intent(in), optional :: use_cam_sulfchem_in
126 if ( present(aer_drydep_list_in) ) then
127 aer_drydep_list(:) = aer_drydep_list_in(:)
130 if ( present(aer_wetdep_list_in) ) then
131 aer_wetdep_list(:) = aer_wetdep_list_in(:)
133 if ( present(use_cam_sulfchem_in) ) then
134 use_cam_sulfchem = use_cam_sulfchem_in
137 end subroutine mz_aero_setopts
139 !===============================================================================
140 subroutine mz_aero_initialize( )
142 use cam_history, only : addfld, add_default, phys_decomp
143 use sulchem, only : inisulchem
144 use mo_chem_utls, only : get_inv_ndx
145 use dust_intr, only : dst_wet_dep=>dust_has_wet_dep
146 use progseasalts_intr,only : sst_wet_dep=>progseasalts_has_wet_dep
147 use dust_intr, only : dust_names
148 use progseasalts_intr,only : progseasalts_names
149 use gas_wetdep_opts, only : gas_wetdep_list, gas_wetdep_cnt
151 use module_cam_support, only: addfld, add_default, phys_decomp
160 logical :: history_aerosol ! Output the MAM aerosol tendencies
162 !-----------------------------------------------------------------------
164 call phys_getopts( history_aerosol_out = history_aerosol )
166 dst_wet_dep(:) = .false.
167 sst_wet_dep(:) = .false.
169 history_aerosol = .FALSE.
174 !*NOTE* -only when invoked inside WRF
175 !Set num_mz_aerosols to some value greater than 0 so that the code inside 'mz_aero_wet_intr'
177 num_mz_aerosols = pcnst
180 count_species: do m = 1,pcnst
182 if ( len_trim(aer_wetdep_list(m)) == 0 ) exit count_species
184 do mm=1,gas_wetdep_cnt
185 if ( trim(gas_wetdep_list(mm)) == trim(aer_wetdep_list(m)) ) then
186 call endrun('mz_aero_initialize: '//trim(aer_wetdep_list(m))//' is in both het_lst and aer_wetdep_list')
190 call cnst_get_ind ( aer_wetdep_list(m), id, abort=.false. )
192 write(iulog,*) 'mz_aero_initialize: '//trim(aer_wetdep_list(m))//' does not exit in simulation'
194 call wrf_message(iulog)
196 call endrun('mz_aero_initialize: invalid washout species')
198 where( aer_wetdep_list(m) == dust_names )
201 where( aer_wetdep_list(m) == progseasalts_names )
206 write(iulog,*) 'mz_aero_initialize: '//aer_wetdep_list(m)//' will have wet removal'
208 call wrf_message(iulog)
211 call addfld (trim(aer_wetdep_list(m))//'SFWET','kg/m2/s ',1, 'A','Wet deposition flux at surface',phys_decomp)
212 call addfld (trim(aer_wetdep_list(m))//'SFSIC','kg/m2/s ', &
213 1, 'A','Wet deposition flux (incloud, convective) at surface',phys_decomp)
214 call addfld (trim(aer_wetdep_list(m))//'SFSIS','kg/m2/s ', &
215 1, 'A','Wet deposition flux (incloud, stratiform) at surface',phys_decomp)
216 call addfld (trim(aer_wetdep_list(m))//'SFSBC','kg/m2/s ', &
217 1, 'A','Wet deposition flux (belowcloud, convective) at surface',phys_decomp)
218 call addfld (trim(aer_wetdep_list(m))//'SFSBS','kg/m2/s ', &
219 1, 'A','Wet deposition flux (belowcloud, stratiform) at surface',phys_decomp)
220 call addfld (trim(aer_wetdep_list(m))//'WET','kg/kg/s ',pver, 'A','wet deposition tendency',phys_decomp)
221 call addfld (trim(aer_wetdep_list(m))//'SIC','kg/kg/s ',pver, 'A', &
222 trim(aer_wetdep_list(m))//' ic wet deposition',phys_decomp)
223 call addfld (trim(aer_wetdep_list(m))//'SIS','kg/kg/s ',pver, 'A', &
224 trim(aer_wetdep_list(m))//' is wet deposition',phys_decomp)
225 call addfld (trim(aer_wetdep_list(m))//'SBC','kg/kg/s ',pver, 'A', &
226 trim(aer_wetdep_list(m))//' bc wet deposition',phys_decomp)
227 call addfld (trim(aer_wetdep_list(m))//'SBS','kg/kg/s ',pver, 'A', &
228 trim(aer_wetdep_list(m))//' bs wet deposition',phys_decomp)
229 if ( history_aerosol ) then
230 call add_default (trim(aer_wetdep_list(m))//'SFWET', 1, ' ')
231 call add_default (trim(aer_wetdep_list(m))//'SFSIC', 1, ' ')
232 call add_default (trim(aer_wetdep_list(m))//'SFSIS', 1, ' ')
233 call add_default (trim(aer_wetdep_list(m))//'SFSBC', 1, ' ')
234 call add_default (trim(aer_wetdep_list(m))//'SFSBS', 1, ' ')
236 num_mz_aerosols = num_mz_aerosols + 1
242 count_dry_species: do m = 1,pcnst
244 if ( len_trim(aer_drydep_list(m)) == 0 ) exit count_dry_species
246 call cnst_get_ind ( aer_drydep_list(m), id, abort=.false. )
248 write(*,*) 'mz_aero_initialize: '//trim(aer_drydep_list(m))//' does not exist in simulation'
249 call endrun('mz_aero_initialize: invalid drydep species')
252 write(*,*) 'mz_aero_initialize: '//aer_drydep_list(m)//' will have dry deposition'
254 call addfld (trim(aer_drydep_list(m))//'DDF','kg/m2/s ', 1, 'A', &
255 trim(aer_drydep_list(m))//' dry deposition flux at bottom (grav + turb)',phys_decomp)
256 call addfld (trim(aer_drydep_list(m))//'TBF','kg/m2/s ', 1, 'A', &
257 trim(aer_drydep_list(m))//' turbulent dry deposition flux',phys_decomp)
258 call addfld (trim(aer_drydep_list(m))//'GVF','kg/m2/s ', 1, 'A', &
259 trim(aer_drydep_list(m))//' gravitational dry deposition flux',phys_decomp)
260 call addfld (trim(aer_drydep_list(m))//'DTQ','kg/kg/s ',pver, 'A', &
261 trim(aer_drydep_list(m))//' dry deposition',phys_decomp)
262 call addfld (trim(aer_drydep_list(m))//'DDV','m/s ',pver, 'A', &
263 trim(aer_drydep_list(m))//' deposition velocity',phys_decomp)
264 if ( history_aerosol ) then
265 call add_default (trim(aer_drydep_list(m))//'DDF', 1, ' ')
266 call add_default (trim(aer_drydep_list(m))//'TBF', 1, ' ')
267 call add_default (trim(aer_drydep_list(m))//'GVF', 1, ' ')
271 enddo count_dry_species
274 allocate( mz_aerosol_ids(num_mz_aerosols) )
276 do m = 1, num_mz_aerosols
277 call cnst_get_ind ( aer_wetdep_list(m), mz_aerosol_ids(m), abort=.false. )
283 id_h2o2 => spc_ids(4)
289 inv_o3 = get_inv_ndx('O3') > 0
290 inv_oh = get_inv_ndx('OH') > 0
291 inv_no3 = get_inv_ndx('NO3') > 0
292 inv_ho2 = get_inv_ndx('HO2') > 0
293 call cnst_get_ind ( 'SO2', id_so2, abort=.false. )
294 call cnst_get_ind ( 'SO4', id_so4, abort=.false. )
295 call cnst_get_ind ( 'H2O2', id_h2o2, abort=.false. )
296 call cnst_get_ind ( 'DMS', id_dms, abort=.false. )
299 id_o3 = get_inv_ndx('O3')
301 call cnst_get_ind ( 'O3', id_o3, abort=.false. )
304 id_oh = get_inv_ndx('OH')
306 call cnst_get_ind ( 'OH', id_oh, abort=.false. )
309 id_no3 = get_inv_ndx('NO3')
311 call cnst_get_ind ( 'NO3', id_no3, abort=.false. )
314 id_ho2 = get_inv_ndx('HO2')
316 call cnst_get_ind ( 'HO2', id_ho2, abort=.false. )
319 do_cam_sulfchem = use_cam_sulfchem .and. all(spc_ids > 0)
320 if ( do_cam_sulfchem ) then
325 write(iulog,*) 'mz_aero_initialize: do_cam_sulfchem = ',do_cam_sulfchem
327 call wrf_message(iulog)
331 end subroutine mz_aero_initialize
333 !===============================================================================
334 subroutine mz_aero_wet_intr ( lchnk_in, ncol_in, state_q, state_pdel, &
335 state_pmid, state_t, ptend_name, ptend_lq, ptend_q, nstep, dt, cme, prain, &
336 evapr, cldv, cldvcu, cldvst, cldc, cldn, fracis, calday, cmfdqr, evapc, conicw, rainmr &
337 #if ( defined MODAL_AERO )
338 , rate1ord_cw2pr_st & ! rce 2010/05/01
339 , dgncur_awet, qqcw, qaerwat &
342 !-----------------------------------------------------------------------
343 !-----------------------------------------------------------------------
345 use cam_history, only: outfld
346 use physics_types, only: physics_state, physics_ptend
347 use camsrfexch_types, only: cam_out_t
349 use module_cam_support, only: outfld
351 use wetdep, only: wetdepa_v1, wetdepa_v2
353 use sulchem, only: sulf_chemdr, cldychmini, dicor
355 use physconst, only: gravit
356 use constituents, only: cnst_mw
357 use physconst, only: amass => mwdry ! molecular weight dry air ~ kg/kmole
358 use physconst, only: boltz ! J/K/molecule
360 use dust_intr, only: dust_names
361 use progseasalts_intr,only: progseasalts_names
362 use tracer_cnst, only: get_cnst_data
363 use chem_mods, only: fix_mass
368 use modal_aero_deposition, only: set_srf_wetdep
372 !-----------------------------------------------------------------------
374 !-----------------------------------------------------------------------
378 real(r8), intent(in) :: dt ! time step
380 type(physics_state), intent(in ) :: state ! Physics state variables
382 integer, intent(in) :: lchnk_in,ncol_in
383 real(r8), intent(in) :: state_q(pcols,pver,pcnst)
384 real(r8), intent(in) :: state_pdel(pcols,pver)
385 real(r8), intent(in) :: state_t(pcols,pver)
386 real(r8), intent(in) :: state_pmid(pcols,pver)
388 integer, intent(in) :: nstep
389 real(r8), intent(in) :: cme(pcols,pver) ! local condensation of cloud water
390 real(r8), intent(in) :: prain(pcols,pver) ! production of rain
391 real(r8), intent(in) :: evapr(pcols,pver) ! evaporation of rain
392 real(r8), intent(in) :: cldn(pcols,pver) ! cloud fraction
393 real(r8), intent(in) :: cldc(pcols,pver) ! convective cloud fraction
394 real(r8), intent(in) :: cldv(pcols,pver) ! cloudy volume undergoing scavenging
395 real(r8), intent(in) :: cldvcu(pcols,pver) ! Convective precipitation area at the top interface of current layer
396 real(r8), intent(in) :: cldvst(pcols,pver) ! Stratiform precipitation area at the top interface of current layer
397 real(r8), intent(in) :: conicw(pcols, pver)
398 real(r8), intent(in) :: cmfdqr(pcols, pver)
399 real(r8), intent(in) :: evapc(pcols, pver) ! Evaporation rate of convective precipitation
400 real(r8), intent(in) :: rainmr(pcols, pver) ! rain mixing ratio
401 real(r8), intent(in) :: dlf(pcols,pver) ! Detrainment of convective condensate
403 type(physics_ptend), intent(inout) :: ptend ! indivdual parameterization tendencies
405 character(*), intent(inout) :: ptend_name
406 logical, intent(inout) :: ptend_lq(pcnst)
407 real(r8), intent(inout) :: ptend_q(pcols,pver,pcnst)
408 real(r8), target, intent(inout) :: qqcw(pcols,pver,pcnst) ! cloudborne tracer MR array
410 real(r8), intent(inout) :: fracis(pcols,pver,pcnst) ! fraction of transported species that are insoluble
411 real(r8), intent(in) :: calday ! current calendar day
412 #if ( defined MODAL_AERO )
413 real(r8), intent(in) :: rate1ord_cw2pr_st(pcols,pver) ! 1st order rate for strat cw to precip (1/s) ! rce 2010/05/01
414 real(r8), intent(in) :: dgncur_awet(pcols,pver,ntot_amode) ! wet/ambient geom. mean diameter (m)
415 ! for number distribution
416 real(r8), intent(inout) :: qaerwat(pcols,pver,ntot_amode)
419 type(cam_out_t), intent(inout) :: cam_out
421 !Balwinder.Singh@pnnl.gov: Temporarily defined as 'real' as it is not currently being used in any computations
422 real(r8), intent(in) :: cam_out
428 integer :: m ! tracer index
429 integer :: ixcldice, ixcldliq
430 integer :: lchnk ! chunk identifier
431 integer :: ncol ! number of atmospheric columns
433 real(r8) :: iscavt(pcols, pver)
434 real(r8) :: totcond(pcols, pver) ! sum of cldice and cldliq
435 integer :: yr, mon, day, ncsec
439 real(r8), dimension(pcols,pver) :: h2o23d,o3,oh,no3,ho2,so2,so4,dms,h2o2,ekso2,ekh2o2
441 real(r8), dimension(pcols,pver) ::&
443 hion ! Hydrogen ion concentration in drops
446 indcp(pcols,pver), &! Indices of cloudy grid points
447 ncldypts(pver) ! Number of cloudy grid points
449 real(r8) :: icwmr2(pcols,pver) ! in cloud water mixing ratio for hack scheme
450 real(r8) :: icscavt(pcols, pver)
451 real(r8) :: isscavt(pcols, pver)
452 real(r8) :: bcscavt(pcols, pver)
453 real(r8) :: bsscavt(pcols, pver)
454 real(r8) :: sol_factb, sol_facti
455 real(r8) :: sol_factic(pcols,pver)
456 real(r8) :: sol_factbi, sol_factii, sol_factiic
457 real(r8) :: xhnm(pcols, pver)
458 real(r8) :: sflx(pcols) ! deposition flux
459 real(r8) :: dicorfac(pcols) ! factors to increase HO2 diurnal averages
461 real(r8) :: scavcoef(pcols,pver) ! Dana and Hales coefficient (/mm) (0.1)
463 integer :: jnv ! index for scavcoefnv 3rd dimension
464 integer :: lphase ! index for interstitial / cloudborne aerosol
465 integer :: lspec ! index for aerosol number / chem-mass / water-mass
466 integer :: lcoardust, lcoarnacl ! indices for coarse mode dust and seasalt masses
467 real(r8) :: dqdt_tmp(pcols,pver) ! temporary array to hold tendency for 1 species
468 real(r8) :: f_act_conv(pcols,pver) ! prescribed aerosol activation fraction for convective cloud ! rce 2010/05/01
469 real(r8) :: f_act_conv_coarse(pcols,pver) ! similar but for coarse mode ! rce 2010/05/02
470 real(r8) :: f_act_conv_coarse_dust, f_act_conv_coarse_nacl ! rce 2010/05/02
471 real(r8) :: fracis_cw(pcols,pver)
472 real(r8) :: hygro_sum_old(pcols,pver) ! before removal [sum of (mass*hydro/dens)]
473 real(r8) :: hygro_sum_del(pcols,pver) ! removal change to [sum of (mass*hydro/dens)]
474 real(r8) :: hygro_sum_old_ik, hygro_sum_new_ik
475 real(r8) :: prec(pcols) ! precipitation rate
476 real(r8) :: q_tmp(pcols,pver) ! temporary array to hold "most current" mixing ratio for 1 species
477 real(r8) :: qqcw_tmp(pcols,pver) ! temporary array to hold qqcw ! rce 2010/05/01
478 real(r8) :: scavcoefnv(pcols,pver,0:2) ! Dana and Hales coefficient (/mm) for
479 ! cloud-borne num & vol (0),
480 ! interstitial num (1), interstitial vol (2)
481 real(r8) :: tmpa, tmpb
482 real(r8) :: tmpdust, tmpnacl
483 real(r8) :: water_old, water_new ! temporary old/new aerosol water mix-rat
484 logical :: isprx(pcols,pver) ! true if precipation
485 real(r8) :: aerdepwetis(pcols,pcnst) ! aerosol wet deposition (interstitial)
486 real(r8) :: aerdepwetcw(pcols,pcnst) ! aerosol wet deposition (cloud water)
487 real(r8), pointer :: fldcw(:,:)
490 !-----------------------------------------------------------------------
491 call cnst_get_ind('CLDICE', ixcldice)
492 call cnst_get_ind('CLDLIQ', ixcldliq)
501 totcond(:ncol, :) = state_q(:ncol,:,ixcldliq) + state_q(:ncol,:,ixcldice)
503 if ( num_mz_aerosols > 0 ) then
505 ! Wet deposition of mozart aerosol species.
506 ptend_name = ptend_name//'+mz_aero_wetdep'
511 where (prec(:ncol) >= 1.e-7)
512 isprx(:ncol,k) = .true.
514 isprx(:ncol,k) = .false.
516 prec(:ncol) = prec(:ncol) + (prain(:ncol,k) + cmfdqr(:ncol,k) - evapr(:ncol,k)) &
517 *state_pdel(:ncol,k)/gravit
521 ! calculate the mass-weighted sol_factic for coarse mode species
522 ! sol_factic_coarse(:,:) = 0.30_r8 ! tuned 1/4
523 f_act_conv_coarse(:,:) = 0.60_r8 ! rce 2010/05/02
524 f_act_conv_coarse_dust = 0.40_r8 ! rce 2010/05/02
525 f_act_conv_coarse_nacl = 0.80_r8 ! rce 2010/05/02
526 if (modeptr_coarse > 0) then
527 lcoardust = lptr_dust_a_amode(modeptr_coarse)
528 lcoarnacl = lptr_nacl_a_amode(modeptr_coarse)
529 if ((lcoardust > 0) .and. (lcoarnacl > 0)) then
532 tmpdust = max( 0.0_r8, state_q(i,k,lcoardust) + ptend_q(i,k,lcoardust)*dt )
533 tmpnacl = max( 0.0_r8, state_q(i,k,lcoarnacl) + ptend_q(i,k,lcoarnacl)*dt )
534 if ((tmpdust+tmpnacl) > 1.0e-30_r8) then
535 ! sol_factic_coarse(i,k) = (0.2_r8*tmpdust + 0.4_r8*tmpnacl)/(tmpdust+tmpnacl) ! tuned 1/6
536 f_act_conv_coarse(i,k) = (f_act_conv_coarse_dust*tmpdust &
537 + f_act_conv_coarse_nacl*tmpnacl)/(tmpdust+tmpnacl) ! rce 2010/05/02
545 scavcoefnv(:,:,0) = 0.0_r8 ! below-cloud scavcoef = 0.0 for cloud-borne species
547 do m = 1, ntot_amode ! main loop over aerosol modes
549 do lphase = 1, 2 ! loop over interstitial (1) and cloud-borne (2) forms
551 ! sol_factb and sol_facti values
552 ! sol_factb - currently this is basically a tuning factor
553 ! sol_facti & sol_factic - currently has a physical basis, and reflects activation fraction
555 ! 2008-mar-07 rce - sol_factb (interstitial) changed from 0.3 to 0.1
556 ! - sol_factic (interstitial, dust modes) changed from 1.0 to 0.5
557 ! - sol_factic (cloud-borne, pcarb modes) no need to set it to 0.0
558 ! because the cloud-borne pcarbon == 0 (no activation)
561 ! prior to this date, sol_factic was used for convective in-cloud wet removal,
562 ! and its value reflected a combination of an activation fraction (which varied between modes)
563 ! and a tuning factor
564 ! from this date forward, two parameters are used for convective in-cloud wet removal
565 ! f_act_conv is the activation fraction
566 ! note that "non-activation" of aerosol in air entrained into updrafts should
568 ! eventually we might use the activate routine (with w ~= 1 m/s) to calculate
569 ! this, but there is still the entrainment issue
570 ! sol_factic is strictly a tuning factor
572 if (lphase == 1) then ! interstial aerosol
573 hygro_sum_old(:,:) = 0.0_r8
574 hygro_sum_del(:,:) = 0.0_r8
575 call modal_aero_bcscavcoef_get( m, ncol, isprx, dgncur_awet, &
576 scavcoefnv(:,:,1), scavcoefnv(:,:,2) )
578 sol_factb = 0.1_r8 ! all below-cloud scav ON (0.1 "tuning factor")
579 ! sol_factb = 0.03_r8 ! all below-cloud scav ON (0.1 "tuning factor") ! tuned 1/6
581 sol_facti = 0.0_r8 ! strat in-cloud scav totally OFF for institial
583 sol_factic = 0.4_r8 ! xl 2010/05/20
585 if (m == modeptr_pcarbon) then
586 ! sol_factic = 0.0_r8 ! conv in-cloud scav OFF (0.0 activation fraction)
587 f_act_conv = 0.0_r8 ! rce 2010/05/02
588 else if ((m == modeptr_finedust) .or. (m == modeptr_coardust)) then
589 ! sol_factic = 0.2_r8 ! conv in-cloud scav ON (0.5 activation fraction) ! tuned 1/4
590 f_act_conv = 0.4_r8 ! rce 2010/05/02
592 ! sol_factic = 0.4_r8 ! conv in-cloud scav ON (1.0 activation fraction) ! tuned 1/4
593 f_act_conv = 0.8_r8 ! rce 2010/05/02
596 else ! cloud-borne aerosol (borne by stratiform cloud drops)
597 sol_factb = 0.0_r8 ! all below-cloud scav OFF (anything cloud-borne is located "in-cloud")
599 sol_facti = 1.0_r8 ! strat in-cloud scav totally ON for cloud-borne
600 ! sol_facti = 0.6_r8 ! strat in-cloud scav totally ON for cloud-borne ! tuned 1/6
601 sol_factic = 0.0_r8 ! conv in-cloud scav OFF (having this on would mean
602 ! that conv precip collects strat droplets)
603 f_act_conv = 0.0_r8 ! conv in-cloud scav OFF (having this on would mean
608 ! wetdepa has 6 "sol_fact" parameters:
609 ! sol_facti, sol_factic, sol_factb for liquid cloud
610 ! sol_factii, sol_factiic, sol_factbi for ice cloud
611 ! the ice cloud parameters are optional, and if not provided, they default to
612 ! one of the other sol_fact parameters (see subr. wetdepa about this)
613 ! for now, we set the ice cloud parameters equal
614 ! to their liquid cloud counterparts
615 ! currently the ice parameters are not used in wetdepa as
616 ! wetdepa sets "weight" (the ice cloud fraction) to 0.0
617 ! if this changes, we will have to give more thought to
618 ! the ice cloud parameter values
620 sol_factbi = sol_factb
621 sol_factii = sol_facti
622 sol_factiic = sol_factic(1,1)
625 do lspec = 0, nspec_amode(m)+1 ! loop over number + chem constituents + water
627 if (lspec == 0) then ! number
628 if (lphase == 1) then
632 mm = numptrcw_amode(m)
635 else if (lspec <= nspec_amode(m)) then ! non-water mass
636 if (lphase == 1) then
637 mm = lmassptr_amode(lspec,m)
640 mm = lmassptrcw_amode(lspec,m)
644 ! bypass wet removal of aerosol water
646 if (lphase == 1) then
648 ! mm = lwaterptr_amode(m)
659 ! set f_act_conv for interstitial (lphase=1) coarse mode species
660 ! for the convective in-cloud, we conceptually treat the coarse dust and seasalt
661 ! as being externally mixed, and apply f_act_conv = f_act_conv_coarse_dust/nacl to dust/seasalt
662 ! number and sulfate are conceptually partitioned to the dust and seasalt
663 ! on a mass basis, so the f_act_conv for number and sulfate are
664 ! mass-weighted averages of the values used for dust/seasalt
665 if ((lphase == 1) .and. (m == modeptr_coarse)) then
666 ! sol_factic = sol_factic_coarse
667 f_act_conv = f_act_conv_coarse ! rce 2010/05/02
669 if (lmassptr_amode(lspec,m) == lptr_dust_a_amode(m)) then
670 ! sol_factic = 0.2_r8 ! tuned 1/4
671 f_act_conv = f_act_conv_coarse_dust ! rce 2010/05/02
672 else if (lmassptr_amode(lspec,m) == lptr_nacl_a_amode(m)) then
673 ! sol_factic = 0.4_r8 ! tuned 1/6
674 f_act_conv = f_act_conv_coarse_nacl ! rce 2010/05/02
678 if ((lphase == 1) .and. (lspec <= nspec_amode(m))) then
679 ptend_lq(mm) = .TRUE.
680 dqdt_tmp(:,:) = 0.0_r8
681 ! q_tmp reflects changes from modal_aero_calcsize and is the "most current" q
682 q_tmp(1:ncol,:) = state_q(1:ncol,:,mm) + ptend_q(1:ncol,:,mm)*dt
684 fldcw => qqcw_get_field(mm,lchnk)
686 fldcw => qqcw(:,:,mm)
688 call wetdepa_v2( state_t, state_pmid, state_q, state_pdel, &
689 cldn, cldc, cmfdqr, evapc, conicw, prain, cme, &
690 evapr, totcond, q_tmp(:,:), dt, &
691 dqdt_tmp(:,:), iscavt, cldv, cldvcu, cldvst, dlf, fracis(:,:,mm), sol_factb, ncol, &
692 scavcoefnv(:,:,jnv), &
693 .false., rate1ord_cw2pr_st, fldcw, f_act_conv, & ! rce 2010/05/01
694 icscavt=icscavt, isscavt=isscavt, bcscavt=bcscavt, bsscavt=bsscavt, &
695 sol_facti_in=sol_facti, sol_factbi_in=sol_factbi, sol_factii_in=sol_factii, & ! rce 2010/05/03
696 sol_factic_in=sol_factic, sol_factiic_in=sol_factiic ) ! rce 2010/05/03
698 ptend_q(1:ncol,:,mm) = ptend_q(1:ncol,:,mm) + dqdt_tmp(1:ncol,:)
700 call outfld( trim(cnst_name(mm))//'WET', dqdt_tmp(:,:), pcols, lchnk)
701 call outfld( trim(cnst_name(mm))//'SIC', icscavt, pcols, lchnk)
702 call outfld( trim(cnst_name(mm))//'SIS', isscavt, pcols, lchnk)
703 call outfld( trim(cnst_name(mm))//'SBC', bcscavt, pcols, lchnk)
704 call outfld( trim(cnst_name(mm))//'SBS', bsscavt, pcols, lchnk)
709 sflx(i)=sflx(i)+dqdt_tmp(i,k)*state_pdel(i,k)/gravit
712 call outfld( trim(cnst_name(mm))//'SFWET', sflx, pcols, lchnk)
713 aerdepwetis(:ncol,mm) = sflx(:ncol)
718 sflx(i)=sflx(i)+icscavt(i,k)*state_pdel(i,k)/gravit
721 call outfld( trim(cnst_name(mm))//'SFSIC', sflx, pcols, lchnk)
725 sflx(i)=sflx(i)+isscavt(i,k)*state_pdel(i,k)/gravit
728 call outfld( trim(cnst_name(mm))//'SFSIS', sflx, pcols, lchnk)
732 sflx(i)=sflx(i)+bcscavt(i,k)*state_pdel(i,k)/gravit
735 call outfld( trim(cnst_name(mm))//'SFSBC', sflx, pcols, lchnk)
739 sflx(i)=sflx(i)+bsscavt(i,k)*state_pdel(i,k)/gravit
742 call outfld( trim(cnst_name(mm))//'SFSBS', sflx, pcols, lchnk)
745 tmpa = spechygro(lspectype_amode(lspec,m))/ &
746 specdens_amode(lspectype_amode(lspec,m))
748 hygro_sum_old(1:ncol,:) = hygro_sum_old(1:ncol,:) &
749 + tmpa*q_tmp(1:ncol,:)
750 hygro_sum_del(1:ncol,:) = hygro_sum_del(1:ncol,:) &
751 + tmpb*dqdt_tmp(1:ncol,:)
754 else if ((lphase == 1) .and. (lspec == nspec_amode(m)+1)) then
755 ! aerosol water -- because of how wetdepa treats evaporation of stratiform
756 ! precip, it is not appropriate to apply wetdepa to aerosol water
757 ! instead, "hygro_sum" = [sum of (mass*hygro/dens)] is calculated before and
758 ! after wet removal, and new water is calculated using
759 ! new_water = old_water*min(10,(hygro_sum_new/hygro_sum_old))
760 ! the "min(10,...)" is to avoid potential problems when hygro_sum_old ~= 0
761 ! also, individual wet removal terms (ic,is,bc,bs) are not output to history
762 ! ptend%lq(mm) = .TRUE.
763 ! dqdt_tmp(:,:) = 0.0_r8
766 ! water_old = max( 0.0_r8, state%q(i,k,mm)+ptend%q(i,k,mm)*dt )
767 water_old = max( 0.0_r8, qaerwat(i,k,mm) )
768 hygro_sum_old_ik = max( 0.0_r8, hygro_sum_old(i,k) )
769 hygro_sum_new_ik = max( 0.0_r8, hygro_sum_old_ik+hygro_sum_del(i,k) )
770 if (hygro_sum_new_ik >= 10.0_r8*hygro_sum_old_ik) then
771 water_new = 10.0_r8*water_old
773 water_new = water_old*(hygro_sum_new_ik/hygro_sum_old_ik)
775 ! dqdt_tmp(i,k) = (water_new - water_old)/dt
776 qaerwat(i,k,mm) = water_new
780 ! ptend%q(1:ncol,:,mm) = ptend%q(1:ncol,:,mm) + dqdt_tmp(1:ncol,:)
782 ! call outfld( trim(cnst_name(mm))//'WET', dqdt_tmp(:,:), pcols, lchnk)
787 ! sflx(i)=sflx(i)+dqdt_tmp(i,k)*state%pdel(i,k)/gravit
790 ! call outfld( trim(cnst_name(mm))//'SFWET', sflx, pcols, lchnk)
793 dqdt_tmp(:,:) = 0.0_r8
794 qqcw_tmp(:,:) = 0.0_r8 ! rce 2010/05/01
796 fldcw => qqcw_get_field(mm,lchnk)
798 fldcw => qqcw(:,:,mm)
800 call wetdepa_v2( state_t, state_pmid, state_q, state_pdel, &
801 cldn, cldc, cmfdqr, evapc, conicw, prain, cme, &
802 evapr, totcond, fldcw, dt, &
803 dqdt_tmp(:,:), iscavt, cldv, cldvcu, cldvst, dlf, fracis_cw(:,:), sol_factb, ncol, &
804 scavcoefnv(:,:,jnv), &
805 .true., rate1ord_cw2pr_st, qqcw_tmp, f_act_conv, & ! rce 2010/05/01
806 icscavt=icscavt, isscavt=isscavt, bcscavt=bcscavt, bsscavt=bsscavt, &
807 sol_facti_in=sol_facti, sol_factbi_in=sol_factbi, sol_factii_in=sol_factii, & ! rce 2010/05/03
808 sol_factic_in=sol_factic, sol_factiic_in=sol_factiic ) ! rce 2010/05/03
810 fldcw(1:ncol,:) = fldcw(1:ncol,:) + dqdt_tmp(1:ncol,:) * dt
815 sflx(i)=sflx(i)+dqdt_tmp(i,k)*state_pdel(i,k)/gravit
818 call outfld( trim(cnst_name_cw(mm))//'SFWET', sflx, pcols, lchnk)
819 aerdepwetcw(:ncol,mm) = sflx(:ncol)
824 sflx(i)=sflx(i)+icscavt(i,k)*state_pdel(i,k)/gravit
827 call outfld( trim(cnst_name_cw(mm))//'SFSIC', sflx, pcols, lchnk)
831 sflx(i)=sflx(i)+isscavt(i,k)*state_pdel(i,k)/gravit
834 call outfld( trim(cnst_name_cw(mm))//'SFSIS', sflx, pcols, lchnk)
838 sflx(i)=sflx(i)+bcscavt(i,k)*state_pdel(i,k)/gravit
841 call outfld( trim(cnst_name_cw(mm))//'SFSBC', sflx, pcols, lchnk)
845 sflx(i)=sflx(i)+bsscavt(i,k)*state_pdel(i,k)/gravit
848 call outfld( trim(cnst_name_cw(mm))//'SFSBS', sflx, pcols, lchnk)
852 enddo ! lspec = 0, nspec_amode(m)+1
853 enddo ! lphase = 1, 2
854 enddo ! m = 1, ntot_amode
856 call set_srf_wetdep(aerdepwetis, aerdepwetcw, cam_out)
860 scavcoef(:ncol,:)=0.1_r8
861 do m = 1, num_mz_aerosols
863 mm = mz_aerosol_ids(m)
865 if (mm > 0 .and. (.not. any(dust_names==cnst_name(mm))) .and. (.not. any(progseasalts_names==cnst_name(mm))) ) then
866 ptend%lq(mm) = .TRUE.
870 call wetdepa_v1( state%t, state%pmid, state%q, state%pdel, &
871 cldn, cldc, cmfdqr, conicw, prain, cme, &
872 evapr, totcond, state%q(:,:,mm), dt, &
873 ptend%q(:,:,mm), iscavt, cldv, fracis(:,:,mm), sol_factb, ncol, &
874 scavcoef, icscavt=icscavt, isscavt=isscavt, bcscavt=bcscavt, bsscavt=bsscavt, &
875 sol_facti_in=sol_facti)
877 call outfld( trim(cnst_name(mm))//'WET', ptend%q(:,:,mm), pcols, lchnk)
878 call outfld( trim(cnst_name(mm))//'SIC', icscavt , pcols, lchnk)
879 call outfld( trim(cnst_name(mm))//'SIS', isscavt, pcols, lchnk)
880 call outfld( trim(cnst_name(mm))//'SBC', bcscavt, pcols, lchnk)
881 call outfld( trim(cnst_name(mm))//'SBS', bsscavt, pcols, lchnk)
886 sflx(i)=sflx(i)+ptend%q(i,k,mm)*state%pdel(i,k)/gravit
889 call outfld( trim(cnst_name(mm))//'SFWET', sflx, pcols, lchnk)
891 ! export deposition fluxes to coupler
892 select case (trim(cnst_name(mm)))
895 cam_out%bcphiwet(i) = max(-sflx(i), 0._r8)
899 cam_out%ocphiwet(i) = max(-sflx(i), 0._r8)
909 if ( do_cam_sulfchem ) then
911 so4(:ncol,:) = state%q(:ncol,:,id_so4) + ptend%q(:ncol,:,id_so4)*dt
912 so2(:ncol,:) = state%q(:ncol,:,id_so2) + ptend%q(:ncol,:,id_so2)*dt
913 dms(:ncol,:) = state%q(:ncol,:,id_dms)
914 h2o2(:ncol,:) = state%q(:ncol,:,id_h2o2)
916 ! need oh,ho2,no3 in molec/cm3, o3 in kg/kg
919 call get_cnst_data( 'O3', o3(:ncol,:), ncol, lchnk ) ! vmr
921 o3(:ncol,:) = state%q(:ncol,:,id_o3)*amass/fix_mass(id_o3) ! vmr
925 xhnm(:ncol,:) = 1.e-6_r8 * state%pmiddry(:ncol,:) / (boltz*state%t(:ncol,:))
928 call get_cnst_data( 'OH', oh(:ncol,:), ncol, lchnk ) ! vmr
929 oh(:ncol,:) = oh(:ncol,:) * xhnm(:ncol,:) ! molec/cm3
931 oh(:ncol,:) = state%q(:ncol,:,id_oh)* (amass/cnst_mw(id_oh )) * xhnm(:ncol,:)
934 call get_cnst_data( 'NO3', no3(:ncol,:), ncol, lchnk ) ! vmr
935 no3(:ncol,:) = no3(:ncol,:) * xhnm(:ncol,:) ! molec/cm3
937 no3(:ncol,:) = state%q(:ncol,:,id_no3)* (amass/cnst_mw(id_no3)) * xhnm(:ncol,:)
940 call get_cnst_data( 'HO2', ho2(:ncol,:), ncol, lchnk ) ! vmr
941 ho2(:ncol,:) = ho2(:ncol,:) * xhnm(:ncol,:) ! molec/cm3
943 ho2(:ncol,:) = state%q(:ncol,:,id_ho2)* (amass/cnst_mw(id_ho2)) * xhnm(:ncol,:)
946 ! alter HO2 from diurnal average to instantaneous value
947 call dicor( calday, state%lat, ncol, dicorfac)
950 ho2(i,k) = ho2(i,k)*dicorfac(i)
955 call cldychmini( state%t, state%pmid, totcond, rainmr, cldn, &
956 cldv, conicw, icwmr2, so2, so4, &
957 ph, hion, ekso2, ekh2o2, indcp, &
959 call outfld( 'PH', ph, pcols, lchnk )
961 call sulf_chemdr( state%t, state%pmid, totcond, rainmr, cldn, cldv, &
962 conicw, icwmr2, indcp, ncldypts, hion, &
963 so2, so4, dms, h2o2, ekso2, ekh2o2, &
964 o3, h2o23d, oh, no3, ho2, state%q(:,:,1), &
965 state%zm, dt, calday, state%lat, state%lon, ncol, lchnk )
967 ptend%q(:ncol,:,id_so2) = (so2(:ncol,:)-state%q(:ncol,:,id_so2))/dt
968 ptend%lq(id_so2) = .true.
970 ptend%q(:ncol,:,id_so4) = (so4(:ncol,:)-state%q(:ncol,:,id_so4))/dt
971 ptend%lq(id_so4) = .true.
973 ptend%q(:ncol,:,id_dms) = (dms(:ncol,:)-state%q(:ncol,:,id_dms))/dt
974 ptend%lq(id_dms) = .true.
976 ptend%q(:ncol,:,id_h2o2) = (h2o2(:ncol,:)-state%q(:ncol,:,id_h2o2))/dt
977 ptend%lq(id_h2o2) = .true.
983 end subroutine mz_aero_wet_intr
988 !===============================================================================
989 subroutine mz_aero_dry_intr ( state, ptend, wvflx, dt, lat, clat, &
990 fsds, obklen, ts, ustar, prect, snowh, pblh, hflx, month, landfrac, &
991 icefrac, ocnfrac, fvin,ram1in, dgncur_awet, wetdens, qaerwat, &
993 !-----------------------------------------------------------------------
996 ! Interface to dry deposition and sedimentation of aerosols
998 ! Author: Xiaohong Liu and Dick Easter
1000 !-----------------------------------------------------------------------
1001 use cam_history, only: outfld
1002 use ppgrid, only: pverp
1003 use physics_types, only: physics_state, physics_ptend
1004 use camsrfexch_types, only: cam_out_t
1005 use physconst, only: gravit, rair, rhoh2o
1006 use drydep_mod, only: setdvel, d3ddflux, calcram
1007 use dust_sediment_mod, only: dust_sediment_tend, dust_sediment_vel
1009 use modal_aero_deposition, only: set_srf_drydep
1010 !-----------------------------------------------------------------------
1012 !-----------------------------------------------------------------------
1016 real(r8), intent(in) :: dt ! time step
1017 type(physics_state), intent(in ) :: state ! Physics state variables
1018 integer, intent(in) :: lat(pcols) ! latitude index for S->N storage
1019 real(r8), intent(in) :: clat(pcols) ! latitude
1020 real(r8), intent(in) :: fsds(pcols) ! longwave down at sfc
1021 real(r8), intent(in) :: obklen(pcols) ! obklen
1022 real(r8), intent(in) :: ustar(pcols) ! sfc fric vel--used over oceans and sea ice.
1023 real(r8), intent(in) :: ts(pcols) ! sfc temp
1024 real(r8), intent(in) :: landfrac(pcols) ! land fraction
1025 real(r8), intent(in) :: icefrac(pcols) ! ice fraction
1026 real(r8), intent(in) :: ocnfrac(pcols) ! ocean fraction
1027 real(r8), intent(in) :: hflx(pcols) ! sensible heat flux
1028 real(r8), intent(in) :: prect(pcols) ! prect
1029 real(r8), intent(in) :: snowh(pcols) ! snow depth
1030 real(r8), intent(in) :: pblh(pcols) ! pbl height
1031 integer, intent(in) :: month
1032 real(r8), intent(in) :: wvflx(pcols) ! water vapor flux
1033 real(r8), intent(in) :: fvin(pcols) ! for dry dep velocities from land model
1034 real(r8), intent(in) :: ram1in(pcols) ! for dry dep velocities from land model
1035 real(r8), intent(in) :: dgncur_awet(pcols,pver,ntot_amode)
1036 real(r8), intent(in) :: wetdens(pcols,pver,ntot_amode)
1037 real(r8), intent(inout) :: qaerwat(pcols,pver,ntot_amode)
1039 type(physics_ptend), intent(inout) :: ptend ! indivdual parameterization tendencies
1040 type(cam_out_t), intent(inout) :: cam_out
1045 integer :: jvlc ! index for last dimension of vlc_xxx arrays
1046 integer :: lphase ! index for interstitial / cloudborne aerosol
1047 integer :: lspec ! index for aerosol number / chem-mass / water-mass
1048 integer :: m ! aerosol mode index
1049 integer :: mm ! tracer index
1050 integer :: lchnk ! chunk identifier
1051 integer :: ncol ! number of atmospheric columns
1052 real(r8) :: tvs(pcols,pver)
1053 real(r8) :: sflx(pcols) ! deposition flux
1054 real(r8):: dep_trb(pcols) !kg/m2/s
1055 real(r8):: dep_dry(pcols) !kg/m2/s (total of grav and trb)
1056 real(r8):: dep_grv(pcols) !kg/m2/s (total of grav and trb)
1057 real (r8) :: rho(pcols,pver) ! air density in kg/m3
1058 real(r8) :: pvmzaer(pcols,pverp) ! sedimentation velocity in Pa
1059 real(r8) :: fv(pcols) ! for dry dep velocities, from land modified over ocean & ice
1060 real(r8) :: ram1(pcols) ! for dry dep velocities, from land modified over ocean & ice
1061 real(r8) :: dqdt_tmp(pcols,pver) ! temporary array to hold tendency for 1 species
1063 real(r8) :: rad_drop(pcols,pver)
1064 real(r8) :: dens_drop(pcols,pver)
1065 real(r8) :: sg_drop(pcols,pver)
1066 real(r8) :: rad_aer(pcols,pver)
1067 real(r8) :: dens_aer(pcols,pver)
1068 real(r8) :: sg_aer(pcols,pver)
1070 real(r8) :: vlc_dry(pcols,pver,4) ! dep velocity
1071 real(r8) :: vlc_grv(pcols,pver,4) ! dep velocity
1072 real(r8):: vlc_trb(pcols,4) ! dep velocity
1073 real(r8) :: aerdepdryis(pcols,pcnst) ! aerosol dry deposition (interstitial)
1074 real(r8) :: aerdepdrycw(pcols,pcnst) ! aerosol dry deposition (cloud water)
1075 real(r8), pointer :: fldcw(:,:)
1076 !-----------------------------------------------------------------------
1080 tvs(:ncol,:) = state%t(:ncol,:)!*(1+state%q(:ncol,k)
1081 rho(:ncol,:)= state%pmid(:ncol,:)/(rair*state%t(:ncol,:))
1083 ! Dry deposition of mozart aerosol species.
1084 ptend%name = ptend%name//'+mz_aero_drydep'
1086 ! #################################
1087 ! call setdvel( ncol, landfrac, icefrac, ocnfrac, .001_r8, .001_r8, .001_r8, dvel )
1088 ! we get the ram1,fv from the land model as ram1in,fvin, but need to calculate it over oceans and ice.
1089 ! better if we got thse from the ocean and ice model
1090 ! for friction velocity, we use ustar (from taux and tauy), except over land, where we use fv from the land model.
1092 call calcram(ncol,landfrac,icefrac,ocnfrac,obklen,&
1093 ustar,ram1in,ram1,state%t(:,pver),state%pmid(:,pver),&
1094 state%pdel(:,pver),fvin,fv)
1095 ! call outfld( 'airFV', fv(:), pcols, lchnk )
1096 ! call outfld( 'RAM1', ram1(:), pcols, lchnk )
1097 ! call outfld( 'icefrc', icefrac(:), pcols, lchnk )
1101 ! calc settling/deposition velocities for cloud droplets (and cloud-borne aerosols)
1103 ! *** mean drop radius should eventually be computed from ndrop and qcldwtr
1104 rad_drop(:,:) = 5.0e-6_r8
1105 dens_drop(:,:) = rhoh2o
1108 call modal_aero_depvel_part( ncol,state%t(:,:), state%pmid(:,:), ram1, fv, &
1109 vlc_dry(:,:,jvlc), vlc_trb(:,jvlc), vlc_grv(:,:,jvlc), &
1110 rad_drop(:,:), dens_drop(:,:), sg_drop(:,:), 0, lchnk)
1112 call modal_aero_depvel_part( ncol,state%t(:,:), state%pmid(:,:), ram1, fv, &
1113 vlc_dry(:,:,jvlc), vlc_trb(:,jvlc), vlc_grv(:,:,jvlc), &
1114 rad_drop(:,:), dens_drop(:,:), sg_drop(:,:), 3, lchnk)
1118 do m = 1, ntot_amode ! main loop over aerosol modes
1120 do lphase = 1, 2 ! loop over interstitial / cloud-borne forms
1122 if (lphase == 1) then ! interstial aerosol - calc settling/dep velocities of mode
1124 ! rad_aer = volume mean wet radius (m)
1125 ! dgncur_awet = geometric mean wet diameter for number distribution (m)
1126 rad_aer(1:ncol,:) = 0.5_r8*dgncur_awet(1:ncol,:,m) &
1127 *exp(1.5*(alnsg_amode(m)**2))
1128 ! dens_aer(1:ncol,:) = wet density (kg/m3)
1129 dens_aer(1:ncol,:) = wetdens(1:ncol,:,m)
1130 sg_aer(1:ncol,:) = sigmag_amode(m)
1133 call modal_aero_depvel_part( ncol, state%t(:,:), state%pmid(:,:), ram1, fv, &
1134 vlc_dry(:,:,jvlc), vlc_trb(:,jvlc), vlc_grv(:,:,jvlc), &
1135 rad_aer(:,:), dens_aer(:,:), sg_aer(:,:), 0, lchnk)
1137 call modal_aero_depvel_part( ncol, state%t(:,:), state%pmid(:,:), ram1, fv, &
1138 vlc_dry(:,:,jvlc), vlc_trb(:,jvlc), vlc_grv(:,:,jvlc), &
1139 rad_aer(:,:), dens_aer(:,:), sg_aer(:,:), 3, lchnk)
1142 do lspec = 0, nspec_amode(m)+1 ! loop over number + constituents + water
1144 if (lspec == 0) then ! number
1145 if (lphase == 1) then
1146 mm = numptr_amode(m)
1149 mm = numptrcw_amode(m)
1152 else if (lspec <= nspec_amode(m)) then ! non-water mass
1153 if (lphase == 1) then
1154 mm = lmassptr_amode(lspec,m)
1157 mm = lmassptrcw_amode(lspec,m)
1161 ! bypass dry deposition of aerosol water
1163 if (lphase == 1) then
1165 ! mm = lwaterptr_amode(m)
1176 ! if (lphase == 1) then
1177 if ((lphase == 1) .and. (lspec <= nspec_amode(m))) then
1178 ptend%lq(mm) = .TRUE.
1180 ! use pvprogseasalts instead (means making the top level 0)
1181 pvmzaer(:ncol,1)=0._r8
1182 pvmzaer(:ncol,2:pverp) = vlc_dry(:ncol,:,jvlc)
1184 call outfld( trim(cnst_name(mm))//'DDV', pvmzaer(:,2:pverp), pcols, lchnk )
1186 if(.true.) then ! use phil's method
1187 ! convert from meters/sec to pascals/sec
1188 ! pvprogseasalts(:,1) is assumed zero, use density from layer above in conversion
1189 pvmzaer(:ncol,2:pverp) = pvmzaer(:ncol,2:pverp) * rho(:ncol,:)*gravit
1191 ! calculate the tendencies and sfc fluxes from the above velocities
1192 call dust_sediment_tend( &
1193 ncol, dt, state%pint(:,:), state%pmid, state%pdel, state%t , &
1194 state%q(:,:,mm), pvmzaer, ptend%q(:,:,mm), sflx )
1195 else !use charlie's method
1196 call d3ddflux( ncol, vlc_dry(:,:,jvlc), state%q(:,:,mm), state%pmid, &
1197 state%pdel, tvs, sflx, ptend%q(:,:,mm), dt )
1200 ! apportion dry deposition into turb and gravitational settling for tapes
1202 dep_trb(i)=sflx(i)*vlc_trb(i,jvlc)/vlc_dry(i,pver,jvlc)
1203 dep_grv(i)=sflx(i)*vlc_grv(i,pver,jvlc)/vlc_dry(i,pver,jvlc)
1206 call outfld( trim(cnst_name(mm))//'DDF', sflx, pcols, lchnk)
1207 call outfld( trim(cnst_name(mm))//'TBF', dep_trb, pcols, lchnk )
1208 call outfld( trim(cnst_name(mm))//'GVF', dep_grv, pcols, lchnk )
1209 call outfld( trim(cnst_name(mm))//'DTQ', ptend%q(:,:,mm), pcols, lchnk)
1210 aerdepdryis(:ncol,mm) = sflx(:ncol)
1212 else if ((lphase == 1) .and. (lspec == nspec_amode(m)+1)) then ! aerosol water
1213 ! use pvprogseasalts instead (means making the top level 0)
1214 pvmzaer(:ncol,1)=0._r8
1215 pvmzaer(:ncol,2:pverp) = vlc_dry(:ncol,:,jvlc)
1217 if(.true.) then ! use phil's method
1218 ! convert from meters/sec to pascals/sec
1219 ! pvprogseasalts(:,1) is assumed zero, use density from layer above in conversion
1220 pvmzaer(:ncol,2:pverp) = pvmzaer(:ncol,2:pverp) * rho(:ncol,:)*gravit
1222 ! calculate the tendencies and sfc fluxes from the above velocities
1223 call dust_sediment_tend( &
1224 ncol, dt, state%pint(:,:), state%pmid, state%pdel, state%t , &
1225 qaerwat(:,:,mm), pvmzaer, dqdt_tmp(:,:), sflx )
1226 else !use charlie's method
1227 call d3ddflux( ncol, vlc_dry(:,:,jvlc), qaerwat(:,:,mm), state%pmid, &
1228 state%pdel, tvs, sflx, dqdt_tmp(:,:), dt )
1231 ! apportion dry deposition into turb and gravitational settling for tapes
1233 dep_trb(i)=sflx(i)*vlc_trb(i,jvlc)/vlc_dry(i,pver,jvlc)
1234 dep_grv(i)=sflx(i)*vlc_grv(i,pver,jvlc)/vlc_dry(i,pver,jvlc)
1237 qaerwat(1:ncol,:,mm) = qaerwat(1:ncol,:,mm) + dqdt_tmp(1:ncol,:) * dt
1240 ! use pvprogseasalts instead (means making the top level 0)
1241 pvmzaer(:ncol,1)=0._r8
1242 pvmzaer(:ncol,2:pverp) = vlc_dry(:ncol,:,jvlc)
1243 fldcw => qqcw_get_field(mm,lchnk)
1244 if(.true.) then ! use phil's method
1245 ! convert from meters/sec to pascals/sec
1246 ! pvprogseasalts(:,1) is assumed zero, use density from layer above in conversion
1247 pvmzaer(:ncol,2:pverp) = pvmzaer(:ncol,2:pverp) * rho(:ncol,:)*gravit
1249 ! calculate the tendencies and sfc fluxes from the above velocities
1250 call dust_sediment_tend( &
1251 ncol, dt, state%pint(:,:), state%pmid, state%pdel, state%t , &
1252 fldcw(:,:), pvmzaer, dqdt_tmp(:,:), sflx )
1253 else !use charlie's method
1254 call d3ddflux( ncol, vlc_dry(:,:,jvlc), fldcw(:,:), state%pmid, &
1255 state%pdel, tvs, sflx, dqdt_tmp(:,:), dt )
1258 ! apportion dry deposition into turb and gravitational settling for tapes
1260 dep_trb(i)=sflx(i)*vlc_trb(i,jvlc)/vlc_dry(i,pver,jvlc)
1261 dep_grv(i)=sflx(i)*vlc_grv(i,pver,jvlc)/vlc_dry(i,pver,jvlc)
1264 fldcw(1:ncol,:) = fldcw(1:ncol,:) + dqdt_tmp(1:ncol,:) * dt
1266 call outfld( trim(cnst_name_cw(mm))//'DDF', sflx, pcols, lchnk)
1267 call outfld( trim(cnst_name_cw(mm))//'TBF', dep_trb, pcols, lchnk )
1268 call outfld( trim(cnst_name_cw(mm))//'GVF', dep_grv, pcols, lchnk )
1269 aerdepdrycw(:ncol,mm) = sflx(:ncol)
1273 enddo ! lspec = 0, nspec_amode(m)+1
1274 enddo ! lphase = 1, 2
1275 enddo ! m = 1, ntot_amode
1277 call set_srf_drydep(aerdepdryis, aerdepdrycw, cam_out)
1280 end subroutine mz_aero_dry_intr
1283 !===============================================================================
1284 subroutine modal_aero_depvel_part( ncol, t, pmid, ram1, fv, vlc_dry, vlc_trb, vlc_grv, &
1285 radius_part, density_part, sig_part, moment, lchnk )
1287 ! calculates surface deposition velocity of particles
1288 ! L. Zhang, S. Gong, J. Padro, and L. Barrie
1289 ! A size-seggregated particle dry deposition scheme for an atmospheric aerosol module
1290 ! Atmospheric Environment, 35, 549-560, 2001.
1297 use physconst, only: pi,boltz, gravit, rair
1298 use mo_drydep, only: n_land_type, fraction_landuse
1304 real(r8), intent(in) :: t(pcols,pver) !atm temperature (K)
1305 real(r8), intent(in) :: pmid(pcols,pver) !atm pressure (Pa)
1306 real(r8), intent(in) :: fv(pcols) !friction velocity (m/s)
1307 real(r8), intent(in) :: ram1(pcols) !aerodynamical resistance (s/m)
1308 real(r8), intent(in) :: radius_part(pcols,pver) ! mean (volume/number) particle radius (m)
1309 real(r8), intent(in) :: density_part(pcols,pver) ! density of particle material (kg/m3)
1310 real(r8), intent(in) :: sig_part(pcols,pver) ! geometric standard deviation of particles
1311 integer, intent(in) :: moment ! moment of size distribution (0 for number, 2 for surface area, 3 for volume)
1312 integer, intent(in) :: ncol
1313 integer, intent(in) :: lchnk
1315 real(r8), intent(out) :: vlc_trb(pcols) !Turbulent deposn velocity (m/s)
1316 real(r8), intent(out) :: vlc_grv(pcols,pver) !grav deposn velocity (m/s)
1317 real(r8), intent(out) :: vlc_dry(pcols,pver) !dry deposn velocity (m/s)
1318 !------------------------------------------------------------------------
1320 !------------------------------------------------------------------------
1322 integer :: m,i,k,ix !indices
1323 real(r8) :: rho !atm density (kg/m**3)
1324 real(r8) :: vsc_dyn_atm(pcols,pver) ![kg m-1 s-1] Dynamic viscosity of air
1325 real(r8) :: vsc_knm_atm(pcols,pver) ![m2 s-1] Kinematic viscosity of atmosphere
1326 real(r8) :: shm_nbr ![frc] Schmidt number
1327 real(r8) :: stk_nbr ![frc] Stokes number
1328 real(r8) :: mfp_atm(pcols,pver) ![m] Mean free path of air
1329 real(r8) :: dff_aer ![m2 s-1] Brownian diffusivity of particle
1330 real(r8) :: slp_crc(pcols,pver) ![frc] Slip correction factor
1331 real(r8) :: rss_trb ![s m-1] Resistance to turbulent deposition
1332 real(r8) :: rss_lmn ![s m-1] Quasi-laminar layer resistance
1333 real(r8) :: brownian ! collection efficiency for Browning diffusion
1334 real(r8) :: impaction ! collection efficiency for impaction
1335 real(r8) :: interception ! collection efficiency for interception
1336 real(r8) :: stickfrac ! fraction of particles sticking to surface
1337 real(r8) :: radius_moment(pcols,pver) ! median radius (m) for moment
1338 real(r8) :: lnsig ! ln(sig_part)
1339 real(r8) :: dispersion ! accounts for influence of size dist dispersion on bulk settling velocity
1340 ! assuming radius_part is number mode radius * exp(1.5 ln(sigma))
1344 real(r8) :: wrk1, wrk2, wrk3
1347 real(r8) gamma(11) ! exponent of schmidt number
1348 ! data gamma/0.54d+00, 0.56d+00, 0.57d+00, 0.54d+00, 0.54d+00, &
1349 ! 0.56d+00, 0.54d+00, 0.54d+00, 0.54d+00, 0.56d+00, &
1351 data gamma/0.56d+00, 0.54d+00, 0.54d+00, 0.56d+00, 0.56d+00, &
1352 0.56d+00, 0.50d+00, 0.54d+00, 0.54d+00, 0.54d+00, &
1356 real(r8) alpha(11) ! parameter for impaction
1357 ! data alpha/50.00d+00, 0.95d+00, 0.80d+00, 1.20d+00, 1.30d+00, &
1358 ! 0.80d+00, 50.00d+00, 50.00d+00, 2.00d+00, 1.50d+00, &
1360 data alpha/1.50d+00, 1.20d+00, 1.20d+00, 0.80d+00, 1.00d+00, &
1361 0.80d+00, 100.00d+00, 50.00d+00, 2.00d+00, 1.20d+00, &
1365 real(r8) radius_collector(11) ! radius (m) of surface collectors
1366 ! data radius_collector/-1.00d+00, 5.10d-03, 3.50d-03, 3.20d-03, 10.00d-03, &
1367 ! 5.00d-03, -1.00d+00, -1.00d+00, 10.00d-03, 10.00d-03, &
1369 data radius_collector/10.00d-03, 3.50d-03, 3.50d-03, 5.10d-03, 2.00d-03, &
1370 5.00d-03, -1.00d+00, -1.00d+00, 10.00d-03, 3.50d-03, &
1372 save radius_collector
1374 integer :: iwet(11) ! flag for wet surface = 1, otherwise = -1
1375 ! data iwet/1, -1, -1, -1, -1, &
1376 ! -1, -1, -1, 1, -1, &
1378 data iwet/-1, -1, -1, -1, -1, &
1384 !------------------------------------------------------------------------
1388 lnsig = log(sig_part(i,k))
1389 ! use a maximum radius of 50 microns when calculating deposition velocity
1390 radius_moment(i,k) = min(50.0d-6,radius_part(i,k))* &
1391 exp((float(moment)-1.5)*lnsig*lnsig)
1392 dispersion = exp(2.*lnsig*lnsig)
1394 rho=pmid(i,k)/rair/t(i,k)
1396 ! Quasi-laminar layer resistance: call rss_lmn_get
1397 ! Size-independent thermokinetic properties
1398 vsc_dyn_atm(i,k) = 1.72e-5_r8 * ((t(i,k)/273.0_r8)**1.5_r8) * 393.0_r8 / &
1399 (t(i,k)+120.0_r8) ![kg m-1 s-1] RoY94 p. 102
1400 mfp_atm(i,k) = 2.0_r8 * vsc_dyn_atm(i,k) / & ![m] SeP97 p. 455
1401 (pmid(i,k)*sqrt(8.0_r8/(pi*rair*t(i,k))))
1402 vsc_knm_atm(i,k) = vsc_dyn_atm(i,k) / rho ![m2 s-1] Kinematic viscosity of air
1404 slp_crc(i,k) = 1.0_r8 + mfp_atm(i,k) * &
1405 (1.257_r8+0.4_r8*exp(-1.1_r8*radius_moment(i,k)/(mfp_atm(i,k)))) / &
1406 radius_moment(i,k) ![frc] Slip correction factor SeP97 p. 464
1407 vlc_grv(i,k) = (4.0_r8/18.0_r8) * radius_moment(i,k)*radius_moment(i,k)*density_part(i,k)* &
1408 gravit*slp_crc(i,k) / vsc_dyn_atm(i,k) ![m s-1] Stokes' settling velocity SeP97 p. 466
1409 vlc_grv(i,k) = vlc_grv(i,k) * dispersion
1411 vlc_dry(i,k)=vlc_grv(i,k)
1414 k=pver ! only look at bottom level for next part
1416 dff_aer = boltz * t(i,k) * slp_crc(i,k) / & ![m2 s-1]
1417 (6.0_r8*pi*vsc_dyn_atm(i,k)*radius_moment(i,k)) !SeP97 p.474
1418 shm_nbr = vsc_knm_atm(i,k) / dff_aer ![frc] SeP97 p.972
1422 do lt = 1,n_land_type
1423 lnd_frc = fraction_landuse(i,lt,lchnk)
1424 if ( lnd_frc /= 0._r8 ) then
1425 brownian = shm_nbr**(-gamma(lt))
1426 if (radius_collector(lt) > 0.0d0) then
1428 stk_nbr = vlc_grv(i,k) * fv(i) / (gravit*radius_collector(lt))
1429 interception = 2.0_r8*(radius_moment(i,k)/radius_collector(lt))**2.0_r8
1431 ! non-vegetated surface
1432 stk_nbr = vlc_grv(i,k) * fv(i) * fv(i) / (gravit*vsc_knm_atm(i,k)) ![frc] SeP97 p.965
1433 interception = 0.0_r8
1435 impaction = (stk_nbr/(alpha(lt)+stk_nbr))**2.0_r8
1437 if (iwet(lt) > 0) then
1440 stickfrac = exp(-sqrt(stk_nbr))
1441 if (stickfrac < 1.0d-10) stickfrac = 1.0d-10
1443 rss_lmn = 1.0_r8 / (3.0_r8 * fv(i) * stickfrac * (brownian+interception+impaction))
1444 rss_trb = ram1(i) + rss_lmn + ram1(i)*rss_lmn*vlc_grv(i,k)
1446 wrk1 = 1.0_r8 / rss_trb
1447 wrk2 = wrk2 + lnd_frc*( wrk1 )
1448 wrk3 = wrk3 + lnd_frc*( wrk1 + vlc_grv(i,k) )
1456 end subroutine modal_aero_depvel_part
1460 !===============================================================================
1461 subroutine modal_aero_bcscavcoef_get( m, ncol, isprx, dgn_awet, scavcoefnum, scavcoefvol )
1464 !-----------------------------------------------------------------------
1467 integer,intent(in) :: m, ncol
1468 logical,intent(in):: isprx(pcols,pver)
1469 real(r8), intent(in) :: dgn_awet(pcols,pver,ntot_amode)
1470 real(r8), intent(out) :: scavcoefnum(pcols,pver), scavcoefvol(pcols,pver)
1473 real(r8) dumdgratio, xgrow, dumfhi, dumflo, scavimpvol, scavimpnum
1479 ! do only if no precip
1480 if ( isprx(i,k) ) then
1482 ! interpolate table values using log of (actual-wet-size)/(base-dry-size)
1484 dumdgratio = dgn_awet(i,k,m)/dgnum_amode(m)
1486 if ((dumdgratio .ge. 0.99) .and. (dumdgratio .le. 1.01)) then
1487 scavimpvol = scavimptblvol(0,m)
1488 scavimpnum = scavimptblnum(0,m)
1490 xgrow = log( dumdgratio ) / dlndg_nimptblgrow
1491 jgrow = int( xgrow )
1492 if (xgrow .lt. 0.) jgrow = jgrow - 1
1493 if (jgrow .lt. nimptblgrow_mind) then
1494 jgrow = nimptblgrow_mind
1497 jgrow = min( jgrow, nimptblgrow_maxd-1 )
1500 dumfhi = xgrow - jgrow
1501 dumflo = 1. - dumfhi
1503 scavimpvol = dumflo*scavimptblvol(jgrow,m) + &
1504 dumfhi*scavimptblvol(jgrow+1,m)
1505 scavimpnum = dumflo*scavimptblnum(jgrow,m) + &
1506 dumfhi*scavimptblnum(jgrow+1,m)
1510 ! impaction scavenging removal amount for volume
1511 scavcoefvol(i,k) = exp( scavimpvol )
1512 ! impaction scavenging removal amount to number
1513 scavcoefnum(i,k) = exp( scavimpnum )
1515 ! scavcoef = impaction scav rate (1/h) for precip = 1 mm/h
1516 ! scavcoef = impaction scav rate (1/s) for precip = pfx_inrain
1517 ! (scavcoef/3600) = impaction scav rate (1/s) for precip = 1 mm/h
1518 ! (pfx_inrain*3600) = in-rain-area precip rate (mm/h)
1519 ! impactrate = (scavcoef/3600) * (pfx_inrain*3600)
1521 scavcoefvol(i,k) = 0._r8
1522 scavcoefnum(i,k) = 0._r8
1529 end subroutine modal_aero_bcscavcoef_get
1532 !===============================================================================
1533 subroutine modal_aero_bcscavcoef_init
1534 !-----------------------------------------------------------------------
1537 ! Computes lookup table for aerosol impaction/interception scavenging rates
1539 ! Authors: R. Easter
1541 !-----------------------------------------------------------------------
1543 use shr_kind_mod,only: r8 => shr_kind_r8
1546 use abortutils, only: endrun
1548 use module_cam_support, only: endrun
1556 parameter (nnfit_maxd=27)
1558 integer i, jgrow, jdens, jpress, jtemp, ll, mode, nnfit
1561 real(r8) dg0, dg0_cgs, press, &
1562 rhodryaero, rhowetaero, rhowetaero_cgs, rmserr, &
1563 scavratenum, scavratevol, sigmag, &
1564 temp, wetdiaratio, wetvolratio
1565 real(r8) aafitnum(1), xxfitnum(1,nnfit_maxd), yyfitnum(nnfit_maxd)
1566 real(r8) aafitvol(1), xxfitvol(1,nnfit_maxd), yyfitvol(nnfit_maxd)
1569 dlndg_nimptblgrow = log( 1.25d00 )
1571 do 7900 mode = 1, ntot_amode
1573 sigmag = sigmag_amode(mode)
1575 ll = lspectype_amode(1,mode)
1576 rhodryaero = specdens_amode(ll)
1578 do 7800 jgrow = nimptblgrow_mind, nimptblgrow_maxd
1580 wetdiaratio = exp( jgrow*dlndg_nimptblgrow )
1581 dg0 = dgnum_amode(mode)*wetdiaratio
1583 wetvolratio = exp( jgrow*dlndg_nimptblgrow*3. )
1584 rhowetaero = 1.0 + (rhodryaero-1.0)/wetvolratio
1585 rhowetaero = min( rhowetaero, rhodryaero )
1588 ! compute impaction scavenging rates at 1 temp-press pair and save
1593 press = 0.75e6 ! dynes/cm2
1594 rhowetaero = rhodryaero
1596 dg0_cgs = dg0*1.0e2 ! m to cm
1597 rhowetaero_cgs = rhowetaero*1.0e-3 ! kg/m3 to g/cm3
1598 call calc_1_impact_rate( &
1599 dg0_cgs, sigmag, rhowetaero_cgs, temp, press, &
1600 scavratenum, scavratevol, lunerr )
1603 if (nnfit .gt. nnfit_maxd) then
1607 9110 format( '*** subr. modal_aero_bcscavcoef_init -- nnfit too big' )
1609 xxfitnum(1,nnfit) = 1.
1610 yyfitnum(nnfit) = log( scavratenum )
1612 xxfitvol(1,nnfit) = 1.
1613 yyfitvol(nnfit) = log( scavratevol )
1618 ! skip mlinfit stuff because scav table no longer has dependencies on
1619 ! air temp, air press, and particle wet density
1620 ! just load the log( scavrate--- ) values
1623 !! do linear regression
1624 !! log(scavrate) = a1 + a2*log(wetdens)
1626 ! call mlinft( xxfitnum, yyfitnum, aafitnum, nnfit, 1, 1, rmserr )
1627 ! call mlinft( xxfitvol, yyfitvol, aafitvol, nnfit, 1, 1, rmserr )
1629 ! scavimptblnum(jgrow,mode) = aafitnum(1)
1630 ! scavimptblvol(jgrow,mode) = aafitvol(1)
1632 scavimptblnum(jgrow,mode) = yyfitnum(1)
1633 scavimptblvol(jgrow,mode) = yyfitvol(1)
1641 end subroutine modal_aero_bcscavcoef_init
1644 !===============================================================================
1645 subroutine calc_1_impact_rate( &
1646 dg0, sigmag, rhoaero, temp, press, &
1647 scavratenum, scavratevol, lunerr )
1649 ! routine computes a single impaction scavenging rate
1650 ! for precipitation rate of 1 mm/h
1652 ! dg0 = geometric mean diameter of aerosol number size distrib. (cm)
1653 ! sigmag = geometric standard deviation of size distrib.
1654 ! rhoaero = density of aerosol particles (g/cm^3)
1655 ! temp = temperature (K)
1656 ! press = pressure (dyne/cm^2)
1657 ! scavratenum = number scavenging rate (1/h)
1658 ! scavratevol = volume or mass scavenging rate (1/h)
1659 ! lunerr = logical unit for error message
1661 use shr_kind_mod, only: r8 => shr_kind_r8
1667 real(r8) dg0, sigmag, rhoaero, temp, press, scavratenum, scavratevol
1671 parameter (nrainsvmax=50)
1672 real(r8) rrainsv(nrainsvmax), xnumrainsv(nrainsvmax),&
1673 vfallrainsv(nrainsvmax)
1676 parameter (naerosvmax=51)
1677 real(r8) aaerosv(naerosvmax), &
1678 ynumaerosv(naerosvmax), yvolaerosv(naerosvmax)
1680 integer i, ja, jr, na, nr
1681 real(r8) a, aerodiffus, aeromass, ag0, airdynvisc, airkinvisc
1682 real(r8) anumsum, avolsum, boltzmann, cair, chi
1683 real(r8) d, dr, dum, dumfuchs, dx
1684 real(r8) ebrown, eimpact, eintercept, etotal, freepath, gravity
1685 real(r8) pi, precip, precipmmhr, precipsum
1686 real(r8) r, rainsweepout, reynolds, rhi, rhoair, rhowater, rlo, rnumsum
1687 real(r8) scavsumnum, scavsumnumbb
1688 real(r8) scavsumvol, scavsumvolbb
1689 real(r8) schmidt, sqrtreynolds, sstar, stokes, sx
1690 real(r8) taurelax, vfall, vfallstp
1691 real(r8) x, xg0, xg3, xhi, xlo, xmuwaterair
1697 nr = 1 + nint( (rhi-rlo)/dr )
1698 if (nr .gt. nrainsvmax) then
1702 9110 format( '*** subr. calc_1_impact_rate -- nr > nrainsvmax' )
1705 precip = precipmmhr/36000.
1710 xg3 = xg0 + 3.*sx*sx
1716 dx = max( 0.2_r8*sx, 0.01_r8 )
1717 xlo = xg3 - max( 4._r8*sx, 2._r8*dx )
1718 xhi = xg3 + max( 4._r8*sx, 2._r8*dx )
1720 na = 1 + nint( (xhi-xlo)/dx )
1721 if (na .gt. naerosvmax) then
1725 9120 format( '*** subr. calc_1_impact_rate -- na > naerosvmax' )
1728 cair = press/(8.31436e7*temp)
1730 rhoair = 28.966*cair
1731 ! molecular freepath
1732 freepath = 2.8052e-10/cair
1733 ! boltzmann constant
1734 boltzmann = 1.3807e-16
1739 ! air dynamic viscosity
1740 airdynvisc = 1.8325e-4 * (416.16/(temp+120.)) * &
1741 ((temp/296.16)**1.5)
1742 ! air kinemaic viscosity
1743 airkinvisc = airdynvisc/rhoair
1744 ! ratio of water viscosity to air viscosity (from Slinn)
1750 ! compute rain drop number concentrations
1751 ! rrainsv = raindrop radius (cm)
1752 ! xnumrainsv = raindrop number concentration (#/cm^3)
1753 ! (number in the bin, not number density)
1754 ! vfallrainsv = fall velocity (cm/s)
1760 xnumrainsv(i) = exp( -r/2.7e-2 )
1763 if (d .le. 0.007) then
1764 vfallstp = 2.88e5 * d**2.
1765 else if (d .le. 0.025) then
1766 vfallstp = 2.8008e4 * d**1.528
1767 else if (d .le. 0.1) then
1768 vfallstp = 4104.9 * d**1.008
1769 else if (d .le. 0.25) then
1770 vfallstp = 1812.1 * d**0.638
1772 vfallstp = 1069.8 * d**0.235
1775 vfall = vfallstp * sqrt(1.204e-3/rhoair)
1776 vfallrainsv(i) = vfall
1777 precipsum = precipsum + vfall*(r**3)*xnumrainsv(i)
1779 precipsum = precipsum*pi*1.333333
1783 xnumrainsv(i) = xnumrainsv(i)*(precip/precipsum)
1784 rnumsum = rnumsum + xnumrainsv(i)
1788 ! compute aerosol concentrations
1789 ! aaerosv = particle radius (cm)
1790 ! fnumaerosv = fraction of total number in the bin (--)
1791 ! fvolaerosv = fraction of total volume in the bin (--)
1800 ynumaerosv(i) = exp( -0.5*dum*dum )
1801 yvolaerosv(i) = ynumaerosv(i)*1.3333*pi*a*a*a
1802 anumsum = anumsum + ynumaerosv(i)
1803 avolsum = avolsum + yvolaerosv(i)
1807 ynumaerosv(i) = ynumaerosv(i)/anumsum
1808 yvolaerosv(i) = yvolaerosv(i)/avolsum
1813 ! compute scavenging
1818 ! outer loop for rain drop radius
1823 vfall = vfallrainsv(jr)
1825 reynolds = r * vfall / airkinvisc
1826 sqrtreynolds = sqrt( reynolds )
1829 ! inner loop for aerosol particle radius
1841 dumfuchs = 1. + 1.246*dum + 0.42*dum*exp(-0.87/dum)
1842 taurelax = 2.*rhoaero*a*a*dumfuchs/(9.*rhoair*airkinvisc)
1844 aeromass = 4.*pi*a*a*a*rhoaero/3.
1845 aerodiffus = boltzmann*temp*taurelax/aeromass
1847 schmidt = airkinvisc/aerodiffus
1848 stokes = vfall*taurelax/r
1850 ebrown = 4.*(1. + 0.4*sqrtreynolds*(schmidt**0.3333333)) / &
1853 dum = (1. + 2.*xmuwaterair*chi) / &
1854 (1. + xmuwaterair/sqrtreynolds)
1855 eintercept = 4.*chi*(chi + dum)
1857 dum = log( 1. + reynolds )
1858 sstar = (1.2 + dum/12.) / (1. + dum)
1860 if (stokes .gt. sstar) then
1861 dum = stokes - sstar
1862 eimpact = (dum/(dum+0.6666667)) ** 1.5
1865 etotal = ebrown + eintercept + eimpact
1866 etotal = min( etotal, 1.0_r8 )
1868 rainsweepout = xnumrainsv(jr)*4.*pi*r*r*vfall
1870 scavsumnumbb = scavsumnumbb + rainsweepout*etotal*ynumaerosv(ja)
1871 scavsumvolbb = scavsumvolbb + rainsweepout*etotal*yvolaerosv(ja)
1875 scavsumnum = scavsumnum + scavsumnumbb
1876 scavsumvol = scavsumvol + scavsumvolbb
1879 scavratenum = scavsumnum*3600.
1880 scavratevol = scavsumvol*3600.
1885 end subroutine calc_1_impact_rate
1888 ! (defined MODAL_AERO)
1891 !-------------------------------------------------------------------
1892 !-------------------------------------------------------------------
1893 !===============================================================================
1895 function mz_prescribed_dust()
1897 ! Return true if MOZART is supplying prescribed dust.
1899 use dust_intr, only: dust_names
1900 use tracer_cnst, only: num_tracer_cnst, tracer_cnst_flds
1902 logical :: mz_prescribed_dust
1905 !-----------------------------------------------------------------------
1907 mz_prescribed_dust = .false.
1908 do i = 1, num_tracer_cnst
1909 if ( trim(tracer_cnst_flds(i)) == dust_names(1) ) then
1910 mz_prescribed_dust = .true.
1915 end function mz_prescribed_dust
1917 !===============================================================================
1920 end module mz_aerosols_intr