PartMC 2.1.4
coag_kernel_brown.F90
Go to the documentation of this file.
00001 ! Copyright (C) 2005-2011 Nicole Riemer and Matthew West
00002 ! Copyright (C) 2007 Richard Easter
00003 ! Licensed under the GNU General Public License version 2 or (at your
00004 ! option) any later version. See the file COPYING for details.
00005     
00006 !> \file
00007 !> The pmc_coag_kernel_brown module.
00008 
00009 !> Brownian coagulation kernel.
00010 module pmc_coag_kernel_brown
00011 
00012   use pmc_env_state
00013   use pmc_constants
00014   use pmc_util
00015   use pmc_aero_particle
00016   
00017 contains
00018 
00019 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00020 
00021   !> Compute the Brownian coagulation kernel.
00022   !!
00023   !! Uses equation (16.28) of M. Z. Jacobson, Fundamentals of
00024   !! Atmospheric Modeling, Cambridge University Press, 1999.
00025   subroutine kernel_brown(aero_particle_1, aero_particle_2, &
00026        aero_data, env_state, k)
00027 
00028     !> First particle.
00029     type(aero_particle_t), intent(in) :: aero_particle_1
00030     !> Second particle.
00031     type(aero_particle_t), intent(in) :: aero_particle_2
00032     !> Aerosol data.
00033     type(aero_data_t), intent(in) :: aero_data
00034     !> Environment state.
00035     type(env_state_t), intent(in) :: env_state
00036     !> Kernel k(a,b) (m^3/s).
00037     real(kind=dp), intent(out) :: k
00038 
00039     real(kind=dp) :: v1, v2, d1, d2
00040 
00041     v1 = aero_particle_volume(aero_particle_1)
00042     v2 = aero_particle_volume(aero_particle_2)
00043     d1 = aero_particle_density(aero_particle_1, aero_data)
00044     d2 = aero_particle_density(aero_particle_2, aero_data)
00045 
00046     call kernel_brown_helper(v1, d1, v2, d2, env_state%temp, &
00047          env_state%pressure, k)
00048 
00049   end subroutine kernel_brown
00050 
00051 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00052 
00053   !> Compute the maximum Brownian coagulation kernel.
00054   !!
00055   !! Finds the maximum kernel value between particles of volumes v1
00056   !! and v2, by sampling over possible densities.
00057   subroutine kernel_brown_max(v1, v2, aero_data, env_state, k_max)
00058 
00059     !> Volume of first particle (m^3).
00060     real(kind=dp), intent(in) :: v1
00061     !> Volume of second particle (m^3).
00062     real(kind=dp), intent(in) :: v2
00063     !> Aerosol data.
00064     type(aero_data_t), intent(in) :: aero_data
00065     !> Environment state.
00066     type(env_state_t), intent(in) :: env_state
00067     !> Maximum kernel value (m^3/s).
00068     real(kind=dp), intent(out) :: k_max
00069 
00070     !> Number of density sample points.
00071     integer, parameter :: n_sample = 3
00072 
00073     real(kind=dp) :: d1, d2, d_min, d_max, k
00074     integer :: i, j
00075     
00076     d_min = minval(aero_data%density)
00077     d_max = maxval(aero_data%density)
00078     
00079     k_max = 0d0
00080     do i = 1,n_sample
00081        do j = 1,n_sample
00082           d1 = d_max * real(n_sample - i, kind=dp) 
00083                / real(n_sample - 1, kind=dp) + 
00084                d_min * real(i - 1, kind=dp) / real(n_sample - 1, kind=dp)
00085           d2 = d_max * real(n_sample - j, kind=dp) 
00086                / real(n_sample - 1, kind=dp) + 
00087                d_min * real(j - 1, kind=dp) / real(n_sample - 1, kind=dp)
00088           call kernel_brown_helper(v1, d1, v2, d2, env_state%temp, &
00089                env_state%pressure, k)
00090           if (k > k_max) k_max = k
00091        end do
00092     end do
00093 
00094   end subroutine kernel_brown_max
00095 
00096 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00097 
00098   !> Helper function that does the actual Brownian kernel computation.
00099   !!
00100   !! Helper function. Do not call directly. Instead use kernel_brown().
00101   !!
00102   !! Uses equation (16.28) of M. Z. Jacobson, Fundamentals of
00103   !! Atmospheric Modeling, Cambridge University Press, 1999.
00104   subroutine kernel_brown_helper(v1, d1, v2, d2, tk, press, bckernel)
00105 
00106     !> Volume of first particle (m^3).
00107     real(kind=dp), intent(in) :: v1
00108     !> Density of first particle (kg/m^3).
00109     real(kind=dp), intent(in) :: d1
00110     !> Volume of second particle (m^3).
00111     real(kind=dp), intent(in) :: v2
00112     !> Density of second particle (kg/m^3).
00113     real(kind=dp), intent(in) :: d2
00114     !> Temperature (K).
00115     real(kind=dp), intent(in) :: tk
00116     !> Pressure (Pa).
00117     real(kind=dp), intent(in) :: press
00118     !> Kernel k(a,b) (m^3/s).
00119     real(kind=dp), intent(out) :: bckernel
00120 
00121     integer, parameter :: nbin_maxd = 1000
00122     integer, save :: nbin = 0
00123     real(kind=dp), save :: rad_sv(nbin_maxd)
00124     real(kind=dp) :: avogad, bckernel1, boltz, cunning, deltasq_i, 
00125          deltasq_j, den_i, den_j, diffus_i, diffus_j, diffus_sum, 
00126          freepath, gasfreepath, gasspeed, knud, mwair, rad_i, rad_j, 
00127          rad_sum, rgas, rhoair, speedsq_i, speedsq_j, tmp1, tmp2, 
00128          viscosd, viscosk, vol_i, vol_j
00129 
00130     ! boltz   = boltzmann's constant (erg/K = g*cm^2/s/K)
00131     ! avogad  = avogadro's number (molecules/mol)
00132     ! mwair   = molecular weight of air (g/mol)
00133     ! rgas    = gas constant (atmos/(mol/liter)/K)
00134     ! rhoair  = air density (g/cm^3)
00135     ! viscosd = air dynamic viscosity (g/cm/s)
00136     ! viscosk = air kinematic viscosity (cm^2/s)
00137     ! gasspeed    = air molecule mean thermal velocity (cm/s)
00138     ! gasfreepath = air molecule mean free path (cm)
00139 
00140     boltz = const%boltzmann * 1d7 ! J/K to erg/K
00141     avogad = const%avagadro
00142     mwair = const%air_molec_weight * 1d3 ! kg/mole to g/mole
00143     rgas = const%univ_gas_const * 1d-2 ! J/mole/K to atmos/(mol/liter)/K
00144     
00145     rhoair = 0.001d0 * ((press/1.01325d5)*mwair/(rgas*tk))
00146     
00147     viscosd = (1.8325d-04*(296.16d0+120d0)/(tk+120d0)) * (tk/296.16d0)**1.5d0
00148     viscosk = viscosd/rhoair
00149     gasspeed = sqrt(8d0*boltz*tk*avogad/(const%pi*mwair))
00150     gasfreepath = 2d0*viscosk/gasspeed
00151 
00152     ! coagulation kernel from eqn 16.28 of jacobson (1999) text
00153     !
00154     ! diffus_i/j  = particle brownian diffusion coefficient  (cm^2/s)
00155     ! speedsq_i/j = square of particle mean thermal velocity (cm/s)
00156     ! freepath    = particle mean free path (cm)
00157     ! cunning     = cunningham slip-flow correction factor
00158     ! deltasq_i/j = square of "delta_i" in eqn 16.29d0
00159     !
00160     ! bckernel1   = brownian coagulation kernel (cm3/s)
00161 
00162     den_i     = d1 * 1.0d-3   ! particle wet density (g/cm3)
00163     vol_i     = v1 * 1.0d+6   ! particle wet volume (cm3)
00164     rad_i     = vol2rad(vol_i)       ! particle wet radius (cm)
00165     
00166     knud      = gasfreepath/rad_i  
00167     cunning   = 1d0 + knud*(1.249d0 + 0.42d0*exp(-0.87d0/knud))
00168     diffus_i  = boltz*tk*cunning/(6d0*const%pi*rad_i*viscosd)
00169     speedsq_i = 8d0*boltz*tk/(const%pi*den_i*vol_i)
00170     freepath  = 8d0*diffus_i/(const%pi*sqrt(speedsq_i))
00171     tmp1      = (2d0*rad_i + freepath)**3
00172     tmp2      = (4d0*rad_i*rad_i + freepath*freepath)**1.5d0
00173     deltasq_i = ( (tmp1-tmp2)/(6d0*rad_i*freepath) - 2d0*rad_i )**2
00174     
00175     den_j     = d2 * 1.0d-3
00176     vol_j     = v2 * 1.0d+6
00177     rad_j     = vol2rad(vol_j)
00178     
00179     knud      = gasfreepath/rad_j  
00180     cunning   = 1d0 + knud*(1.249d0 + 0.42d0*exp(-0.87d0/knud))
00181     diffus_j  = boltz*tk*cunning/(6d0*const%pi*rad_j*viscosd)
00182     speedsq_j = 8d0*boltz*tk/(const%pi*den_j*vol_j)
00183     freepath  = 8d0*diffus_j/(const%pi*sqrt(speedsq_j))
00184     tmp1      = (2d0*rad_j + freepath)**3
00185     tmp2      = (4d0*rad_j*rad_j + freepath*freepath)**1.5d0
00186     deltasq_j = ( (tmp1-tmp2)/(6d0*rad_j*freepath) - 2d0*rad_j )**2
00187     
00188     rad_sum    = rad_i + rad_j
00189     diffus_sum = diffus_i + diffus_j 
00190     tmp1       = rad_sum/(rad_sum + sqrt(deltasq_i + deltasq_j))
00191     tmp2       = 4d0*diffus_sum/(rad_sum*sqrt(speedsq_i + speedsq_j))
00192     bckernel1  = 4d0*const%pi*rad_sum*diffus_sum/(tmp1 + tmp2)
00193     
00194     bckernel   = bckernel1 * 1.0d-6
00195     
00196   end subroutine kernel_brown_helper
00197   
00198 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00199   
00200 end module pmc_coag_kernel_brown