PyPartMC 1.4.2__cp38-cp38-win_amd64.whl → 2.0.0rc4__cp38-cp38-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of PyPartMC might be problematic. Click here for more details.

PyPartMC/__init__.py CHANGED
@@ -1,13 +1,18 @@
1
1
  """
2
- .. include::../README.md
2
+ .. include::../../README.md
3
3
  """
4
4
 
5
+ # pylint: disable=invalid-name
6
+ import importlib.metadata
7
+
5
8
  # pylint: disable=invalid-name,wrong-import-position
6
9
  import os
7
10
  from collections import namedtuple
8
11
  from contextlib import contextmanager
9
12
  from pathlib import Path
10
13
 
14
+ import nanobind
15
+
11
16
 
12
17
  # https://github.com/diegoferigo/cmake-build-extension/blob/master/src/cmake_build_extension/__init__.py
13
18
  @contextmanager
@@ -69,10 +74,13 @@ si = __generate_si()
69
74
  SI-prefix-aware unit multipliers, resulting in e.g.: `p = 1000 * si.hPa`
70
75
  notation. Note: no dimensional analysis is done! """
71
76
 
72
- with __build_extension_env():
73
- import _PyPartMC
74
- from _PyPartMC import *
75
- from _PyPartMC import __all__ as _PyPartMC_all # pylint: disable=no-name-in-module
76
- from _PyPartMC import __version__, __versions_of_build_time_dependencies__
77
+ from ._PyPartMC import * # pylint: disable=import-error
78
+ from ._PyPartMC import ( # pylint: disable=import-error
79
+ __versions_of_build_time_dependencies__,
80
+ )
81
+
82
+ __version__ = importlib.metadata.version(__package__)
77
83
 
78
- __all__ = tuple([*_PyPartMC_all, "si"])
84
+ # walkaround for MATLAB bindings
85
+ # pylint: disable=undefined-variable
86
+ setattr(nanobind, "nb_type_0", type(_PyPartMC.AeroData))
@@ -1,397 +1,393 @@
1
- Metadata-Version: 2.1
2
- Name: PyPartMC
3
- Version: 1.4.2
4
- Summary: Python interface to PartMC
5
- Author: PyPartMC team (see https://github.com/open-atmos/PyPartMC/graphs/contributors)
6
- Author-email: nriemer@illinois.edu
7
- License: GPL-3.0
8
- Project-URL: Tracker, https://github.com/open-atmos/PyPartMC/issues
9
- Project-URL: Documentation, https://open-atmos.github.io/PyPartMC
10
- Project-URL: Source, https://github.com/open-atmos/PyPartMC/
11
- Requires-Python: >=3.7
12
- Description-Content-Type: text/markdown
13
- License-File: LICENSE
14
- Requires-Dist: numpy
15
- Provides-Extra: examples
16
- Requires-Dist: matplotlib!=3.10.0; extra == "examples"
17
- Requires-Dist: ipywidgets; extra == "examples"
18
- Requires-Dist: voila; extra == "examples"
19
- Requires-Dist: open-atmos-jupyter-utils; extra == "examples"
20
- Requires-Dist: PySDM; extra == "examples"
21
- Requires-Dist: PyMieScatt; extra == "examples"
22
- Requires-Dist: SciPy; extra == "examples"
23
- Provides-Extra: tests
24
- Requires-Dist: pytest; extra == "tests"
25
- Requires-Dist: pytest-order; extra == "tests"
26
- Requires-Dist: fastcore!=1.5.8; extra == "tests"
27
- Requires-Dist: ghapi; extra == "tests"
28
- Requires-Dist: scipy; extra == "tests"
29
-
30
- ![logo](https://raw.githubusercontent.com/wiki/open-atmos/PyPartMC/logo.svg)
31
-
32
- # PyPartMC
33
-
34
- PyPartMC is a Python interface to [PartMC](https://lagrange.mechse.illinois.edu/partmc/),
35
- a particle-resolved Monte-Carlo code for atmospheric aerosol simulation.
36
- Development of PyPartMC has been intended to remove limitations to the use of Fortran-implemented PartMC.
37
- PyPartMC facilitates the dissemination of computational research results by streamlining independent execution
38
- of PartMC simulations (also during peer-review processes).
39
- Additionally, the ability to easily package examples, simple simulations, and results in a web-based notebook
40
- allows PyPartMC to support the efforts of many members of the scientific community, including researchers,
41
- instructors, and students, with nominal software and hardware requirements.
42
-
43
- Documentation of PyPartMC is hosted at https://open-atmos.github.io/PyPartMC.
44
- PyPartMC is implemented in C++ and it also constitutes a C++ API to the PartMC Fortran internals.
45
- The Python API can facilitate using PartMC from other environments - see, e.g., Julia and Matlab examples below.
46
-
47
- For an outline of the project, rationale, architecture, and features, refer to: [D'Aquino et al., 2024 (SoftwareX)](https://doi.org/10.1016/j.softx.2023.101613) (please cite if PyPartMC is used in your research).
48
- For a list of talks and other relevant resources, please see [project Wiki](https://github.com/open-atmos/PyPartMC/wiki/).
49
- If interested in contributing to PyPartMC, please have a look a the [notes for developers](https://github.com/open-atmos/PyPartMC/tree/main/CONTRIBUTING.md).
50
-
51
- [![US Funding](https://img.shields.io/static/v1?label=US%20DOE%20Funding%20by&color=267c32&message=ASR&logoWidth=25&logo=image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAQCAMAAAA25D/gAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAASFBMVEVOTXyyIjRDQnNZWINZWITtzdFUU4BVVIFVVYHWiZM9PG/KZnNXVoJaWYT67/FKSXhgX4hgX4lcW4VbWoX03uHQeIN2VXj///9pZChlAAAAAWJLR0QXC9aYjwAAAAd0SU1FB+EICRMGJV+KCCQAAABdSURBVBjThdBJDoAgEETRkkkZBBX0/kd11QTTpH1/STqpAAwWBkobSlkGbt0o5xmEfqxDZJB2Q6XMoBwnVSbTylWp0hi42rmbwTOYPDfR5Kc+07IIUQQvghX9THsBHcES8/SiF0kAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTctMDgtMDlUMTk6MDY6MzcrMDA6MDCX1tBgAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE3LTA4LTA5VDE5OjA2OjM3KzAwOjAw5oto3AAAAABJRU5ErkJggg==)](https://asr.science.energy.gov/) [![PL Funding](https://img.shields.io/static/v1?label=PL%20Funding%20by&color=d21132&message=NCN&logoWidth=25&logo=image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAABmJLR0QA/wD/AP+gvaeTAAAAKUlEQVQ4jWP8////fwYqAiZqGjZqIHUAy4dJS6lqIOMdEZvRZDPcDQQAb3cIaY1Sbi4AAAAASUVORK5CYII=)](https://www.ncn.gov.pl/?language=en)
52
-
53
- [![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0.html)
54
- [![Copyright](https://img.shields.io/static/v1?label=Copyright&color=249fe2&message=UIUC&)](https://atmos.illinois.edu/)
55
- [![tests+pypi](https://github.com/open-atmos/PyPartMC/actions/workflows/tests+pypi.yml/badge.svg)](https://github.com/open-atmos/PyPartMC/actions/workflows/tests+pypi.yml)
56
- [![API docs](https://shields.mitmproxy.org/badge/docs-pdoc.dev-brightgreen.svg)](https://open-atmos.github.io/PyPartMC/)
57
- [![codecov](https://codecov.io/gh/open-atmos/PyPartMC/graph/badge.svg?token=27IK9ZIQXE)](https://codecov.io/gh/open-atmos/PyPartMC)
58
- [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.7662635.svg)](https://doi.org/10.5281/zenodo.7662635)
59
- [![PyPI version](https://badge.fury.io/py/PyPartMC.svg)](https://pypi.org/p/PyPartMC)
60
- [![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active)
61
-
62
- [![Python 3](https://img.shields.io/static/v1?label=Python&logo=Python&color=3776AB&message=3)](https://www.python.org/)
63
- [![Linux OK](https://img.shields.io/static/v1?label=Linux&logo=Linux&color=yellow&message=%E2%9C%93)](https://en.wikipedia.org/wiki/Linux)
64
- [![macOS OK](https://img.shields.io/static/v1?label=macOS&logo=Apple&color=silver&message=%E2%9C%93)](https://en.wikipedia.org/wiki/macOS)
65
- [![Windows OK](https://img.shields.io/static/v1?label=Windows&logo=Windows&color=white&message=%E2%9C%93)](https://en.wikipedia.org/wiki/Windows)
66
- [![Jupyter](https://img.shields.io/static/v1?label=Jupyter&logo=Jupyter&color=f37626&message=%E2%9C%93)](https://jupyter.org/)
67
-
68
- ## Installation
69
-
70
- ### Using the command-line `pip` tool (also applies to conda environments)
71
- ```bash
72
- pip install PyPartMC
73
- ```
74
-
75
- Note that, depending on the environment (OS, hardware, Python version), the pip-install invocation
76
- may either trigger a download of a pre-compiled binary, or trigger compilation of PyPartMC.
77
- In the latter case, a Fortran compiler and some development tools includiong CMake, m4 and perl
78
- are required (while all non-Python dependencies are included in the PyPartMC source archive).
79
- In both cases, all Python dependencies will be resolved by pip.
80
-
81
- ### In a Jupyter notebook cell (also on Colab or jupyter-hub instances)
82
-
83
- ```python
84
- ! pip install PyPartMC
85
- import PyPartMC
86
- ```
87
-
88
- #### Jupyter notebooks with examples
89
- Note: clicking the badges below redirects to cloud-computing platforms. The mybinder.org links allow anonymous execution, Google Colab requires logging in with a Google account, ARM JupyerHub requires logging in with an ARM account (and directing Jupyter to a particular notebook within the `examples` folder).
90
-
91
- The example notebooks feature additional dependencies that can be installed with:
92
- ```bash
93
- pip install PyPartMC[examples]
94
- ```
95
-
96
- - Urban plume scenario demo (as in [PartMC](https://github.com/compdyn/partmc/tree/master/scenarios/1_urban_plume)):
97
- [![View notebook](https://img.shields.io/static/v1?label=render%20on&logo=github&color=87ce3e&message=GitHub)](https://github.com/open-atmos/PyPartMC/blob/main/examples/particle_simulation.ipynb)
98
- [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/open-atmos/PyPartMC/blob/main/examples/particle_simulation.ipynb)
99
- [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/open-atmos/PyPartMC.git/main?urlpath=lab/tree/examples/particle_simulation.ipynb)
100
- [![ARM JupyterHub](https://img.shields.io/static/v1?label=launch%20in&logo=jupyter&color=lightblue&message=ARM+JupyterHub)](https://jupyterhub.arm.gov/hub/user-redirect/git-pull?repo=https%3A//github.com/open-atmos/PyPartMC&branch=main&urlPath=)
101
- - Dry-Wet Particle Size Equilibration with PartMC and PySDM:
102
- [![View notebook](https://img.shields.io/static/v1?label=render%20on&logo=github&color=87ce3e&message=GitHub)](https://github.com/open-atmos/PyPartMC/blob/main/examples/lognorm_ex.ipynb)
103
- [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/open-atmos/PyPartMC/blob/main/examples/lognorm_ex.ipynb)
104
- [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/open-atmos/PyPartMC.git/main?urlpath=lab/tree/examples/lognorm_ex.ipynb)
105
- [![ARM JupyterHub](https://img.shields.io/static/v1?label=launch%20in&logo=jupyter&color=lightblue&message=ARM+JupyterHub)](https://jupyterhub.arm.gov/hub/user-redirect/git-pull?repo=https%3A//github.com/open-atmos/PyPartMC&branch=main&urlPath=)
106
- [![Voila](https://img.shields.io/static/v1?label=Voil%C3%A0&logo=jupyter&color=teal&message=web+app)](https://mybinder.org/v2/gh/open-atmos/PyPartMC/main?urlpath=voila%2Frender%2Fexamples%2Flognorm_ex.ipynb)
107
- - Simulation output processing example (loading from netCDF files using PyPartMC):
108
- [![View notebook](https://img.shields.io/static/v1?label=render%20on&logo=github&color=87ce3e&message=GitHub)](https://github.com/open-atmos/PyPartMC/blob/main/examples/process_simulation_output.ipynb)
109
- [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/open-atmos/PyPartMC/blob/main/examples/process_simulation_output.ipynb)
110
- [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/open-atmos/PyPartMC.git/main?urlpath=lab/tree/examples/process_simulation_output.ipynb)
111
- [![ARM JupyterHub](https://img.shields.io/static/v1?label=launch%20in&logo=jupyter&color=lightblue&message=ARM+JupyterHub)](https://jupyterhub.arm.gov/hub/user-redirect/git-pull?repo=https%3A//github.com/open-atmos/PyPartMC&branch=main&urlPath=)
112
- - Optical properties calculation using external Python package ([PyMieScatt](https://pymiescatt.readthedocs.io/en/latest/)):
113
- [![View notebook](https://img.shields.io/static/v1?label=render%20on&logo=github&color=87ce3e&message=GitHub)](https://github.com/open-atmos/PyPartMC/blob/main/examples/mie_optical.ipynb)
114
- [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/open-atmos/PyPartMC/blob/main/examples/mie_optical.ipynb)
115
- [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/open-atmos/PyPartMC.git/main?urlpath=lab/tree/examples/mie_optical.ipynb)
116
- [![ARM JupyterHub](https://img.shields.io/static/v1?label=launch%20in&logo=jupyter&color=lightblue&message=ARM+JupyterHub)](https://jupyterhub.arm.gov/hub/user-redirect/git-pull?repo=https%3A//github.com/open-atmos/PyPartMC&branch=main&urlPath=)
117
- - Cloud parcel example featuring supersaturation-evolution-coupled CCN activation and drop growth:
118
- [![View notebook](https://img.shields.io/static/v1?label=render%20on&logo=github&color=87ce3e&message=GitHub)](https://github.com/open-atmos/PyPartMC/blob/main/examples/cloud_parcel.ipynb)
119
- [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/open-atmos/PyPartMC/blob/main/examples/cloud_parcel.ipynb)
120
- [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/open-atmos/PyPartMC.git/main?urlpath=lab/tree/examples/cloud_parcel.ipynb)
121
- [![ARM JupyterHub](https://img.shields.io/static/v1?label=launch%20in&logo=jupyter&color=lightblue&message=ARM+JupyterHub)](https://jupyterhub.arm.gov/hub/user-redirect/git-pull?repo=https%3A//github.com/open-atmos/PyPartMC&branch=main&urlPath=)
122
- - Coagulation Model Intercomparison with PySDM, Droplets.jl:
123
- [![View notebook](https://img.shields.io/static/v1?label=render%20on&logo=github&color=87ce3e&message=GitHub)](https://github.com/open-atmos//PyPartMC/blob/main/examples/additive_coag_comparison.ipynb)
124
- [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/open-atmos/PyPartMC/blob/main/examples/additive_coag_comparison.ipynb)
125
- [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/open-atmos/PyPartMC.git/main?urlpath=lab/tree/examples/additive_coag_comparison.ipynb)
126
- [![ARM JupyterHub](https://img.shields.io/static/v1?label=launch%20in&logo=jupyter&color=lightblue&message=ARM+JupyterHub)](https://jupyterhub.arm.gov/hub/user-redirect/git-pull?repo=https%3A//github.com/open-atmos/PyPartMC&branch=main&urlPath=)
127
-
128
- ## Features
129
-
130
- - works on Linux, macOS and Windows (compatibility assured with [CI builds](https://github.com/open-atmos/PyPartMC/blob/main/.github/workflows/tests.yml))
131
- - hassle-free installation using `pip` (prior PartMC installation **not needed**)
132
- - works out of the box on [mybinder.org](https://mybinder.org/), [Google Colab](colab.research.google.com/) and alike
133
- - ships with [a set of examples](https://github.com/open-atmos/PyPartMC/tree/main/examples) maintained in a form of Jupyter notebooks
134
- - Pythonic API (but retaining PartMC jargon) incl. Python GC deallocation of Fortran objects
135
- - specification of parameters using native Python datatypes (lists, dicts) in place of PartMC spec files
136
- - code snippets in README depicting how to use PyPartMC from Julia and Matlab (also executed on CI)
137
- - auto-generated [API docs on the web](https://open-atmos.github.io/PyPartMC/)
138
- - support for [de]serialization of selected wrapped structures using JSON
139
- - based on [unmodified PartMC code](https://github.com/open-atmos/PyPartMC/tree/main/gitmodules)
140
- - does not use or require shell or any pre-installed libraries
141
- - aiming at 100% [unit test coverage](https://github.com/open-atmos/PyPartMC/tree/main/tests)
142
-
143
- ## Usage examples
144
-
145
- The listings below depict how the identical task of randomly sampling particles from an aerosol size distribution in PartMC can be
146
- done in different programming languages.
147
-
148
- For a Fortran equivalent of the Python, Julia and Matlab programs below, see the [`readme_fortran` folder](https://github.com/open-atmos/PyPartMC/tree/main/readme_fortran).
149
-
150
- #### Python
151
-
152
- ```Python
153
- import numpy as np
154
-
155
- import PyPartMC as ppmc
156
- from PyPartMC import si
157
-
158
- aero_data = ppmc.AeroData((
159
- # [density, ions in solution, molecular weight, kappa]
160
- {"OC": [1000 *si.kg/si.m**3, 0, 1e-3 *si.kg/si.mol, 0.001]},
161
- {"BC": [1800 *si.kg/si.m**3, 0, 1e-3 *si.kg/si.mol, 0]},
162
- ))
163
-
164
- aero_dist = ppmc.AeroDist(
165
- aero_data,
166
- [{
167
- "cooking": {
168
- "mass_frac": [{"OC": [1]}],
169
- "diam_type": "geometric",
170
- "mode_type": "log_normal",
171
- "num_conc": 3200 / si.cm**3,
172
- "geom_mean_diam": 8.64 * si.nm,
173
- "log10_geom_std_dev": 0.28,
174
- }
175
- },
176
- {
177
- "diesel": {
178
- "mass_frac": [{"OC": [0.3]}, {"BC": [0.7]}],
179
- "diam_type": "geometric",
180
- "mode_type": "log_normal",
181
- "num_conc": 2900 / si.cm**3,
182
- "geom_mean_diam": 50 * si.nm,
183
- "log10_geom_std_dev": 0.24,
184
- }
185
- }],
186
- )
187
-
188
- n_part = 100
189
- aero_state = ppmc.AeroState(aero_data, n_part, "nummass_source")
190
- aero_state.dist_sample(aero_dist)
191
- print(np.dot(aero_state.masses(), aero_state.num_concs), "# kg/m3")
192
- ```
193
-
194
- #### Julia (using [PyCall.jl](https://github.com/JuliaPy/PyCall.jl))
195
- ```Julia
196
- using Pkg
197
- Pkg.add("PyCall")
198
-
199
- using PyCall
200
- ppmc = pyimport("PyPartMC")
201
- si = ppmc["si"]
202
-
203
- aero_data = ppmc.AeroData((
204
- # (density, ions in solution, molecular weight, kappa)
205
- Dict("OC"=>(1000 * si.kg/si.m^3, 0, 1e-3 * si.kg/si.mol, 0.001)),
206
- Dict("BC"=>(1800 * si.kg/si.m^3, 0, 1e-3 * si.kg/si.mol, 0))
207
- ))
208
-
209
- aero_dist = ppmc.AeroDist(aero_data, (
210
- Dict(
211
- "cooking" => Dict(
212
- "mass_frac" => (Dict("OC" => (1,)),),
213
- "diam_type" => "geometric",
214
- "mode_type" => "log_normal",
215
- "num_conc" => 3200 / si.cm^3,
216
- "geom_mean_diam" => 8.64 * si.nm,
217
- "log10_geom_std_dev" => .28,
218
- )
219
- ),
220
- Dict(
221
- "diesel" => Dict(
222
- "mass_frac" => (Dict("OC" => (.3,)), Dict("BC" => (.7,))),
223
- "diam_type" => "geometric",
224
- "mode_type" => "log_normal",
225
- "num_conc" => 2900 / si.cm^3,
226
- "geom_mean_diam" => 50 * si.nm,
227
- "log10_geom_std_dev" => .24,
228
- )
229
- )
230
- ))
231
-
232
- n_part = 100
233
- aero_state = ppmc.AeroState(aero_data, n_part, "nummass_source")
234
- aero_state.dist_sample(aero_dist)
235
- print(aero_state.masses()'aero_state.num_concs, "# kg/m3")
236
- ```
237
-
238
- #### Matlab (using [Matlab's built-in Python interface](https://www.mathworks.com/help/matlab/python-language.html))
239
-
240
- notes (see the [PyPartMC Matlab CI workflow](https://github.com/open-atmos/PyPartMC/blob/main/.github/workflows/readme_listings.yml) for an example on how to achieve it on Ubuntu 20):
241
- - Matlab ships with convenience copies of C, C++ and Fortran runtime libraries which are `dlopened()` by default; one way to make PyPartMC OK with it is to [pip-]install by compiling from source using the very same version of GCC that Matlab borrowed these libraries from (e.g., [GCC 9 for Matlab R2022a, etc](https://www.mathworks.com/support/requirements/supported-compilers-linux.html));
242
- - Matlab needs to [use the same Python interpretter/venv](https://www.mathworks.com/support/requirements/python-compatibility.html) as the pip invocation used to install PyPartMC;
243
- - a single-line `pybind11_builtins.py` file with just `pybind11_type=type` inside needs to be placed within Matlab's `PYTHONPATH` to sort out a [Matlab-pybind11 incompatibility](https://github.com/pybind/pybind11/issues/3945).
244
-
245
- ````Matlab
246
- ppmc = py.importlib.import_module('PyPartMC');
247
- si = py.importlib.import_module('PyPartMC').si;
248
-
249
- aero_data = ppmc.AeroData(py.tuple({ ...
250
- py.dict(pyargs("OC", py.tuple({1000 * si.kg/si.m^3, 0, 1e-3 * si.kg/si.mol, 0.001}))), ...
251
- py.dict(pyargs("BC", py.tuple({1800 * si.kg/si.m^3, 0, 1e-3 * si.kg/si.mol, 0}))) ...
252
- }));
253
-
254
- aero_dist = ppmc.AeroDist(aero_data, py.tuple({ ...
255
- py.dict(pyargs( ...
256
- "cooking", py.dict(pyargs( ...
257
- "mass_frac", py.tuple({py.dict(pyargs("OC", py.tuple({1})))}), ...
258
- "diam_type", "geometric", ...
259
- "mode_type", "log_normal", ...
260
- "num_conc", 3200 / si.cm^3, ...
261
- "geom_mean_diam", 8.64 * si.nm, ...
262
- "log10_geom_std_dev", .28 ...
263
- )) ...
264
- )), ...
265
- py.dict(pyargs( ...
266
- "diesel", py.dict(pyargs( ...
267
- "mass_frac", py.tuple({ ...
268
- py.dict(pyargs("OC", py.tuple({.3}))), ...
269
- py.dict(pyargs("BC", py.tuple({.7}))), ...
270
- }), ...
271
- "diam_type", "geometric", ...
272
- "mode_type", "log_normal", ...
273
- "num_conc", 2900 / si.cm^3, ...
274
- "geom_mean_diam", 50 * si.nm, ...
275
- "log10_geom_std_dev", .24 ...
276
- )) ...
277
- )) ...
278
- }));
279
-
280
- n_part = 100;
281
- aero_state = ppmc.AeroState(aero_data, n_part, "nummass_source");
282
- aero_state.dist_sample(aero_dist);
283
- masses = cell(aero_state.masses());
284
- num_concs = cell(aero_state.num_concs);
285
- fprintf('%g # kg/m3\n', dot([masses{:}], [num_concs{:}]))
286
- ````
287
-
288
- #### usage in other projects
289
-
290
- PyPartMC is used within the [test workflow of the PySDM project](https://github.com/atmos-cloud-sim-uj/PySDM/tree/main/tests/smoke_tests/box/partmc).
291
-
292
- ## Other packages with relevant feature scope
293
-
294
- - [aerosolGDEFoam](https://openaerosol.sourceforge.io/): OpenFOAM CFD-coupled aerosol dynamics including nucleation, coagulation, and surface growth
295
- - [AIOMFAC and AIOMFAC-web](http://www.aiomfac.caltech.edu/): Fortran-implemented aerosol thermodynamic model for calculation of activity coefficients in organic-inorganic mixtures – from simple binary solutions to complex multicomponent systems
296
- - [DustPy](https://stammler.github.io/dustpy/): Python package for modelling dust evolution in protoplanetary disks (differences: focus on astrophysical applications vs. atmospheric aerosol)
297
- - [multilayerpy](https://github.com/tintin554/multilayerpy): kinetic multi-layer model for aerosol particles and films
298
- - [PyBox](https://pybox.readthedocs.io): aerosol simulation model featuring gas and particle chamistry (differences: PyBox focuses on chemical mechanisms; PyPartMC is an interface to PartMC which focuses on physics - e.g., collisions of aerosol particles - while chemical processes are handled with external software, e.g., CAMP or MOSAIC)
299
- - [PyCHAM](https://github.com/simonom/PyCHAM): CHemistry with Aerosol Microphysics in Python Box Model for modelling of indoor environments, including aerosol chambers
300
- - [PySDM](https://open-atmos.github.io/PySDM): particle-based Monte-Carlo aerosol-cloud simulation package (differences: PySDM focuses on growth and breakup processes relevant to cloud droplets; PyPartMC focuses on processes relevant to air pollutants and their chemical and physical transformations)
301
- - [SSH-aerosol](https://github.com/sshaerosol/ssh-aerosol): C++/Fortran package for simulating evolution of primary and secondary atmospheric aerosols
302
-
303
- ## FAQ
304
- - Q: How to install PyPartMC with MOSAIC enabled?
305
- A: Installation can be done using `pip`, however, `pip` needs to be instructed not to use binary packages available at pypi.org but rather to compile from source (pip will download the source from pip.org), and the path to compiled MOSAIC library needs to be provided at compile-time; the following command should convey it:
306
- ```bash
307
- MOSAIC_HOME=<<PATH_TO_MOSAIC_LIB>> pip install --force-reinstall --no-binary=PyPartMC PyPartMC
308
- ```
309
-
310
- - Q: Why `pip install PyPartMC` triggers compilation on my brand new Apple machine, while it quickly downloads and installs binary packages when executed on older Macs, Windows or Linux?
311
- A: We are providing binary wheels on PyPI for Apple-silicon (arm64) machines for selected macOS version made available by Github. In case the macOS version you are using is newer, compilation from source is triggered.
312
-
313
- - Q: Why some of the constructors expect data to be passed as **lists of single-entry dictionaries** instead of multi-element dictionaries?
314
- A: This is intentional and related with PartMC relying on the order of elements within spec-file input; while Python dictionaries preserve ordering (insertion order), JSON format does not, and we intend to make these data structures safe to be [de]serialized using JSON.
315
-
316
- - Q: How to check the version of PartMC that PyPartMC was compiled against?
317
- A: Version numbers of compile-time dependencies of PyPartMC, including PartMC, can be accessed as follows:
318
- ```Python
319
- import PyPartMC
320
- PyPartMC.__versions_of_build_time_dependencies__['PartMC']
321
- ```
322
-
323
- - Q: Why m4 and perl are required at compile time?
324
- A: PyPartMC includes parts of netCDF and HDF5 codebases which depend on m4 and perl, respectively, for generating source files before compilation.
325
-
326
- ## Troubleshooting
327
-
328
- #### Common installation issues
329
- ```
330
- error: [Errno 2] No such file or directory: 'cmake'
331
- ```
332
- Try rerunning after installing CMake, e.g., using `apt-get install cmake` (Ubuntu/Debian), `brew install cmake` (homebrew on macOS) or using [MSYS2](https://www.msys2.org/docs/cmake/) on Windows.
333
-
334
- ```
335
- No CMAKE_Fortran_COMPILER could be found.
336
- ```
337
- Try installing a Fortran compiler (e.g., `brew reinstall gcc` with Homebrew on macOS or using [MSYS2](https://packages.msys2.org/package/mingw-w64-x86_64-gcc-fortran?repo=mingw64) on Windows).
338
-
339
- ```
340
- Could not find NC_M4 using the following names: m4, m4.exe
341
- ```
342
- Try installing `m4` (e.g., using [MSYS2](https://packages.msys2.org/package/m4?repo=msys&variant=x86_64) on Windows).
343
-
344
- ## Acknowledgement and citations
345
-
346
- We would greatly appreciate citation of the PartMC model description paper (Riemer et al., 2009)
347
- and the PyPartMC description paper (D’Aquino et al., 2024) if PyPartMC was used in your study.
348
- The citations are:
349
- - Riemer, N., M. West, R. A. Zaveri, R. C. Easter: Simulating the evolution of soot
350
- mixing-state with a particle-resolved aerosol model
351
- J. Geophys. Res., 114, D09202, 2009, DOI: [10.1029/2008JD011073](https://doi.org/10.1029/2008JD011073)
352
- - D’Aquino, Z., S. Arabas, J. H. Curtis, A. Vaishnav, N. Riemer, M. West: PyPartMC: A
353
- pythonic interfact to a particle-resolved, Monte Carlo aerosol simulation framework
354
- SoftwareX, 25, 101613, 2024, DOI: [10.1016/j.softx.2023.101613](https://doi.org/10.1016/j.softx.2023.101613)
355
-
356
- The following paragraph provides a more substantial description of PartMC (text released into the public domain and can be freely copied by anyone for any purpose):
357
-
358
- > PartMC is a stochastic, particle-resolved aerosol box model. It tracks the
359
- composition of many computational particles (10<sup>4</sup> to 10<sup>6</sup>) within a well-mixed air
360
- volume, each represented by a composition vector that evolves based on physical
361
- and chemical processes. The physical processes—including Brownian coagulation,
362
- new particle formation, emissions, dilution, and deposition—are simulated using a
363
- stochastic Monte Carlo approach via a Poisson process while chemical processes are
364
- simulated deterministically for each computational particle. The weighted flow
365
- algorithm (DeVille, Riemer, and West, 2011, 2019) enhances efficiency and reduces
366
- ensemble variance. Detailed numerical methods are described in Riemer et al.
367
- (2009), DeVille et al. (2011, 2019), and Curtis et al. (2016). PartMC is open-source
368
- under the GNU GPL v2 and available at
369
- [github.com/compdyn/partmc](https://github.com/compdyn/partmc).
370
- >
371
- > References:
372
- > - Curtis, J. H., M. D. Michelotti, N. Riemer, M. T. Heath, M. West: Accelerated
373
- simulation of stochastic particle removal processes in particle-resolved aerosol
374
- models, J. Computational Phys., 322, 21-32, 2016, DOI: [10.1016/j.jcp.2016.06.029](https://doi.org/10.1016/j.jcp.2016.06.029)
375
- > - DeVille, L., N. Riemer, M. West, Convergence of a generalized weighted flow
376
- algorithm for stochastic particle coagulation, J. Computational Dynamics, 6, 69-94,
377
- 2019, DOI: [10.3934/jcd.2019003](https://doi.org/10.3934/jcd.2019003)
378
- > - DeVille, R. E. L., N. Riemer, M. West, The Weighted Flow Algorithm (WFA) for
379
- stochastic particle coagulation, J. Computational Phys., 230, 8427-8451, 2011,
380
- DOI: [10.1016/j.jcp.2011.07.027](https://doi.org/10.1016/j.jcp.2011.07.027)
381
- > - Riemer, N., M. West, R. A. Zaveri, R. C. Easter, Simulating the evolution of soot
382
- mixing-state with a particle-resolved aerosol model, J. Geophys. Res., 114, D09202,
383
- 2009., DOI: [10.1029/2008JD011073](https://doi.org/10.1029/2008JD011073)
384
-
385
- ## Credits
386
-
387
- #### PyPartMC:
388
-
389
- authors: [PyPartMC developers](https://github.com/open-atmos/PyPartMC/graphs/contributors)
390
- funding: [US Department of Energy Atmospheric System Research programme](https://asr.science.energy.gov/), [Polish National Science Centre](https://ncn.gov.pl/en)
391
- copyright: [University of Illinois at Urbana-Champaign](https://atmos.illinois.edu/)
392
- licence: [GPL v3](https://www.gnu.org/licenses/gpl-3.0.en.html)
393
-
394
- #### PartMC:
395
- authors: [Nicole Riemer](https://www.atmos.uiuc.edu/~nriemer/), [Matthew West](https://lagrange.mechse.illinois.edu/mwest/), [Jeff Curtis](https://publish.illinois.edu/jcurtis2/) et al.
396
- licence: [GPL v2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html) or later
397
-
1
+ Metadata-Version: 2.4
2
+ Name: PyPartMC
3
+ Version: 2.0.0rc4
4
+ Summary: Python interface to PartMC
5
+ Author-Email: "https://github.com/open-atmos/PyPartMC/graphs/contributors" <nriemer@illinois.edu>
6
+ License-Expression: GPL-3.0
7
+ Project-URL: Documentation, https://open-atmos.github.io/PyPartMC
8
+ Project-URL: Source, https://github.com/open-atmos/PyPartMC/
9
+ Project-URL: Tracker, https://github.com/open-atmos/PyPartMC/issues
10
+ Requires-Python: >=3.8
11
+ Requires-Dist: numpy
12
+ Requires-Dist: nanobind
13
+ Provides-Extra: tests
14
+ Requires-Dist: pytest; extra == "tests"
15
+ Requires-Dist: pytest-order; extra == "tests"
16
+ Provides-Extra: examples
17
+ Requires-Dist: matplotlib!=3.10.0; extra == "examples"
18
+ Requires-Dist: ipywidgets; extra == "examples"
19
+ Requires-Dist: voila; extra == "examples"
20
+ Requires-Dist: open-atmos-jupyter-utils; extra == "examples"
21
+ Requires-Dist: PySDM; extra == "examples"
22
+ Requires-Dist: PyMieScatt; extra == "examples"
23
+ Requires-Dist: SciPy; extra == "examples"
24
+ Requires-Dist: dustpy; platform_system != "Windows" and extra == "examples"
25
+ Description-Content-Type: text/markdown
26
+
27
+ ![logo](https://raw.githubusercontent.com/wiki/open-atmos/PyPartMC/logo.svg)
28
+
29
+ # PyPartMC
30
+
31
+ PyPartMC is a Python interface to [PartMC](https://lagrange.mechse.illinois.edu/partmc/),
32
+ a particle-resolved Monte-Carlo code for atmospheric aerosol simulation.
33
+ Development of PyPartMC has been intended to remove limitations to the use of Fortran-implemented PartMC.
34
+ PyPartMC facilitates the dissemination of computational research results by streamlining independent execution
35
+ of PartMC simulations (also during peer-review processes).
36
+ Additionally, the ability to easily package examples, simple simulations, and results in a web-based notebook
37
+ allows PyPartMC to support the efforts of many members of the scientific community, including researchers,
38
+ instructors, and students, with nominal software and hardware requirements.
39
+
40
+ Documentation of PyPartMC is hosted at https://open-atmos.github.io/PyPartMC.
41
+ PyPartMC is implemented in C++ and it also constitutes a C++ API to the PartMC Fortran internals.
42
+ The Python API can facilitate using PartMC from other environments - see, e.g., Julia and Matlab examples below.
43
+
44
+ For an outline of the project, rationale, architecture, and features, refer to: [D'Aquino et al., 2024 (SoftwareX)](https://doi.org/10.1016/j.softx.2023.101613) (please cite if PyPartMC is used in your research).
45
+ For a list of talks and other relevant resources, please see [project Wiki](https://github.com/open-atmos/PyPartMC/wiki/).
46
+ If interested in contributing to PyPartMC, please have a look a the [notes for developers](https://github.com/open-atmos/PyPartMC/tree/main/CONTRIBUTING.md).
47
+
48
+ [![US Funding](https://img.shields.io/static/v1?label=US%20DOE%20Funding%20by&color=267c32&message=ASR&logoWidth=25&logo=image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAQCAMAAAA25D/gAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAASFBMVEVOTXyyIjRDQnNZWINZWITtzdFUU4BVVIFVVYHWiZM9PG/KZnNXVoJaWYT67/FKSXhgX4hgX4lcW4VbWoX03uHQeIN2VXj///9pZChlAAAAAWJLR0QXC9aYjwAAAAd0SU1FB+EICRMGJV+KCCQAAABdSURBVBjThdBJDoAgEETRkkkZBBX0/kd11QTTpH1/STqpAAwWBkobSlkGbt0o5xmEfqxDZJB2Q6XMoBwnVSbTylWp0hi42rmbwTOYPDfR5Kc+07IIUQQvghX9THsBHcES8/SiF0kAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTctMDgtMDlUMTk6MDY6MzcrMDA6MDCX1tBgAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE3LTA4LTA5VDE5OjA2OjM3KzAwOjAw5oto3AAAAABJRU5ErkJggg==)](https://asr.science.energy.gov/) [![PL Funding](https://img.shields.io/static/v1?label=PL%20Funding%20by&color=d21132&message=NCN&logoWidth=25&logo=image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAABmJLR0QA/wD/AP+gvaeTAAAAKUlEQVQ4jWP8////fwYqAiZqGjZqIHUAy4dJS6lqIOMdEZvRZDPcDQQAb3cIaY1Sbi4AAAAASUVORK5CYII=)](https://www.ncn.gov.pl/?language=en)
49
+
50
+ [![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0.html)
51
+ [![Copyright](https://img.shields.io/static/v1?label=Copyright&color=249fe2&message=UIUC&)](https://atmos.illinois.edu/)
52
+ [![tests+pypi](https://github.com/open-atmos/PyPartMC/actions/workflows/buildwheels.yml/badge.svg)](https://github.com/open-atmos/PyPartMC/actions/workflows/buildwheels.yml)
53
+ [![API docs](https://shields.mitmproxy.org/badge/docs-pdoc.dev-brightgreen.svg)](https://open-atmos.github.io/PyPartMC/)
54
+ [![codecov](https://codecov.io/gh/open-atmos/PyPartMC/graph/badge.svg?token=27IK9ZIQXE)](https://codecov.io/gh/open-atmos/PyPartMC)
55
+ [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.7662635.svg)](https://doi.org/10.5281/zenodo.7662635)
56
+ [![PyPI version](https://badge.fury.io/py/PyPartMC.svg)](https://pypi.org/p/PyPartMC)
57
+ [![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active)
58
+ [![pyOpenSci Peer-Reviewed](https://pyopensci.org/badges/peer-reviewed.svg)](https://github.com/pyOpenSci/software-review/issues/179)
59
+
60
+ [![Python 3](https://img.shields.io/static/v1?label=Python&logo=Python&color=3776AB&message=3)](https://www.python.org/)
61
+ [![Linux OK](https://img.shields.io/static/v1?label=Linux&logo=Linux&color=yellow&message=%E2%9C%93)](https://en.wikipedia.org/wiki/Linux)
62
+ [![macOS OK](https://img.shields.io/static/v1?label=macOS&logo=Apple&color=silver&message=%E2%9C%93)](https://en.wikipedia.org/wiki/macOS)
63
+ [![Windows OK](https://img.shields.io/static/v1?label=Windows&logo=Windows&color=white&message=%E2%9C%93)](https://en.wikipedia.org/wiki/Windows)
64
+ [![Jupyter](https://img.shields.io/static/v1?label=Jupyter&logo=Jupyter&color=f37626&message=%E2%9C%93)](https://jupyter.org/)
65
+
66
+ ## Installation
67
+
68
+ ### Using the command-line `pip` tool (also applies to conda environments)
69
+ ```bash
70
+ pip install PyPartMC
71
+ ```
72
+
73
+ Note that, depending on the environment (OS, hardware, Python version), the pip-install invocation
74
+ may either trigger a download of a pre-compiled binary, or trigger compilation of PyPartMC.
75
+ In the latter case, a Fortran compiler and some development tools includiong CMake, m4 and perl
76
+ are required (while all non-Python dependencies are included in the PyPartMC source archive).
77
+ In both cases, all Python dependencies will be resolved by pip.
78
+
79
+ ### In a Jupyter notebook cell (also on Colab or jupyter-hub instances)
80
+
81
+ ```python
82
+ ! pip install PyPartMC
83
+ import PyPartMC
84
+ ```
85
+
86
+ #### Jupyter notebooks with examples
87
+ Note: clicking the badges below redirects to cloud-computing platforms. The mybinder.org links allow anonymous execution, Google Colab requires logging in with a Google account, ARM JupyerHub requires logging in with an ARM account (and directing Jupyter to a particular notebook within the `examples` folder).
88
+
89
+ The example notebooks feature additional dependencies that can be installed with:
90
+ ```bash
91
+ pip install PyPartMC[examples]
92
+ ```
93
+
94
+ - Urban plume scenario demo (as in [PartMC](https://github.com/compdyn/partmc/tree/master/scenarios/1_urban_plume)):
95
+ [![View notebook](https://img.shields.io/static/v1?label=render%20on&logo=github&color=87ce3e&message=GitHub)](https://github.com/open-atmos/PyPartMC/blob/main/examples/particle_simulation.ipynb)
96
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/open-atmos/PyPartMC/blob/main/examples/particle_simulation.ipynb)
97
+ [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/open-atmos/PyPartMC.git/main?urlpath=lab/tree/examples/particle_simulation.ipynb)
98
+ [![ARM JupyterHub](https://img.shields.io/static/v1?label=launch%20in&logo=jupyter&color=lightblue&message=ARM+JupyterHub)](https://jupyterhub.arm.gov/hub/user-redirect/git-pull?repo=https%3A//github.com/open-atmos/PyPartMC&branch=main&urlPath=)
99
+ - Dry-Wet Particle Size Equilibration with PartMC and PySDM:
100
+ [![View notebook](https://img.shields.io/static/v1?label=render%20on&logo=github&color=87ce3e&message=GitHub)](https://github.com/open-atmos/PyPartMC/blob/main/examples/lognorm_ex.ipynb)
101
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/open-atmos/PyPartMC/blob/main/examples/lognorm_ex.ipynb)
102
+ [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/open-atmos/PyPartMC.git/main?urlpath=lab/tree/examples/lognorm_ex.ipynb)
103
+ [![ARM JupyterHub](https://img.shields.io/static/v1?label=launch%20in&logo=jupyter&color=lightblue&message=ARM+JupyterHub)](https://jupyterhub.arm.gov/hub/user-redirect/git-pull?repo=https%3A//github.com/open-atmos/PyPartMC&branch=main&urlPath=)
104
+ [![Voila](https://img.shields.io/static/v1?label=Voil%C3%A0&logo=jupyter&color=teal&message=web+app)](https://mybinder.org/v2/gh/open-atmos/PyPartMC/main?urlpath=voila%2Frender%2Fexamples%2Flognorm_ex.ipynb)
105
+ - Simulation output processing example (loading from netCDF files using PyPartMC):
106
+ [![View notebook](https://img.shields.io/static/v1?label=render%20on&logo=github&color=87ce3e&message=GitHub)](https://github.com/open-atmos/PyPartMC/blob/main/examples/process_simulation_output.ipynb)
107
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/open-atmos/PyPartMC/blob/main/examples/process_simulation_output.ipynb)
108
+ [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/open-atmos/PyPartMC.git/main?urlpath=lab/tree/examples/process_simulation_output.ipynb)
109
+ [![ARM JupyterHub](https://img.shields.io/static/v1?label=launch%20in&logo=jupyter&color=lightblue&message=ARM+JupyterHub)](https://jupyterhub.arm.gov/hub/user-redirect/git-pull?repo=https%3A//github.com/open-atmos/PyPartMC&branch=main&urlPath=)
110
+ - Optical properties calculation using external Python package ([PyMieScatt](https://pymiescatt.readthedocs.io/en/latest/)):
111
+ [![View notebook](https://img.shields.io/static/v1?label=render%20on&logo=github&color=87ce3e&message=GitHub)](https://github.com/open-atmos/PyPartMC/blob/main/examples/mie_optical.ipynb)
112
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/open-atmos/PyPartMC/blob/main/examples/mie_optical.ipynb)
113
+ [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/open-atmos/PyPartMC.git/main?urlpath=lab/tree/examples/mie_optical.ipynb)
114
+ [![ARM JupyterHub](https://img.shields.io/static/v1?label=launch%20in&logo=jupyter&color=lightblue&message=ARM+JupyterHub)](https://jupyterhub.arm.gov/hub/user-redirect/git-pull?repo=https%3A//github.com/open-atmos/PyPartMC&branch=main&urlPath=)
115
+ - Cloud parcel example featuring supersaturation-evolution-coupled CCN activation and drop growth:
116
+ [![View notebook](https://img.shields.io/static/v1?label=render%20on&logo=github&color=87ce3e&message=GitHub)](https://github.com/open-atmos/PyPartMC/blob/main/examples/cloud_parcel.ipynb)
117
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/open-atmos/PyPartMC/blob/main/examples/cloud_parcel.ipynb)
118
+ [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/open-atmos/PyPartMC.git/main?urlpath=lab/tree/examples/cloud_parcel.ipynb)
119
+ [![ARM JupyterHub](https://img.shields.io/static/v1?label=launch%20in&logo=jupyter&color=lightblue&message=ARM+JupyterHub)](https://jupyterhub.arm.gov/hub/user-redirect/git-pull?repo=https%3A//github.com/open-atmos/PyPartMC&branch=main&urlPath=)
120
+ - Coagulation model intercomparison for additive (Golovin) kernel with: PyPartMC, [PySDM](https://open-atmos.github.io/PySDM), [Droplets.jl](https://github.com/emmacware/droplets.jl) and [dustpy](https://stammler.github.io/dustpy/):
121
+ [![View notebook](https://img.shields.io/static/v1?label=render%20on&logo=github&color=87ce3e&message=GitHub)](https://github.com/open-atmos/PyPartMC/blob/main/examples/additive_coag_comparison.ipynb)
122
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/open-atmos/PyPartMC/blob/main/examples/additive_coag_comparison.ipynb)
123
+ [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/open-atmos/PyPartMC.git/main?urlpath=lab/tree/examples/additive_coag_comparison.ipynb)
124
+ [![ARM JupyterHub](https://img.shields.io/static/v1?label=launch%20in&logo=jupyter&color=lightblue&message=ARM+JupyterHub)](https://jupyterhub.arm.gov/hub/user-redirect/git-pull?repo=https%3A//github.com/open-atmos/PyPartMC&branch=main&urlPath=)
125
+ - Particle simulation with multiphase chemistry handled using [CAMP](https://doi.org/10.5194/gmd-15-3663-2022) (without coagulation):
126
+ [![View notebook](https://img.shields.io/static/v1?label=render%20on&logo=github&color=87ce3e&message=GitHub)](https://github.com/open-atmos/PyPartMC/blob/main/examples/particle_simulation_with_camp.ipynb.ipynb)
127
+ [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/open-atmos/PyPartMC/blob/main/examples/particle_simulation_with_camp.ipynb)
128
+ [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/open-atmos/PyPartMC.git/main?urlpath=lab/tree/examples/particle_simulation_with_camp.ipynb)
129
+ [![ARM JupyterHub](https://img.shields.io/static/v1?label=launch%20in&logo=jupyter&color=lightblue&message=ARM+JupyterHub)](https://jupyterhub.arm.gov/hub/user-redirect/git-pull?repo=https%3A//github.com/open-atmos/PyPartMC&branch=main&urlPath=)
130
+
131
+ ## Features
132
+
133
+ - works on Linux, macOS and Windows (compatibility assured with [CI builds](https://github.com/open-atmos/PyPartMC/blob/main/.github/workflows/buildwheels.yml))
134
+ - hassle-free installation using `pip` (prior PartMC installation **not needed**)
135
+ - works out of the box on [mybinder.org](https://mybinder.org/), [Google Colab](colab.research.google.com/) and alike
136
+ - ships with [a set of examples](https://github.com/open-atmos/PyPartMC/tree/main/examples) maintained in a form of Jupyter notebooks
137
+ - Pythonic API (but retaining PartMC jargon) incl. Python GC deallocation of Fortran objects
138
+ - specification of parameters using native Python datatypes (lists, dicts) in place of PartMC spec files
139
+ - code snippets in README depicting how to use PyPartMC from Julia and Matlab (also executed on CI)
140
+ - auto-generated [API docs on the web](https://open-atmos.github.io/PyPartMC/)
141
+ - support for [de]serialization of selected wrapped structures using JSON
142
+ - based on [unmodified PartMC code](https://github.com/open-atmos/PyPartMC/tree/main/gitmodules)
143
+ - does not use or require shell or any pre-installed libraries
144
+ - aiming at 100% [unit test coverage](https://github.com/open-atmos/PyPartMC/tree/main/tests)
145
+
146
+ ## Usage examples
147
+
148
+ The listings below depict how the identical task of randomly sampling particles from an aerosol size distribution in PartMC can be
149
+ done in different programming languages.
150
+
151
+ For a Fortran equivalent of the Python, Julia and Matlab programs below, see the [`readme_fortran` folder](https://github.com/open-atmos/PyPartMC/tree/main/readme_fortran).
152
+
153
+ #### Python
154
+
155
+ ```Python
156
+ import numpy as np
157
+
158
+ import PyPartMC as ppmc
159
+ from PyPartMC import si
160
+
161
+ aero_data = ppmc.AeroData((
162
+ # [density, ions in solution, molecular weight, kappa]
163
+ {"OC": [1000 *si.kg/si.m**3, 0, 1e-3 *si.kg/si.mol, 0.001]},
164
+ {"BC": [1800 *si.kg/si.m**3, 0, 1e-3 *si.kg/si.mol, 0]},
165
+ ))
166
+
167
+ aero_dist = ppmc.AeroDist(
168
+ aero_data,
169
+ [{
170
+ "cooking": {
171
+ "mass_frac": [{"OC": [1]}],
172
+ "diam_type": "geometric",
173
+ "mode_type": "log_normal",
174
+ "num_conc": 3200 / si.cm**3,
175
+ "geom_mean_diam": 8.64 * si.nm,
176
+ "log10_geom_std_dev": 0.28,
177
+ },
178
+ "diesel": {
179
+ "mass_frac": [{"OC": [0.3]}, {"BC": [0.7]}],
180
+ "diam_type": "geometric",
181
+ "mode_type": "log_normal",
182
+ "num_conc": 2900 / si.cm**3,
183
+ "geom_mean_diam": 50 * si.nm,
184
+ "log10_geom_std_dev": 0.24,
185
+ }
186
+ }],
187
+ )
188
+
189
+ n_part = 100
190
+ aero_state = ppmc.AeroState(aero_data, n_part, "nummass_source")
191
+ aero_state.dist_sample(aero_dist)
192
+ print(np.dot(aero_state.masses(), aero_state.num_concs), "# kg/m3")
193
+ ```
194
+
195
+ #### Julia (using [PyCall.jl](https://github.com/JuliaPy/PyCall.jl))
196
+ ```Julia
197
+ using Pkg
198
+ Pkg.add("PyCall")
199
+
200
+ using PyCall
201
+ ppmc = pyimport("PyPartMC")
202
+ si = ppmc["si"]
203
+
204
+ aero_data = ppmc.AeroData((
205
+ # (density, ions in solution, molecular weight, kappa)
206
+ Dict("OC"=>(1000 * si.kg/si.m^3, 0, 1e-3 * si.kg/si.mol, 0.001)),
207
+ Dict("BC"=>(1800 * si.kg/si.m^3, 0, 1e-3 * si.kg/si.mol, 0))
208
+ ))
209
+
210
+ aero_dist = ppmc.AeroDist(aero_data, (
211
+ Dict(
212
+ "cooking" => Dict(
213
+ "mass_frac" => (Dict("OC" => (1,)),),
214
+ "diam_type" => "geometric",
215
+ "mode_type" => "log_normal",
216
+ "num_conc" => 3200 / si.cm^3,
217
+ "geom_mean_diam" => 8.64 * si.nm,
218
+ "log10_geom_std_dev" => .28,
219
+ ),
220
+ "diesel" => Dict(
221
+ "mass_frac" => (Dict("OC" => (.3,)), Dict("BC" => (.7,))),
222
+ "diam_type" => "geometric",
223
+ "mode_type" => "log_normal",
224
+ "num_conc" => 2900 / si.cm^3,
225
+ "geom_mean_diam" => 50 * si.nm,
226
+ "log10_geom_std_dev" => .24,
227
+ )
228
+ ),
229
+ ))
230
+
231
+ n_part = 100
232
+ aero_state = ppmc.AeroState(aero_data, n_part, "nummass_source")
233
+ aero_state.dist_sample(aero_dist)
234
+ print(aero_state.masses()'aero_state.num_concs, "# kg/m3")
235
+ ```
236
+
237
+ #### Matlab (using [Matlab's built-in Python interface](https://www.mathworks.com/help/matlab/python-language.html))
238
+
239
+ notes (see the [PyPartMC Matlab CI workflow](https://github.com/open-atmos/PyPartMC/blob/main/.github/workflows/readme_listings.yml) for an example on how to achieve it on Ubuntu 20):
240
+ - Matlab ships with convenience copies of C, C++ and Fortran runtime libraries which are `dlopened()` by default; one way to make PyPartMC OK with it is to [pip-]install by compiling from source using the very same version of GCC that Matlab borrowed these libraries from (e.g., [GCC 9 for Matlab R2022a, etc](https://www.mathworks.com/support/requirements/supported-compilers-linux.html));
241
+ - Matlab needs to [use the same Python interpretter/venv](https://www.mathworks.com/support/requirements/python-compatibility.html) as the pip invocation used to install PyPartMC;
242
+
243
+ ````Matlab
244
+ ppmc = py.importlib.import_module('PyPartMC');
245
+ si = py.importlib.import_module('PyPartMC').si;
246
+
247
+ aero_data = ppmc.AeroData(py.tuple({ ...
248
+ py.dict(pyargs("OC", py.tuple({1000 * si.kg/si.m^3, 0, 1e-3 * si.kg/si.mol, 0.001}))), ...
249
+ py.dict(pyargs("BC", py.tuple({1800 * si.kg/si.m^3, 0, 1e-3 * si.kg/si.mol, 0}))) ...
250
+ }));
251
+
252
+ aero_dist = ppmc.AeroDist(aero_data, py.tuple({ ...
253
+ py.dict(pyargs( ...
254
+ "cooking", py.dict(pyargs( ...
255
+ "mass_frac", py.tuple({py.dict(pyargs("OC", py.tuple({1})))}), ...
256
+ "diam_type", "geometric", ...
257
+ "mode_type", "log_normal", ...
258
+ "num_conc", 3200 / si.cm^3, ...
259
+ "geom_mean_diam", 8.64 * si.nm, ...
260
+ "log10_geom_std_dev", .28 ...
261
+ )), ...
262
+ "diesel", py.dict(pyargs( ...
263
+ "mass_frac", py.tuple({ ...
264
+ py.dict(pyargs("OC", py.tuple({.3}))), ...
265
+ py.dict(pyargs("BC", py.tuple({.7}))), ...
266
+ }), ...
267
+ "diam_type", "geometric", ...
268
+ "mode_type", "log_normal", ...
269
+ "num_conc", 2900 / si.cm^3, ...
270
+ "geom_mean_diam", 50 * si.nm, ...
271
+ "log10_geom_std_dev", .24 ...
272
+ )) ...
273
+ )) ...
274
+ }));
275
+
276
+ n_part = 100;
277
+ aero_state = ppmc.AeroState(aero_data, n_part, "nummass_source");
278
+ aero_state.dist_sample(aero_dist);
279
+ masses = cell(aero_state.masses());
280
+ num_concs = cell(aero_state.num_concs);
281
+ fprintf('%g # kg/m3\n', dot([masses{:}], [num_concs{:}]))
282
+ ````
283
+
284
+ #### usage in other projects
285
+
286
+ PyPartMC is used within the [test workflow of the PySDM project](https://github.com/atmos-cloud-sim-uj/PySDM/tree/main/tests/smoke_tests/box/partmc).
287
+
288
+ ## Other packages with relevant feature scope
289
+
290
+ - [aerosolGDEFoam](https://openaerosol.sourceforge.io/): OpenFOAM CFD-coupled aerosol dynamics including nucleation, coagulation, and surface growth
291
+ - [AIOMFAC and AIOMFAC-web](http://www.aiomfac.caltech.edu/): Fortran-implemented aerosol thermodynamic model for calculation of activity coefficients in organic-inorganic mixtures – from simple binary solutions to complex multicomponent systems
292
+ - [DustPy](https://stammler.github.io/dustpy/): Python package for modelling dust evolution in protoplanetary disks (differences: focus on astrophysical applications vs. atmospheric aerosol)
293
+ - [multilayerpy](https://github.com/tintin554/multilayerpy): kinetic multi-layer model for aerosol particles and films
294
+ - [PyBox](https://pybox.readthedocs.io): aerosol simulation model featuring gas and particle chamistry (differences: PyBox focuses on chemical mechanisms; PyPartMC is an interface to PartMC which focuses on physics - e.g., collisions of aerosol particles - while chemical processes are handled with external software, e.g., CAMP or MOSAIC)
295
+ - [PyCHAM](https://github.com/simonom/PyCHAM): CHemistry with Aerosol Microphysics in Python Box Model for modelling of indoor environments, including aerosol chambers
296
+ - [PySDM](https://open-atmos.github.io/PySDM): particle-based Monte-Carlo aerosol-cloud simulation package (differences: PySDM focuses on growth and breakup processes relevant to cloud droplets; PyPartMC focuses on processes relevant to air pollutants and their chemical and physical transformations)
297
+ - [SSH-aerosol](https://github.com/sshaerosol/ssh-aerosol): C++/Fortran package for simulating evolution of primary and secondary atmospheric aerosols
298
+
299
+ ## FAQ
300
+ - Q: How to install PyPartMC with MOSAIC enabled?
301
+ A: Installation can be done using `pip`, however, `pip` needs to be instructed not to use binary packages available at pypi.org but rather to compile from source (pip will download the source from pip.org), and the path to compiled MOSAIC library needs to be provided at compile-time; the following command should convey it:
302
+ ```bash
303
+ MOSAIC_HOME=<<PATH_TO_MOSAIC_LIB>> pip install --force-reinstall --no-binary=PyPartMC PyPartMC
304
+ ```
305
+
306
+ - Q: Why `pip install PyPartMC` triggers compilation on my brand new Apple machine, while it quickly downloads and installs binary packages when executed on older Macs, Windows or Linux?
307
+ A: We are providing binary wheels on PyPI for Apple-silicon (arm64) machines for selected macOS version made available by Github. In case the macOS version you are using is newer, compilation from source is triggered.
308
+
309
+ - Q: Why some of the constructors expect data to be passed as **lists of single-entry dictionaries** instead of multi-element dictionaries?
310
+ A: This is intentional and related with PartMC relying on the order of elements within spec-file input; while Python dictionaries preserve ordering (insertion order), JSON format does not, and we intend to make these data structures safe to be [de]serialized using JSON.
311
+
312
+ - Q: How to check the version of PartMC that PyPartMC was compiled against?
313
+ A: Version numbers of compile-time dependencies of PyPartMC, including PartMC, can be accessed as follows:
314
+ ```Python
315
+ import PyPartMC
316
+ PyPartMC.__versions_of_build_time_dependencies__['PartMC']
317
+ ```
318
+
319
+ - Q: Why m4 and perl are required at compile time?
320
+ A: PyPartMC includes parts of netCDF and HDF5 codebases which depend on m4 and perl, respectively, for generating source files before compilation.
321
+
322
+ ## Troubleshooting
323
+
324
+ #### Common installation issues
325
+ ```
326
+ error: [Errno 2] No such file or directory: 'cmake'
327
+ ```
328
+ Try rerunning after installing CMake, e.g., using `apt-get install cmake` (Ubuntu/Debian), `brew install cmake` (homebrew on macOS) or using [MSYS2](https://www.msys2.org/docs/cmake/) on Windows.
329
+
330
+ ```
331
+ No CMAKE_Fortran_COMPILER could be found.
332
+ ```
333
+ Try installing a Fortran compiler (e.g., `brew reinstall gcc` with Homebrew on macOS or using [MSYS2](https://packages.msys2.org/package/mingw-w64-x86_64-gcc-fortran?repo=mingw64) on Windows).
334
+
335
+ ```
336
+ Could not find NC_M4 using the following names: m4, m4.exe
337
+ ```
338
+ Try installing `m4` (e.g., using [MSYS2](https://packages.msys2.org/package/m4?repo=msys&variant=x86_64) on Windows).
339
+
340
+ ## Acknowledgement and citations
341
+
342
+ We would greatly appreciate citation of the PartMC model description paper (Riemer et al., 2009)
343
+ and the PyPartMC description paper (D’Aquino et al., 2024) if PyPartMC was used in your study.
344
+ The citations are:
345
+ - Riemer, N., M. West, R. A. Zaveri, R. C. Easter: Simulating the evolution of soot
346
+ mixing-state with a particle-resolved aerosol model
347
+ J. Geophys. Res., 114, D09202, 2009, DOI: [10.1029/2008JD011073](https://doi.org/10.1029/2008JD011073)
348
+ - D’Aquino, Z., S. Arabas, J. H. Curtis, A. Vaishnav, N. Riemer, M. West: PyPartMC: A
349
+ pythonic interfact to a particle-resolved, Monte Carlo aerosol simulation framework
350
+ SoftwareX, 25, 101613, 2024, DOI: [10.1016/j.softx.2023.101613](https://doi.org/10.1016/j.softx.2023.101613)
351
+
352
+ The following paragraph provides a more substantial description of PartMC (text released into the public domain and can be freely copied by anyone for any purpose):
353
+
354
+ > PartMC is a stochastic, particle-resolved aerosol box model. It tracks the
355
+ composition of many computational particles (10<sup>4</sup> to 10<sup>6</sup>) within a well-mixed air
356
+ volume, each represented by a composition vector that evolves based on physical
357
+ and chemical processes. The physical processes—including Brownian coagulation,
358
+ new particle formation, emissions, dilution, and deposition—are simulated using a
359
+ stochastic Monte Carlo approach via a Poisson process while chemical processes are
360
+ simulated deterministically for each computational particle. The weighted flow
361
+ algorithm (DeVille, Riemer, and West, 2011, 2019) enhances efficiency and reduces
362
+ ensemble variance. Detailed numerical methods are described in Riemer et al.
363
+ (2009), DeVille et al. (2011, 2019), and Curtis et al. (2016). PartMC is open-source
364
+ under the GNU GPL v2 and available at
365
+ [github.com/compdyn/partmc](https://github.com/compdyn/partmc).
366
+ >
367
+ > References:
368
+ > - Curtis, J. H., M. D. Michelotti, N. Riemer, M. T. Heath, M. West: Accelerated
369
+ simulation of stochastic particle removal processes in particle-resolved aerosol
370
+ models, J. Computational Phys., 322, 21-32, 2016, DOI: [10.1016/j.jcp.2016.06.029](https://doi.org/10.1016/j.jcp.2016.06.029)
371
+ > - DeVille, L., N. Riemer, M. West, Convergence of a generalized weighted flow
372
+ algorithm for stochastic particle coagulation, J. Computational Dynamics, 6, 69-94,
373
+ 2019, DOI: [10.3934/jcd.2019003](https://doi.org/10.3934/jcd.2019003)
374
+ > - DeVille, R. E. L., N. Riemer, M. West, The Weighted Flow Algorithm (WFA) for
375
+ stochastic particle coagulation, J. Computational Phys., 230, 8427-8451, 2011,
376
+ DOI: [10.1016/j.jcp.2011.07.027](https://doi.org/10.1016/j.jcp.2011.07.027)
377
+ > - Riemer, N., M. West, R. A. Zaveri, R. C. Easter, Simulating the evolution of soot
378
+ mixing-state with a particle-resolved aerosol model, J. Geophys. Res., 114, D09202,
379
+ 2009., DOI: [10.1029/2008JD011073](https://doi.org/10.1029/2008JD011073)
380
+
381
+ ## Credits
382
+
383
+ #### PyPartMC:
384
+
385
+ authors: [PyPartMC developers](https://github.com/open-atmos/PyPartMC/graphs/contributors)
386
+ funding: [US Department of Energy Atmospheric System Research programme](https://asr.science.energy.gov/), [Polish National Science Centre](https://ncn.gov.pl/en)
387
+ copyright: [University of Illinois at Urbana-Champaign](https://atmos.illinois.edu/)
388
+ licence: [GPL v3](https://www.gnu.org/licenses/gpl-3.0.en.html)
389
+
390
+ #### PartMC:
391
+ authors: [Nicole Riemer](https://www.atmos.uiuc.edu/~nriemer/), [Matthew West](https://lagrange.mechse.illinois.edu/mwest/), [Jeff Curtis](https://publish.illinois.edu/jcurtis2/) et al.
392
+ licence: [GPL v2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html) or later
393
+
@@ -0,0 +1,6 @@
1
+ PyPartMC/__init__.py,sha256=UxEKfxEgrPz4tNfNPCzWf3WGLCCuDcZ7HpJHV-efZ5Y,2435
2
+ PyPartMC/_PyPartMC.cp38-win_amd64.pyd,sha256=Ro7l0TZO7jMiCZRDOatpsFa2R56R9-Gp88GIVcY81ms,9405440
3
+ pypartmc-2.0.0rc4.dist-info/METADATA,sha256=lBLrEuhekaomGGZnNoffaa6Fpxzyxes9GGcFxPyTB20,27597
4
+ pypartmc-2.0.0rc4.dist-info/WHEEL,sha256=yXMtVL9U8RkqJEJfb-z5X2s1_G1r2eGG-REYk3wgjZ0,104
5
+ pypartmc-2.0.0rc4.dist-info/licenses/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
6
+ pypartmc-2.0.0rc4.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.3.0)
2
+ Generator: scikit-build-core 0.11.6
3
3
  Root-Is-Purelib: false
4
4
  Tag: cp38-cp38-win_amd64
5
5
 
@@ -1,7 +0,0 @@
1
- _PyPartMC.cp38-win_amd64.pyd,sha256=HguV5A2JEA27wUBTHPREgVipXYv6UM7I1N56ow6Voys,9584128
2
- PyPartMC/__init__.py,sha256=72fDfFXn4xRxfdLGOx8NCml41RxzBitBNZ-sUuvH-x0,2295
3
- PyPartMC-1.4.2.dist-info/LICENSE,sha256=IwGE9guuL-ryRPEKi6wFPI_zOhg7zDZbTYuHbSt_SAk,35823
4
- PyPartMC-1.4.2.dist-info/METADATA,sha256=RCThdM7z5TwxfMYeCRUgm8AunpKjiMSJE8F4cga-rCE,27092
5
- PyPartMC-1.4.2.dist-info/WHEEL,sha256=rTcqimtzpX3smAWAhGmiRSWAxTY4PqYPNE-p4kscHDQ,99
6
- PyPartMC-1.4.2.dist-info/top_level.txt,sha256=PJxy22pTnxcBhqrb6r4AIL32rkxA61gzw7ohlzybgSM,19
7
- PyPartMC-1.4.2.dist-info/RECORD,,
@@ -1,2 +0,0 @@
1
- PyPartMC
2
- _PyPartMC