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