musica 0.12.2__cp312-cp312-win_amd64.whl → 0.13.0__cp312-cp312-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.
- musica/CMakeLists.txt +4 -0
- musica/_musica.cp312-win_amd64.pyd +0 -0
- musica/_version.py +1 -1
- musica/binding_common.cpp +6 -9
- musica/binding_common.hpp +17 -1
- musica/grid.cpp +206 -0
- musica/grid.py +98 -0
- musica/grid_map.cpp +117 -0
- musica/grid_map.py +167 -0
- musica/mechanism_configuration/__init__.py +18 -1
- musica/mechanism_configuration/ancillary.py +6 -0
- musica/mechanism_configuration/arrhenius.py +111 -269
- musica/mechanism_configuration/branched.py +116 -275
- musica/mechanism_configuration/emission.py +63 -52
- musica/mechanism_configuration/first_order_loss.py +73 -157
- musica/mechanism_configuration/mechanism.py +93 -0
- musica/mechanism_configuration/phase.py +44 -33
- musica/mechanism_configuration/phase_species.py +58 -0
- musica/mechanism_configuration/photolysis.py +77 -67
- musica/mechanism_configuration/reaction_component.py +54 -0
- musica/mechanism_configuration/reactions.py +17 -58
- musica/mechanism_configuration/species.py +45 -71
- musica/mechanism_configuration/surface.py +78 -74
- musica/mechanism_configuration/taylor_series.py +136 -0
- musica/mechanism_configuration/ternary_chemical_activation.py +138 -330
- musica/mechanism_configuration/troe.py +138 -330
- musica/mechanism_configuration/tunneling.py +105 -229
- musica/mechanism_configuration/user_defined.py +79 -68
- musica/mechanism_configuration.cpp +54 -162
- musica/musica.cpp +2 -5
- musica/profile.cpp +294 -0
- musica/profile.py +93 -0
- musica/profile_map.cpp +117 -0
- musica/profile_map.py +167 -0
- musica/test/examples/v1/full_configuration/full_configuration.json +91 -233
- musica/test/examples/v1/full_configuration/full_configuration.yaml +191 -290
- musica/test/integration/test_chapman.py +2 -2
- musica/test/integration/test_tuvx.py +72 -15
- musica/test/unit/test_grid.py +137 -0
- musica/test/unit/test_grid_map.py +126 -0
- musica/test/unit/test_parser.py +10 -10
- musica/test/unit/test_profile.py +169 -0
- musica/test/unit/test_profile_map.py +137 -0
- musica/test/unit/test_serializer.py +17 -16
- musica/test/unit/test_state.py +17 -4
- musica/test/unit/test_util_full_mechanism.py +78 -298
- musica/tuvx.cpp +94 -15
- musica/tuvx.py +92 -22
- musica/types.py +13 -5
- {musica-0.12.2.dist-info → musica-0.13.0.dist-info}/METADATA +14 -14
- musica-0.13.0.dist-info/RECORD +80 -0
- musica/mechanism_configuration/aqueous_equilibrium.py +0 -274
- musica/mechanism_configuration/condensed_phase_arrhenius.py +0 -309
- musica/mechanism_configuration/condensed_phase_photolysis.py +0 -88
- musica/mechanism_configuration/henrys_law.py +0 -44
- musica/mechanism_configuration/mechanism_configuration.py +0 -234
- musica/mechanism_configuration/simpol_phase_transfer.py +0 -217
- musica/mechanism_configuration/wet_deposition.py +0 -52
- musica-0.12.2.dist-info/RECORD +0 -70
- {musica-0.12.2.dist-info → musica-0.13.0.dist-info}/WHEEL +0 -0
- {musica-0.12.2.dist-info → musica-0.13.0.dist-info}/entry_points.txt +0 -0
- {musica-0.12.2.dist-info → musica-0.13.0.dist-info}/licenses/AUTHORS.md +0 -0
- {musica-0.12.2.dist-info → musica-0.13.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,55 +1,52 @@
|
|
|
1
1
|
import pytest
|
|
2
2
|
import os
|
|
3
|
-
from musica.mechanism_configuration import
|
|
3
|
+
from musica.mechanism_configuration import Mechanism, Parser
|
|
4
4
|
from test_util_full_mechanism import get_fully_defined_mechanism, validate_full_v1_mechanism
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
def test_mechanism_export_loop(tmp_path):
|
|
8
8
|
parser = Parser()
|
|
9
|
-
|
|
9
|
+
mechanism = get_fully_defined_mechanism()
|
|
10
10
|
extensions = [".yml", ".yaml", ".json"]
|
|
11
11
|
for extension in extensions:
|
|
12
12
|
path = f"{tmp_path}/test_mechanism{extension}"
|
|
13
|
-
|
|
13
|
+
mechanism.export(path)
|
|
14
14
|
mechanism = parser.parse(path)
|
|
15
15
|
validate_full_v1_mechanism(mechanism)
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
def test_serialize_parser_loop(tmp_path):
|
|
19
19
|
parser = Parser()
|
|
20
|
-
|
|
21
|
-
extensions = [".
|
|
20
|
+
mechanism = get_fully_defined_mechanism()
|
|
21
|
+
extensions = [".json", ".yml", ".yaml"]
|
|
22
22
|
for extension in extensions:
|
|
23
23
|
path = f"{tmp_path}/test_mechanism{extension}"
|
|
24
|
-
|
|
24
|
+
mechanism.export(path)
|
|
25
25
|
mechanism = parser.parse(path)
|
|
26
26
|
validate_full_v1_mechanism(mechanism)
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
def test_serialize_to_file(tmp_path):
|
|
30
|
-
|
|
30
|
+
mechanism = get_fully_defined_mechanism()
|
|
31
31
|
extensions = [".yml", ".yaml", ".json"]
|
|
32
32
|
for extension in extensions:
|
|
33
33
|
file_path = f'{tmp_path}/test_mechanism{extension}'
|
|
34
34
|
assert not os.path.exists(file_path)
|
|
35
|
-
|
|
35
|
+
mechanism.export(file_path)
|
|
36
36
|
assert os.path.exists(file_path)
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
def test_bad_inputs():
|
|
40
|
-
|
|
41
|
-
MechanismSerializer.serialize(None)
|
|
42
|
-
with pytest.raises(TypeError):
|
|
43
|
-
MechanismSerializer.serialize('not a mechanism')
|
|
40
|
+
mechanism = Mechanism(name="Full Configuration")
|
|
44
41
|
with pytest.raises(Exception):
|
|
45
|
-
|
|
42
|
+
mechanism.export("unsupported.txt")
|
|
46
43
|
|
|
47
44
|
|
|
48
45
|
def test_path_creation(tmp_path):
|
|
49
46
|
mechanism = Mechanism(name="Full Configuration")
|
|
50
47
|
path = f"{tmp_path}/non_existant_path/"
|
|
51
48
|
assert not os.path.exists(path)
|
|
52
|
-
|
|
49
|
+
mechanism.export(f"{path}test_mechanism.json")
|
|
53
50
|
assert os.path.exists(path)
|
|
54
51
|
|
|
55
52
|
|
|
@@ -59,11 +56,15 @@ def test_overwrite_file(tmp_path):
|
|
|
59
56
|
assert not os.path.exists(file_path)
|
|
60
57
|
|
|
61
58
|
# write first file
|
|
62
|
-
|
|
59
|
+
mechanism.export(file_path)
|
|
63
60
|
files = list(tmp_path.iterdir())
|
|
64
61
|
assert len(files) == 1
|
|
65
62
|
|
|
66
63
|
# overwrite file
|
|
67
|
-
|
|
64
|
+
mechanism.export(file_path)
|
|
68
65
|
files = list(tmp_path.iterdir())
|
|
69
66
|
assert len(files) == 1
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
if __name__ == "__main__":
|
|
70
|
+
pytest.main([__file__])
|
musica/test/unit/test_state.py
CHANGED
|
@@ -12,8 +12,7 @@ def create_test_mechanism() -> Mechanism:
|
|
|
12
12
|
# Chemical species
|
|
13
13
|
A = mc.Species(
|
|
14
14
|
name="A",
|
|
15
|
-
|
|
16
|
-
molecular_weight_kg_mol=13.2,
|
|
15
|
+
molecular_weight_kg_mol=32.1,
|
|
17
16
|
other_properties={
|
|
18
17
|
"__absolute tolerance": "1.0e-30"})
|
|
19
18
|
B = mc.Species(name="B")
|
|
@@ -21,7 +20,7 @@ def create_test_mechanism() -> Mechanism:
|
|
|
21
20
|
M = mc.Species(name="M", is_third_body=True)
|
|
22
21
|
|
|
23
22
|
# Chemical phases
|
|
24
|
-
gas = mc.Phase(name="gas", species=[A, B, C, M])
|
|
23
|
+
gas = mc.Phase(name="gas", species=[mc.PhaseSpecies(name=A.name, diffusion_coefficient_m2_s=1.0), B, C, M])
|
|
25
24
|
|
|
26
25
|
# Reactions
|
|
27
26
|
my_arrhenius = mc.Arrhenius(
|
|
@@ -146,7 +145,8 @@ def create_test_mechanism() -> Mechanism:
|
|
|
146
145
|
species=[A, B, C, M],
|
|
147
146
|
phases=[gas],
|
|
148
147
|
reactions=[my_arrhenius, my_other_arrhenius, my_troe, my_ternary,
|
|
149
|
-
my_branched, my_tunneling,
|
|
148
|
+
my_branched, my_tunneling,
|
|
149
|
+
my_surface, photo_b,
|
|
150
150
|
my_emission, my_first_order_loss, user_defined],
|
|
151
151
|
version=mc.Version(1, 0, 0),
|
|
152
152
|
)
|
|
@@ -259,6 +259,15 @@ def test_set_get_user_defined_rate_parameters():
|
|
|
259
259
|
result = state.get_user_defined_rate_parameters()
|
|
260
260
|
assert result["EMIS.my emission"][0] == 1.0
|
|
261
261
|
|
|
262
|
+
params = {
|
|
263
|
+
"SURF.my surface.effective radius [m]": 0.5,
|
|
264
|
+
"SURF.my surface.particle number concentration [# m-3]": 1000.0,
|
|
265
|
+
}
|
|
266
|
+
state.set_user_defined_rate_parameters(params)
|
|
267
|
+
result = state.get_user_defined_rate_parameters()
|
|
268
|
+
assert result["SURF.my surface.effective radius [m]"][0] == 0.5
|
|
269
|
+
assert result["SURF.my surface.particle number concentration [# m-3]"][0] == 1000.0
|
|
270
|
+
|
|
262
271
|
# Test multiple grid cells
|
|
263
272
|
state_multi = solver.create_state(number_of_grid_cells=2)
|
|
264
273
|
params_multi = {"PHOTO.photo B": [1.0, 2.0]}
|
|
@@ -323,3 +332,7 @@ def test_set_get_user_defined_rate_parameters():
|
|
|
323
332
|
"USER.my user defined"
|
|
324
333
|
]
|
|
325
334
|
assert sorted(expected_params) == sorted(param_names)
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
if __name__ == "__main__":
|
|
338
|
+
pytest.main([__file__])
|
|
@@ -1,71 +1,35 @@
|
|
|
1
1
|
import musica.mechanism_configuration as mc
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
def get_fully_defined_mechanism():
|
|
4
|
+
def get_fully_defined_mechanism() -> mc.Mechanism:
|
|
5
5
|
# Chemical species
|
|
6
|
-
A = mc.Species(name="A", other_properties={"__absolute tolerance": "1.0e-30"})
|
|
7
|
-
B = mc.Species(name="B",
|
|
8
|
-
C = mc.Species(name="C",
|
|
9
|
-
M = mc.Species(name="M")
|
|
6
|
+
A = mc.Species(name="A", molecular_weight_kg_mol=0.02897, other_properties={"__absolute tolerance": "1.0e-30"})
|
|
7
|
+
B = mc.Species(name="B", constant_concentration_mol_m3=1e19)
|
|
8
|
+
C = mc.Species(name="C", constant_mixing_ratio_mol_mol=1e-20)
|
|
9
|
+
M = mc.Species(name="M", is_third_body=True)
|
|
10
10
|
H2O2 = mc.Species(
|
|
11
11
|
name="H2O2",
|
|
12
|
-
HLC_298K_mol_m3_Pa=1.011596348,
|
|
13
|
-
HLC_exponential_factor_K=6340,
|
|
14
|
-
diffusion_coefficient_m2_s=1.46e-05,
|
|
15
|
-
N_star=1.74,
|
|
16
12
|
molecular_weight_kg_mol=0.0340147,
|
|
17
|
-
density_kg_m3=1000.0,
|
|
18
13
|
other_properties={"__absolute tolerance": "1.0e-10"},
|
|
19
14
|
)
|
|
20
15
|
ethanol = mc.Species(
|
|
21
16
|
name="ethanol",
|
|
22
|
-
diffusion_coefficient_m2_s=0.95e-05,
|
|
23
|
-
N_star=2.55,
|
|
24
17
|
molecular_weight_kg_mol=0.04607,
|
|
25
18
|
other_properties={"__absolute tolerance": "1.0e-20"},
|
|
26
19
|
)
|
|
27
|
-
ethanol_aq = mc.Species(
|
|
28
|
-
name="ethanol_aq",
|
|
29
|
-
molecular_weight_kg_mol=0.04607,
|
|
30
|
-
density_kg_m3=1000.0,
|
|
31
|
-
other_properties={"__absolute tolerance": "1.0e-20"},
|
|
32
|
-
)
|
|
33
|
-
H2O2_aq = mc.Species(
|
|
34
|
-
name="H2O2_aq",
|
|
35
|
-
molecular_weight_kg_mol=0.0340147,
|
|
36
|
-
density_kg_m3=1000.0,
|
|
37
|
-
other_properties={"__absolute tolerance": "1.0e-10"},
|
|
38
|
-
)
|
|
39
|
-
H2O_aq = mc.Species(
|
|
40
|
-
name="H2O_aq",
|
|
41
|
-
density_kg_m3=1000.0,
|
|
42
|
-
molecular_weight_kg_mol=0.01801,
|
|
43
|
-
)
|
|
44
|
-
aerosol_stuff = mc.Species(
|
|
45
|
-
name="aerosol stuff",
|
|
46
|
-
molecular_weight_kg_mol=0.5,
|
|
47
|
-
density_kg_m3=1000.0,
|
|
48
|
-
other_properties={"__absolute tolerance": "1.0e-20"},
|
|
49
|
-
)
|
|
50
|
-
more_aerosol_stuff = mc.Species(
|
|
51
|
-
name="more aerosol stuff",
|
|
52
|
-
molecular_weight_kg_mol=0.2,
|
|
53
|
-
density_kg_m3=1000.0,
|
|
54
|
-
other_properties={"__absolute tolerance": "1.0e-20"},
|
|
55
|
-
)
|
|
56
20
|
|
|
57
21
|
# Chemical phases
|
|
58
|
-
gas = mc.Phase(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
22
|
+
gas = mc.Phase(
|
|
23
|
+
name="gas",
|
|
24
|
+
species=[
|
|
25
|
+
mc.PhaseSpecies(
|
|
26
|
+
name=A.name,
|
|
27
|
+
diffusion_coefficient_m2_s=1.0),
|
|
28
|
+
B,
|
|
29
|
+
C,
|
|
30
|
+
ethanol,
|
|
31
|
+
H2O2,
|
|
32
|
+
M])
|
|
69
33
|
|
|
70
34
|
# Reactions
|
|
71
35
|
my_arrhenius = mc.Arrhenius(
|
|
@@ -85,31 +49,6 @@ def get_fully_defined_mechanism():
|
|
|
85
49
|
products=[(1.2, B)]
|
|
86
50
|
)
|
|
87
51
|
|
|
88
|
-
my_condensed_arrhenius = mc.CondensedPhaseArrhenius(
|
|
89
|
-
name="my condensed arrhenius",
|
|
90
|
-
condensed_phase=aqueous_aerosol,
|
|
91
|
-
A=123.45,
|
|
92
|
-
B=1.3,
|
|
93
|
-
Ea=123.45,
|
|
94
|
-
D=300.0,
|
|
95
|
-
E=0.6e-5,
|
|
96
|
-
reactants=[H2O2_aq, H2O_aq],
|
|
97
|
-
products=[ethanol_aq],
|
|
98
|
-
other_properties={"__irrelevant": "2"},
|
|
99
|
-
)
|
|
100
|
-
|
|
101
|
-
my_other_condensed_arrhenius = mc.CondensedPhaseArrhenius(
|
|
102
|
-
name="my other condensed arrhenius",
|
|
103
|
-
condensed_phase=aqueous_aerosol,
|
|
104
|
-
A=123.45,
|
|
105
|
-
B=1.3,
|
|
106
|
-
C=123.45,
|
|
107
|
-
D=300.0,
|
|
108
|
-
E=0.6e-5,
|
|
109
|
-
reactants=[H2O2_aq, H2O_aq],
|
|
110
|
-
products=[ethanol_aq]
|
|
111
|
-
)
|
|
112
|
-
|
|
113
52
|
my_troe = mc.Troe(
|
|
114
53
|
name="my troe",
|
|
115
54
|
gas_phase=gas,
|
|
@@ -172,7 +111,6 @@ def get_fully_defined_mechanism():
|
|
|
172
111
|
gas_phase_species=A,
|
|
173
112
|
reaction_probability=2.0e-2,
|
|
174
113
|
gas_phase_products=[B, C],
|
|
175
|
-
condensed_phase=surface_reacting_phase,
|
|
176
114
|
other_properties={"__irrelevant": "2"},
|
|
177
115
|
)
|
|
178
116
|
|
|
@@ -185,15 +123,6 @@ def get_fully_defined_mechanism():
|
|
|
185
123
|
other_properties={"__irrelevant": "2"},
|
|
186
124
|
)
|
|
187
125
|
|
|
188
|
-
condensed_photo_B = mc.CondensedPhasePhotolysis(
|
|
189
|
-
name="condensed photo B",
|
|
190
|
-
condensed_phase=aqueous_aerosol,
|
|
191
|
-
reactants=[H2O2_aq],
|
|
192
|
-
products=[ethanol_aq],
|
|
193
|
-
scaling_factor=12.3,
|
|
194
|
-
other_properties={"__irrelevant": "2"},
|
|
195
|
-
)
|
|
196
|
-
|
|
197
126
|
my_emission = mc.Emission(
|
|
198
127
|
name="my emission",
|
|
199
128
|
gas_phase=gas,
|
|
@@ -210,35 +139,6 @@ def get_fully_defined_mechanism():
|
|
|
210
139
|
other_properties={"__irrelevant": "2"},
|
|
211
140
|
)
|
|
212
141
|
|
|
213
|
-
my_aqueous_equilibrium = mc.AqueousEquilibrium(
|
|
214
|
-
name="my aqueous eq",
|
|
215
|
-
condensed_phase=aqueous_aerosol,
|
|
216
|
-
condensed_phase_water=H2O_aq,
|
|
217
|
-
A=1.14e-2,
|
|
218
|
-
C=2300.0,
|
|
219
|
-
k_reverse=0.32,
|
|
220
|
-
reactants=[(2, A)],
|
|
221
|
-
products=[B, C],
|
|
222
|
-
other_properties={"__irrelevant": "2"},
|
|
223
|
-
)
|
|
224
|
-
|
|
225
|
-
my_wet_deposition = mc.WetDeposition(
|
|
226
|
-
name="rxn cloud",
|
|
227
|
-
condensed_phase=cloud,
|
|
228
|
-
scaling_factor=12.3,
|
|
229
|
-
other_properties={"__irrelevant": "2"},
|
|
230
|
-
)
|
|
231
|
-
|
|
232
|
-
my_simpol_phase_transfer = mc.SimpolPhaseTransfer(
|
|
233
|
-
name="my simpol",
|
|
234
|
-
gas_phase=gas,
|
|
235
|
-
gas_phase_species=ethanol,
|
|
236
|
-
condensed_phase=aqueous_aerosol,
|
|
237
|
-
condensed_phase_species=ethanol_aq,
|
|
238
|
-
B=[-1.97e03, 2.91e00, 1.96e-03, -4.96e-01],
|
|
239
|
-
other_properties={"__irrelevant": "2"},
|
|
240
|
-
)
|
|
241
|
-
|
|
242
142
|
user_defined = mc.UserDefined(
|
|
243
143
|
name="my user defined",
|
|
244
144
|
gas_phase=gas,
|
|
@@ -248,18 +148,29 @@ def get_fully_defined_mechanism():
|
|
|
248
148
|
other_properties={"__irrelevant": "2"}
|
|
249
149
|
)
|
|
250
150
|
|
|
151
|
+
taylor_series_reaction = mc.TaylorSeries(
|
|
152
|
+
name="my taylor series",
|
|
153
|
+
gas_phase=gas,
|
|
154
|
+
A=12.3,
|
|
155
|
+
B=-1.5,
|
|
156
|
+
C=1.0e-6,
|
|
157
|
+
D=340,
|
|
158
|
+
E=0.00032,
|
|
159
|
+
reactants=[B],
|
|
160
|
+
products=[C],
|
|
161
|
+
other_properties={"__irrelevant": "2"}
|
|
162
|
+
)
|
|
163
|
+
|
|
251
164
|
# Mechanism
|
|
252
165
|
return mc.Mechanism(
|
|
253
166
|
name="Full Configuration",
|
|
254
|
-
species=[A, B, C, M, H2O2, ethanol,
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
my_wet_deposition, my_simpol_phase_transfer,
|
|
262
|
-
user_defined],
|
|
167
|
+
species=[A, B, C, M, H2O2, ethanol],
|
|
168
|
+
phases=[gas],
|
|
169
|
+
reactions=[my_arrhenius, my_other_arrhenius, my_troe, my_ternary, my_branched,
|
|
170
|
+
my_tunneling, my_surface, photo_B,
|
|
171
|
+
my_emission, my_first_order_loss, user_defined,
|
|
172
|
+
taylor_series_reaction
|
|
173
|
+
],
|
|
263
174
|
version=mc.Version(1, 0, 0),
|
|
264
175
|
)
|
|
265
176
|
|
|
@@ -267,49 +178,25 @@ def get_fully_defined_mechanism():
|
|
|
267
178
|
def _validate_species(species):
|
|
268
179
|
# Define the expected species and their required attributes
|
|
269
180
|
expected_species = {
|
|
270
|
-
"A": {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
"M": {},
|
|
274
|
-
"H2O2": {
|
|
275
|
-
"HLC_298K_mol_m3_Pa": 1.011596348,
|
|
276
|
-
"HLC_exponential_factor_K": 6340,
|
|
277
|
-
"diffusion_coefficient_m2_s": 1.46e-05,
|
|
278
|
-
"N_star": 1.74,
|
|
279
|
-
"molecular_weight_kg_mol": 0.0340147,
|
|
280
|
-
"density_kg_m3": 1000.0,
|
|
281
|
-
"other_properties": {"__absolute tolerance": "1e-10"},
|
|
181
|
+
"A": {
|
|
182
|
+
"molecular_weight_kg_mol": 0.02897,
|
|
183
|
+
"other_properties": {"__absolute tolerance": "1e-30"}
|
|
282
184
|
},
|
|
283
|
-
"
|
|
284
|
-
"
|
|
285
|
-
"N_star": 2.55,
|
|
286
|
-
"molecular_weight_kg_mol": 0.04607,
|
|
287
|
-
"other_properties": {"__absolute tolerance": "1e-20"},
|
|
185
|
+
"B": {
|
|
186
|
+
"constant_concentration_mol_m3": 1e19,
|
|
288
187
|
},
|
|
289
|
-
"
|
|
290
|
-
"
|
|
291
|
-
"density_kg_m3": 1000.0,
|
|
292
|
-
"other_properties": {"__absolute tolerance": "1e-20"},
|
|
188
|
+
"C": {
|
|
189
|
+
"constant_mixing_ratio_mol_mol": 1e-20,
|
|
293
190
|
},
|
|
294
|
-
"
|
|
191
|
+
"M": {"is_third_body": True},
|
|
192
|
+
"H2O2": {
|
|
295
193
|
"molecular_weight_kg_mol": 0.0340147,
|
|
296
|
-
"density_kg_m3": 1000.0,
|
|
297
194
|
"other_properties": {"__absolute tolerance": "1e-10"},
|
|
298
195
|
},
|
|
299
|
-
"
|
|
300
|
-
"
|
|
301
|
-
"molecular_weight_kg_mol": 0.01801,
|
|
302
|
-
},
|
|
303
|
-
"aerosol stuff": {
|
|
304
|
-
"molecular_weight_kg_mol": 0.5,
|
|
305
|
-
"density_kg_m3": 1000.0,
|
|
306
|
-
"other_properties": {"__absolute tolerance": "1e-20"},
|
|
307
|
-
},
|
|
308
|
-
"more aerosol stuff": {
|
|
309
|
-
"molecular_weight_kg_mol": 0.2,
|
|
310
|
-
"density_kg_m3": 1000.0,
|
|
196
|
+
"ethanol": {
|
|
197
|
+
"molecular_weight_kg_mol": 0.04607,
|
|
311
198
|
"other_properties": {"__absolute tolerance": "1e-20"},
|
|
312
|
-
}
|
|
199
|
+
}
|
|
313
200
|
}
|
|
314
201
|
|
|
315
202
|
# Create a dictionary for quick lookup of species by name
|
|
@@ -341,28 +228,14 @@ def _validate_species(species):
|
|
|
341
228
|
|
|
342
229
|
|
|
343
230
|
def _validate_phases(phases):
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
# Create a dictionary for quick lookup of phases by name
|
|
353
|
-
phases_dict = {phase.name: phase for phase in phases}
|
|
354
|
-
|
|
355
|
-
# Validate each expected phase
|
|
356
|
-
for name, expected_species in expected_phases.items():
|
|
357
|
-
assert name in phases_dict, f"Phase '{name}' is missing."
|
|
358
|
-
assert hasattr(
|
|
359
|
-
phases_dict[name], "species"
|
|
360
|
-
), f"Phase '{name}' does not have a 'species' attribute."
|
|
361
|
-
phase_species = getattr(phases_dict[name], "species")
|
|
362
|
-
assert set(phase_species) == set(expected_species), (
|
|
363
|
-
f"Phase '{name}' has species {phase_species}, "
|
|
364
|
-
f"expected {expected_species}."
|
|
365
|
-
)
|
|
231
|
+
assert len(phases) == 1
|
|
232
|
+
assert phases[0].name == "gas"
|
|
233
|
+
assert phases[0].species[0].name == "A"
|
|
234
|
+
assert phases[0].species[0].diffusion_coefficient_m2_s == 1.0
|
|
235
|
+
assert phases[0].species[1].name == "B"
|
|
236
|
+
assert phases[0].species[2].name == "C"
|
|
237
|
+
assert phases[0].species[3].name == "ethanol"
|
|
238
|
+
assert phases[0].species[4].name == "H2O2"
|
|
366
239
|
|
|
367
240
|
|
|
368
241
|
def _extract_components(components):
|
|
@@ -403,75 +276,6 @@ def _validate_arrhenius(reactions):
|
|
|
403
276
|
assert reactions[1].other_properties == {}
|
|
404
277
|
|
|
405
278
|
|
|
406
|
-
def _validate_simpol_phase_transfer(reactions):
|
|
407
|
-
assert reactions[0].type == mc.ReactionType.SimpolPhaseTransfer
|
|
408
|
-
assert reactions[0].gas_phase == "gas"
|
|
409
|
-
assert _extract_components([reactions[0].gas_phase_species]) == [
|
|
410
|
-
{"species name": "ethanol", "coefficient": 1}
|
|
411
|
-
]
|
|
412
|
-
assert reactions[0].condensed_phase == "aqueous aerosol"
|
|
413
|
-
assert _extract_components([reactions[0].condensed_phase_species]) == [
|
|
414
|
-
{"species name": "ethanol_aq", "coefficient": 1}
|
|
415
|
-
]
|
|
416
|
-
assert reactions[0].B == [-1.97e03, 2.91e00, 1.96e-03, -4.96e-01]
|
|
417
|
-
assert reactions[0].name == "my simpol"
|
|
418
|
-
assert reactions[0].other_properties == {"__irrelevant": "2"}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
def _validate_aqueous_equilibrium(reactions):
|
|
422
|
-
assert reactions[0].type == mc.ReactionType.AqueousEquilibrium
|
|
423
|
-
assert reactions[0].condensed_phase == "aqueous aerosol"
|
|
424
|
-
assert reactions[0].condensed_phase_water == "H2O_aq"
|
|
425
|
-
assert reactions[0].A == 1.14e-2
|
|
426
|
-
assert reactions[0].C == 2300.0
|
|
427
|
-
assert reactions[0].k_reverse == 0.32
|
|
428
|
-
assert _extract_components(reactions[0].reactants) == [
|
|
429
|
-
{"species name": "A", "coefficient": 2}
|
|
430
|
-
]
|
|
431
|
-
assert _extract_components(reactions[0].products) == [
|
|
432
|
-
{"species name": "B", "coefficient": 1},
|
|
433
|
-
{"species name": "C", "coefficient": 1},
|
|
434
|
-
]
|
|
435
|
-
assert reactions[0].name == "my aqueous eq"
|
|
436
|
-
assert reactions[0].other_properties == {"__irrelevant": "2"}
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
def _validate_condensed_phase_arrhenius(reactions):
|
|
440
|
-
for reaction in reactions:
|
|
441
|
-
assert reaction.type == mc.ReactionType.CondensedPhaseArrhenius
|
|
442
|
-
assert reaction.condensed_phase == "aqueous aerosol"
|
|
443
|
-
assert reaction.A == 123.45
|
|
444
|
-
assert reaction.B == 1.3
|
|
445
|
-
assert reaction.D == 300.0
|
|
446
|
-
assert reaction.E == 0.6e-5
|
|
447
|
-
assert _extract_components(reaction.reactants) == [
|
|
448
|
-
{"species name": "H2O2_aq", "coefficient": 1},
|
|
449
|
-
{"species name": "H2O_aq", "coefficient": 1},
|
|
450
|
-
]
|
|
451
|
-
assert _extract_components(reaction.products) == [
|
|
452
|
-
{"species name": "ethanol_aq", "coefficient": 1}
|
|
453
|
-
]
|
|
454
|
-
assert reactions[0].name == "my condensed arrhenius"
|
|
455
|
-
assert reactions[0].C == -123.45 / 1.380649e-23
|
|
456
|
-
assert reactions[0].other_properties == {"__irrelevant": "2"}
|
|
457
|
-
assert reactions[1].name == "my other condensed arrhenius"
|
|
458
|
-
assert reactions[1].C == 123.45
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
def _validate_condensed_phase_photolysis(reactions):
|
|
462
|
-
assert reactions[0].type == mc.ReactionType.CondensedPhasePhotolysis
|
|
463
|
-
assert reactions[0].condensed_phase == "aqueous aerosol"
|
|
464
|
-
assert _extract_components(reactions[0].reactants) == [
|
|
465
|
-
{"species name": "H2O2_aq", "coefficient": 1}
|
|
466
|
-
]
|
|
467
|
-
assert _extract_components(reactions[0].products) == [
|
|
468
|
-
{"species name": "ethanol_aq", "coefficient": 1}
|
|
469
|
-
]
|
|
470
|
-
assert reactions[0].scaling_factor == 12.3
|
|
471
|
-
assert reactions[0].name == "condensed photo B"
|
|
472
|
-
assert reactions[0].other_properties == {"__irrelevant": "2"}
|
|
473
|
-
|
|
474
|
-
|
|
475
279
|
def _validate_emission(reactions):
|
|
476
280
|
assert reactions[0].type == mc.ReactionType.Emission
|
|
477
281
|
assert reactions[0].gas_phase == "gas"
|
|
@@ -519,7 +323,6 @@ def _validate_surface(reactions):
|
|
|
519
323
|
{"species name": "B", "coefficient": 1},
|
|
520
324
|
{"species name": "C", "coefficient": 1},
|
|
521
325
|
]
|
|
522
|
-
assert reactions[0].condensed_phase == "surface reacting phase"
|
|
523
326
|
assert reactions[0].name == "my surface"
|
|
524
327
|
assert reactions[0].other_properties == {"__irrelevant": "2"}
|
|
525
328
|
|
|
@@ -568,28 +371,6 @@ def _validate_ternary_chemical_activation(reactions):
|
|
|
568
371
|
assert reactions[0].other_properties == {"__irrelevant": "2"}
|
|
569
372
|
|
|
570
373
|
|
|
571
|
-
def _validate_ternary_chemical_activation(reactions):
|
|
572
|
-
assert reactions[0].type == mc.ReactionType.TernaryChemicalActivation
|
|
573
|
-
assert reactions[0].gas_phase == "gas"
|
|
574
|
-
assert _extract_components(reactions[0].reactants) == [
|
|
575
|
-
{"species name": "B", "coefficient": 1},
|
|
576
|
-
{"species name": "M", "coefficient": 1},
|
|
577
|
-
]
|
|
578
|
-
assert _extract_components(reactions[0].products) == [
|
|
579
|
-
{"species name": "C", "coefficient": 1}
|
|
580
|
-
]
|
|
581
|
-
assert reactions[0].k0_A == 32.1
|
|
582
|
-
assert reactions[0].k0_B == -2.3
|
|
583
|
-
assert reactions[0].k0_C == 102.3
|
|
584
|
-
assert reactions[0].kinf_A == 63.4
|
|
585
|
-
assert reactions[0].kinf_B == -1.3
|
|
586
|
-
assert reactions[0].kinf_C == 908.5
|
|
587
|
-
assert reactions[0].Fc == 1.3
|
|
588
|
-
assert reactions[0].N == 32.1
|
|
589
|
-
assert reactions[0].name == "my ternary chemical activation"
|
|
590
|
-
assert reactions[0].other_properties == {"__irrelevant": "2"}
|
|
591
|
-
|
|
592
|
-
|
|
593
374
|
def _validate_branched_no_ro2(reactions):
|
|
594
375
|
assert reactions[0].type == mc.ReactionType.Branched
|
|
595
376
|
assert reactions[0].gas_phase == "gas"
|
|
@@ -626,14 +407,6 @@ def _validate_tunneling(reactions):
|
|
|
626
407
|
assert reactions[0].other_properties == {"__irrelevant": "2"}
|
|
627
408
|
|
|
628
409
|
|
|
629
|
-
def _validate_wet_deposition(reactions):
|
|
630
|
-
assert reactions[0].type == mc.ReactionType.WetDeposition
|
|
631
|
-
assert reactions[0].name == "rxn cloud"
|
|
632
|
-
assert reactions[0].condensed_phase == "cloud"
|
|
633
|
-
assert reactions[0].scaling_factor == 12.3
|
|
634
|
-
assert reactions[0].other_properties == {"__irrelevant": "2"}
|
|
635
|
-
|
|
636
|
-
|
|
637
410
|
def _validate_user_defined(reactions):
|
|
638
411
|
assert reactions[0].type == mc.ReactionType.UserDefined
|
|
639
412
|
assert reactions[0].gas_phase == "gas"
|
|
@@ -650,33 +423,40 @@ def _validate_user_defined(reactions):
|
|
|
650
423
|
assert reactions[0].other_properties == {"__irrelevant": "2"}
|
|
651
424
|
|
|
652
425
|
|
|
426
|
+
def _validate_taylor_series(reactions):
|
|
427
|
+
assert reactions[0].type == mc.ReactionType.TaylorSeries
|
|
428
|
+
assert reactions[0].gas_phase == "gas"
|
|
429
|
+
assert _extract_components(reactions[0].reactants) == [
|
|
430
|
+
{"species name": "B", "coefficient": 1}
|
|
431
|
+
]
|
|
432
|
+
assert _extract_components(reactions[0].products) == [
|
|
433
|
+
{"species name": "C", "coefficient": 1}
|
|
434
|
+
]
|
|
435
|
+
assert reactions[0].A == 12.3
|
|
436
|
+
assert reactions[0].B == -1.5
|
|
437
|
+
assert reactions[0].C == 1.0e-6
|
|
438
|
+
assert reactions[0].D == 340
|
|
439
|
+
assert reactions[0].E == 0.00032
|
|
440
|
+
assert reactions[0].name == "my taylor series"
|
|
441
|
+
|
|
442
|
+
|
|
653
443
|
def validate_full_v1_mechanism(mechanism):
|
|
654
444
|
assert mechanism is not None
|
|
655
445
|
assert mechanism.name == "Full Configuration"
|
|
656
|
-
assert len(mechanism.species) ==
|
|
446
|
+
assert len(mechanism.species) == 6
|
|
657
447
|
_validate_species(mechanism.species)
|
|
658
|
-
assert len(mechanism.phases) ==
|
|
448
|
+
assert len(mechanism.phases) == 1
|
|
659
449
|
_validate_phases(mechanism.phases)
|
|
660
|
-
assert len(mechanism.reactions.aqueous_equilibrium) == 1
|
|
661
|
-
_validate_aqueous_equilibrium(mechanism.reactions.aqueous_equilibrium)
|
|
662
450
|
assert len(mechanism.reactions.arrhenius) == 2
|
|
663
451
|
_validate_arrhenius(mechanism.reactions.arrhenius)
|
|
664
452
|
assert len(mechanism.reactions.branched) == 1
|
|
665
453
|
_validate_branched_no_ro2(mechanism.reactions.branched)
|
|
666
|
-
assert len(mechanism.reactions.condensed_phase_arrhenius) == 2
|
|
667
|
-
_validate_condensed_phase_arrhenius(mechanism.reactions.condensed_phase_arrhenius)
|
|
668
|
-
assert len(mechanism.reactions.condensed_phase_photolysis) == 1
|
|
669
|
-
_validate_condensed_phase_photolysis(
|
|
670
|
-
mechanism.reactions.condensed_phase_photolysis
|
|
671
|
-
)
|
|
672
454
|
assert len(mechanism.reactions.emission) == 1
|
|
673
455
|
_validate_emission(mechanism.reactions.emission)
|
|
674
456
|
assert len(mechanism.reactions.first_order_loss) == 1
|
|
675
457
|
_validate_first_order_loss(mechanism.reactions.first_order_loss)
|
|
676
458
|
assert len(mechanism.reactions.photolysis) == 1
|
|
677
459
|
_validate_photolysis(mechanism.reactions.photolysis)
|
|
678
|
-
assert len(mechanism.reactions.simpol_phase_transfer) == 1
|
|
679
|
-
_validate_simpol_phase_transfer(mechanism.reactions.simpol_phase_transfer)
|
|
680
460
|
assert len(mechanism.reactions.surface) == 1
|
|
681
461
|
_validate_surface(mechanism.reactions.surface)
|
|
682
462
|
assert len(mechanism.reactions.troe) == 1
|
|
@@ -685,14 +465,14 @@ def validate_full_v1_mechanism(mechanism):
|
|
|
685
465
|
_validate_ternary_chemical_activation(mechanism.reactions.ternary_chemical_activation)
|
|
686
466
|
assert len(mechanism.reactions.tunneling) == 1
|
|
687
467
|
_validate_tunneling(mechanism.reactions.tunneling)
|
|
688
|
-
assert len(mechanism.reactions.wet_deposition) == 1
|
|
689
|
-
_validate_wet_deposition(mechanism.reactions.wet_deposition)
|
|
690
468
|
assert len(mechanism.reactions.user_defined) == 1
|
|
691
469
|
_validate_user_defined(mechanism.reactions.user_defined)
|
|
470
|
+
assert len(mechanism.reactions.taylor_series) == 1
|
|
471
|
+
_validate_taylor_series(mechanism.reactions.taylor_series)
|
|
692
472
|
assert mechanism.version.major == 1
|
|
693
473
|
assert mechanism.version.minor == 0
|
|
694
474
|
assert mechanism.version.patch == 0
|
|
695
|
-
assert len(mechanism.reactions) ==
|
|
475
|
+
assert len(mechanism.reactions) == 12
|
|
696
476
|
for reaction in mechanism.reactions:
|
|
697
477
|
assert reaction is not None
|
|
698
478
|
assert isinstance(reaction.type, mc.ReactionType)
|