PartMC
2.2.0
|
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