PartMC
2.2.1
|
00001 ! Copyright (C) 2007-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_coag_kernel_zero module. 00007 00008 !> Constant kernel equal to zero. 00009 !! 00010 !! This is only of interest for the exact solution to the 00011 !! no-coagulation, no-condensation case that can be used to test 00012 !! emissions and background dilution. 00013 module pmc_coag_kernel_zero 00014 00015 use pmc_bin_grid 00016 use pmc_env_state 00017 use pmc_util 00018 use pmc_aero_binned 00019 use pmc_aero_dist 00020 use pmc_aero_data 00021 use pmc_aero_data 00022 use pmc_aero_particle 00023 00024 contains 00025 00026 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00027 00028 !> Zero coagulation kernel. 00029 subroutine kernel_zero(aero_particle_1, aero_particle_2, & 00030 aero_data, env_state, k) 00031 00032 !> First particle. 00033 type(aero_particle_t), intent(in) :: aero_particle_1 00034 !> Second particle. 00035 type(aero_particle_t), intent(in) :: aero_particle_2 00036 !> Aerosol data. 00037 type(aero_data_t), intent(in) :: aero_data 00038 !> Environment state. 00039 type(env_state_t), intent(in) :: env_state 00040 !> Coagulation kernel. 00041 real(kind=dp), intent(out) :: k 00042 00043 k = 0d0 00044 00045 end subroutine kernel_zero 00046 00047 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00048 00049 !> Minimum and maximum of the zero coagulation kernel. 00050 subroutine kernel_zero_minmax(v1, v2, aero_data, env_state, k_min, k_max) 00051 00052 !> Volume of first particle. 00053 real(kind=dp), intent(in) :: v1 00054 !> Volume of second particle. 00055 real(kind=dp), intent(in) :: v2 00056 !> Aerosol data. 00057 type(aero_data_t), intent(in) :: aero_data 00058 !> Environment state. 00059 type(env_state_t), intent(in) :: env_state 00060 !> Coagulation kernel minimum value. 00061 real(kind=dp), intent(out) :: k_min 00062 !> Coagulation kernel maximum value. 00063 real(kind=dp), intent(out) :: k_max 00064 00065 k_min = 0d0 00066 k_max = 0d0 00067 00068 end subroutine kernel_zero_minmax 00069 00070 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00071 00072 !> Exact solution with the zero coagulation kernel. Only useful for 00073 !> testing emissions and background dilution. 00074 !! 00075 !! With only constant-rate emissions and dilution the number 00076 !! distribution \f$n(D,t)\f$ at diameter \f$D\f$ and time \f$t\f$ 00077 !! satisfies: 00078 !! \f[ 00079 !! \frac{d n(D,t)}{dt} = k_{\rm emit} n_{\rm emit}(D) 00080 !! + k_{\rm dilute} (n_{\rm back}(D) - n(D,t)) 00081 !! \f] 00082 !! together with the initial condition \f$ n(D,0) = n_0(D) \f$. Here 00083 !! \f$n_{\rm emit}(D)\f$ and \f$n_{\rm back}(D)\f$ are emission and 00084 !! background size distributions, with corresponding rates \f$k_{\rm 00085 !! emit}\f$ and \f$k_{\rm dilute}\f$. All values are taken at time 00086 !! \f$t = 0\f$ and held constant, so there is no support for 00087 !! time-varying emissions or background dilution. 00088 !! 00089 !! This is a family of ODEs parameterized by \f$D\f$ with 00090 !! solution: 00091 !! \f[ 00092 !! n(D,t) = n_{\infty}(D) 00093 !! + (n_0(D) - n_{\infty}(D)) \exp(-k_{\rm dilute} t) 00094 !! \f] 00095 !! where the steady state limit is: 00096 !! \f[ 00097 !! n_{\infty}(D) = n(D,\infty) 00098 !! = n_{\rm back}(D) 00099 !! + \frac{k_{\rm emit}}{k_{\rm dilute}} n_{\rm emit}(D) 00100 !! \f] 00101 subroutine soln_zero(bin_grid, aero_data, time, aero_dist_init, & 00102 env_state, aero_binned) 00103 00104 !> Bin grid. 00105 type(bin_grid_t), intent(in) :: bin_grid 00106 !> Aerosol data. 00107 type(aero_data_t), intent(in) :: aero_data 00108 !> Current time (s). 00109 real(kind=dp), intent(in) :: time 00110 !> Initial distribution. 00111 type(aero_dist_t), intent(in) :: aero_dist_init 00112 !> Environment state. 00113 type(env_state_t), intent(in) :: env_state 00114 !> Output state. 00115 type(aero_binned_t), intent(inout) :: aero_binned 00116 00117 type(aero_binned_t) :: aero_binned_limit 00118 00119 if (env_state%aero_dilution_rate == 0d0) then 00120 call aero_binned_zero(aero_binned) 00121 call aero_binned_add_aero_dist(aero_binned, bin_grid, aero_data, & 00122 env_state%aero_emissions) 00123 call aero_binned_scale(aero_binned, & 00124 env_state%aero_emission_rate * time / env_state%height) 00125 else 00126 ! calculate the limit steady state distribution 00127 call aero_binned_allocate_size(aero_binned_limit, bin_grid%n_bin, & 00128 aero_data%n_spec) 00129 call aero_binned_add_aero_dist(aero_binned_limit, bin_grid, & 00130 aero_data, env_state%aero_emissions) 00131 call aero_binned_scale(aero_binned_limit, & 00132 env_state%aero_emission_rate / env_state%height & 00133 / env_state%aero_dilution_rate) 00134 call aero_binned_add_aero_dist(aero_binned_limit, bin_grid, & 00135 aero_data, env_state%aero_background) 00136 00137 ! calculate the current state 00138 call aero_binned_zero(aero_binned) 00139 call aero_binned_add_aero_dist(aero_binned, bin_grid, aero_data, & 00140 aero_dist_init) 00141 call aero_binned_sub(aero_binned, aero_binned_limit) 00142 call aero_binned_scale(aero_binned, & 00143 exp(-env_state%aero_dilution_rate * time)) 00144 call aero_binned_add(aero_binned, aero_binned_limit) 00145 00146 call aero_binned_deallocate(aero_binned_limit) 00147 end if 00148 00149 end subroutine soln_zero 00150 00151 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00152 00153 end module pmc_coag_kernel_zero