PartMC  2.8.0
run_part.F90
Go to the documentation of this file.
1 ! Copyright (C) 2005-2017 Nicole Riemer and 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_run_part module.
7 
8 !> Monte Carlo simulation.
10 
11  use pmc_constants
12  use pmc_util
13  use pmc_aero_state
14  use pmc_scenario
15  use pmc_env_state
16  use pmc_aero_data
17  use pmc_gas_data
18  use pmc_gas_state
19  use pmc_output
20  use pmc_mosaic
21  use pmc_coagulation
23  use pmc_coag_kernel
24  use pmc_nucleate
26  use pmc_mpi
28  use pmc_photolysis
30 #ifdef PMC_USE_CAMP
31  use camp_camp_core
32  use camp_camp_state
33  use camp_env_state, only: camp_env_state_t => env_state_t
34 #endif
35 #ifdef PMC_USE_SUNDIALS
36  use pmc_condense
37 #endif
38 #ifdef PMC_USE_MPI
39  use mpi
40 #endif
41 
42  !> Type code for undefined or invalid parallel coagulation method.
43  integer, parameter :: parallel_coag_type_invalid = 0
44  !> Type code for local parallel coagulation.
45  integer, parameter :: parallel_coag_type_local = 1
46  !> Type code for distributed parallel coagulation.
47  integer, parameter :: parallel_coag_type_dist = 2
48 
49  !> Options controlling the execution of run_part().
51  !> Final time (s).
52  real(kind=dp) :: t_max
53  !> Output interval (0 disables) (s).
54  real(kind=dp) :: t_output
55  !> Progress interval (0 disables) (s).
56  real(kind=dp) :: t_progress
57  !> Timestep for coagulation.
58  real(kind=dp) :: del_t
59  !> Prefix for output files.
60  character(len=300) :: output_prefix
61  !> Type of coagulation kernel.
62  integer :: coag_kernel_type
63  !> Type of nucleation.
64  integer :: nucleate_type
65  !> Source of nucleation.
66  integer :: nucleate_source
67  !> Weight class of nucleation.
68  integer :: nucleate_weight_class
69  !> Whether to do coagulation.
70  logical :: do_coagulation
71  !> Whether to do nucleation.
72  logical :: do_nucleation
73  !> Whether to do freezing.
74  logical :: do_immersion_freezing
75  !> The immersion freezing scheme options.
76  integer :: immersion_freezing_scheme_type
77  !> Slope parameter for the INAS parameterization (singular scheme only).
78  real(kind=dp) :: inas_a
79  !> Intercept parameter for the INAS parameterization (singular scheme only).
80  real(kind=dp) :: inas_b
81  !> The freezing rate parameter for "const" scheme.
82  real(kind=dp) :: freezing_rate
83  !> Whether to use the naive algorithm for time-dependent scheme.
84  !> (If false, use the binned tau-leaping algorithm.)
85  logical :: do_freezing_naive
86  !> Allow doubling if needed.
87  logical :: allow_doubling
88  !> Allow halving if needed.
89  logical :: allow_halving
90  !> Whether to do condensation.
91  logical :: do_condensation
92  !> Whether to do MOSAIC.
93  logical :: do_mosaic
94  !> Whether to compute optical properties.
95  logical :: do_optical
96  !> Whether to have explicitly selected weighting.
97  logical :: do_select_weighting
98  !> Type of particle weighting scheme.
99  integer :: weighting_type
100  !> Weighting exponent for power weighting scheme.
101  real(kind=dp) :: weighting_exponent
102  !> Repeat number of run.
103  integer :: i_repeat
104  !> Total number of repeats.
105  integer :: n_repeat
106  !> Wall clock time of start.
107  real(kind=dp) :: t_wall_start
108  !> Whether to record particle removal information.
109  logical :: record_removals
110  !> Whether to run in parallel.
111  logical :: do_parallel
112  !> Parallel output type.
113  integer :: output_type
114  !> Mixing timescale between processes (s).
115  real(kind=dp) :: mix_timescale
116  !> Whether to average gases each timestep.
117  logical :: gas_average
118  !> Whether to average environment each timestep.
119  logical :: env_average
120  !> Parallel coagulation method type.
121  integer :: parallel_coag_type
122  !> Whether to run CAMP.
123  logical :: do_camp_chem
124  !> Whether to run TChem.
125  logical :: do_tchem
126  !> UUID for this simulation.
127  character(len=PMC_UUID_LEN) :: uuid
128  end type run_part_opt_t
129 
130 contains
131 
132 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
133 
134  !> Do a particle-resolved Monte Carlo simulation.
135 #ifdef PMC_USE_CAMP
136  subroutine run_part(scenario, env_state, aero_data, aero_state, gas_data, &
137  gas_state, run_part_opt, camp_core, photolysis)
138 #else
139  subroutine run_part(scenario, env_state, aero_data, aero_state, gas_data, &
140  gas_state, run_part_opt)
141 #endif
142 
143  !> Environment state.
144  type(scenario_t), intent(in) :: scenario
145  !> Environment state.
146  type(env_state_t), intent(inout) :: env_state
147  !> Aerosol data.
148  type(aero_data_t), intent(inout) :: aero_data
149  !> Aerosol state.
150  type(aero_state_t), intent(inout) :: aero_state
151  !> Gas data.
152  type(gas_data_t), intent(in) :: gas_data
153  !> Gas state.
154  type(gas_state_t), intent(inout) :: gas_state
155  !> Monte Carlo options.
156  type(run_part_opt_t), intent(in) :: run_part_opt
157 #ifdef PMC_USE_CAMP
158  !> CAMP chemistry core
159  type(camp_core_t), pointer, intent(inout), optional :: camp_core
160  !> Photolysis calculator
161  type(photolysis_t), pointer, intent(inout), optional :: photolysis
162 #endif
163 
164  real(kind=dp) :: time, pre_time, pre_del_t, prop_done
165  real(kind=dp) :: last_output_time, last_progress_time
166  integer :: rank, n_proc, pre_index, ncid
167  integer :: pre_i_repeat
168  integer :: n_samp, n_coag, n_emit, n_dil_in, n_dil_out, n_nuc
169  integer :: progress_n_samp, progress_n_coag
170  integer :: progress_n_emit, progress_n_dil_in, progress_n_dil_out
171  integer :: progress_n_nuc, n_part_before
172  integer :: global_n_part, global_n_samp, global_n_coag
173  integer :: global_n_emit, global_n_dil_in, global_n_dil_out
174  integer :: global_n_nuc
175  logical :: do_output, do_state, do_state_netcdf, do_progress, did_coag
176  real(kind=dp) :: t_start, t_wall_now, t_wall_elapsed, t_wall_remain
177  type(env_state_t) :: old_env_state
178  integer :: n_time, i_time, pre_i_time
179  integer :: i_state, i_state_netcdf, i_output
180  integer :: i_cur, i_next
181 
182  rank = pmc_mpi_rank()
183  n_proc = pmc_mpi_size()
184 
185  i_time = 0
186  i_output = 1
187  i_state = 1
188  i_state_netcdf = 1
189  time = 0d0
190  progress_n_samp = 0
191  progress_n_coag = 0
192  progress_n_emit = 0
193  progress_n_dil_in = 0
194  progress_n_dil_out = 0
195  progress_n_nuc = 0
196 
197  call check_time_multiple("t_max", run_part_opt%t_max, &
198  "del_t", run_part_opt%del_t)
199  call check_time_multiple("t_output", run_part_opt%t_output, &
200  "del_t", run_part_opt%del_t)
201  call check_time_multiple("t_progress", run_part_opt%t_progress, &
202  "del_t", run_part_opt%del_t)
203 
204  if (run_part_opt%do_mosaic) then
205  call mosaic_init(env_state, aero_data, run_part_opt%del_t, &
206  run_part_opt%do_optical)
207  if (run_part_opt%do_optical) then
208  call mosaic_aero_optical_init(env_state, aero_data, &
209  aero_state, gas_data, gas_state)
210  call mosaic_optical_wavelengths(aero_data)
211  end if
212  end if
213 
214  if (run_part_opt%t_output > 0d0) then
215  call output_state(run_part_opt%output_prefix, &
216  run_part_opt%output_type, aero_data, aero_state, gas_data, &
217  gas_state, env_state, i_state, time, run_part_opt%del_t, &
218  run_part_opt%i_repeat, run_part_opt%record_removals, &
219  run_part_opt%do_optical, run_part_opt%uuid)
220  call aero_info_array_zero(aero_state%aero_info_array)
221  end if
222 
223  call aero_state_rebalance(aero_state, aero_data, &
224  run_part_opt%allow_doubling, &
225  run_part_opt%allow_halving, initial_state_warning=.true.)
226 
227  t_start = env_state%elapsed_time
228  last_output_time = time
229  last_progress_time = time
230  n_time = nint(run_part_opt%t_max / run_part_opt%del_t)
231 
232  global_n_part = aero_state_total_particles_all_procs(aero_state)
233  if (rank == 0) then
234  ! progress only printed from root process
235  if (run_part_opt%i_repeat == 1) then
236  t_wall_elapsed = 0d0
237  t_wall_remain = 0d0
238  else
239  t_wall_now = system_clock_time()
240  prop_done = real(run_part_opt%i_repeat - 1, kind=dp) &
241  / real(run_part_opt%n_repeat, kind=dp)
242  t_wall_elapsed = t_wall_now - run_part_opt%t_wall_start
243  t_wall_remain = (1d0 - prop_done) / prop_done &
244  * t_wall_elapsed
245  end if
246  call print_part_progress(run_part_opt%i_repeat, time, &
247  global_n_part, 0, 0, 0, 0, 0, t_wall_elapsed, t_wall_remain)
248  end if
249 
250  i_cur = 1
251  i_next = n_time
252  call run_part_timeblock(scenario, env_state, aero_data, aero_state, &
253  gas_data, gas_state, run_part_opt, &
254 #ifdef PMC_USE_CAMP
255  camp_core, photolysis, &
256 #endif
257  i_cur, i_next, t_start, last_output_time, last_progress_time, &
258  i_output, progress_n_samp, progress_n_coag, progress_n_emit, &
259  progress_n_dil_in, progress_n_dil_out, progress_n_nuc)
260 
261  if (run_part_opt%do_mosaic) then
262  call mosaic_cleanup()
263  end if
264 
265  end subroutine run_part
266 
267 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
268 
269  !> Print the current simulation progress to the screen.
270  subroutine print_part_progress(i_repeat, t_sim_elapsed, n_part, n_coag, &
271  n_emit, n_dil_in, n_dil_out, n_nuc, t_wall_elapsed, t_wall_remain)
272 
273  !> Repeat number of simulation.
274  integer, intent(in) :: i_repeat
275  !> Elapsed simulation time (s).
276  real(kind=dp), intent(in) :: t_sim_elapsed
277  !> Number of particles.
278  integer, intent(in) :: n_part
279  !> Number of coagulated particles since last progress printing.
280  integer, intent(in) :: n_coag
281  !> Number of emitted particles since last progress printing.
282  integer, intent(in) :: n_emit
283  !> Number of diluted-in particles since last progress printing.
284  integer, intent(in) :: n_dil_in
285  !> Number of diluted-out particles since last progress printing.
286  integer, intent(in) :: n_dil_out
287  !> Number of nucleated particles since last progress printing.
288  integer, intent(in) :: n_nuc
289  !> Elapsed wall time (s).
290  real(kind=dp), intent(in) :: t_wall_elapsed
291  !> Estimated remaining wall time (s).
292  real(kind=dp), intent(in) :: t_wall_remain
293 
294  write(*,'(a6,a1,a6,a1,a7,a1,a7,a1,a7,a1,a8,a1,a9,a1,a7,a1,a6,a1,a6)') &
295  "repeat", " ", "t_sim", " ", "n_part", " ", "n_coag", " ", &
296  "n_emit", " ", "n_dil_in", " ", "n_dil_out", " ", "n_nuc", " ", &
297  "t_wall", " ", "t_rem"
298  write(*,'(a6,a1,a6,a1,a7,a1,a7,a1,a7,a1,a8,a1,a9,a1,a7,a1,a6,a1,a6)') &
299  trim(integer_to_string_max_len(i_repeat, 6)), " ", &
300  trim(time_to_string_max_len(t_sim_elapsed, 6)), " ", &
301  trim(integer_to_string_max_len(n_part, 7)), " ", &
302  trim(integer_to_string_max_len(n_coag, 7)), " ", &
303  trim(integer_to_string_max_len(n_emit, 7)), " ", &
304  trim(integer_to_string_max_len(n_dil_in, 7)), " ", &
305  trim(integer_to_string_max_len(n_dil_out, 7)), " ", &
306  trim(integer_to_string_max_len(n_nuc, 7)), " ", &
307  trim(time_to_string_max_len(t_wall_elapsed, 6)), " ", &
308  trim(time_to_string_max_len(t_wall_remain, 6))
309 
310  end subroutine print_part_progress
311 
312 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
313 
314  !> Determines the number of bytes required to pack the given value.
315  integer function pmc_mpi_pack_size_run_part_opt(val)
316 
317  !> Value to pack.
318  type(run_part_opt_t), intent(in) :: val
319 
321  pmc_mpi_pack_size_real(val%t_max) &
322  + pmc_mpi_pack_size_real(val%t_output) &
323  + pmc_mpi_pack_size_real(val%t_progress) &
324  + pmc_mpi_pack_size_real(val%del_t) &
325  + pmc_mpi_pack_size_string(val%output_prefix) &
326  + pmc_mpi_pack_size_integer(val%coag_kernel_type) &
327  + pmc_mpi_pack_size_integer(val%nucleate_type) &
328  + pmc_mpi_pack_size_integer(val%nucleate_source) &
329  + pmc_mpi_pack_size_integer(val%nucleate_weight_class) &
330  + pmc_mpi_pack_size_logical(val%do_coagulation) &
331  + pmc_mpi_pack_size_logical(val%do_nucleation) &
332  + pmc_mpi_pack_size_logical(val%do_immersion_freezing) &
333  + pmc_mpi_pack_size_integer(val%immersion_freezing_scheme_type) &
334  + pmc_mpi_pack_size_real(val%INAS_a) &
335  + pmc_mpi_pack_size_real(val%INAS_b) &
336  + pmc_mpi_pack_size_real(val%freezing_rate) &
337  + pmc_mpi_pack_size_logical(val%do_freezing_naive) &
338  + pmc_mpi_pack_size_logical(val%allow_doubling) &
339  + pmc_mpi_pack_size_logical(val%allow_halving) &
340  + pmc_mpi_pack_size_logical(val%do_condensation) &
341  + pmc_mpi_pack_size_logical(val%do_mosaic) &
342  + pmc_mpi_pack_size_logical(val%do_optical) &
343  + pmc_mpi_pack_size_logical(val%do_select_weighting) &
344  + pmc_mpi_pack_size_integer(val%weighting_type) &
345  + pmc_mpi_pack_size_real(val%weighting_exponent) &
346  + pmc_mpi_pack_size_integer(val%i_repeat) &
347  + pmc_mpi_pack_size_integer(val%n_repeat) &
348  + pmc_mpi_pack_size_real(val%t_wall_start) &
349  + pmc_mpi_pack_size_logical(val%record_removals) &
350  + pmc_mpi_pack_size_logical(val%do_parallel) &
351  + pmc_mpi_pack_size_integer(val%output_type) &
352  + pmc_mpi_pack_size_real(val%mix_timescale) &
353  + pmc_mpi_pack_size_logical(val%gas_average) &
354  + pmc_mpi_pack_size_logical(val%env_average) &
355  + pmc_mpi_pack_size_integer(val%parallel_coag_type) &
356  + pmc_mpi_pack_size_logical(val%do_camp_chem) &
357  + pmc_mpi_pack_size_logical(val%do_tchem) &
358  + pmc_mpi_pack_size_string(val%uuid)
359 
360  end function pmc_mpi_pack_size_run_part_opt
361 
362 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
363 
364  !> Packs the given value into the buffer, advancing position.
365  subroutine pmc_mpi_pack_run_part_opt(buffer, position, val)
366 
367  !> Memory buffer.
368  character, intent(inout) :: buffer(:)
369  !> Current buffer position.
370  integer, intent(inout) :: position
371  !> Value to pack.
372  type(run_part_opt_t), intent(in) :: val
373 
374 #ifdef PMC_USE_MPI
375  integer :: prev_position
376 
377  prev_position = position
378  call pmc_mpi_pack_real(buffer, position, val%t_max)
379  call pmc_mpi_pack_real(buffer, position, val%t_output)
380  call pmc_mpi_pack_real(buffer, position, val%t_progress)
381  call pmc_mpi_pack_real(buffer, position, val%del_t)
382  call pmc_mpi_pack_string(buffer, position, val%output_prefix)
383  call pmc_mpi_pack_integer(buffer, position, val%coag_kernel_type)
384  call pmc_mpi_pack_integer(buffer, position, val%nucleate_type)
385  call pmc_mpi_pack_integer(buffer, position, val%nucleate_source)
386  call pmc_mpi_pack_integer(buffer, position, val%nucleate_weight_class)
387  call pmc_mpi_pack_logical(buffer, position, val%do_coagulation)
388  call pmc_mpi_pack_logical(buffer, position, val%do_nucleation)
389  call pmc_mpi_pack_logical(buffer, position, val%do_immersion_freezing)
390  call pmc_mpi_pack_integer(buffer, position, &
391  val%immersion_freezing_scheme_type)
392 
393  call pmc_mpi_pack_real(buffer, position, val%INAS_a)
394  call pmc_mpi_pack_real(buffer, position, val%INAS_b)
395  call pmc_mpi_pack_real(buffer, position, val%freezing_rate)
396  call pmc_mpi_pack_logical(buffer, position, val%do_freezing_naive)
397  call pmc_mpi_pack_logical(buffer, position, val%allow_doubling)
398  call pmc_mpi_pack_logical(buffer, position, val%allow_halving)
399  call pmc_mpi_pack_logical(buffer, position, val%do_condensation)
400  call pmc_mpi_pack_logical(buffer, position, val%do_mosaic)
401  call pmc_mpi_pack_logical(buffer, position, val%do_optical)
402  call pmc_mpi_pack_logical(buffer, position, val%do_select_weighting)
403  call pmc_mpi_pack_integer(buffer, position, val%weighting_type)
404  call pmc_mpi_pack_real(buffer, position, val%weighting_exponent)
405  call pmc_mpi_pack_integer(buffer, position, val%i_repeat)
406  call pmc_mpi_pack_integer(buffer, position, val%n_repeat)
407  call pmc_mpi_pack_real(buffer, position, val%t_wall_start)
408  call pmc_mpi_pack_logical(buffer, position, val%record_removals)
409  call pmc_mpi_pack_logical(buffer, position, val%do_parallel)
410  call pmc_mpi_pack_integer(buffer, position, val%output_type)
411  call pmc_mpi_pack_real(buffer, position, val%mix_timescale)
412  call pmc_mpi_pack_logical(buffer, position, val%gas_average)
413  call pmc_mpi_pack_logical(buffer, position, val%env_average)
414  call pmc_mpi_pack_integer(buffer, position, val%parallel_coag_type)
415  call pmc_mpi_pack_logical(buffer, position, val%do_camp_chem)
416  call pmc_mpi_pack_logical(buffer, position, val%do_tchem)
417  call pmc_mpi_pack_string(buffer, position, val%uuid)
418  call assert(946070052, &
419  position - prev_position <= pmc_mpi_pack_size_run_part_opt(val))
420 #endif
421 
422  end subroutine pmc_mpi_pack_run_part_opt
423 
424 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
425 
426  !> Unpacks the given value from the buffer, advancing position.
427  subroutine pmc_mpi_unpack_run_part_opt(buffer, position, val)
428 
429  !> Memory buffer.
430  character, intent(inout) :: buffer(:)
431  !> Current buffer position.
432  integer, intent(inout) :: position
433  !> Value to pack.
434  type(run_part_opt_t), intent(inout) :: val
435 
436 #ifdef PMC_USE_MPI
437  integer :: prev_position
438 
439  prev_position = position
440  call pmc_mpi_unpack_real(buffer, position, val%t_max)
441  call pmc_mpi_unpack_real(buffer, position, val%t_output)
442  call pmc_mpi_unpack_real(buffer, position, val%t_progress)
443  call pmc_mpi_unpack_real(buffer, position, val%del_t)
444  call pmc_mpi_unpack_string(buffer, position, val%output_prefix)
445  call pmc_mpi_unpack_integer(buffer, position, val%coag_kernel_type)
446  call pmc_mpi_unpack_integer(buffer, position, val%nucleate_type)
447  call pmc_mpi_unpack_integer(buffer, position, val%nucleate_source)
448  call pmc_mpi_unpack_integer(buffer, position, val%nucleate_weight_class)
449  call pmc_mpi_unpack_logical(buffer, position, val%do_coagulation)
450  call pmc_mpi_unpack_logical(buffer, position, val%do_nucleation)
451  call pmc_mpi_unpack_logical(buffer, position, val%do_immersion_freezing)
452  call pmc_mpi_unpack_integer(buffer, position, val%immersion_freezing_scheme_type)
453  call pmc_mpi_unpack_real(buffer, position, val%INAS_a)
454  call pmc_mpi_unpack_real(buffer, position, val%INAS_b)
455  call pmc_mpi_unpack_real(buffer, position, val%freezing_rate)
456  call pmc_mpi_unpack_logical(buffer, position, val%do_freezing_naive)
457  call pmc_mpi_unpack_logical(buffer, position, val%allow_doubling)
458  call pmc_mpi_unpack_logical(buffer, position, val%allow_halving)
459  call pmc_mpi_unpack_logical(buffer, position, val%do_condensation)
460  call pmc_mpi_unpack_logical(buffer, position, val%do_mosaic)
461  call pmc_mpi_unpack_logical(buffer, position, val%do_optical)
462  call pmc_mpi_unpack_logical(buffer, position, val%do_select_weighting)
463  call pmc_mpi_unpack_integer(buffer, position, val%weighting_type)
464  call pmc_mpi_unpack_real(buffer, position, val%weighting_exponent)
465  call pmc_mpi_unpack_integer(buffer, position, val%i_repeat)
466  call pmc_mpi_unpack_integer(buffer, position, val%n_repeat)
467  call pmc_mpi_unpack_real(buffer, position, val%t_wall_start)
468  call pmc_mpi_unpack_logical(buffer, position, val%record_removals)
469  call pmc_mpi_unpack_logical(buffer, position, val%do_parallel)
470  call pmc_mpi_unpack_integer(buffer, position, val%output_type)
471  call pmc_mpi_unpack_real(buffer, position, val%mix_timescale)
472  call pmc_mpi_unpack_logical(buffer, position, val%gas_average)
473  call pmc_mpi_unpack_logical(buffer, position, val%env_average)
474  call pmc_mpi_unpack_integer(buffer, position, val%parallel_coag_type)
475  call pmc_mpi_unpack_logical(buffer, position, val%do_camp_chem)
476  call pmc_mpi_unpack_logical(buffer, position, val%do_tchem)
477  call pmc_mpi_unpack_string(buffer, position, val%uuid)
478  call assert(480118362, &
479  position - prev_position <= pmc_mpi_pack_size_run_part_opt(val))
480 #endif
481 
482  end subroutine pmc_mpi_unpack_run_part_opt
483 
484 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
485 
486  !> Read the specification for a run_part simulation from a spec file.
487  subroutine spec_file_read_run_part(file, run_part_opt, aero_data, &
488  aero_state_init, gas_data, gas_state_init, env_state_init, &
489  aero_dist_init, scenario, &
490 #ifdef PMC_USE_CAMP
491  camp_core, photolysis, aero_state, &
492 #endif
493  n_part, rand_init, do_init_equilibrate, do_restart)
494 
495  !> Spec file.
496  type(spec_file_t), intent(inout) :: file
497  !> Monte Carlo options.
498  type(run_part_opt_t), intent(inout) :: run_part_opt
499  !> Aerosol data.
500  type(aero_data_t), intent(inout) :: aero_data
501  !> Initial aerosol state.
502  type(aero_state_t), intent(inout) :: aero_state_init
503  !> Gas data.
504  type(gas_data_t), intent(inout) :: gas_data
505  !> Initial gas state.
506  type(gas_state_t), intent(inout) :: gas_state_init
507  !> Initial environmental state.
508  type(env_state_t), intent(inout) :: env_state_init
509  !> Initial aerosol distribution.
510  type(aero_dist_t), intent(inout) :: aero_dist_init
511  !> Scenario data.
512  type(scenario_t), intent(inout) :: scenario
513 #ifdef PMC_USE_CAMP
514  !> CAMP core.
515  type(camp_core_t), pointer :: camp_core
516  !> Photolysis calculator.
517  type(photolysis_t), pointer :: photolysis
518  !> Aerosol state.
519  type(aero_state_t), intent(inout) :: aero_state
520 #endif
521  !> Ideal number of computational particles.
522  real(kind=dp), intent(inout) :: n_part
523  !> Random number generator seed.
524  integer, intent(out) :: rand_init
525  !> Whether to equilibrate.
526  logical, intent(out) :: do_init_equilibrate
527  !> Whether simulation is a restart.
528  logical, intent(out) :: do_restart
529 
530  integer :: i_repeat, i_group
531  logical :: read_aero_weight_classes
532  character(len=PMC_MAX_FILENAME_LEN) :: restart_filename
533  integer :: dummy_index, dummy_i_repeat
534  real(kind=dp) :: dummy_time, dummy_del_t
535  character(len=PMC_MAX_FILENAME_LEN) :: sub_filename
536  type(spec_file_t) :: sub_file
537  character(len=PMC_MAX_FILENAME_LEN) :: camp_config_filename, &
538  tchem_gas_filename, tchem_aero_filename, tchem_numerics_filename
539  integer :: n_grid_cells
540 
541  call spec_file_read_string(file, 'output_prefix', &
542  run_part_opt%output_prefix)
543  call spec_file_read_integer(file, 'n_repeat', run_part_opt%n_repeat)
544  call spec_file_read_real(file, 'n_part', n_part)
545  call spec_file_read_logical(file, 'restart', do_restart)
546  if (do_restart) then
547  call spec_file_read_string(file, 'restart_file', restart_filename)
548  end if
549 
550  if (.not. do_restart) then
551  call spec_file_read_logical(file, 'do_select_weighting', &
552  run_part_opt%do_select_weighting)
553  read_aero_weight_classes = .false.
554  if (run_part_opt%do_select_weighting) then
555  call spec_file_read_aero_state_weighting_type(file, &
556  run_part_opt%weighting_type, run_part_opt%weighting_exponent)
557  if (run_part_opt%weighting_type &
559  read_aero_weight_classes = .true.
560  end if
561  else
562  run_part_opt%weighting_type = aero_state_weight_nummass_source
563  run_part_opt%weighting_exponent = 0.0d0
564  end if
565  end if
566 
567  call spec_file_read_real(file, 't_max', run_part_opt%t_max)
568  call spec_file_read_real(file, 'del_t', run_part_opt%del_t)
569  call spec_file_read_real(file, 't_output', run_part_opt%t_output)
570  call spec_file_read_real(file, 't_progress', run_part_opt%t_progress)
571 
572  call spec_file_read_logical(file, 'do_camp_chem', run_part_opt%do_camp_chem)
573  if (run_part_opt%do_camp_chem) then
574 #ifdef PMC_USE_CAMP
575  call spec_file_read_string(file, 'camp_config', camp_config_filename)
576  camp_core => camp_core_t(camp_config_filename)
577  call camp_core%initialize()
578  photolysis => photolysis_t(camp_core)
579 #else
580  call spec_file_die_msg(648994111, file, &
581  'cannot do camp chem, CAMP support not compiled in')
582 #endif
583  end if
584 
585  call spec_file_read_logical(file, 'do_tchem', run_part_opt%do_tchem)
586  if (run_part_opt%do_tchem) then
587 #ifdef PMC_USE_TCHEM
588  call spec_file_read_string(file, 'tchem_gas_config', &
589  tchem_gas_filename)
590  call spec_file_read_string(file, 'tchem_aero_config', &
591  tchem_aero_filename)
592  call spec_file_read_string(file, 'tchem_numerics_config', &
593  tchem_numerics_filename)
594 #endif
595  end if
596 
597  if (run_part_opt%do_tchem) then
598 #ifdef PMC_USE_TCHEM
599  n_grid_cells = 1
600  call pmc_tchem_initialize(tchem_gas_filename, tchem_aero_filename, &
601  tchem_numerics_filename, gas_data, aero_data, n_grid_cells)
602 #endif
603  end if
604 
605  if (do_restart) then
606  call input_state(restart_filename, dummy_index, dummy_time, &
607  dummy_del_t, dummy_i_repeat, run_part_opt%uuid, aero_data, &
608  aero_state_init, gas_data, gas_state_init, env_state_init)
609  end if
610 
611  if (.not. do_restart) then
612  env_state_init%elapsed_time = 0d0
613 
614  if (.not. (run_part_opt%do_camp_chem .or. run_part_opt%do_tchem)) then
615  call spec_file_read_string(file, 'gas_data', sub_filename)
616  call spec_file_open(sub_filename, sub_file)
617  call spec_file_read_gas_data(sub_file, gas_data)
618  call spec_file_close(sub_file)
619  else if (run_part_opt%do_camp_chem) then
620 #ifdef PMC_USE_CAMP
621  call gas_data_initialize(gas_data, camp_core)
622 #endif
623  end if
624  call spec_file_read_string(file, 'gas_init', sub_filename)
625  call spec_file_open(sub_filename, sub_file)
626  call spec_file_read_gas_state(sub_file, gas_data, gas_state_init)
627  call spec_file_close(sub_file)
628 
629  if (.not. run_part_opt%do_camp_chem) then
630  call spec_file_read_string(file, 'aerosol_data', sub_filename)
631  call spec_file_open(sub_filename, sub_file)
632  call spec_file_read_aero_data(sub_file, aero_data)
633  call spec_file_close(sub_file)
634  ! FIXME: Temporary to run PartMC. Replace with initialization from TChem
635  else if (run_part_opt%do_tchem) then
636  call spec_file_read_string(file, 'aerosol_data', sub_filename)
637  call spec_file_open(sub_filename, sub_file)
638  call spec_file_read_aero_data(sub_file, aero_data)
639  call spec_file_close(sub_file)
640  else
641 #ifdef PMC_USE_CAMP
642  call aero_data_initialize(aero_data, camp_core)
643  call aero_state_initialize(aero_state, aero_data, camp_core)
644 #endif
645  end if
646  call spec_file_read_fractal(file, aero_data%fractal)
647 
648  call spec_file_read_string(file, 'aerosol_init', sub_filename)
649  call spec_file_open(sub_filename, sub_file)
650  call spec_file_read_aero_dist(sub_file, aero_data, &
651  read_aero_weight_classes, aero_dist_init)
652  call spec_file_close(sub_file)
653  end if
654 
655  call spec_file_read_scenario(file, gas_data, aero_data, &
656  read_aero_weight_classes, scenario)
657  call spec_file_read_env_state(file, env_state_init)
658 
659  call spec_file_read_logical(file, 'do_coagulation', &
660  run_part_opt%do_coagulation)
661  if (run_part_opt%do_coagulation) then
662  call spec_file_read_coag_kernel_type(file, run_part_opt%coag_kernel_type)
663  if (run_part_opt%coag_kernel_type == coag_kernel_type_additive) then
664  call spec_file_read_real(file, 'additive_kernel_coeff', &
665  env_state_init%additive_kernel_coefficient)
666  end if
667  else
668  run_part_opt%coag_kernel_type = coag_kernel_type_invalid
669  end if
670 
671  call spec_file_read_logical(file, 'do_condensation', &
672  run_part_opt%do_condensation)
673 #ifndef PMC_USE_SUNDIALS
674  call assert_msg(121370218, &
675  run_part_opt%do_condensation .eqv. .false., &
676  "cannot use condensation, SUNDIALS support is not compiled in")
677 #endif
678  do_init_equilibrate = .false.
679  if (run_part_opt%do_condensation) then
680  call spec_file_read_logical(file, 'do_init_equilibrate', &
681  do_init_equilibrate)
682  end if
683 
684  call spec_file_read_logical(file, 'do_mosaic', run_part_opt%do_mosaic)
685  if (run_part_opt%do_mosaic .and. (.not. mosaic_support())) then
686  call spec_file_die_msg(230495365, file, &
687  'cannot use MOSAIC, support is not compiled in')
688  end if
689  if (run_part_opt%do_mosaic .and. run_part_opt%do_condensation) then
690  call spec_file_die_msg(599877804, file, &
691  'cannot use MOSAIC and condensation simultaneously')
692  end if
693  if (run_part_opt%do_mosaic) then
694  call spec_file_read_logical(file, 'do_optical', &
695  run_part_opt%do_optical)
696  else
697  run_part_opt%do_optical = .false.
698  end if
699 
700  call spec_file_read_logical(file, 'do_nucleation', &
701  run_part_opt%do_nucleation)
702  if (run_part_opt%do_nucleation) then
703  call spec_file_read_nucleate_type(file, aero_data, &
704  run_part_opt%nucleate_type, run_part_opt%nucleate_source, &
705  run_part_opt%nucleate_weight_class)
706  else
707  run_part_opt%nucleate_type = nucleate_type_invalid
708  end if
709  call spec_file_read_logical(file, 'do_immersion_freezing', &
710  run_part_opt%do_immersion_freezing)
711 
712  if (run_part_opt%do_immersion_freezing) then
713 
714  call spec_file_read_immersion_freezing_scheme_type(file, &
715  run_part_opt%immersion_freezing_scheme_type)
716 
717  if (run_part_opt%immersion_freezing_scheme_type .eq. &
719  call spec_file_read_real(file, 'freezing_rate', &
720  run_part_opt%freezing_rate)
721  end if
722 
723  if ((run_part_opt%immersion_freezing_scheme_type .eq. &
725  (run_part_opt%immersion_freezing_scheme_type .eq. &
727  call spec_file_read_logical(file, 'do_freezing_naive', &
728  run_part_opt%do_freezing_naive)
729  end if
730 
731 
732  if (run_part_opt%immersion_freezing_scheme_type .eq.&
734  call spec_file_read_real(file, 'INAS_a', run_part_opt%INAS_a)
735  call spec_file_read_real(file, 'INAS_b', run_part_opt%INAS_b)
736  end if
737 
738  end if
739 
740  call spec_file_read_integer(file, 'rand_init', rand_init)
741  call spec_file_read_logical(file, 'allow_doubling', &
742  run_part_opt%allow_doubling)
743  call spec_file_read_logical(file, 'allow_halving', &
744  run_part_opt%allow_halving)
745  call spec_file_read_logical(file, 'record_removals', &
746  run_part_opt%record_removals)
747 
748  call spec_file_read_logical(file, 'do_parallel', run_part_opt%do_parallel)
749  if (run_part_opt%do_parallel) then
750 #ifndef PMC_USE_MPI
751  call spec_file_die_msg(929006383, file, &
752  'cannot use parallel mode, support is not compiled in')
753 #endif
754  call spec_file_read_output_type(file, run_part_opt%output_type)
755  call spec_file_read_real(file, 'mix_timescale', &
756  run_part_opt%mix_timescale)
757  call spec_file_read_logical(file, 'gas_average', &
758  run_part_opt%gas_average)
759  call spec_file_read_logical(file, 'env_average', &
760  run_part_opt%env_average)
761  call spec_file_read_parallel_coag_type(file, &
762  run_part_opt%parallel_coag_type)
763  else
764  run_part_opt%output_type = output_type_single
765  run_part_opt%mix_timescale = 0d0
766  run_part_opt%gas_average = .false.
767  run_part_opt%env_average = .false.
768  run_part_opt%parallel_coag_type = parallel_coag_type_local
769  end if
770 
771  call spec_file_close(file)
772 
773  end subroutine spec_file_read_run_part
774 
775 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
776 
777  !> Read the specification for a parallel coagulation type from a spec file.
778  subroutine spec_file_read_parallel_coag_type(file, parallel_coag_type)
779 
780  !> Spec file.
781  type(spec_file_t), intent(inout) :: file
782  !> Kernel type.
783  integer, intent(out) :: parallel_coag_type
784 
785  character(len=SPEC_LINE_MAX_VAR_LEN) :: parallel_coag_type_name
786 
787  !> \page input_format_parallel_coag Input File Format: Parallel Coagulation Type
788  !!
789  !! The output type is specified by the parameter:
790  !! - \b parallel_coag (string): type of parallel coagulation ---
791  !! must be one of: \c local for only within-process
792  !! coagulation or \c dist to have all processes perform
793  !! coagulation globally, requesting particles from other
794  !! processes as needed
795  !!
796  !! See also:
797  !! - \ref spec_file_format --- the input file text format
798 
799  call spec_file_read_string(file, 'parallel_coag', &
800  parallel_coag_type_name)
801  if (trim(parallel_coag_type_name) == 'local') then
802  parallel_coag_type = parallel_coag_type_local
803  elseif (trim(parallel_coag_type_name) == 'dist') then
804  parallel_coag_type = parallel_coag_type_dist
805  else
806  call spec_file_die_msg(494684716, file, &
807  "Unknown parallel coagulation type: " &
808  // trim(parallel_coag_type_name))
809  end if
810 
811  end subroutine spec_file_read_parallel_coag_type
812 
813 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
814 
815  !> Do a one particle-resolved Monte Carlo simulation timestep.
816  subroutine run_part_timestep(scenario, env_state, aero_data, aero_state, &
817  gas_data, gas_state, run_part_opt, &
818 #ifdef PMC_USE_CAMP
819  camp_core, photolysis, &
820 #endif
821  i_time, t_start, last_output_time, last_progress_time, i_output, &
822  progress_n_samp, progress_n_coag, progress_n_emit, progress_n_dil_in, &
823  progress_n_dil_out, progress_n_nuc)
824 
825  !> Environment state.
826  type(scenario_t), intent(in) :: scenario
827  !> Environment state.
828  type(env_state_t), intent(inout) :: env_state
829  !> Aerosol data.
830  type(aero_data_t), intent(in) :: aero_data
831  !> Aerosol state.
832  type(aero_state_t), intent(inout) :: aero_state
833  !> Gas data.
834  type(gas_data_t), intent(in) :: gas_data
835  !> Gas state.
836  type(gas_state_t), intent(inout) :: gas_state
837  !> Monte Carlo options.
838  type(run_part_opt_t), intent(in) :: run_part_opt
839 #ifdef PMC_USE_CAMP
840  !> CAMP chemistry core
841  type(camp_core_t), pointer, intent(inout), optional :: camp_core
842  !> Photolysis calculator
843  type(photolysis_t), pointer, intent(inout), optional :: photolysis
844 #endif
845  !> Current simulation time.
846  integer, intent(in) :: i_time
847  ! Start time of simulation.
848  real(kind=dp), intent(in) :: t_start
849  !> Last time output was written (s).
850  real(kind=dp), intent(inout) :: last_output_time
851  !> Last time progress was output to screen (s).
852  real(kind=dp), intent(inout) :: last_progress_time
853  !> Output timestep integer for output filename.
854  integer, intent(inout) :: i_output
855  !> Total number of samples tested.
856  integer, intent(inout) :: progress_n_samp
857  !> Number of coagulation events.
858  integer, intent(inout) :: progress_n_coag
859  !> Number of particles added by emission.
860  integer, intent(inout) :: progress_n_emit
861  !> Number of particles added by dilution.
862  integer, intent(inout) :: progress_n_dil_in
863  !> Number of particles removed by dilution.
864  integer, intent(inout) :: progress_n_dil_out
865  !> Number of particles added by nucleation.
866  integer, intent(inout) :: progress_n_nuc
867 
868  real(kind=dp) :: prop_done
869  integer :: n_samp, n_coag, n_emit, n_dil_in, n_dil_out, n_nuc
870  integer :: n_part_before
871  integer :: global_n_part, global_n_samp, global_n_coag
872  integer :: global_n_emit, global_n_dil_in, global_n_dil_out
873  integer :: global_n_nuc
874  logical :: do_output, do_state, do_state_netcdf, do_progress
875  real(kind=dp) :: t_wall_now, t_wall_elapsed, t_wall_remain, time
876  type(env_state_t) :: old_env_state
877 #ifdef PMC_USE_CAMP
878  type(camp_state_t), pointer :: camp_state
879  type(camp_state_t), pointer :: camp_pre_aero_state, camp_post_aero_state
880  type(camp_env_state_t) :: camp_env_state
881 #endif
882 
883  time = i_time * run_part_opt%del_t
884 
885 #ifdef PMC_USE_CAMP
886  if (run_part_opt%do_camp_chem) then
887  camp_env_state%temp = env_state%temp
888  camp_env_state%pressure = env_state%pressure
889  camp_state => camp_core%new_state_one_cell(camp_env_state)
890  camp_pre_aero_state => camp_core%new_state_one_cell(camp_env_state)
891  camp_post_aero_state => camp_core%new_state_one_cell(camp_env_state)
892  end if
893 #endif
894 
895  old_env_state = env_state
896  call scenario_update_env_state(scenario, env_state, time + t_start)
897 
898  if (run_part_opt%do_nucleation) then
899  n_part_before = aero_state_total_particles(aero_state)
900  call nucleate(run_part_opt%nucleate_type, &
901  run_part_opt%nucleate_source, run_part_opt%nucleate_weight_class, &
902  env_state, gas_data, aero_data, &
903  aero_state, gas_state, run_part_opt%del_t, &
904  run_part_opt%allow_doubling, run_part_opt%allow_halving)
905  n_nuc = aero_state_total_particles(aero_state) &
906  - n_part_before
907  progress_n_nuc = progress_n_nuc + n_nuc
908  end if
909  if (run_part_opt%do_immersion_freezing) then
910  call ice_nucleation_immersion_freezing(aero_state, aero_data, env_state, &
911  run_part_opt%del_t, run_part_opt%immersion_freezing_scheme_type, &
912  run_part_opt%freezing_rate, run_part_opt%do_freezing_naive, &
913  run_part_opt%INAS_a, run_part_opt%INAS_b)
914  call ice_nucleation_melting(aero_state, aero_data, env_state)
915  end if
916  if (run_part_opt%do_coagulation) then
917  if (run_part_opt%parallel_coag_type &
918  == parallel_coag_type_local) then
919  call mc_coag(run_part_opt%coag_kernel_type, env_state, &
920  aero_data, aero_state, run_part_opt%del_t, n_samp, n_coag)
921  elseif (run_part_opt%parallel_coag_type &
922  == parallel_coag_type_dist) then
923  call mc_coag_dist(run_part_opt%coag_kernel_type, env_state, &
924  aero_data, aero_state, run_part_opt%del_t, n_samp, n_coag)
925  else
926  call die_msg(323011762, "unknown parallel coagulation type: " &
927  // trim(integer_to_string(run_part_opt%parallel_coag_type)))
928  end if
929  progress_n_samp = progress_n_samp + n_samp
930  progress_n_coag = progress_n_coag + n_coag
931  end if
932 
933 #ifdef PMC_USE_SUNDIALS
934  if (run_part_opt%do_condensation) then
935  call condense_particles(aero_state, aero_data, old_env_state, &
936  env_state, run_part_opt%del_t)
937  end if
938 #endif
939 
940  call scenario_update_gas_state(scenario, run_part_opt%del_t, &
941  env_state, old_env_state, gas_data, gas_state)
942  call scenario_update_aero_state(scenario, run_part_opt%del_t, &
943  env_state, old_env_state, aero_data, aero_state, n_emit, &
944  n_dil_in, n_dil_out, run_part_opt%allow_doubling, &
945  run_part_opt%allow_halving)
946  progress_n_emit = progress_n_emit + n_emit
947  progress_n_dil_in = progress_n_dil_in + n_dil_in
948  progress_n_dil_out = progress_n_dil_out + n_dil_out
949 
950  if (run_part_opt%do_camp_chem) then
951 #ifdef PMC_USE_CAMP
952  call pmc_camp_interface_solve(camp_core, camp_state, &
953  camp_pre_aero_state, camp_post_aero_state, env_state, &
954  aero_data, aero_state, gas_data, gas_state, photolysis, &
955  run_part_opt%del_t)
956 #endif
957  end if
958 
959  if (run_part_opt%do_tchem) then
960 #ifdef PMC_USE_TCHEM
961  call pmc_tchem_interface_solve(env_state, aero_data, aero_state, &
962  gas_data, gas_state, run_part_opt%del_t)
963 #endif
964  end if
965 
966  if (run_part_opt%do_mosaic) then
967  call mosaic_timestep(env_state, aero_data, aero_state, gas_data, &
968  gas_state, run_part_opt%do_optical, run_part_opt%uuid)
969  end if
970 
971  if (run_part_opt%mix_timescale > 0d0) then
972  call aero_state_mix(aero_state, run_part_opt%del_t, &
973  run_part_opt%mix_timescale, aero_data)
974  end if
975  if (run_part_opt%gas_average) then
976  call gas_state_mix(gas_state)
977  end if
978  if (run_part_opt%gas_average) then
979  call env_state_mix(env_state)
980  end if
981 
982  call aero_state_rebalance(aero_state, aero_data, &
983  run_part_opt%allow_doubling, &
984  run_part_opt%allow_halving, initial_state_warning=.false.)
985 
986 
987  if (run_part_opt%t_output > 0d0) then
988  call check_event(time, run_part_opt%del_t, run_part_opt%t_output, &
989  last_output_time, do_output)
990  if (do_output) then
991  i_output = i_output + 1
992  call output_state(run_part_opt%output_prefix, &
993  run_part_opt%output_type, aero_data, aero_state, gas_data, &
994  gas_state, env_state, i_output, time, run_part_opt%del_t, &
995  run_part_opt%i_repeat, run_part_opt%record_removals, &
996  run_part_opt%do_optical, run_part_opt%uuid)
997  call aero_info_array_zero(aero_state%aero_info_array)
998  end if
999  end if
1000 
1001  if (.not. run_part_opt%record_removals) then
1002  ! If we are not recording removals then we can zero them as
1003  ! often as possible to minimize the cost of maintaining
1004  ! them.
1005  call aero_info_array_zero(aero_state%aero_info_array)
1006  end if
1007 
1008  if (run_part_opt%t_progress > 0d0) then
1009  call check_event(time, run_part_opt%del_t, &
1010  run_part_opt%t_progress, last_progress_time, do_progress)
1011  if (do_progress) then
1012  global_n_part = aero_state_total_particles_all_procs(aero_state)
1013  call pmc_mpi_reduce_sum_integer(progress_n_samp, global_n_samp)
1014  call pmc_mpi_reduce_sum_integer(progress_n_coag, global_n_coag)
1015  call pmc_mpi_reduce_sum_integer(progress_n_emit, global_n_emit)
1016  call pmc_mpi_reduce_sum_integer(progress_n_dil_in, &
1017  global_n_dil_in)
1018  call pmc_mpi_reduce_sum_integer(progress_n_dil_out, &
1019  global_n_dil_out)
1020  call pmc_mpi_reduce_sum_integer(progress_n_nuc, global_n_nuc)
1021  if (pmc_mpi_rank() == 0) then
1022  ! progress only printed from root process
1023  t_wall_now = system_clock_time()
1024  prop_done = (real(run_part_opt%i_repeat - 1, kind=dp) &
1025  + time / run_part_opt%t_max) &
1026  / real(run_part_opt%n_repeat, kind=dp)
1027  t_wall_elapsed = t_wall_now - run_part_opt%t_wall_start
1028  t_wall_remain = (1d0 - prop_done) / prop_done * t_wall_elapsed
1029  call print_part_progress(run_part_opt%i_repeat, time, &
1030  global_n_part, global_n_coag, global_n_emit, &
1031  global_n_dil_in, global_n_dil_out, global_n_nuc, &
1032  t_wall_elapsed, t_wall_remain)
1033  end if
1034  ! reset counters so they show information since last
1035  ! progress display
1036  progress_n_samp = 0
1037  progress_n_coag = 0
1038  progress_n_emit = 0
1039  progress_n_dil_in = 0
1040  progress_n_dil_out = 0
1041  progress_n_nuc = 0
1042  end if
1043  end if
1044 
1045  end subroutine run_part_timestep
1046 
1047 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1048 
1049  !> Do a number of time steps of particle-reoslved Monte Carlo simulation.
1050  subroutine run_part_timeblock(scenario, env_state, aero_data, aero_state, &
1051  gas_data, gas_state, run_part_opt, &
1052 #ifdef PMC_USE_CAMP
1053  camp_core, photolysis, &
1054 #endif
1055  i_cur, i_next, t_start, last_output_time, last_progress_time, &
1056  i_output, progress_n_samp, progress_n_coag, progress_n_emit, &
1057  progress_n_dil_in, progress_n_dil_out, progress_n_nuc)
1058 
1059  !> Environment state.
1060  type(scenario_t), intent(in) :: scenario
1061  !> Environment state.
1062  type(env_state_t), intent(inout) :: env_state
1063  !> Aerosol data.
1064  type(aero_data_t), intent(in) :: aero_data
1065  !> Aerosol state.
1066  type(aero_state_t), intent(inout) :: aero_state
1067  !> Gas data.
1068  type(gas_data_t), intent(in) :: gas_data
1069  !> Gas state.
1070  type(gas_state_t), intent(inout) :: gas_state
1071  !> Monte Carlo options.
1072  type(run_part_opt_t), intent(in) :: run_part_opt
1073 #ifdef PMC_USE_CAMP
1074  !> CAMP chemistry core
1075  type(camp_core_t), pointer, intent(inout), optional :: camp_core
1076  !> Photolysis calculator
1077  type(photolysis_t), pointer, intent(inout), optional :: photolysis
1078 #endif
1079  !> Current simulation timestep.
1080  integer, intent(in) :: i_cur
1081  ! Start time of simulation.
1082  real(kind=dp), intent(in) :: t_start
1083  ! End timestep to simulate.
1084  integer, intent(in) :: i_next
1085  !> Last time output was written (s).
1086  real(kind=dp), intent(inout) :: last_output_time
1087  !> Last time progress was output to screen (s).
1088  real(kind=dp), intent(inout) :: last_progress_time
1089  !> Output timestep integer for output filename.
1090  integer, intent(inout) :: i_output
1091  !> Total number of samples tested.
1092  integer, intent(inout) :: progress_n_samp
1093  !> Number of coagulation events.
1094  integer, intent(inout) :: progress_n_coag
1095  !> Number of particles added by emission.
1096  integer, intent(inout) :: progress_n_emit
1097  !> Number of particles added by dilution.
1098  integer, intent(inout) :: progress_n_dil_in
1099  !> Number of particles removed by dilution.
1100  integer, intent(inout) :: progress_n_dil_out
1101  !> Number of particles added by nucleation.
1102  integer, intent(inout) :: progress_n_nuc
1103 
1104  integer :: i_time
1105 
1106  do i_time = i_cur,i_next
1107  call run_part_timestep(scenario, env_state, aero_data, aero_state, &
1108  gas_data, gas_state, run_part_opt, &
1109 #ifdef PMC_USE_CAMP
1110  camp_core, photolysis, &
1111 #endif
1112  i_time, t_start, last_output_time, last_progress_time, i_output, &
1113  progress_n_samp, progress_n_coag, progress_n_emit, &
1114  progress_n_dil_in, progress_n_dil_out, progress_n_nuc)
1115  end do
1116 
1117  end subroutine run_part_timeblock
1118 
1119 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1120 
1121  !> Read the specification for a run_part simulation from a spec file.
1122  subroutine pmc_mpi_broadcast_run_part(run_part_opt, aero_data, &
1123  aero_state_init, gas_data, gas_state_init, env_state_init, &
1124  aero_dist_init, scenario, &
1125 #ifdef PMC_USE_CAMP
1126  camp_core, photolysis, aero_state, &
1127 #endif
1128  n_part, rand_init, do_init_equilibrate, do_restart)
1129 
1130  !> Monte Carlo options.
1131  type(run_part_opt_t), intent(inout) :: run_part_opt
1132  !> Aerosol data.
1133  type(aero_data_t), intent(inout) :: aero_data
1134  !> Initial aerosol state.
1135  type(aero_state_t), intent(inout) :: aero_state_init
1136  !> Gas data.
1137  type(gas_data_t), intent(inout) :: gas_data
1138  !> Initial gas state.
1139  type(gas_state_t), intent(inout) :: gas_state_init
1140  !> Initial environmental state.
1141  type(env_state_t), intent(inout) :: env_state_init
1142  !> Initial aerosol distribution.
1143  type(aero_dist_t), intent(inout) :: aero_dist_init
1144  !> Scenario data.
1145  type(scenario_t), intent(inout) :: scenario
1146 #ifdef PMC_USE_CAMP
1147  !> CAMP core.
1148  type(camp_core_t), pointer :: camp_core
1149  !> Photolysis calculator.
1150  type(photolysis_t), pointer :: photolysis
1151  !> Aerosol state.
1152  type(aero_state_t), intent(inout) :: aero_state
1153 #endif
1154  !> Ideal number of computational particles.
1155  real(kind=dp), intent(inout) :: n_part
1156  !> Random number generator seed.
1157  integer, intent(inout) :: rand_init
1158  !> Whether to equilibrate.
1159  logical, intent(inout) :: do_init_equilibrate
1160  !> Whether simulation is a restart.
1161  logical, intent(inout) :: do_restart
1162 
1163  character, allocatable :: buffer(:)
1164  integer :: buffer_size, max_buffer_size
1165  integer :: position
1166 
1167 #ifdef PMC_USE_MPI
1168  if (pmc_mpi_rank() == 0) then
1169  ! root process determines size
1170  max_buffer_size = 0
1171  max_buffer_size = max_buffer_size &
1172  + pmc_mpi_pack_size_run_part_opt(run_part_opt)
1173  max_buffer_size = max_buffer_size &
1174  + pmc_mpi_pack_size_real(n_part)
1175  max_buffer_size = max_buffer_size &
1176  + pmc_mpi_pack_size_gas_data(gas_data)
1177  max_buffer_size = max_buffer_size &
1178  + pmc_mpi_pack_size_gas_state(gas_state_init)
1179  max_buffer_size = max_buffer_size &
1180  + pmc_mpi_pack_size_aero_data(aero_data)
1181  max_buffer_size = max_buffer_size &
1182  + pmc_mpi_pack_size_aero_dist(aero_dist_init)
1183  max_buffer_size = max_buffer_size &
1184  + pmc_mpi_pack_size_scenario(scenario)
1185  max_buffer_size = max_buffer_size &
1186  + pmc_mpi_pack_size_env_state(env_state_init)
1187  max_buffer_size = max_buffer_size &
1188  + pmc_mpi_pack_size_integer(rand_init)
1189  max_buffer_size = max_buffer_size &
1190  + pmc_mpi_pack_size_logical(do_restart)
1191  max_buffer_size = max_buffer_size &
1192  + pmc_mpi_pack_size_logical(do_init_equilibrate)
1193  max_buffer_size = max_buffer_size &
1194  + pmc_mpi_pack_size_aero_state(aero_state_init)
1195 
1196  allocate(buffer(max_buffer_size))
1197 
1198  position = 0
1199  call pmc_mpi_pack_run_part_opt(buffer, position, run_part_opt)
1200  call pmc_mpi_pack_real(buffer, position, n_part)
1201  call pmc_mpi_pack_gas_data(buffer, position, gas_data)
1202  call pmc_mpi_pack_gas_state(buffer, position, gas_state_init)
1203  call pmc_mpi_pack_aero_data(buffer, position, aero_data)
1204  call pmc_mpi_pack_aero_dist(buffer, position, aero_dist_init)
1205  call pmc_mpi_pack_scenario(buffer, position, scenario)
1206  call pmc_mpi_pack_env_state(buffer, position, env_state_init)
1207  call pmc_mpi_pack_integer(buffer, position, rand_init)
1208  call pmc_mpi_pack_logical(buffer, position, do_restart)
1209  call pmc_mpi_pack_logical(buffer, position, do_init_equilibrate)
1210  call pmc_mpi_pack_aero_state(buffer, position, aero_state_init)
1211  call assert(181905491, position <= max_buffer_size)
1212  buffer_size = position ! might be less than we allocated
1213  end if
1214 
1215  ! tell everyone the size
1216  call pmc_mpi_bcast_integer(buffer_size)
1217 
1218  if (pmc_mpi_rank() /= 0) then
1219  ! non-root processes allocate space
1220  allocate(buffer(buffer_size))
1221  end if
1222 
1223  ! broadcast data to everyone
1224  call pmc_mpi_bcast_packed(buffer)
1225 
1226  if (pmc_mpi_rank() /= 0) then
1227  ! non-root processes unpack data
1228  position = 0
1229  call pmc_mpi_unpack_run_part_opt(buffer, position, run_part_opt)
1230  call pmc_mpi_unpack_real(buffer, position, n_part)
1231  call pmc_mpi_unpack_gas_data(buffer, position, gas_data)
1232  call pmc_mpi_unpack_gas_state(buffer, position, gas_state_init)
1233  call pmc_mpi_unpack_aero_data(buffer, position, aero_data)
1234  call pmc_mpi_unpack_aero_dist(buffer, position, aero_dist_init)
1235  call pmc_mpi_unpack_scenario(buffer, position, scenario)
1236  call pmc_mpi_unpack_env_state(buffer, position, env_state_init)
1237  call pmc_mpi_unpack_integer(buffer, position, rand_init)
1238  call pmc_mpi_unpack_logical(buffer, position, do_restart)
1239  call pmc_mpi_unpack_logical(buffer, position, do_init_equilibrate)
1240  call pmc_mpi_unpack_aero_state(buffer, position, aero_state_init)
1241  call assert(143770146, position == buffer_size)
1242  end if
1243 
1244  ! free the buffer
1245  deallocate(buffer)
1246 #endif
1247 
1248  end subroutine pmc_mpi_broadcast_run_part
1249 
1250 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1251 
1252 end module pmc_run_part
pmc_run_part::parallel_coag_type_local
integer, parameter parallel_coag_type_local
Type code for local parallel coagulation.
Definition: run_part.F90:45
pmc_util::time_to_string_max_len
character(len=pmc_util_convert_string_len) function time_to_string_max_len(time, max_len)
Convert a time to a string format of maximum length.
Definition: util.F90:929
pmc_ice_nucleation::immersion_freezing_scheme_abifm
integer, parameter immersion_freezing_scheme_abifm
Type code for the ABIFM immersion freezing scheme.
Definition: ice_nucleation.F90:27
pmc_run_part::pmc_mpi_pack_run_part_opt
subroutine pmc_mpi_pack_run_part_opt(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: run_part.F90:366
pmc_gas_data::gas_data_t
Constant gas data.
Definition: gas_data.F90:35
pmc_mpi::pmc_mpi_size
integer function pmc_mpi_size()
Returns the total number of processes.
Definition: mpi.F90:134
pmc_mpi
Wrapper functions for MPI.
Definition: mpi.F90:13
pmc_aero_state::aero_state_weight_nummass_source
integer, parameter aero_state_weight_nummass_source
Coupled number/mass weighting by source.
Definition: aero_state.F90:51
pmc_gas_state::gas_state_mix
subroutine gas_state_mix(val)
Average val over all processes.
Definition: gas_state.F90:472
pmc_util::system_clock_time
real(kind=dp) function system_clock_time()
Returns the current system clock time in seconds.
Definition: util.F90:1977
pmc_aero_state::aero_state_weight_flat_specified
integer, parameter aero_state_weight_flat_specified
Flat weighting by specified weight classes.
Definition: aero_state.F90:53
pmc_nucleate
Aerosol nucleation functions.
Definition: nucleate.F90:9
pmc_spec_file::spec_file_read_integer
subroutine spec_file_read_integer(file, name, var)
Read an integer from a spec file that must have the given name.
Definition: spec_file.F90:541
pmc_aero_data::pmc_mpi_unpack_aero_data
subroutine pmc_mpi_unpack_aero_data(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: aero_data.F90:632
pmc_output::input_state
subroutine input_state(filename, index, time, del_t, i_repeat, uuid, aero_data, aero_state, gas_data, gas_state, env_state)
Read the current state.
Definition: output.F90:498
pmc_mpi::pmc_mpi_pack_size_real
integer function pmc_mpi_pack_size_real(val)
Determines the number of bytes required to pack the given value.
Definition: mpi.F90:385
pmc_spec_file::spec_file_close
subroutine spec_file_close(file)
Close a spec file.
Definition: spec_file.F90:135
pmc_ice_nucleation::immersion_freezing_scheme_singular
integer, parameter immersion_freezing_scheme_singular
Type code for the singular (INAS) immersion freezing scheme.
Definition: ice_nucleation.F90:25
pmc_mosaic::mosaic_init
subroutine mosaic_init(env_state, aero_data, del_t, do_optical)
Initialize all MOSAIC data-structures.
Definition: mosaic.F90:39
pmc_util::integer_to_string_max_len
character(len=pmc_util_convert_string_len) function integer_to_string_max_len(val, max_len)
Convert an integer to a string format of maximum length.
Definition: util.F90:853
pmc_scenario
The scenario_t structure and associated subroutines.
Definition: scenario.F90:9
pmc_scenario::scenario_t
Scenario data.
Definition: scenario.F90:54
pmc_gas_data
The gas_data_t structure and associated subroutines.
Definition: gas_data.F90:9
pmc_env_state::pmc_mpi_unpack_env_state
subroutine pmc_mpi_unpack_env_state(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: env_state.F90:468
pmc_ice_nucleation::ice_nucleation_immersion_freezing
subroutine ice_nucleation_immersion_freezing(aero_state, aero_data, env_state, del_t, immersion_freezing_scheme_type, freezing_rate, do_freezing_naive, INAS_a, INAS_b)
Main subroutine for immersion freezing simulation.
Definition: ice_nucleation.F90:37
pmc_run_part::run_part
subroutine run_part(scenario, env_state, aero_data, aero_state, gas_data, gas_state, run_part_opt)
Do a particle-resolved Monte Carlo simulation.
Definition: run_part.F90:141
pmc_scenario::pmc_mpi_pack_scenario
subroutine pmc_mpi_pack_scenario(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: scenario.F90:1063
pmc_coagulation_dist::mc_coag_dist
subroutine mc_coag_dist(coag_kernel_type, env_state, aero_data, aero_state, del_t, tot_n_samp, tot_n_coag)
Do coagulation for time del_t.
Definition: coagulation_dist.F90:106
pmc_util::die_msg
subroutine die_msg(code, error_msg)
Error immediately.
Definition: util.F90:135
pmc_mpi::pmc_mpi_rank
integer function pmc_mpi_rank()
Returns the rank of the current process.
Definition: mpi.F90:117
pmc_mpi::pmc_mpi_pack_logical
subroutine pmc_mpi_pack_logical(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: mpi.F90:813
pmc_env_state::env_state_mix
subroutine env_state_mix(val)
Average val over all processes.
Definition: env_state.F90:339
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_condense
Water condensation onto aerosol particles.
Definition: condense.F90:29
pmc_mpi::pmc_mpi_pack_string
subroutine pmc_mpi_pack_string(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: mpi.F90:786
pmc_run_part::run_part_opt_t
Options controlling the execution of run_part().
Definition: run_part.F90:50
pmc_output::output_state
subroutine output_state(prefix, output_type, aero_data, aero_state, gas_data, gas_state, env_state, index, time, del_t, i_repeat, record_removals, record_optical, uuid)
Write the current state.
Definition: output.F90:112
pmc_aero_state::aero_state_total_particles_all_procs
integer function aero_state_total_particles_all_procs(aero_state, i_group, i_class)
Returns the total number of particles across all processes.
Definition: aero_state.F90:327
pmc_run_part::run_part_timestep
subroutine run_part_timestep(scenario, env_state, aero_data, aero_state, gas_data, gas_state, run_part_opt, i_time, t_start, last_output_time, last_progress_time, i_output, progress_n_samp, progress_n_coag, progress_n_emit, progress_n_dil_in, progress_n_dil_out, progress_n_nuc)
Do a one particle-resolved Monte Carlo simulation timestep.
Definition: run_part.F90:824
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:584
pmc_gas_data::pmc_mpi_pack_gas_data
subroutine pmc_mpi_pack_gas_data(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: gas_data.F90:276
pmc_scenario::pmc_mpi_unpack_scenario
subroutine pmc_mpi_unpack_scenario(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: scenario.F90:1122
pmc_env_state::env_state_t
Current environment state.
Definition: env_state.F90:29
pmc_mpi::pmc_mpi_pack_real
subroutine pmc_mpi_pack_real(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: mpi.F90:761
pmc_util::assert
subroutine assert(code, condition_ok)
Errors unless condition_ok is true.
Definition: util.F90:104
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:209
pmc_scenario::scenario_update_aero_state
subroutine scenario_update_aero_state(scenario, delta_t, env_state, old_env_state, aero_data, aero_state, n_emit, n_dil_in, n_dil_out, allow_doubling, allow_halving)
Do emissions and background dilution for a particle aerosol distribution.
Definition: scenario.F90:262
pmc_aero_state
The aero_state_t structure and assocated subroutines.
Definition: aero_state.F90:9
pmc_mpi::pmc_mpi_unpack_string
subroutine pmc_mpi_unpack_string(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: mpi.F90:1214
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:134
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_mpi::pmc_mpi_pack_size_logical
integer function pmc_mpi_pack_size_logical(val)
Determines the number of bytes required to pack the given value.
Definition: mpi.F90:427
pmc_mosaic
Interface to the MOSAIC aerosol and gas phase chemistry code.
Definition: mosaic.F90:9
pmc_spec_file::spec_file_t
An input file with extra data for printing messages.
Definition: spec_file.F90:59
pmc_gas_state
The gas_state_t structure and associated subroutines.
Definition: gas_state.F90:9
pmc_condense::condense_particles
subroutine condense_particles(aero_state, aero_data, env_state_initial, env_state_final, del_t)
Do condensation to all the particles for a given time interval, including updating the environment to...
Definition: condense.F90:149
pmc_mpi::pmc_mpi_bcast_integer
subroutine pmc_mpi_bcast_integer(val)
Broadcast the given value from process 0 to all other processes.
Definition: mpi.F90:288
pmc_gas_state::pmc_mpi_unpack_gas_state
subroutine pmc_mpi_unpack_gas_state(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: gas_state.F90:547
pmc_env_state::pmc_mpi_pack_env_state
subroutine pmc_mpi_pack_env_state(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: env_state.F90:421
pmc_run_part::parallel_coag_type_invalid
integer, parameter parallel_coag_type_invalid
Type code for undefined or invalid parallel coagulation method.
Definition: run_part.F90:43
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:563
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::integer_to_string
character(len=pmc_util_convert_string_len) function integer_to_string(val)
Convert an integer to a string format.
Definition: util.F90:767
pmc_coagulation
Aerosol particle coagulation.
Definition: coagulation.F90:11
pmc_util::assert_msg
subroutine assert_msg(code, condition_ok, error_msg)
Errors unless condition_ok is true.
Definition: util.F90:78
pmc_output::output_type_single
integer, parameter output_type_single
Type code for single output (one file for all processes, written by process 0).
Definition: output.F90:97
pmc_run_part::pmc_mpi_broadcast_run_part
subroutine pmc_mpi_broadcast_run_part(run_part_opt, aero_data, aero_state_init, gas_data, gas_state_init, env_state_init, aero_dist_init, scenario, n_part, rand_init, do_init_equilibrate, do_restart)
Read the specification for a run_part simulation from a spec file.
Definition: run_part.F90:1129
pmc_aero_state::aero_state_total_particles
integer function aero_state_total_particles(aero_state, i_group, i_class)
Returns the total number of particles in an aerosol distribution.
Definition: aero_state.F90:288
pmc_run_part::parallel_coag_type_dist
integer, parameter parallel_coag_type_dist
Type code for distributed parallel coagulation.
Definition: run_part.F90:47
pmc_nucleate::nucleate
subroutine nucleate(nucleate_type, nucleate_source, nucleate_weight_class, env_state, gas_data, aero_data, aero_state, gas_state, del_t, allow_doubling, allow_halving)
Do nucleation of the type given by the first argument.
Definition: nucleate.F90:34
pmc_ice_nucleation::immersion_freezing_scheme_const
integer, parameter immersion_freezing_scheme_const
Type code for constant ice nucleation rate (J_het) immersion freezing scheme.
Definition: ice_nucleation.F90:23
pmc_spec_file::spec_file_open
subroutine spec_file_open(filename, file)
Open a spec file for reading.
Definition: spec_file.F90:112
pmc_scenario::pmc_mpi_pack_size_scenario
integer function pmc_mpi_pack_size_scenario(val)
Determines the number of bytes required to pack the given value.
Definition: scenario.F90:1007
pmc_mosaic::mosaic_cleanup
subroutine mosaic_cleanup()
Clean-up after running MOSAIC, deallocating memory.
Definition: mosaic.F90:131
pmc_photolysis
The photolysis_t type and related functions.
Definition: photolysis.F90:9
pmc_mosaic::mosaic_optical_wavelengths
subroutine mosaic_optical_wavelengths(aero_data)
Fetch the wavelengths that optical cross-sections are calculated at in MOSAIC. If not using multiple ...
Definition: mosaic.F90:679
pmc_run_part
Monte Carlo simulation.
Definition: run_part.F90:9
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_coagulation::mc_coag
subroutine mc_coag(coag_kernel_type, env_state, aero_data, aero_state, del_t, tot_n_samp, tot_n_coag)
Do coagulation for time del_t.
Definition: coagulation.F90:45
pmc_mpi::pmc_mpi_bcast_packed
subroutine pmc_mpi_bcast_packed(val)
Broadcast the given value from process 0 to all other processes.
Definition: mpi.F90:326
pmc_tchem_interface
An interface between PartMC and TChem.
Definition: tchem_interface.F90:9
pmc_aero_data::aero_data_t
Aerosol material properties and associated data.
Definition: aero_data.F90:55
pmc_mpi::pmc_mpi_unpack_integer
subroutine pmc_mpi_unpack_integer(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: mpi.F90:1139
pmc_mpi::pmc_mpi_unpack_logical
subroutine pmc_mpi_unpack_logical(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: mpi.F90:1242
pmc_output
Write data in NetCDF format.
Definition: output.F90:68
pmc_constants
Physical constants.
Definition: constants.F90:9
pmc_aero_state::pmc_mpi_unpack_aero_state
subroutine pmc_mpi_unpack_aero_state(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: aero_state.F90:2418
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_run_part::run_part_timeblock
subroutine run_part_timeblock(scenario, env_state, aero_data, aero_state, gas_data, gas_state, run_part_opt, i_cur, i_next, t_start, last_output_time, last_progress_time, i_output, progress_n_samp, progress_n_coag, progress_n_emit, progress_n_dil_in, progress_n_dil_out, progress_n_nuc)
Do a number of time steps of particle-reoslved Monte Carlo simulation.
Definition: run_part.F90:1058
pmc_aero_state::pmc_mpi_pack_aero_state
subroutine pmc_mpi_pack_aero_state(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: aero_state.F90:2392
pmc_run_part::spec_file_read_run_part
subroutine spec_file_read_run_part(file, run_part_opt, aero_data, aero_state_init, gas_data, gas_state_init, env_state_init, aero_dist_init, scenario, n_part, rand_init, do_init_equilibrate, do_restart)
Read the specification for a run_part simulation from a spec file.
Definition: run_part.F90:494
pmc_gas_data::pmc_mpi_pack_size_gas_data
integer function pmc_mpi_pack_size_gas_data(val)
Determines the number of bytes required to pack the given value.
Definition: gas_data.F90:262
pmc_aero_state::pmc_mpi_pack_size_aero_state
integer function pmc_mpi_pack_size_aero_state(val)
Determines the number of bytes required to pack the given value.
Definition: aero_state.F90:2373
pmc_util
Common utility subroutines.
Definition: util.F90:9
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_aero_state::aero_state_rebalance
subroutine aero_state_rebalance(aero_state, aero_data, allow_doubling, allow_halving, initial_state_warning)
Double or halve the particle population in each weight group to maintain close to n_part_ideal partic...
Definition: aero_state.F90:1794
pmc_gas_state::pmc_mpi_pack_gas_state
subroutine pmc_mpi_pack_gas_state(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: gas_state.F90:524
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_gas_data::pmc_mpi_unpack_gas_data
subroutine pmc_mpi_unpack_gas_data(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: gas_data.F90:300
pmc_run_part::pmc_mpi_unpack_run_part_opt
subroutine pmc_mpi_unpack_run_part_opt(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: run_part.F90:428
pmc_camp_interface
An interface between PartMC and the CAMP.
Definition: camp_interface.F90:9
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:605
pmc_aero_state::aero_state_mix
subroutine aero_state_mix(aero_state, del_t, mix_timescale, aero_data, specify_prob_transfer)
Mix the aero_states between all processes. Currently uses a simple all-to-all diffusion.
Definition: aero_state.F90:1930
pmc_mosaic::mosaic_aero_optical_init
subroutine mosaic_aero_optical_init(env_state, aero_data, aero_state, gas_data, gas_state)
Compute the optical properties of each aerosol particle for initial timestep.
Definition: mosaic.F90:564
pmc_mpi::pmc_mpi_pack_size_integer
integer function pmc_mpi_pack_size_integer(val)
Determines the number of bytes required to pack the given value.
Definition: mpi.F90:345
pmc_mosaic::mosaic_timestep
subroutine mosaic_timestep(env_state, aero_data, aero_state, gas_data, gas_state, do_optical, uuid)
Do one timestep with MOSAIC.
Definition: mosaic.F90:413
pmc_mpi::pmc_mpi_pack_integer
subroutine pmc_mpi_pack_integer(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: mpi.F90:711
pmc_run_part::print_part_progress
subroutine print_part_progress(i_repeat, t_sim_elapsed, n_part, n_coag, n_emit, n_dil_in, n_dil_out, n_nuc, t_wall_elapsed, t_wall_remain)
Print the current simulation progress to the screen.
Definition: run_part.F90:272
pmc_aero_data
The aero_data_t structure and associated subroutines.
Definition: aero_data.F90:9
pmc_mpi::pmc_mpi_reduce_sum_integer
subroutine pmc_mpi_reduce_sum_integer(val, val_sum)
Computes the sum of val across all processes, storing the result in val_sum on the root process.
Definition: mpi.F90:1663
pmc_aero_data::pmc_mpi_pack_size_aero_data
integer function pmc_mpi_pack_size_aero_data(val)
Determines the number of bytes required to pack the given value.
Definition: aero_data.F90:572
pmc_env_state::pmc_mpi_pack_size_env_state
integer function pmc_mpi_pack_size_env_state(val)
Determines the number of bytes required to pack the given value.
Definition: env_state.F90:384
pmc_mpi::pmc_mpi_unpack_real
subroutine pmc_mpi_unpack_real(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: mpi.F90:1189
pmc_run_part::pmc_mpi_pack_size_run_part_opt
integer function pmc_mpi_pack_size_run_part_opt(val)
Determines the number of bytes required to pack the given value.
Definition: run_part.F90:316
pmc_gas_state::pmc_mpi_pack_size_gas_state
integer function pmc_mpi_pack_size_gas_state(val)
Determines the number of bytes required to pack the given value.
Definition: gas_state.F90:511
pmc_nucleate::nucleate_type_invalid
integer, parameter nucleate_type_invalid
Type code for unknown or invalid nucleation type.
Definition: nucleate.F90:18
pmc_ice_nucleation::ice_nucleation_melting
subroutine ice_nucleation_melting(aero_state, aero_data, env_state)
Simulates melting: if the environmental temperature is above the freezing temperature of water,...
Definition: ice_nucleation.F90:359
pmc_aero_state::aero_state_t
The current collection of aerosol particles.
Definition: aero_state.F90:69
pmc_coagulation_dist
Parallel aerosol particle coagulation with MPI.
Definition: coagulation_dist.F90:9
pmc_mosaic::mosaic_support
logical function mosaic_support()
Whether MOSAIC support is compiled in.
Definition: mosaic.F90:26
pmc_mpi::pmc_mpi_pack_size_string
integer function pmc_mpi_pack_size_string(val)
Determines the number of bytes required to pack the given value.
Definition: mpi.F90:405
pmc_aero_data::pmc_mpi_pack_aero_data
subroutine pmc_mpi_pack_aero_data(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: aero_data.F90:597
pmc_ice_nucleation
Definition: ice_nucleation.F90:8