! Include shortname defintions, so that the F77 code does not have to be modified to ! reference the CARMA structure. #include "carma_globaer.h" !! This routine calculates particle source terms due to evaporation . !! !! @author Andy Ackerman !! @version Aug-2001 subroutine evapp(carma, cstate, iz, rc) ! types use carma_precision_mod use carma_enums_mod use carma_constants_mod use carma_types_mod use carmastate_mod use carma_mod implicit none type(carma_type), intent(in) :: carma !! the carma object type(carmastate_type), intent(inout) :: cstate !! the carma state object integer, intent(in) :: iz !! z index integer, intent(inout) :: rc !! return code, negative indicates failure ! Local declarations integer :: ibin !! bin index integer :: ielem !! element index integer :: ig !! source group index integer :: ip !! source number concentration element integer :: ic integer :: ic1 !! element of first core mass in group integer :: iecore integer :: ieto integer :: igto integer :: iavg logical :: evap_total real(kind=f) :: sig_mono real(kind=f) :: coretot real(kind=f) :: coremom real(kind=f) :: smf integer :: nbin ! Define criterion for monodisperse core mass distributions sig_mono = sqrt( ALMOST_ZERO ) ! Loop over source groups (from which evaporation is being treated) do ig = 1, NGROUP ip = ienconc(ig) ! No evaporation unless particles are volatile if( itype(ip) .eq. I_VOLATILE )then ! Make sure that these always get intializaed, since they can ! cause problems in other parts of the code if they aren't. totevap(:,ig) = .false. cmf(:,ig) = 0._f if (pconmax(iz, ig) > FEW_PC) then ic1 = icorelem(1,ig) ! Loop over source bins and calculate temporary evaporation source ! for droplets in next smaller bin assuming no total evaporation do ibin = 1, NBIN evdrop = pc(iz,ibin,ip)*evaplg(ibin,ig) ! Check for evaporation of a sufficient number of droplets ! if( evdrop .gt. 0._f .and. pc(iz,ibin,ip) .gt. SMALL_PC )then if( evdrop .gt. 0._f )then ! No cores: transfer droplets within group if( ic1 .eq. 0 )then call evap_ingrp(carma,cstate,iz,ibin,ig,ip,rc) else ! First core is not involatile (therefore none are) ! -- this is a hack until enforced/checked in setupbins() -- ! transfer droplets within group ! if( itype(ic1) .ne. I_COREMASS )then call evap_ingrp(carma,cstate,iz,ibin,ig,ip,rc) else ! Have cores: calculate the amount of the source term ! by number associated with total evaporation of secondary cores coretot = pc(iz,ibin,ic1) do ic = 2, ncore(ig) iecore = icorelem(ic,ig) if( itype(iecore) .eq. I_COREMASS )then coretot = coretot + pc(iz,ibin,iecore) endif enddo do ic = 2, ncore(ig) iecore = icorelem(ic,ig) if( itype(iecore) .eq. I_COREMASS )then evcore(ic) = evdrop*pc(iz,ibin,iecore)/coretot endif enddo ! Calculate average particle core mass and fraction coreavg = coretot / pc(iz,ibin,ip) coreavg = min( rmass(ibin,ig), coreavg ) cmf(ibin,ig) = coreavg / rmass(ibin,ig) ! cmf(ibin,ig) = max( 0., min( ONE, cmf(ibin,ig) ) ) ! Get target number concentration element and group for total evaporation ! and evaluate logical flags regarding position on CN bin and index of ! target CN bin ieto = ievp2elem(ic1) igto = igelem(ieto) too_small = coreavg .lt. rmass(1,igto) nbin = NBIN too_big = coreavg .gt. rmass(nbin,igto) if( .not. (too_small .or. too_big) )then iavg = log( coreavg / rmassmin(igto) ) / & log( rmrat(igto) ) + 2 iavg = min( iavg, NBIN ) endif ! Only consider size of evaporating cores relative to nuc_small ! when treating core second moment for this particle group if( if_sec_mom(ig) )then nuc_small = coreavg .lt. rmass(1,igto) else nuc_small = .false. endif ! Want total evaporation when ! cores smaller than smallest nucleated ! OR evaporating droplets are in bin 1 ! OR droplets will be created with core mass fraction > 1 evap_total = nuc_small .or. ibin .eq. 1 .or. & rmrat(ig)*cmf(ibin,ig) .gt. ONE ! No core second moment: evaporate to monodisperse CN cores or within group.! if( .not. if_sec_mom(ig) )then if( evap_total )then call evap_mono(carma,cstate,iz,ibin,ig,iavg,ieto,igto,rc) else call evap_ingrp(carma,cstate,iz,ibin,ig,ip,rc) endif ! Have core second moments: evaporate to mono- or polydisperse CN cores ! or within group. First calculate average core second moment , ! second moment fraction , and square of the logarithm of the geometric ! standard deviation of the assumed core mass distribution . else coremom = pc(iz,ibin,imomelem(ig)) / pc(iz,ibin,ip) smf = coremom / rmass(ibin,ig)**2 coresig = log( smf / cmf(ibin,ig)**2 ) ! Want total evaporation for above reasons ! OR droplets will be created with core moment fraction > 1 evap_total = evap_total .or. rmrat(ig)**2*smf .gt. ONE if( evap_total )then ! Want monodisperse total evaporation when ! cores smaller than smallest nucleated ! OR evaporating core distribution is narrow ! Otherwise want polydisperse total evaporation if( nuc_small .or. coresig .le. sig_mono )then call evap_mono(carma,cstate,iz,ibin,ig,iavg,ieto,igto,rc) else call evap_poly(carma,cstate,iz,ibin,ig,iavg,ieto,igto,rc) endif ! Droplet evaporation within group else call evap_ingrp(carma,cstate,iz,ibin,ig,ip,rc) endif endif ! if_sec_mom(ig) endif ! itype(ic1) endif ! ic1=0 endif ! evaplg > 0 enddo ! ibin=1,NBIN endif ! enough particles endif ! volatile particles enddo ! ig=1,NGROUP ! Return to caller with evaporation production terms evaluated. return end