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