PartMC
2.1.5
|
00001 ! Copyright (C) 2010, 2011 Matthew West 00002 ! Licensed under the GNU General Public License version 2 or (at your 00003 ! option) any later version. See the file COPYING for details. 00004 00005 !> \file 00006 !> The pmc_nucleate module. 00007 00008 !> Aerosol nucleation functions. 00009 module pmc_nucleate 00010 00011 use pmc_env_state 00012 use pmc_bin_grid 00013 use pmc_aero_state 00014 use pmc_aero_data 00015 use pmc_gas_data 00016 use pmc_gas_state 00017 00018 !> Type code for unknown or invalid nucleation type. 00019 integer, parameter :: NUCLEATE_TYPE_INVALID = 0 00020 !> Type code for H2SO4 to SO4 nucleation with quadratic rate. 00021 integer, parameter :: NUCLEATE_TYPE_SULF_ACID = 1 00022 00023 contains 00024 00025 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00026 00027 !> Do nucleation of the type given by the first argument. 00028 subroutine nucleate(nucleate_type, bin_grid, env_state, gas_data, & 00029 aero_data, aero_weight, aero_state, gas_state, del_t) 00030 00031 !> Type of nucleation. 00032 integer, intent(in) :: nucleate_type 00033 !> Bin grid. 00034 type(bin_grid_t), intent(in) :: bin_grid 00035 !> Environment state. 00036 type(env_state_t), intent(in) :: env_state 00037 !> Gas data. 00038 type(gas_data_t), intent(in) :: gas_data 00039 !> Aerosol data. 00040 type(aero_data_t), intent(in) :: aero_data 00041 !> Aerosol weight. 00042 type(aero_weight_t), intent(in) :: aero_weight 00043 !> Aerosol state. 00044 type(aero_state_t), intent(inout) :: aero_state 00045 !> Gas state. 00046 type(gas_state_t), intent(inout) :: gas_state 00047 !> Time to perform nucleation for. 00048 real(kind=dp), intent(in) :: del_t 00049 00050 if (nucleate_type == NUCLEATE_TYPE_SULF_ACID) then 00051 call nucleate_sulf_acid(bin_grid, env_state, gas_data, aero_data, & 00052 aero_weight, aero_state, gas_state, del_t) 00053 else 00054 call die_msg(983831728, & 00055 "unknown nucleation type: " & 00056 // trim(integer_to_string(nucleate_type))) 00057 end if 00058 00059 end subroutine nucleate 00060 00061 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00062 00063 !> Nucleate sulfuric acid into aerosol particles, using a power-law 00064 !> dependence, for time \c del_t. 00065 !! 00066 !! The modeled emission rate is \f$ J = K H^2 \f$, where \f$H\f$ is 00067 !! the concentration of \f$ \rm H_2SO_4 \f$ and \f$K\f$ is a 00068 !! constant coefficient. 00069 !! 00070 !! The reference is: 00071 !! 00072 !! C. Kuang, P. H. McMurry, A. V. McCormick, and F. L. Eisele 00073 !! (2008), Dependence of nucleation rates on sulfuric acid vapor 00074 !! concentration in diverse atmospheric locations, 00075 !! <i>J. Geophys. Res.</i>, 113, D10209, doi:<a 00076 !! href="http://dx.doi.org/10.1029/2007JD009253">10.1029/2007JD009253</a>. 00077 subroutine nucleate_sulf_acid(bin_grid, env_state, gas_data, aero_data, & 00078 aero_weight, aero_state, gas_state, del_t) 00079 00080 !> Bin grid. 00081 type(bin_grid_t), intent(in) :: bin_grid 00082 !> Environment state. 00083 type(env_state_t), intent(in) :: env_state 00084 !> Gas data. 00085 type(gas_data_t), intent(in) :: gas_data 00086 !> Aerosol data. 00087 type(aero_data_t), intent(in) :: aero_data 00088 !> Aerosol weight. 00089 type(aero_weight_t), intent(in) :: aero_weight 00090 !> Aerosol state. 00091 type(aero_state_t), intent(inout) :: aero_state 00092 !> Gas state. 00093 type(gas_state_t), intent(inout) :: gas_state 00094 !> Time to perform nucleation for. 00095 real(kind=dp), intent(in) :: del_t 00096 00097 real(kind=dp), parameter :: nucleate_coeff = 1d-18 ! K (m^3 s^{-1}) 00098 real(kind=dp), parameter :: nucleate_diam = 1d-9 ! diameter of new 00099 ! particles (m) 00100 00101 integer :: i_gas_h2so4, i_aero_so4, n_samp, i_samp, i_bin 00102 real(kind=dp) :: sulf_acid_conc, nucleate_rate, n_samp_avg 00103 real(kind=dp) :: total_so4_vol, vol, h2so4_removed_conc 00104 real(kind=dp) :: nucleate_comp_vol 00105 type(aero_particle_t) :: aero_particle 00106 00107 ! look up the species numbers 00108 i_gas_h2so4 = gas_data_spec_by_name(gas_data, "H2SO4") 00109 call assert_msg(886839228, i_gas_h2so4 > 0, & 00110 "nucleate_sulf_acid requires H2SO4 as a gas species") 00111 i_aero_so4 = aero_data_spec_by_name(aero_data, "SO4") 00112 call assert_msg(551966998, i_aero_so4 > 0, & 00113 "nucleate_sulf_acid requires SO4 as an aerosol species") 00114 00115 ! H2SO4 concentration in molecules / m^3 00116 sulf_acid_conc = env_state_ppb_to_conc(env_state, & 00117 gas_state%mix_rat(i_gas_h2so4)) 00118 00119 ! particle nucleation rate in (particles m^{-3} s^{-1}) 00120 nucleate_rate = nucleate_coeff * sulf_acid_conc**2 00121 00122 ! computational volume at the size of nucleated particles (only 00123 ! valid for mono-disperse nucleation) 00124 nucleate_comp_vol = aero_state%comp_vol & 00125 / aero_weight_value(aero_weight, nucleate_diam / 2d0) 00126 00127 ! determine number of nucleated particles 00128 n_samp_avg = nucleate_rate * nucleate_comp_vol * del_t 00129 n_samp = rand_poisson(n_samp_avg) 00130 00131 ! create the particles 00132 call aero_particle_allocate_size(aero_particle, aero_data%n_spec, & 00133 aero_data%n_source) 00134 total_so4_vol = 0d0 00135 do i_samp = 1,n_samp 00136 vol = diam2vol(nucleate_diam) 00137 total_so4_vol = total_so4_vol + vol 00138 00139 aero_particle%vol(i_aero_so4) = vol 00140 call aero_particle_new_id(aero_particle) 00141 call aero_particle_set_create_time(aero_particle, & 00142 env_state%elapsed_time) 00143 i_bin = aero_particle_in_bin(aero_particle, bin_grid) 00144 call aero_state_add_particle(aero_state, i_bin, aero_particle) 00145 end do 00146 call aero_particle_deallocate(aero_particle) 00147 00148 ! remove gases that formed new particles 00149 h2so4_removed_conc = & 00150 total_so4_vol * aero_data%density(i_aero_so4) & 00151 / aero_data%molec_weight(i_aero_so4) & ! moles of SO4 00152 * const%avagadro & ! molecules of SO4 00153 / nucleate_comp_vol ! molecules / m^3 00154 gas_state%mix_rat(i_gas_h2so4) = gas_state%mix_rat(i_gas_h2so4) & 00155 - env_state_conc_to_ppb(env_state, h2so4_removed_conc) 00156 if (gas_state%mix_rat(i_gas_h2so4) < 0d0) then 00157 gas_state%mix_rat(i_gas_h2so4) = 0d0 00158 end if 00159 00160 end subroutine nucleate_sulf_acid 00161 00162 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00163 00164 subroutine spec_file_read_nucleate_type(file, nucleate_type) 00165 00166 !> Spec file. 00167 type(spec_file_t), intent(inout) :: file 00168 !> Aerosol weight. 00169 integer, intent(out) :: nucleate_type 00170 00171 character(len=SPEC_LINE_MAX_VAR_LEN) :: nucleate_type_name 00172 00173 !> \page input_format_nucleate Input File Format: Nucleation Parameterization 00174 !! 00175 !! The nucleation parameterization is specified by the parameter: 00176 !! - \b nucleate (string): the type of nucleation 00177 !! parameterization --- must be one of: "none" for no 00178 !! nucleation; or "sulf_acid" for the nucleate_sulf_acid() 00179 !! parameterization 00180 !! 00181 !! See also: 00182 !! - \ref spec_file_format --- the input file text format 00183 00184 call spec_file_read_string(file, 'nucleate', nucleate_type_name) 00185 if (nucleate_type_name == 'sulf_acid') then 00186 nucleate_type = NUCLEATE_TYPE_SULF_ACID 00187 else 00188 call spec_file_die_msg(707263678, file, "unknown nucleate type: " & 00189 // trim(nucleate_type_name)) 00190 end if 00191 00192 end subroutine spec_file_read_nucleate_type 00193 00194 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00195 00196 end module pmc_nucleate