3 # include "../chem/MODAL_AERO_CPP_DEFINES.h"
6 # define MODAL_AERO_3MODE
8 ! Updated to CESM1.0.3 (CAM5.1.01) by Balwinder.Singh@pnnl.gov
11 !---------------------------------------------------------------------------------
13 ! CAM Interface for aerosol activation
15 ! Author: Andrew Gettelman
16 ! Based on code from: Hugh Morrison, Xiaohong Liu and Steve Ghan
18 ! Description in: Morrison and Gettelman, 2008. J. Climate (MG2008)
19 ! Gettelman et al., 2010 J. Geophys. Res. - Atmospheres (G2010)
20 ! for questions contact Andrew Gettelman (andrew@ucar.edu)
21 ! Modifications: A. Gettelman Nov 2010 - changed to support separation of
22 ! microphysics and macrophysics and concentrate aerosol information here
24 !---------------------------------------------------------------------------------
26 use shr_kind_mod, only: r8=>shr_kind_r8
28 use spmd_utils, only: masterproc
29 use ppgrid, only: pcols, pver, pverp
31 use module_cam_support, only: masterproc, pcols, pver, pverp
33 use physconst, only: gravit, rair, tmelt, cpair, rh2o, r_universal, mwh2o, rhoh2o
34 use physconst, only: latvap, latice
36 use abortutils, only: endrun
38 use module_cam_support, only: endrun
40 use error_function, only: erf,erfc
41 use wv_saturation, only: estblf, hlatv, tmin, hlatf, rgasv, pcf, cp, epsqs, ttrice, &
42 vqsatd2, vqsatd2_single,polysvp
44 use cam_history, only: addfld, add_default, phys_decomp, outfld
45 use cam_logfile, only: iulog
46 use rad_constituents, only: rad_cnst_get_info, rad_cnst_get_aer_props
47 use phys_control, only: phys_getopts
48 use cldwat2m_macro, only: rhmini, rhmaxi
50 use module_cam_support, only: addfld, add_default, phys_decomp, outfld, iulog
58 public :: ini_microp_aero, microp_aero_ts
62 logical :: wsubTKE ! If .true. (.false.), use UW's TKE (kkvh) for computing wsub
65 real(r8), private:: rn_dst1, rn_dst2, rn_dst3, rn_dst4 !dust number mean radius for contact freezing
66 real(r8), private:: pi ! pi
67 real(r8), private:: tt0 ! Freezing temperature
68 real(r8), private:: qsmall !min mixing ratio
70 real(r8), private:: r !Dry air Gas constant
75 integer, private:: psat
76 parameter (psat=6) ! number of supersaturations to calc ccn concentration
77 real(r8), private:: aten
79 real(r8), allocatable, private:: alogsig(:) ! natl log of geometric standard dev of aerosol
80 real(r8), allocatable, private:: exp45logsig(:)
81 real(r8), allocatable, private:: argfactor(:)
82 real(r8), allocatable, private:: amcube(:) ! cube of dry mode radius (m)
83 real(r8), allocatable, private:: smcrit(:) ! critical supersatuation for activation
84 real(r8), allocatable, private:: lnsm(:) ! ln(smcrit)
85 real(r8), private:: amcubesulfate(pcols) ! cube of dry mode radius (m) of sulfate
86 real(r8), private:: smcritsulfate(pcols) ! critical supersatuation for activation of sulfate
87 real(r8), allocatable, private:: amcubefactor(:) ! factors for calculating mode radius
88 real(r8), allocatable, private:: smcritfactor(:) ! factors for calculating critical supersaturation
89 real(r8), private:: super(psat)
90 real(r8), private:: alogten,alog2,alog3,alogaten
91 real(r8), private, parameter :: supersat(psat)= &! supersaturation (%) to determine ccn concentration
92 (/0.02,0.05,0.1,0.2,0.5,1.0/)
93 real(r8), allocatable, private:: ccnfact(:,:)
95 real(r8), allocatable, private:: f1(:),f2(:) ! abdul-razzak functions of width
96 real(r8), private:: third, sixth,zero
97 real(r8), private:: sq2, sqpi
99 integer :: naer_all ! number of aerosols affecting climate
100 integer :: idxsul = -1 ! index in aerosol list for sulfate
101 integer :: idxdst1 = -1 ! index in aerosol list for dust1
102 integer :: idxdst2 = -1 ! index in aerosol list for dust2
103 integer :: idxdst3 = -1 ! index in aerosol list for dust3
104 integer :: idxdst4 = -1 ! index in aerosol list for dust4
106 integer :: idxbcphi = -1 ! index in aerosol list for Soot (BCPHIL)
109 character(len=20), allocatable :: aername(:)
110 real(r8), allocatable :: dryrad_aer(:)
111 real(r8), allocatable :: density_aer(:)
112 real(r8), allocatable :: hygro_aer(:)
113 real(r8), allocatable :: dispersion_aer(:)
114 real(r8), allocatable :: num_to_mass_aer(:)
118 !===============================================================================
120 subroutine ini_microp_aero
122 !-----------------------------------------------------------------------
125 ! initialize constants for aerosols needed by microphysics
126 ! called from stratiform.F90
128 ! Author: Andrew Gettelman May 2010
130 !-----------------------------------------------------------------------
132 use ndrop, only: activate_init
133 use constituents, only: cnst_name
135 use cam_history, only: fieldname_len
136 use spmd_utils, only: masterproc
137 use modal_aero_data, only: cnst_name_cw, &
138 lmassptr_amode, lmassptrcw_amode, &
139 nspec_amode, ntot_amode, numptr_amode, numptrcw_amode, ntot_amode
141 use module_cam_support, only: fieldname_len, masterproc
142 use modal_aero_data, only: cnst_name_cw => cnst_name_cw_mp, &
143 lmassptr_amode => lmassptr_amode_mp, lmassptrcw_amode => lmassptrcw_amode_mp , &
144 nspec_amode => nspec_amode_mp , ntot_amode => ntot_amode_mp, &
145 numptr_amode => numptr_amode_mp , numptrcw_amode => numptrcw_amode_mp
148 integer :: lphase, lspec
149 character(len=fieldname_len) :: tmpname
150 character(len=fieldname_len+3) :: fieldname
151 character(128) :: long_name
153 logical :: history_aerosol ! Output the MAM aerosol tendencies
160 real(r8) surften ! surface tension of water w/respect to air (N/m)
164 character(len=16) :: eddy_scheme = ' '
165 logical :: history_microphysics ! output variables for microphysics diagnostics package
167 ! Query the PBL eddy scheme
168 call phys_getopts(eddy_scheme_out = eddy_scheme, &
169 history_microphysics_out = history_microphysics )
171 if (trim(eddy_scheme) .eq. 'diag_TKE') wsubTKE = .true.
173 history_microphysics =.FALSE.
177 ! Access the physical properties of the aerosols that are affecting the climate
178 ! by using routines from the rad_constituents module.
180 call rad_cnst_get_info(0, naero=naer_all)
183 dryrad_aer(naer_all), &
184 density_aer(naer_all), &
185 hygro_aer(naer_all), &
186 dispersion_aer(naer_all), &
187 num_to_mass_aer(naer_all) )
189 do iaer = 1, naer_all
190 call rad_cnst_get_aer_props(0, iaer, &
191 aername = aername(iaer), &
192 dryrad_aer = dryrad_aer(iaer), &
193 density_aer = density_aer(iaer), &
194 hygro_aer = hygro_aer(iaer), &
195 dispersion_aer = dispersion_aer(iaer), &
196 num_to_mass_aer = num_to_mass_aer(iaer) )
199 ! Look for sulfate aerosol in this list (Bulk aerosol only)
200 if (trim(aername(iaer)) == 'SULFATE') idxsul = iaer
201 if (trim(aername(iaer)) == 'DUST1') idxdst1 = iaer
202 if (trim(aername(iaer)) == 'DUST2') idxdst2 = iaer
203 if (trim(aername(iaer)) == 'DUST3') idxdst3 = iaer
204 if (trim(aername(iaer)) == 'DUST4') idxdst4 = iaer
205 if (trim(aername(iaer)) == 'BCPHIL') idxbcphi = iaer
208 !addfield calls for outputting aerosol number concentration
210 call addfld(aername(iaer)//'_m3', 'm-3', pver, 'A', 'aerosol number concentration', phys_decomp)
215 write(iulog,*) 'ini_micro: iaer, name, dryrad, density, hygro, dispersion, num_to_mass'
217 call wrf_message(iulog)
219 do iaer = 1, naer_all
220 write(iulog,*) iaer, aername(iaer), dryrad_aer(iaer), density_aer(iaer), hygro_aer(iaer), &
221 dispersion_aer(iaer), num_to_mass_aer(iaer)
223 call wrf_message(iulog)
227 write(iulog,*) 'ini_micro: SULFATE aerosol properties NOT FOUND'
229 call wrf_message(iulog)
232 write(iulog,*) 'ini_micro: SULFATE aerosol properties FOUND at index ',idxsul
234 call wrf_message(iulog)
239 call addfld ('CCN1 ','#/cm3 ',pver, 'A','CCN concentration at S=0.02%',phys_decomp)
240 call addfld ('CCN2 ','#/cm3 ',pver, 'A','CCN concentration at S=0.05%',phys_decomp)
241 call addfld ('CCN3 ','#/cm3 ',pver, 'A','CCN concentration at S=0.1%',phys_decomp)
242 call addfld ('CCN4 ','#/cm3 ',pver, 'A','CCN concentration at S=0.2%',phys_decomp)
243 call addfld ('CCN5 ','#/cm3 ',pver, 'A','CCN concentration at S=0.5%',phys_decomp)
244 call addfld ('CCN6 ','#/cm3 ',pver, 'A','CCN concentration at S=1.0%',phys_decomp)
246 call add_default('CCN3', 1, ' ' )
248 call addfld ('NIHF ','#/m3 ',pver, 'A','Activated Ice Number Concentation due to homogenous freezing',phys_decomp)
249 call addfld ('NIDEP ','#/m3 ',pver, 'A','Activated Ice Number Concentation due to deposition nucleation',phys_decomp)
250 call addfld ('NIIMM ','#/m3 ',pver, 'A','Activated Ice Number Concentation due to immersion freezing',phys_decomp)
251 call addfld ('NIMEY ','#/m3 ',pver, 'A','Activated Ice Number Concentation due to meyers deposition',phys_decomp)
253 ! contact freezing due to dust
254 ! dust number mean radius (m), Zender et al JGR 2003 assuming number mode radius of 0.6 micron, sigma=2
261 ! smallest mixing ratio considered in microphysics
265 ! set parameters for droplet activation, following abdul-razzak and ghan 2000, JGR
267 ! mathematical constants
273 pi=4._r8*atan(1.0_r8)
276 r= rair !Dry air Gas constant: note units(phys_constants are in J/K/kmol)
278 ! freezing temperature
279 tt0=273.15_r8 !should be tmelt
282 aten=2.*mwh2o*surften/(r_universal*tt0*rhoh2o)
286 super(:)=0.01*supersat(:)
288 allocate(alogsig(naer_all), &
289 exp45logsig(naer_all), &
290 argfactor(naer_all), &
294 amcubefactor(naer_all), &
295 smcritfactor(naer_all), &
296 ccnfact(psat,naer_all), &
301 alogsig(m)=log(dispersion_aer(m))
302 exp45logsig(m)=exp(4.5*alogsig(m)*alogsig(m))
303 argfactor(m)=2./(3.*sqrt(2.)*alogsig(m))
304 f1(m)=0.5*exp(2.5*alogsig(m)*alogsig(m))
305 f2(m)=1.+0.25*alogsig(m)
306 amcubefactor(m)=3._r8/(4._r8*pi*exp45logsig(m)*density_aer(m))
307 smcritfactor(m)=2._r8*aten*sqrt(aten/(27._r8*max(1.e-10_r8,hygro_aer(m))))
308 amcube(m)=amcubefactor(m)/(num_to_mass_aer(m))
309 if(hygro_aer(m).gt.1.e-10) then
310 smcrit(m)=smcritfactor(m)/sqrt(amcube(m))
314 lnsm(m)=log(smcrit(m))
317 arg=argfactor(m)*log(smcrit(m)/super(l))
322 ccnfact(l,m)=1.e-6_r8*0.5_r8*erfc(arg)
331 call phys_getopts( history_aerosol_out = history_aerosol)
334 ! Add dropmixnuc tendencies for all modal aerosol species
337 do lspec = 0, nspec_amode(m)+1 ! loop over number + chem constituents + water
339 if (lspec == 0) then ! number
341 if (lphase == 1) then
344 l = numptrcw_amode(m)
346 else if (lspec <= nspec_amode(m)) then ! non-water mass
347 if (lphase == 1) then
348 l = lmassptr_amode(lspec,m)
350 l = lmassptrcw_amode(lspec,m)
355 if (lphase == 1) then
356 tmpname = cnst_name(l)
358 tmpname = cnst_name_cw(l)
361 fieldname = trim(tmpname) // '_mixnuc1'
362 long_name = trim(tmpname) // ' dropmixnuc mixnuc column tendency'
363 call addfld( fieldname, unit, 1, 'A', long_name, phys_decomp )
364 if ( history_aerosol ) then
365 call add_default( fieldname, 1, ' ' )
366 if ( masterproc ) write(*,'(2a)') 'microp_driver_init addfld - ', fieldname
375 end subroutine ini_microp_aero
378 !===============================================================================
379 !activation routine for each timestep goes here...
381 subroutine microp_aero_ts ( &
382 lchnk, ncol, deltatin, t, ttend, &
384 nc, ni, p, pdel, cldn, &
386 cldo, pint, rpdel, zm, omega, &
388 qaer, cflx, qaertend, dgnumwet,dgnum, &
392 kkvh, tke, turbtype, smaw, wsub, wsubi, &
393 naai, naai_hom, npccn, rndst, nacon &
399 use wv_saturation, only: vqsatd, vqsatd_water
401 use constituents, only: pcnst
403 use module_cam_support, only: pcnst => pcnst_mp
406 use ndrop, only: dropmixnuc
408 use modal_aero_data, only:numptr_amode, modeptr_accum, modeptr_coarse, modeptr_aitken, &
409 lptr_dust_a_amode,lptr_nacl_a_amode,ntot_amode
411 use modal_aero_data, only:numptr_amode => numptr_amode_mp, modeptr_accum => modeptr_accum_mp, &
412 modeptr_coarse => modeptr_coarse_mp , modeptr_aitken => modeptr_aitken_mp, &
413 lptr_dust_a_amode => lptr_dust_a_amode_mp, lptr_nacl_a_amode => lptr_nacl_a_amode_mp, &
414 ntot_amode => ntot_amode_mp, modeptr_coardust => modeptr_coardust_mp !BSINGH - Added modeptr_coarsedust for MAM7 compliance
420 integer, intent(in) :: lchnk
421 integer, intent(in) :: ncol
422 real(r8), intent(in) :: deltatin ! time step (s)
423 real(r8), intent(in) :: t(pcols,pver) ! input temperature (K)
424 real(r8), intent(in) :: ttend(pcols,pver) ! non-microphysical temperature tendency (K/s)
425 real(r8), intent(in) :: qn(pcols,pver) ! input h20 vapor mixing ratio (kg/kg)
426 ! note: all input cloud variables are grid-averaged
427 real(r8), intent(in) :: qc(pcols,pver) ! cloud water mixing ratio (kg/kg)
428 real(r8), intent(in) :: qi(pcols,pver) ! cloud ice mixing ratio (kg/kg)
429 real(r8), intent(in) :: nc(pcols,pver) ! cloud water number conc (1/kg)
430 real(r8), intent(in) :: ni(pcols,pver) ! cloud ice number conc (1/kg)
431 real(r8), intent(in) :: p(pcols,pver) ! air pressure (pa)
432 real(r8), intent(in) :: pdel(pcols,pver) ! pressure difference across level (pa)
433 real(r8), intent(in) :: cldn(pcols,pver) ! cloud fraction
434 real(r8), intent(in) :: icecldf(pcols,pver) ! ice cloud fraction
435 real(r8), intent(in) :: liqcldf(pcols,pver) ! liquid cloud fraction
436 real(r8), intent(in) :: cldo(pcols,pver) ! old cloud fraction
437 real(r8), intent(in) :: pint(pcols,pverp) ! air pressure layer interfaces (pa)
438 real(r8), intent(in) :: rpdel(pcols,pver) ! inverse pressure difference across level (pa)
439 real(r8), intent(in) :: zm(pcols,pver) ! geopotential height of model levels (m)
440 real(r8), intent(in) :: omega(pcols,pver) ! vertical velocity (Pa/s)
442 real(r8), intent(in) :: qaer(pcols,pver,pcnst) ! aerosol number and mass mixing ratios
443 real(r8), intent(in) :: cflx(pcols,pcnst) ! constituent flux from surface
444 real(r8), intent(inout) :: qaertend(pcols,pver,pcnst) ! qaer tendency (1/s)
446 real(r8), intent(inout) :: qqcw(pcols,pver,pcnst) ! cloud-borne aerosol
448 real(r8), intent(in) :: dgnumwet(pcols,pver,ntot_amode) ! aerosol mode diameter
449 real(r8), intent(in) :: dgnum(pcols,pver,ntot_amode) ! aerosol mode dry diameter
451 real(r8), intent(in) :: aer_mmr(:,:,:) ! aerosol mass mixing ratio
453 real(r8), intent(in) :: kkvh(pcols,pver+1) ! vertical eddy diff coef (m2 s-1)
454 real(r8), intent(in) :: tke(pcols,pver+1) ! TKE from the UW PBL scheme (m2 s-2)
455 real(r8), intent(in) :: turbtype(pcols,pver+1) ! Turbulence type at each interface
456 real(r8), intent(in) :: smaw(pcols,pver+1) ! Normalized instability function of momentum. 0 <= <= 4.964 and 1 at neutral condition.
460 real(r8), intent(out) :: wsub(pcols,pver) ! diagnosed sub-grid vertical velocity st. dev. (m/s)
461 real(r8), intent(out) :: wsubi(pcols,pver) ! diagnosed sub-grid vertical velocity ice (m/s)
462 real(r8), intent(out) :: naai(pcols,pver) ! number of activated aerosol for ice nucleation
463 real(r8), intent(out) :: naai_hom(pcols,pver)! number of activated aerosol for ice nucleation (homogeneous freezing only)
464 real(r8), intent(out) :: npccn(pcols,pver) ! number of CCN (liquid activated)
465 real(r8), intent(out) :: rndst(pcols,pver,4) ! radius of 4 dust bins for contact freezing (from microp_aero_ts)
466 real(r8), intent(out) :: nacon(pcols,pver,4) ! number in 4 dust bins for contact freezing (from microp_aero_ts)
470 ! all units mks unless otherwise stated
472 real(r8) :: tkem(pcols,pver) ! Layer-mean TKE
473 real(r8) :: smm(pcols,pver) ! Layer-mean instability function
474 real(r8) :: relhum(pcols,pver) ! relative humidity
475 real(r8) :: cldm(pcols,pver) ! cloud fraction
476 real(r8) :: icldm(pcols,pver) ! ice cloud fraction
477 real(r8) :: lcldm(pcols,pver) ! liq cloud fraction
478 real(r8) :: nfice(pcols,pver) !fice variable
480 real(r8) :: qcld ! total cloud water
481 real(r8) :: lcldn(pcols,pver) ! fractional coverage of new liquid cloud
482 real(r8) :: lcldo(pcols,pver) ! fractional coverage of old liquid cloud
483 real(r8) :: nctend_mixnuc(pcols,pver)
484 real(r8) :: deltat ! sub-time step (s)
485 real(r8) :: nihf2,niimm2,nidep2,nimey2,dum2 !dummy variables for activated ice nuclei by diffferent processes
486 real(r8) arg !variable for CCN number (BAM)
488 integer ftrue ! integer used to determine cloud depth
489 real(r8) :: dum ! temporary dummy variable
491 real(r8) :: q(pcols,pver) ! water vapor mixing ratio (kg/kg)
492 ! real(r8) :: t(pcols,pver) ! temperature (K)
493 real(r8) :: ncloc(pcols,pver) ! local variable for nc
494 real(r8) :: rho(pcols,pver) ! air density (kg m-3)
495 real(r8) :: mincld ! minimum allowed cloud fraction
497 ! used in contact freezing via dust particles
498 real(r8) tcnt, viscosity, mfp
499 real(r8) slip1, slip2, slip3, slip4
500 real(r8) dfaer1, dfaer2, dfaer3, dfaer4
501 real(r8) nacon1,nacon2,nacon3,nacon4
503 real(r8) dmc,ssmc,dstrn ! variables for modal scheme.
505 ! returns from function/subroutine calls
506 real(r8) :: tsp(pcols,pver) ! saturation temp (K)
507 real(r8) :: qsp(pcols,pver) ! saturation mixing ratio (kg/kg)
508 real(r8) :: qsphy(pcols,pver) ! saturation mixing ratio (kg/kg): hybrid rh
509 real(r8) :: qs(pcols) ! liquid-ice weighted sat mixing rat (kg/kg)
510 real(r8) :: es(pcols) ! liquid-ice weighted sat vapor press (pa)
511 real(r8) :: esl(pcols,pver) ! liquid sat vapor pressure (pa)
512 real(r8) :: esi(pcols,pver) ! ice sat vapor pressure (pa)
513 real(r8) :: gammas(pcols) ! parameter for cond/evap of cloud water
515 ! new aerosol variables
516 real(r8), allocatable :: naermod(:) ! aerosol number concentration (/m3)
517 real(r8), allocatable :: naer2(:,:,:) ! new aerosol number concentration (/m3)
519 real(r8), allocatable :: maerosol(:,:) ! aerosol mass conc (kg/m3)
521 real(r8) ccn(pcols,pver,psat) ! number conc of aerosols activated at supersat
522 character*8, parameter :: ccn_name(psat)=(/'CCN1','CCN2','CCN3','CCN4','CCN5','CCN6'/)
524 !output for ice nucleation
525 real(r8) :: nimey(pcols,pver) !output number conc of ice nuclei due to meyers deposition (1/m3)
526 real(r8) :: nihf(pcols,pver) !output number conc of ice nuclei due to heterogenous freezing (1/m3)
527 real(r8) :: nidep(pcols,pver) !output number conc of ice nuclei due to deoposion nucleation (hetero nuc) (1/m3)
528 real(r8) :: niimm(pcols,pver) !output number conc of ice nuclei due to immersion freezing (hetero nuc) (1/m3)
530 ! loop array variables
531 integer i,k,nstep,n, l
533 integer, allocatable :: ntype(:)
535 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
537 ! initialize output fields for ice nucleation
538 nimey(1:ncol,1:pver)=0._r8
539 nihf(1:ncol,1:pver)=0._r8
540 nidep(1:ncol,1:pver)=0._r8
541 niimm(1:ncol,1:pver)=0._r8
544 naai(1:ncol,1:pver)=0._r8
545 naai_hom(1:ncol,1:pver)=0._r8
546 npccn(1:ncol,1:pver)=0._r8
547 nacon(1:ncol,1:pver,:)=0._r8
549 ! set default or fixed dust bins for contact freezing
550 rndst(1:ncol,1:pver,1)=rn_dst1
551 rndst(1:ncol,1:pver,2)=rn_dst2
552 rndst(1:ncol,1:pver,3)=rn_dst3
553 rndst(1:ncol,1:pver,4)=rn_dst4
556 tkem(1:ncol,1:pver)=0._r8
557 smm(1:ncol,1:pver)=0._r8
559 allocate(naermod(naer_all), &
560 naer2(pcols,pver,naer_all), &
561 maerosol(1,naer_all), &
564 ! assign variable deltat for sub-stepping...
567 ! initialize multi-level fields
568 q(1:ncol,1:pver)=qn(1:ncol,1:pver)
569 ncloc(1:ncol,1:pver)=nc(1:ncol,1:pver)
571 ! parameters for scheme
574 ! initialize time-varying parameters
578 rho(i,k)=p(i,k)/(r*t(i,k))
582 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
583 ! More refined computation of sub-grid vertical velocity
584 ! Set to be zero at the surface by initialization.
590 tkem(i,k) = 0.5_r8 * ( tke(i,k) + tke(i,k+1) )
591 smm(i,k) = 0.5_r8 * ( smaw(i,k) + smaw(i,k+1) )
592 if( turbtype(i,k) .eq. 3._r8 ) then ! Bottom entrainment interface
593 tkem(i,k) = 0.5_r8 * tke(i,k+1)
594 smm(i,k) = 0.5_r8 * smaw(i,k+1)
595 elseif( turbtype(i,k+1) .eq. 4._r8 ) then ! Top entrainment interface
596 tkem(i,k) = 0.5_r8 * tke(i,k)
597 smm(i,k) = 0.5_r8 * smaw(i,k)
599 smm(i,k) = 0.259_r8*smm(i,k)
600 smm(i,k) = max(smm(i,k), 0.4743_r8)
609 ! get sub-grid vertical velocity from diff coef.
610 ! following morrison et al. 2005, JAS
611 ! assume mixing length of 30 m
613 dum=(kkvh(i,k)+kkvh(i,k+1))/2._r8/30._r8
614 ! use maximum sub-grid vertical vel of 10 m/s
616 ! set wsub to value at current vertical level
620 wsub(i,k) = sqrt(0.5_r8*(tke(i,k)+tke(i,k+1))*(2._r8/3._r8))
621 wsub(i,k) = min(wsub(i,k),10._r8)
623 wsubi(i,k) = max(0.001_r8,wsub(i,k))
624 wsubi(i,k) = min(wsubi(i,k),0.2_r8)
625 wsub(i,k) = max(0.20_r8,wsub(i,k))
629 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
630 !Get humidity and saturation vapor pressures
634 ! find wet bulk temperature and saturation value for provisional t and q without
637 call vqsatd_water(t(1,k),p(1,k),es,qs,gammas,ncol) ! use rhw
641 esl(i,k)=polysvp(t(i,k),0)
642 esi(i,k)=polysvp(t(i,k),1)
644 ! hm fix, make sure when above freezing that esi=esl, not active yet
645 if (t(i,k).gt.tmelt)esi(i,k)=esl(i,k)
647 relhum(i,k)=q(i,k)/qs(i)
649 ! get cloud fraction, check for minimum
651 cldm(i,k)=max(cldn(i,k),mincld)
653 icldm(i,k)=max(icecldf(i,k),mincld)
654 lcldm(i,k)=max(liqcldf(i,k),mincld)
657 ! calculate nfice based on liquid and ice mmr (no rain and snow mmr available yet)
660 dumfice=qc(i,k)+qi(i,k)
661 if (dumfice.gt.qsmall .and. qi(i,k).gt.qsmall) then
662 nfice(i,k)=qi(i,k)/dumfice
669 maerosol(1,m)=aer_mmr(i,k,m)*rho(i,k)
671 ! For bulk aerosols only:
672 ! set number nucleated for sulfate based on Lohmann et al 2000 (JGR) eq 2
673 ! Na=340.*(massSO4)^0.58 where Na=cm-3 and massSO4=ug/m3
674 ! convert units to Na [m-3] and SO4 [kgm-3]
675 ! Na(m-3)= 1.e6 cm3 m-3 Na(cm-3)=340. *(massSO4[kg/m3]*1.e9ug/kg)^0.58
676 ! or Na(m-3)= 1.e6* 340.*(1.e9ug/kg)^0.58 * (massSO4[kg/m3])^0.58
678 if(m .eq. idxsul) then
679 ! naer2(i,k,m)= 5.64259e13_r8 * maerosol(1,m)**0.58
680 naer2(i,k,m)=maerosol(1,m)*num_to_mass_aer(m)*2._r8
682 naer2(i,k,m)=maerosol(1,m)*num_to_mass_aer(m)
687 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
690 if (t(i,k).lt.tmelt - 5._r8) then
693 ! get ice nucleation rate
695 call nucleati(wsubi(i,k),t(i,k),relhum(i,k),icldm(i,k),qc(i,k),nfice(i,k),rho(i,k), &
697 qaer(i,k,:)*rho(i,k),dgnum(i,k,:),1,naer_all,dum2,nihf2,niimm2,nidep2,nimey2)
699 naer2(i,k,:)/25._r8,1,naer_all,dum2,nihf2,niimm2,nidep2,nimey2)
711 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
712 !droplet activation for bulk aerosol
715 if (qc(i,k).ge.qsmall) then
717 ! get droplet activation rate
719 call activate(wsub(i,k),t(i,k),rho(i,k), &
720 naer2(i,k,:), naer_all,naer_all, maerosol, &
721 dispersion_aer,hygro_aer, density_aer, dum2)
728 !note: deltat = deltat/2. to account for sub step in microphysics
729 npccn(i,k) = (dum - nc(i,k)/lcldm(i,k))/(deltat/2._r8)*lcldm(i,k)
735 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
736 !droplet activation for modal aerosol
739 ! partition cloud fraction into liquid water part
744 if(qcld.gt.qsmall)then
745 lcldn(i,k)=cldn(i,k)*qc(i,k)/qcld
746 lcldo(i,k)=cldo(i,k)*qc(i,k)/qcld
754 call dropmixnuc(lchnk, ncol, ncloc, nctend_mixnuc, t, omega, &
755 p, pint, pdel, rpdel, zm, kkvh, wsub, lcldn, lcldo, &
756 qaer, cflx, qaertend, deltat &
762 npccn(:ncol,:)= nctend_mixnuc(:ncol,:)
766 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
767 ! Contact freezing (-40<T<-3 C) (Young, 1974) with hooks into simulated dust
768 ! estimate rndst and nanco for 4 dust bins here to pass to MG microphysics
774 if (t(i,k).lt.269.15_r8) then
777 !BSINGH - Following #if added for MAM7 compliance
778 #ifdef MODAL_AERO_7MODE
779 nacon(i,k,3)=qaer(i,k,numptr_amode(modeptr_coardust))*rho(i,k)
780 rndst(i,k,3)=0.5_r8*dgnumwet(i,k,modeptr_coardust)
781 #elif ( defined MODAL_AERO_3MODE )
782 ! For modal aerosols:
783 ! use size '3' for dust coarse mode...
784 ! scale by dust fraction in coarse mode
785 dmc= qaer(i,k,lptr_dust_a_amode(modeptr_coarse))
786 ssmc=qaer(i,k,lptr_nacl_a_amode(modeptr_coarse))
787 if (dmc.gt.0.0_r8) then
788 nacon(i,k,3)=dmc/(ssmc+dmc) * qaer(i,k,numptr_amode(modeptr_coarse))*rho(i,k) !*tcnt
793 !also redefine parameters based on size...
795 rndst(i,k,3)=0.5_r8*dgnumwet(i,k,modeptr_coarse)
797 !BSINGH - Following #endif added for MAM7 compliance
799 if (rndst(i,k,3).le.0._r8) then
805 !For Bulk Aerosols: set equal to aerosol number for dust for bins 2-4 (bin 1=0)
807 if (idxdst2.gt.0) then
808 nacon(i,k,2)=naer2(i,k,idxdst2) !*tcnt ! 1/m3
810 if (idxdst3.gt.0) then
811 nacon(i,k,3)=naer2(i,k,idxdst3) !*tcnt
813 if (idxdst4.gt.0) then
814 nacon(i,k,4)=naer2(i,k,idxdst4) ! *tcnt
821 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
822 !bulk aerosol ccn concentration (modal does it in ndrop, from dropmixnuc)
824 ! ccn concentration as diagnostic
830 ! Lohmann treatment for sulfate has variable size distribution
832 if (naer2(i,k,m).gt.0._r8) then
833 amcubesulfate(i)=amcubefactor(m)*aer_mmr(i,k,m)*rho(i,k)/(naer2(i,k,m))
834 smcritsulfate(i)=smcritfactor(m)/sqrt(amcubesulfate(i))
836 smcritsulfate(i)=1._r8
843 arg=argfactor(m)*log(smcritsulfate(i)/super(l))
846 ccnfact(l,m)=1.0e-6_r8
848 ccnfact(l,m)=0.5e-6_r8*erfc(arg)
853 ccn(i,k,l)=ccn(i,k,l)+naer2(i,k,m)*ccnfact(l,m)
856 ccn(:ncol,k,l)=ccn(:ncol,k,l)+naer2(:ncol,k,m)*ccnfact(l,m)
863 call outfld(ccn_name(l), ccn(1,1,l) , pcols, lchnk )
868 call outfld(aername(l)//'_m3', naer2(1,1,l), pcols, lchnk)
871 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
872 ! output activated liquid and ice (convert from #/kg -> #/m3)
875 nihf(i,k)=nihf(i,k)*rho(i,k)
876 niimm(i,k)=niimm(i,k)*rho(i,k)
877 nidep(i,k)=nidep(i,k)*rho(i,k)
878 nimey(i,k)=nimey(i,k)*rho(i,k)
881 call outfld('NIHF',nihf, pcols,lchnk)
882 call outfld('NIIMM',niimm, pcols,lchnk)
883 call outfld('NIDEP',nidep, pcols,lchnk)
884 call outfld('NIMEY',nimey, pcols,lchnk)
893 end subroutine microp_aero_ts
895 !##############################################################################
897 subroutine activate(wbar, tair, rhoair, &
898 na, pmode, nmode, ma, sigman, hygro, rhodry, nact)
900 ! calculates number fraction of aerosols activated as CCN
901 ! assumes an internal mixture within each of up to pmode multiple aerosol modes
902 ! a gaussiam spectrum of updrafts can be treated.
906 ! Abdul-Razzak and Ghan, A parameterization of aerosol activation.
907 ! 2. Multiple aerosol types. J. Geophys. Res., 105, 6837-6844.
909 use physconst, only: rair, epsilo, cpair, rh2o, latvap, gravit, &
910 rhoh2o, mwh2o, r_universal
911 use wv_saturation, only: estblf, epsqs
918 integer pmode,ptype ! dimension of modes, types in modes
919 real(r8) wbar ! grid cell mean vertical velocity (m/s)
920 real(r8) tair ! air temperature (K)
921 real(r8) rhoair ! air density (kg/m3)
922 real(r8) na(pmode) ! aerosol number concentration (/m3)
923 integer nmode ! number of aerosol modes
924 real(r8) ma(pmode) ! aerosol mass concentration (kg/m3)
925 real(r8) rhodry(pmode) ! density of aerosol material
927 real(r8) sigman(pmode) ! geometric standard deviation of aerosol size distribution
928 real(r8) hygro(pmode) ! hygroscopicity of aerosol mode
933 real(r8) nact ! number fraction of aerosols activated
948 integer, parameter:: nx=200
950 real(r8) surften ! surface tension of water w/respect to air (N/m)
953 real(r8) p0 ! reference pressure (Pa)
957 real(r8), allocatable :: volc(:) ! total aerosol volume concentration (m3/m3)
958 real(r8) tmass ! total aerosol mass concentration (g/cm3)
959 real(r8) rm ! number mode radius of aerosol at max supersat (cm)
960 real(r8) pres ! pressure (Pa)
961 real(r8) path ! mean free path (m)
962 real(r8) diff ! diffusivity (m2/s)
963 real(r8) conduct ! thermal conductivity (Joule/m/sec/deg)
964 real(r8) diff0,conduct0
965 real(r8) qs ! water vapor saturation mixing ratio
966 real(r8) dqsdt ! change in qs with temperature
967 real(r8) dqsdp ! change in qs with pressure
968 real(r8) gloc ! thermodynamic function (m2/s)
970 real(r8), allocatable :: eta(:)
971 real(r8), allocatable :: smc(:)
972 real(r8) lnsmax ! ln(smax)
978 real(r8) rlo,rhi,xint1,xint2,xint3,xint4
984 real(r8) xmincoeff,xcut,volcut,surfcut
985 real(r8) z,z1,z2,wf1,wf2,zf1,zf2,gf1,gf2,gf
986 real(r8) :: etafactor1,etafactor2max
987 real(r8),allocatable :: etafactor2(:)
991 real(r8),allocatable :: amcubeloc(:)
992 real(r8),allocatable :: lnsmloc(:)
999 etafactor2(maxmodes), &
1000 amcubeloc(maxmodes), &
1003 if(maxmodes<pmode)then
1004 write(iulog,*)'maxmodes,pmode in activate =',maxmodes,pmode
1006 call wrf_message(iulog)
1008 call endrun('activate')
1013 if(nmode.eq.1.and.na(1).lt.1.e-20)return
1015 if(wbar.le.0.)return
1017 pres=rair*rhoair*tair
1018 diff0=0.211e-4*(p0/pres)*(tair/tt0)**1.94
1019 conduct0=(5.69+0.017*(tair-tt0))*4.186e2*1.e-5 ! convert to J/m/s/deg
1021 qs = epsilo*es/(pres-(1.0_r8 - epsqs)*es)
1022 dqsdt=latvap/(rh2o*tair*tair)*qs
1023 alpha=gravit*(latvap/(cpair*rh2o*tair*tair)-1./(rair*tair))
1024 gammaloc=(1+latvap/cpair*dqsdt)/(rhoair*qs)
1025 ! growth coefficent Abdul-Razzak & Ghan 1998 eqn 16
1026 ! should depend on mean radius of mode to account for gas kinetic effects
1027 gloc=1./(rhoh2o/(diff0*rhoair*qs) &
1028 +latvap*rhoh2o/(conduct0*tair)*(latvap/(rh2o*tair)-1.))
1030 beta=4.*pi*rhoh2o*gloc*gammaloc
1031 etafactor2max=1.e10/(alpha*wbar)**1.5 ! this should make eta big if na is very small.
1034 ! internal mixture of aerosols
1035 volc(m)=ma(m)/(rhodry(m)) ! only if variable size dist
1036 ! pjj/cray - use TINY intrinsic
1037 ! if(volc(m).gt.1.e-39.and.na(m).gt.1.e-39)then
1038 if(volc(m).gt. TINY(volc) .and.na(m).gt. TINY(na))then
1039 etafactor2(m)=1./(na(m)*beta*sqrtg) !fixed or variable size dist
1040 ! number mode radius (m)
1041 amcubeloc(m)=(3.*volc(m)/(4.*pi*exp45logsig(m)*na(m))) ! only if variable size dist
1042 smc(m)=smcrit(m) ! only for prescribed size dist
1044 if(hygro(m).gt.1.e-10)then ! loop only if variable size dist
1045 smc(m)=2.*aten*sqrt(aten/(27.*hygro(m)*amcubeloc(m)))
1051 etafactor2(m)=etafactor2max ! this should make eta big if na is very small.
1053 lnsmloc(m)=log(smc(m)) ! only if variable size dist
1062 zeta=2.*sqrtalw*aten/(3.*sqrtg)
1063 etafactor1=2.*alw*sqrtalw
1066 eta(m)=etafactor1*etafactor2(m)
1069 call maxsat(zeta,eta,nmode,smc,smax)
1072 xmincoeff=alogaten-2.*third*(lnsmax-alog2)-alog3
1076 x=2*(lnsmloc(m)-lnsmax)/(3*sq2*alogsig(m))
1077 nact=nact+0.5*(1.-erf(x))*na(m)
1079 nact=nact/rhoair ! convert from #/m3 to #/kg
1090 end subroutine activate
1092 subroutine maxsat(zeta,eta,nmode,smc,smax)
1094 ! calculates maximum supersaturation for multiple
1095 ! competing aerosol modes.
1097 ! Abdul-Razzak and Ghan, A parameterization of aerosol activation.
1098 ! 2. Multiple aerosol types. J. Geophys. Res., 105, 6837-6844.
1103 ! parameter (pmode=naer_all)
1104 integer nmode ! number of modes
1105 real(r8) :: smc(:) ! critical supersaturation for number mode radius
1108 real(r8) smax ! maximum supersaturation
1109 integer m ! mode index
1110 real(r8) sum, g1, g2
1113 if(zeta.gt.1.e5*eta(m).or.smc(m)*smc(m).gt.1.e5*eta(m))then
1114 ! weak forcing. essentially none activated
1117 ! significant activation of this mode. calc activation all modes.
1128 if(eta(m).gt.1.e-20)then
1129 g1=sqrt(zeta/eta(m))
1131 g2=smc(m)/sqrt(eta(m)+3*zeta)
1134 sum=sum+(f1(m)*g1+f2(m)*g2)/(smc(m)*smc(m))
1144 end subroutine maxsat
1147 subroutine nucleati(wbar, tair, relhum, cldn, qc, nfice, rhoair, &
1149 qaerpt, dgnum, ptype, naer_all, nuci, onihf, oniimm, onidep, onimey)
1151 na, ptype, naer_all, nuci, onihf, oniimm, onidep, onimey)
1154 !---------------------------------------------------------------
1156 ! The parameterization of ice nucleation.
1158 ! Method: The current method is based on Liu & Penner (2005)
1159 ! It related the ice nucleation with the aerosol number, temperature and the
1160 ! updraft velocity. It includes homogeneous freezing of sulfate, immersion
1161 ! freezing of soot, and Meyers et al. (1992) deposition nucleation
1163 ! Authors: Xiaohong Liu, 01/2005, modifications by A. Gettelman 2009-2010
1164 !----------------------------------------------------------------
1167 use modal_aero_data, only:numptr_amode, modeptr_accum, modeptr_coarse, modeptr_aitken, &
1168 ntot_amode, sigmag_amode, &
1169 lptr_dust_a_amode,lptr_nacl_a_amode
1170 use constituents, only: pcnst
1172 use modal_aero_data, only:numptr_amode => numptr_amode_mp, modeptr_accum => modeptr_accum_mp, &
1173 modeptr_coarse => modeptr_coarse_mp , modeptr_aitken => modeptr_aitken_mp, &
1174 ntot_amode => ntot_amode_mp , sigmag_amode => sigmag_amode_mp, &
1175 lptr_dust_a_amode => lptr_dust_a_amode_mp, lptr_nacl_a_amode => lptr_nacl_a_amode_mp, &
1176 modeptr_coardust => modeptr_coardust_mp !BSINGH - Added modeptr_coarsedust for MAM7 compliance
1177 use module_cam_support, only: pcnst =>pcnst_mp
1181 !-----------------------------------------------------
1184 integer ptype, naer_all
1185 real(r8), intent(in) :: wbar ! grid cell mean vertical velocity (m/s)
1186 real(r8), intent(in) :: tair ! temperature (K)
1187 real(r8), intent(in) :: relhum ! relative humidity with respective to liquid
1188 real(r8), intent(in) :: cldn ! new value of cloud fraction (fraction)
1189 real(r8), intent(in) :: qc ! liquid water mixing ratio (kg/kg)
1190 real(r8), intent(in) :: nfice ! ice mass fraction
1191 real(r8), intent(in) :: rhoair ! air density (kg/m3)
1193 real(r8), intent(in) :: qaerpt(pcnst) ! aerosol number and mass mixing ratios
1194 real(r8), intent(in) :: dgnum(ntot_amode) ! aerosol mode dry diameter (m)
1196 real(r8), intent(in) :: na(naer_all) ! aerosol number concentration (/m3)
1203 real(r8), intent(out) :: nuci ! ice number nucleated (#/kg)
1204 real(r8), intent(out) :: onihf ! nucleated number from homogeneous freezing of so4
1205 real(r8), intent(out) :: oniimm ! nucleated number from immersion freezing
1206 real(r8), intent(out) :: onidep ! nucleated number from deposition nucleation
1207 real(r8), intent(out) :: onimey ! nucleated number from deposition nucleation (meyers: mixed phase)
1212 real(r8) so4_num ! so4 aerosol number (#/cm^3)
1213 real(r8) soot_num ! soot (hydrophilic) aerosol number (#/cm^3)
1214 real(r8) dst1_num,dst2_num,dst3_num,dst4_num ! dust aerosol number (#/cm^3)
1215 real(r8) dst_num ! total dust aerosol number (#/cm^3)
1216 real(r8) nihf ! nucleated number from homogeneous freezing of so4
1217 real(r8) niimm ! nucleated number from immersion freezing
1218 real(r8) nidep ! nucleated number from deposition nucleation
1219 real(r8) nimey ! nucleated number from deposition nucleation (meyers)
1220 real(r8) n1,ni ! nucleated number
1221 real(r8) tc,A,B,C,regm,RHw ! work variable
1222 real(r8) esl,esi,deles ! work variable
1225 real(r8) dmc,ssmc ! variables for modal scheme.
1235 !For modal aerosols, assume for the upper troposphere:
1236 ! soot = accumulation mode
1237 ! sulfate = aiken mode
1238 ! dust = coarse mode
1239 ! since modal has internal mixtures.
1242 soot_num = qaerpt(numptr_amode(modeptr_accum))*1.0e-6_r8 !#/cm^3
1243 !BSINGH - Following #if added for MAM7 compliance
1244 #ifdef MODAL_AERO_7MODE
1245 dst_num=qaerpt(numptr_amode(modeptr_coardust))*1.0e-6_r8 !#/cm^3
1246 #elif ( defined MODAL_AERO_3MODE )
1247 dmc= qaerpt(lptr_dust_a_amode(modeptr_coarse))
1248 ssmc=qaerpt(lptr_nacl_a_amode(modeptr_coarse))
1249 if (dmc.gt.0._r8) then
1250 dst_num=dmc/(ssmc+dmc) * qaerpt(numptr_amode(modeptr_coarse))*1.0e-6_r8 !#/cm^3
1254 !BSINGH - Following #endif added for MAM7 compliance
1256 if (dgnum(modeptr_aitken) .gt. 0._r8 ) then
1257 so4_num = qaerpt(numptr_amode(modeptr_aitken))*1.0e-6_r8 & !#/cm^3, only allow so4 with D>0.1 um in ice nucleation
1258 * (0.5_r8 - 0.5_r8*erf(log(0.1e-6_r8/dgnum(modeptr_aitken))/ &
1259 (2._r8**0.5_r8*log(sigmag_amode(modeptr_aitken)))))
1263 so4_num = max(0.0_r8,so4_num)
1265 if(idxsul .gt. 0) then
1266 so4_num=na(idxsul)*1.0e-6_r8 ! #/cm^3
1269 !continue above philosophy here....
1271 if(idxbcphi .gt. 0) then
1272 soot_num=na(idxbcphi)*1.0e-6_r8 !#/cm^3
1275 if(idxdst1 .gt. 0) then
1276 dst1_num=na(idxdst1) *1.0e-6_r8 !#/cm^3
1279 if(idxdst2 .gt. 0) then
1280 dst2_num=na(idxdst2)*1.0e-6_r8 !#/cm^3
1283 if(idxdst3 .gt. 0) then
1284 dst3_num=na(idxdst3)*1.0e-6_r8 !#/cm^3
1287 if(idxdst4 .gt. 0) then
1288 dst4_num=na(idxdst4)*1.0e-6_r8 !#/cm^3
1291 dst_num =dst1_num+dst2_num+dst3_num+dst4_num
1295 ! no soot nucleation
1306 if(so4_num.ge.1.0e-10_r8 .and. (soot_num+dst_num).ge.1.0e-10_r8 .and. cldn.gt.0._r8) then
1308 !-----------------------------
1309 ! RHw parameterization for heterogeneous immersion nucleation
1313 RHw=(A*tc*tc+B*tc+C)*0.01_r8 ! RHi ~ 120-130%
1317 if((tc.le.-35.0_r8) .and. ((relhum*polysvp(tair,0)/polysvp(tair,1)*subgrid).ge.1.2_r8)) then ! use higher RHi threshold
1319 A = -1.4938_r8 * log(soot_num+dst_num) + 12.884_r8
1320 B = -10.41_r8 * log(soot_num+dst_num) - 67.69_r8
1321 regm = A * log(wbar) + B
1323 if(tc.gt.regm) then ! heterogeneous nucleation only
1324 if(tc.lt.-40._r8 .and. wbar.gt.1._r8) then ! exclude T<-40 & W>1m/s from hetero. nucleation
1325 call hf(tc,wbar,relhum,subgrid,so4_num,nihf)
1330 call hetero(tc,wbar,soot_num+dst_num,niimm,nidep)
1334 elseif (tc.lt.regm-5._r8) then ! homogeneous nucleation only
1335 call hf(tc,wbar,relhum,subgrid,so4_num,nihf)
1339 else ! transition between homogeneous and heterogeneous: interpolate in-between
1340 if(tc.lt.-40._r8 .and. wbar.gt.1._r8) then ! exclude T<-40 & W>1m/s from hetero. nucleation
1341 call hf(tc,wbar,relhum,subgrid,so4_num,nihf)
1347 call hf(regm-5._r8,wbar,relhum,subgrid,so4_num,nihf)
1348 call hetero(regm,wbar,soot_num+dst_num,niimm,nidep)
1350 if(nihf.le.(niimm+nidep)) then
1353 n1=(niimm+nidep)*((niimm+nidep)/nihf)**((tc-regm)/5._r8)
1364 ! deposition/condensation nucleation in mixed clouds (-40<T<0C) (Meyers, 1992)
1365 if(tc.lt.0._r8 .and. tc.gt.-37._r8 .and. qc.gt.1.e-12_r8) then
1366 esl = polysvp(tair,0) ! over water in mixed clouds
1367 esi = polysvp(tair,1) ! over ice
1369 nimey=1.e-3_r8*exp(12.96_r8*deles/esi - 0.639_r8)
1375 if(nuci.gt.9999._r8.or.nuci.lt.0._r8) then
1376 write(iulog, *) 'Warning: incorrect ice nucleation number (nuci reset =0)'
1378 call wrf_message(iulog)
1380 write(iulog, *) ni, tair, relhum, wbar, nihf, niimm, nidep,deles,esi,dst2_num,dst3_num,dst4_num
1382 call wrf_message(iulog)
1387 nuci=nuci*1.e+6_r8/rhoair ! change unit from #/cm3 to #/kg
1388 onimey=nimey*1.e+6_r8/rhoair
1389 onidep=nidep*1.e+6_r8/rhoair
1390 oniimm=niimm*1.e+6_r8/rhoair
1391 onihf=nihf*1.e+6_r8/rhoair
1394 end subroutine nucleati
1396 subroutine hetero(T,ww,Ns,Nis,Nid)
1398 real(r8), intent(in) :: T, ww, Ns
1399 real(r8), intent(out) :: Nis, Nid
1401 real(r8) A11,A12,A21,A22,B11,B12,B21,B22
1404 !---------------------------------------------------------------------
1416 ! ice from immersion nucleation (cm^-3)
1418 B = (A11+B11*log(Ns)) * log(ww) + (A12+B12*log(Ns))
1421 Nis = exp(A22) * Ns**B22 * exp(B*T) * ww**C
1424 Nid = 0.0_r8 ! don't include deposition nucleation for cirrus clouds when T<-37C
1427 end subroutine hetero
1430 subroutine hf(T,ww,RH,subgrid,Na,Ni)
1432 real(r8), intent(in) :: T, ww, RH, subgrid, Na
1433 real(r8), intent(out) :: Ni
1435 real(r8) A1_fast,A21_fast,A22_fast,B1_fast,B21_fast,B22_fast
1436 real(r8) A2_fast,B2_fast
1437 real(r8) C1_fast,C2_fast,k1_fast,k2_fast
1438 real(r8) A1_slow,A2_slow,B1_slow,B2_slow,B3_slow
1439 real(r8) C1_slow,C2_slow,k1_slow,k2_slow
1444 !---------------------------------------------------------------------
1448 A21_fast =-1.6387_r8 !(T>-64 deg)
1449 A22_fast =-6.045_r8 !(T<=-64 deg)
1451 B21_fast =-0.042_r8 !(T>-64 deg)
1452 B22_fast =-0.112_r8 !(T<=-64 deg)
1466 !----------------------------
1468 A = 6.0e-4_r8*log(ww)+6.6e-3_r8
1469 B = 6.0e-2_r8*log(ww)+1.052_r8
1470 C = 1.68_r8 *log(ww)+129.35_r8
1471 RHw=(A*T*T+B*T+C)*0.01_r8
1473 if((T.le.-37.0_r8) .and. ((RH*subgrid).ge.RHw)) then
1475 regm = 6.07_r8*log(ww)-55.0_r8
1477 if(T.ge.regm) then ! fast-growth regime
1479 if(T.gt.-64.0_r8) then
1487 k1_fast = exp(A2_fast + B2_fast*T + C2_fast*log(ww))
1488 k2_fast = A1_fast+B1_fast*T+C1_fast*log(ww)
1490 Ni = k1_fast*Na**(k2_fast)
1493 else ! slow-growth regime
1495 k1_slow = exp(A2_slow + (B2_slow+B3_slow*log(ww))*T + C2_slow*log(ww))
1496 k2_slow = A1_slow+B1_slow*T+C1_slow*log(ww)
1498 Ni = k1_slow*Na**(k2_slow)
1508 !cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
1509 ! error function in single precision
1511 ! Copyright(C) 1996 Takuya OOURA (email: ooura@mmm.t.u-tokyo.ac.jp).
1512 ! You may use, copy, modify this code for any purpose and
1513 ! without fee. You may distribute this ORIGINAL package.
1515 real(r8) function derf(x)
1516 implicit real (a - h, o - z)
1517 ! pjj/cray function type
1520 dimension a(0 : 64), b(0 : 64)
1522 data (a(i), i = 0, 12) / &
1523 0.00000000005958930743d0, -0.00000000113739022964d0, &
1524 0.00000001466005199839d0, -0.00000016350354461960d0, &
1525 0.00000164610044809620d0, -0.00001492559551950604d0, &
1526 0.00012055331122299265d0, -0.00085483269811296660d0, &
1527 0.00522397762482322257d0, -0.02686617064507733420d0, &
1528 0.11283791670954881569d0, -0.37612638903183748117d0, &
1529 1.12837916709551257377d0 /
1530 data (a(i), i = 13, 25) / &
1531 0.00000000002372510631d0, -0.00000000045493253732d0, &
1532 0.00000000590362766598d0, -0.00000006642090827576d0, &
1533 0.00000067595634268133d0, -0.00000621188515924000d0, &
1534 0.00005103883009709690d0, -0.00037015410692956173d0, &
1535 0.00233307631218880978d0, -0.01254988477182192210d0, &
1536 0.05657061146827041994d0, -0.21379664776456006580d0, &
1537 0.84270079294971486929d0 /
1538 data (a(i), i = 26, 38) / &
1539 0.00000000000949905026d0, -0.00000000018310229805d0, &
1540 0.00000000239463074000d0, -0.00000002721444369609d0, &
1541 0.00000028045522331686d0, -0.00000261830022482897d0, &
1542 0.00002195455056768781d0, -0.00016358986921372656d0, &
1543 0.00107052153564110318d0, -0.00608284718113590151d0, &
1544 0.02986978465246258244d0, -0.13055593046562267625d0, &
1545 0.67493323603965504676d0 /
1546 data (a(i), i = 39, 51) / &
1547 0.00000000000382722073d0, -0.00000000007421598602d0, &
1548 0.00000000097930574080d0, -0.00000001126008898854d0, &
1549 0.00000011775134830784d0, -0.00000111992758382650d0, &
1550 0.00000962023443095201d0, -0.00007404402135070773d0, &
1551 0.00050689993654144881d0, -0.00307553051439272889d0, &
1552 0.01668977892553165586d0, -0.08548534594781312114d0, &
1553 0.56909076642393639985d0 /
1554 data (a(i), i = 52, 64) / &
1555 0.00000000000155296588d0, -0.00000000003032205868d0, &
1556 0.00000000040424830707d0, -0.00000000471135111493d0, &
1557 0.00000005011915876293d0, -0.00000048722516178974d0, &
1558 0.00000430683284629395d0, -0.00003445026145385764d0, &
1559 0.00024879276133931664d0, -0.00162940941748079288d0, &
1560 0.00988786373932350462d0, -0.05962426839442303805d0, &
1561 0.49766113250947636708d0 /
1562 data (b(i), i = 0, 12) / &
1563 -0.00000000029734388465d0, 0.00000000269776334046d0, &
1564 -0.00000000640788827665d0, -0.00000001667820132100d0, &
1565 -0.00000021854388148686d0, 0.00000266246030457984d0, &
1566 0.00001612722157047886d0, -0.00025616361025506629d0, &
1567 0.00015380842432375365d0, 0.00815533022524927908d0, &
1568 -0.01402283663896319337d0, -0.19746892495383021487d0,&
1569 0.71511720328842845913d0 /
1570 data (b(i), i = 13, 25) / &
1571 -0.00000000001951073787d0, -0.00000000032302692214d0, &
1572 0.00000000522461866919d0, 0.00000000342940918551d0, &
1573 -0.00000035772874310272d0, 0.00000019999935792654d0, &
1574 0.00002687044575042908d0, -0.00011843240273775776d0, &
1575 -0.00080991728956032271d0, 0.00661062970502241174d0, &
1576 0.00909530922354827295d0, -0.20160072778491013140d0, &
1577 0.51169696718727644908d0 /
1578 data (b(i), i = 26, 38) / &
1579 0.00000000003147682272d0, -0.00000000048465972408d0, &
1580 0.00000000063675740242d0, 0.00000003377623323271d0, &
1581 -0.00000015451139637086d0, -0.00000203340624738438d0,&
1582 0.00001947204525295057d0, 0.00002854147231653228d0, &
1583 -0.00101565063152200272d0, 0.00271187003520095655d0, &
1584 0.02328095035422810727d0, -0.16725021123116877197d0, &
1585 0.32490054966649436974d0 /
1586 data (b(i), i = 39, 51) / &
1587 0.00000000002319363370d0, -0.00000000006303206648d0, &
1588 -0.00000000264888267434d0, 0.00000002050708040581d0, &
1589 0.00000011371857327578d0, -0.00000211211337219663d0, &
1590 0.00000368797328322935d0, 0.00009823686253424796d0, &
1591 -0.00065860243990455368d0, -0.00075285814895230877d0,&
1592 0.02585434424202960464d0, -0.11637092784486193258d0, &
1593 0.18267336775296612024d0 /
1594 data (b(i), i = 52, 64) / &
1595 -0.00000000000367789363d0, 0.00000000020876046746d0, &
1596 -0.00000000193319027226d0, -0.00000000435953392472d0, &
1597 0.00000018006992266137d0, -0.00000078441223763969d0, &
1598 -0.00000675407647949153d0, 0.00008428418334440096d0, &
1599 -0.00017604388937031815d0, -0.00239729611435071610d0, &
1600 0.02064129023876022970d0, -0.06905562880005864105d0, &
1601 0.09084526782065478489d0 /
1603 if (w .lt. 2.2d0) then
1608 y = ((((((((((((a(k) * t + a(k + 1)) * t + &
1609 a(k + 2)) * t + a(k + 3)) * t + a(k + 4)) * t + &
1610 a(k + 5)) * t + a(k + 6)) * t + a(k + 7)) * t + &
1611 a(k + 8)) * t + a(k + 9)) * t + a(k + 10)) * t + &
1612 a(k + 11)) * t + a(k + 12)) * w
1613 else if (w .lt. 6.9d0) then
1617 y = (((((((((((b(k) * t + b(k + 1)) * t + &
1618 b(k + 2)) * t + b(k + 3)) * t + b(k + 4)) * t + &
1619 b(k + 5)) * t + b(k + 6)) * t + b(k + 7)) * t + &
1620 b(k + 8)) * t + b(k + 9)) * t + b(k + 10)) * t + &
1621 b(k + 11)) * t + b(k + 12)
1629 if (x .lt. 0) y = -y
1634 end module microp_aero