1 !************************************************************************
2 ! This computer software was prepared by Battelle Memorial Institute,
3 ! hereinafter the Contractor, under Contract No. DE-AC05-76RL0 1830 with
4 ! the Department of Energy (DOE). NEITHER THE GOVERNMENT NOR THE
5 ! CONTRACTOR MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY
6 ! LIABILITY FOR THE USE OF THIS SOFTWARE.
8 ! MOSAIC module: see chem/module_mosaic_driver.F for references and terms
10 !************************************************************************
12 MODULE module_mixactivate
14 PUBLIC prescribe_aerosol_mixactivate, mixactivate
18 !----------------------------------------------------------------------
19 !----------------------------------------------------------------------
20 ! 06-nov-2005 rce - grid_id & ktau added to arg list
21 ! 25-apr-2006 rce - dens_aer is (g/cm3), NOT (kg/m3)
22 subroutine prescribe_aerosol_mixactivate ( &
23 grid_id, ktau, dtstep, naer, &
24 rho_phy, th_phy, pi_phy, w, cldfra, cldfra_old, &
25 z, dz8w, p_at_w, t_at_w, exch_h, &
26 qv, qc, qi, qndrop3d, &
28 ids,ide, jds,jde, kds,kde, &
29 ims,ime, jms,jme, kms,kme, &
30 its,ite, jts,jte, kts,kte, &
33 ! USE module_configure
35 ! wrapper to call mixactivate for mosaic description of aerosol
40 integer, intent(in) :: &
42 ids, ide, jds, jde, kds, kde, &
43 ims, ime, jms, jme, kms, kme, &
44 its, ite, jts, jte, kts, kte
46 real, intent(in) :: dtstep
47 real, intent(inout) :: naer ! aerosol number (/kg)
50 dimension( ims:ime, kms:kme, jms:jme ) :: &
51 rho_phy, th_phy, pi_phy, w, &
52 z, dz8w, p_at_w, t_at_w, exch_h
54 real, intent(inout), &
55 dimension( ims:ime, kms:kme, jms:jme ) :: cldfra, cldfra_old
58 dimension( ims:ime, kms:kme, jms:jme ) :: &
61 real, intent(inout), &
62 dimension( ims:ime, kms:kme, jms:jme ) :: &
66 dimension( ims:ime, kms:kme, jms:jme) :: nsource
68 LOGICAL, OPTIONAL :: f_qc, f_qi
71 integer maxd_aphase, maxd_atype, maxd_asize, maxd_acomp, max_chem
72 parameter (maxd_aphase=2,maxd_atype=1,maxd_asize=1,maxd_acomp=1, max_chem=10)
73 real ddvel(its:ite, jts:jte, max_chem) ! dry deposition velosity
74 real qsrflx(ims:ime, jms:jme, max_chem) ! dry deposition flux of aerosol
75 real chem(ims:ime, kms:kme, jms:jme, max_chem) ! chem array
77 real hygro( its:ite, kts:kte, jts:jte, maxd_asize, maxd_atype ) ! bulk
78 integer ntype_aer, nsize_aer(maxd_atype),ncomp_aer(maxd_atype), nphase_aer
79 integer massptr_aer( maxd_acomp, maxd_asize, maxd_atype, maxd_aphase ), &
80 waterptr_aer( maxd_asize, maxd_atype ), &
81 numptr_aer( maxd_asize, maxd_atype, maxd_aphase ), &
83 real dlo_sect( maxd_asize, maxd_atype ), & ! minimum size of section (cm)
84 dhi_sect( maxd_asize, maxd_atype ), & ! maximum size of section (cm)
85 sigmag_aer(maxd_asize, maxd_atype), & ! geometric standard deviation of aerosol size dist
86 dgnum_aer(maxd_asize, maxd_atype), & ! median diameter (cm) of number distrib of mode
87 dens_aer( maxd_acomp, maxd_atype), & ! density (g/cm3) of material
88 mw_aer( maxd_acomp, maxd_atype), & ! molecular weight (g/mole)
89 dpvolmean_aer(maxd_asize, maxd_atype) ! mean-volume diameter (cm) of mode
90 ! terminology: (pi/6) * (mean-volume diameter)**3 ==
91 ! (volume mixing ratio of section/mode)/(number mixing ratio)
92 real, dimension(ims:ime,kms:kme,jms:jme) :: &
93 ccn1,ccn2,ccn3,ccn4,ccn5,ccn6 ! number conc of aerosols activated at supersat
95 real, dimension(ims:ime,kms:kme,jms:jme) :: t_phy
103 naer=1000.e6 ! #/kg default value
110 t_phy(its:ite,kts:kte,jts:jte)=th_phy(its:ite,kts:kte,jts:jte)*pi_phy(its:ite,kts:kte,jts:jte)
114 nsize_aer(n)=maxd_asize
115 ncomp_aer(n)=maxd_acomp
117 nphase_aer=maxd_aphase
119 ! set properties for each type and size
122 dlo_sect( m,n )=0.01e-4 ! minimum size of section (cm)
123 dhi_sect( m,n )=0.5e-4 ! maximum size of section (cm)
124 sigmag_aer(m,n)=2. ! geometric standard deviation of aerosol size dist
125 dgnum_aer(m,n)=0.1e-4 ! median diameter (cm) of number distrib of mode
126 dpvolmean_aer(m,n) = dgnum_aer(m,n) * exp( 1.5 * (log(sigmag_aer(m,n)))**2 )
129 dens_aer( l, n)=1.0 ! density (g/cm3) of material
130 mw_aer( l, n)=132. ! molecular weight (g/mole)
138 numptr_aer( m, n, p )=ptr
139 if(p.eq.ai_phase)then
140 chem(its:ite,kts:kte,jts:jte,ptr)=naer
142 chem(its:ite,kts:kte,jts:jte,ptr)=0.
152 if(ptr.gt.max_chem)then
153 write(6,*)'ptr,max_chem=',ptr,max_chem,' in prescribe_aerosol_mixactivate'
154 call wrf_error_fatal("1")
156 massptr_aer(l, m, n, p)=ptr
157 ! maer is ug/kg-air; naer is #/kg-air; dgnum is cm; dens_aer is g/cm3
158 ! 1.e6 factor converts g to ug
159 maer= 1.0e6 * naer * dens_aer(l,n) * ( (3.1416/6.) * &
160 (dgnum_aer(m,n)**3) * exp( 4.5*((log(sigmag_aer(m,n)))**2) ) )
161 if(p.eq.ai_phase)then
162 chem(its:ite,kts:kte,jts:jte,ptr)=maer
164 chem(its:ite,kts:kte,jts:jte,ptr)=0.
173 if(ptr.gt.max_chem)then
174 write(6,*)'ptr,max_chem=',ptr,max_chem,' in prescribe_aerosol_mixactivate'
175 call wrf_error_fatal("1")
177 !wig waterptr_aer(m, n)=ptr
178 waterptr_aer(m, n)=-1
181 ddvel(its:ite,jts:jte,:)=0.
182 hygro(its:ite,kts:kte,jts:jte,:,:) = 0.5
184 ! 06-nov-2005 rce - grid_id & ktau added to arg list
185 call mixactivate( msectional, &
186 chem,max_chem,qv,qc,qi,qndrop3d, &
187 t_phy, w, ddvel, idrydep_onoff, &
188 maxd_acomp, maxd_asize, maxd_atype, maxd_aphase, &
189 ncomp_aer, nsize_aer, ntype_aer, nphase_aer, &
190 numptr_aer, massptr_aer, dlo_sect, dhi_sect, sigmag_aer, dpvolmean_aer, &
192 waterptr_aer, hygro, ai_phase, cw_phase, &
193 ids,ide, jds,jde, kds,kde, &
194 ims,ime, jms,jme, kms,kme, &
195 its,ite, jts,jte, kts,kte, &
196 rho_phy, z, dz8w, p_at_w, t_at_w, exch_h, &
197 cldfra, cldfra_old, qsrflx, &
198 ccn1, ccn2, ccn3, ccn4, ccn5, ccn6, nsource, &
199 grid_id, ktau, dtstep, &
200 F_QC=f_qc, F_QI=f_qi )
203 end subroutine prescribe_aerosol_mixactivate
205 !----------------------------------------------------------------------
206 !----------------------------------------------------------------------
207 ! nov-04 sg ! replaced amode with aer and expanded aerosol dimension to include type and phase
209 ! 06-nov-2005 rce - grid_id & ktau added to arg list
210 ! 25-apr-2006 rce - dens_aer is (g/cm3), NOT (kg/m3)
211 subroutine mixactivate( msectional, &
212 chem, num_chem, qv, qc, qi, qndrop3d, &
213 temp, w, ddvel, idrydep_onoff, &
214 maxd_acomp, maxd_asize, maxd_atype, maxd_aphase, &
215 ncomp_aer, nsize_aer, ntype_aer, nphase_aer, &
216 numptr_aer, massptr_aer, dlo_sect, dhi_sect, sigmag_aer, dpvolmean_aer, &
218 waterptr_aer, hygro, ai_phase, cw_phase, &
219 ids,ide, jds,jde, kds,kde, &
220 ims,ime, jms,jme, kms,kme, &
221 its,ite, jts,jte, kts,kte, &
222 rho, zm, dz8w, p_at_w, t_at_w, kvh, &
223 cldfra, cldfra_old, qsrflx, &
224 ccn1, ccn2, ccn3, ccn4, ccn5, ccn6, nsource, &
225 grid_id, ktau, dtstep, &
229 ! vertical diffusion and nucleation of cloud droplets
230 ! assume cloud presence controlled by cloud fraction
231 ! doesn't distinguish between warm, cold clouds
233 USE module_model_constants, only: g, rhowater, xlv, cp, rvovrd, r_d, r_v, mwdry, ep_2
234 USE module_radiation_driver, only: cal_cldfra
240 INTEGER, intent(in) :: grid_id, ktau
241 INTEGER, intent(in) :: num_chem
242 integer, intent(in) :: ids,ide, jds,jde, kds,kde, &
243 ims,ime, jms,jme, kms,kme, &
244 its,ite, jts,jte, kts,kte
246 integer maxd_aphase, nphase_aer, maxd_atype, ntype_aer
247 integer maxd_asize, maxd_acomp, nsize_aer(maxd_atype)
248 integer, intent(in) :: &
249 ncomp_aer( maxd_atype ), &
250 massptr_aer( maxd_acomp, maxd_asize, maxd_atype, maxd_aphase ), &
251 waterptr_aer( maxd_asize, maxd_atype ), &
252 numptr_aer( maxd_asize, maxd_atype, maxd_aphase), &
254 integer, intent(in) :: msectional ! 1 for sectional, 0 for modal
255 integer, intent(in) :: idrydep_onoff
256 real, intent(in) :: &
257 dlo_sect( maxd_asize, maxd_atype ), & ! minimum size of section (cm)
258 dhi_sect( maxd_asize, maxd_atype ), & ! maximum size of section (cm)
259 sigmag_aer(maxd_asize, maxd_atype), & ! geometric standard deviation of aerosol size dist
260 dens_aer( maxd_acomp, maxd_atype), & ! density (g/cm3) of material
261 mw_aer( maxd_acomp, maxd_atype), & ! molecular weight (g/mole)
262 dpvolmean_aer(maxd_asize, maxd_atype) ! mean-volume diameter (cm) of mode
263 ! terminology: (pi/6) * (mean-volume diameter)**3 ==
264 ! (volume mixing ratio of section/mode)/(number mixing ratio)
267 REAL, intent(inout), DIMENSION( ims:ime, kms:kme, jms:jme, num_chem ) :: &
268 chem ! aerosol molar mixing ratio (ug/kg or #/kg)
270 REAL, intent(in), DIMENSION( ims:ime, kms:kme, jms:jme ) :: &
271 qv, qc, qi ! water species (vapor, cloud drops, cloud ice) mixing ratio (g/g)
273 LOGICAL, OPTIONAL :: f_qc, f_qi
275 REAL, intent(inout), DIMENSION( ims:ime, kms:kme, jms:jme ) :: &
276 qndrop3d ! water species mixing ratio (g/g)
278 real, intent(in) :: dtstep ! time step for microphysics (s)
279 real, intent(in) :: temp(ims:ime, kms:kme, jms:jme) ! temperature (K)
280 real, intent(in) :: w(ims:ime, kms:kme, jms:jme) ! vertical velocity (m/s)
281 real, intent(in) :: rho(ims:ime, kms:kme, jms:jme) ! density at mid-level (kg/m3)
282 REAL, intent(in) :: ddvel( its:ite, jts:jte, num_chem ) ! deposition velocity (m/s)
283 real, intent(in) :: zm(ims:ime, kms:kme, jms:jme) ! geopotential height of level (m)
284 real, intent(in) :: dz8w(ims:ime, kms:kme, jms:jme) ! layer thickness (m)
285 real, intent(in) :: p_at_w(ims:ime, kms:kme, jms:jme) ! pressure at layer interface (Pa)
286 real, intent(in) :: t_at_w(ims:ime, kms:kme, jms:jme) ! temperature at layer interface (K)
287 real, intent(in) :: kvh(ims:ime, kms:kme, jms:jme) ! vertical diffusivity (m2/s)
288 real, intent(inout) :: cldfra_old(ims:ime, kms:kme, jms:jme)! cloud fraction on previous time step
289 real, intent(inout) :: cldfra(ims:ime, kms:kme, jms:jme) ! cloud fraction
290 real, intent(in) :: hygro( its:ite, kts:kte, jts:jte, maxd_asize, maxd_atype ) ! bulk hygroscopicity &
292 REAL, intent(out), DIMENSION( ims:ime, jms:jme, num_chem ) :: qsrflx ! dry deposition rate for aerosol
293 real, intent(out), dimension(ims:ime,kms:kme,jms:jme) :: nsource, & ! droplet number source (#/kg/s)
294 ccn1,ccn2,ccn3,ccn4,ccn5,ccn6 ! number conc of aerosols activated at supersat
297 !--------------------Local storage-------------------------------------
299 real :: dgnum_aer(maxd_asize, maxd_atype) ! median diameter (cm) of number distrib of mode
300 real :: qndrop(kms:kme) ! cloud droplet number mixing ratio (#/kg)
301 real :: lcldfra(kms:kme) ! liquid cloud fraction
302 real :: lcldfra_old(kms:kme) ! liquid cloud fraction for previous timestep
303 real :: wtke(kms:kme) ! turbulent vertical velocity at base of layer k (m2/s)
304 real zn(kms:kme) ! g/pdel (m2/g) for layer
305 real zs(kms:kme) ! inverse of distance between levels (m)
306 real, parameter :: zkmin = 0.01
307 real, parameter :: zkmax = 100.
308 real cs(kms:kme) ! air density (kg/m3) at layer center
309 real csbot(kms:kme) ! air density (kg/m3) at layer bottom
310 real csbot_cscen(kms:kme) ! csbot(k)/cs(k)
311 real dz(kms:kme) ! geometric thickness of layers (m)
313 real wdiab ! diabatic vertical velocity
314 ! real, parameter :: wmixmin = 0.1 ! minimum turbulence vertical velocity (m/s)
315 real, parameter :: wmixmin = 0.2 ! minimum turbulence vertical velocity (m/s)
316 ! real, parameter :: wmixmin = 1.0 ! minimum turbulence vertical velocity (m/s)
317 real :: qndrop_new(kms:kme) ! droplet number nucleated on cloud boundaries
318 real :: ekd(kms:kme) ! diffusivity for droplets (m2/s)
319 real :: ekk(kms:kme) ! density*diffusivity for droplets (kg/m3 m2/s)
320 real :: srcn(kms:kme) ! droplet source rate (/s)
321 real, parameter :: sq2pi = 2.5066282746
325 real wbar,wmix,wmin,wmax
327 real tmpa, tmpb, tmpc, tmpc1, tmpc2, tmpd, tmpe, tmpf
330 real fluxntot ! (#/cm2/s)
332 real depvel_drop, depvel_tmp
333 real, parameter :: depvel_uplimit = 1.0 ! upper limit for dep vels (m/s)
334 real :: surfrate(num_chem) ! surface exchange rate (/s)
335 real surfratemax ! max surfrate for all species treated here
336 real surfrate_drop ! surfade exchange rate for droplelts
338 integer nsubmix,nsubmix_bnd
339 integer i,j,k,m,n,nsub
344 integer nnew,nsav,ntemp
345 real :: overlapp(kms:kme),overlapm(kms:kme) ! cloud overlap
346 real :: ekkp(kms:kme),ekkm(kms:kme) ! zn*zs*density*diffusivity
347 ! integer, save :: count_submix(100)=0 ! wig: Note that this is a no-no for tile threads with OMP
349 integer lnum,lnumcw,l,lmass,lmasscw,lsfc,lsfccw,ltype,lsig,lwater
350 integer :: ntype(maxd_asize)
352 real :: naerosol(maxd_asize, maxd_atype) ! interstitial aerosol number conc (/m3)
353 real :: naerosolcw(maxd_asize, maxd_atype) ! activated number conc (/m3)
354 real :: maerosol(maxd_acomp,maxd_asize, maxd_atype) ! interstit mass conc (kg/m3)
355 real :: maerosolcw(maxd_acomp,maxd_asize, maxd_atype) ! activated mass conc (kg/m3)
356 real :: maerosol_tot(maxd_asize, maxd_atype) ! species-total interstit mass conc (kg/m3)
357 real :: maerosol_totcw(maxd_asize, maxd_atype) ! species-total activated mass conc (kg/m3)
358 real :: vaerosol(maxd_asize, maxd_atype) ! interstit+activated aerosol volume conc (m3/m3)
359 real :: vaerosolcw(maxd_asize, maxd_atype) ! activated aerosol volume conc (m3/m3)
360 real :: raercol(kms:kme,num_chem,2) ! aerosol mass, number mixing ratios
361 real :: source(kms:kme) !
363 real :: fn(maxd_asize, maxd_atype) ! activation fraction for aerosol number
364 real :: fs(maxd_asize, maxd_atype) ! activation fraction for aerosol sfcarea
365 real :: fm(maxd_asize, maxd_atype) ! activation fraction for aerosol mass
366 integer :: ncomp(maxd_atype)
368 real :: fluxn(maxd_asize, maxd_atype) ! number activation fraction flux (m/s)
369 real :: fluxs(maxd_asize, maxd_atype) ! sfcarea activation fraction flux (m/s)
370 real :: fluxm(maxd_asize, maxd_atype) ! mass activation fraction flux (m/s)
371 real :: flux_fullact(kms:kme) ! 100% activation fraction flux (m/s)
372 ! note: activation fraction fluxes are defined as
373 ! fluxn = [flux of activated aero. number into cloud (#/m2/s)]
374 ! / [aero. number conc. in updraft, just below cloudbase (#/m3)]
376 real :: nact(kms:kme,maxd_asize, maxd_atype) ! fractional aero. number activation rate (/s)
377 real :: mact(kms:kme,maxd_asize, maxd_atype) ! fractional aero. mass activation rate (/s)
378 real :: npv(maxd_asize, maxd_atype) ! number per volume concentration (/m3)
381 real :: hygro_aer(maxd_asize, maxd_atype) ! hygroscopicity of aerosol mode
382 real :: exp45logsig ! exp(4.5*alogsig**2)
383 real :: alogsig(maxd_asize, maxd_atype) ! natl log of geometric standard dev of aerosol
384 integer, parameter :: psat=6 ! number of supersaturations to calc ccn concentration
385 real ccn(kts:kte,psat) ! number conc of aerosols activated at supersat
386 real, parameter :: supersat(psat)= &! supersaturation (%) to determine ccn concentration
387 (/0.02,0.05,0.1,0.2,0.5,1.0/)
388 real super(psat) ! supersaturation
389 real, parameter :: surften = 0.076 ! surface tension of water w/respect to air (N/m)
390 real :: ccnfact(psat,maxd_asize, maxd_atype)
391 real :: amcube(maxd_asize, maxd_atype) ! cube of dry mode radius (m)
392 real :: argfactor(maxd_asize, maxd_atype)
393 real aten ! surface tension parameter
394 real t0 ! reference temperature
395 real sm ! critical supersaturation
398 integer,parameter :: icheck_colmass = 0
399 ! icheck_colmass > 0 turns on mass/number conservation checking
400 ! values of 1, 10, 100 produce less to more diagnostics
401 integer :: colmass_worst_ij( 2, 0:maxd_acomp, maxd_asize, maxd_atype )
402 integer :: colmass_maxworst_i(3)
403 real :: colmass_bgn( 0:maxd_acomp, maxd_asize, maxd_atype, maxd_aphase )
404 real :: colmass_end( 0:maxd_acomp, maxd_asize, maxd_atype, maxd_aphase )
405 real :: colmass_sfc( 0:maxd_acomp, maxd_asize, maxd_atype, maxd_aphase )
406 real :: colmass_worst( 0:maxd_acomp, maxd_asize, maxd_atype )
407 real :: colmass_maxworst_r
408 real :: rhodz( kts:kte ), rhodzsum
420 character*8, parameter :: ccn_name(psat)=(/'CCN1','CCN2','CCN3','CCN4','CCN5','CCN6'/)
423 colmass_worst(:,:,:) = 0.0
424 colmass_worst_ij(:,:,:,:) = -1
428 if (abs(0.8427-ERF_ALT(arg))/0.8427>0.001) then
429 write (6,*) 'erf_alt(1.0) = ',ERF_ALT(arg)
430 call wrf_error_fatal('dropmixnuc: Error function error')
433 if (ERF_ALT(arg) /= 0.0) then
434 write (6,*) 'erf_alt(0.0) = ',ERF_ALT(arg)
435 call wrf_error_fatal('dropmixnuc: Error function error')
441 depvel_drop = 0.1 ! prescribed here rather than getting it from dry_dep_driver
442 if (idrydep_onoff .le. 0) depvel_drop = 0.0
443 depvel_drop = min(depvel_drop,depvel_uplimit)
447 ncomp(n)=ncomp_aer(n)
448 alogsig(m,n)=alog(sigmag_aer(m,n))
449 dgnum_aer(m,n) = dpvolmean_aer(m,n) * exp( -1.5*alogsig(m,n)*alogsig(m,n) )
450 ! print *,'sigmag_aer,dgnum_aer=',sigmag_aer(m,n),dgnum_aer(m,n)
451 ! npv is used only if number is diagnosed from volume
452 npv(m,n)=6./(pi*(0.01*dgnum_aer(m,n))**3*exp(4.5*alogsig(m,n)*alogsig(m,n)))
455 t0=273.15 !wig, 1-Mar-2009: Added .15
456 aten=2.*surften/(r_v*t0*rhowater)
457 super(:)=0.01*supersat(:)
460 exp45logsig=exp(4.5*alogsig(m,n)*alogsig(m,n))
461 argfactor(m,n)=2./(3.*sqrt(2.)*alogsig(m,n))
462 amcube(m,n)=3./(4.*pi*exp45logsig*npv(m,n))
466 IF( PRESENT(F_QC) .AND. PRESENT ( F_QI ) ) THEN
467 CALL cal_cldfra(CLDFRA,qc,qi,f_qc,f_qi, &
468 ids,ide, jds,jde, kds,kde, &
469 ims,ime, jms,jme, kms,kme, &
470 its,ite, jts,jte, kts,kte )
473 qsrflx(its:ite,jts:jte,:) = 0.
475 ! start loop over columns
477 OVERALL_MAIN_J_LOOP: do j=jts,jte
478 OVERALL_MAIN_I_LOOP: do i=its,ite
480 ! load number nucleated into qndrop on cloud boundaries
482 ! initialization for current i .........................................
485 zs(k)=1./(zm(i,k,j)-zm(i,k-1,j))
491 !!$ if(qndrop3d(i,k,j).lt.-10.e6.or.qndrop3d(i,k,j).gt.1.E20)then
492 !!$! call wrf_error_fatal("1")
495 qcld=qc(i,k,j)+qi(i,k,j)
499 if(qcld.lt.-1..or.qcld.gt.1.)then
500 write(6,'(a,g12.2,a,3i5)')'qcld=',qcld,' for i,k,j=',i,k,j
501 call wrf_error_fatal("1")
503 if(qcld.gt.1.e-20)then
504 lcldfra(k)=cldfra(i,k,j)*qc(i,k,j)/qcld
505 lcldfra_old(k)=cldfra_old(i,k,j)*qc(i,k,j)/qcld
510 qndrop(k)=qndrop3d(i,k,j)
512 cs(k)=rho(i,k,j) ! air density (kg/m3)
520 zn(k)=1./(cs(k)*dz(k))
523 ekd(k)=max(ekd(k),zkmin)
524 ekd(k)=min(ekd(k),zkmax)
528 ! diagnose subgrid vertical velocity from diffusivity
530 wtke(k)=sq2pi*depvel_drop
531 ! wtke(k)=sq2pi*kvh(i,k,j)
532 ! wtke(k)=max(wtke(k),wmixmin)
534 wtke(k)=sq2pi*ekd(k)/dz(k)
536 wtke(k)=max(wtke(k),wmixmin)
539 nsource(i,kte+1,j) = 0.
544 tmpa = dz(k-1) ; tmpb = dz(k)
545 tmpc = tmpa/(tmpa + tmpb)
546 csbot(k) = cs(k-1)*(1.0-tmpc) + cs(k)*tmpc
547 csbot_cscen(k) = csbot(k)/cs(k)
550 csbot_cscen(kts) = 1.0
551 csbot(kte+1) = cs(kte)
552 csbot_cscen(kte+1) = 1.0
554 ! calculate surface rate and mass mixing ratio for aerosol
559 surfrate_drop=depvel_drop/dz(kts)
560 surfratemax = max( surfratemax, surfrate_drop )
563 lnum=numptr_aer(m,n,ai_phase)
564 lnumcw=numptr_aer(m,n,cw_phase)
566 depvel_tmp = max( 0.0, min( ddvel(i,j,lnum), depvel_uplimit ) )
567 surfrate(lnum)=depvel_tmp/dz(kts)
568 surfrate(lnumcw)=surfrate_drop
569 surfratemax = max( surfratemax, surfrate(lnum) )
570 ! scale = 1000./mwdry ! moles/kg
572 raercol(kts:kte,lnumcw,nsav)=chem(i,kts:kte,j,lnumcw)*scale ! #/kg
573 raercol(kts:kte,lnum,nsav)=chem(i,kts:kte,j,lnum)*scale
576 lmass=massptr_aer(l,m,n,ai_phase)
577 lmasscw=massptr_aer(l,m,n,cw_phase)
578 ! scale = mw_aer(l,n)/mwdry
579 scale = 1.e-9 ! kg/ug
580 depvel_tmp = max( 0.0, min( ddvel(i,j,lmass), depvel_uplimit ) )
581 surfrate(lmass)=depvel_tmp/dz(kts)
582 surfrate(lmasscw)=surfrate_drop
583 surfratemax = max( surfratemax, surfrate(lmass) )
584 raercol(kts:kte,lmasscw,nsav)=chem(i,kts:kte,j,lmasscw)*scale ! kg/kg
585 raercol(kts:kte,lmass,nsav)=chem(i,kts:kte,j,lmass)*scale ! kg/kg
587 lwater=waterptr_aer(m,n)
589 depvel_tmp = max( 0.0, min( ddvel(i,j,lwater), depvel_uplimit ) )
590 surfrate(lwater)=depvel_tmp/dz(kts)
591 surfratemax = max( surfratemax, surfrate(lwater) )
592 raercol(kts:kte,lwater,nsav)=chem(i,kts:kte,j,lwater) ! don't bother to convert units,
593 ! because it doesn't contribute to aerosol mass
599 ! mass conservation checking
600 if (icheck_colmass > 0) then
602 ! calc initial column burdens
603 colmass_bgn(:,:,:,:) = 0.0
604 colmass_end(:,:,:,:) = 0.0
605 colmass_sfc(:,:,:,:) = 0.0
606 rhodz(kts:kte) = 1.0/zn(kts:kte)
607 rhodzsum = sum( rhodz(kts:kte) )
610 lnum=numptr_aer(m,n,ai_phase)
611 lnumcw=numptr_aer(m,n,cw_phase)
613 colmass_bgn(0,m,n,1) = sum( chem(i,kts:kte,j,lnum )*rhodz(kts:kte) )
614 colmass_bgn(0,m,n,2) = sum( chem(i,kts:kte,j,lnumcw)*rhodz(kts:kte) )
617 lmass=massptr_aer(l,m,n,ai_phase)
618 lmasscw=massptr_aer(l,m,n,cw_phase)
619 colmass_bgn(l,m,n,1) = sum( chem(i,kts:kte,j,lmass )*rhodz(kts:kte) )
620 colmass_bgn(l,m,n,2) = sum( chem(i,kts:kte,j,lmasscw)*rhodz(kts:kte) )
624 endif ! (icheck_colmass > 0)
627 ! droplet nucleation/aerosol activation
629 ! k-loop for growing/shrinking cloud calcs .............................
630 GROW_SHRINK_MAIN_K_LOOP: do k=kts,kte
635 ! if(lcldfra(k)-lcldfra_old(k).gt.0.01)then ! this line is the "old" criterion
639 ! upwards vertical advection when lcldfra(k-1) < lcldfra(k)
641 ! tmpc1 = cloud fraction increase from previous time step
642 tmpc1 = max( (lcldfra(k)-lcldfra_old(k)), 0.0 )
644 ! tmpc2 = fraction of layer for which vertical advection from below
645 ! (over dtstep) displaces cloudy air with clear air
646 ! = (courant number using upwards w at layer bottom)*(difference in cloud fraction)
647 tmpcourno = dtstep*max(w(i,k,j),0.0)/dz(k)
648 tmpc2 = max( (lcldfra(k)-lcldfra(km1)), 0.0 ) * tmpcourno
649 tmpc2 = min( tmpc2, 1.0 )
650 ! tmpc2 = 0.0 ! this turns off the vertical advect part
655 if ((tmpc1 > 0.001) .or. (tmpc2 > 0.001)) then
658 wbar=w(i,k,j)+wtke(k)
661 ! 06-nov-2005 rce - increase wmax from 10 to 50 (deep convective clouds)
665 ! load aerosol properties, assuming external mixtures
668 call loadaer(raercol(1,1,nsav),k,kms,kme,num_chem, &
669 cs(k), npv(m,n), dlo_sect(m,n),dhi_sect(m,n), &
670 maxd_acomp, ncomp(n), &
671 grid_id, ktau, i, j, m, n, &
672 numptr_aer(m,n,ai_phase),numptr_aer(m,n,cw_phase), &
674 massptr_aer(1,m,n,ai_phase), massptr_aer(1,m,n,cw_phase), &
675 maerosol(1,m,n), maerosolcw(1,m,n), &
676 maerosol_tot(m,n), maerosol_totcw(m,n), &
677 naerosol(m,n), naerosolcw(m,n), &
678 vaerosol(m,n), vaerosolcw(m,n) )
680 hygro_aer(m,n)=hygro(i,k,j,m,n)
684 ! 06-nov-2005 rce - grid_id & ktau added to arg list
685 call activate(wbar,wmix,wdiab,wmin,wmax,temp(i,k,j),cs(k), &
686 msectional, maxd_atype, ntype_aer, maxd_asize, nsize_aer, &
687 naerosol, vaerosol, &
688 dlo_sect,dhi_sect,sigmag_aer,hygro_aer, &
689 fn,fs,fm,fluxn,fluxs,fluxm,flux_fullact(k), grid_id, ktau, i, j, k )
692 do m = 1,nsize_aer(n)
693 lnum = numptr_aer(m,n,ai_phase)
694 lnumcw = numptr_aer(m,n,cw_phase)
695 if (tmpc1 > 0.0) then
696 dact = tmpc1*fn(m,n)*raercol(k,lnum,nsav) ! interstitial only
700 if (tmpc2 > 0.0) then
701 dact = dact + tmpc2*fn(m,n)*raercol(km1,lnum,nsav) ! interstitial only
703 dact = min( dact, 0.99*raercol(k,lnum,nsav) )
704 raercol(k,lnumcw,nsav) = raercol(k,lnumcw,nsav)+dact
705 raercol(k,lnum, nsav) = raercol(k,lnum, nsav)-dact
706 qndrop(k) = qndrop(k)+dact
707 nsource(i,k,j) = nsource(i,k,j)+dact*dtinv
709 lmass = massptr_aer(l,m,n,ai_phase)
710 lmasscw = massptr_aer(l,m,n,cw_phase)
711 if (tmpc1 > 0.0) then
712 dact = tmpc1*fm(m,n)*raercol(k,lmass,nsav) ! interstitial only
716 if (tmpc2 > 0.0) then
717 dact = dact + tmpc2*fm(m,n)*raercol(km1,lmass,nsav) ! interstitial only
719 dact = min( dact, 0.99*raercol(k,lmass,nsav) )
720 raercol(k,lmasscw,nsav) = raercol(k,lmasscw,nsav)+dact
721 raercol(k,lmass, nsav) = raercol(k,lmass, nsav)-dact
726 endif ! ((tmpc1 > 0.001) .or. (tmpc2 > 0.001))
729 if(lcldfra(k) < lcldfra_old(k) .and. lcldfra_old(k) > 1.e-20)then ! this line is the "old" criterion
732 ! shrinking cloud ......................................................
734 ! droplet loss in decaying cloud
735 nsource(i,k,j)=nsource(i,k,j)+qndrop(k)*(lcldfra(k)-lcldfra_old(k))*dtinv
736 qndrop(k)=qndrop(k)*(1.+lcldfra(k)-lcldfra_old(k))
737 ! convert activated aerosol to interstitial in decaying cloud
739 tmpc = (lcldfra(k)-lcldfra_old(k))/lcldfra_old(k)
742 lnum=numptr_aer(m,n,ai_phase)
743 lnumcw=numptr_aer(m,n,cw_phase)
745 dact=raercol(k,lnumcw,nsav)*tmpc
746 raercol(k,lnumcw,nsav)=raercol(k,lnumcw,nsav)+dact
747 raercol(k,lnum,nsav)=raercol(k,lnum,nsav)-dact
750 lmass=massptr_aer(l,m,n,ai_phase)
751 lmasscw=massptr_aer(l,m,n,cw_phase)
752 dact=raercol(k,lmasscw,nsav)*tmpc
753 raercol(k,lmasscw,nsav)=raercol(k,lmasscw,nsav)+dact
754 raercol(k,lmass,nsav)=raercol(k,lmass,nsav)-dact
761 enddo GROW_SHRINK_MAIN_K_LOOP
762 ! end of k-loop for growing/shrinking cloud calcs ......................
766 ! ......................................................................
767 ! start of main k-loop for calc of old cloud activation tendencies ..........
768 ! this loop does "set up" for the nsubmix loop
771 ! changed this part of code to use current cloud fraction (lcldfra) exclusively
773 OLD_CLOUD_MAIN_K_LOOP: do k=kts,kte
776 flux_fullact(k) = 0.0
777 if(lcldfra(k).gt.0.01)then
781 if(lcldfra(k)-lcldfra(km1).gt.0.01.or.k.eq.kts)then
787 wmix=wtke(k) ! spectrum of updrafts
788 wbar=w(i,k,j) ! spectrum of updrafts
789 ! wmix=0. ! single updraft
790 ! wbar=wtke(k) ! single updraft
791 ! 06-nov-2005 rce - increase wmax from 10 to 50 (deep convective clouds)
793 ekd(k)=wtke(k)*dz(k)/sq2pi
794 alogarg=max(1.e-20,1/lcldfra(k)-1.)
795 wmin=wbar+wmix*0.25*sq2pi*alog(alogarg)
799 call loadaer(raercol(1,1,nsav),km1,kms,kme,num_chem, &
800 cs(k), npv(m,n),dlo_sect(m,n),dhi_sect(m,n), &
801 maxd_acomp, ncomp(n), &
802 grid_id, ktau, i, j, m, n, &
803 numptr_aer(m,n,ai_phase),numptr_aer(m,n,cw_phase), &
805 massptr_aer(1,m,n,ai_phase), massptr_aer(1,m,n,cw_phase), &
806 maerosol(1,m,n), maerosolcw(1,m,n), &
807 maerosol_tot(m,n), maerosol_totcw(m,n), &
808 naerosol(m,n), naerosolcw(m,n), &
809 vaerosol(m,n), vaerosolcw(m,n) )
811 hygro_aer(m,n)=hygro(i,k,j,m,n)
815 ! print *,'old cloud wbar,wmix=',wbar,wmix
817 call activate(wbar,wmix,wdiab,wmin,wmax,temp(i,k,j),cs(k), &
818 msectional, maxd_atype, ntype_aer, maxd_asize, nsize_aer, &
819 naerosol, vaerosol, &
820 dlo_sect,dhi_sect, sigmag_aer,hygro_aer, &
821 fn,fs,fm,fluxn,fluxs,fluxm,flux_fullact(k), grid_id, ktau, i, j, k )
824 ! the activation-fraction fluxes (fluxn, fluxm) from subr activate assume that
825 ! wbar << wmix, which is valid for global-model scale but not mesoscale
826 ! for wrf-chem application, divide these by flux_fullact to get a
827 ! "flux-weighted-average" activation fraction, then multiply by (ekd(k)*zs(k))
828 ! which is the local "turbulent vertical-mixing velocity"
830 if (flux_fullact(k) > 1.0e-20) then
832 tmpf = flux_fullact(k)
835 tmpb = max( fluxn(m,n), 0.0 ) / max( fluxn(m,n), tmpf )
836 fluxn(m,n) = tmpa*tmpb
837 tmpb = max( fluxm(m,n), 0.0 ) / max( fluxm(m,n), tmpf )
838 fluxm(m,n) = tmpa*tmpb
848 tmpc = lcldfra(k)-lcldfra(km1)
853 ! flux of activated mass into layer k (in kg/m2/s)
854 ! = "actmassflux" = dumc*fluxm*raercol(kp1,lmass)*csbot(k)
855 ! source of activated mass (in kg/kg/s) = flux divergence
856 ! = actmassflux/(cs(i,k)*dz(i,k))
857 ! so need factor of csbot_cscen = csbot(k)/cs(i,k)
859 tmpe = csbot_cscen(k)/(dz(k))
863 fluxn(m,n)=fluxn(m,n)*tmpc
864 ! fluxs(m,n)=fluxs(m,n)*tmpc
865 fluxm(m,n)=fluxm(m,n)*tmpc
866 lnum=numptr_aer(m,n,ai_phase)
867 fluxntot=fluxntot+fluxn(m,n)*raercol(km1,lnum,nsav)
868 ! print *,'fn=',fn(m,n),' for m,n=',m,n
869 ! print *,'old cloud tmpc=',tmpc,' fn=',fn(m,n),' for m,n=',m,n
870 nact(k,m,n)=nact(k,m,n)+fluxn(m,n)*tmpe
871 mact(k,m,n)=mact(k,m,n)+fluxm(m,n)*tmpe
874 flux_fullact(k) = flux_fullact(k)*tmpe
875 nsource(i,k,j)=nsource(i,k,j)+fluxntot*zs(k)
876 fluxntot=fluxntot*cs(k)
883 if(qndrop(k).gt.10000.e6)then
884 print *,'i,k,j,lcldfra,qndrop=',i,k,j,lcldfra(k),qndrop(k)
885 print *,'cldfra,ql,qi',cldfra(i,k,j),qc(i,k,j),qi(i,k,j)
887 nsource(i,k,j)=nsource(i,k,j)-qndrop(k)*dtinv
889 ! convert activated aerosol to interstitial in decaying cloud
892 lnum=numptr_aer(m,n,ai_phase)
893 lnumcw=numptr_aer(m,n,cw_phase)
895 raercol(k,lnum,nsav)=raercol(k,lnum,nsav)+raercol(k,lnumcw,nsav)
896 raercol(k,lnumcw,nsav)=0.
899 lmass=massptr_aer(l,m,n,ai_phase)
900 lmasscw=massptr_aer(l,m,n,cw_phase)
901 raercol(k,lmass,nsav)=raercol(k,lmass,nsav)+raercol(k,lmasscw,nsav)
902 raercol(k,lmasscw,nsav)=0.
909 enddo OLD_CLOUD_MAIN_K_LOOP
911 ! cycle OVERALL_MAIN_I_LOOP
914 ! switch nsav, nnew so that nnew is the updated aerosol
920 ! load new droplets in layers above, below clouds
924 ! rce-comment -- ekd(k) is eddy-diffusivity at k/k-1 interface
925 ! want ekk(k) = ekd(k) * (density at k/k-1 interface)
927 ekk(k)=ekd(k)*csbot(k)
931 ekkp(k)=zn(k)*ekk(k+1)*zs(k+1)
932 ekkm(k)=zn(k)*ekk(k)*zs(k)
934 if(k.eq.kts)tinv=tinv+surfratemax
935 if(tinv.gt.1.e-6)then
941 nsubmix=dtstep/dtmix+1
947 ! count_submix(nsubmix_bnd)=count_submix(nsubmix_bnd)+1
949 fac_srflx = -1.0/(zn(1)*nsubmix)
954 if(lcldfra(kp1).gt.0)then
955 overlapp(k)=min(lcldfra(k)/lcldfra(kp1),1.)
959 if(lcldfra(km1).gt.0)then
960 overlapm(k)=min(lcldfra(k)/lcldfra(km1),1.)
968 ! ......................................................................
969 ! start of nsubmix-loop for calc of old cloud activation tendencies ....
970 OLD_CLOUD_NSUBMIX_LOOP: do nsub=1,nsubmix
971 qndrop_new(kts:kte)=qndrop(kts:kte)
972 ! switch nsav, nnew so that nsav is the updated aerosol
979 lnum=numptr_aer(m,n,ai_phase)
980 ! update droplet source
981 ! rce-comment - activation source in layer k involves particles from k-1
982 ! srcn(kts :kte)=srcn(kts :kte)+nact(kts :kte,m,n)*(raercol(kts:kte ,lnum,nsav))
983 srcn(kts+1:kte)=srcn(kts+1:kte)+nact(kts+1:kte,m,n)*(raercol(kts:kte-1,lnum,nsav))
984 ! rce-comment - new formulation for k=kts should be implemented
985 srcn(kts )=srcn(kts )+nact(kts ,m,n)*(raercol(kts ,lnum,nsav))
988 call explmix(qndrop,srcn,ekkp,ekkm,overlapp,overlapm, &
989 qndrop_new,surfrate_drop,kms,kme,kts,kte,dtmix,.false.)
992 lnum=numptr_aer(m,n,ai_phase)
993 lnumcw=numptr_aer(m,n,cw_phase)
995 ! rce-comment - activation source in layer k involves particles from k-1
996 ! source(kts :kte)= nact(kts :kte,m,n)*(raercol(kts:kte ,lnum,nsav))
997 source(kts+1:kte)= nact(kts+1:kte,m,n)*(raercol(kts:kte-1,lnum,nsav))
998 ! rce-comment - new formulation for k=kts should be implemented
999 source(kts )= nact(kts ,m,n)*(raercol(kts ,lnum,nsav))
1000 call explmix(raercol(1,lnumcw,nnew),source,ekkp,ekkm,overlapp,overlapm, &
1001 raercol(1,lnumcw,nsav),surfrate(lnumcw),kms,kme,kts,kte,dtmix,&
1003 call explmix(raercol(1,lnum,nnew),source,ekkp,ekkm,overlapp,overlapm, &
1004 raercol(1,lnum,nsav),surfrate(lnum),kms,kme,kts,kte,dtmix, &
1005 .true.,raercol(1,lnumcw,nsav))
1006 qsrflx(i,j,lnum) = qsrflx(i,j,lnum) + fac_srflx* &
1007 raercol(kts,lnum,nsav)*surfrate(lnum)
1008 qsrflx(i,j,lnumcw) = qsrflx(i,j,lnumcw) + fac_srflx* &
1009 raercol(kts,lnumcw,nsav)*surfrate(lnumcw)
1010 if (icheck_colmass > 0) then
1011 tmpf = dtmix*rhodz(kts)
1012 colmass_sfc(0,m,n,1) = colmass_sfc(0,m,n,1) &
1013 + raercol(kts,lnum ,nsav)*surfrate(lnum )*tmpf
1014 colmass_sfc(0,m,n,2) = colmass_sfc(0,m,n,2) &
1015 + raercol(kts,lnumcw,nsav)*surfrate(lnumcw)*tmpf
1019 lmass=massptr_aer(l,m,n,ai_phase)
1020 lmasscw=massptr_aer(l,m,n,cw_phase)
1021 ! rce-comment - activation source in layer k involves particles from k-1
1022 ! source(kts :kte)= mact(kts :kte,m,n)*(raercol(kts:kte ,lmass,nsav))
1023 source(kts+1:kte)= mact(kts+1:kte,m,n)*(raercol(kts:kte-1,lmass,nsav))
1024 ! rce-comment - new formulation for k=kts should be implemented
1025 source(kts )= mact(kts ,m,n)*(raercol(kts ,lmass,nsav))
1026 call explmix(raercol(1,lmasscw,nnew),source,ekkp,ekkm,overlapp,overlapm, &
1027 raercol(1,lmasscw,nsav),surfrate(lmasscw),kms,kme,kts,kte,dtmix, &
1029 call explmix(raercol(1,lmass,nnew),source,ekkp,ekkm,overlapp,overlapm, &
1030 raercol(1,lmass,nsav),surfrate(lmass),kms,kme,kts,kte,dtmix, &
1031 .true.,raercol(1,lmasscw,nsav))
1032 qsrflx(i,j,lmass) = qsrflx(i,j,lmass) + fac_srflx* &
1033 raercol(kts,lmass,nsav)*surfrate(lmass)
1034 qsrflx(i,j,lmasscw) = qsrflx(i,j,lmasscw) + fac_srflx* &
1035 raercol(kts,lmasscw,nsav)*surfrate(lmasscw)
1036 if (icheck_colmass > 0) then
1037 ! colmass_sfc calculation
1038 ! colmass_bgn/end = bgn/end column burden = sum.over.k.of{ rho(k)*dz(k)*chem(k,l) }
1039 ! colmass_sfc = surface loss over dtstep
1040 ! = sum.over.nsubmix.substeps{ depvel(l)*rho(kts)*chem(kts,l)*dtmix }
1041 ! surfrate(l) = depvel(l)/dz(kts) so need to multiply by dz(kts)
1042 ! for mass, raercol(k,l) = chem(k,l)*1.0e-9, so need to multiply by 1.0e9
1043 tmpf = dtmix*rhodz(kts)*1.0e9
1044 colmass_sfc(l,m,n,1) = colmass_sfc(l,m,n,1) &
1045 + raercol(kts,lmass ,nsav)*surfrate(lmass )*tmpf
1046 colmass_sfc(l,m,n,2) = colmass_sfc(l,m,n,2) &
1047 + raercol(kts,lmasscw,nsav)*surfrate(lmasscw)*tmpf
1050 lwater=waterptr_aer(m,n) ! aerosol water
1053 call explmix( raercol(1,lwater,nnew),source,ekkp,ekkm,overlapp,overlapm, &
1054 raercol(1,lwater,nsav),surfrate(lwater),kms,kme,kts,kte,dtmix, &
1060 enddo OLD_CLOUD_NSUBMIX_LOOP
1062 ! cycle OVERALL_MAIN_I_LOOP
1064 ! evaporate particles again if no cloud
1067 if(lcldfra(k).eq.0.)then
1072 ! convert activated aerosol to interstitial in decaying cloud
1075 lnum=numptr_aer(m,n,ai_phase)
1076 lnumcw=numptr_aer(m,n,cw_phase)
1078 raercol(k,lnum,nnew)=raercol(k,lnum,nnew)+raercol(k,lnumcw,nnew)
1079 raercol(k,lnumcw,nnew)=0.
1082 lmass=massptr_aer(l,m,n,ai_phase)
1083 lmasscw=massptr_aer(l,m,n,cw_phase)
1084 raercol(k,lmass,nnew)=raercol(k,lmass,nnew)+raercol(k,lmasscw,nnew)
1085 raercol(k,lmasscw,nnew)=0.
1092 ! cycle OVERALL_MAIN_I_LOOP
1097 ! if(lcldfra(k).gt.0.1)then
1098 ! write(6,'(a,3i5,f12.1)')'i,j,k,qndrop=',i,j,k,qndrop(k)
1100 if(qndrop(k).lt.-10.e6.or.qndrop(k).gt.1.e12)then
1101 write(6,'(a,g12.2,a,3i5)')'after qndrop=',qndrop(k),' for i,k,j=',i,k,j
1104 qndrop3d(i,k,j) = max(qndrop(k),1.e-6)
1106 if(qndrop3d(i,k,j).lt.-10.e6.or.qndrop3d(i,k,j).gt.1.E20)then
1107 write(6,'(a,g12.2,a,3i5)')'after qndrop3d=',qndrop3d(i,k,j),' for i,k,j=',i,k,j
1109 if(qc(i,k,j).lt.-1..or.qc(i,k,j).gt.1.)then
1110 write(6,'(a,g12.2,a,3i5)')'qc=',qc(i,k,j),' for i,k,j=',i,k,j
1111 call wrf_error_fatal("1")
1113 if(qi(i,k,j).lt.-1..or.qi(i,k,j).gt.1.)then
1114 write(6,'(a,g12.2,a,3i5)')'qi=',qi(i,k,j),' for i,k,j=',i,k,j
1115 call wrf_error_fatal("1")
1117 if(qv(i,k,j).lt.-1..or.qv(i,k,j).gt.1.)then
1118 write(6,'(a,g12.2,a,3i5)')'qv=',qv(i,k,j),' for i,k,j=',i,k,j
1119 call wrf_error_fatal("1")
1121 cldfra_old(i,k,j) = cldfra(i,k,j)
1122 ! if(k.gt.6.and.k.lt.11)cldfra_old(i,k,j)=1.
1125 ! cycle OVERALL_MAIN_I_LOOP
1127 ! update chem and convert back to mole/mole
1132 lnum=numptr_aer(m,n,ai_phase)
1133 lnumcw=numptr_aer(m,n,cw_phase)
1137 chem(i,kts:kte,j,lnumcw)= raercol(kts:kte,lnumcw,nnew)*scale
1138 chem(i,kts:kte,j,lnum)= raercol(kts:kte,lnum,nnew)*scale
1141 lmass=massptr_aer(l,m,n,ai_phase)
1142 lmasscw=massptr_aer(l,m,n,cw_phase)
1143 ! scale = mwdry/mw_aer(l,n)
1145 chem(i,kts:kte,j,lmasscw)=raercol(kts:kte,lmasscw,nnew)*scale ! ug/kg
1146 chem(i,kts:kte,j,lmass)=raercol(kts:kte,lmass,nnew)*scale ! ug/kg
1148 lwater=waterptr_aer(m,n)
1149 if(lwater>0)chem(i,kts:kte,j,lwater)=raercol(kts:kte,lwater,nnew) ! don't convert units
1151 sm=2.*aten*sqrt(aten/(27.*hygro(i,k,j,m,n)*amcube(m,n)))
1153 arg=argfactor(m,n)*log(sm/super(l))
1156 ccnfact(l,m,n)=1.e-6 ! convert from #/m3 to #/cm3
1158 ccnfact(l,m,n)=1.e-6*0.5*ERFC_NUM_RECIPES(arg)
1163 ! ccn concentration as diagnostic
1164 ! assume same hygroscopicity and ccnfact for cloud-phase and aerosol phase particles
1165 ccn(k,l)=ccn(k,l)+(raercol(k,lnum,nnew)+raercol(k,lnumcw,nnew))*cs(k)*ccnfact(l,m,n)
1171 !wig, 22-Nov-2006: added vertical bounds to prevent out-of-bounds at top
1172 if(l.eq.1)ccn1(i,kts:kte,j)=ccn(:,l)
1173 if(l.eq.2)ccn2(i,kts:kte,j)=ccn(:,l)
1174 if(l.eq.3)ccn3(i,kts:kte,j)=ccn(:,l)
1175 if(l.eq.4)ccn4(i,kts:kte,j)=ccn(:,l)
1176 if(l.eq.5)ccn5(i,kts:kte,j)=ccn(:,l)
1177 if(l.eq.6)ccn6(i,kts:kte,j)=ccn(:,l)
1180 ! mass conservation checking
1181 if (icheck_colmass > 0) then
1182 ! calc final column burdens
1185 lnum=numptr_aer(m,n,ai_phase)
1186 lnumcw=numptr_aer(m,n,cw_phase)
1188 colmass_end(0,m,n,1) = sum( chem(i,kts:kte,j,lnum )*rhodz(kts:kte) )
1189 colmass_end(0,m,n,2) = sum( chem(i,kts:kte,j,lnumcw)*rhodz(kts:kte) )
1192 lmass=massptr_aer(l,m,n,ai_phase)
1193 lmasscw=massptr_aer(l,m,n,cw_phase)
1194 colmass_end(l,m,n,1) = sum( chem(i,kts:kte,j,lmass )*rhodz(kts:kte) )
1195 colmass_end(l,m,n,2) = sum( chem(i,kts:kte,j,lmasscw)*rhodz(kts:kte) )
1199 ! calc burden change errors for each interstitial/activated pair
1203 ! tmpa & tmpb = beginning & ending column burden divided by rhodzsum,
1204 ! = beginning & ending column-mean mixing ratios
1205 ! tmpc = loss to surface divided by rhodzsum,
1206 tmpa = ( colmass_bgn(l,m,n,1) + colmass_bgn(l,m,n,2) )/rhodzsum
1207 tmpb = ( colmass_end(l,m,n,1) + colmass_end(l,m,n,2) )/rhodzsum
1208 tmpc = ( colmass_sfc(l,m,n,1) + colmass_sfc(l,m,n,2) )/rhodzsum
1210 ! tmpd = ((final burden) + (sfc loss)) - (initial burden)
1211 ! = burden change error
1212 tmpd = (tmpb + tmpc) - tmpa
1213 tmpe = max( tmpa, 1.0e-20 )
1215 ! tmpf = (burden change error) / (initial burden)
1216 if (abs(tmpd) < 1.0e5*tmpe) then
1218 else if (tmpf < 0.0) then
1223 if (abs(tmpf) > abs(colmass_worst(l,m,n))) then
1224 colmass_worst(l,m,n) = tmpf
1225 colmass_worst_ij(1,l,m,n) = i
1226 colmass_worst_ij(2,l,m,n) = j
1231 endif ! (icheck_colmass > 0)
1234 enddo OVERALL_MAIN_I_LOOP ! end of main loop over i
1235 enddo OVERALL_MAIN_J_LOOP ! end of main loop over j
1238 ! mass conservation checking
1239 if (icheck_colmass > 0) then
1240 if (icheck_colmass >= 100) write(*,'(a)') &
1241 'mixactivate colmass worst errors bgn - type, size, comp, err, i, j'
1242 colmass_maxworst_r = 0.0
1243 colmass_maxworst_i(:) = -1
1247 if (icheck_colmass >= 100) &
1248 write(*,'(3i3,1p,e10.2,2i4)') n, m, l, &
1249 colmass_worst(l,m,n), colmass_worst_ij(1:2,l,m,n)
1250 if (abs(colmass_worst(l,m,n)) > abs(colmass_maxworst_r)) then
1251 colmass_maxworst_r = colmass_worst(l,m,n)
1252 colmass_maxworst_i(1) = n
1253 colmass_maxworst_i(2) = m
1254 colmass_maxworst_i(3) = l
1259 if ((icheck_colmass >= 10) .or. (abs(colmass_maxworst_r) >= 1.0e-6)) &
1260 write(*,'(a,3i3,1p,e10.2)') 'mixactivate colmass maxworst', &
1261 colmass_maxworst_i(1:3), colmass_maxworst_r
1262 endif ! (icheck_colmass > 0)
1266 end subroutine mixactivate
1269 !----------------------------------------------------------------------
1270 !----------------------------------------------------------------------
1271 subroutine explmix( q, src, ekkp, ekkm, overlapp, overlapm, &
1272 qold, surfrate, kms, kme, kts, kte, dt, &
1275 ! explicit integration of droplet/aerosol mixing
1276 ! with source due to activation/nucleation
1280 integer, intent(in) :: kms,kme ! number of levels for array definition
1281 integer, intent(in) :: kts,kte ! number of levels for looping
1282 real, intent(inout) :: q(kms:kme) ! mixing ratio to be updated
1283 real, intent(in) :: qold(kms:kme) ! mixing ratio from previous time step
1284 real, intent(in) :: src(kms:kme) ! source due to activation/nucleation (/s)
1285 real, intent(in) :: ekkp(kms:kme) ! zn*zs*density*diffusivity (kg/m3 m2/s) at interface
1286 ! below layer k (k,k+1 interface)
1287 real, intent(in) :: ekkm(kms:kme) ! zn*zs*density*diffusivity (kg/m3 m2/s) at interface
1288 ! above layer k (k,k+1 interface)
1289 real, intent(in) :: overlapp(kms:kme) ! cloud overlap below
1290 real, intent(in) :: overlapm(kms:kme) ! cloud overlap above
1291 real, intent(in) :: surfrate ! surface exchange rate (/s)
1292 real, intent(in) :: dt ! time step (s)
1293 logical, intent(in) :: is_unact ! true if this is an unactivated species
1294 real, intent(in),optional :: qactold(kms:kme)
1295 ! mixing ratio of ACTIVATED species from previous step
1296 ! *** this should only be present
1297 ! if the current species is unactivated number/sfc/mass
1301 if ( is_unact ) then
1302 ! the qactold*(1-overlap) terms are resuspension of activated material
1306 q(k) = qold(k) + dt*( - src(k) + ekkp(k)*(qold(kp1) - qold(k) + &
1307 qactold(kp1)*(1.0-overlapp(k))) &
1308 + ekkm(k)*(qold(km1) - qold(k) + &
1309 qactold(km1)*(1.0-overlapm(k))) )
1310 ! if(q(k)<-1.e-30)then ! force to non-negative
1311 ! print *,'q=',q(k),' in explmix'
1320 q(k) = qold(k) + dt*(src(k) + ekkp(k)*(overlapp(k)*qold(kp1)-qold(k)) + &
1321 ekkm(k)*(overlapm(k)*qold(km1)-qold(k)) )
1322 ! if(q(k)<-1.e-30)then ! force to non-negative
1323 ! print *,'q=',q(k),' in explmix'
1329 ! dry deposition loss at base of lowest layer
1330 q(kts)=q(kts)-surfrate*qold(kts)*dt
1331 ! if(q(kts)<-1.e-30)then ! force to non-negative
1332 ! print *,'q=',q(kts),' in explmix'
1333 q(kts)=max(q(kts),0.)
1337 end subroutine explmix
1339 !----------------------------------------------------------------------
1340 !----------------------------------------------------------------------
1341 ! 06-nov-2005 rce - grid_id & ktau added to arg list
1342 subroutine activate(wbar, sigw, wdiab, wminf, wmaxf, tair, rhoair, &
1343 msectional, maxd_atype, ntype_aer, maxd_asize, nsize_aer, &
1344 na, volc, dlo_sect,dhi_sect,sigman, hygro, &
1345 fn, fs, fm, fluxn, fluxs, fluxm, flux_fullact, &
1346 grid_id, ktau, ii, jj, kk )
1348 ! calculates number, surface, and mass fraction of aerosols activated as CCN
1349 ! calculates flux of cloud droplets, surface area, and aerosol mass into cloud
1350 ! assumes an internal mixture within each of aerosol mode.
1351 ! A sectional treatment within each type is assumed if ntype_aer >7.
1352 ! A gaussiam spectrum of updrafts can be treated.
1356 ! Abdul-Razzak and Ghan, A parameterization of aerosol activation.
1357 ! 2. Multiple aerosol types. J. Geophys. Res., 105, 6837-6844.
1359 USE module_model_constants, only: g,rhowater, xlv, cp, rvovrd, r_d, r_v, &
1360 mwdry,svp1,svp2,svp3,ep_2
1367 integer,intent(in) :: maxd_atype ! dimension of types
1368 integer,intent(in) :: maxd_asize ! dimension of sizes
1369 integer,intent(in) :: ntype_aer ! number of types
1370 integer,intent(in) :: nsize_aer(maxd_atype) ! number of sizes for type
1371 integer,intent(in) :: msectional ! 1 for sectional, 0 for modal
1372 integer,intent(in) :: grid_id ! WRF grid%id
1373 integer,intent(in) :: ktau ! WRF time step count
1374 integer,intent(in) :: ii, jj, kk ! i,j,k of current grid cell
1375 real,intent(in) :: wbar ! grid cell mean vertical velocity (m/s)
1376 real,intent(in) :: sigw ! subgrid standard deviation of vertical vel (m/s)
1377 real,intent(in) :: wdiab ! diabatic vertical velocity (0 if adiabatic)
1378 real,intent(in) :: wminf ! minimum updraft velocity for integration (m/s)
1379 real,intent(in) :: wmaxf ! maximum updraft velocity for integration (m/s)
1380 real,intent(in) :: tair ! air temperature (K)
1381 real,intent(in) :: rhoair ! air density (kg/m3)
1382 real,intent(in) :: na(maxd_asize,maxd_atype) ! aerosol number concentration (/m3)
1383 real,intent(in) :: sigman(maxd_asize,maxd_atype) ! geometric standard deviation of aerosol size distribution
1384 real,intent(in) :: hygro(maxd_asize,maxd_atype) ! bulk hygroscopicity of aerosol mode
1385 real,intent(in) :: volc(maxd_asize,maxd_atype) ! total aerosol volume concentration (m3/m3)
1386 real,intent(in) :: dlo_sect( maxd_asize, maxd_atype ), & ! minimum size of section (cm)
1387 dhi_sect( maxd_asize, maxd_atype ) ! maximum size of section (cm)
1391 real,intent(inout) :: fn(maxd_asize,maxd_atype) ! number fraction of aerosols activated
1392 real,intent(inout) :: fs(maxd_asize,maxd_atype) ! surface fraction of aerosols activated
1393 real,intent(inout) :: fm(maxd_asize,maxd_atype) ! mass fraction of aerosols activated
1394 real,intent(inout) :: fluxn(maxd_asize,maxd_atype) ! flux of activated aerosol number fraction into cloud (m/s)
1395 real,intent(inout) :: fluxs(maxd_asize,maxd_atype) ! flux of activated aerosol surface fraction (m/s)
1396 real,intent(inout) :: fluxm(maxd_asize,maxd_atype) ! flux of activated aerosol mass fraction into cloud (m/s)
1397 real,intent(inout) :: flux_fullact ! flux when activation fraction = 100% (m/s)
1401 !!$ external erf,erfc
1403 ! external qsat_water
1404 integer, parameter:: nx=200
1405 integer iquasisect_option, isectional
1407 real, parameter :: surften = 0.076 ! surface tension of water w/respect to air (N/m)
1408 real, parameter :: p0 = 1013.25e2 ! reference pressure (Pa)
1409 real, parameter :: t0 = 273.15 ! reference temperature (K)
1410 real ylo(maxd_asize,maxd_atype),yhi(maxd_asize,maxd_atype) ! 1-particle volume at section interfaces
1411 real ymean(maxd_asize,maxd_atype) ! 1-particle volume at r=rmean
1412 real ycut, lnycut, betayy, betayy2, gammayy, phiyy
1413 real surfc(maxd_asize,maxd_atype) ! surface concentration (m2/m3)
1414 real sign(maxd_asize,maxd_atype) ! geometric standard deviation of size distribution
1415 real alnsign(maxd_asize,maxd_atype) ! natl log of geometric standard dev of aerosol
1416 real am(maxd_asize,maxd_atype) ! number mode radius of dry aerosol (m)
1417 real lnhygro(maxd_asize,maxd_atype) ! ln(b)
1418 real f1(maxd_asize,maxd_atype) ! array to hold parameter for maxsat
1419 real pres ! pressure (Pa)
1420 real path ! mean free path (m)
1421 real diff ! diffusivity (m2/s)
1422 real conduct ! thermal conductivity (Joule/m/sec/deg)
1424 real es ! saturation vapor pressure
1425 real qs ! water vapor saturation mixing ratio
1426 real dqsdt ! change in qs with temperature
1427 real dqsdp ! change in qs with pressure
1428 real gg ! thermodynamic function (m2/s)
1429 real sqrtg ! sqrt(gg)
1430 real sm(maxd_asize,maxd_atype) ! critical supersaturation for number mode radius
1431 real lnsm(maxd_asize,maxd_atype) ! ln( sm )
1432 real zeta, eta(maxd_asize,maxd_atype)
1433 real lnsmax ! ln(smax)
1438 logical :: top ! true if cloud top, false if cloud base or new cloud
1439 real asub(maxd_asize,maxd_atype),bsub(maxd_asize,maxd_atype) ! coefficients of submode size distribution N=a+bx
1440 real totn(maxd_atype) ! total aerosol number concentration
1441 real aten ! surface tension parameter
1442 real gmrad(maxd_atype) ! geometric mean radius
1443 real gmradsq(maxd_atype) ! geometric mean of radius squared
1444 real gmlnsig(maxd_atype) ! geometric standard deviation
1445 real gmsm(maxd_atype) ! critical supersaturation at radius gmrad
1446 real sumflxn(maxd_asize,maxd_atype)
1447 real sumflxs(maxd_asize,maxd_atype)
1448 real sumflxm(maxd_asize,maxd_atype)
1450 real sumfn(maxd_asize,maxd_atype)
1451 real sumfs(maxd_asize,maxd_atype)
1452 real sumfm(maxd_asize,maxd_atype)
1453 real sumns(maxd_atype)
1454 real fnold(maxd_asize,maxd_atype) ! number fraction activated
1455 real fsold(maxd_asize,maxd_atype) ! surface fraction activated
1456 real fmold(maxd_asize,maxd_atype) ! mass fraction activated
1458 real alogten,alog2,alog3,alogaten
1460 real rlo(maxd_asize,maxd_atype), rhi(maxd_asize,maxd_atype)
1461 real rmean(maxd_asize,maxd_atype)
1462 ! mean radius (m) for the section (not used with modal)
1463 ! calculated from current volume & number
1466 real wmin,wmax,w,dw,dwmax,dwmin,wnuc,dwnew,wb
1467 real dfmin,dfmax,fnew,fold,fnmin,fnbar,fsbar,fmbar
1472 real z,z1,z2,wf1,wf2,zf1,zf2,gf1,gf2,gf
1473 real etafactor1,etafactor2(maxd_asize,maxd_atype),etafactor2max
1474 integer m,n,nw,nwmax
1476 ! numerical integration parameters
1477 real, parameter :: eps = 0.3
1478 real, parameter :: fmax = 0.99
1479 real, parameter :: sds = 3.
1481 ! mathematical constants
1482 real third, twothird, sixth, zero, one, two, three
1484 real, parameter :: sq2 = 1.4142135624
1485 real, parameter :: sqpi = 1.7724538509
1486 real, parameter :: pi = 3.1415926536
1488 ! integer, save :: ndist(nx) ! accumulates frequency distribution of integration bins required
1491 ! for nsize_aer>7, a sectional approach is used and isectional = iquasisect_option
1492 ! activation fractions (fn,fs,fm) are computed as follows
1493 ! iquasisect_option = 1,3 - each section treated as a narrow lognormal
1494 ! iquasisect_option = 2,4 - within-section dn/dx = a + b*x, x = ln(r)
1495 ! smax is computed as follows (when explicit activation is OFF)
1496 ! iquasisect_option = 1,2 - razzak-ghan modal parameterization with
1497 ! single mode having same ntot, dgnum, sigmag as the combined sections
1498 ! iquasisect_option = 3,4 - razzak-ghan sectional parameterization
1499 ! for nsize_aer=<9, a modal approach is used and isectional = 0
1502 ! if either (na(n,m) < nsmall) or (volc(n,m) < vsmall)
1503 ! then treat bin/mode (n,m) as being empty, and set its fn/fs/fm=0.0
1504 ! (for single precision, gradual underflow starts around 1.0e-38,
1505 ! and strange things can happen when in that region)
1506 real, parameter :: nsmall = 1.0e-20 ! aer number conc in #/m3
1507 real, parameter :: vsmall = 1.0e-37 ! aer volume conc in m3/m3
1508 logical bin_is_empty(maxd_asize,maxd_atype), all_bins_empty
1509 logical bin_is_narrow(maxd_asize,maxd_atype)
1511 integer idiagaa, ipass_nwloop
1512 integer idiag_dndy_neg, idiag_fnsm_prob
1514 ! The flag for cloud top is no longer used so set it to false. This is an
1515 ! antiquated feature related to radiation enhancing mass fluxes at cloud
1516 ! top. It is currently, as of Feb. 2009, set to false in the CAM version
1520 !.......................................................................
1522 ! start calc. of modal or sectional activation properties (start of section 1)
1524 !.......................................................................
1525 idiag_dndy_neg = 1 ! set this to 0 to turn off
1526 ! warnings about dn/dy < 0
1527 idiag_fnsm_prob = 1 ! set this to 0 to turn off
1528 ! warnings about fn/fs/fm misbehavior
1530 iquasisect_option = 2
1531 if(msectional.gt.0)then
1532 isectional = iquasisect_option
1538 ! print *,'ntype_aer,n,nsize_aer(n)=',ntype_aer,n,nsize_aer(n)
1540 if(ntype_aer.eq.1.and.nsize_aer(n).eq.1.and.na(1,1).lt.1.e-20)then
1557 twothird = 2.0/3.0 !wig, 1-Mar-2009: Corrected value from 2/6
1560 pres=r_d*rhoair*tair
1561 diff0=0.211e-4*(p0/pres)*(tair/t0)**1.94
1562 conduct0=(5.69+0.017*(tair-t0))*4.186e2*1.e-5 ! convert to J/m/s/deg
1563 es=1000.*svp1*exp( svp2*(tair-t0)/(tair-svp3) )
1564 qs=ep_2*es/(pres-es)
1565 dqsdt=xlv/(r_v*tair*tair)*qs
1566 alpha=g*(xlv/(cp*r_v*tair*tair)-1./(r_d*tair))
1567 gamma=(1+xlv/cp*dqsdt)/(rhoair*qs)
1568 gg=1./(rhowater/(diff0*rhoair*qs)+xlv*rhowater/(conduct0*tair)*(xlv/(r_v*tair)-1.))
1570 beta=4.*pi*rhowater*gg*gamma
1571 aten=2.*surften/(r_v*tair*rhowater)
1576 etafactor2max=1.e10/(alpha*wmaxf)**1.5 ! this should make eta big if na is very small.
1578 all_bins_empty = .true.
1585 alnsign(m,n)=log(sigman(m,n))
1586 ! internal mixture of aerosols
1588 bin_is_empty(m,n) = .true.
1589 if (volc(m,n).gt.vsmall .and. na(m,n).gt.nsmall) then
1590 bin_is_empty(m,n) = .false.
1591 all_bins_empty = .false.
1592 lnhygro(m,n)=log(hygro(m,n))
1593 ! number mode radius (m,n)
1594 ! write(6,*)'alnsign,volc,na=',alnsign(m,n),volc(m,n),na(m,n)
1595 am(m,n)=exp(-1.5*alnsign(m,n)*alnsign(m,n))* &
1596 (3.*volc(m,n)/(4.*pi*na(m,n)))**third
1598 if (isectional .gt. 0) then
1600 ! need to use bulk properties because parameterization doesn't
1601 ! work well for narrow bins.
1602 totn(n)=totn(n)+na(m,n)
1604 gmrad(n)=gmrad(n)+na(m,n)*alogam
1605 gmradsq(n)=gmradsq(n)+na(m,n)*alogam*alogam
1607 etafactor2(m,n)=1./(na(m,n)*beta*sqrtg)
1609 if(hygro(m,n).gt.1.e-10)then
1610 sm(m,n)=2.*aten/(3.*am(m,n))*sqrt(aten/(3.*hygro(m,n)*am(m,n)))
1614 ! write(6,*)'sm,hygro,am=',sm(m,n),hygro(m,n),am(m,n)
1617 etafactor2(m,n)=etafactor2max ! this should make eta big if na is very small.
1620 lnsm(m,n)=log(sm(m,n))
1621 if ((isectional .eq. 3) .or. (isectional .eq. 4)) then
1622 sumns(n)=sumns(n)+na(m,n)/sm(m,n)**twothird
1624 ! write(6,'(a,i4,6g12.2)')'m,na,am,hygro,lnhygro,sm,lnsm=',m,na(m,n),am(m,n),hygro(m,n),lnhygro(m,n),sm(m,n),lnsm(m,n)
1628 ! if all bins are empty, set all activation fractions to zero and exit
1629 if ( all_bins_empty ) then
1646 if (isectional .le. 0) then
1647 ! Initialize maxsat at this cell and timestep for the
1648 ! modal setup (the sectional case is handled below).
1649 call maxsat_init(maxd_atype, ntype_aer, &
1650 maxd_asize, nsize_aer, alnsign, f1)
1656 !wig 19-Oct-2006: Add zero trap based May 2006 e-mail from
1657 !Ghan. Transport can clear out a cell leading to
1658 !inconsistencies with the mass.
1659 gmrad(n)=gmrad(n)/max(totn(n),1e-20)
1660 gmlnsig=gmradsq(n)/totn(n)-gmrad(n)*gmrad(n) ! [ln(sigmag)]**2
1661 gmlnsig(n)=sqrt( max( 1.e-4, gmlnsig(n) ) )
1662 gmrad(n)=exp(gmrad(n))
1663 if ((isectional .eq. 3) .or. (isectional .eq. 4)) then
1664 gmsm(n)=totn(n)/sumns(n)
1665 gmsm(n)=gmsm(n)*gmsm(n)*gmsm(n)
1666 gmsm(n)=sqrt(gmsm(n))
1668 ! gmsm(n)=2.*aten/(3.*gmrad(n))*sqrt(aten/(3.*hygro(1,n)*gmrad(n)))
1669 gmsm(n)=2.*aten/(3.*gmrad(n))*sqrt(aten/(3.*hygro(nsize_aer(n),n)*gmrad(n)))
1673 ! Initialize maxsat at this cell and timestep for the
1674 ! sectional setup (the modal case is handled above)...
1675 call maxsat_init(maxd_atype, ntype_aer, &
1676 maxd_asize, (/1/), gmlnsig, f1)
1678 !.......................................................................
1679 ! calculate sectional "sub-bin" size distribution
1681 ! dn/dy = nt*( a + b*y ) for ylo < y < yhi
1683 ! nt = na(m,n) = number mixing ratio of the bin
1685 ! v = (4pi/3)*r**3 = particle volume
1686 ! vhi = v at r=rhi (upper bin boundary)
1687 ! ylo = y at lower bin boundary = vlo/vhi = (rlo/rhi)**3
1688 ! yhi = y at upper bin boundary = 1.0
1690 ! dv/dy = v * dn/dy = nt*vhi*( a*y + b*y*y )
1692 !.......................................................................
1693 ! 02-may-2006 - this dn/dy replaces the previous
1694 ! dn/dx = a + b*x where l = ln(r)
1695 ! the old dn/dx was overly complicated for cases of rmean near rlo or rhi
1696 ! the new dn/dy is consistent with that used in the movesect routine,
1697 ! which does continuous growth by condensation and aqueous chemistry
1698 !.......................................................................
1699 do 25002 n = 1,ntype_aer
1700 do 25000 m = 1,nsize_aer(n)
1702 ! convert from diameter in cm to radius in m
1703 rlo(m,n) = 0.5*0.01*dlo_sect(m,n)
1704 rhi(m,n) = 0.5*0.01*dhi_sect(m,n)
1705 ylo(m,n) = (rlo(m,n)/rhi(m,n))**3
1708 ! 04-nov-2005 - extremely narrow bins will be treated using 0/1 activation
1709 ! this is to avoid potential numerical problems
1710 bin_is_narrow(m,n) = .false.
1711 if ((rhi(m,n)/rlo(m,n)) .le. 1.01) bin_is_narrow(m,n) = .true.
1713 ! rmean is mass mean radius for the bin; xmean = log(rmean)
1714 ! just use section midpoint if bin is empty
1715 if ( bin_is_empty(m,n) ) then
1716 rmean(m,n) = sqrt(rlo(m,n)*rhi(m,n))
1717 ymean(m,n) = (rmean(m,n)/rhi(m,n))**3
1721 rmean(m,n) = (volc(m,n)/(ccc*na(m,n)))**third
1722 rmean(m,n) = max( rlo(m,n), min( rhi(m,n), rmean(m,n) ) )
1723 ymean(m,n) = (rmean(m,n)/rhi(m,n))**3
1724 if ( bin_is_narrow(m,n) ) goto 25000
1726 ! if rmean is extremely close to either rlo or rhi,
1727 ! treat the bin as extremely narrow
1728 if ((rhi(m,n)/rmean(m,n)) .le. 1.01) then
1729 bin_is_narrow(m,n) = .true.
1730 rlo(m,n) = min( rmean(m,n), (rhi(m,n)/1.01) )
1731 ylo(m,n) = (rlo(m,n)/rhi(m,n))**3
1733 else if ((rmean(m,n)/rlo(m,n)) .le. 1.01) then
1734 bin_is_narrow(m,n) = .true.
1735 rhi(m,n) = max( rmean(m,n), (rlo(m,n)*1.01) )
1736 ylo(m,n) = (rlo(m,n)/rhi(m,n))**3
1737 ymean(m,n) = (rmean(m,n)/rhi(m,n))**3
1741 ! if rmean is somewhat close to either rlo or rhi, then dn/dy will be
1742 ! negative near the upper or lower bin boundary
1743 ! in these cases, assume that all the particles are in a subset of the full bin,
1744 ! and adjust rlo or rhi so that rmean will be near the center of this subset
1745 ! note that the bin is made narrower LOCALLY/TEMPORARILY,
1746 ! just for the purposes of the activation calculation
1747 gammayy = (ymean(m,n)-ylo(m,n)) / (yhi(m,n)-ylo(m,n))
1748 if (gammayy .lt. 0.34) then
1749 dumaa = ylo(m,n) + (yhi(m,n)-ylo(m,n))*(gammayy/0.34)
1750 rhi(m,n) = rhi(m,n)*(dumaa**third)
1751 ylo(m,n) = (rlo(m,n)/rhi(m,n))**3
1752 ymean(m,n) = (rmean(m,n)/rhi(m,n))**3
1753 else if (gammayy .ge. 0.66) then
1754 dumaa = ylo(m,n) + (yhi(m,n)-ylo(m,n))*((gammayy-0.66)/0.34)
1756 rlo(m,n) = rhi(m,n)*(dumaa**third)
1758 if ((rhi(m,n)/rlo(m,n)) .le. 1.01) then
1759 bin_is_narrow(m,n) = .true.
1763 betayy = ylo(m,n)/yhi(m,n)
1764 betayy2 = betayy*betayy
1765 bsub(m,n) = (12.0*ymean(m,n) - 6.0*(1.0+betayy)) / &
1766 (4.0*(1.0-betayy2*betayy) - 3.0*(1.0-betayy2)*(1.0+betayy))
1767 asub(m,n) = (1.0 - bsub(m,n)*(1.0-betayy2)*0.5) / (1.0-betayy)
1769 if ( asub(m,n)+bsub(m,n)*ylo(m,n) .lt. 0. ) then
1770 if (idiag_dndy_neg .gt. 0) then
1771 print *,'dndy<0 at lower boundary'
1773 print *,'na=',na(m,n),' volc=',volc(m,n)
1774 print *,'volc/(na*pi*4/3)=', (volc(m,n)/(na(m,n)*ccc))
1775 print *,'rlo(m,n),rhi(m,n)=',rlo(m,n),rhi(m,n)
1776 print *,'dlo_sect/2,dhi_sect/2=', &
1777 (0.005*dlo_sect(m,n)),(0.005*dhi_sect(m,n))
1778 print *,'asub,bsub,ylo,yhi=',asub(m,n),bsub(m,n),ylo(m,n),yhi(m,n)
1779 print *,'asub+bsub*ylo=', &
1780 (asub(m,n)+bsub(m,n)*ylo(m,n))
1781 print *,'subr activate error 11 - i,j,k =', ii, jj, kk
1784 if ( asub(m,n)+bsub(m,n)*yhi(m,n) .lt. 0. ) then
1785 if (idiag_dndy_neg .gt. 0) then
1786 print *,'dndy<0 at upper boundary'
1788 print *,'na=',na(m,n),' volc=',volc(m,n)
1789 print *,'volc/(na*pi*4/3)=', (volc(m,n)/(na(m,n)*ccc))
1790 print *,'rlo(m,n),rhi(m,n)=',rlo(m,n),rhi(m,n)
1791 print *,'dlo_sect/2,dhi_sect/2=', &
1792 (0.005*dlo_sect(m,n)),(0.005*dhi_sect(m,n))
1793 print *,'asub,bsub,ylo,yhi=',asub(m,n),bsub(m,n),ylo(m,n),yhi(m,n)
1794 print *,'asub+bsub*yhi=', &
1795 (asub(m,n)+bsub(m,n)*yhi(m,n))
1796 print *,'subr activate error 12 - i,j,k =', ii, jj, kk
1800 25000 continue ! m=1,nsize_aer(n)
1801 25002 continue ! n=1,ntype_aer
1805 !.......................................................................
1807 ! end calc. of modal or sectional activation properties (end of section 1)
1809 !.......................................................................
1813 ! sjg 7-16-98 upward
1814 ! print *,'wbar,sigw=',wbar,sigw
1816 if(sigw.le.1.e-5) goto 50000
1818 !.......................................................................
1820 ! start calc. of activation fractions/fluxes
1821 ! for spectrum of updrafts (start of section 2)
1823 !.......................................................................
1826 ! 06-nov-2005 rce - set idiagaa=1 for testing/debugging
1827 ! if ((grid_id.eq.1) .and. (ktau.eq.167) .and. &
1828 ! (ii.eq.24) .and. (jj.eq. 1) .and. (kk.eq.14)) idiagaa = 1
1833 wmin=min(zero,-wdiab)
1835 wmax=min(wmaxf,wbar+sds*sigw)
1836 wmin=max(wminf,-wdiab)
1838 wmin=max(wmin,wbar-sds*sigw)
1875 ! 06-nov-2005 rce - set wold=w here
1880 ! 06-nov-2005 rce - define nwmax; calc dwmin from nwmax
1882 ! dwmin = min( dwmax, 0.01 )
1883 dwmin = (wmax - wmin)/(nwmax-1)
1884 dwmin = min( dwmax, dwmin )
1885 dwmin = max( 0.01, dwmin )
1888 ! loop over updrafts, incrementing sums as you go
1889 ! the "200" is (arbitrary) upper limit for number of updrafts
1890 ! if integration finishes before this, OK; otherwise, ERROR
1892 if (idiagaa.gt.0) then
1893 write(*,94700) ktau, grid_id, ii, jj, kk, nwmax
1894 write(*,94710) 'wbar,sigw,wdiab=', wbar, sigw, wdiab
1895 write(*,94710) 'wmin,wmax,dwmin,dwmax=', wmin, wmax, dwmin, dwmax
1896 write(*,94720) -1, w, wold, dw
1898 94700 format( / 'activate 47000 - ktau,id,ii,jj,kk,nwmax=', 6i5 )
1899 94710 format( 'activate 47000 - ', a, 6(1x,f11.5) )
1900 94720 format( 'activate 47000 - nw,w,wold,dw=', i5, 3(1x,f11.5) )
1902 do 47000 nw = 1, nwmax
1905 if (idiagaa.gt.0) write(*,94720) nw, w, wold, dw
1907 ! write(6,*)'wnuc=',wnuc
1910 zeta=2.*sqrtalw*aten/(3.*sqrtg)
1911 etafactor1=2.*alw*sqrtalw
1912 if (isectional .gt. 0) then
1914 ! use bulk properties
1917 if(totn(n).gt.1.e-10)then
1918 eta(1,n)=etafactor1/(totn(n)*beta*sqrtg)
1923 call maxsat(zeta,eta,maxd_atype,ntype_aer, &
1924 maxd_asize,(/1/),gmsm,gmlnsig,f1,smax)
1926 x=2*(log(gmsm(1))-lnsmax)/(3*sq2*gmlnsig(1))
1927 fnew=0.5*(1.-ERF_ALT(x))
1933 eta(m,n)=etafactor1*etafactor2(m,n)
1937 call maxsat(zeta,eta,maxd_atype,ntype_aer, &
1938 maxd_asize,nsize_aer,sm,alnsign,f1,smax)
1939 ! write(6,*)'w,smax=',w,smax
1943 x=2*(lnsm(nsize_aer(1),1)-lnsmax)/(3*sq2*alnsign(nsize_aer(1),1))
1944 fnew=0.5*(1.-ERF_ALT(x))
1949 ! 06-nov-2005 rce - "n" here should be "nw" (?)
1950 ! if(fnew-fold.gt.dfmax.and.n.gt.1)then
1951 if(fnew-fold.gt.dfmax.and.nw.gt.1)then
1952 ! reduce updraft increment for greater accuracy in integration
1953 if (dw .gt. 1.01*dwmin) then
1963 if(fnew-fold.lt.dfmin)then
1964 ! increase updraft increment to accelerate integration
1965 dwnew=min(1.5*dw,dwmax)
1969 z=(w-wbar)/(sigw*sq2)
1972 xmincoeff=alogaten-2.*third*(lnsmax-alog2)-alog3
1973 ! write(6,*)'xmincoeff=',xmincoeff
1976 do 44002 n=1,ntype_aer
1977 do 44000 m=1,nsize_aer(n)
1978 if ( bin_is_empty(m,n) ) then
1982 else if ((isectional .eq. 2) .or. (isectional .eq. 4)) then
1984 ! within-section dn/dx = a + b*x
1985 xcut=xmincoeff-third*lnhygro(m,n)
1986 ! ycut=(exp(xcut)/rhi(m,n))**3
1987 ! 07-jul-2006 rce - the above line gave a (rare) overflow when smax=1.0e-20
1988 ! if (ycut > yhi), then actual value of ycut is unimportant,
1989 ! so do the following to avoid overflow
1990 lnycut = 3.0 * ( xcut - log(rhi(m,n)) )
1991 lnycut = min( lnycut, log(yhi(m,n)*1.0e5) )
1993 ! write(6,*)'m,n,rcut,rlo,rhi=',m,n,exp(xcut),rlo(m,n),rhi(m,n)
1994 ! if(lnsmax.lt.lnsmn(m,n))then
1995 if(ycut.gt.yhi(m,n))then
1999 elseif(ycut.lt.ylo(m,n))then
2003 elseif ( bin_is_narrow(m,n) ) then
2004 ! 04-nov-2005 rce - for extremely narrow bins,
2005 ! do zero activation if xcut>xmean, 100% activation otherwise
2006 if (ycut.gt.ymean(m,n)) then
2017 fn(m,n) = asub(m,n)*(1.0-phiyy) + 0.5*bsub(m,n)*(1.0-phiyy*phiyy)
2018 if (fn(m,n).lt.zero .or. fn(m,n).gt.one) then
2019 if (idiag_fnsm_prob .gt. 0) then
2020 print *,'fn(',m,n,')=',fn(m,n),' outside 0,1 - activate err21'
2021 print *,'na,volc =', na(m,n), volc(m,n)
2022 print *,'asub,bsub =', asub(m,n), bsub(m,n)
2023 print *,'yhi,ycut =', yhi(m,n), ycut
2027 if (fn(m,n) .le. zero) then
2028 ! 10-nov-2005 rce - if fn=0, then fs & fm must be 0
2032 else if (fn(m,n) .ge. one) then
2033 ! 10-nov-2005 rce - if fn=1, then fs & fm must be 1
2038 ! 10-nov-2005 rce - otherwise, calc fm and check it
2039 fm(m,n) = (yhi(m,n)/ymean(m,n)) * (0.5*asub(m,n)*(1.0-phiyy*phiyy) + &
2040 third*bsub(m,n)*(1.0-phiyy*phiyy*phiyy))
2041 if (fm(m,n).lt.fn(m,n) .or. fm(m,n).gt.one) then
2042 if (idiag_fnsm_prob .gt. 0) then
2043 print *,'fm(',m,n,')=',fm(m,n),' outside fn,1 - activate err22'
2044 print *,'na,volc,fn =', na(m,n), volc(m,n), fn(m,n)
2045 print *,'asub,bsub =', asub(m,n), bsub(m,n)
2046 print *,'yhi,ycut =', yhi(m,n), ycut
2049 if (fm(m,n) .le. fn(m,n)) then
2050 ! 10-nov-2005 rce - if fm=fn, then fs must =fn
2053 else if (fm(m,n) .ge. one) then
2054 ! 10-nov-2005 rce - if fm=1, then fs & fn must be 1
2059 ! 10-nov-2005 rce - these two checks assure that the mean size
2060 ! of the activated & interstitial particles will be between rlo & rhi
2061 dumaa = fn(m,n)*(yhi(m,n)/ymean(m,n))
2062 fm(m,n) = min( fm(m,n), dumaa )
2063 dumaa = 1.0 + (fn(m,n)-1.0)*(ylo(m,n)/ymean(m,n))
2064 fm(m,n) = min( fm(m,n), dumaa )
2065 ! 10-nov-2005 rce - now calculate fs and bound it by fn, fm
2066 betayy = ylo(m,n)/yhi(m,n)
2067 dumaa = phiyy**twothird
2068 dumbb = betayy**twothird
2070 (asub(m,n)*(1.0-phiyy*dumaa) + &
2071 0.625*bsub(m,n)*(1.0-phiyy*phiyy*dumaa)) / &
2072 (asub(m,n)*(1.0-betayy*dumbb) + &
2073 0.625*bsub(m,n)*(1.0-betayy*betayy*dumbb))
2074 fs(m,n)=max(fs(m,n),fn(m,n))
2075 fs(m,n)=min(fs(m,n),fm(m,n))
2082 x=2*(lnsm(m,n)-lnsmax)/(3*sq2*alnsign(m,n))
2083 fn(m,n)=0.5*(1.-ERF_ALT(x))
2084 arg=x-sq2*alnsign(m,n)
2085 fs(m,n)=0.5*(1.-ERF_ALT(arg))
2086 arg=x-1.5*sq2*alnsign(m,n)
2087 fm(m,n)=0.5*(1.-ERF_ALT(arg))
2088 ! print *,'w,x,fn,fs,fm=',w,x,fn(m,n),fs(m,n),fm(m,n)
2094 fnmin=min(fn(m,n),fnmin)
2095 ! integration is second order accurate
2096 ! assumes linear variation of f*gaus with w
2098 fnbar=(fn(m,n)*gaus+fnold(m,n)*gold)
2099 fsbar=(fs(m,n)*gaus+fsold(m,n)*gold)
2100 fmbar=(fm(m,n)*gaus+fmold(m,n)*gold)
2101 if((top.and.w.lt.0.).or.(.not.top.and.w.gt.0.))then
2102 sumflxn(m,n)=sumflxn(m,n)+sixth*(wb*fnbar &
2103 +(fn(m,n)*gaus*w+fnold(m,n)*gold*wold))*dw
2104 sumflxs(m,n)=sumflxs(m,n)+sixth*(wb*fsbar &
2105 +(fs(m,n)*gaus*w+fsold(m,n)*gold*wold))*dw
2106 sumflxm(m,n)=sumflxm(m,n)+sixth*(wb*fmbar &
2107 +(fm(m,n)*gaus*w+fmold(m,n)*gold*wold))*dw
2109 sumfn(m,n)=sumfn(m,n)+0.5*fnbar*dw
2110 ! write(6,'(a,9g10.2)')'lnsmax,lnsm(m,n),x,fn(m,n),fnold(m,n),g,gold,fnbar,dw=', &
2111 ! lnsmax,lnsm(m,n),x,fn(m,n),fnold(m,n),g,gold,fnbar,dw
2113 sumfs(m,n)=sumfs(m,n)+0.5*fsbar*dw
2115 sumfm(m,n)=sumfm(m,n)+0.5*fmbar*dw
2118 44000 continue ! m=1,nsize_aer(n)
2119 44002 continue ! n=1,ntype_aer
2121 ! same form as sumflxm(m,n) but replace the fm/fmold(m,n) with 1.0
2122 sumflx_fullact = sumflx_fullact &
2123 + sixth*(wb*(gaus+gold) + (gaus*w + gold*wold))*dw
2124 ! sumg=sumg+0.5*(gaus+gold)*dw
2129 if(nw.gt.1.and.(w.gt.wmax.or.fnmin.gt.fmax))go to 48000
2132 47000 continue ! nw = 1, nwmax
2135 print *,'do loop is too short in activate'
2136 print *,'wmin=',wmin,' w=',w,' wmax=',wmax,' dw=',dw
2137 print *,'wbar=',wbar,' sigw=',sigw,' wdiab=',wdiab
2138 print *,'wnuc=',wnuc
2141 print *,'na=',(na(m,n),m=1,nsize_aer(n))
2142 print *,'fn=',(fn(m,n),m=1,nsize_aer(n))
2144 ! dump all subr parameters to allow testing with standalone code
2145 ! (build a driver that will read input and call activate)
2146 print *,'top,wbar,sigw,wdiab,tair,rhoair,ntype_aer='
2147 print *, top,wbar,sigw,wdiab,tair,rhoair,ntype_aer
2157 print *,'subr activate error 31 - i,j,k =', ii, jj, kk
2158 ! 06-nov-2005 rce - if integration fails, repeat it once with additional diagnostics
2159 if (ipass_nwloop .eq. 1) then
2164 call wrf_error_fatal("STOP: activate before 48000")
2169 ! ndist(n)=ndist(n)+1
2170 if(.not.top.and.w.lt.wmaxf)then
2172 ! contribution from all updrafts stronger than wmax
2173 ! assuming constant f (close to fmax)
2176 z1=(w-wbar)/(sigw*sq2)
2177 z2=(wmaxf-wbar)/(sigw*sq2)
2178 integ=sigw*0.5*sq2*sqpi*(ERFC_NUM_RECIPES(z1)-ERFC_NUM_RECIPES(z2))
2179 ! consider only upward flow into cloud base when estimating flux
2181 zf1=(wf1-wbar)/(sigw*sq2)
2184 zf2=(wf2-wbar)/(sigw*sq2)
2187 integf=wbar*sigw*0.5*sq2*sqpi*(ERFC_NUM_RECIPES(zf1)-ERFC_NUM_RECIPES(zf2))+sigw*sigw*gf
2191 sumflxn(m,n)=sumflxn(m,n)+integf*fn(m,n)
2192 sumfn(m,n)=sumfn(m,n)+fn(m,n)*integ
2193 sumflxs(m,n)=sumflxs(m,n)+integf*fs(m,n)
2194 sumfs(m,n)=sumfs(m,n)+fs(m,n)*integ
2195 sumflxm(m,n)=sumflxm(m,n)+integf*fm(m,n)
2196 sumfm(m,n)=sumfm(m,n)+fm(m,n)*integ
2199 ! same form as sumflxm(m,n) but replace the fm(m,n) with 1.0
2200 sumflx_fullact = sumflx_fullact + integf
2208 ! fn(m,n)=sumfn(m,n)/(sumg)
2209 fn(m,n)=sumfn(m,n)/(sq2*sqpi*sigw)
2210 fluxn(m,n)=sumflxn(m,n)/(sq2*sqpi*sigw)
2211 if(fn(m,n).gt.1.01)then
2212 if (idiag_fnsm_prob .gt. 0) then
2213 print *,'fn=',fn(m,n),' > 1 - activate err41'
2214 print *,'w,m,n,na,am=',w,m,n,na(m,n),am(m,n)
2215 print *,'integ,sumfn,sigw=',integ,sumfn(m,n),sigw
2216 print *,'subr activate error - i,j,k =', ii, jj, kk
2218 fluxn(m,n) = fluxn(m,n)/fn(m,n)
2221 fs(m,n)=sumfs(m,n)/(sq2*sqpi*sigw)
2222 fluxs(m,n)=sumflxs(m,n)/(sq2*sqpi*sigw)
2223 if(fs(m,n).gt.1.01)then
2224 if (idiag_fnsm_prob .gt. 0) then
2225 print *,'fs=',fs(m,n),' > 1 - activate err42'
2226 print *,'m,n,isectional=',m,n,isectional
2227 print *,'alnsign(m,n)=',alnsign(m,n)
2228 print *,'rcut,rlo(m,n),rhi(m,n)',exp(xcut),rlo(m,n),rhi(m,n)
2229 print *,'w,m,na,am=',w,m,na(m,n),am(m,n)
2230 print *,'integ,sumfs,sigw=',integ,sumfs(m,n),sigw
2232 fluxs(m,n) = fluxs(m,n)/fs(m,n)
2235 ! fm(m,n)=sumfm(m,n)/(sumg)
2236 fm(m,n)=sumfm(m,n)/(sq2*sqpi*sigw)
2237 fluxm(m,n)=sumflxm(m,n)/(sq2*sqpi*sigw)
2238 if(fm(m,n).gt.1.01)then
2239 if (idiag_fnsm_prob .gt. 0) then
2240 print *,'fm(',m,n,')=',fm(m,n),' > 1 - activate err43'
2242 fluxm(m,n) = fluxm(m,n)/fm(m,n)
2247 ! same form as fluxm(m,n)
2248 flux_fullact = sumflx_fullact/(sq2*sqpi*sigw)
2251 !.......................................................................
2253 ! end calc. of activation fractions/fluxes
2254 ! for spectrum of updrafts (end of section 2)
2256 !.......................................................................
2258 !.......................................................................
2260 ! start calc. of activation fractions/fluxes
2261 ! for (single) uniform updraft (start of section 3)
2263 !.......................................................................
2267 ! write(6,*)'uniform updraft =',wnuc
2269 ! 04-nov-2005 rce - moved the code for "wnuc.le.0" code to here
2288 zeta=2.*sqrtalw*aten/(3.*sqrtg)
2290 if (isectional .gt. 0) then
2292 ! use bulk properties
2294 if(totn(n).gt.1.e-10)then
2295 eta(1,n)=2*alw*sqrtalw/(totn(n)*beta*sqrtg)
2300 call maxsat(zeta,eta,maxd_atype,ntype_aer, &
2301 maxd_asize,(/1/),gmsm,gmlnsig,f1,smax)
2307 if(na(m,n).gt.1.e-10)then
2308 eta(m,n)=2*alw*sqrtalw/(na(m,n)*beta*sqrtg)
2315 call maxsat(zeta,eta,maxd_atype,ntype_aer, &
2316 maxd_asize,nsize_aer,sm,alnsign,f1,smax)
2321 xmincoeff=alogaten-2.*third*(lnsmax-alog2)-alog3
2323 do 55002 n=1,ntype_aer
2324 do 55000 m=1,nsize_aer(n)
2326 ! 04-nov-2005 rce - check for bin_is_empty here too, just like earlier
2327 if ( bin_is_empty(m,n) ) then
2332 else if ((isectional .eq. 2) .or. (isectional .eq. 4)) then
2334 ! within-section dn/dx = a + b*x
2335 xcut=xmincoeff-third*lnhygro(m,n)
2336 ! ycut=(exp(xcut)/rhi(m,n))**3
2337 ! 07-jul-2006 rce - the above line gave a (rare) overflow when smax=1.0e-20
2338 ! if (ycut > yhi), then actual value of ycut is unimportant,
2339 ! so do the following to avoid overflow
2340 lnycut = 3.0 * ( xcut - log(rhi(m,n)) )
2341 lnycut = min( lnycut, log(yhi(m,n)*1.0e5) )
2343 ! write(6,*)'m,n,rcut,rlo,rhi=',m,n,exp(xcut),rlo(m,n),rhi(m,n)
2344 ! if(lnsmax.lt.lnsmn(m,n))then
2345 if(ycut.gt.yhi(m,n))then
2349 ! elseif(lnsmax.gt.lnsmx(m,n))then
2350 elseif(ycut.lt.ylo(m,n))then
2354 elseif ( bin_is_narrow(m,n) ) then
2355 ! 04-nov-2005 rce - for extremely narrow bins,
2356 ! do zero activation if xcut>xmean, 100% activation otherwise
2357 if (ycut.gt.ymean(m,n)) then
2368 fn(m,n) = asub(m,n)*(1.0-phiyy) + 0.5*bsub(m,n)*(1.0-phiyy*phiyy)
2369 if (fn(m,n).lt.zero .or. fn(m,n).gt.one) then
2370 if (idiag_fnsm_prob .gt. 0) then
2371 print *,'fn(',m,n,')=',fn(m,n),' outside 0,1 - activate err21'
2372 print *,'na,volc =', na(m,n), volc(m,n)
2373 print *,'asub,bsub =', asub(m,n), bsub(m,n)
2374 print *,'yhi,ycut =', yhi(m,n), ycut
2378 if (fn(m,n) .le. zero) then
2379 ! 10-nov-2005 rce - if fn=0, then fs & fm must be 0
2383 else if (fn(m,n) .ge. one) then
2384 ! 10-nov-2005 rce - if fn=1, then fs & fm must be 1
2389 ! 10-nov-2005 rce - otherwise, calc fm and check it
2390 fm(m,n) = (yhi(m,n)/ymean(m,n)) * (0.5*asub(m,n)*(1.0-phiyy*phiyy) + &
2391 third*bsub(m,n)*(1.0-phiyy*phiyy*phiyy))
2392 if (fm(m,n).lt.fn(m,n) .or. fm(m,n).gt.one) then
2393 if (idiag_fnsm_prob .gt. 0) then
2394 print *,'fm(',m,n,')=',fm(m,n),' outside fn,1 - activate err22'
2395 print *,'na,volc,fn =', na(m,n), volc(m,n), fn(m,n)
2396 print *,'asub,bsub =', asub(m,n), bsub(m,n)
2397 print *,'yhi,ycut =', yhi(m,n), ycut
2400 if (fm(m,n) .le. fn(m,n)) then
2401 ! 10-nov-2005 rce - if fm=fn, then fs must =fn
2404 else if (fm(m,n) .ge. one) then
2405 ! 10-nov-2005 rce - if fm=1, then fs & fn must be 1
2410 ! 10-nov-2005 rce - these two checks assure that the mean size
2411 ! of the activated & interstitial particles will be between rlo & rhi
2412 dumaa = fn(m,n)*(yhi(m,n)/ymean(m,n))
2413 fm(m,n) = min( fm(m,n), dumaa )
2414 dumaa = 1.0 + (fn(m,n)-1.0)*(ylo(m,n)/ymean(m,n))
2415 fm(m,n) = min( fm(m,n), dumaa )
2416 ! 10-nov-2005 rce - now calculate fs and bound it by fn, fm
2417 betayy = ylo(m,n)/yhi(m,n)
2418 dumaa = phiyy**twothird
2419 dumbb = betayy**twothird
2421 (asub(m,n)*(1.0-phiyy*dumaa) + &
2422 0.625*bsub(m,n)*(1.0-phiyy*phiyy*dumaa)) / &
2423 (asub(m,n)*(1.0-betayy*dumbb) + &
2424 0.625*bsub(m,n)*(1.0-betayy*betayy*dumbb))
2425 fs(m,n)=max(fs(m,n),fn(m,n))
2426 fs(m,n)=min(fs(m,n),fm(m,n))
2434 x=2*(lnsm(m,n)-lnsmax)/(3*sq2*alnsign(m,n))
2435 fn(m,n)=0.5*(1.-ERF_ALT(x))
2436 arg=x-sq2*alnsign(m,n)
2437 fs(m,n)=0.5*(1.-ERF_ALT(arg))
2438 arg=x-1.5*sq2*alnsign(m,n)
2439 fm(m,n)=0.5*(1.-ERF_ALT(arg))
2445 if((top.and.wbar.lt.0.).or.(.not.top.and.wbar.gt.0.))then
2446 fluxn(m,n)=fn(m,n)*w
2447 fluxs(m,n)=fs(m,n)*w
2448 fluxm(m,n)=fm(m,n)*w
2455 55000 continue ! m=1,nsize_aer(n)
2456 55002 continue ! n=1,ntype_aer
2458 if((top.and.wbar.lt.0.).or.(.not.top.and.wbar.gt.0.))then
2464 ! 04-nov-2005 rce - moved the code for "wnuc.le.0" from here
2465 ! to near the start the uniform undraft section
2467 !.......................................................................
2469 ! end calc. of activation fractions/fluxes
2470 ! for (single) uniform updraft (end of section 3)
2472 !.......................................................................
2480 ! do m=1,nsize_aer(n)
2481 ! write(6,'(a,2i3,5e10.1)')'n,m,na,wbar,sigw,fn,fm=',n,m,na(m,n),wbar,sigw,fn(m,n),fm(m,n)
2487 end subroutine activate
2491 !----------------------------------------------------------------------
2492 !----------------------------------------------------------------------
2493 subroutine maxsat(zeta,eta, &
2494 maxd_atype,ntype_aer,maxd_asize,nsize_aer, &
2497 ! Calculates maximum supersaturation for multiple competing aerosol
2498 ! modes. Note that maxsat_init must be called before calling this
2501 ! Abdul-Razzak and Ghan, A parameterization of aerosol activation.
2502 ! 2. Multiple aerosol types. J. Geophys. Res., 105, 6837-6844.
2506 integer, intent(in) :: maxd_atype
2507 integer, intent(in) :: ntype_aer
2508 integer, intent(in) :: maxd_asize
2509 integer, intent(in) :: nsize_aer(maxd_atype) ! number of size bins
2510 real, intent(in) :: sm(maxd_asize,maxd_atype) ! critical supersaturation for number mode radius
2511 real, intent(in) :: zeta, eta(maxd_asize,maxd_atype)
2512 real, intent(in) :: alnsign(maxd_asize,maxd_atype) ! ln(sigma)
2513 real, intent(in) :: f1(maxd_asize,maxd_atype)
2514 real, intent(out) :: smax ! maximum supersaturation
2518 integer m ! size index
2519 integer n ! type index
2523 if(zeta.gt.1.e5*eta(m,n) .or. &
2524 sm(m,n)*sm(m,n).gt.1.e5*eta(m,n))then
2525 ! weak forcing. essentially none activated
2528 ! significant activation of this mode. calc activation all modes.
2541 if(eta(m,n).gt.1.e-20)then
2542 g1=sqrt(zeta/eta(m,n))
2544 g2=sm(m,n)/sqrt(eta(m,n)+3*zeta)
2548 (f1(m,n)*g1+(1.+0.25*alnsign(m,n))*g2)/(sm(m,n)*sm(m,n))
2555 smax=1./sqrt(thesum)
2558 end subroutine maxsat
2562 !----------------------------------------------------------------------
2563 !----------------------------------------------------------------------
2564 subroutine maxsat_init(maxd_atype, ntype_aer, &
2565 maxd_asize, nsize_aer, alnsign, f1)
2567 ! Calculates the f1 paramter needed by maxsat.
2569 ! Abdul-Razzak and Ghan, A parameterization of aerosol activation.
2570 ! 2. Multiple aerosol types. J. Geophys. Res., 105, 6837-6844.
2574 integer, intent(in) :: maxd_atype
2575 integer, intent(in) :: ntype_aer ! number of aerosol types
2576 integer, intent(in) :: maxd_asize
2577 integer, intent(in) :: nsize_aer(maxd_atype) ! number of size bins
2578 real, intent(in) :: alnsign(maxd_asize,maxd_atype) ! ln(sigma)
2579 real, intent(out) :: f1(maxd_asize,maxd_atype)
2581 integer m ! size index
2582 integer n ! type index
2584 ! calculate and save f1(sigma), assumes sigma is invariant
2585 ! between calls to this init routine
2589 f1(m,n)=0.5*exp(2.5*alnsign(m,n)*alnsign(m,n))
2593 end subroutine maxsat_init
2597 !----------------------------------------------------------------------
2598 !----------------------------------------------------------------------
2599 ! 25-apr-2006 rce - dens_aer is (g/cm3), NOT (kg/m3);
2600 ! grid_id, ktau, i, j, isize, itype added to arg list to assist debugging
2601 subroutine loadaer(chem,k,kmn,kmx,num_chem,cs,npv, &
2602 dlo_sect,dhi_sect,maxd_acomp, ncomp, &
2603 grid_id, ktau, i, j, isize, itype, &
2604 numptr_aer, numptrcw_aer, dens_aer, &
2605 massptr_aer, massptrcw_aer, &
2606 maerosol, maerosolcw, &
2607 maerosol_tot, maerosol_totcw, &
2608 naerosol, naerosolcw, &
2609 vaerosol, vaerosolcw)
2613 ! load aerosol number, surface, mass concentrations
2617 integer, intent(in) :: num_chem ! maximum number of consituents
2618 integer, intent(in) :: k,kmn,kmx
2619 real, intent(in) :: chem(kmn:kmx,num_chem) ! aerosol mass, number mixing ratios
2620 real, intent(in) :: cs ! air density (kg/m3)
2621 real, intent(in) :: npv ! number per volume concentration (/m3)
2622 integer, intent(in) :: maxd_acomp,ncomp
2623 integer, intent(in) :: numptr_aer,numptrcw_aer
2624 integer, intent(in) :: massptr_aer(maxd_acomp), massptrcw_aer(maxd_acomp)
2625 real, intent(in) :: dens_aer(maxd_acomp) ! aerosol material density (g/cm3)
2626 real, intent(in) :: dlo_sect,dhi_sect ! minimum, maximum diameter of section (cm)
2627 integer, intent(in) :: grid_id, ktau, i, j, isize, itype
2631 real, intent(out) :: naerosol ! interstitial number conc (/m3)
2632 real, intent(out) :: naerosolcw ! activated number conc (/m3)
2633 real, intent(out) :: maerosol(maxd_acomp) ! interstitial mass conc (kg/m3)
2634 real, intent(out) :: maerosolcw(maxd_acomp) ! activated mass conc (kg/m3)
2635 real, intent(out) :: maerosol_tot ! total-over-species interstitial mass conc (kg/m3)
2636 real, intent(out) :: maerosol_totcw ! total-over-species activated mass conc (kg/m3)
2637 real, intent(out) :: vaerosol ! interstitial volume conc (m3/m3)
2638 real, intent(out) :: vaerosolcw ! activated volume conc (m3/m3)
2642 integer lnum,lnumcw,l,ltype,lmass,lmasscw,lsfc,lsfccw
2643 real num_at_dhi, num_at_dlo
2644 real npv_at_dhi, npv_at_dlo
2645 real, parameter :: pi = 3.1415926526
2646 real specvol ! inverse aerosol material density (m3/kg)
2655 lmass=massptr_aer(l)
2656 lmasscw=massptrcw_aer(l)
2657 maerosol(l)=chem(k,lmass)*cs
2658 maerosol(l)=max(maerosol(l),0.)
2659 maerosolcw(l)=chem(k,lmasscw)*cs
2660 maerosolcw(l)=max(maerosolcw(l),0.)
2661 maerosol_tot=maerosol_tot+maerosol(l)
2662 maerosol_totcw=maerosol_totcw+maerosolcw(l)
2663 ! [ 1.e-3 factor because dens_aer is (g/cm3), specvol is (m3/kg) ]
2664 specvol=1.0e-3/dens_aer(l)
2665 vaerosol=vaerosol+maerosol(l)*specvol
2666 vaerosolcw=vaerosolcw+maerosolcw(l)*specvol
2667 ! write(6,'(a,3e12.2)')'maerosol,dens_aer,vaerosol=',maerosol(l),dens_aer(l),vaerosol
2671 ! aerosol number predicted
2672 ! [ 1.0e6 factor because because dhi_ & dlo_sect are (cm), vaerosol is (m3) ]
2673 npv_at_dhi = 6.0e6/(pi*dhi_sect*dhi_sect*dhi_sect)
2674 npv_at_dlo = 6.0e6/(pi*dlo_sect*dlo_sect*dlo_sect)
2676 naerosol=chem(k,lnum)*cs
2677 naerosolcw=chem(k,lnumcw)*cs
2678 num_at_dhi = vaerosol*npv_at_dhi
2679 num_at_dlo = vaerosol*npv_at_dlo
2680 naerosol = max( num_at_dhi, min( num_at_dlo, naerosol ) )
2682 ! write(6,'(a,5e10.1)')'naerosol,num_at_dhi,num_at_dlo,dhi_sect,dlo_sect', &
2683 ! naerosol,num_at_dhi,num_at_dlo,dhi_sect,dlo_sect
2684 num_at_dhi = vaerosolcw*npv_at_dhi
2685 num_at_dlo = vaerosolcw*npv_at_dlo
2686 naerosolcw = max( num_at_dhi, min( num_at_dlo, naerosolcw ) )
2688 ! aerosol number diagnosed from mass and prescribed size
2689 naerosol=vaerosol*npv
2690 naerosol=max(naerosol,0.)
2691 naerosolcw=vaerosolcw*npv
2692 naerosolcw=max(naerosolcw,0.)
2697 end subroutine loadaer
2701 !-----------------------------------------------------------------------
2702 real function erfc_num_recipes( x )
2704 ! from press et al, numerical recipes, 1990, page 164
2708 double precision erfc_dbl, dum, t, zz
2711 t = 1.0/(1.0 + 0.5*zz)
2713 ! erfc_num_recipes =
2714 ! & t*exp( -zz*zz - 1.26551223 + t*(1.00002368 + t*(0.37409196 +
2715 ! & t*(0.09678418 + t*(-0.18628806 + t*(0.27886807 +
2716 ! & t*(-1.13520398 +
2717 ! & t*(1.48851587 + t*(-0.82215223 + t*0.17087277 )))))))))
2719 dum = ( -zz*zz - 1.26551223 + t*(1.00002368 + t*(0.37409196 + &
2720 t*(0.09678418 + t*(-0.18628806 + t*(0.27886807 + &
2722 t*(1.48851587 + t*(-0.82215223 + t*0.17087277 )))))))))
2724 erfc_dbl = t * exp(dum)
2725 if (x .lt. 0.0) erfc_dbl = 2.0d0 - erfc_dbl
2727 erfc_num_recipes = erfc_dbl
2730 end function erfc_num_recipes
2732 !-----------------------------------------------------------------------
2733 real function erf_alt( x )
2737 real,intent(in) :: x
2739 erf_alt = 1. - erfc_num_recipes(x)
2741 end function erf_alt
2743 END MODULE module_mixactivate