PageRenderTime 71ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 1ms

/wrfv2_fire/phys/module_mixactivate.F

http://github.com/jbeezley/wrf-fire
FORTRAN Legacy | 2743 lines | 1845 code | 334 blank | 564 comment | 153 complexity | aa80bcb1902394863ac73d83dbb3835e MD5 | raw file
Possible License(s): AGPL-1.0

Large files files are truncated, but you can click here to view the full file

  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.
  7. !
  8. ! MOSAIC module: see chem/module_mosaic_driver.F for references and terms
  9. ! of use
  10. !************************************************************************
  11. MODULE module_mixactivate
  12. PRIVATE
  13. PUBLIC prescribe_aerosol_mixactivate, mixactivate
  14. CONTAINS
  15. !----------------------------------------------------------------------
  16. !----------------------------------------------------------------------
  17. ! 06-nov-2005 rce - grid_id & ktau added to arg list
  18. ! 25-apr-2006 rce - dens_aer is (g/cm3), NOT (kg/m3)
  19. subroutine prescribe_aerosol_mixactivate ( &
  20. grid_id, ktau, dtstep, naer, &
  21. rho_phy, th_phy, pi_phy, w, cldfra, cldfra_old, &
  22. z, dz8w, p_at_w, t_at_w, exch_h, &
  23. qv, qc, qi, qndrop3d, &
  24. nsource, &
  25. ids,ide, jds,jde, kds,kde, &
  26. ims,ime, jms,jme, kms,kme, &
  27. its,ite, jts,jte, kts,kte, &
  28. f_qc, f_qi )
  29. ! USE module_configure
  30. ! wrapper to call mixactivate for mosaic description of aerosol
  31. implicit none
  32. ! subr arguments
  33. integer, intent(in) :: &
  34. grid_id, ktau, &
  35. ids, ide, jds, jde, kds, kde, &
  36. ims, ime, jms, jme, kms, kme, &
  37. its, ite, jts, jte, kts, kte
  38. real, intent(in) :: dtstep
  39. real, intent(inout) :: naer ! aerosol number (/kg)
  40. real, intent(in), &
  41. dimension( ims:ime, kms:kme, jms:jme ) :: &
  42. rho_phy, th_phy, pi_phy, w, &
  43. z, dz8w, p_at_w, t_at_w, exch_h
  44. real, intent(inout), &
  45. dimension( ims:ime, kms:kme, jms:jme ) :: cldfra, cldfra_old
  46. real, intent(in), &
  47. dimension( ims:ime, kms:kme, jms:jme ) :: &
  48. qv, qc, qi
  49. real, intent(inout), &
  50. dimension( ims:ime, kms:kme, jms:jme ) :: &
  51. qndrop3d
  52. real, intent(out), &
  53. dimension( ims:ime, kms:kme, jms:jme) :: nsource
  54. LOGICAL, OPTIONAL :: f_qc, f_qi
  55. ! local vars
  56. integer maxd_aphase, maxd_atype, maxd_asize, maxd_acomp, max_chem
  57. parameter (maxd_aphase=2,maxd_atype=1,maxd_asize=1,maxd_acomp=1, max_chem=10)
  58. real ddvel(its:ite, jts:jte, max_chem) ! dry deposition velosity
  59. real qsrflx(ims:ime, jms:jme, max_chem) ! dry deposition flux of aerosol
  60. real chem(ims:ime, kms:kme, jms:jme, max_chem) ! chem array
  61. integer i,j,k,l,m,n,p
  62. real hygro( its:ite, kts:kte, jts:jte, maxd_asize, maxd_atype ) ! bulk
  63. integer ntype_aer, nsize_aer(maxd_atype),ncomp_aer(maxd_atype), nphase_aer
  64. integer massptr_aer( maxd_acomp, maxd_asize, maxd_atype, maxd_aphase ), &
  65. waterptr_aer( maxd_asize, maxd_atype ), &
  66. numptr_aer( maxd_asize, maxd_atype, maxd_aphase ), &
  67. ai_phase, cw_phase
  68. real dlo_sect( maxd_asize, maxd_atype ), & ! minimum size of section (cm)
  69. dhi_sect( maxd_asize, maxd_atype ), & ! maximum size of section (cm)
  70. sigmag_aer(maxd_asize, maxd_atype), & ! geometric standard deviation of aerosol size dist
  71. dgnum_aer(maxd_asize, maxd_atype), & ! median diameter (cm) of number distrib of mode
  72. dens_aer( maxd_acomp, maxd_atype), & ! density (g/cm3) of material
  73. mw_aer( maxd_acomp, maxd_atype), & ! molecular weight (g/mole)
  74. dpvolmean_aer(maxd_asize, maxd_atype) ! mean-volume diameter (cm) of mode
  75. ! terminology: (pi/6) * (mean-volume diameter)**3 ==
  76. ! (volume mixing ratio of section/mode)/(number mixing ratio)
  77. real, dimension(ims:ime,kms:kme,jms:jme) :: &
  78. ccn1,ccn2,ccn3,ccn4,ccn5,ccn6 ! number conc of aerosols activated at supersat
  79. integer idrydep_onoff
  80. real, dimension(ims:ime,kms:kme,jms:jme) :: t_phy
  81. integer msectional
  82. integer ptr
  83. real maer
  84. if(naer.lt.1.)then
  85. naer=1000.e6 ! #/kg default value
  86. endif
  87. ai_phase=1
  88. cw_phase=2
  89. idrydep_onoff = 0
  90. msectional = 0
  91. t_phy(its:ite,kts:kte,jts:jte)=th_phy(its:ite,kts:kte,jts:jte)*pi_phy(its:ite,kts:kte,jts:jte)
  92. ntype_aer=maxd_atype
  93. do n=1,ntype_aer
  94. nsize_aer(n)=maxd_asize
  95. ncomp_aer(n)=maxd_acomp
  96. end do
  97. nphase_aer=maxd_aphase
  98. ! set properties for each type and size
  99. do n=1,ntype_aer
  100. do m=1,nsize_aer(n)
  101. dlo_sect( m,n )=0.01e-4 ! minimum size of section (cm)
  102. dhi_sect( m,n )=0.5e-4 ! maximum size of section (cm)
  103. sigmag_aer(m,n)=2. ! geometric standard deviation of aerosol size dist
  104. dgnum_aer(m,n)=0.1e-4 ! median diameter (cm) of number distrib of mode
  105. dpvolmean_aer(m,n) = dgnum_aer(m,n) * exp( 1.5 * (log(sigmag_aer(m,n)))**2 )
  106. end do
  107. do l=1,ncomp_aer(n)
  108. dens_aer( l, n)=1.0 ! density (g/cm3) of material
  109. mw_aer( l, n)=132. ! molecular weight (g/mole)
  110. end do
  111. end do
  112. ptr=0
  113. do p=1,nphase_aer
  114. do n=1,ntype_aer
  115. do m=1,nsize_aer(n)
  116. ptr=ptr+1
  117. numptr_aer( m, n, p )=ptr
  118. if(p.eq.ai_phase)then
  119. chem(its:ite,kts:kte,jts:jte,ptr)=naer
  120. else
  121. chem(its:ite,kts:kte,jts:jte,ptr)=0.
  122. endif
  123. end do ! size
  124. end do ! type
  125. end do ! phase
  126. do p=1,maxd_aphase
  127. do n=1,ntype_aer
  128. do m=1,nsize_aer(n)
  129. do l=1,ncomp_aer(n)
  130. ptr=ptr+1
  131. if(ptr.gt.max_chem)then
  132. write(6,*)'ptr,max_chem=',ptr,max_chem,' in prescribe_aerosol_mixactivate'
  133. call wrf_error_fatal("1")
  134. endif
  135. massptr_aer(l, m, n, p)=ptr
  136. ! maer is ug/kg-air; naer is #/kg-air; dgnum is cm; dens_aer is g/cm3
  137. ! 1.e6 factor converts g to ug
  138. maer= 1.0e6 * naer * dens_aer(l,n) * ( (3.1416/6.) * &
  139. (dgnum_aer(m,n)**3) * exp( 4.5*((log(sigmag_aer(m,n)))**2) ) )
  140. if(p.eq.ai_phase)then
  141. chem(its:ite,kts:kte,jts:jte,ptr)=maer
  142. else
  143. chem(its:ite,kts:kte,jts:jte,ptr)=0.
  144. endif
  145. end do
  146. end do ! size
  147. end do ! type
  148. end do ! phase
  149. do n=1,ntype_aer
  150. do m=1,nsize_aer(n)
  151. ptr=ptr+1
  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")
  155. endif
  156. !wig waterptr_aer(m, n)=ptr
  157. waterptr_aer(m, n)=-1
  158. end do ! size
  159. end do ! type
  160. ddvel(its:ite,jts:jte,:)=0.
  161. hygro(its:ite,kts:kte,jts:jte,:,:) = 0.5
  162. ! 06-nov-2005 rce - grid_id & ktau added to arg list
  163. call mixactivate( msectional, &
  164. chem,max_chem,qv,qc,qi,qndrop3d, &
  165. t_phy, w, ddvel, idrydep_onoff, &
  166. maxd_acomp, maxd_asize, maxd_atype, maxd_aphase, &
  167. ncomp_aer, nsize_aer, ntype_aer, nphase_aer, &
  168. numptr_aer, massptr_aer, dlo_sect, dhi_sect, sigmag_aer, dpvolmean_aer, &
  169. dens_aer, mw_aer, &
  170. waterptr_aer, hygro, ai_phase, cw_phase, &
  171. ids,ide, jds,jde, kds,kde, &
  172. ims,ime, jms,jme, kms,kme, &
  173. its,ite, jts,jte, kts,kte, &
  174. rho_phy, z, dz8w, p_at_w, t_at_w, exch_h, &
  175. cldfra, cldfra_old, qsrflx, &
  176. ccn1, ccn2, ccn3, ccn4, ccn5, ccn6, nsource, &
  177. grid_id, ktau, dtstep, &
  178. F_QC=f_qc, F_QI=f_qi )
  179. end subroutine prescribe_aerosol_mixactivate
  180. !----------------------------------------------------------------------
  181. !----------------------------------------------------------------------
  182. ! nov-04 sg ! replaced amode with aer and expanded aerosol dimension to include type and phase
  183. ! 06-nov-2005 rce - grid_id & ktau added to arg list
  184. ! 25-apr-2006 rce - dens_aer is (g/cm3), NOT (kg/m3)
  185. subroutine mixactivate( msectional, &
  186. chem, num_chem, qv, qc, qi, qndrop3d, &
  187. temp, 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, &
  191. dens_aer, mw_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, zm, dz8w, p_at_w, t_at_w, kvh, &
  197. cldfra, cldfra_old, qsrflx, &
  198. ccn1, ccn2, ccn3, ccn4, ccn5, ccn6, nsource, &
  199. grid_id, ktau, dtstep, &
  200. f_qc, f_qi )
  201. ! vertical diffusion and nucleation of cloud droplets
  202. ! assume cloud presence controlled by cloud fraction
  203. ! doesn't distinguish between warm, cold clouds
  204. USE module_model_constants, only: g, rhowater, xlv, cp, rvovrd, r_d, r_v, mwdry, ep_2
  205. USE module_radiation_driver, only: cal_cldfra
  206. implicit none
  207. ! input
  208. INTEGER, intent(in) :: grid_id, ktau
  209. INTEGER, intent(in) :: num_chem
  210. integer, intent(in) :: ids,ide, jds,jde, kds,kde, &
  211. ims,ime, jms,jme, kms,kme, &
  212. its,ite, jts,jte, kts,kte
  213. integer maxd_aphase, nphase_aer, maxd_atype, ntype_aer
  214. integer maxd_asize, maxd_acomp, nsize_aer(maxd_atype)
  215. integer, intent(in) :: &
  216. ncomp_aer( maxd_atype ), &
  217. massptr_aer( maxd_acomp, maxd_asize, maxd_atype, maxd_aphase ), &
  218. waterptr_aer( maxd_asize, maxd_atype ), &
  219. numptr_aer( maxd_asize, maxd_atype, maxd_aphase), &
  220. ai_phase, cw_phase
  221. integer, intent(in) :: msectional ! 1 for sectional, 0 for modal
  222. integer, intent(in) :: idrydep_onoff
  223. real, intent(in) :: &
  224. dlo_sect( maxd_asize, maxd_atype ), & ! minimum size of section (cm)
  225. dhi_sect( maxd_asize, maxd_atype ), & ! maximum size of section (cm)
  226. sigmag_aer(maxd_asize, maxd_atype), & ! geometric standard deviation of aerosol size dist
  227. dens_aer( maxd_acomp, maxd_atype), & ! density (g/cm3) of material
  228. mw_aer( maxd_acomp, maxd_atype), & ! molecular weight (g/mole)
  229. dpvolmean_aer(maxd_asize, maxd_atype) ! mean-volume diameter (cm) of mode
  230. ! terminology: (pi/6) * (mean-volume diameter)**3 ==
  231. ! (volume mixing ratio of section/mode)/(number mixing ratio)
  232. REAL, intent(inout), DIMENSION( ims:ime, kms:kme, jms:jme, num_chem ) :: &
  233. chem ! aerosol molar mixing ratio (ug/kg or #/kg)
  234. REAL, intent(in), DIMENSION( ims:ime, kms:kme, jms:jme ) :: &
  235. qv, qc, qi ! water species (vapor, cloud drops, cloud ice) mixing ratio (g/g)
  236. LOGICAL, OPTIONAL :: f_qc, f_qi
  237. REAL, intent(inout), DIMENSION( ims:ime, kms:kme, jms:jme ) :: &
  238. qndrop3d ! water species mixing ratio (g/g)
  239. real, intent(in) :: dtstep ! time step for microphysics (s)
  240. real, intent(in) :: temp(ims:ime, kms:kme, jms:jme) ! temperature (K)
  241. real, intent(in) :: w(ims:ime, kms:kme, jms:jme) ! vertical velocity (m/s)
  242. real, intent(in) :: rho(ims:ime, kms:kme, jms:jme) ! density at mid-level (kg/m3)
  243. REAL, intent(in) :: ddvel( its:ite, jts:jte, num_chem ) ! deposition velocity (m/s)
  244. real, intent(in) :: zm(ims:ime, kms:kme, jms:jme) ! geopotential height of level (m)
  245. real, intent(in) :: dz8w(ims:ime, kms:kme, jms:jme) ! layer thickness (m)
  246. real, intent(in) :: p_at_w(ims:ime, kms:kme, jms:jme) ! pressure at layer interface (Pa)
  247. real, intent(in) :: t_at_w(ims:ime, kms:kme, jms:jme) ! temperature at layer interface (K)
  248. real, intent(in) :: kvh(ims:ime, kms:kme, jms:jme) ! vertical diffusivity (m2/s)
  249. real, intent(inout) :: cldfra_old(ims:ime, kms:kme, jms:jme)! cloud fraction on previous time step
  250. real, intent(inout) :: cldfra(ims:ime, kms:kme, jms:jme) ! cloud fraction
  251. real, intent(in) :: hygro( its:ite, kts:kte, jts:jte, maxd_asize, maxd_atype ) ! bulk hygroscopicity &
  252. REAL, intent(out), DIMENSION( ims:ime, jms:jme, num_chem ) :: qsrflx ! dry deposition rate for aerosol
  253. real, intent(out), dimension(ims:ime,kms:kme,jms:jme) :: nsource, & ! droplet number source (#/kg/s)
  254. ccn1,ccn2,ccn3,ccn4,ccn5,ccn6 ! number conc of aerosols activated at supersat
  255. !--------------------Local storage-------------------------------------
  256. !
  257. real :: dgnum_aer(maxd_asize, maxd_atype) ! median diameter (cm) of number distrib of mode
  258. real :: qndrop(kms:kme) ! cloud droplet number mixing ratio (#/kg)
  259. real :: lcldfra(kms:kme) ! liquid cloud fraction
  260. real :: lcldfra_old(kms:kme) ! liquid cloud fraction for previous timestep
  261. real :: wtke(kms:kme) ! turbulent vertical velocity at base of layer k (m2/s)
  262. real zn(kms:kme) ! g/pdel (m2/g) for layer
  263. real zs(kms:kme) ! inverse of distance between levels (m)
  264. real, parameter :: zkmin = 0.01
  265. real, parameter :: zkmax = 100.
  266. real cs(kms:kme) ! air density (kg/m3) at layer center
  267. real csbot(kms:kme) ! air density (kg/m3) at layer bottom
  268. real csbot_cscen(kms:kme) ! csbot(k)/cs(k)
  269. real dz(kms:kme) ! geometric thickness of layers (m)
  270. real wdiab ! diabatic vertical velocity
  271. ! real, parameter :: wmixmin = 0.1 ! minimum turbulence vertical velocity (m/s)
  272. real, parameter :: wmixmin = 0.2 ! minimum turbulence vertical velocity (m/s)
  273. ! real, parameter :: wmixmin = 1.0 ! minimum turbulence vertical velocity (m/s)
  274. real :: qndrop_new(kms:kme) ! droplet number nucleated on cloud boundaries
  275. real :: ekd(kms:kme) ! diffusivity for droplets (m2/s)
  276. real :: ekk(kms:kme) ! density*diffusivity for droplets (kg/m3 m2/s)
  277. real :: srcn(kms:kme) ! droplet source rate (/s)
  278. real, parameter :: sq2pi = 2.5066282746
  279. real dtinv
  280. integer km1,kp1
  281. real wbar,wmix,wmin,wmax
  282. real dum
  283. real tmpa, tmpb, tmpc, tmpc1, tmpc2, tmpd, tmpe, tmpf
  284. real tmpcourno
  285. real dact
  286. real fluxntot ! (#/cm2/s)
  287. real fac_srflx
  288. real depvel_drop, depvel_tmp
  289. real, parameter :: depvel_uplimit = 1.0 ! upper limit for dep vels (m/s)
  290. real :: surfrate(num_chem) ! surface exchange rate (/s)
  291. real surfratemax ! max surfrate for all species treated here
  292. real surfrate_drop ! surfade exchange rate for droplelts
  293. real dtmin,tinv,dtt
  294. integer nsubmix,nsubmix_bnd
  295. integer i,j,k,m,n,nsub
  296. real dtmix
  297. real alogarg
  298. real qcld
  299. real pi
  300. integer nnew,nsav,ntemp
  301. real :: overlapp(kms:kme),overlapm(kms:kme) ! cloud overlap
  302. real :: ekkp(kms:kme),ekkm(kms:kme) ! zn*zs*density*diffusivity
  303. ! integer, save :: count_submix(100)=0 ! wig: Note that this is a no-no for tile threads with OMP
  304. integer lnum,lnumcw,l,lmass,lmasscw,lsfc,lsfccw,ltype,lsig,lwater
  305. integer :: ntype(maxd_asize)
  306. real :: naerosol(maxd_asize, maxd_atype) ! interstitial aerosol number conc (/m3)
  307. real :: naerosolcw(maxd_asize, maxd_atype) ! activated number conc (/m3)
  308. real :: maerosol(maxd_acomp,maxd_asize, maxd_atype) ! interstit mass conc (kg/m3)
  309. real :: maerosolcw(maxd_acomp,maxd_asize, maxd_atype) ! activated mass conc (kg/m3)
  310. real :: maerosol_tot(maxd_asize, maxd_atype) ! species-total interstit mass conc (kg/m3)
  311. real :: maerosol_totcw(maxd_asize, maxd_atype) ! species-total activated mass conc (kg/m3)
  312. real :: vaerosol(maxd_asize, maxd_atype) ! interstit+activated aerosol volume conc (m3/m3)
  313. real :: vaerosolcw(maxd_asize, maxd_atype) ! activated aerosol volume conc (m3/m3)
  314. real :: raercol(kms:kme,num_chem,2) ! aerosol mass, number mixing ratios
  315. real :: source(kms:kme) !
  316. real :: fn(maxd_asize, maxd_atype) ! activation fraction for aerosol number
  317. real :: fs(maxd_asize, maxd_atype) ! activation fraction for aerosol sfcarea
  318. real :: fm(maxd_asize, maxd_atype) ! activation fraction for aerosol mass
  319. integer :: ncomp(maxd_atype)
  320. real :: fluxn(maxd_asize, maxd_atype) ! number activation fraction flux (m/s)
  321. real :: fluxs(maxd_asize, maxd_atype) ! sfcarea activation fraction flux (m/s)
  322. real :: fluxm(maxd_asize, maxd_atype) ! mass activation fraction flux (m/s)
  323. real :: flux_fullact(kms:kme) ! 100% activation fraction flux (m/s)
  324. ! note: activation fraction fluxes are defined as
  325. ! fluxn = [flux of activated aero. number into cloud (#/m2/s)]
  326. ! / [aero. number conc. in updraft, just below cloudbase (#/m3)]
  327. real :: nact(kms:kme,maxd_asize, maxd_atype) ! fractional aero. number activation rate (/s)
  328. real :: mact(kms:kme,maxd_asize, maxd_atype) ! fractional aero. mass activation rate (/s)
  329. real :: npv(maxd_asize, maxd_atype) ! number per volume concentration (/m3)
  330. real scale
  331. real :: hygro_aer(maxd_asize, maxd_atype) ! hygroscopicity of aerosol mode
  332. real :: exp45logsig ! exp(4.5*alogsig**2)
  333. real :: alogsig(maxd_asize, maxd_atype) ! natl log of geometric standard dev of aerosol
  334. integer, parameter :: psat=6 ! number of supersaturations to calc ccn concentration
  335. real ccn(kts:kte,psat) ! number conc of aerosols activated at supersat
  336. real, parameter :: supersat(psat)= &! supersaturation (%) to determine ccn concentration
  337. (/0.02,0.05,0.1,0.2,0.5,1.0/)
  338. real super(psat) ! supersaturation
  339. real, parameter :: surften = 0.076 ! surface tension of water w/respect to air (N/m)
  340. real :: ccnfact(psat,maxd_asize, maxd_atype)
  341. real :: amcube(maxd_asize, maxd_atype) ! cube of dry mode radius (m)
  342. real :: argfactor(maxd_asize, maxd_atype)
  343. real aten ! surface tension parameter
  344. real t0 ! reference temperature
  345. real sm ! critical supersaturation
  346. real arg
  347. integer,parameter :: icheck_colmass = 0
  348. ! icheck_colmass > 0 turns on mass/number conservation checking
  349. ! values of 1, 10, 100 produce less to more diagnostics
  350. integer :: colmass_worst_ij( 2, 0:maxd_acomp, maxd_asize, maxd_atype )
  351. integer :: colmass_maxworst_i(3)
  352. real :: colmass_bgn( 0:maxd_acomp, maxd_asize, maxd_atype, maxd_aphase )
  353. real :: colmass_end( 0:maxd_acomp, maxd_asize, maxd_atype, maxd_aphase )
  354. real :: colmass_sfc( 0:maxd_acomp, maxd_asize, maxd_atype, maxd_aphase )
  355. real :: colmass_worst( 0:maxd_acomp, maxd_asize, maxd_atype )
  356. real :: colmass_maxworst_r
  357. real :: rhodz( kts:kte ), rhodzsum
  358. !!$#if (defined AIX)
  359. !!$#define ERF erf
  360. !!$#define ERFC erfc
  361. !!$#else
  362. !!$#define ERF erf
  363. !!$ real erf
  364. !!$#define ERFC erfc
  365. !!$ real erfc
  366. !!$#endif
  367. character*8, parameter :: ccn_name(psat)=(/'CCN1','CCN2','CCN3','CCN4','CCN5','CCN6'/)
  368. colmass_worst(:,:,:) = 0.0
  369. colmass_worst_ij(:,:,:,:) = -1
  370. arg = 1.0
  371. if (abs(0.8427-ERF_ALT(arg))/0.8427>0.001) then
  372. write (6,*) 'erf_alt(1.0) = ',ERF_ALT(arg)
  373. call wrf_error_fatal('dropmixnuc: Error function error')
  374. endif
  375. arg = 0.0
  376. if (ERF_ALT(arg) /= 0.0) then
  377. write (6,*) 'erf_alt(0.0) = ',ERF_ALT(arg)
  378. call wrf_error_fatal('dropmixnuc: Error function error')
  379. endif
  380. pi = 4.*atan(1.0)
  381. dtinv=1./dtstep
  382. depvel_drop = 0.1 ! prescribed here rather than getting it from dry_dep_driver
  383. if (idrydep_onoff .le. 0) depvel_drop = 0.0
  384. depvel_drop = min(depvel_drop,depvel_uplimit)
  385. do n=1,ntype_aer
  386. do m=1,nsize_aer(n)
  387. ncomp(n)=ncomp_aer(n)
  388. alogsig(m,n)=alog(sigmag_aer(m,n))
  389. dgnum_aer(m,n) = dpvolmean_aer(m,n) * exp( -1.5*alogsig(m,n)*alogsig(m,n) )
  390. ! print *,'sigmag_aer,dgnum_aer=',sigmag_aer(m,n),dgnum_aer(m,n)
  391. ! npv is used only if number is diagnosed from volume
  392. npv(m,n)=6./(pi*(0.01*dgnum_aer(m,n))**3*exp(4.5*alogsig(m,n)*alogsig(m,n)))
  393. end do
  394. end do
  395. t0=273.15 !wig, 1-Mar-2009: Added .15
  396. aten=2.*surften/(r_v*t0*rhowater)
  397. super(:)=0.01*supersat(:)
  398. do n=1,ntype_aer
  399. do m=1,nsize_aer(n)
  400. exp45logsig=exp(4.5*alogsig(m,n)*alogsig(m,n))
  401. argfactor(m,n)=2./(3.*sqrt(2.)*alogsig(m,n))
  402. amcube(m,n)=3./(4.*pi*exp45logsig*npv(m,n))
  403. enddo
  404. enddo
  405. IF( PRESENT(F_QC) .AND. PRESENT ( F_QI ) ) THEN
  406. CALL cal_cldfra(CLDFRA,qc,qi,f_qc,f_qi, &
  407. ids,ide, jds,jde, kds,kde, &
  408. ims,ime, jms,jme, kms,kme, &
  409. its,ite, jts,jte, kts,kte )
  410. END IF
  411. qsrflx(its:ite,jts:jte,:) = 0.
  412. ! start loop over columns
  413. OVERALL_MAIN_J_LOOP: do j=jts,jte
  414. OVERALL_MAIN_I_LOOP: do i=its,ite
  415. ! load number nucleated into qndrop on cloud boundaries
  416. ! initialization for current i .........................................
  417. do k=kts+1,kte
  418. zs(k)=1./(zm(i,k,j)-zm(i,k-1,j))
  419. enddo
  420. zs(kts)=zs(kts+1)
  421. zs(kte+1)=0.
  422. do k=kts,kte
  423. !!$ if(qndrop3d(i,k,j).lt.-10.e6.or.qndrop3d(i,k,j).gt.1.E20)then
  424. !!$! call wrf_error_fatal("1")
  425. !!$ endif
  426. if(f_qi)then
  427. qcld=qc(i,k,j)+qi(i,k,j)
  428. else
  429. qcld=qc(i,k,j)
  430. endif
  431. if(qcld.lt.-1..or.qcld.gt.1.)then
  432. write(6,'(a,g12.2,a,3i5)')'qcld=',qcld,' for i,k,j=',i,k,j
  433. call wrf_error_fatal("1")
  434. endif
  435. if(qcld.gt.1.e-20)then
  436. lcldfra(k)=cldfra(i,k,j)*qc(i,k,j)/qcld
  437. lcldfra_old(k)=cldfra_old(i,k,j)*qc(i,k,j)/qcld
  438. else
  439. lcldfra(k)=0.
  440. lcldfra_old(k)=0.
  441. endif
  442. qndrop(k)=qndrop3d(i,k,j)
  443. ! qndrop(k)=1.e5
  444. cs(k)=rho(i,k,j) ! air density (kg/m3)
  445. dz(k)=dz8w(i,k,j)
  446. do n=1,ntype_aer
  447. do m=1,nsize_aer(n)
  448. nact(k,m,n)=0.
  449. mact(k,m,n)=0.
  450. enddo
  451. enddo
  452. zn(k)=1./(cs(k)*dz(k))
  453. if(k>kts)then
  454. ekd(k)=kvh(i,k,j)
  455. ekd(k)=max(ekd(k),zkmin)
  456. ekd(k)=min(ekd(k),zkmax)
  457. else
  458. ekd(k)=0
  459. endif
  460. ! diagnose subgrid vertical velocity from diffusivity
  461. if(k.eq.kts)then
  462. wtke(k)=sq2pi*depvel_drop
  463. ! wtke(k)=sq2pi*kvh(i,k,j)
  464. ! wtke(k)=max(wtke(k),wmixmin)
  465. else
  466. wtke(k)=sq2pi*ekd(k)/dz(k)
  467. endif
  468. wtke(k)=max(wtke(k),wmixmin)
  469. nsource(i,k,j)=0.
  470. enddo
  471. nsource(i,kte+1,j) = 0.
  472. qndrop(kte+1) = 0.
  473. zn(kte+1) = 0.
  474. do k = kts+1, kte
  475. tmpa = dz(k-1) ; tmpb = dz(k)
  476. tmpc = tmpa/(tmpa + tmpb)
  477. csbot(k) = cs(k-1)*(1.0-tmpc) + cs(k)*tmpc
  478. csbot_cscen(k) = csbot(k)/cs(k)
  479. end do
  480. csbot(kts) = cs(kts)
  481. csbot_cscen(kts) = 1.0
  482. csbot(kte+1) = cs(kte)
  483. csbot_cscen(kte+1) = 1.0
  484. ! calculate surface rate and mass mixing ratio for aerosol
  485. surfratemax = 0.0
  486. nsav=1
  487. nnew=2
  488. surfrate_drop=depvel_drop/dz(kts)
  489. surfratemax = max( surfratemax, surfrate_drop )
  490. do n=1,ntype_aer
  491. do m=1,nsize_aer(n)
  492. lnum=numptr_aer(m,n,ai_phase)
  493. lnumcw=numptr_aer(m,n,cw_phase)
  494. if(lnum>0)then
  495. depvel_tmp = max( 0.0, min( ddvel(i,j,lnum), depvel_uplimit ) )
  496. surfrate(lnum)=depvel_tmp/dz(kts)
  497. surfrate(lnumcw)=surfrate_drop
  498. surfratemax = max( surfratemax, surfrate(lnum) )
  499. ! scale = 1000./mwdry ! moles/kg
  500. scale = 1.
  501. raercol(kts:kte,lnumcw,nsav)=chem(i,kts:kte,j,lnumcw)*scale ! #/kg
  502. raercol(kts:kte,lnum,nsav)=chem(i,kts:kte,j,lnum)*scale
  503. endif
  504. do l=1,ncomp(n)
  505. lmass=massptr_aer(l,m,n,ai_phase)
  506. lmasscw=massptr_aer(l,m,n,cw_phase)
  507. ! scale = mw_aer(l,n)/mwdry
  508. scale = 1.e-9 ! kg/ug
  509. depvel_tmp = max( 0.0, min( ddvel(i,j,lmass), depvel_uplimit ) )
  510. surfrate(lmass)=depvel_tmp/dz(kts)
  511. surfrate(lmasscw)=surfrate_drop
  512. surfratemax = max( surfratemax, surfrate(lmass) )
  513. raercol(kts:kte,lmasscw,nsav)=chem(i,kts:kte,j,lmasscw)*scale ! kg/kg
  514. raercol(kts:kte,lmass,nsav)=chem(i,kts:kte,j,lmass)*scale ! kg/kg
  515. enddo
  516. lwater=waterptr_aer(m,n)
  517. if(lwater>0)then
  518. depvel_tmp = max( 0.0, min( ddvel(i,j,lwater), depvel_uplimit ) )
  519. surfrate(lwater)=depvel_tmp/dz(kts)
  520. surfratemax = max( surfratemax, surfrate(lwater) )
  521. raercol(kts:kte,lwater,nsav)=chem(i,kts:kte,j,lwater) ! don't bother to convert units,
  522. ! because it doesn't contribute to aerosol mass
  523. endif
  524. enddo ! size
  525. enddo ! type
  526. ! mass conservation checking
  527. if (icheck_colmass > 0) then
  528. ! calc initial column burdens
  529. colmass_bgn(:,:,:,:) = 0.0
  530. colmass_end(:,:,:,:) = 0.0
  531. colmass_sfc(:,:,:,:) = 0.0
  532. rhodz(kts:kte) = 1.0/zn(kts:kte)
  533. rhodzsum = sum( rhodz(kts:kte) )
  534. do n=1,ntype_aer
  535. do m=1,nsize_aer(n)
  536. lnum=numptr_aer(m,n,ai_phase)
  537. lnumcw=numptr_aer(m,n,cw_phase)
  538. if(lnum>0)then
  539. colmass_bgn(0,m,n,1) = sum( chem(i,kts:kte,j,lnum )*rhodz(kts:kte) )
  540. colmass_bgn(0,m,n,2) = sum( chem(i,kts:kte,j,lnumcw)*rhodz(kts:kte) )
  541. endif
  542. do l=1,ncomp(n)
  543. lmass=massptr_aer(l,m,n,ai_phase)
  544. lmasscw=massptr_aer(l,m,n,cw_phase)
  545. colmass_bgn(l,m,n,1) = sum( chem(i,kts:kte,j,lmass )*rhodz(kts:kte) )
  546. colmass_bgn(l,m,n,2) = sum( chem(i,kts:kte,j,lmasscw)*rhodz(kts:kte) )
  547. enddo
  548. enddo ! size
  549. enddo ! type
  550. endif ! (icheck_colmass > 0)
  551. ! droplet nucleation/aerosol activation
  552. ! k-loop for growing/shrinking cloud calcs .............................
  553. GROW_SHRINK_MAIN_K_LOOP: do k=kts,kte
  554. km1=max0(k-1,1)
  555. kp1=min0(k+1,kde-1)
  556. ! if(lcldfra(k)-lcldfra_old(k).gt.0.01)then ! this line is the "old" criterion
  557. ! go to 10
  558. ! growing cloud PLUS
  559. ! upwards vertical advection when lcldfra(k-1) < lcldfra(k)
  560. !
  561. ! tmpc1 = cloud fraction increase from previous time step
  562. tmpc1 = max( (lcldfra(k)-lcldfra_old(k)), 0.0 )
  563. if (k > kts) then
  564. ! tmpc2 = fraction of layer for which vertical advection from below
  565. ! (over dtstep) displaces cloudy air with clear air
  566. ! = (courant number using upwards w at layer bottom)*(difference in cloud fraction)
  567. tmpcourno = dtstep*max(w(i,k,j),0.0)/dz(k)
  568. tmpc2 = max( (lcldfra(k)-lcldfra(km1)), 0.0 ) * tmpcourno
  569. tmpc2 = min( tmpc2, 1.0 )
  570. ! tmpc2 = 0.0 ! this turns off the vertical advect part
  571. else
  572. tmpc2 = 0.0
  573. endif
  574. if ((tmpc1 > 0.001) .or. (tmpc2 > 0.001)) then
  575. ! wmix=wtke(k)
  576. wbar=w(i,k,j)+wtke(k)
  577. wmix=0.
  578. wmin=0.
  579. ! 06-nov-2005 rce - increase wmax from 10 to 50 (deep convective clouds)
  580. wmax=50.
  581. wdiab=0
  582. ! load aerosol properties, assuming external mixtures
  583. do n=1,ntype_aer
  584. do m=1,nsize_aer(n)
  585. call loadaer(raercol(1,1,nsav),k,kms,kme,num_chem, &
  586. cs(k), npv(m,n), dlo_sect(m,n),dhi_sect(m,n), &
  587. maxd_acomp, ncomp(n), &
  588. grid_id, ktau, i, j, m, n, &
  589. numptr_aer(m,n,ai_phase),numptr_aer(m,n,cw_phase), &
  590. dens_aer(1,n), &
  591. massptr_aer(1,m,n,ai_phase), massptr_aer(1,m,n,cw_phase), &
  592. maerosol(1,m,n), maerosolcw(1,m,n), &
  593. maerosol_tot(m,n), maerosol_totcw(m,n), &
  594. naerosol(m,n), naerosolcw(m,n), &
  595. vaerosol(m,n), vaerosolcw(m,n) )
  596. hygro_aer(m,n)=hygro(i,k,j,m,n)
  597. enddo
  598. enddo
  599. ! 06-nov-2005 rce - grid_id & ktau added to arg list
  600. call activate(wbar,wmix,wdiab,wmin,wmax,temp(i,k,j),cs(k), &
  601. msectional, maxd_atype, ntype_aer, maxd_asize, nsize_aer, &
  602. naerosol, vaerosol, &
  603. dlo_sect,dhi_sect,sigmag_aer,hygro_aer, &
  604. fn,fs,fm,fluxn,fluxs,fluxm,flux_fullact(k), grid_id, ktau, i, j, k )
  605. do n = 1,ntype_aer
  606. do m = 1,nsize_aer(n)
  607. lnum = numptr_aer(m,n,ai_phase)
  608. lnumcw = numptr_aer(m,n,cw_phase)
  609. if (tmpc1 > 0.0) then
  610. dact = tmpc1*fn(m,n)*raercol(k,lnum,nsav) ! interstitial only
  611. else
  612. dact = 0.0
  613. endif
  614. if (tmpc2 > 0.0) then
  615. dact = dact + tmpc2*fn(m,n)*raercol(km1,lnum,nsav) ! interstitial only
  616. endif
  617. dact = min( dact, 0.99*raercol(k,lnum,nsav) )
  618. raercol(k,lnumcw,nsav) = raercol(k,lnumcw,nsav)+dact
  619. raercol(k,lnum, nsav) = raercol(k,lnum, nsav)-dact
  620. qndrop(k) = qndrop(k)+dact
  621. nsource(i,k,j) = nsource(i,k,j)+dact*dtinv
  622. do l = 1,ncomp(n)
  623. lmass = massptr_aer(l,m,n,ai_phase)
  624. lmasscw = massptr_aer(l,m,n,cw_phase)
  625. if (tmpc1 > 0.0) then
  626. dact = tmpc1*fm(m,n)*raercol(k,lmass,nsav) ! interstitial only
  627. else
  628. dact = 0.0
  629. endif
  630. if (tmpc2 > 0.0) then
  631. dact = dact + tmpc2*fm(m,n)*raercol(km1,lmass,nsav) ! interstitial only
  632. endif
  633. dact = min( dact, 0.99*raercol(k,lmass,nsav) )
  634. raercol(k,lmasscw,nsav) = raercol(k,lmasscw,nsav)+dact
  635. raercol(k,lmass, nsav) = raercol(k,lmass, nsav)-dact
  636. enddo
  637. enddo
  638. enddo
  639. ! 10 continue
  640. endif ! ((tmpc1 > 0.001) .or. (tmpc2 > 0.001))
  641. if(lcldfra(k) < lcldfra_old(k) .and. lcldfra_old(k) > 1.e-20)then ! this line is the "old" criterion
  642. ! go to 20
  643. ! shrinking cloud ......................................................
  644. ! droplet loss in decaying cloud
  645. nsource(i,k,j)=nsource(i,k,j)+qndrop(k)*(lcldfra(k)-lcldfra_old(k))*dtinv
  646. qndrop(k)=qndrop(k)*(1.+lcldfra(k)-lcldfra_old(k))
  647. ! convert activated aerosol to interstitial in decaying cloud
  648. tmpc = (lcldfra(k)-lcldfra_old(k))/lcldfra_old(k)
  649. do n=1,ntype_aer
  650. do m=1,nsize_aer(n)
  651. lnum=numptr_aer(m,n,ai_phase)
  652. lnumcw=numptr_aer(m,n,cw_phase)
  653. if(lnum.gt.0)then
  654. dact=raercol(k,lnumcw,nsav)*tmpc
  655. raercol(k,lnumcw,nsav)=raercol(k,lnumcw,nsav)+dact
  656. raercol(k,lnum,nsav)=raercol(k,lnum,nsav)-dact
  657. endif
  658. do l=1,ncomp(n)
  659. lmass=massptr_aer(l,m,n,ai_phase)
  660. lmasscw=massptr_aer(l,m,n,cw_phase)
  661. dact=raercol(k,lmasscw,nsav)*tmpc
  662. raercol(k,lmasscw,nsav)=raercol(k,lmasscw,nsav)+dact
  663. raercol(k,lmass,nsav)=raercol(k,lmass,nsav)-dact
  664. enddo
  665. enddo
  666. enddo
  667. ! 20 continue
  668. endif
  669. enddo GROW_SHRINK_MAIN_K_LOOP
  670. ! end of k-loop for growing/shrinking cloud calcs ......................
  671. ! ......................................................................
  672. ! start of main k-loop for calc of old cloud activation tendencies ..........
  673. ! this loop does "set up" for the nsubmix loop
  674. !
  675. ! rce-comment
  676. ! changed this part of code to use current cloud fraction (lcldfra) exclusively
  677. OLD_CLOUD_MAIN_K_LOOP: do k=kts,kte
  678. km1=max0(k-1,kts)
  679. kp1=min0(k+1,kde-1)
  680. flux_fullact(k) = 0.0
  681. if(lcldfra(k).gt.0.01)then
  682. ! go to 30
  683. ! old cloud
  684. if(lcldfra(k)-lcldfra(km1).gt.0.01.or.k.eq.kts)then
  685. ! interior cloud
  686. ! cloud base
  687. wdiab=0
  688. wmix=wtke(k) ! spectrum of updrafts
  689. wbar=w(i,k,j) ! spectrum of updrafts
  690. ! wmix=0. ! single updraft
  691. ! wbar=wtke(k) ! single updraft
  692. ! 06-nov-2005 rce - increase wmax from 10 to 50 (deep convective clouds)
  693. wmax=50.
  694. ekd(k)=wtke(k)*dz(k)/sq2pi
  695. alogarg=max(1.e-20,1/lcldfra(k)-1.)
  696. wmin=wbar+wmix*0.25*sq2pi*alog(alogarg)
  697. do n=1,ntype_aer
  698. do m=1,nsize_aer(n)
  699. call loadaer(raercol(1,1,nsav),km1,kms,kme,num_chem, &
  700. cs(k), npv(m,n),dlo_sect(m,n),dhi_sect(m,n), &
  701. maxd_acomp, ncomp(n), &
  702. grid_id, ktau, i, j, m, n, &
  703. numptr_aer(m,n,ai_phase),numptr_aer(m,n,cw_phase), &
  704. dens_aer(1,n), &
  705. massptr_aer(1,m,n,ai_phase), massptr_aer(1,m,n,cw_phase), &
  706. maerosol(1,m,n), maerosolcw(1,m,n), &
  707. maerosol_tot(m,n), maerosol_totcw(m,n), &
  708. naerosol(m,n), naerosolcw(m,n), &
  709. vaerosol(m,n), vaerosolcw(m,n) )
  710. hygro_aer(m,n)=hygro(i,k,j,m,n)
  711. enddo
  712. enddo
  713. ! print *,'old cloud wbar,wmix=',wbar,wmix
  714. call activate(wbar,wmix,wdiab,wmin,wmax,temp(i,k,j),cs(k), &
  715. msectional, maxd_atype, ntype_aer, maxd_asize, nsize_aer, &
  716. naerosol, vaerosol, &
  717. dlo_sect,dhi_sect, sigmag_aer,hygro_aer, &
  718. fn,fs,fm,fluxn,fluxs,fluxm,flux_fullact(k), grid_id, ktau, i, j, k )
  719. ! rce-comment
  720. ! the activation-fraction fluxes (fluxn, fluxm) from subr activate assume that
  721. ! wbar << wmix, which is valid for global-model scale but not mesoscale
  722. ! for wrf-chem application, divide these by flux_fullact to get a
  723. ! "flux-weighted-average" activation fraction, then multiply by (ekd(k)*zs(k))
  724. ! which is the local "turbulent vertical-mixing velocity"
  725. if (k > kts) then
  726. if (flux_fullact(k) > 1.0e-20) then
  727. tmpa = ekd(k)*zs(k)
  728. tmpf = flux_fullact(k)
  729. do n=1,ntype_aer
  730. do m=1,nsize_aer(n)
  731. tmpb = max( fluxn(m,n), 0.0 ) / max( fluxn(m,n), tmpf )
  732. fluxn(m,n) = tmpa*tmpb
  733. tmpb = max( fluxm(m,n), 0.0 ) / max( fluxm(m,n), tmpf )
  734. fluxm(m,n) = tmpa*tmpb
  735. enddo
  736. enddo
  737. else
  738. fluxn(:,:) = 0.0
  739. fluxm(:,:) = 0.0
  740. endif
  741. endif
  742. if(k.gt.kts)then
  743. tmpc = lcldfra(k)-lcldfra(km1)
  744. else
  745. tmpc=lcldfra(k)
  746. endif
  747. ! rce-comment
  748. ! flux of activated mass into layer k (in kg/m2/s)
  749. ! = "actmassflux" = dumc*fluxm*raercol(kp1,lmass)*csbot(k)
  750. ! source of activated mass (in kg/kg/s) = flux divergence
  751. ! = actmassflux/(cs(i,k)*dz(i,k))
  752. ! so need factor of csbot_cscen = csbot(k)/cs(i,k)
  753. ! tmpe=1./(dz(k))
  754. tmpe = csbot_cscen(k)/(dz(k))
  755. fluxntot=0.
  756. do n=1,ntype_aer
  757. do m=1,nsize_aer(n)
  758. fluxn(m,n)=fluxn(m,n)*tmpc
  759. ! fluxs(m,n)=fluxs(m,n)*tmpc
  760. fluxm(m,n)=fluxm(m,n)*tmpc
  761. lnum=numptr_aer(m,n,ai_phase)
  762. fluxntot=fluxntot+fluxn(m,n)*raercol(km1,lnum,nsav)
  763. ! print *,'fn=',fn(m,n),' for m,n=',m,n
  764. ! print *,'old cloud tmpc=',tmpc,' fn=',fn(m,n),' for m,n=',m,n
  765. nact(k,m,n)=nact(k,m,n)+fluxn(m,n)*tmpe
  766. mact(k,m,n)=mact(k,m,n)+fluxm(m,n)*tmpe
  767. enddo
  768. enddo
  769. flux_fullact(k) = flux_fullact(k)*tmpe
  770. nsource(i,k,j)=nsource(i,k,j)+fluxntot*zs(k)
  771. fluxntot=fluxntot*cs(k)
  772. endif
  773. ! 30 continue
  774. else
  775. ! go to 40
  776. ! no cloud
  777. if(qndrop(k).gt.10000.e6)then
  778. print *,'i,k,j,lcldfra,qndrop=',i,k,j,lcldfra(k),qndrop(k)
  779. print *,'cldfra,ql,qi',cldfra(i,k,j),qc(i,k,j),qi(i,k,j)
  780. endif
  781. nsource(i,k,j)=nsource(i,k,j)-qndrop(k)*dtinv
  782. qndrop(k)=0.
  783. ! convert activated aerosol to interstitial in decaying cloud
  784. do n=1,ntype_aer
  785. do m=1,nsize_aer(n)
  786. lnum=numptr_aer(m,n,ai_phase)
  787. lnumcw=numptr_aer(m,n,cw_phase)
  788. if(lnum.gt.0)then
  789. raercol(k,lnum,nsav)=raercol(k,lnum,nsav)+raercol(k,lnumcw,nsav)
  790. raercol(k,lnumcw,nsav)=0.
  791. endif
  792. do l=1,ncomp(n)
  793. lmass=massptr_aer(l,m,n,ai_phase)
  794. lmasscw=massptr_aer(l,m,n,cw_phase)
  795. raercol(k,lmass,nsav)=raercol(k,lmass,nsav)+raercol(k,lmasscw,nsav)
  796. raercol(k,lmasscw,nsav)=0.
  797. enddo
  798. enddo
  799. enddo
  800. ! 40 continue
  801. endif
  802. enddo OLD_CLOUD_MAIN_K_LOOP
  803. ! cycle OVERALL_MAIN_I_LOOP
  804. ! switch nsav, nnew so that nnew is the updated aerosol
  805. ntemp=nsav
  806. nsav=nnew
  807. nnew=ntemp
  808. ! load new droplets in layers above, below clouds
  809. dtmin=dtstep
  810. ekk(kts)=0.0
  811. ! rce-comment -- ekd(k) is eddy-diffusivity at k/k-1 interface
  812. ! want ekk(k) = ekd(k) * (density at k/k-1 interface)
  813. do k=kts+1,kte
  814. ekk(k)=ekd(k)*csbot(k)
  815. enddo
  816. ekk(kte+1)=0.0
  817. do k=kts,kte
  818. ekkp(k)=zn(k)*ekk(k+1)*zs(k+1)
  819. ekkm(k)=zn(k)*ekk(k)*zs(k)
  820. tinv=ekkp(k)+ekkm(k)
  821. if(k.eq.kts)tinv=tinv+surfratemax
  822. if(tinv.gt.1.e-6)then
  823. dtt=1./tinv
  824. dtmin=min(dtmin,dtt)
  825. endif
  826. enddo
  827. dtmix=0.9*dtmin
  828. nsubmix=dtstep/dtmix+1
  829. if(nsubmix>100)then
  830. nsubmix_bnd=100
  831. else
  832. nsubmix_bnd=nsubmix
  833. endif
  834. ! count_submix(nsubmix_bnd)=count_submix(nsubmix_bnd)+1
  835. dtmix=dtstep/nsubmix
  836. fac_srflx = -1.0/(zn(1)*nsubmix)
  837. do k=kts,kte
  838. kp1=min(k+1,kde-1)
  839. km1=max(k-1,1)
  840. if(lcldfra(kp1).gt.0)then
  841. overlapp(k)=min(lcldfra(k)/lcldfra(kp1),1.)
  842. else
  843. overlapp(k)=1.
  844. endif
  845. if(lcldfra(km1).gt.0)then
  846. overlapm(k)=min(lcldfra(k)/lcldfra(km1),1.)
  847. else
  848. overlapm(k)=1.
  849. endif
  850. enddo
  851. ! ......................................................................
  852. ! start of nsubmix-loop for calc of old cloud activation tendencies ....
  853. OLD_CLOUD_NSUBMIX_LOOP: do nsub=1,nsubmix
  854. qndrop_new(kts:kte)=qndrop(kts:kte)
  855. ! switch nsav, nnew so that nsav is the updated aerosol
  856. ntemp=nsav
  857. nsav=nnew
  858. nnew=ntemp
  859. srcn(:)=0.0
  860. do n=1,ntype_aer
  861. do m=1,nsize_aer(n)
  862. lnum=numptr_aer(m,n,ai_phase)
  863. ! update droplet source
  864. ! rce-comment - activation source in layer k involves particles from k-1
  865. ! srcn(kts :kte)=srcn(kts :kte)+nact(kts :kte,m,n)*(raercol(kts:kte ,lnum,nsav))
  866. srcn(kts+1:kte)=srcn(kts+1:kte)+nact(kts+1:kte,m,n)*(raercol(kts:kte-1,lnum,nsav))
  867. ! rce-comment - new formulation for k=kts should be implemented
  868. srcn(kts )=srcn(kts )+nact(kts ,m,n)*(raercol(kts ,lnum,nsav))
  869. enddo
  870. enddo
  871. call explmix(qndrop,srcn,ekkp,ekkm,overlapp,overlapm, &
  872. qndrop_new,surfrate_drop,kms,kme,kts,kte,dtmix,.false.)
  873. do n=1,ntype_aer
  874. do m=1,nsize_aer(n)
  875. lnum=numptr_aer(m,n,ai_phase)
  876. lnumcw=numptr_aer(m,n,cw_phase)
  877. if(lnum>0)then
  878. ! rce-comment - activation source in layer k involves particles from k-1
  879. ! source(kts :kte)= nact(kts :kte,m,n)*(raercol(kts:kte ,lnum,nsav))
  880. source(kts+1:kte)= nact(kts+1:kte,m,n)*(raercol(kts:kte-1,lnum,nsav))
  881. ! rce-comment - new formulation for k=kts should be implemented
  882. source(kts )= nact(kts ,m,n)*(raercol(kts ,lnum,nsav))
  883. call explmix(raercol(1,lnumcw,nnew),source,ekkp,ekkm,overlapp,overlapm, &
  884. raercol(1,lnumcw,nsav),surfrate(lnumcw),kms,kme,kts,kte,dtmix,&
  885. .false.)
  886. call explmix(raercol(1,lnum,nnew),source,ekkp,ekkm,overlapp,overlapm, &
  887. raercol(1,lnum,nsav),surfrate(lnum),kms,kme,kts,kte,dtmix, &
  888. .true.,raercol(1,lnumcw,nsav))
  889. qsrflx(i,j,lnum) = qsrflx(i,j,lnum) + fac_srflx* &
  890. raercol(kts,lnum,nsav)*surfrate(lnum)
  891. qsrflx(i,j,lnumcw) = qsrflx(i,j,lnumcw) + fac_srflx* &
  892. raercol(kts,lnumcw,nsav)*surfrate(lnumcw)
  893. if (icheck_colmass > 0) then
  894. tmpf = dtmix*rhodz(kts)
  895. colmass_sfc(0,m,n,1) = colmass_sfc(0,m,n,1) &
  896. + raercol(kts,lnum ,nsav)*surfrate(lnum )*tmpf
  897. colmass_sfc(0,m,n,2) = colmass_sfc(0,m,n,2) &
  898. + raercol(kts,lnumcw,nsav)*surfrate(lnumcw)*tmpf
  899. endif
  900. endif
  901. do l=1,ncomp(n)
  902. lmass=massptr_aer(l,m,n,ai_phase)
  903. lmasscw=massptr_aer(l,m,n,cw_phase)
  904. ! rce-comment - activation source in layer k involves particles from k-1
  905. ! source(kts :kte)= mact(kts :kte,m,n)*(raercol(kts:kte ,lmass,nsav))
  906. source(kts+1:kte)= mact(kts+1:kte,m,n)*(raercol(kts:kte-1,lmass,nsav))
  907. ! rce-comment - new formulation for k=kts should be implemented
  908. source(kts )= mact(kts ,m,n)*(raercol(kts ,lmass,nsav))
  909. call explmix(raercol(1,lmasscw,nnew),source,ekkp,ekkm,overlapp,overlapm, &
  910. raercol(1,lmasscw,nsav),surfrate(lmasscw),kms,kme,kts,kte,dtmix, &
  911. .false.)
  912. call explmix(raercol(1,lmass,nnew),source,ekkp,ekkm,overlapp,overlapm, &
  913. raercol(1,lmass,nsav),surfrate(lmass),kms,kme,kts,kte,dtmix, &
  914. .true.,raercol(1,lmasscw,nsav))
  915. qsrflx(i,j,lmass) = qsrflx(i,j,lmass) + fac_srflx* &
  916. raercol(kts,lmass,nsav)*surfrate(lmass)
  917. qsrflx(i,j,lmasscw) = qsrflx(i,j,lmasscw) + fac_srflx* &
  918. raercol(kts,lmasscw,nsav)*surfrate(lmasscw)
  919. if (icheck_colmass > 0) then
  920. ! colmass_sfc calculation
  921. ! colmass_bgn/end = bgn/end column burden = sum.over.k.of{ rho(k)*dz(k)*chem(k,l) }
  922. ! colmass_sfc = surface loss over dtstep
  923. ! = sum.over.nsubmix.substeps{ depvel(l)*rho(kts)*chem(kts,l)*dtmix }
  924. ! surfrate(l) = depvel(l)/dz(kts) so need to multiply by dz(kts)
  925. ! for mass, raercol(k,l) = chem(k,l)*1.0e-9, so need to multiply by 1.0e9
  926. tmpf = dtmix*rhodz(kts)*1.0e9
  927. colmass_sfc(l,m,n,1) = colmass_sfc(l,m,n,1) &
  928. + raercol(kts,lmass ,nsav)*surfrate(lmass )*tmpf
  929. colmass_sfc(l,m,n,2) = colmass_sfc(l,m,n,2) &
  930. + raercol(kts,lmasscw,nsav)*surfrate(lmasscw)*tmpf
  931. endif
  932. enddo
  933. lwater=waterptr_aer(m,n) ! aerosol water
  934. if(lwater>0)then
  935. source(:)=0.
  936. call explmix( raercol(1,lwater,nnew),source,ekkp,ekkm,overlapp,overlapm, &
  937. raercol(1,lwater,nsav),surfrate(lwater),kms,kme,kts,kte,dtmix, &
  938. .true.,source)
  939. endif
  940. enddo ! size
  941. enddo ! type
  942. enddo OLD_CLOUD_NSUBMIX_LOOP
  943. ! cycle OVERALL_MAIN_I_LOOP
  944. ! evaporate particles again if no cloud
  945. do k=kts,kte
  946. if(lcldfra(k).eq.0.)then
  947. ! no cloud
  948. qndrop(k)=0.
  949. ! convert activated aerosol to interstitial in decaying cloud
  950. do n=1,ntype_aer
  951. do m=1,nsize_aer(n)
  952. lnum=numptr_aer(m,n,ai_phase)
  953. lnumcw=numptr_aer(m,n,cw_phase)
  954. if(lnum.gt.0)then
  955. raercol(k,lnum,nnew)=raercol(k,lnum,nnew)+raercol(k,lnumcw,nnew)
  956. raercol(k,lnumcw,nnew)=0.
  957. endif
  958. do l=1,ncomp(n)
  959. lmass=massptr_aer(l,m,n,ai_phase)
  960. lmasscw=massptr_aer(l,m,n,cw_phase)
  961. raercol(k,lmass,nnew)=raercol(k,lmass,nnew)+raercol(k,lmasscw,nnew)
  962. raercol(k,lmasscw,nnew)=0.
  963. enddo
  964. enddo
  965. enddo
  966. endif
  967. enddo
  968. ! cycle OVERALL_MAIN_I_LOOP
  969. ! droplet number
  970. do k=kts,kte
  971. ! if(lcldfra(k).gt.0.1)then
  972. ! write(6,'(a,3i5,f12.1)')'i,j,k,qndrop=',i,j,k,qndrop(k)
  973. ! endif
  974. if(qndrop(k).lt.-10.e6.or.qndrop(k).gt.1.e12)then
  975. write(6,'(a,g12.2,a,3i5)')'after qndrop=',qndrop(k),' for i,k,j=',i,k,j
  976. endif
  977. qndrop3d(i,k,j) = max(qndrop(k),1.e-6)
  978. if(qndrop3d(i,k,j).lt.-10.e6.or.qndrop3d(i,k,j).gt.1.E20)then
  979. write(6,'(a,g12.2,a,3i5)')'after qndrop3d=',qndrop3d(i,k,j),' for i,k,j=',i,k,j
  980. endif
  981. if(qc(i,k,j).lt.-1..or.qc(i,k,j).gt.1.)then
  982. write(6,'(a,g12.2,a,3i5)')'qc=',qc(i,k,j),' for i,k,j=',i,k,j
  983. call wrf_error_fatal("1")
  984. endif
  985. if(qi(i,k,j).lt.-1..or.qi(i,k,j).gt.1.)then
  986. write(6,'(a,g12.2,a,3i5)')'qi=',qi(i,k,j),' for i,k,j=',i,k,j
  987. call wrf_error_fatal("1")
  988. endif
  989. if(qv(i,k,j).lt.-1..or.qv(i,k,j).gt.1.)then
  990. write(6,'(a,g12.2,a,3i5)')'qv=',qv(i,k,j),' for i,k,j=',i,k,j
  991. call wrf_error_fatal("1")
  992. endif
  993. cldfra_old(i,k,j) = cldfra(i,k,j)
  994. ! if(k.gt.6.and.k.lt.11)cldfra_old(i,k,j)=1.
  995. enddo
  996. ! cycle OVERALL_MAIN_I_LOOP
  997. ! update chem and convert back to mole/mole
  998. ccn(:,:) = 0.
  999. do n=1,ntype_aer
  1000. do m=1,nsize_aer(n)
  1001. lnum=numptr_aer(m,n,ai_phase)
  1002. lnumcw=numptr_aer(m,n,cw_phase)
  1003. if(lnum.gt.0)then
  1004. ! scale=mwdry*0.001
  1005. scale = 1.
  1006. chem(i,kts:kte,j,lnumcw)= raercol(kts:kte,lnumcw,nnew)*scale
  1007. chem(i,kts:kte,j,lnum)= raercol(kts:kte,lnum,nnew)*scale
  1008. endif
  1009. do l=1,ncomp(n)
  1010. lmass=massptr_aer(l,m,n,ai_phase)
  1011. lmasscw=massptr_aer(l,m,n,cw_phase)
  1012. ! scale = mwdry/mw_aer(l,n)
  1013. scale = 1.e9
  1014. chem(i,kts:kte,j,lmasscw)=raercol(kts:kte,lmasscw,nnew)*scale ! ug/kg
  1015. chem(i,kts:kte,j,lmass)=raercol(kts:kte,lmass,nnew)*scale ! ug/kg
  1016. enddo
  1017. lwater=waterptr_aer(m,n)
  1018. if(lwater>0)chem(i,kts:kte,j,lwater)=raercol(kts:kte,lwater,nnew) ! don't convert units
  1019. do k=kts,kte
  1020. sm=2.*aten*sqrt(aten/(27.*hygro(i,k,j,m,n)*amcube(m,n)))
  1021. do l=1,psat
  1022. arg=argfactor(m,n)*log(sm/super(l))
  1023. if(arg<2)then
  1024. if(arg<-2)then
  1025. ccnfact(l,m,n)=1.e-6 ! convert from #/m3 to #/cm3
  1026. else
  1027. ccnfact(l,m,n)=1.e-6*0.5*ERFC_NUM_RECIPES(arg)
  1028. endif
  1029. else
  1030. ccnfact(l,m,n) = 0.
  1031. endif
  1032. ! ccn concentration as diagnostic
  1033. ! assume same hygroscopicity and ccnfact for cloud-phase and aerosol phase particles
  1034. ccn(k,l)=ccn(k,l)+(raercol(k,lnum,nnew)+raercol(k,lnumcw,nnew))*cs(k)*ccnfact(l,m,n)
  1035. enddo
  1036. enddo
  1037. enddo
  1038. enddo
  1039. do l=1,psat
  1040. !wig, 22-Nov-2006: added vertical bounds to prevent out-of-bounds at top
  1041. if(l.eq.1)ccn1(i,kts:kte,j)=ccn(:,l)
  1042. if(l.eq.2)ccn2(i,kts:kte,j)=ccn(:,l)
  1043. if(l.eq.3)ccn3(i,kts:kte,j)=ccn(:,l)
  1044. if(l.eq.4)ccn4(i,kts:kte,j)=ccn(:,l)
  1045. if(l.eq.5)ccn5(i,kts:kte,j)=ccn(:,l)
  1046. if(l.eq.6)ccn6(i,kts:kte,j)=ccn(:,l)
  1047. end do
  1048. ! mass conservation checking
  1049. if (icheck_colmass > 0) then
  1050. ! calc final column burdens
  1051. do n=1,ntype_aer
  1052. do m=1,nsize_aer(n)
  1053. lnum=numptr_aer(m,n,ai_phase)
  1054. lnumcw=numptr_aer(m,n,cw_phase)
  1055. if(lnum>0)then
  1056. colmass_end(0,m,n,1) = sum( chem(i,kts:kte,j,lnum )*rhodz(kts:kte) )
  1057. colmass_end(0,m,n,2) = sum( chem(i,kts:kte,j,lnumcw)*rhodz(kts:kte) )
  1058. endif
  1059. do l=1,ncomp(n)
  1060. lmass=massptr_aer(l,m,n,ai_phase)
  1061. lmasscw=massptr_aer(l,m,n,cw_phase)
  1062. colmass_end(l,m,n,1) = sum( chem(i,kts:kte,j,lmass )*rhodz(kts:kte) )
  1063. colmass_end(l,m,n,2) = sum( chem(i,kts:kte,j,lmasscw)*rhodz(kts:kte) )
  1064. enddo
  1065. enddo ! size
  1066. enddo ! type
  1067. ! calc burden change errors for each interstitial/activated pair
  1068. do n=1,ntype_aer
  1069. do m=1,nsize_aer(n)
  1070. do l=0,ncomp(n)

Large files files are truncated, but you can click here to view the full file