musica 0.10.1__cp37-cp37m-win_amd64.whl → 0.11.1.0__cp37-cp37m-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 musica might be problematic. Click here for more details.

Binary file
lib/musica.lib CHANGED
Binary file
lib/yaml-cpp.lib CHANGED
Binary file
musica/CMakeLists.txt ADDED
@@ -0,0 +1,47 @@
1
+ pybind11_add_module(_musica
2
+ binding.cpp
3
+ musica.cpp
4
+ mechanism_configuration.cpp
5
+ )
6
+
7
+ target_link_libraries(_musica
8
+ PRIVATE
9
+ musica::musica
10
+ )
11
+
12
+ include(silence_warnings)
13
+ silence_warnings(_musica)
14
+
15
+ if (APPLE)
16
+ # set the rpath for the shared library
17
+ set_target_properties(_musica PROPERTIES
18
+ INSTALL_RPATH "@loader_path"
19
+ BUILD_WITH_INSTALL_RPATH TRUE
20
+ )
21
+ elseif(UNIX)
22
+ set(CUDA_RPATH
23
+ "$ORIGIN/../../nvidia/cublas/lib"
24
+ "$ORIGIN/../../nvidia/cuda_runtime/lib"
25
+ )
26
+
27
+ message(STATUS "Adding RPATH for python site packages libs at ${CUDA_RPATH}")
28
+
29
+ set_target_properties(_musica PROPERTIES
30
+ INSTALL_RPATH "$ORIGIN;${CUDA_RPATH}"
31
+ BUILD_WITH_INSTALL_RPATH TRUE
32
+ )
33
+ endif()
34
+
35
+ if(WIN32)
36
+ # makefiles on windows don't need the config directory
37
+ if (${CMAKE_GENERATOR} MATCHES "MinGW Makefiles")
38
+ set(PYTHON_MODULE_PATH "${CMAKE_CURRENT_BINARY_DIR}")
39
+ else()
40
+ # but visual studio does
41
+ set(PYTHON_MODULE_PATH "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>")
42
+ endif()
43
+ else()
44
+ set(PYTHON_MODULE_PATH "${CMAKE_CURRENT_BINARY_DIR}")
45
+ endif()
46
+
47
+ install(TARGETS _musica yaml-cpp musica LIBRARY DESTINATION .)
musica/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ from _musica import *
2
+ from .types import *
3
+ from .mechanism_configuration import *
musica/_version.py CHANGED
@@ -1 +1 @@
1
- version = "0.10.1"
1
+ version = "0.11.1.0"
musica/binding.cpp ADDED
@@ -0,0 +1,19 @@
1
+ // Copyright (C) 2023-2025 University Corporation for Atmospheric Research
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ #include <pybind11/pybind11.h>
5
+
6
+ namespace py = pybind11;
7
+
8
+ void bind_musica(py::module_ &);
9
+ void bind_mechanism_configuration(py::module_ &);
10
+
11
+ // Wraps micm.cpp
12
+ PYBIND11_MODULE(_musica, m)
13
+ {
14
+ py::module_ core = m.def_submodule("_core", "Wrapper classes for MUSICA C library structs and functions");
15
+ py::module_ mechanism_configuration = m.def_submodule("_mechanism_configuration", "Wrapper classes for Mechanism Configuration library structs and functions");
16
+
17
+ bind_musica(core);
18
+ bind_mechanism_configuration(mechanism_configuration);
19
+ }
@@ -0,0 +1,519 @@
1
+ // Copyright (C) 2025 University Corporation for Atmospheric Research
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ #include <pybind11/pybind11.h>
4
+ #include <pybind11/stl.h>
5
+
6
+ #include <mechanism_configuration/constants.hpp>
7
+ #include <mechanism_configuration/v1/parser.hpp>
8
+ #include <mechanism_configuration/v1/types.hpp>
9
+ #include <mechanism_configuration/v1/validation.hpp>
10
+ #include <variant>
11
+
12
+ namespace py = pybind11;
13
+ namespace constants = mechanism_configuration::constants;
14
+ namespace validation = mechanism_configuration::v1::validation;
15
+ using namespace mechanism_configuration::v1::types;
16
+
17
+ enum class ReactionType
18
+ {
19
+ Arrhenius,
20
+ Branched,
21
+ CondensedPhaseArrhenius,
22
+ CondensedPhasePhotolysis,
23
+ Emission,
24
+ FirstOrderLoss,
25
+ SimpolPhaseTransfer,
26
+ AqueousEquilibrium,
27
+ WetDeposition,
28
+ HenrysLaw,
29
+ Photolysis,
30
+ Surface,
31
+ Troe,
32
+ Tunneling,
33
+ UserDefined
34
+ };
35
+
36
+ struct ReactionsIterator
37
+ {
38
+ using VariantType = std::variant<
39
+ Arrhenius,
40
+ Branched,
41
+ CondensedPhaseArrhenius,
42
+ CondensedPhasePhotolysis,
43
+ Emission,
44
+ FirstOrderLoss,
45
+ SimpolPhaseTransfer,
46
+ AqueousEquilibrium,
47
+ WetDeposition,
48
+ HenrysLaw,
49
+ Photolysis,
50
+ Surface,
51
+ Troe,
52
+ Tunneling,
53
+ UserDefined>;
54
+
55
+ std::vector<std::vector<VariantType>> reaction_lists;
56
+ size_t outer_index = 0;
57
+ size_t inner_index = 0;
58
+
59
+ ReactionsIterator(Reactions &reactions)
60
+ : reaction_lists{ std::vector<VariantType>(reactions.arrhenius.begin(), reactions.arrhenius.end()),
61
+ std::vector<VariantType>(reactions.branched.begin(), reactions.branched.end()),
62
+ std::vector<VariantType>(reactions.condensed_phase_arrhenius.begin(), reactions.condensed_phase_arrhenius.end()),
63
+ std::vector<VariantType>(reactions.condensed_phase_photolysis.begin(), reactions.condensed_phase_photolysis.end()),
64
+ std::vector<VariantType>(reactions.emission.begin(), reactions.emission.end()),
65
+ std::vector<VariantType>(reactions.first_order_loss.begin(), reactions.first_order_loss.end()),
66
+ std::vector<VariantType>(reactions.simpol_phase_transfer.begin(), reactions.simpol_phase_transfer.end()),
67
+ std::vector<VariantType>(reactions.aqueous_equilibrium.begin(), reactions.aqueous_equilibrium.end()),
68
+ std::vector<VariantType>(reactions.wet_deposition.begin(), reactions.wet_deposition.end()),
69
+ std::vector<VariantType>(reactions.henrys_law.begin(), reactions.henrys_law.end()),
70
+ std::vector<VariantType>(reactions.photolysis.begin(), reactions.photolysis.end()),
71
+ std::vector<VariantType>(reactions.surface.begin(), reactions.surface.end()),
72
+ std::vector<VariantType>(reactions.troe.begin(), reactions.troe.end()),
73
+ std::vector<VariantType>(reactions.tunneling.begin(), reactions.tunneling.end()),
74
+ std::vector<VariantType>(reactions.user_defined.begin(), reactions.user_defined.end()) }
75
+ {
76
+ }
77
+
78
+ py::object next()
79
+ {
80
+ while (outer_index < reaction_lists.size())
81
+ {
82
+ const auto &vec = reaction_lists[outer_index];
83
+ if (inner_index < vec.size())
84
+ {
85
+ return std::visit([](auto &&arg) { return py::cast(arg); }, vec[inner_index++]);
86
+ }
87
+ ++outer_index;
88
+ inner_index = 0;
89
+ }
90
+ throw py::stop_iteration();
91
+ }
92
+ };
93
+
94
+ std::vector<ReactionComponent> get_reaction_components(const py::list& components)
95
+ {
96
+ std::vector<ReactionComponent> reaction_components;
97
+ for (const auto &item : components) {
98
+ if (py::isinstance<Species>(item)) {
99
+ ReactionComponent component;
100
+ component.species_name = item.cast<Species>().name;
101
+ reaction_components.push_back(component);
102
+ } else if (py::isinstance<py::tuple>(item) && py::len(item.cast<py::tuple>()) == 2) {
103
+ auto item_tuple = item.cast<py::tuple>();
104
+ if (py::isinstance<py::float_>(item_tuple[0]) && py::isinstance<Species>(item_tuple[1])) {
105
+ ReactionComponent component;
106
+ component.species_name = item_tuple[1].cast<Species>().name;
107
+ component.coefficient = item_tuple[0].cast<double>();
108
+ reaction_components.push_back(component);
109
+ } else if (py::isinstance<py::int_>(item_tuple[0]) && py::isinstance<Species>(item_tuple[1])) {
110
+ ReactionComponent component;
111
+ component.species_name = item_tuple[1].cast<Species>().name;
112
+ component.coefficient = item_tuple[0].cast<int>();
113
+ reaction_components.push_back(component);
114
+ } else {
115
+ throw py::value_error("Invalid tuple format. Expected (float, Species).");
116
+ }
117
+ } else {
118
+ throw py::value_error("Invalid type for reactant. Expected a Species or a tuple of (float, Species).");
119
+ }
120
+ }
121
+ std::unordered_set<std::string> component_names;
122
+ for (const auto &component : reaction_components) {
123
+ if (!component_names.insert(component.species_name).second) {
124
+ throw py::value_error("Duplicate reaction component name found: " + component.species_name);
125
+ }
126
+ }
127
+ return reaction_components;
128
+ }
129
+
130
+ Reactions create_reactions(const py::list& reactions)
131
+ {
132
+ Reactions reaction_obj;
133
+ for (const auto &item : reactions) {
134
+ if (py::isinstance<Arrhenius>(item)) {
135
+ reaction_obj.arrhenius.push_back(item.cast<Arrhenius>());
136
+ } else if (py::isinstance<Branched>(item)) {
137
+ reaction_obj.branched.push_back(item.cast<Branched>());
138
+ } else if (py::isinstance<CondensedPhaseArrhenius>(item)) {
139
+ reaction_obj.condensed_phase_arrhenius.push_back(item.cast<CondensedPhaseArrhenius>());
140
+ } else if (py::isinstance<CondensedPhasePhotolysis>(item)) {
141
+ reaction_obj.condensed_phase_photolysis.push_back(item.cast<CondensedPhasePhotolysis>());
142
+ } else if (py::isinstance<Emission>(item)) {
143
+ reaction_obj.emission.push_back(item.cast<Emission>());
144
+ } else if (py::isinstance<FirstOrderLoss>(item)) {
145
+ reaction_obj.first_order_loss.push_back(item.cast<FirstOrderLoss>());
146
+ } else if (py::isinstance<SimpolPhaseTransfer>(item)) {
147
+ reaction_obj.simpol_phase_transfer.push_back(item.cast<SimpolPhaseTransfer>());
148
+ } else if (py::isinstance<AqueousEquilibrium>(item)) {
149
+ reaction_obj.aqueous_equilibrium.push_back(item.cast<AqueousEquilibrium>());
150
+ } else if (py::isinstance<WetDeposition>(item)) {
151
+ reaction_obj.wet_deposition.push_back(item.cast<WetDeposition>());
152
+ } else if (py::isinstance<HenrysLaw>(item)) {
153
+ reaction_obj.henrys_law.push_back(item.cast<HenrysLaw>());
154
+ } else if (py::isinstance<Photolysis>(item)) {
155
+ reaction_obj.photolysis.push_back(item.cast<Photolysis>());
156
+ } else if (py::isinstance<Surface>(item)) {
157
+ reaction_obj.surface.push_back(item.cast<Surface>());
158
+ } else if (py::isinstance<Troe>(item)) {
159
+ reaction_obj.troe.push_back(item.cast<Troe>());
160
+ } else if (py::isinstance<Tunneling>(item)) {
161
+ reaction_obj.tunneling.push_back(item.cast<Tunneling>());
162
+ } else if (py::isinstance<UserDefined>(item)) {
163
+ reaction_obj.user_defined.push_back(item.cast<UserDefined>());
164
+ } else {
165
+ throw py::value_error("Invalid reaction type.");
166
+ }
167
+ }
168
+ return reaction_obj;
169
+ }
170
+
171
+ void bind_mechanism_configuration(py::module_ & mechanism_configuration)
172
+ {
173
+ py::enum_<ReactionType>(mechanism_configuration, "_ReactionType")
174
+ .value("Arrhenius", ReactionType::Arrhenius)
175
+ .value("Branched", ReactionType::Branched)
176
+ .value("CondensedPhaseArrhenius", ReactionType::CondensedPhaseArrhenius)
177
+ .value("CondensedPhasePhotolysis", ReactionType::CondensedPhasePhotolysis)
178
+ .value("Emission", ReactionType::Emission)
179
+ .value("FirstOrderLoss", ReactionType::FirstOrderLoss)
180
+ .value("SimpolPhaseTransfer", ReactionType::SimpolPhaseTransfer)
181
+ .value("AqueousEquilibrium", ReactionType::AqueousEquilibrium)
182
+ .value("WetDeposition", ReactionType::WetDeposition)
183
+ .value("HenrysLaw", ReactionType::HenrysLaw)
184
+ .value("Photolysis", ReactionType::Photolysis)
185
+ .value("Surface", ReactionType::Surface)
186
+ .value("Troe", ReactionType::Troe)
187
+ .value("Tunneling", ReactionType::Tunneling)
188
+ .value("UserDefined", ReactionType::UserDefined);
189
+
190
+ py::class_<Species>(mechanism_configuration, "_Species")
191
+ .def(py::init<>())
192
+ .def_readwrite("name", &Species::name)
193
+ .def_readwrite("absolute_tolerance", &Species::absolute_tolerance)
194
+ .def_readwrite("diffusion_coefficient_m2_s", &Species::diffusion_coefficient)
195
+ .def_readwrite("molecular_weight_kg_mol", &Species::molecular_weight)
196
+ .def_readwrite("HLC_298K_mol_m3_Pa", &Species::henrys_law_constant_298)
197
+ .def_readwrite("HLC_exponential_factor_K", &Species::henrys_law_constant_exponential_factor)
198
+ .def_readwrite("N_star", &Species::n_star)
199
+ .def_readwrite("density_kg_m3", &Species::density)
200
+ .def_readwrite("tracer_type", &Species::tracer_type)
201
+ .def_readwrite("other_properties", &Species::unknown_properties)
202
+ .def("__str__", [](const Species &s) { return s.name; })
203
+ .def("__repr__", [](const Species &s) { return "<Species: " + s.name + ">"; });
204
+
205
+ py::class_<Phase>(mechanism_configuration, "_Phase")
206
+ .def(py::init<>())
207
+ .def_readwrite("name", &Phase::name)
208
+ .def_readwrite("species", &Phase::species)
209
+ .def_readwrite("other_properties", &Phase::unknown_properties)
210
+ .def("__str__", [](const Phase &p) { return p.name; })
211
+ .def("__repr__", [](const Phase &p) { return "<Phase: " + p.name + ">"; });
212
+
213
+ py::class_<ReactionComponent>(mechanism_configuration, "_ReactionComponent")
214
+ .def(py::init<>())
215
+ .def(py::init([](const std::string &species_name) {
216
+ ReactionComponent rc;
217
+ rc.species_name = species_name;
218
+ return rc;
219
+ }))
220
+ .def(py::init([](const std::string &species_name, double coefficient) {
221
+ ReactionComponent rc;
222
+ rc.species_name = species_name;
223
+ rc.coefficient = coefficient;
224
+ return rc;
225
+ }))
226
+ .def_readwrite("species_name", &ReactionComponent::species_name)
227
+ .def_readwrite("coefficient", &ReactionComponent::coefficient)
228
+ .def_readwrite("other_properties", &ReactionComponent::unknown_properties)
229
+ .def("__str__", [](const ReactionComponent &rc) { return rc.species_name; })
230
+ .def("__repr__", [](const ReactionComponent &rc) { return "<ReactionComponent: " + rc.species_name + ">"; });
231
+
232
+ py::class_<Arrhenius>(mechanism_configuration, "_Arrhenius")
233
+ .def(py::init<>())
234
+ .def_readwrite("A", &Arrhenius::A)
235
+ .def_readwrite("B", &Arrhenius::B)
236
+ .def_readwrite("C", &Arrhenius::C)
237
+ .def_readwrite("D", &Arrhenius::D)
238
+ .def_readwrite("E", &Arrhenius::E)
239
+ .def_readwrite("reactants", &Arrhenius::reactants)
240
+ .def_readwrite("products", &Arrhenius::products)
241
+ .def_readwrite("name", &Arrhenius::name)
242
+ .def_readwrite("gas_phase", &Arrhenius::gas_phase)
243
+ .def_readwrite("other_properties", &Arrhenius::unknown_properties)
244
+ .def("__str__", [](const Arrhenius &a) { return a.name; })
245
+ .def("__repr__", [](const Arrhenius &a) { return "<Arrhenius: " + a.name + ">"; })
246
+ .def_property_readonly("type", [](const Arrhenius &) { return ReactionType::Arrhenius; });
247
+
248
+ py::class_<CondensedPhaseArrhenius>(mechanism_configuration, "_CondensedPhaseArrhenius")
249
+ .def(py::init<>())
250
+ .def_readwrite("A", &CondensedPhaseArrhenius::A)
251
+ .def_readwrite("B", &CondensedPhaseArrhenius::B)
252
+ .def_readwrite("C", &CondensedPhaseArrhenius::C)
253
+ .def_readwrite("D", &CondensedPhaseArrhenius::D)
254
+ .def_readwrite("E", &CondensedPhaseArrhenius::E)
255
+ .def_readwrite("reactants", &CondensedPhaseArrhenius::reactants)
256
+ .def_readwrite("products", &CondensedPhaseArrhenius::products)
257
+ .def_readwrite("name", &CondensedPhaseArrhenius::name)
258
+ .def_readwrite("aerosol_phase", &CondensedPhaseArrhenius::aerosol_phase)
259
+ .def_readwrite("aerosol_phase_water", &CondensedPhaseArrhenius::aerosol_phase_water)
260
+ .def_readwrite("other_properties", &CondensedPhaseArrhenius::unknown_properties)
261
+ .def("__str__", [](const CondensedPhaseArrhenius &cpa) { return cpa.name; })
262
+ .def("__repr__", [](const CondensedPhaseArrhenius &cpa) { return "<CondensedPhaseArrhenius: " + cpa.name + ">"; })
263
+ .def_property_readonly("type", [](const CondensedPhaseArrhenius &) { return ReactionType::CondensedPhaseArrhenius; });
264
+
265
+ py::class_<Troe>(mechanism_configuration, "_Troe")
266
+ .def(py::init<>())
267
+ .def_readwrite("k0_A", &Troe::k0_A)
268
+ .def_readwrite("k0_B", &Troe::k0_B)
269
+ .def_readwrite("k0_C", &Troe::k0_C)
270
+ .def_readwrite("kinf_A", &Troe::kinf_A)
271
+ .def_readwrite("kinf_B", &Troe::kinf_B)
272
+ .def_readwrite("kinf_C", &Troe::kinf_C)
273
+ .def_readwrite("Fc", &Troe::Fc)
274
+ .def_readwrite("N", &Troe::N)
275
+ .def_readwrite("reactants", &Troe::reactants)
276
+ .def_readwrite("products", &Troe::products)
277
+ .def_readwrite("name", &Troe::name)
278
+ .def_readwrite("gas_phase", &Troe::gas_phase)
279
+ .def_readwrite("other_properties", &Troe::unknown_properties)
280
+ .def("__str__", [](const Troe &t) { return t.name; })
281
+ .def("__repr__", [](const Troe &t) { return "<Troe: " + t.name + ">"; })
282
+ .def_property_readonly("type", [](const Troe &) { return ReactionType::Troe; });
283
+
284
+ py::class_<Branched>(mechanism_configuration, "_Branched")
285
+ .def(py::init<>())
286
+ .def_readwrite("X", &Branched::X)
287
+ .def_readwrite("Y", &Branched::Y)
288
+ .def_readwrite("a0", &Branched::a0)
289
+ .def_readwrite("n", &Branched::n)
290
+ .def_readwrite("reactants", &Branched::reactants)
291
+ .def_readwrite("nitrate_products", &Branched::nitrate_products)
292
+ .def_readwrite("alkoxy_products", &Branched::alkoxy_products)
293
+ .def_readwrite("name", &Branched::name)
294
+ .def_readwrite("gas_phase", &Branched::gas_phase)
295
+ .def_readwrite("other_properties", &Branched::unknown_properties)
296
+ .def("__str__", [](const Branched &b) { return b.name; })
297
+ .def("__repr__", [](const Branched &b) { return "<Branched: " + b.name + ">"; })
298
+ .def_property_readonly("type", [](const Branched &) { return ReactionType::Branched; });
299
+
300
+ py::class_<Tunneling>(mechanism_configuration, "_Tunneling")
301
+ .def(py::init<>())
302
+ .def_readwrite("A", &Tunneling::A)
303
+ .def_readwrite("B", &Tunneling::B)
304
+ .def_readwrite("C", &Tunneling::C)
305
+ .def_readwrite("reactants", &Tunneling::reactants)
306
+ .def_readwrite("products", &Tunneling::products)
307
+ .def_readwrite("name", &Tunneling::name)
308
+ .def_readwrite("gas_phase", &Tunneling::gas_phase)
309
+ .def_readwrite("other_properties", &Tunneling::unknown_properties)
310
+ .def("__str__", [](const Tunneling &t) { return t.name; })
311
+ .def("__repr__", [](const Tunneling &t) { return "<Tunneling: " + t.name + ">"; })
312
+ .def_property_readonly("type", [](const Tunneling &) { return ReactionType::Tunneling; });
313
+
314
+ py::class_<Surface>(mechanism_configuration, "_Surface")
315
+ .def(py::init<>())
316
+ .def_readwrite("reaction_probability", &Surface::reaction_probability)
317
+ .def_readwrite("gas_phase_species", &Surface::gas_phase_species)
318
+ .def_readwrite("gas_phase_products", &Surface::gas_phase_products)
319
+ .def_readwrite("name", &Surface::name)
320
+ .def_readwrite("gas_phase", &Surface::gas_phase)
321
+ .def_readwrite("aerosol_phase", &Surface::aerosol_phase)
322
+ .def_readwrite("other_properties", &Surface::unknown_properties)
323
+ .def("__str__", [](const Surface &s) { return s.name; })
324
+ .def("__repr__", [](const Surface &s) { return "<Surface: " + s.name + ">"; })
325
+ .def_property_readonly("type", [](const Surface &) { return ReactionType::Surface; });
326
+
327
+ py::class_<Photolysis>(mechanism_configuration, "_Photolysis")
328
+ .def(py::init<>())
329
+ .def_readwrite("scaling_factor", &Photolysis::scaling_factor)
330
+ .def_readwrite("reactants", &Photolysis::reactants)
331
+ .def_readwrite("products", &Photolysis::products)
332
+ .def_readwrite("name", &Photolysis::name)
333
+ .def_readwrite("gas_phase", &Photolysis::gas_phase)
334
+ .def_readwrite("other_properties", &Photolysis::unknown_properties)
335
+ .def("__str__", [](const Photolysis &p) { return p.name; })
336
+ .def("__repr__", [](const Photolysis &p) { return "<Photolysis: " + p.name + ">"; })
337
+ .def_property_readonly("type", [](const Photolysis &) { return ReactionType::Photolysis; });
338
+
339
+ py::class_<CondensedPhasePhotolysis>(mechanism_configuration, "_CondensedPhasePhotolysis")
340
+ .def(py::init<>())
341
+ .def_readwrite("scaling_factor", &CondensedPhasePhotolysis::scaling_factor)
342
+ .def_readwrite("reactants", &CondensedPhasePhotolysis::reactants)
343
+ .def_readwrite("products", &CondensedPhasePhotolysis::products)
344
+ .def_readwrite("name", &CondensedPhasePhotolysis::name)
345
+ .def_readwrite("aerosol_phase", &CondensedPhasePhotolysis::aerosol_phase)
346
+ .def_readwrite("aerosol_phase_water", &CondensedPhasePhotolysis::aerosol_phase_water)
347
+ .def_readwrite("other_properties", &CondensedPhasePhotolysis::unknown_properties)
348
+ .def("__str__", [](const CondensedPhasePhotolysis &cpp) { return cpp.name; })
349
+ .def("__repr__", [](const CondensedPhasePhotolysis &cpp) { return "<CondensedPhasePhotolysis: " + cpp.name + ">"; })
350
+ .def_property_readonly("type", [](const CondensedPhasePhotolysis &) { return ReactionType::CondensedPhasePhotolysis; });
351
+
352
+ py::class_<Emission>(mechanism_configuration, "_Emission")
353
+ .def(py::init<>())
354
+ .def_readwrite("scaling_factor", &Emission::scaling_factor)
355
+ .def_readwrite("products", &Emission::products)
356
+ .def_readwrite("name", &Emission::name)
357
+ .def_readwrite("gas_phase", &Emission::gas_phase)
358
+ .def_readwrite("other_properties", &Emission::unknown_properties)
359
+ .def("__str__", [](const Emission &e) { return e.name; })
360
+ .def("__repr__", [](const Emission &e) { return "<Emission: " + e.name + ">"; })
361
+ .def_property_readonly("type", [](const Emission &) { return ReactionType::Emission; });
362
+
363
+ py::class_<FirstOrderLoss>(mechanism_configuration, "_FirstOrderLoss")
364
+ .def(py::init<>())
365
+ .def_readwrite("scaling_factor", &FirstOrderLoss::scaling_factor)
366
+ .def_readwrite("reactants", &FirstOrderLoss::reactants)
367
+ .def_readwrite("name", &FirstOrderLoss::name)
368
+ .def_readwrite("gas_phase", &FirstOrderLoss::gas_phase)
369
+ .def_readwrite("other_properties", &FirstOrderLoss::unknown_properties)
370
+ .def("__str__", [](const FirstOrderLoss &fol) { return fol.name; })
371
+ .def("__repr__", [](const FirstOrderLoss &fol) { return "<FirstOrderLoss: " + fol.name + ">"; })
372
+ .def_property_readonly("type", [](const FirstOrderLoss &) { return ReactionType::FirstOrderLoss; });
373
+
374
+ py::class_<AqueousEquilibrium>(mechanism_configuration, "_AqueousEquilibrium")
375
+ .def(py::init<>())
376
+ .def_readwrite("name", &AqueousEquilibrium::name)
377
+ .def_readwrite("gas_phase", &AqueousEquilibrium::gas_phase)
378
+ .def_readwrite("aerosol_phase", &AqueousEquilibrium::aerosol_phase)
379
+ .def_readwrite("aerosol_phase_water", &AqueousEquilibrium::aerosol_phase_water)
380
+ .def_readwrite("reactants", &AqueousEquilibrium::reactants)
381
+ .def_readwrite("products", &AqueousEquilibrium::products)
382
+ .def_readwrite("A", &AqueousEquilibrium::A)
383
+ .def_readwrite("C", &AqueousEquilibrium::C)
384
+ .def_readwrite("k_reverse", &AqueousEquilibrium::k_reverse)
385
+ .def_readwrite("other_properties", &AqueousEquilibrium::unknown_properties)
386
+ .def("__str__", [](const AqueousEquilibrium &ae) { return ae.name; })
387
+ .def("__repr__", [](const AqueousEquilibrium &ae) { return "<AqueousEquilibrium: " + ae.name + ">"; })
388
+ .def_property_readonly("type", [](const AqueousEquilibrium &) { return ReactionType::AqueousEquilibrium; });
389
+
390
+ py::class_<WetDeposition>(mechanism_configuration, "_WetDeposition")
391
+ .def(py::init<>())
392
+ .def_readwrite("scaling_factor", &WetDeposition::scaling_factor)
393
+ .def_readwrite("name", &WetDeposition::name)
394
+ .def_readwrite("aerosol_phase", &WetDeposition::aerosol_phase)
395
+ .def_readwrite("other_properties", &WetDeposition::unknown_properties)
396
+ .def("__str__", [](const WetDeposition &wd) { return wd.name; })
397
+ .def("__repr__", [](const WetDeposition &wd) { return "<WetDeposition: " + wd.name + ">"; })
398
+ .def_property_readonly("type", [](const WetDeposition &) { return ReactionType::WetDeposition; });
399
+
400
+ py::class_<HenrysLaw>(mechanism_configuration, "_HenrysLaw")
401
+ .def(py::init<>())
402
+ .def_readwrite("name", &HenrysLaw::name)
403
+ .def_readwrite("gas_phase", &HenrysLaw::gas_phase)
404
+ .def_readwrite("gas_phase_species", &HenrysLaw::gas_phase_species)
405
+ .def_readwrite("aerosol_phase", &HenrysLaw::aerosol_phase)
406
+ .def_readwrite("aerosol_phase_water", &HenrysLaw::aerosol_phase_water)
407
+ .def_readwrite("aerosol_phase_species", &HenrysLaw::aerosol_phase_species)
408
+ .def_readwrite("other_properties", &HenrysLaw::unknown_properties)
409
+ .def("__str__", [](const HenrysLaw &hl) { return hl.name; })
410
+ .def("__repr__", [](const HenrysLaw &hl) { return "<HenrysLaw: " + hl.name + ">"; })
411
+ .def_property_readonly("type", [](const HenrysLaw &) { return ReactionType::HenrysLaw; });
412
+
413
+ py::class_<SimpolPhaseTransfer>(mechanism_configuration, "_SimpolPhaseTransfer")
414
+ .def(py::init<>())
415
+ .def_readwrite("gas_phase", &SimpolPhaseTransfer::gas_phase)
416
+ .def_readwrite("gas_phase_species", &SimpolPhaseTransfer::gas_phase_species)
417
+ .def_readwrite("aerosol_phase", &SimpolPhaseTransfer::aerosol_phase)
418
+ .def_readwrite("aerosol_phase_species", &SimpolPhaseTransfer::aerosol_phase_species)
419
+ .def_readwrite("name", &SimpolPhaseTransfer::name)
420
+ .def_readwrite("B", &SimpolPhaseTransfer::B)
421
+ .def_readwrite("other_properties", &SimpolPhaseTransfer::unknown_properties)
422
+ .def("__str__", [](const SimpolPhaseTransfer &spt) { return spt.name; })
423
+ .def("__repr__", [](const SimpolPhaseTransfer &spt) { return "<SimpolPhaseTransfer: " + spt.name + ">"; })
424
+ .def_property_readonly("type", [](const SimpolPhaseTransfer &) { return ReactionType::SimpolPhaseTransfer; });
425
+
426
+ py::class_<UserDefined>(mechanism_configuration, "_UserDefined")
427
+ .def(py::init<>())
428
+ .def_readwrite("scaling_factor", &UserDefined::scaling_factor)
429
+ .def_readwrite("reactants", &UserDefined::reactants)
430
+ .def_readwrite("products", &UserDefined::products)
431
+ .def_readwrite("name", &UserDefined::name)
432
+ .def_readwrite("gas_phase", &UserDefined::gas_phase)
433
+ .def_readwrite("other_properties", &UserDefined::unknown_properties)
434
+ .def("__str__", [](const UserDefined &p) { return p.name; })
435
+ .def("__repr__", [](const UserDefined &p) { return "<UserDefined: " + p.name + ">"; })
436
+ .def_property_readonly("type", [](const UserDefined &) { return ReactionType::UserDefined; });
437
+
438
+ py::class_<Reactions>(mechanism_configuration, "_Reactions")
439
+ .def(py::init<>())
440
+ .def(py::init([](const py::list &reactions) {
441
+ return create_reactions(reactions);
442
+ }))
443
+ .def_readwrite("arrhenius", &Reactions::arrhenius)
444
+ .def_readwrite("branched", &Reactions::branched)
445
+ .def_readwrite("condensed_phase_arrhenius", &Reactions::condensed_phase_arrhenius)
446
+ .def_readwrite("condensed_phase_photolysis", &Reactions::condensed_phase_photolysis)
447
+ .def_readwrite("emission", &Reactions::emission)
448
+ .def_readwrite("first_order_loss", &Reactions::first_order_loss)
449
+ .def_readwrite("simpol_phase_transfer", &Reactions::simpol_phase_transfer)
450
+ .def_readwrite("aqueous_equilibrium", &Reactions::aqueous_equilibrium)
451
+ .def_readwrite("wet_deposition", &Reactions::wet_deposition)
452
+ .def_readwrite("henrys_law", &Reactions::henrys_law)
453
+ .def_readwrite("photolysis", &Reactions::photolysis)
454
+ .def_readwrite("surface", &Reactions::surface)
455
+ .def_readwrite("troe", &Reactions::troe)
456
+ .def_readwrite("tunneling", &Reactions::tunneling)
457
+ .def_readwrite("user_defined", &Reactions::user_defined)
458
+ .def(
459
+ "__len__",
460
+ [](const Reactions &r)
461
+ {
462
+ return r.arrhenius.size() + r.branched.size() + r.condensed_phase_arrhenius.size() + r.condensed_phase_photolysis.size() +
463
+ r.emission.size() + r.first_order_loss.size() + r.simpol_phase_transfer.size() + r.aqueous_equilibrium.size() +
464
+ r.wet_deposition.size() + r.henrys_law.size() + r.photolysis.size() + r.surface.size() + r.troe.size() + r.tunneling.size() +
465
+ r.user_defined.size();
466
+ })
467
+ .def("__str__", [](const Reactions &r) { return "Reactions"; })
468
+ .def("__repr__", [](const Reactions &r) { return "<Reactions>"; })
469
+ .def("__iter__", [](Reactions &r) { return ReactionsIterator(r); });
470
+
471
+ py::class_<ReactionsIterator>(mechanism_configuration, "_ReactionsIterator")
472
+ .def("__iter__", [](ReactionsIterator &it) -> ReactionsIterator & { return it; })
473
+ .def("__next__", &ReactionsIterator::next);
474
+
475
+ py::class_<Mechanism>(mechanism_configuration, "_Mechanism")
476
+ .def(py::init<>())
477
+ .def_readwrite("name", &Mechanism::name)
478
+ .def_readwrite("species", &Mechanism::species)
479
+ .def_readwrite("phases", &Mechanism::phases)
480
+ .def_readwrite("reactions", &Mechanism::reactions)
481
+ .def_readwrite("version", &Mechanism::version)
482
+ .def("__str__", [](const Mechanism &m) { return m.name; })
483
+ .def("__repr__", [](const Mechanism &m) { return "<Mechanism: " + m.name + ">"; });
484
+
485
+ py::class_<mechanism_configuration::Version>(mechanism_configuration, "_Version")
486
+ .def(py::init<>())
487
+ .def(py::init<unsigned int, unsigned int, unsigned int>())
488
+ .def(py::init<std::string>())
489
+ .def_readwrite("major", &mechanism_configuration::Version::major)
490
+ .def_readwrite("minor", &mechanism_configuration::Version::minor)
491
+ .def_readwrite("patch", &mechanism_configuration::Version::patch)
492
+ .def("to_string", &mechanism_configuration::Version::to_string)
493
+ .def("__str__", &mechanism_configuration::Version::to_string)
494
+ .def("__repr__", [](const mechanism_configuration::Version &v) { return "<Version: " + v.to_string() + ">"; });
495
+
496
+ using V1Parser = mechanism_configuration::v1::Parser;
497
+
498
+ py::class_<V1Parser>(mechanism_configuration, "_Parser")
499
+ .def(py::init<>())
500
+ .def(
501
+ "parse",
502
+ [](V1Parser &self, const std::string &path)
503
+ {
504
+ auto parsed = self.Parse(std::filesystem::path(path));
505
+ if (parsed)
506
+ {
507
+ return *parsed;
508
+ }
509
+ else
510
+ {
511
+ std::string error = "Error parsing file: " + path + "\n";
512
+ for (auto &e : parsed.errors)
513
+ {
514
+ error += e.second + "\n";
515
+ }
516
+ throw std::runtime_error(error);
517
+ }
518
+ });
519
+ }