PartMC  2.2.1
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 minimum and maximum Brownian coagulation kernel.
00054   !!
00055   !! Finds the minimum and maximum kernel values between particles of
00056   !! volumes v1 and v2, by sampling over possible densities.
00057   subroutine kernel_brown_minmax(v1, v2, aero_data, env_state, k_min, 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     !> Minimum kernel value (m^3/s).
00068     real(kind=dp), intent(out) :: k_min
00069     !> Maximum kernel value (m^3/s).
00070     real(kind=dp), intent(out) :: k_max
00071 
00072     !> Number of density sample points.
00073     integer, parameter :: n_sample = 3
00074 
00075     real(kind=dp) :: d1, d2, d_min, d_max, k
00076     integer :: i, j
00077     logical :: first
00078     
00079     d_min = minval(aero_data%density)
00080     d_max = maxval(aero_data%density)
00081 
00082     first = .true.
00083     do i = 1,n_sample
00084        do j = 1,n_sample
00085           d1 = interp_linear_disc(d_min, d_max, n_sample, i)
00086           d2 = interp_linear_disc(d_min, d_max, n_sample, j)
00087           call kernel_brown_helper(v1, d1, v2, d2, &
00088                env_state%temp, env_state%pressure, k)
00089           if (first) then
00090              first = .false.
00091              k_min = k
00092              k_max = k
00093           else
00094              k_min = min(k_min, k)
00095              k_max = max(k_max, k)
00096           end if
00097        end do
00098     end do
00099 
00100   end subroutine kernel_brown_minmax
00101 
00102 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00103 
00104   !> Helper function that does the actual Brownian kernel computation.
00105   !!
00106   !! Helper function. Do not call directly. Instead use kernel_brown().
00107   !!
00108   !! Uses equation (16.28) of M. Z. Jacobson, Fundamentals of
00109   !! Atmospheric Modeling, Cambridge University Press, 1999.
00110   subroutine kernel_brown_helper(v1, d1, v2, d2, tk, press, bckernel)
00111 
00112     !> Volume of first particle (m^3).
00113     real(kind=dp), intent(in) :: v1
00114     !> Density of first particle (kg/m^3).
00115     real(kind=dp), intent(in) :: d1
00116     !> Volume of second particle (m^3).
00117     real(kind=dp), intent(in) :: v2
00118     !> Density of second particle (kg/m^3).
00119     real(kind=dp), intent(in) :: d2
00120     !> Temperature (K).
00121     real(kind=dp), intent(in) :: tk
00122     !> Pressure (Pa).
00123     real(kind=dp), intent(in) :: press
00124     !> Kernel k(a,b) (m^3/s).
00125     real(kind=dp), intent(out) :: bckernel
00126 
00127     integer, parameter :: nbin_maxd = 1000
00128     integer, save :: nbin = 0
00129     real(kind=dp), save :: rad_sv(nbin_maxd)
00130     real(kind=dp) :: avogad, bckernel1, boltz, cunning, deltasq_i, 
00131          deltasq_j, den_i, den_j, diffus_i, diffus_j, diffus_sum, 
00132          freepath, gasfreepath, gasspeed, knud, mwair, rad_i, rad_j, 
00133          rad_sum, rgas, rhoair, speedsq_i, speedsq_j, tmp1, tmp2, 
00134          viscosd, viscosk, vol_i, vol_j
00135 
00136     ! boltz   = boltzmann's constant (erg/K = g*cm^2/s/K)
00137     ! avogad  = avogadro's number (molecules/mol)
00138     ! mwair   = molecular weight of air (g/mol)
00139     ! rgas    = gas constant (atmos/(mol/liter)/K)
00140     ! rhoair  = air density (g/cm^3)
00141     ! viscosd = air dynamic viscosity (g/cm/s)
00142     ! viscosk = air kinematic viscosity (cm^2/s)
00143     ! gasspeed    = air molecule mean thermal velocity (cm/s)
00144     ! gasfreepath = air molecule mean free path (cm)
00145 
00146     boltz = const%boltzmann * 1d7 ! J/K to erg/K
00147     avogad = const%avagadro
00148     mwair = const%air_molec_weight * 1d3 ! kg/mole to g/mole
00149     rgas = const%univ_gas_const * 1d-2 ! J/mole/K to atmos/(mol/liter)/K
00150     
00151     rhoair = 0.001d0 * ((press/1.01325d5)*mwair/(rgas*tk))
00152     
00153     viscosd = (1.8325d-04*(296.16d0+120d0)/(tk+120d0)) * (tk/296.16d0)**1.5d0
00154     viscosk = viscosd/rhoair
00155     gasspeed = sqrt(8d0*boltz*tk*avogad/(const%pi*mwair))
00156     gasfreepath = 2d0*viscosk/gasspeed
00157 
00158     ! coagulation kernel from eqn 16.28 of jacobson (1999) text
00159     !
00160     ! diffus_i/j  = particle brownian diffusion coefficient  (cm^2/s)
00161     ! speedsq_i/j = square of particle mean thermal velocity (cm/s)
00162     ! freepath    = particle mean free path (cm)
00163     ! cunning     = cunningham slip-flow correction factor
00164     ! deltasq_i/j = square of "delta_i" in eqn 16.29d0
00165     !
00166     ! bckernel1   = brownian coagulation kernel (cm3/s)
00167 
00168     den_i     = d1 * 1.0d-3   ! particle wet density (g/cm3)
00169     vol_i     = v1 * 1.0d+6   ! particle wet volume (cm3)
00170     rad_i     = vol2rad(vol_i)       ! particle wet radius (cm)
00171     
00172     knud      = gasfreepath/rad_i  
00173     cunning   = 1d0 + knud*(1.249d0 + 0.42d0*exp(-0.87d0/knud))
00174     diffus_i  = boltz*tk*cunning/(6d0*const%pi*rad_i*viscosd)
00175     speedsq_i = 8d0*boltz*tk/(const%pi*den_i*vol_i)
00176     freepath  = 8d0*diffus_i/(const%pi*sqrt(speedsq_i))
00177     tmp1      = (2d0*rad_i + freepath)**3
00178     tmp2      = (4d0*rad_i*rad_i + freepath*freepath)**1.5d0
00179     deltasq_i = ( (tmp1-tmp2)/(6d0*rad_i*freepath) - 2d0*rad_i )**2
00180     
00181     den_j     = d2 * 1.0d-3
00182     vol_j     = v2 * 1.0d+6
00183     rad_j     = vol2rad(vol_j)
00184     
00185     knud      = gasfreepath/rad_j  
00186     cunning   = 1d0 + knud*(1.249d0 + 0.42d0*exp(-0.87d0/knud))
00187     diffus_j  = boltz*tk*cunning/(6d0*const%pi*rad_j*viscosd)
00188     speedsq_j = 8d0*boltz*tk/(const%pi*den_j*vol_j)
00189     freepath  = 8d0*diffus_j/(const%pi*sqrt(speedsq_j))
00190     tmp1      = (2d0*rad_j + freepath)**3
00191     tmp2      = (4d0*rad_j*rad_j + freepath*freepath)**1.5d0
00192     deltasq_j = ( (tmp1-tmp2)/(6d0*rad_j*freepath) - 2d0*rad_j )**2
00193     
00194     rad_sum    = rad_i + rad_j
00195     diffus_sum = diffus_i + diffus_j 
00196     tmp1       = rad_sum/(rad_sum + sqrt(deltasq_i + deltasq_j))
00197     tmp2       = 4d0*diffus_sum/(rad_sum*sqrt(speedsq_i + speedsq_j))
00198     bckernel1  = 4d0*const%pi*rad_sum*diffus_sum/(tmp1 + tmp2)
00199     
00200     bckernel   = bckernel1 * 1.0d-6
00201     
00202   end subroutine kernel_brown_helper
00203   
00204 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00205   
00206 end module pmc_coag_kernel_brown