PartMC  2.6.1
coag_kernel_zero.F90
Go to the documentation of this file.
1 ! Copyright (C) 2007-2016 Matthew West
2 ! Licensed under the GNU General Public License version 2 or (at your
3 ! option) any later version. See the file COPYING for details.
4 
5 !> \file
6 !> The pmc_coag_kernel_zero module.
7 
8 !> Constant kernel equal to zero.
9 !!
10 !! This is only of interest for the exact solution to the
11 !! no-coagulation, no-condensation case that can be used to test
12 !! emissions and background dilution.
14 
15  use pmc_bin_grid
16  use pmc_scenario
17  use pmc_env_state
18  use pmc_util
19  use pmc_aero_binned
20  use pmc_aero_dist
21  use pmc_aero_data
23 
24 contains
25 
26 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
27 
28  !> Zero coagulation kernel.
29  subroutine kernel_zero(aero_particle_1, aero_particle_2, &
30  aero_data, env_state, k)
31 
32  !> First particle.
33  type(aero_particle_t), intent(in) :: aero_particle_1
34  !> Second particle.
35  type(aero_particle_t), intent(in) :: aero_particle_2
36  !> Aerosol data.
37  type(aero_data_t), intent(in) :: aero_data
38  !> Environment state.
39  type(env_state_t), intent(in) :: env_state
40  !> Coagulation kernel.
41  real(kind=dp), intent(out) :: k
42 
43  k = 0d0
44 
45  end subroutine kernel_zero
46 
47 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
48 
49  !> Minimum and maximum of the zero coagulation kernel.
50  subroutine kernel_zero_minmax(v1, v2, aero_data, env_state, k_min, k_max)
51 
52  !> Volume of first particle.
53  real(kind=dp), intent(in) :: v1
54  !> Volume of second particle.
55  real(kind=dp), intent(in) :: v2
56  !> Aerosol data.
57  type(aero_data_t), intent(in) :: aero_data
58  !> Environment state.
59  type(env_state_t), intent(in) :: env_state
60  !> Coagulation kernel minimum value.
61  real(kind=dp), intent(out) :: k_min
62  !> Coagulation kernel maximum value.
63  real(kind=dp), intent(out) :: k_max
64 
65  k_min = 0d0
66  k_max = 0d0
67 
68  end subroutine kernel_zero_minmax
69 
70 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
71 
72  !> Exact solution with the zero coagulation kernel. Only useful for
73  !> testing emissions, background dilution, and proportional loss functions.
74  !!
75  !! With only constant-rate emissions, dilutionm, and proportional losses
76  !! the numberdistribution \f$n(D,t)\f$ at diameter \f$D\f$ and time \f$t\f$
77  !! satisfies:
78  !! \f[
79  !! \frac{d n(D,t)}{dt} = k_{\rm emit} n_{\rm emit}(D)
80  !! + (k_{\rm dilute} + k_{\rm loss}(D)) (n_{\rm back}(D) - n(D,t))
81  !! \f]
82  !! together with the initial condition \f$ n(D,0) = n_0(D) \f$. Here
83  !! \f$n_{\rm emit}(D)\f$ and \f$n_{\rm back}(D)\f$ are emission and
84  !! background size distributions, with corresponding rates \f$k_{\rm
85  !! emit}\f$ and \f$k_{\rm dilute}\f$. An optional loss function
86  !! \f$k_{\rm loss}(D)\f$ can be used to specify a size-dependent
87  !! rate at which particles are lost. All values are taken at time
88  !! \f$t = 0\f$ and held constant, so there is no support for
89  !! time-varying emissions, background dilution, or loss functions.
90  !!
91  !! This is a family of ODEs parameterized by \f$D\f$ with
92  !! solution:
93  !! \f[
94  !! n(D,t) = n_{\infty}(D)
95  !! + (n_0(D) - n_{\infty}(D)) \exp(
96  !! -(k_{\rm dilute} + k_{\rm loss}(D)) t)
97  !! \f]
98  !! where the steady state limit is:
99  !! \f[
100  !! n_{\infty}(D) = n(D,\infty)
101  !! = n_{\rm back}(D)
102  !! + \frac{k_{\rm emit}}{k_{\rm dilute}
103  !! + k_{\rm loss}(D)} n_{\rm emit}(D)
104  !! \f]
105  subroutine soln_zero(bin_grid, aero_data, time, aero_dist_init, &
106  scenario, env_state, aero_binned)
107 
108  !> Bin grid.
109  type(bin_grid_t), intent(in) :: bin_grid
110  !> Aerosol data.
111  type(aero_data_t), intent(in) :: aero_data
112  !> Current time (s).
113  real(kind=dp), intent(in) :: time
114  !> Initial distribution.
115  type(aero_dist_t), intent(in) :: aero_dist_init
116  !> Scenario.
117  type(scenario_t), intent(in) :: scenario
118  !> Environment state.
119  type(env_state_t), intent(in) :: env_state
120  !> Output state.
121  type(aero_binned_t), intent(inout) :: aero_binned
122 
123  integer :: i
124  real(kind=dp) :: emission_rate_scale, dilution_rate, p
125  real(kind=dp), allocatable :: loss_array(:)
126  type(aero_dist_t) :: emissions, background
127  type(aero_binned_t) :: background_binned, aero_binned_limit
128 
129  logical, save :: already_warned_water = .false.
130 
131  call aero_binned_set_sizes(aero_binned, bin_grid_size(bin_grid), &
132  aero_data_n_spec(aero_data))
133  call aero_binned_set_sizes(background_binned, &
134  bin_grid_size(bin_grid), aero_data_n_spec(aero_data))
135 
136  call aero_dist_interp_1d(scenario%aero_emission, &
137  scenario%aero_emission_time, scenario%aero_emission_rate_scale, &
138  env_state%elapsed_time, emissions, emission_rate_scale)
139  call aero_dist_interp_1d(scenario%aero_background, &
140  scenario%aero_dilution_time, scenario%aero_dilution_rate, 0d0, &
141  background, dilution_rate)
142  call aero_binned_add_aero_dist(background_binned, bin_grid, aero_data, &
143  background)
144 
145  if (dilution_rate == 0d0 .and. &
146  scenario%loss_function_type == scenario_loss_function_none) then
147  call aero_binned_zero(aero_binned)
148  call aero_binned_add_aero_dist(aero_binned, bin_grid, aero_data, &
149  emissions)
150  call aero_binned_scale(aero_binned, &
151  emission_rate_scale * time / env_state%height)
152  else
153  allocate(loss_array(bin_grid_size(bin_grid)))
154 
155  if (scenario%loss_function_type /= scenario_loss_function_none) then
156  if (aero_data%name(1) /= "H2O") then
157  call warn_msg(176257943, &
158  "exact solution assumes composition is water", &
159  already_warned_water)
160  end if
161  end if
162 
163  do i = 1,bin_grid_size(bin_grid)
164  loss_array(i) = dilution_rate + scenario_loss_rate(scenario, &
165  aero_data_rad2vol(aero_data, bin_grid%centers(i)), &
166  const%water_density, aero_data, env_state)
167  call assert_msg(181676342, loss_array(i) > 0, &
168  "non-positive loss rate")
169  loss_array(i) = 1d0 / loss_array(i)
170  end do
171 
172  ! calculate the limit steady state distribution
173  call aero_binned_set_sizes(aero_binned_limit, &
174  bin_grid_size(bin_grid), aero_data_n_spec(aero_data))
175  call aero_binned_add_aero_dist(aero_binned_limit, bin_grid, &
176  aero_data, emissions)
177  call aero_binned_scale(aero_binned_limit, &
178  emission_rate_scale / env_state%height)
179  call aero_binned_scale(background_binned, dilution_rate)
180  call aero_binned_add(aero_binned_limit, background_binned)
181  call aero_binned_scale_by_array(aero_binned_limit, loss_array)
182 
183  do i = 1,bin_grid_size(bin_grid)
184  loss_array(i) = exp(-time / loss_array(i))
185  end do
186 
187  ! calculate the current state
188  call aero_binned_zero(aero_binned)
189  call aero_binned_add_aero_dist(aero_binned, bin_grid, aero_data, &
190  aero_dist_init)
191  call aero_binned_sub(aero_binned, aero_binned_limit)
192  call aero_binned_scale_by_array(aero_binned, loss_array)
193  call aero_binned_add(aero_binned, aero_binned_limit)
194  end if
195 
196  end subroutine soln_zero
197 
198 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
199 
200 end module pmc_coag_kernel_zero
pmc_aero_particle::aero_particle_t
Single aerosol particle data structure.
Definition: aero_particle.F90:26
pmc_aero_data::aero_data_n_spec
elemental integer function aero_data_n_spec(aero_data)
Return the number of aerosol species, or -1 if uninitialized.
Definition: aero_data.F90:236
pmc_aero_binned::aero_binned_set_sizes
subroutine aero_binned_set_sizes(aero_binned, n_bin, n_spec)
Set the number of bins and species in an aero_binned_t.
Definition: aero_binned.F90:72
pmc_scenario::scenario_loss_rate
real(kind=dp) function scenario_loss_rate(scenario, vol, density, aero_data, env_state)
Evaluate a loss rate function.
Definition: scenario.F90:381
pmc_coag_kernel_zero::kernel_zero_minmax
subroutine kernel_zero_minmax(v1, v2, aero_data, env_state, k_min, k_max)
Minimum and maximum of the zero coagulation kernel.
Definition: coag_kernel_zero.F90:51
pmc_aero_particle
The aero_particle_t structure and associated subroutines.
Definition: aero_particle.F90:9
pmc_scenario
The scenario_t structure and associated subroutines.
Definition: scenario.F90:9
pmc_scenario::scenario_t
Scenario data.
Definition: scenario.F90:54
pmc_aero_binned::aero_binned_add
subroutine aero_binned_add(aero_binned, aero_binned_delta)
Add two aero_binned_t structures together.
Definition: aero_binned.F90:110
pmc_scenario::scenario_loss_function_none
integer, parameter scenario_loss_function_none
Type code for a zero loss function.
Definition: scenario.F90:28
pmc_constants::dp
integer, parameter dp
Kind of a double precision real number.
Definition: constants.F90:12
pmc_aero_dist::aero_dist_interp_1d
subroutine aero_dist_interp_1d(aero_dist_list, time_list, rate_list, time, aero_dist, rate)
Determine the current aero_dist and rate by interpolating at the current time with the lists of aero_...
Definition: aero_dist.F90:177
pmc_coag_kernel_zero::soln_zero
subroutine soln_zero(bin_grid, aero_data, time, aero_dist_init, scenario, env_state, aero_binned)
Exact solution with the zero coagulation kernel. Only useful for testing emissions,...
Definition: coag_kernel_zero.F90:107
pmc_bin_grid::bin_grid_size
elemental integer function bin_grid_size(bin_grid)
Return the number of bins in the grid, or -1 if the bin grid is not allocated.
Definition: bin_grid.F90:51
pmc_env_state::env_state_t
Current environment state.
Definition: env_state.F90:29
pmc_aero_binned::aero_binned_add_aero_dist
subroutine aero_binned_add_aero_dist(aero_binned, bin_grid, aero_data, aero_dist)
Add an aero_dist_t to an aero_binned_t.
Definition: aero_binned.F90:229
pmc_util::warn_msg
subroutine warn_msg(code, warning_msg, already_warned)
Prints a warning message.
Definition: util.F90:37
pmc_aero_binned::aero_binned_scale_by_array
subroutine aero_binned_scale_by_array(aero_binned, alpha_array)
Scales an aero_binned_t element-wise by an array of reals.
Definition: aero_binned.F90:207
pmc_util::assert_msg
subroutine assert_msg(code, condition_ok, error_msg)
Errors unless condition_ok is true.
Definition: util.F90:77
pmc_aero_dist
The aero_dist_t structure and associated subroutines.
Definition: aero_dist.F90:18
pmc_coag_kernel_zero
Constant kernel equal to zero.
Definition: coag_kernel_zero.F90:13
pmc_constants::const
type(const_t), save const
Fixed variable for accessing the constant's values.
Definition: constants.F90:73
pmc_aero_binned::aero_binned_sub
subroutine aero_binned_sub(aero_binned, aero_binned_delta)
Subtract one aero_binned_t structure from another.
Definition: aero_binned.F90:164
pmc_env_state
The env_state_t structure and associated subroutines.
Definition: env_state.F90:9
pmc_aero_data::aero_data_t
Aerosol material properties and associated data.
Definition: aero_data.F90:49
pmc_aero_dist::aero_dist_t
A complete aerosol distribution, consisting of several modes.
Definition: aero_dist.F90:33
pmc_util
Common utility subroutines.
Definition: util.F90:9
pmc_aero_binned::aero_binned_scale
subroutine aero_binned_scale(aero_binned, alpha)
Scale an aero_binned_t by a real number.
Definition: aero_binned.F90:190
pmc_aero_binned::aero_binned_zero
subroutine aero_binned_zero(aero_binned)
Set all internal data in an aero_binned_t structure to zero.
Definition: aero_binned.F90:93
pmc_aero_binned
The aero_binned_t structure and associated subroutines.
Definition: aero_binned.F90:9
pmc_aero_binned::aero_binned_t
Aerosol number and volume distributions stored per bin.
Definition: aero_binned.F90:37
pmc_bin_grid
The bin_grid_t structure and associated subroutines.
Definition: bin_grid.F90:9
pmc_aero_data::aero_data_rad2vol
real(kind=dp) elemental function aero_data_rad2vol(aero_data, r)
Convert geometric radius (m) to mass-equivalent volume (m^3).
Definition: aero_data.F90:122
pmc_aero_data
The aero_data_t structure and associated subroutines.
Definition: aero_data.F90:9
pmc_bin_grid::bin_grid_t
1D grid, either logarithmic or linear.
Definition: bin_grid.F90:33
pmc_coag_kernel_zero::kernel_zero
subroutine kernel_zero(aero_particle_1, aero_particle_2, aero_data, env_state, k)
Zero coagulation kernel.
Definition: coag_kernel_zero.F90:31