PartMC  2.2.1
nucleate.F90
Go to the documentation of this file.
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