PartMC  2.9.0
run_sect.F90
Go to the documentation of this file.
1 ! Copyright (C) 2005-2012 Nicole Riemer and Matthew West
2 ! Copyright (C) Andreas Bott
3 ! Licensed under the GNU General Public License version 2 or (at your
4 ! option) any later version. See the file COPYING for details.
5 
6 !> \file
7 !> The pmc_run_sect module.
8 
9 !> 1D sectional simulation.
10 !!
11 !! Sectional code based on \c coad1d.f by Andreas Bott
12 !! - http://www.meteo.uni-bonn.de/mitarbeiter/ABott/
13 !! - Released under the GPL to Nicole Riemer (personal communication)
14 !! - A. Bott, A flux method for the numerical solution of the
15 !! stochastic collection equation, J. Atmos. Sci. 55, 2284-2293,
16 !! 1998.
18 
19  use pmc_bin_grid
20  use pmc_aero_binned
21  use pmc_util
22  use pmc_aero_dist
23  use pmc_scenario
24  use pmc_env_state
25  use pmc_aero_data
26  use pmc_coag_kernel
27  use pmc_output
28  use pmc_gas_data
29  use pmc_gas_state
30 
31  !> Options controlling the operation of run_sect().
33  !> Final time (s).
34  real(kind=dp) :: t_max
35  !> Timestep for coagulation (s).
36  real(kind=dp) :: del_t
37  !> Output interval (0 disables) (s).
38  real(kind=dp) :: t_output
39  !> Progress interval (0 disables) (s).
40  real(kind=dp) :: t_progress
41  !> Whether to do aerosol background dilution (optional in spec file
42  !> and only allowed with loss_function = drydep; defaults to \c .true.).
43  logical :: do_aero_dilution
44  !> Type of coagulation kernel.
45  integer :: coag_kernel_type
46  !> Whether to do coagulation.
47  logical :: do_coagulation
48  !> Whether to run CAMP.
49  logical :: do_camp_chem
50  !> Whether to run TChem.
51  logical :: do_tchem
52  !> Whether to do condensation.
53  logical :: do_condensation
54  !> Whether to run MOSAIC.
55  logical :: do_mosaic
56  !> Whether to compute optical properties.
57  logical :: do_optical
58  !> Whether to do nucleation.
59  logical :: do_nucleation
60  !> Whether to do immersion freezing.
61  logical :: do_immersion_freezing
62  !> Output prefix.
63  character(len=300) :: prefix
64  !> UUID of the simulation.
65  character(len=PMC_UUID_LEN) :: uuid
66  end type run_sect_opt_t
67 
68 contains
69 
70 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
71 
72  !> Run a sectional simulation.
73  subroutine run_sect(bin_grid, gas_data, aero_data, aero_dist, &
74  scenario, env_state, run_sect_opt)
75 
76  !> Bin grid.
77  type(bin_grid_t), intent(in) :: bin_grid
78  !> Gas data.
79  type(gas_data_t), intent(in) :: gas_data
80  !> Aerosol data.
81  type(aero_data_t), intent(in) :: aero_data
82  !> Aerosol distribution.
83  type(aero_dist_t), intent(inout) :: aero_dist
84  !> Environment data.
85  type(scenario_t), intent(inout) :: scenario
86  !> Environment state.
87  type(env_state_t), intent(inout) :: env_state
88  !> Options.
89  type(run_sect_opt_t), intent(in) :: run_sect_opt
90 
91  real(kind=dp) c(bin_grid_size(bin_grid),bin_grid_size(bin_grid))
92  integer ima(bin_grid_size(bin_grid),bin_grid_size(bin_grid))
93  real(kind=dp) g(bin_grid_size(bin_grid)), r(bin_grid_size(bin_grid))
94  real(kind=dp) e(bin_grid_size(bin_grid))
95  real(kind=dp) k_bin(bin_grid_size(bin_grid),bin_grid_size(bin_grid))
96  real(kind=dp) ck(bin_grid_size(bin_grid),bin_grid_size(bin_grid))
97  real(kind=dp) ec(bin_grid_size(bin_grid),bin_grid_size(bin_grid))
98  real(kind=dp) taug(bin_grid_size(bin_grid)), taup(bin_grid_size(bin_grid))
99  real(kind=dp) taul(bin_grid_size(bin_grid)), tauu(bin_grid_size(bin_grid))
100  real(kind=dp) prod(bin_grid_size(bin_grid)), ploss(bin_grid_size(bin_grid))
101  real(kind=dp) time, last_output_time, last_progress_time
102  type(env_state_t) :: old_env_state
103  type(aero_binned_t) :: aero_binned
104  type(gas_state_t) :: gas_state
105 
106  integer i, j, i_time, num_t, i_summary
107  logical do_output, do_progress
108 
109  call check_time_multiple("t_max", run_sect_opt%t_max, &
110  "del_t", run_sect_opt%del_t)
111  call check_time_multiple("t_output", run_sect_opt%t_output, &
112  "del_t", run_sect_opt%del_t)
113  call check_time_multiple("t_progress", run_sect_opt%t_progress, &
114  "del_t", run_sect_opt%del_t)
115 
116  ! g : spectral mass distribution (mg/cm^3)
117  ! e : droplet mass grid (mg)
118  ! r : droplet radius grid (um)
119  ! log_width : constant grid distance of logarithmic grid
120 
121  if (aero_data_n_spec(aero_data) /= 1) then
122  call die_msg(844211192, &
123  'run_sect() can only use one aerosol species')
124  end if
125 
126  ! output data structure
127  call gas_state_set_size(gas_state, gas_data_n_spec(gas_data))
128 
129  ! mass and radius grid
130  do i = 1,bin_grid_size(bin_grid)
131  r(i) = bin_grid%centers(i) * 1d6 ! radius in m to um
132  e(i) = aero_data_rad2vol(aero_data, bin_grid%centers(i)) &
133  * aero_data%density(1) * 1d6 ! vol in m^3 to mass in mg
134  end do
135 
136  ! initial mass distribution
137  call aero_binned_add_aero_dist(aero_binned, bin_grid, aero_data, &
138  aero_dist)
139 
140  call courant(bin_grid_size(bin_grid), bin_grid%widths(1), e, ima, c)
141 
142  ! initialize time
143  last_progress_time = 0d0
144  time = 0d0
145  i_summary = 1
146 
147  ! precompute kernel values for all pairs of bins
148  if (run_sect_opt%do_coagulation) then
149  call bin_kernel(bin_grid_size(bin_grid), bin_grid%centers, aero_data, &
150  run_sect_opt%coag_kernel_type, env_state, k_bin)
151  call smooth_bin_kernel(bin_grid_size(bin_grid), k_bin, ck)
152  do i = 1,bin_grid_size(bin_grid)
153  do j = 1,bin_grid_size(bin_grid)
154  ck(i,j) = ck(i,j) * 1d6 ! m^3/s to cm^3/s
155  end do
156  end do
157 
158  ! multiply kernel with constant timestep and logarithmic grid distance
159  do i = 1,bin_grid_size(bin_grid)
160  do j = 1,bin_grid_size(bin_grid)
161  ck(i,j) = ck(i,j) * run_sect_opt%del_t * bin_grid%widths(i)
162  end do
163  end do
164  end if
165 
166  ! initial output
167  call check_event(time, run_sect_opt%del_t, run_sect_opt%t_output, &
168  last_output_time, do_output)
169  if (do_output) then
170  call output_sectional(run_sect_opt%prefix, bin_grid, aero_data, &
171  aero_binned, gas_data, gas_state, env_state, scenario, i_summary, &
172  time, run_sect_opt%t_output, run_sect_opt%uuid)
173  end if
174 
175  ! main time-stepping loop
176  num_t = nint(run_sect_opt%t_max / run_sect_opt%del_t)
177  do i_time = 1, num_t
178 
179  if (run_sect_opt%do_coagulation) then
180  g = aero_binned%vol_conc(:,1) * aero_data%density(1)
181  call coad(bin_grid_size(bin_grid), run_sect_opt%del_t, taug, taup, &
182  taul, tauu, prod, ploss, c, ima, g, r, e, ck, ec)
183  aero_binned%vol_conc(:,1) = g / aero_data%density(1)
184  aero_binned%num_conc = aero_binned%vol_conc(:,1) &
185  / aero_data_rad2vol(aero_data, bin_grid%centers)
186  end if
187 
188  time = run_sect_opt%t_max * real(i_time, kind=dp) &
189  / real(num_t, kind=dp)
190 
191  old_env_state = env_state
192  call scenario_update_env_state(scenario, env_state, time)
193  call scenario_update_gas_state(scenario, run_sect_opt%del_t, &
194  env_state, old_env_state, gas_data, gas_state)
195  call scenario_update_aero_binned(scenario, run_sect_opt%del_t, &
196  env_state, old_env_state, bin_grid, aero_data, &
197  run_sect_opt%do_aero_dilution, aero_binned)
198 
199  ! print output
200  call check_event(time, run_sect_opt%del_t, run_sect_opt%t_output, &
201  last_output_time, do_output)
202  if (do_output) then
203  i_summary = i_summary + 1
204  call output_sectional(run_sect_opt%prefix, bin_grid, aero_data, &
205  aero_binned, gas_data, gas_state, env_state, scenario, &
206  i_summary, time, run_sect_opt%t_output, run_sect_opt%uuid)
207  end if
208 
209  ! print progress to stdout
210  call check_event(time, run_sect_opt%del_t, run_sect_opt%t_progress, &
211  last_progress_time, do_progress)
212  if (do_progress) then
213  write(*,'(a6,a8)') 'step', 'time'
214  write(*,'(i6,f8.1)') i_time, time
215  end if
216  end do
217 
218  end subroutine run_sect
219 
220 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
221 
222  !> Read the specification for a run_sect simulation from a spec file.
223  subroutine spec_file_read_run_sect(file, run_sect_opt, aero_data, &
224  bin_grid, gas_data, env_state, aero_dist_init, scenario)
225 
226  !> Spec file.
227  type(spec_file_t), intent(inout) :: file
228  !> Options controlling the operation of run_sect().
229  type(run_sect_opt_t), intent(inout) :: run_sect_opt
230  !> Aerosol data.
231  type(aero_data_t), intent(out) :: aero_data
232  !> Bin grid.
233  type(bin_grid_t), intent(out) :: bin_grid
234  !> Initial aerosol state.
235  type(aero_dist_t), intent(out) :: aero_dist_init
236  !> Scenario data.
237  type(scenario_t), intent(out) :: scenario
238  !> Environmental state.
239  type(env_state_t), intent(out) :: env_state
240  !> Gas data.
241  type(gas_data_t), intent(out) :: gas_data
242 
243  character(len=PMC_MAX_FILENAME_LEN) :: sub_filename
244  type(spec_file_t) :: sub_file
245  type(spec_line_t) :: line
246 
247  call spec_file_read_string(file, 'output_prefix', run_sect_opt%prefix)
248 
249  call spec_file_read_real(file, 't_max', run_sect_opt%t_max)
250  call spec_file_read_real(file, 'del_t', run_sect_opt%del_t)
251  call spec_file_read_real(file, 't_output', run_sect_opt%t_output)
252  call spec_file_read_real(file, 't_progress', run_sect_opt%t_progress)
253 
254  call spec_file_read_radius_bin_grid(file, bin_grid)
255 
256  call spec_file_read_logical(file, 'do_camp_chem', &
257  run_sect_opt%do_camp_chem)
258  if (run_sect_opt%do_camp_chem) then
259  call spec_file_die_msg(645601039, file, &
260  "sectional run does not support CAMP chemistry")
261  end if
262 
263  call spec_file_read_logical(file, 'do_tchem', run_sect_opt%do_tchem)
264  if (run_sect_opt%do_tchem) then
265  call spec_file_die_msg(366298338, file, &
266  "sectional run does not support TChem chemistry")
267  end if
268 
269  call spec_file_read_string(file, 'gas_data', sub_filename)
270  call spec_file_open(sub_filename, sub_file)
271  call spec_file_read_gas_data(sub_file, gas_data)
272  call spec_file_close(sub_file)
273 
274  call spec_file_read_string(file, 'aerosol_data', sub_filename)
275  call spec_file_open(sub_filename, sub_file)
276  call spec_file_read_aero_data(sub_file, aero_data)
277  call spec_file_close(sub_file)
278 
279  call spec_file_read_fractal(file, aero_data%fractal)
280 
281  call spec_file_read_string(file, 'aerosol_init', sub_filename)
282  call spec_file_open(sub_filename, sub_file)
283  call spec_file_read_aero_dist(sub_file, aero_data, .false., aero_dist_init)
284  call spec_file_close(sub_file)
285 
286  call spec_file_read_scenario(file, gas_data, aero_data, .false., scenario)
287  call assert_msg(383939910, &
288  scenario%loss_function_type == scenario_loss_function_none &
289  .or. scenario%loss_function_type == scenario_loss_function_drydep, &
290  "sectional run only supports loss_function none or drydep")
291  call spec_file_read_env_state(file, env_state)
292 
293  ! optional line, only allowed with dry deposition (default: dilute)
294  run_sect_opt%do_aero_dilution = .true.
295  call spec_file_read_line_no_eof(file, line)
296  call spec_file_unread_line(file)
297  if (line%name == 'do_aero_dilution') then
298  call spec_file_read_logical(file, 'do_aero_dilution', &
299  run_sect_opt%do_aero_dilution)
300  if (scenario%loss_function_type /= scenario_loss_function_drydep) then
301  call spec_file_die_msg(363374529, file, &
302  "do_aero_dilution is only allowed with loss_function drydep")
303  end if
304  end if
305 
306  call spec_file_read_logical(file, 'do_coagulation', &
307  run_sect_opt%do_coagulation)
308  if (run_sect_opt%do_coagulation) then
309  call spec_file_read_coag_kernel_type(file, &
310  run_sect_opt%coag_kernel_type)
311  if (run_sect_opt%coag_kernel_type == coag_kernel_type_additive) then
312  call spec_file_read_real(file, 'additive_kernel_coeff', &
313  env_state%additive_kernel_coefficient)
314  end if
315  else
316  run_sect_opt%coag_kernel_type = coag_kernel_type_invalid
317  end if
318 
319  call spec_file_read_logical(file, 'do_condensation', &
320  run_sect_opt%do_condensation)
321  if (run_sect_opt%do_condensation) then
322  call spec_file_die_msg(673957476, file, &
323  "sectional run does not support condensation")
324  end if
325 
326  call spec_file_read_logical(file, 'do_mosaic', run_sect_opt%do_mosaic)
327  if (run_sect_opt%do_mosaic) then
328  call spec_file_die_msg(129153012, file, &
329  "sectional run does not support MOSAIC chemistry")
330  call spec_file_read_logical(file, 'do_optical', run_sect_opt%do_optical)
331  if (run_sect_opt%do_optical) then
332  call spec_file_die_msg(627325616, file, &
333  "sectional run does not support optical properties calculation")
334  end if
335  else
336  run_sect_opt%do_optical = .false.
337  end if
338 
339  call spec_file_read_logical(file, 'do_nucleation', &
340  run_sect_opt%do_nucleation)
341  if (run_sect_opt%do_nucleation) then
342  call spec_file_die_msg(100312705, file, &
343  "sectional run does not support nucleation")
344  end if
345 
346  call spec_file_read_logical(file, 'do_immersion_freezing', &
347  run_sect_opt%do_immersion_freezing)
348  if (run_sect_opt%do_immersion_freezing) then
349  call spec_file_die_msg(160346377, file, &
350  "sectional run does not support immersion freezing")
351  end if
352 
353  call spec_file_close(file)
354 
355  ! finished reading .spec data, now do the run
356 
357  call pmc_srand(0, 0)
358 
359  call uuid4_str(run_sect_opt%uuid)
360 
361  call scenario_init_env_state(scenario, env_state, 0d0)
362 
363  end subroutine spec_file_read_run_sect
364 
365 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
366 
367  !> Collision subroutine, exponential approach.
368  subroutine coad(n_bin, dt, taug, taup, taul, tauu, prod, ploss, &
369  c, ima, g, r, e, ck, ec)
370 
371  integer n_bin
372  real(kind=dp) dt
373  real(kind=dp) taug(n_bin)
374  real(kind=dp) taup(n_bin)
375  real(kind=dp) taul(n_bin)
376  real(kind=dp) tauu(n_bin)
377  real(kind=dp) prod(n_bin)
378  real(kind=dp) ploss(n_bin)
379  real(kind=dp) c(n_bin,n_bin)
380  integer ima(n_bin,n_bin)
381  real(kind=dp) g(n_bin)
382  real(kind=dp) r(n_bin)
383  real(kind=dp) e(n_bin)
384  real(kind=dp) ck(n_bin,n_bin)
385  real(kind=dp) ec(n_bin,n_bin)
386 
387  real(kind=dp), parameter :: gmin = 1d-60
388 
389  integer i, i0, i1, j, k, kp
390  real(kind=dp) x0, gsi, gsj, gsk, gk, x1, flux
391 
392  do i = 1,n_bin
393  prod(i) = 0d0
394  ploss(i) = 0d0
395  end do
396 
397  ! lower and upper integration limit i0,i1
398  do i0 = 1,(n_bin - 1)
399  if (g(i0) .gt. gmin) goto 2000
400  end do
401 2000 continue
402  do i1 = (n_bin - 1),1,-1
403  if (g(i1) .gt. gmin) goto 2010
404  end do
405 2010 continue
406 
407  do i = i0,i1
408  do j = i,i1
409  k = ima(i,j) ! k = 0 means that i + j goes nowhere
410  kp = k + 1
411 
412  x0 = ck(i,j) * g(i) * g(j)
413  x0 = min(x0, g(i) * e(j))
414 
415  if (j .ne. k) x0 = min(x0, g(j) * e(i))
416  gsi = x0 / e(j)
417  gsj = x0 / e(i)
418  gsk = gsi + gsj
419 
420  ! loss from positions i, j
421  ploss(i) = ploss(i) + gsi
422  ploss(j) = ploss(j) + gsj
423  g(i) = g(i) - gsi
424  g(j) = g(j) - gsj
425 
426  if (k > 0) then ! do we have a valid bin for the coagulation result?
427  gk = g(k) + gsk
428 
429  if (gk .gt. gmin) then
430  x1 = log(g(kp) / gk + 1d-60)
431  flux = gsk / x1 * (exp(0.5d0 * x1) &
432  - exp(x1 * (0.5d0 - c(i,j))))
433  flux = min(flux, gk)
434  g(k) = gk - flux
435  g(kp) = g(kp) + flux
436  ! gain for positions i, j
437  prod(k) = prod(k) + gsk - flux
438  prod(kp) = prod(kp) + flux
439  end if
440  end if
441  end do
442  end do
443 
444  end subroutine coad
445 
446 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
447 
448  !> Determines the Courant number for each bin pair.
449  subroutine courant(n_bin, log_width, e, ima, c)
450 
451  !> Number of bins.
452  integer, intent(in) :: n_bin
453  !> Bin scale factor.
454  real(kind=dp), intent(in) :: log_width
455  !> Droplet mass grid (mg).
456  real(kind=dp), intent(in) :: e(n_bin)
457  !> i + j goes in bin ima(i,j).
458  integer, intent(out) :: ima(n_bin,n_bin)
459  !> Courant number for bin pairs.
460  real(kind=dp), intent(out) :: c(n_bin,n_bin)
461 
462  integer i, j, k, kk
463  real(kind=dp) x0
464 
465  c = 0d0 ! added to avoid uninitialized access errors
466  ima = 0 ! ima(i,j) = 0 means that particles i + j go nowhere
467  do i = 1,n_bin
468  do j = i,n_bin
469  x0 = e(i) + e(j)
470  ! this is basically the same as particle_in_bin(), but that
471  ! is actually slightly different than what was always done
472  ! here
473 
474  ! MW 2011-04-28: I think the above comment no longer
475  ! applies, and we can make this just
476  ! bin_grid_find(). FIXME.
477  k = find_1d(n_bin, e, x0)
478  if (k < n_bin) then
479  k = k + 1
480  if (c(i,j) .lt. 1d0 - 1d-08) then
481  kk = k - 1
482  c(i,j) = log(x0 / e(k-1)) / (3d0 * log_width)
483  else
484  c(i,j) = 0d0
485  kk = k
486  end if
487  ima(i,j) = min(n_bin - 1, kk)
488  end if
489  c(j,i) = c(i,j)
490  ima(j,i) = ima(i,j)
491  end do
492  end do
493 
494  end subroutine courant
495 
496 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
497 
498  !> Smooths kernel values for bin pairs, and halves the self-rate.
499  subroutine smooth_bin_kernel(n_bin, k, k_smooth)
500 
501  !> Number of bins.
502  integer, intent(in) :: n_bin
503  !> Kernel values.
504  real(kind=dp), intent(in) :: k(n_bin,n_bin)
505  !> Smoothed kernel values.
506  real(kind=dp), intent(out) :: k_smooth(n_bin,n_bin)
507 
508  integer i, j, im, ip, jm, jp
509 
510  do i = 1,n_bin
511  do j = 1,n_bin
512  jm = max0(j - 1, 1)
513  im = max0(i - 1, 1)
514  jp = min0(j + 1, n_bin)
515  ip = min0(i + 1, n_bin)
516  k_smooth(i,j) = 0.125d0 * (k(i,jm) + k(im,j) &
517  + k(ip,j) + k(i,jp)) &
518  + 0.5d0 * k(i,j)
519  if (i .eq. j) then
520  k_smooth(i,j) = 0.5d0 * k_smooth(i,j)
521  end if
522  end do
523  end do
524 
525  end subroutine smooth_bin_kernel
526 
527 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
528 
529 end module pmc_run_sect
pmc_run_sect::run_sect_opt_t
Options controlling the operation of run_sect().
Definition: run_sect.F90:32
pmc_run_sect
1D sectional simulation.
Definition: run_sect.F90:17
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:250
pmc_gas_data::gas_data_t
Constant gas data.
Definition: gas_data.F90:35
pmc_spec_file::spec_file_close
subroutine spec_file_close(file)
Close a spec file.
Definition: spec_file.F90:135
pmc_gas_state::gas_state_set_size
subroutine gas_state_set_size(gas_state, n_spec)
Sets the sizes of the gas state.
Definition: gas_state.F90:56
pmc_scenario
The scenario_t structure and associated subroutines.
Definition: scenario.F90:9
pmc_scenario::scenario_t
Scenario data.
Definition: scenario.F90:87
pmc_gas_data
The gas_data_t structure and associated subroutines.
Definition: gas_data.F90:9
pmc_util::die_msg
subroutine die_msg(code, error_msg)
Error immediately.
Definition: util.F90:135
pmc_scenario::scenario_loss_function_none
integer, parameter scenario_loss_function_none
Type code for a zero loss function.
Definition: scenario.F90:32
pmc_constants::dp
integer, parameter dp
Kind of a double precision real number.
Definition: constants.F90:12
pmc_coag_kernel
Generic coagulation kernel.
Definition: coag_kernel.F90:9
pmc_spec_file::spec_file_read_logical
subroutine spec_file_read_logical(file, name, var)
Read a logical from a spec file that must have a given name.
Definition: spec_file.F90:603
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_scenario::scenario_update_gas_state
subroutine scenario_update_gas_state(scenario, delta_t, env_state, old_env_state, gas_data, gas_state)
Do gas emissions and background dilution.
Definition: scenario.F90:244
pmc_scenario::scenario_update_env_state
subroutine scenario_update_env_state(scenario, env_state, time)
Update time-dependent contents of the environment. scenario_init_env_state() should have been called ...
Definition: scenario.F90:169
pmc_coag_kernel::coag_kernel_type_additive
integer, parameter coag_kernel_type_additive
Type code for an additive kernel.
Definition: coag_kernel.F90:33
pmc_run_sect::smooth_bin_kernel
subroutine smooth_bin_kernel(n_bin, k, k_smooth)
Smooths kernel values for bin pairs, and halves the self-rate.
Definition: run_sect.F90:500
pmc_spec_file::spec_file_t
An input file with extra data for printing messages.
Definition: spec_file.F90:59
pmc_rand::pmc_srand
subroutine pmc_srand(seed, offset)
Initializes the random number generator to the state defined by the given seed plus offset....
Definition: rand.F90:67
pmc_gas_state
The gas_state_t structure and associated subroutines.
Definition: gas_state.F90:9
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_spec_file::spec_file_read_real
subroutine spec_file_read_real(file, name, var)
Read a real number from a spec file that must have the given name.
Definition: spec_file.F90:582
pmc_util::check_time_multiple
subroutine check_time_multiple(first_name, first_time, second_name, second_time)
Check that the first time interval is close to an integer multiple of the second, and warn if it is n...
Definition: util.F90:377
pmc_util::assert_msg
subroutine assert_msg(code, condition_ok, error_msg)
Errors unless condition_ok is true.
Definition: util.F90:78
pmc_run_sect::spec_file_read_run_sect
subroutine spec_file_read_run_sect(file, run_sect_opt, aero_data, bin_grid, gas_data, env_state, aero_dist_init, scenario)
Read the specification for a run_sect simulation from a spec file.
Definition: run_sect.F90:225
pmc_aero_dist
The aero_dist_t structure and associated subroutines.
Definition: aero_dist.F90:18
pmc_coag_kernel::bin_kernel
subroutine bin_kernel(n_bin, bin_r, aero_data, coag_kernel_type, env_state, k)
Computes an array of kernel values for each bin pair. k(i,j) is the kernel value at the centers of bi...
Definition: coag_kernel.F90:218
pmc_spec_file::spec_file_open
subroutine spec_file_open(filename, file)
Open a spec file for reading.
Definition: spec_file.F90:112
pmc_spec_file::spec_file_read_line_no_eof
subroutine spec_file_read_line_no_eof(file, line)
Read a spec_line from the spec_file. This will always succeed or error out, so should only be called ...
Definition: spec_file.F90:298
pmc_env_state
The env_state_t structure and associated subroutines.
Definition: env_state.F90:9
pmc_gas_state::gas_state_t
Current state of the gas mixing ratios in the system.
Definition: gas_state.F90:33
pmc_rand::uuid4_str
subroutine uuid4_str(uuid)
Generate a version 4 UUID as a string.
Definition: rand.F90:661
pmc_aero_data::aero_data_t
Aerosol material properties and associated data.
Definition: aero_data.F90:55
pmc_output
Write data in NetCDF format.
Definition: output.F90:68
pmc_coag_kernel::coag_kernel_type_invalid
integer, parameter coag_kernel_type_invalid
Type code for an undefined or invalid kernel.
Definition: coag_kernel.F90:29
pmc_scenario::scenario_update_aero_binned
subroutine scenario_update_aero_binned(scenario, delta_t, env_state, old_env_state, bin_grid, aero_data, do_aero_dilution, aero_binned)
Do emissions and background dilution from the environment for a binned aerosol distribution.
Definition: scenario.F90:386
pmc_aero_dist::aero_dist_t
A complete aerosol distribution, consisting of several modes.
Definition: aero_dist.F90:33
pmc_scenario::scenario_loss_function_drydep
integer, parameter scenario_loss_function_drydep
Type code for a loss rate function based on dry deposition.
Definition: scenario.F90:38
pmc_util
Common utility subroutines.
Definition: util.F90:9
pmc_spec_file::spec_file_unread_line
subroutine spec_file_unread_line(file)
Set the line number and file read pointer back one entry.
Definition: spec_file.F90:470
pmc_util::check_event
subroutine check_event(time, timestep, interval, last_time, do_event)
Computes whether an event is scheduled to take place.
Definition: util.F90:408
pmc_gas_data::gas_data_n_spec
elemental integer function gas_data_n_spec(gas_data)
Return the number of gas species.
Definition: gas_data.F90:109
pmc_scenario::scenario_init_env_state
subroutine scenario_init_env_state(scenario, env_state, time)
Initialize the time-dependent contents of the environment. Thereafter scenario_update_env_state() sho...
Definition: scenario.F90:146
pmc_spec_file::spec_file_die_msg
subroutine spec_file_die_msg(code, file, msg)
Exit with an error message containing filename and line number.
Definition: spec_file.F90:74
pmc_output::output_sectional
subroutine output_sectional(prefix, bin_grid, aero_data, aero_binned, gas_data, gas_state, env_state, scenario, index, time, del_t, uuid)
Write the current sectional data.
Definition: output.F90:666
pmc_aero_binned
The aero_binned_t structure and associated subroutines.
Definition: aero_binned.F90:9
pmc_run_sect::coad
subroutine coad(n_bin, dt, taug, taup, taul, tauu, prod, ploss, c, ima, g, r, e, ck, ec)
Collision subroutine, exponential approach.
Definition: run_sect.F90:370
pmc_spec_file::spec_file_read_string
subroutine spec_file_read_string(file, name, var)
Read a string from a spec file that must have a given name.
Definition: spec_file.F90:624
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:136
pmc_aero_data
The aero_data_t structure and associated subroutines.
Definition: aero_data.F90:9
pmc_run_sect::run_sect
subroutine run_sect(bin_grid, gas_data, aero_data, aero_dist, scenario, env_state, run_sect_opt)
Run a sectional simulation.
Definition: run_sect.F90:75
pmc_bin_grid::bin_grid_t
1D grid, either logarithmic or linear.
Definition: bin_grid.F90:33
pmc_run_sect::courant
subroutine courant(n_bin, log_width, e, ima, c)
Determines the Courant number for each bin pair.
Definition: run_sect.F90:450
pmc_util::find_1d
integer function find_1d(n, x_vals, x)
Find the position of a real number in an arbitrary 1D array.
Definition: util.F90:593