PartMC  2.6.1
partmc.F90
Go to the documentation of this file.
1 ! Copyright (C) 2007-2012, 2016, 2017, 2018, 2021 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 partmc program.
7 
8 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
9 
10 !> \mainpage PartMC Code Documentation
11 !!
12 !! \subpage input_format - Input file format description.
13 !!
14 !! \subpage output_format - Output file format description.
15 !!
16 !! \subpage module_diagram - Diagram of modules and dependencies.
17 !!
18 !! \subpage coding_style - Description of code conventions and style.
19 !!
20 !! \subpage publications - Publications about PartMC.
21 
22 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
23 
24 !> \page input_format Input File Format
25 !!
26 !! The input file format is plain text:
27 !!
28 !! \subpage spec_file_format "Spec File Format"
29 !!
30 !! When running PartMC with the command <tt>partmc input.spec</tt> the
31 !! first line of the <tt>input.spec</tt> file must define the \c
32 !! run_type with:
33 !! <pre>
34 !! run_type &lt;type&gt;
35 !! </pre>
36 !! where <tt>&lt;type&gt;</tt> is one of \c particle, \c exact, or \c
37 !! sectional. This determines the type of run as well as the format of the
38 !! remainder of the spec file. The rest of the spec file is described by:
39 !!
40 !! \subpage input_format_particle "Particle-resolved simulation"
41 !!
42 !! \subpage input_format_exact "Exact (analytical) solution"
43 !!
44 !! \subpage input_format_sectional "Sectional model simulation"
45 
46 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
47 
48 !> \page module_diagram Module Diagram
49 !!
50 !! \dotfile partmc_modules.gv
51 
52 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
53 
54 !> \page coding_style Coding Style
55 !!
56 !! The code is mainly modern Fortran, with a few parts still clearly
57 !! showing their Fortran 77 heritage. Fortran 2003 features are used
58 !! heavily (especially allocatable array features). The code needs to
59 !! be processed with \c cpp or a compatible pre-processor.
60 !!
61 !! \section oo_fortran Object Oriented Fortran
62 !!
63 !! Extensive use is made of Fortran 90 derived types. Derived types
64 !! are named \c my_type_t and are generally defined in modules named
65 !! \c pmc_my_type within files named \c my_type.F90. Almost all
66 !! subroutines and function in each \c my_type.F90 file have names of
67 !! the form \c my_type_*() and take an object of type \c my_type_t
68 !! (called \c my_type) as the first argument on which to operate.
69 !!
70 !! Module names are always the same as the name of the containing
71 !! file, but prefixed with \c pmc_. Thus the module \c
72 !! pmc_condense is contained in the file \c condense.F90.
73 !!
74 !! \section mem_manage Memory Management
75 !!
76 !! The memory allocation policy is to always use \c allocatable
77 !! arrays and to do the allocation in the lowest-level routine
78 !! possible. Explicit \c allocate() and \c deallocate() statements are
79 !! discouraged in favor of automatic memory management, where
80 !! possible.
81 
82 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
83 
84 !> \page publications PartMC Publications
85 !!
86 !! - Z.&nbsp;Zheng, J.&nbsp;H. Curtis, Y. Yao, J.&nbsp;T. Gasparik,
87 !! V.&nbsp;G. Anantharaj, L. Zhao, M. West, and N. Riemer (2021)
88 !! Estimating submicron aerosol mixing state at the global scale
89 !! with machine learning and earth system modeling, <i>Earth and
90 !! Space Science</i> <b>8</b>(2), e2020EA001500, DOI: <a
91 !! href="http://dx.doi.org/10.1029/2020EA001500">10.1029/2020EA001500</a>.
92 !! - J.&nbsp;T. Gasparik, Q. Ye, J.&nbsp;H. Curtis,
93 !! A.&nbsp;A. Presto, N.&nbsp;M. Donahue, R.&nbsp;C. Sullivan,
94 !! M. West, and N. Riemer (2020) Quantifying errors in the aerosol
95 !! mixing-state index based on limited particle sample size,
96 !! <i>Aerosol Science and Technology</i> <b>54</b>(12), 1527-1541,
97 !! DOI: <a
98 !! href="http://dx.doi.org/10.1080/02786826.2020.1804523">10.1080/02786826.2020.1804523</a>.
99 !! - C. Shou, N. Riemer, T.&nbsp;B. Onasch, A.&nbsp;J. Sedlacek,
100 !! A.&nbsp;T. Lambe, E.&nbsp;R. Lewis, P. Davidovits, and M. West
101 !! (2019) Mixing state evolution of agglomerating particles in an
102 !! aerosol chamber: Comparison of measurements and
103 !! particle-resolved simulations, <i>Aerosol Science and
104 !! Technology</i> <b>53</b>(11), 1229-1243, DOI: <a
105 !! href="http://dx.doi.org/10.1080/02786826.2019.1661959">10.1080/02786826.2019.1661959</a>
106 !! - N. Riemer, A.&nbsp;P. Ault, M. West, R.&nbsp;L. Craig, and
107 !! J.&nbsp;H. Curtis (2019) Aerosol mixing state: Measurements,
108 !! modeling, and impacts, <i>Reviews of Geophysics</i>
109 !! <b>57</b>(2), 187-249, DOI: <a
110 !! href="http://dx.doi.org/10.1029/2018RG000615">10.1029/2018RG000615</a>
111 !! - R.&nbsp;E.&nbsp;L. DeVille, N. Riemer, and M. West (2019)
112 !! Convergence of a generalized Weighted Flow Algorithm for
113 !! stochastic particle coagulation, <i>Journal of Computational
114 !! Dynamics</i> <b>6</b>(1), 69-94, DOI: <a
115 !! href="http://dx.doi.org/10.3934/jcd.2019003">10.3934/jcd.2019003</a>
116 !! - M.&nbsp;Hughes, J.&nbsp;K.&nbsp;Kodros, J.&nbsp;R.&nbsp;Pierce,
117 !! M.&nbsp;West, and N.&nbsp;Riemer (2018) Machine learning to
118 !! predict the global distribution of aerosol mixing state
119 !! metrics, <i>Atmosphere</i> <b>9</b>(1), 15, DOI: <a
120 !! href="http://dx.doi.org/10.3390/atmos9010015">10.3390/atmos9010015</a>.
121 !! - J.&nbsp;Ching, M.&nbsp;West, and N.&nbsp;Riemer (2018)
122 !! Quantifying impacts of aerosol mixing state on
123 !! nucleation-scavenging of black carbon aerosol particles,
124 !! <i>Atmosphere</i> <b>9</b>(1), 17, DOI: <a
125 !! href="http://dx.doi.org/10.3390/atmos9010017">10.3390/atmos9010017</a>.
126 !! - J.&nbsp;H.&nbsp;Curtis, N.&nbsp;Riemer, and M.&nbsp;West,
127 !! (2017) A single-column particle-resolved model for simulating
128 !! the vertical distribution of aerosol mixing state:
129 !! WRF-PartMC-MOSAIC-SCM v1.0, <i>Geoscientific Model
130 !! Development</i> <b>10</b>, 4057-4079, DOI: <a
131 !! href="http://dx.doi.org/10.5194/gmd-10-4057-2017">10.5194/gmd-10-4057-2017</a>.
132 !! - J.&nbsp;Tian, B.&nbsp;T.&nbsp;Brem, M.&nbsp;West,
133 !! T.&nbsp;C.&nbsp;Bond, M.&nbsp;J.&nbsp;Rood, and N.&nbsp;Riemer
134 !! (2017) Simulating aerosol chamber experiments with the
135 !! particle-resolved aerosol model PartMC, <i>Aerosol Science and
136 !! Technology</i> <b>51</b>(7), 856-867, DOI: <a
137 !! href="http://dx.doi.org/10.1080/02786826.2017.1311988">10.1080/02786826.2017.1311988</a>.
138 !! - J.&nbsp;Ching, J.&nbsp;Fast, M.&nbsp;West, and N.&nbsp;Riemer
139 !! (2017) Metrics to quantify the importance of mixing state for
140 !! CCN activity, <i>Atmospheric Chemistry and Physics</i>
141 !! <b>17</b>, 7445-7458, DOI: <a
142 !! href="http://dx.doi.org/10.5194/acp-17-7445-2017">10.5194/acp-17-7445-2017</a>.
143 !! - J.&nbsp;Ching, N.&nbsp;Riemer, and M.&nbsp;West (2016) Black
144 !! carbon mixing state impacts on cloud microphysical properties:
145 !! Effects of aerosol plume and environmental conditions,
146 !! <i>Journal of Geophysical Research</i> <b>121</b>(10),
147 !! 5990-6013, DOI: <a
148 !! href="http://dx.doi.org/10.1002/2016JD024851">10.1002/2016JD024851</a>.
149 !! - J.&nbsp;H.&nbsp;Curtis, M.&nbsp;D.&nbsp;Michelotti,
150 !! N.&nbsp;Riemer, M.&nbsp;Heath, and M.&nbsp;West (2016)
151 !! Accelerated simulation of stochastic particle removal processes
152 !! in particle-resolved aerosol models, <i>Journal of
153 !! Computational Physics</i> <b>322</b>, 21-32, DOI: <a
154 !! href="http://dx.doi.org/10.1016/j.jcp.2016.06.029">10.1016/j.jcp.2016.06.029</a>.
155 !! - R.&nbsp;M.&nbsp;Healy, N.&nbsp;Riemer, J.&nbsp;C.&nbsp;Wenger,
156 !! M.&nbsp;Murphy, M.&nbsp;West, L.&nbsp;Poulain,
157 !! A.&nbsp;Wiedensohler, I.&nbsp;P.&nbsp;O'Connor,
158 !! E.&nbsp;McGillicuddy, J.&nbsp;R.&nbsp;Sodeau, and
159 !! G.&nbsp;J.&nbsp;Evans, Single particle diversity and mixing
160 !! state measurements, <i>Atmospheric Chemistry and Physics</i>
161 !! <b>14</b>, 6289-6299, DOI: <a
162 !! href="http://dx.doi.org/10.5194/acp-14-6289-2014">10.5194/acp-14-6289-2014</a>.
163 !! - J.&nbsp;Tian, N.&nbsp;Riemer, M.&nbsp;West,
164 !! L.&nbsp;Pfaffenberger, H.&nbsp;Schlager, and A.&nbsp;Petzold
165 !! (2014) Modeling the evolution of aerosol particles in a ship
166 !! plume using PartMC-MOSAIC, <i>Atmospheric Chemistry and
167 !! Physics</i> <b>14</b>, 5327-5347, DOI: <a
168 !! href="http://dx.doi.org/10.5194/acp-14-5327-2014">10.5194/acp-14-5327-2014</a>.
169 !! - N.&nbsp;Riemer and M.&nbsp;West (2013) Quantifying aerosol mixing
170 !! state with entropy and diversity measures, <i>Atmospheric
171 !! Chemistry and Physics</i> <b>13</b>, 11423-11439, DOI: <a
172 !! href="http://dx.doi.org/10.5194/acp-13-11423-2013">10.5194/acp-13-11423-2013</a>.
173 !! - M.&nbsp;D.&nbsp;Michelotti, M.&nbsp;T.&nbsp;Heath, and
174 !! M.&nbsp;West (2013) Binning for efficient stochastic multiscale
175 !! particle simulations, <i>Atmospheric Chemistry and Physics</i>
176 !! <b>11</b>(4), 1071-1096, DOI: <a
177 !! href="http://dx.doi.org/10.1137/130908038">10.1137/130908038</a>.
178 !! - J.&nbsp;Ching, N.&nbsp;Riemer, and M.&nbsp;West (2012) Impacts of
179 !! black carbon mixing state on black carbon nucleation scavenging:
180 !! Insights from a particle-resolved model, <i>Journal of
181 !! Geophysical Research</i> <b>117</b>(D23209), DOI: <a
182 !! href="http://dx.doi.org/10.1029/2012JD018269">10.1029/2012JD018269</a>.
183 !! - R.&nbsp;E.&nbsp;L.&nbsp;DeVille, N.&nbsp;Riemer, and
184 !! M.&nbsp;West (2011) Weighted Flow Algorithms (WFA) for
185 !! stochastic particle coagulation, <i>Journal of Computational
186 !! Physics</i> <b>230</b>(23), 8427-8451, DOI: <a
187 !! href="http://dx.doi.org/10.1016/j.jcp.2011.07.027">10.1016/j.jcp.2011.07.027</a>.
188 !! - R.&nbsp;A.&nbsp;Zaveri, J.&nbsp;C.&nbsp;Barnard,
189 !! R.&nbsp;C.&nbsp;Easter, N.&nbsp;Riemer, and M.&nbsp;West (2010)
190 !! Particle-resolved simulation of aerosol size, composition,
191 !! mixing state, and the associated optical and cloud condensation
192 !! nuclei activation properties in an evolving urban plume,
193 !! <i>Journal of Geophysical Research</i> <b>115</b>(D17210), DOI: <a
194 !! href="http://dx.doi.org/10.1029/2009JD013616">10.1029/2009JD013616</a>.
195 !! - N.&nbsp;Riemer, M.&nbsp;West, R.&nbsp;A.&nbsp;Zaveri, and
196 !! R.&nbsp;C.&nbsp;Easter (2010) Estimating black carbon aging
197 !! time-scales with a particle-resolved aerosol model, <i>Journal
198 !! of Aerosol Science</i> <b>41</b>(1), 143-158, DOI: <a
199 !! href="http://dx.doi.org/10.1016/j.jaerosci.2009.08.009">10.1016/j.jaerosci.2009.08.009</a>
200 !! - N.&nbsp;Riemer, M.&nbsp;West, R.&nbsp;A.&nbsp;Zaveri, and
201 !! R.&nbsp;C.&nbsp;Easter (2009) Simulating the evolution of soot
202 !! mixing state with a particle-resolved aerosol model, <i>Journal
203 !! of Geophysical Research</i> <b>114</b>(D09202), DOI: <a
204 !! href="http://dx.doi.org/10.1029/2008JD011073">10.1029/2008JD011073</a>
205 !! - R.&nbsp;McGraw, L.&nbsp;Leng, W.&nbsp;Zhu, N.&nbsp;Riemer, and
206 !! M.&nbsp;West (2008) Aerosol dynamics using the quadrature
207 !! method of moments: Comparing several quadrature schemes with
208 !! particle-resolved simulation, <i>Journal of Physics: Conference
209 !! Series</i> <b>125</b>(012020), DOI: <a
210 !! href="http://dx.doi.org/10.1088/1742-6596/125/1/012020">10.1088/1742-6596/125/1/012020</a>
211 
212 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
213 
214 !> Top level driver.
215 program partmc
216 
217  use pmc_mpi
218  use pmc_bin_grid
219  use pmc_aero_state
220  use pmc_aero_dist
221  use pmc_aero_binned
222  use pmc_coag_kernel
223  use pmc_aero_data
224  use pmc_scenario
225  use pmc_env_state
226  use pmc_run_part
227  use pmc_run_exact
228  use pmc_run_sect
229  use pmc_spec_file
230  use pmc_gas_data
231  use pmc_gas_state
232  use pmc_util
233 #ifdef PMC_USE_CAMP
234  use camp_camp_core
235  use pmc_photolysis
236 #endif
237 #ifdef PMC_USE_SUNDIALS
238  use pmc_condense
239 #endif
240 
241  character(len=300) :: spec_name
242 
243  call pmc_mpi_init()
244 
245  if (pmc_mpi_rank() == 0) then
246  ! only the root process accesses the commandline
247 
248  if (command_argument_count() /= 1) then
249  call print_usage()
250  call die_msg(739173192, "invalid commandline arguments")
251  end if
252 
253  call get_command_argument(1, spec_name)
254  end if
255 
256  call pmc_mpi_bcast_string(spec_name)
257  call partmc_run(spec_name)
258 
259  call pmc_mpi_finalize()
260 
261 contains
262 
263 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
264 
265  !> Print the usage text to stderr.
266  subroutine print_usage()
267 
268  write(*,*) 'Usage: partmc <spec-file>'
269 
270  end subroutine print_usage
271 
272 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
273 
274  !> Do a PartMC run.
275  subroutine partmc_run(spec_name)
276 
277  !> Spec filename.
278  character(len=*), intent(in) :: spec_name
279 
280  type(spec_file_t) :: file
281  character(len=100) :: run_type
282  integer :: i
283 
284  ! check filename (must be "filename.spec")
285  i = len_trim(spec_name)
286  if (spec_name((i-4):i) /= '.spec') then
287  call die_msg(710381938, "input filename must end in .spec")
288  end if
289 
290  if (pmc_mpi_rank() == 0) then
291  ! only the root process does I/O
292  call spec_file_open(spec_name, file)
293  call spec_file_read_string(file, 'run_type', run_type)
294  end if
295 
296  call pmc_mpi_bcast_string(run_type)
297  if (trim(run_type) == 'particle') then
298  call partmc_part(file)
299  elseif (trim(run_type) == 'exact') then
300  call partmc_exact(file)
301  elseif (trim(run_type) == 'sectional') then
302  call partmc_sect(file)
303  else
304  call die_msg(719261940, "unknown run_type: " // trim(run_type))
305  end if
306 
307  end subroutine partmc_run
308 
309 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
310 
311  !> Run a Monte Carlo simulation.
312  subroutine partmc_part(file)
313 
314  !> Spec file.
315  type(spec_file_t), intent(inout) :: file
316 
317  type(gas_data_t) :: gas_data
318  type(gas_state_t) :: gas_state
319  type(gas_state_t) :: gas_state_init
320  type(aero_data_t) :: aero_data
321  type(aero_dist_t) :: aero_dist_init
322  type(aero_state_t) :: aero_state
323  type(aero_state_t) :: aero_state_init
324  type(scenario_t) :: scenario
325  type(env_state_t) :: env_state
326  type(env_state_t) :: env_state_init
327  type(run_part_opt_t) :: run_part_opt
328 #ifdef PMC_USE_CAMP
329  type(camp_core_t), pointer :: camp_core
330  type(photolysis_t), pointer :: photolysis
331 #endif
332  integer :: i_repeat, i_group
333  integer :: rand_init
334  character, allocatable :: buffer(:)
335  integer :: buffer_size, max_buffer_size
336  integer :: position
337  logical :: do_restart, do_init_equilibrate, aero_mode_type_exp_present
338  character(len=PMC_MAX_FILENAME_LEN) :: restart_filename
339  integer :: dummy_index, dummy_i_repeat
340  real(kind=dp) :: dummy_time, dummy_del_t, n_part
341  character(len=PMC_MAX_FILENAME_LEN) :: sub_filename
342  type(spec_file_t) :: sub_file
343  character(len=PMC_MAX_FILENAME_LEN) :: camp_config_filename
344 
345  !> \page input_format_particle Input File Format: Particle-Resolved Simulation
346  !!
347  !! See \ref spec_file_format for the input file text format.
348  !!
349  !! A particle-resolved simulation spec file has the parameters:
350  !! - \b run_type (string): must be \c particle
351  !! - \b output_prefix (string): prefix of the output filenames
352  !! --- see \ref output_format for the full name format
353  !! - \b n_repeat (integer): number of repeats
354  !! - \b n_part (integer): number of computational particles to
355  !! simulate (actual number used will vary between <tt>n_part /
356  !! 2</tt> and <tt>n_part * 2</tt> if \c allow_doubling and \c
357  !! allow_halving are \c yes)
358  !! - \b restart (logical): whether to restart the simulation from
359  !! a saved output data file. If \c restart is \c yes, then the
360  !! following parameters must also be provided:
361  !! - \b restart_file (string): name of file from which to load
362  !! restart data, which must be a PartMC output NetCDF file
363  !! - \b t_max (real, unit s): total simulation time
364  !! - \b del_t (real, unit s): timestep size
365  !! - \b t_output (real, unit s): the interval on which to
366  !! output data to disk (see \ref output_format)
367  !! - \b t_progress (real, unit s): the interval on which to
368  !! write summary information to the screen while running
369  !! - \b do_camp_chem (logical): whether to run <b>CAMP</b>.
370  !! If \c do_camp_chem is \c yes, then the following parameters
371  !! must also be provided:
372  !! - \b camp_config (string): name of JSON file containing a list of \b
373  !! CAMP configuration files.
374  !! - \b gas_data (string): name of file from which to read the gas
375  !! material data (only provide if \c restart is \c no) --- the
376  !! file format should be \subpage input_format_gas_data
377  !! - \b gas_init (string): name of file from which to read the
378  !! initial gas state at the start of the simulation (only
379  !! provide option if \c restart is \c no) --- the file format
380  !! should be \subpage input_format_gas_state
381  !! - \b aerosol_data (string): name of file from which to read the
382  !! aerosol material data (only provide if \c restart is \c no)
383  !! --- the file format should be \subpage input_format_aero_data
384  !! - \b do_fractal (logical): whether to consider particles
385  !! as fractal agglomerates. If \c do_fractal is \c no, then all the
386  !! particles are treated as spherical. If \c do_fractal is \c yes,
387  !! then the following parameters must also be provided:
388  !! - \subpage input_format_fractal
389  !! - \b aerosol_init (string): filename containing the initial
390  !! aerosol state at the start of the simulation (only provide
391  !! option if \c restart is \c no) --- the file format should
392  !! be \subpage input_format_aero_dist
393  !! - \subpage input_format_scenario
394  !! - \subpage input_format_env_state
395  !! - \b do_coagulation (logical): whether to perform particle
396  !! coagulation. If \c do_coagulation is \c yes, then the
397  !! following parameters must also be provided:
398  !! - \subpage input_format_coag_kernel
399  !! - \b do_condensation (logical): whether to perform explicit
400  !! water condensation (requires SUNDIALS support to be compiled
401  !! in; cannot be used simultaneously with MOSAIC). If \c
402  !! do_condensation is \c yes, then the following parameters must
403  !! also be provided:
404  !! - \b do_init_equilibrate (logical): whether to equilibrate
405  !! the water content of each particle before starting the
406  !! simulation, note that \b do_init_equilibriate (sic!)
407  !! spelling will work as well for compatibility
408  !! - \b do_mosaic (logical): whether to use the MOSAIC chemistry
409  !! code (requires support to be compiled in; cannot be used
410  !! simultaneously with condensation). If \c do_mosaic is \c
411  !! yes, then the following parameters must also be provided:
412  !! - \b do_optical (logical): whether to compute optical
413  !! properties of the aerosol particles for the output files ---
414  !! see output_format_aero_state
415  !! - \b do_nucleation (logical): whether to perform particle
416  !! nucleation. If \c do_nucleation is \c yes, then the following
417  !! parameters must also be provided:
418  !! - \subpage input_format_nucleate
419  !! - \b rand_init (integer): if greater than zero then use as
420  !! the seed for the random number generator, or if zero then
421  !! generate a random seed for the random number generator ---
422  !! two simulations on the same machine with the same seed
423  !! (greater than 0) will produce identical output
424  !! - \b allow_doubling (logical): if \c yes, then whenever the
425  !! number of simulated particles falls below <tt>n_part /
426  !! 2</tt>, every particle is duplicated to give better
427  !! statistics
428  !! - \b allow_halving (logical): if \c yes, then whenever the
429  !! number of simulated particles rises above <tt>n_part *
430  !! 2</tt>, half of the particles are removed (chosen randomly)
431  !! to reduce the computational expense
432  !! - \b do_select_weighting (logical): whether to explicitly select
433  !! the weighting scheme. If \c do_select_weighting is \c yes, then the
434  !! following parameters must also be provided:
435  !! - \subpage input_format_weight_type
436  !! - \b record_removals (logical): whether to record information
437  !! about aerosol particles removed from the simulation --- see
438  !! \ref output_format_aero_removed
439  !! - \b do_parallel (logical): whether to run in parallel mode
440  !! (requires MPI support to be compiled in). If \c do_parallel
441  !! is \c yes, then the following parameters must also be
442  !! provided:
443  !! - \subpage input_format_output
444  !! - \b mix_timescale (real, unit s): timescale on which to mix
445  !! aerosol particle information amongst processes in an
446  !! attempt to keep the aerosol state consistent (the mixing
447  !! rate is inverse to \c mix_timescale)
448  !! - \b gas_average (logical): whether to average the gas state
449  !! amongst processes each timestep, to ensure uniform gas
450  !! concentrations
451  !! - \b env_average (logical): whether to average the
452  !! environment state amongst processes each timestep, to
453  !! ensure a uniform environment
454  !! - \subpage input_format_parallel_coag
455 
456  if (pmc_mpi_rank() == 0) then
457  ! only the root process does I/O
458 
459  call spec_file_read_string(file, 'output_prefix', &
460  run_part_opt%output_prefix)
461  call spec_file_read_integer(file, 'n_repeat', run_part_opt%n_repeat)
462  call spec_file_read_real(file, 'n_part', n_part)
463  call spec_file_read_logical(file, 'restart', do_restart)
464  if (do_restart) then
465  call spec_file_read_string(file, 'restart_file', restart_filename)
466  end if
467 
468  call spec_file_read_real(file, 't_max', run_part_opt%t_max)
469  call spec_file_read_real(file, 'del_t', run_part_opt%del_t)
470  call spec_file_read_real(file, 't_output', run_part_opt%t_output)
471  call spec_file_read_real(file, 't_progress', run_part_opt%t_progress)
472 
473  call spec_file_read_logical(file, 'do_camp_chem', &
474  run_part_opt%do_camp_chem)
475  if (run_part_opt%do_camp_chem) then
476 #ifdef PMC_USE_CAMP
477  call spec_file_read_string(file, 'camp_config', &
478  camp_config_filename)
479  camp_core => camp_core_t(camp_config_filename)
480  call camp_core%initialize()
481  photolysis => photolysis_t(camp_core)
482 #else
483  call spec_file_die_msg(648994111, file, &
484  'cannot do camp chem, CAMP support not compiled in')
485 #endif
486  end if
487 
488  if (do_restart) then
489  call input_state(restart_filename, dummy_index, dummy_time, &
490  dummy_del_t, dummy_i_repeat, run_part_opt%uuid, aero_data, &
491  aero_state_init, gas_data, gas_state_init, env_state_init)
492  end if
493 
494  if (.not. do_restart) then
495  env_state_init%elapsed_time = 0d0
496  if (.not. run_part_opt%do_camp_chem) then
497  call spec_file_read_string(file, 'gas_data', sub_filename)
498  call spec_file_open(sub_filename, sub_file)
499  call spec_file_read_gas_data(sub_file, gas_data)
500  call spec_file_close(sub_file)
501  else
502 #ifdef PMC_USE_CAMP
503  call gas_data_initialize(gas_data, camp_core)
504 #endif
505  end if
506  call spec_file_read_string(file, 'gas_init', sub_filename)
507  call spec_file_open(sub_filename, sub_file)
508  call spec_file_read_gas_state(sub_file, gas_data, &
509  gas_state_init)
510  call spec_file_close(sub_file)
511 
512  if (.not. run_part_opt%do_camp_chem) then
513  call spec_file_read_string(file, 'aerosol_data', sub_filename)
514  call spec_file_open(sub_filename, sub_file)
515  call spec_file_read_aero_data(sub_file, aero_data)
516  call spec_file_close(sub_file)
517  else
518 #ifdef PMC_USE_CAMP
519  call aero_data_initialize(aero_data, camp_core)
520  call aero_state_initialize(aero_state, aero_data, camp_core)
521 #endif
522  end if
523  call spec_file_read_fractal(file, aero_data%fractal)
524 
525  call spec_file_read_string(file, 'aerosol_init', sub_filename)
526  call spec_file_open(sub_filename, sub_file)
527  call spec_file_read_aero_dist(sub_file, aero_data, aero_dist_init)
528  call spec_file_close(sub_file)
529  end if
530 
531  call spec_file_read_scenario(file, gas_data, aero_data, scenario)
532  call spec_file_read_env_state(file, env_state_init)
533 
534  call spec_file_read_logical(file, 'do_coagulation', &
535  run_part_opt%do_coagulation)
536  if (run_part_opt%do_coagulation) then
537  call spec_file_read_coag_kernel_type(file, &
538  run_part_opt%coag_kernel_type)
539  else
540  run_part_opt%coag_kernel_type = coag_kernel_type_invalid
541  end if
542 
543  call spec_file_read_logical(file, 'do_condensation', &
544  run_part_opt%do_condensation)
545 #ifndef PMC_USE_SUNDIALS
546  call assert_msg(121370218, &
547  run_part_opt%do_condensation .eqv. .false., &
548  "cannot use condensation, SUNDIALS support is not compiled in")
549 #endif
550  do_init_equilibrate = .false.
551  if (run_part_opt%do_condensation) then
552  call spec_file_read_logical(file, 'do_init_equilibrate', &
553  do_init_equilibrate)
554  end if
555 
556  call spec_file_read_logical(file, 'do_mosaic', run_part_opt%do_mosaic)
557  if (run_part_opt%do_mosaic .and. (.not. mosaic_support())) then
558  call spec_file_die_msg(230495365, file, &
559  'cannot use MOSAIC, support is not compiled in')
560  end if
561  if (run_part_opt%do_mosaic .and. run_part_opt%do_condensation) then
562  call spec_file_die_msg(599877804, file, &
563  'cannot use MOSAIC and condensation simultaneously')
564  end if
565  if (run_part_opt%do_mosaic) then
566  call spec_file_read_logical(file, 'do_optical', &
567  run_part_opt%do_optical)
568  else
569  run_part_opt%do_optical = .false.
570  end if
571 
572  call spec_file_read_logical(file, 'do_nucleation', &
573  run_part_opt%do_nucleation)
574  if (run_part_opt%do_nucleation) then
575  call spec_file_read_nucleate_type(file, aero_data, &
576  run_part_opt%nucleate_type, run_part_opt%nucleate_source)
577  else
578  run_part_opt%nucleate_type = nucleate_type_invalid
579  end if
580 
581  call spec_file_read_integer(file, 'rand_init', rand_init)
582  call spec_file_read_logical(file, 'allow_doubling', &
583  run_part_opt%allow_doubling)
584  call spec_file_read_logical(file, 'allow_halving', &
585  run_part_opt%allow_halving)
586  if (.not. do_restart) then
587  call spec_file_read_logical(file, 'do_select_weighting', &
588  run_part_opt%do_select_weighting)
589  if (run_part_opt%do_select_weighting) then
590  call spec_file_read_aero_state_weighting_type(file, &
591  run_part_opt%weighting_type, run_part_opt%weighting_exponent)
592  else
593  run_part_opt%weighting_type = aero_state_weight_nummass_source
594  run_part_opt%weighting_exponent = 0.0d0
595  end if
596  end if
597  call spec_file_read_logical(file, 'record_removals', &
598  run_part_opt%record_removals)
599 
600  call spec_file_read_logical(file, 'do_parallel', &
601  run_part_opt%do_parallel)
602  if (run_part_opt%do_parallel) then
603 #ifndef PMC_USE_MPI
604  call spec_file_die_msg(929006383, file, &
605  'cannot use parallel mode, support is not compiled in')
606 #endif
607  call spec_file_read_output_type(file, run_part_opt%output_type)
608  call spec_file_read_real(file, 'mix_timescale', &
609  run_part_opt%mix_timescale)
610  call spec_file_read_logical(file, 'gas_average', &
611  run_part_opt%gas_average)
612  call spec_file_read_logical(file, 'env_average', &
613  run_part_opt%env_average)
614  call spec_file_read_parallel_coag_type(file, &
615  run_part_opt%parallel_coag_type)
616  else
617  run_part_opt%output_type = output_type_single
618  run_part_opt%mix_timescale = 0d0
619  run_part_opt%gas_average = .false.
620  run_part_opt%env_average = .false.
621  run_part_opt%parallel_coag_type = parallel_coag_type_local
622  end if
623 
624  call spec_file_close(file)
625  end if
626 
627  ! finished reading .spec data, now broadcast data
628 
629  ! initialize RNG with random seed for UUID generation
630  call pmc_srand(0, pmc_mpi_rank())
631 
632  if (.not. do_restart) then
633  call uuid4_str(run_part_opt%uuid)
634  end if
635 
636 #ifdef PMC_USE_MPI
637  if (pmc_mpi_rank() == 0) then
638  ! root process determines size
639  max_buffer_size = 0
640  max_buffer_size = max_buffer_size &
641  + pmc_mpi_pack_size_run_part_opt(run_part_opt)
642  max_buffer_size = max_buffer_size &
643  + pmc_mpi_pack_size_real(n_part)
644  max_buffer_size = max_buffer_size &
645  + pmc_mpi_pack_size_gas_data(gas_data)
646  max_buffer_size = max_buffer_size &
647  + pmc_mpi_pack_size_gas_state(gas_state_init)
648  max_buffer_size = max_buffer_size &
649  + pmc_mpi_pack_size_aero_data(aero_data)
650  max_buffer_size = max_buffer_size &
651  + pmc_mpi_pack_size_aero_dist(aero_dist_init)
652  max_buffer_size = max_buffer_size &
653  + pmc_mpi_pack_size_scenario(scenario)
654  max_buffer_size = max_buffer_size &
655  + pmc_mpi_pack_size_env_state(env_state_init)
656  max_buffer_size = max_buffer_size &
657  + pmc_mpi_pack_size_integer(rand_init)
658  max_buffer_size = max_buffer_size &
659  + pmc_mpi_pack_size_logical(do_restart)
660  max_buffer_size = max_buffer_size &
661  + pmc_mpi_pack_size_logical(do_init_equilibrate)
662  max_buffer_size = max_buffer_size &
663  + pmc_mpi_pack_size_aero_state(aero_state_init)
664 
665  allocate(buffer(max_buffer_size))
666 
667  position = 0
668  call pmc_mpi_pack_run_part_opt(buffer, position, run_part_opt)
669  call pmc_mpi_pack_real(buffer, position, n_part)
670  call pmc_mpi_pack_gas_data(buffer, position, gas_data)
671  call pmc_mpi_pack_gas_state(buffer, position, gas_state_init)
672  call pmc_mpi_pack_aero_data(buffer, position, aero_data)
673  call pmc_mpi_pack_aero_dist(buffer, position, aero_dist_init)
674  call pmc_mpi_pack_scenario(buffer, position, scenario)
675  call pmc_mpi_pack_env_state(buffer, position, env_state_init)
676  call pmc_mpi_pack_integer(buffer, position, rand_init)
677  call pmc_mpi_pack_logical(buffer, position, do_restart)
678  call pmc_mpi_pack_logical(buffer, position, do_init_equilibrate)
679  call pmc_mpi_pack_aero_state(buffer, position, aero_state_init)
680  call assert(181905491, position <= max_buffer_size)
681  buffer_size = position ! might be less than we allocated
682  end if
683 
684  ! tell everyone the size
685  call pmc_mpi_bcast_integer(buffer_size)
686 
687  if (pmc_mpi_rank() /= 0) then
688  ! non-root processes allocate space
689  allocate(buffer(buffer_size))
690  end if
691 
692  ! broadcast data to everyone
693  call pmc_mpi_bcast_packed(buffer)
694 
695  if (pmc_mpi_rank() /= 0) then
696  ! non-root processes unpack data
697  position = 0
698  call pmc_mpi_unpack_run_part_opt(buffer, position, run_part_opt)
699  call pmc_mpi_unpack_real(buffer, position, n_part)
700  call pmc_mpi_unpack_gas_data(buffer, position, gas_data)
701  call pmc_mpi_unpack_gas_state(buffer, position, gas_state_init)
702  call pmc_mpi_unpack_aero_data(buffer, position, aero_data)
703  call pmc_mpi_unpack_aero_dist(buffer, position, aero_dist_init)
704  call pmc_mpi_unpack_scenario(buffer, position, scenario)
705  call pmc_mpi_unpack_env_state(buffer, position, env_state_init)
706  call pmc_mpi_unpack_integer(buffer, position, rand_init)
707  call pmc_mpi_unpack_logical(buffer, position, do_restart)
708  call pmc_mpi_unpack_logical(buffer, position, do_init_equilibrate)
709  call pmc_mpi_unpack_aero_state(buffer, position, aero_state_init)
710  call assert(143770146, position == buffer_size)
711  end if
712 
713  ! free the buffer
714  deallocate(buffer)
715 #endif
716 
717  ! initialize the chemistry solver
718  if (run_part_opt%do_camp_chem) then
719 #ifdef PMC_USE_CAMP
720  call camp_core%solver_initialize()
721 #endif
722  end if
723 
724  ! re-initialize RNG with the given seed
725  call pmc_rand_finalize()
726  call pmc_srand(rand_init, pmc_mpi_rank())
727 
728  call cpu_time(run_part_opt%t_wall_start)
729 
730  do i_repeat = 1,run_part_opt%n_repeat
731  run_part_opt%i_repeat = i_repeat
732 
733  gas_state = gas_state_init
734  if (do_restart) then
735  aero_state = aero_state_init
736  call aero_state_set_n_part_ideal(aero_state, n_part)
737  else
738  call aero_state_zero(aero_state)
739  aero_mode_type_exp_present &
740  = aero_dist_contains_aero_mode_type(aero_dist_init, &
741  aero_mode_type_exp) &
742  .or. scenario_contains_aero_mode_type(scenario, &
743  aero_mode_type_exp)
744  if (aero_mode_type_exp_present) then
745  call warn_msg(245301880, "using flat weighting only due to " &
746  // "presence of exp aerosol mode")
747  call aero_state_set_weight(aero_state, aero_data, &
749  else
750  call aero_state_set_weight(aero_state, aero_data, &
751  run_part_opt%weighting_type, run_part_opt%weighting_exponent)
752  end if
753  call aero_state_set_n_part_ideal(aero_state, n_part)
754  call aero_state_add_aero_dist_sample(aero_state, aero_data, &
755  aero_dist_init, 1d0, 0d0, run_part_opt%allow_doubling, &
756  run_part_opt%allow_halving)
757  end if
758  env_state = env_state_init
759  call scenario_init_env_state(scenario, env_state, &
760  env_state_init%elapsed_time)
761 
762 #ifdef PMC_USE_SUNDIALS
763  if (do_init_equilibrate) then
764  call condense_equilib_particles(env_state, aero_data, aero_state)
765  end if
766 #endif
767 
768  if (run_part_opt%do_camp_chem) then
769 #ifdef PMC_USE_CAMP
770  call run_part(scenario, env_state, aero_data, aero_state, gas_data, &
771  gas_state, run_part_opt, camp_core=camp_core, &
772  photolysis=photolysis)
773 #endif
774  else
775  call run_part(scenario, env_state, aero_data, aero_state, gas_data, &
776  gas_state, run_part_opt)
777  end if
778 
779  end do
780 
781  call pmc_rand_finalize()
782 
783  end subroutine partmc_part
784 
785 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
786 
787  !> Run an exact solution simulation.
788  subroutine partmc_exact(file)
789 
790  !> Spec file.
791  type(spec_file_t), intent(inout) :: file
792 
793  character(len=100) :: soln_name
794  type(aero_data_t) :: aero_data
795  type(scenario_t) :: scenario
796  type(env_state_t) :: env_state
797  type(aero_dist_t) :: aero_dist_init
798  type(run_exact_opt_t) :: run_exact_opt
799  type(bin_grid_t) :: bin_grid
800  type(gas_data_t) :: gas_data
801  character(len=PMC_MAX_FILENAME_LEN) :: sub_filename
802  type(spec_file_t) :: sub_file
803 
804  !> \page input_format_exact Exact (Analytical) Solution
805  !!
806  !! The coagulation kernel and initial distribution must be matched
807  !! for an exact solution to exist. The valid choices are:
808  !!
809  !! <table>
810  !! <tr><th>Coagulation kernel</th>
811  !! <th>Initial aerosol distribution</th></tr>
812  !! <tr><td>Additive</td>
813  !! <td>Single exponential mode</td></tr>
814  !! <tr><td>Constant</td>
815  !! <td>Single exponential mode</td></tr>
816  !! <tr><td>Zero</td>
817  !! <td>Anything</td></tr>
818  !! </table>
819  !!
820  !! See \ref spec_file_format for the input file text format.
821  !!
822  !! An exact (analytical) simulation spec file has the parameters:
823  !! - \b run_type (string): must be \c exact
824  !! - \b output_prefix (string): prefix of the output filenames ---
825  !! the filenames will be of the form \c PREFIX_SSSSSSSS.nc where
826  !! \c SSSSSSSS is is the eight-digit output index (starting at 1
827  !! and incremented each time the state is output)
828  !! - \b t_max (real, unit s): total simulation time
829  !! - \b t_output (real, unit s): the interval on which to output
830  !! data to disk and to print progress information to the screen
831  !! (see \ref output_format)
832  !! - \subpage input_format_diam_bin_grid
833  !! - \b gas_data (string): name of file from which to read the
834  !! gas material data --- the file format should be
835  !! \subpage input_format_gas_data
836  !! - \b aerosol_data (string): name of file from which to read the
837  !! aerosol material data --- the file format should be
838  !! \subpage input_format_aero_data
839  !! - \b do_fractal (logical): whether to consider particles
840  !! as fractal agglomerates. If \c do_fractal is \c no, then all the
841  !! particles are treated as spherical. If \c do_fractal is \c yes,
842  !! then the following parameters must also be provided:
843  !! - \subpage input_format_fractal
844  !! - \b aerosol_init (string): filename containing the initial
845  !! aerosol state at the start of the simulation --- the file
846  !! format should be \subpage input_format_aero_dist
847  !! - \subpage input_format_scenario
848  !! - \subpage input_format_env_state
849  !! - \b do_coagulation (logical): whether to perform particle
850  !! coagulation. If \c do_coagulation is \c yes, then the
851  !! following parameters must also be provided:
852  !! - \subpage input_format_coag_kernel
853  !!
854  !! Example:
855  !! <pre>
856  !! run_type exact # exact solution
857  !! output_prefix additive_exact # prefix of output files
858  !!
859  !! t_max 600 # total simulation time (s)
860  !! t_output 60 # output interval (0 disables) (s)
861  !!
862  !! n_bin 160 # number of bins
863  !! d_min 1e-8 # minimum diameter (m)
864  !! d_max 1e-3 # maximum diameter (m)
865  !!
866  !! gas_data gas_data.dat # file containing gas data
867  !!
868  !! aerosol_data aero_data.dat # file containing aerosol data
869  !! do_fractal no # whether to do fractal treatment
870  !! aerosol_init aero_init_dist.dat # aerosol initial condition file
871  !!
872  !! temp_profile temp.dat # temperature profile file
873  !! height_profile height.dat # height profile file
874  !! gas_emissions gas_emit.dat # gas emissions file
875  !! gas_background gas_back.dat # background gas mixing ratios file
876  !! aero_emissions aero_emit.dat # aerosol emissions file
877  !! aero_background aero_back.dat # aerosol background file
878  !!
879  !! rel_humidity 0.999 # initial relative humidity (1)
880  !! pressure 1e5 # initial pressure (Pa)
881  !! latitude 0 # latitude (degrees, -90 to 90)
882  !! longitude 0 # longitude (degrees, -180 to 180)
883  !! altitude 0 # altitude (m)
884  !! start_time 0 # start time (s since 00:00 UTC)
885  !! start_day 1 # start day of year (UTC)
886  !!
887  !! do_coagulation yes # whether to do coagulation (yes/no)
888  !! kernel additive # Additive coagulation kernel
889  !! </pre>
890 
891  ! only serial code here
892  if (pmc_mpi_rank() /= 0) then
893  return
894  end if
895 
896  call spec_file_read_string(file, 'output_prefix', run_exact_opt%prefix)
897 
898  call spec_file_read_real(file, 't_max', run_exact_opt%t_max)
899  call spec_file_read_real(file, 't_output', run_exact_opt%t_output)
900 
901  call spec_file_read_radius_bin_grid(file, bin_grid)
902 
903  call spec_file_read_string(file, 'gas_data', sub_filename)
904  call spec_file_open(sub_filename, sub_file)
905  call spec_file_read_gas_data(sub_file, gas_data)
906  call spec_file_close(sub_file)
907 
908  call spec_file_read_string(file, 'aerosol_data', sub_filename)
909  call spec_file_open(sub_filename, sub_file)
910  call spec_file_read_aero_data(sub_file, aero_data)
911  call spec_file_close(sub_file)
912 
913  call spec_file_read_fractal(file, aero_data%fractal)
914 
915  call spec_file_read_string(file, 'aerosol_init', sub_filename)
916  call spec_file_open(sub_filename, sub_file)
917  call spec_file_read_aero_dist(sub_file, aero_data, aero_dist_init)
918  call spec_file_close(sub_file)
919 
920  call spec_file_read_scenario(file, gas_data, aero_data, scenario)
921  call spec_file_read_env_state(file, env_state)
922 
923  call spec_file_read_logical(file, 'do_coagulation', &
924  run_exact_opt%do_coagulation)
925  if (run_exact_opt%do_coagulation) then
926  call spec_file_read_coag_kernel_type(file, &
927  run_exact_opt%coag_kernel_type)
928  else
929  run_exact_opt%coag_kernel_type = coag_kernel_type_invalid
930  end if
931 
932  call spec_file_close(file)
933 
934  ! finished reading .spec data, now do the run
935 
936  call pmc_srand(0, 0)
937 
938  call uuid4_str(run_exact_opt%uuid)
939 
940  call scenario_init_env_state(scenario, env_state, 0d0)
941 
942  call run_exact(bin_grid, scenario, env_state, aero_data, &
943  aero_dist_init, gas_data, run_exact_opt)
944 
945  call pmc_rand_finalize()
946 
947  end subroutine partmc_exact
948 
949 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
950 
951  !> Run a sectional code simulation.
952  subroutine partmc_sect(file)
953 
954  !> Spec file.
955  type(spec_file_t), intent(inout) :: file
956 
957  type(run_sect_opt_t) :: run_sect_opt
958  type(aero_data_t) :: aero_data
959  type(aero_dist_t) :: aero_dist_init
960  type(aero_state_t) :: aero_init
961  type(scenario_t) :: scenario
962  type(env_state_t) :: env_state
963  type(bin_grid_t) :: bin_grid
964  type(gas_data_t) :: gas_data
965  character(len=PMC_MAX_FILENAME_LEN) :: sub_filename
966  type(spec_file_t) :: sub_file
967 
968  !> \page input_format_sectional Sectional Model Simulation
969  !!
970  !! See \ref spec_file_format for the input file text format.
971  !!
972  !! A sectional simulation spec file has the parameters:
973  !! - \b run_type (string): must be \c sectional
974  !! - \b output_prefix (string): prefix of the output filenames ---
975  !! the filenames will be of the form \c PREFIX_SSSSSSSS.nc where
976  !! \c SSSSSSSS is is the eight-digit output index (starting at 1
977  !! and incremented each time the state is output)
978  !! - \b del_t (real, unit s): timestep size
979  !! - \b t_output (real, unit s): the interval on which to
980  !! output data to disk (see \ref output_format)
981  !! - \b t_progress (real, unit s): the interval on which to
982  !! write summary information to the screen while running
983  !! - \subpage input_format_diam_bin_grid
984  !! - \b gas_data (string): name of file from which to read the
985  !! gas material data --- the file format should be
986  !! \subpage input_format_gas_data
987  !! - \b aerosol_data (string): name of file from which to read the
988  !! aerosol material data --- the file format should be
989  !! \subpage input_format_aero_data
990  !! - \b do_fractal (logical): whether to consider particles
991  !! as fractal agglomerates. If \c do_fractal is \c no, then all the
992  !! particles are treated as spherical. If \c do_fractal is \c yes,
993  !! then the following parameters must also be provided:
994  !! - \subpage input_format_fractal
995  !! - \b aerosol_init (string): filename containing the initial
996  !! aerosol state at the start of the simulation --- the file
997  !! format should be \subpage input_format_aero_dist
998  !! - \subpage input_format_scenario
999  !! - \subpage input_format_env_state
1000  !! - \b do_coagulation (logical): whether to perform particle
1001  !! coagulation. If \c do_coagulation is \c yes, then the
1002  !! following parameters must also be provided:
1003  !! - \subpage input_format_coag_kernel
1004  !!
1005  !! Example:
1006  !! <pre>
1007  !! run_type sectional # sectional code run
1008  !! output_prefix brown_sect # prefix of output files
1009  !!
1010  !! t_max 86400 # total simulation time (s)
1011  !! del_t 60 # timestep (s)
1012  !! t_output 3600 # output interval (0 disables) (s)
1013  !! t_progress 600 # progress printing interval (0 disables) (s)
1014  !!
1015  !! n_bin 220 # number of bins
1016  !! d_min 1e-10 # minimum diameter (m)
1017  !! d_max 1e-4 # maximum diameter (m)
1018  !!
1019  !! gas_data gas_data.dat # file containing gas data
1020  !! aerosol_data aero_data.dat # file containing aerosol data
1021  !! do_fractal no # whether to do fractal treatment
1022  !! aerosol_init aero_init_dist.dat # initial aerosol distribution
1023  !!
1024  !! temp_profile temp.dat # temperature profile file
1025  !! height_profile height.dat # height profile file
1026  !! gas_emissions gas_emit.dat # gas emissions file
1027  !! gas_background gas_back.dat # background gas mixing ratios file
1028  !! aero_emissions aero_emit.dat # aerosol emissions file
1029  !! aero_background aero_back.dat # aerosol background file
1030  !!
1031  !! rel_humidity 0.999 # initial relative humidity (1)
1032  !! pressure 1e5 # initial pressure (Pa)
1033  !! latitude 0 # latitude (degrees_north, -90 to 90)
1034  !! longitude 0 # longitude (degrees_east, -180 to 180)
1035  !! altitude 0 # altitude (m)
1036  !! start_time 0 # start time (s since 00:00 UTC)
1037  !! start_day 1 # start day of year (UTC)
1038  !!
1039  !! do_coagulation yes # whether to do coagulation (yes/no)
1040  !! kernel brown # coagulation kernel
1041  !! </pre>
1042 
1043  ! only serial code here
1044  if (pmc_mpi_rank() /= 0) then
1045  return
1046  end if
1047 
1048  call spec_file_read_string(file, 'output_prefix', run_sect_opt%prefix)
1049 
1050  call spec_file_read_real(file, 't_max', run_sect_opt%t_max)
1051  call spec_file_read_real(file, 'del_t', run_sect_opt%del_t)
1052  call spec_file_read_real(file, 't_output', run_sect_opt%t_output)
1053  call spec_file_read_real(file, 't_progress', run_sect_opt%t_progress)
1054 
1055  call spec_file_read_radius_bin_grid(file, bin_grid)
1056 
1057  call spec_file_read_string(file, 'gas_data', sub_filename)
1058  call spec_file_open(sub_filename, sub_file)
1059  call spec_file_read_gas_data(sub_file, gas_data)
1060  call spec_file_close(sub_file)
1061 
1062  call spec_file_read_string(file, 'aerosol_data', sub_filename)
1063  call spec_file_open(sub_filename, sub_file)
1064  call spec_file_read_aero_data(sub_file, aero_data)
1065  call spec_file_close(sub_file)
1066 
1067  call spec_file_read_fractal(file, aero_data%fractal)
1068 
1069  call spec_file_read_string(file, 'aerosol_init', sub_filename)
1070  call spec_file_open(sub_filename, sub_file)
1071  call spec_file_read_aero_dist(sub_file, aero_data, aero_dist_init)
1072  call spec_file_close(sub_file)
1073 
1074  call spec_file_read_scenario(file, gas_data, aero_data, scenario)
1075  call spec_file_read_env_state(file, env_state)
1076 
1077  call spec_file_read_logical(file, 'do_coagulation', &
1078  run_sect_opt%do_coagulation)
1079  if (run_sect_opt%do_coagulation) then
1080  call spec_file_read_coag_kernel_type(file, &
1081  run_sect_opt%coag_kernel_type)
1082  else
1083  run_sect_opt%coag_kernel_type = coag_kernel_type_invalid
1084  end if
1085 
1086  call spec_file_close(file)
1087 
1088  ! finished reading .spec data, now do the run
1089 
1090  call pmc_srand(0, 0)
1091 
1092  call uuid4_str(run_sect_opt%uuid)
1093 
1094  call scenario_init_env_state(scenario, env_state, 0d0)
1095 
1096  call run_sect(bin_grid, gas_data, aero_data, aero_dist_init, scenario, &
1097  env_state, run_sect_opt)
1098 
1099  call pmc_rand_finalize()
1100 
1101  end subroutine partmc_sect
1102 
1103 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1104 
1105 end program partmc
pmc_mpi::pmc_mpi_init
subroutine pmc_mpi_init()
Initialize MPI.
Definition: mpi.F90:56
pmc_run_sect::run_sect_opt_t
Options controlling the operation of run_sect().
Definition: run_sect.F90:32
pmc_run_part::parallel_coag_type_local
integer, parameter parallel_coag_type_local
Type code for local parallel coagulation.
Definition: run_part.F90:43
pmc_aero_state::aero_state_zero
subroutine aero_state_zero(aero_state)
Resets an aero_state to have zero particles per bin.
Definition: aero_state.F90:321
pmc_scenario::scenario_contains_aero_mode_type
elemental logical function scenario_contains_aero_mode_type(scenario, aero_mode_type)
Whether any of the contained aerosol modes are of the given type.
Definition: scenario.F90:735
pmc_run_sect
1D sectional simulation.
Definition: run_sect.F90:17
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:486
pmc_gas_data::gas_data_t
Constant gas data.
Definition: gas_data.F90:35
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_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:562
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:365
pmc_spec_file::spec_file_close
subroutine spec_file_close(file)
Close a spec file.
Definition: spec_file.F90:135
pmc_aero_dist::pmc_mpi_pack_aero_dist
subroutine pmc_mpi_pack_aero_dist(buffer, position, val)
Packs the given value into the buffer, advancing position.
Definition: aero_dist.F90:419
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:392
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:122
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:1041
partmc
program partmc
Top level driver.
Definition: partmc.F90:215
pmc_aero_state::aero_state_set_weight
subroutine aero_state_set_weight(aero_state, aero_data, weight_type, exponent)
Sets the weighting functions for an aero_state.
Definition: aero_state.F90:173
pmc_util::die_msg
subroutine die_msg(code, error_msg)
Error immediately.
Definition: util.F90:134
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:638
pmc_aero_state::aero_state_set_n_part_ideal
subroutine aero_state_set_n_part_ideal(aero_state, n_part)
Set the ideal number of particles to the given value. The aero_state%awa must be already set correctl...
Definition: aero_state.F90:218
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_run_part::run_part_opt_t
Options controlling the execution of run_part().
Definition: run_part.F90:48
pmc_spec_file
Reading formatted text input.
Definition: spec_file.F90:43
pmc_condense::condense_equilib_particles
subroutine condense_equilib_particles(env_state, aero_data, aero_state)
Call condense_equilib_particle() on each particle in the aerosol to ensure that every particle has it...
Definition: condense.F90:747
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:1100
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:586
pmc_util::assert
subroutine assert(code, condition_ok)
Errors unless condition_ok is true.
Definition: util.F90:103
pmc_aero_data::aero_data_initialize
subroutine aero_data_initialize(aero_data, camp_core)
Initialize the aero_data_t variable with camp chem data.
Definition: aero_data.F90:855
pmc_aero_state
The aero_state_t structure and assocated subroutines.
Definition: aero_state.F90:9
pmc_aero_state::aero_state_weight_flat
integer, parameter aero_state_weight_flat
Single flat weighting scheme.
Definition: aero_state.F90:41
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:407
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_mpi::pmc_mpi_finalize
subroutine pmc_mpi_finalize()
Shut down MPI.
Definition: mpi.F90:89
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:555
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:359
pmc_util::warn_msg
subroutine warn_msg(code, warning_msg, already_warned)
Prints a warning message.
Definition: util.F90:37
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::assert_msg
subroutine assert_msg(code, condition_ok, error_msg)
Errors unless condition_ok is true.
Definition: util.F90:77
pmc_aero_dist::pmc_mpi_unpack_aero_dist
subroutine pmc_mpi_unpack_aero_dist(buffer, position, val)
Unpacks the given value from the buffer, advancing position.
Definition: aero_dist.F90:449
pmc_aero_dist
The aero_dist_t structure and associated subroutines.
Definition: aero_dist.F90:18
print_usage
subroutine print_usage()
Print the usage text to stderr.
Definition: partmc.F90:267
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:985
pmc_photolysis
The photolysis_t type and related functions.
Definition: photolysis.F90:9
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_run_exact::run_exact
subroutine run_exact(bin_grid, scenario, env_state, aero_data, aero_dist_init, gas_data, run_exact_opt)
Run an exact simulation.
Definition: run_exact.F90:46
pmc_gas_state::gas_state_t
Current state of the gas mixing ratios in the system.
Definition: gas_state.F90:33
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_rand::uuid4_str
subroutine uuid4_str(uuid)
Generate a version 4 UUID as a string.
Definition: rand.F90:600
pmc_aero_data::aero_data_t
Aerosol material properties and associated data.
Definition: aero_data.F90:49
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:818
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:896
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:2231
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_exact::run_exact_opt_t
Options controlling the execution of run_exact().
Definition: run_exact.F90:24
pmc_aero_dist::aero_dist_t
A complete aerosol distribution, consisting of several modes.
Definition: aero_dist.F90:33
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:2205
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:2186
pmc_util
Common utility subroutines.
Definition: util.F90:9
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:111
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:532
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_aero_dist::pmc_mpi_pack_size_aero_dist
integer function pmc_mpi_pack_size_aero_dist(val)
Determines the number of bytes required to pack the given value.
Definition: aero_dist.F90:397
pmc_aero_binned
The aero_binned_t structure and associated subroutines.
Definition: aero_binned.F90:9
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:537
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_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_bin_grid
The bin_grid_t structure and associated subroutines.
Definition: bin_grid.F90:9
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:561
pmc_aero_data
The aero_data_t structure and associated subroutines.
Definition: aero_data.F90:9
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:510
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:58
pmc_bin_grid::bin_grid_t
1D grid, either logarithmic or linear.
Definition: bin_grid.F90:33
partmc_run
subroutine partmc_run(spec_name)
Do a PartMC run.
Definition: partmc.F90:276
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:336
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:843
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:445
pmc_rand::pmc_rand_finalize
subroutine pmc_rand_finalize()
Cleanup the random number generator.
Definition: rand.F90:119
pmc_aero_dist::aero_dist_contains_aero_mode_type
elemental logical function aero_dist_contains_aero_mode_type(aero_dist, aero_mode_type)
Whether any of the modes are of the given type.
Definition: aero_dist.F90:155
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:519
pmc_mpi::pmc_mpi_bcast_string
subroutine pmc_mpi_bcast_string(val)
Broadcast the given value from process 0 to all other processes.
Definition: mpi.F90:307
pmc_aero_state::aero_state_t
The current collection of aerosol particles.
Definition: aero_state.F90:63
pmc_run_exact
Exact solution simulation.
Definition: run_exact.F90:9
pmc_aero_state::aero_state_add_aero_dist_sample
subroutine aero_state_add_aero_dist_sample(aero_state, aero_data, aero_dist, sample_prop, create_time, allow_doubling, allow_halving, n_part_add)
Generates a Poisson sample of an aero_dist, adding to aero_state, with the given sample proportion.
Definition: aero_state.F90:717
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:531
pmc_aero_state::aero_state_initialize
subroutine aero_state_initialize(aero_state, aero_data, camp_core)
Initialize the aero_state_t variable with camp chem data.
Definition: aero_state.F90:2983