musica 0.12.2__cp311-cp311-macosx_15_0_x86_64.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.

Files changed (80) hide show
  1. musica/.dylibs/libaec.0.1.4.dylib +0 -0
  2. musica/.dylibs/libgcc_s.1.1.dylib +0 -0
  3. musica/.dylibs/libgfortran.5.dylib +0 -0
  4. musica/.dylibs/libhdf5.310.5.1.dylib +0 -0
  5. musica/.dylibs/libhdf5_hl.310.0.6.dylib +0 -0
  6. musica/.dylibs/libnetcdf.22.dylib +0 -0
  7. musica/.dylibs/libnetcdff.7.1.0.dylib +0 -0
  8. musica/.dylibs/libquadmath.0.dylib +0 -0
  9. musica/.dylibs/libsz.2.0.1.dylib +0 -0
  10. musica/.dylibs/libzstd.1.5.7.dylib +0 -0
  11. musica/CMakeLists.txt +68 -0
  12. musica/__init__.py +11 -0
  13. musica/_musica.cpython-311-darwin.so +0 -0
  14. musica/_version.py +1 -0
  15. musica/backend.py +41 -0
  16. musica/binding_common.cpp +33 -0
  17. musica/binding_common.hpp +7 -0
  18. musica/carma.cpp +911 -0
  19. musica/carma.py +1729 -0
  20. musica/constants.py +3 -0
  21. musica/cpu_binding.cpp +11 -0
  22. musica/cuda.cpp +12 -0
  23. musica/cuda.py +13 -0
  24. musica/examples/__init__.py +1 -0
  25. musica/examples/carma_aluminum.py +124 -0
  26. musica/examples/carma_sulfate.py +246 -0
  27. musica/examples/examples.py +165 -0
  28. musica/examples/sulfate_box_model.py +439 -0
  29. musica/examples/ts1_latin_hypercube.py +245 -0
  30. musica/gpu_binding.cpp +11 -0
  31. musica/main.py +89 -0
  32. musica/mechanism_configuration/__init__.py +1 -0
  33. musica/mechanism_configuration/aqueous_equilibrium.py +274 -0
  34. musica/mechanism_configuration/arrhenius.py +307 -0
  35. musica/mechanism_configuration/branched.py +299 -0
  36. musica/mechanism_configuration/condensed_phase_arrhenius.py +309 -0
  37. musica/mechanism_configuration/condensed_phase_photolysis.py +88 -0
  38. musica/mechanism_configuration/emission.py +71 -0
  39. musica/mechanism_configuration/first_order_loss.py +174 -0
  40. musica/mechanism_configuration/henrys_law.py +44 -0
  41. musica/mechanism_configuration/mechanism_configuration.py +234 -0
  42. musica/mechanism_configuration/phase.py +47 -0
  43. musica/mechanism_configuration/photolysis.py +88 -0
  44. musica/mechanism_configuration/reactions.py +73 -0
  45. musica/mechanism_configuration/simpol_phase_transfer.py +217 -0
  46. musica/mechanism_configuration/species.py +91 -0
  47. musica/mechanism_configuration/surface.py +94 -0
  48. musica/mechanism_configuration/ternary_chemical_activation.py +352 -0
  49. musica/mechanism_configuration/troe.py +352 -0
  50. musica/mechanism_configuration/tunneling.py +250 -0
  51. musica/mechanism_configuration/user_defined.py +88 -0
  52. musica/mechanism_configuration/utils.py +10 -0
  53. musica/mechanism_configuration/wet_deposition.py +52 -0
  54. musica/mechanism_configuration.cpp +607 -0
  55. musica/musica.cpp +201 -0
  56. musica/test/examples/v1/full_configuration/full_configuration.json +466 -0
  57. musica/test/examples/v1/full_configuration/full_configuration.yaml +295 -0
  58. musica/test/integration/test_analytical.py +324 -0
  59. musica/test/integration/test_carma.py +227 -0
  60. musica/test/integration/test_carma_aluminum.py +12 -0
  61. musica/test/integration/test_carma_sulfate.py +17 -0
  62. musica/test/integration/test_chapman.py +139 -0
  63. musica/test/integration/test_sulfate_box_model.py +34 -0
  64. musica/test/integration/test_tuvx.py +62 -0
  65. musica/test/unit/test_parser.py +64 -0
  66. musica/test/unit/test_serializer.py +69 -0
  67. musica/test/unit/test_state.py +325 -0
  68. musica/test/unit/test_util_full_mechanism.py +698 -0
  69. musica/tools/prepare_build_environment_linux.sh +32 -0
  70. musica/tools/prepare_build_environment_macos.sh +1 -0
  71. musica/tools/repair_wheel_gpu.sh +40 -0
  72. musica/tuvx.cpp +93 -0
  73. musica/tuvx.py +199 -0
  74. musica/types.py +407 -0
  75. musica-0.12.2.dist-info/METADATA +473 -0
  76. musica-0.12.2.dist-info/RECORD +80 -0
  77. musica-0.12.2.dist-info/WHEEL +6 -0
  78. musica-0.12.2.dist-info/entry_points.txt +3 -0
  79. musica-0.12.2.dist-info/licenses/AUTHORS.md +59 -0
  80. musica-0.12.2.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,698 @@
1
+ import musica.mechanism_configuration as mc
2
+
3
+
4
+ def get_fully_defined_mechanism():
5
+ # Chemical species
6
+ A = mc.Species(name="A", other_properties={"__absolute tolerance": "1.0e-30"})
7
+ B = mc.Species(name="B", tracer_type="AEROSOL")
8
+ C = mc.Species(name="C", tracer_type="THIRD_BODY")
9
+ M = mc.Species(name="M")
10
+ H2O2 = mc.Species(
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
+ molecular_weight_kg_mol=0.0340147,
17
+ density_kg_m3=1000.0,
18
+ other_properties={"__absolute tolerance": "1.0e-10"},
19
+ )
20
+ ethanol = mc.Species(
21
+ name="ethanol",
22
+ diffusion_coefficient_m2_s=0.95e-05,
23
+ N_star=2.55,
24
+ molecular_weight_kg_mol=0.04607,
25
+ other_properties={"__absolute tolerance": "1.0e-20"},
26
+ )
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
+
57
+ # Chemical phases
58
+ gas = mc.Phase(name="gas", species=[A, B, C, ethanol])
59
+ aqueous_aerosol = mc.Phase(
60
+ name="aqueous aerosol",
61
+ species=[H2O2_aq, H2O_aq, ethanol_aq, A, B, C],
62
+ other_properties={"__irrelevant": "2"},
63
+ )
64
+ surface_reacting_phase = mc.Phase(
65
+ name="surface reacting phase",
66
+ species=[aerosol_stuff, more_aerosol_stuff]
67
+ )
68
+ cloud = mc.Phase(name="cloud", species=[B, C])
69
+
70
+ # Reactions
71
+ my_arrhenius = mc.Arrhenius(
72
+ name="my arrhenius",
73
+ A=32.1, B=-2.3, C=102.3, D=63.4, E=-1.3,
74
+ gas_phase=gas,
75
+ reactants=[B],
76
+ products=[C],
77
+ other_properties={"__irrelevant": "2"},
78
+ )
79
+
80
+ my_other_arrhenius = mc.Arrhenius(
81
+ name="my other arrhenius",
82
+ A=29.3, B=-1.5, Ea=101.2, D=82.6, E=-0.98,
83
+ gas_phase=gas,
84
+ reactants=[A],
85
+ products=[(1.2, B)]
86
+ )
87
+
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
+ my_troe = mc.Troe(
114
+ name="my troe",
115
+ gas_phase=gas,
116
+ k0_A=1.2e-12,
117
+ k0_B=167,
118
+ k0_C=3,
119
+ kinf_A=136,
120
+ kinf_B=5,
121
+ kinf_C=24,
122
+ Fc=0.9,
123
+ N=0.8,
124
+ reactants=[B, M],
125
+ products=[C],
126
+ other_properties={"__irrelevant": "2"},
127
+ )
128
+
129
+ my_ternary = mc.TernaryChemicalActivation(
130
+ name="my ternary chemical activation",
131
+ gas_phase=gas,
132
+ k0_A=32.1,
133
+ k0_B=-2.3,
134
+ k0_C=102.3,
135
+ kinf_A=63.4,
136
+ kinf_B=-1.3,
137
+ kinf_C=908.5,
138
+ Fc=1.3,
139
+ N=32.1,
140
+ reactants=[B, M],
141
+ products=[C],
142
+ other_properties={"__irrelevant": "2"},
143
+ )
144
+
145
+ my_branched = mc.Branched(
146
+ name="my branched",
147
+ gas_phase=gas,
148
+ reactants=[A],
149
+ alkoxy_products=[B],
150
+ nitrate_products=[C],
151
+ X=1.2e-4,
152
+ Y=167,
153
+ a0=0.15,
154
+ n=9,
155
+ other_properties={"__irrelevant": "2"},
156
+ )
157
+
158
+ my_tunneling = mc.Tunneling(
159
+ name="my tunneling",
160
+ gas_phase=gas,
161
+ reactants=[B],
162
+ products=[C],
163
+ A=123.45,
164
+ B=1200.0,
165
+ C=1.0e8,
166
+ other_properties={"__irrelevant": "2"},
167
+ )
168
+
169
+ my_surface = mc.Surface(
170
+ name="my surface",
171
+ gas_phase=gas,
172
+ gas_phase_species=A,
173
+ reaction_probability=2.0e-2,
174
+ gas_phase_products=[B, C],
175
+ condensed_phase=surface_reacting_phase,
176
+ other_properties={"__irrelevant": "2"},
177
+ )
178
+
179
+ photo_B = mc.Photolysis(
180
+ name="photo B",
181
+ gas_phase=gas,
182
+ reactants=[B],
183
+ products=[C],
184
+ scaling_factor=12.3,
185
+ other_properties={"__irrelevant": "2"},
186
+ )
187
+
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
+ my_emission = mc.Emission(
198
+ name="my emission",
199
+ gas_phase=gas,
200
+ products=[B],
201
+ scaling_factor=12.3,
202
+ other_properties={"__irrelevant": "2"},
203
+ )
204
+
205
+ my_first_order_loss = mc.FirstOrderLoss(
206
+ name="my first order loss",
207
+ gas_phase=gas,
208
+ reactants=[C],
209
+ scaling_factor=12.3,
210
+ other_properties={"__irrelevant": "2"},
211
+ )
212
+
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
+ user_defined = mc.UserDefined(
243
+ name="my user defined",
244
+ gas_phase=gas,
245
+ reactants=[A, B],
246
+ products=[(1.3, C)],
247
+ scaling_factor=12.3,
248
+ other_properties={"__irrelevant": "2"}
249
+ )
250
+
251
+ # Mechanism
252
+ return mc.Mechanism(
253
+ name="Full Configuration",
254
+ species=[A, B, C, M, H2O2, ethanol, ethanol_aq, H2O2_aq, H2O_aq,
255
+ aerosol_stuff, more_aerosol_stuff],
256
+ phases=[gas, aqueous_aerosol, surface_reacting_phase, cloud],
257
+ reactions=[my_arrhenius, my_other_arrhenius, my_condensed_arrhenius,
258
+ my_other_condensed_arrhenius, my_troe, my_ternary, my_branched,
259
+ my_tunneling, my_surface, photo_B, condensed_photo_B,
260
+ my_emission, my_first_order_loss, my_aqueous_equilibrium,
261
+ my_wet_deposition, my_simpol_phase_transfer,
262
+ user_defined],
263
+ version=mc.Version(1, 0, 0),
264
+ )
265
+
266
+
267
+ def _validate_species(species):
268
+ # Define the expected species and their required attributes
269
+ expected_species = {
270
+ "A": {"other_properties": {"__absolute tolerance": "1e-30"}},
271
+ "B": {"tracer_type": "AEROSOL"},
272
+ "C": {"tracer_type": "THIRD_BODY"},
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"},
282
+ },
283
+ "ethanol": {
284
+ "diffusion_coefficient_m2_s": 0.95e-05,
285
+ "N_star": 2.55,
286
+ "molecular_weight_kg_mol": 0.04607,
287
+ "other_properties": {"__absolute tolerance": "1e-20"},
288
+ },
289
+ "ethanol_aq": {
290
+ "molecular_weight_kg_mol": 0.04607,
291
+ "density_kg_m3": 1000.0,
292
+ "other_properties": {"__absolute tolerance": "1e-20"},
293
+ },
294
+ "H2O2_aq": {
295
+ "molecular_weight_kg_mol": 0.0340147,
296
+ "density_kg_m3": 1000.0,
297
+ "other_properties": {"__absolute tolerance": "1e-10"},
298
+ },
299
+ "H2O_aq": {
300
+ "density_kg_m3": 1000.0,
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,
311
+ "other_properties": {"__absolute tolerance": "1e-20"},
312
+ },
313
+ }
314
+
315
+ # Create a dictionary for quick lookup of species by name
316
+ species_dict = {sp.name: sp for sp in species}
317
+
318
+ # Validate each expected species
319
+ for name, attributes in expected_species.items():
320
+ assert name in species_dict, f"Species '{name}' is missing."
321
+ for attr, expected_value in attributes.items():
322
+ assert hasattr(
323
+ species_dict[name], attr
324
+ ), f"Attribute '{attr}' is missing for species '{name}'."
325
+ got_value = getattr(species_dict[name], attr)
326
+ # Handle special cases for floating-point representation
327
+ if isinstance(got_value, str) and ".0e" in got_value:
328
+ got_value = got_value.replace(".0e", "e")
329
+ elif isinstance(got_value, dict):
330
+ def replace_in_dict(d):
331
+ for key, value in d.items():
332
+ if isinstance(value, str) and ".0e" in value:
333
+ d[key] = value.replace(".0e", "e")
334
+ elif isinstance(value, dict):
335
+ replace_in_dict(value)
336
+ replace_in_dict(got_value)
337
+ assert got_value == expected_value, (
338
+ f"Attribute '{attr}' for species '{name}' has value "
339
+ f"{got_value}, expected {expected_value}."
340
+ )
341
+
342
+
343
+ def _validate_phases(phases):
344
+ # Define the expected phases and their associated species
345
+ expected_phases = {
346
+ "gas": ["A", "B", "C", "ethanol"],
347
+ "aqueous aerosol": ["H2O2_aq", "H2O_aq", "ethanol_aq", "A", "B", "C"],
348
+ "surface reacting phase": ["aerosol stuff", "more aerosol stuff"],
349
+ "cloud": ["B", "C"],
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
+ )
366
+
367
+
368
+ def _extract_components(components):
369
+ return [
370
+ {"species name": component.species_name, "coefficient": component.coefficient}
371
+ for component in components
372
+ ]
373
+
374
+
375
+ def _validate_arrhenius(reactions):
376
+ assert reactions[0].type == mc.ReactionType.Arrhenius
377
+ assert _extract_components(reactions[0].reactants) == [
378
+ {"species name": "B", "coefficient": 1}
379
+ ]
380
+ assert _extract_components(reactions[0].products) == [
381
+ {"species name": "C", "coefficient": 1}
382
+ ]
383
+ assert reactions[0].A == 32.1
384
+ assert reactions[0].B == -2.3
385
+ assert reactions[0].C == 102.3
386
+ assert reactions[0].D == 63.4
387
+ assert reactions[0].E == -1.3
388
+ assert reactions[0].name == "my arrhenius"
389
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
390
+ assert reactions[1].type == mc.ReactionType.Arrhenius
391
+ assert _extract_components(reactions[1].reactants) == [
392
+ {"species name": "A", "coefficient": 1}
393
+ ]
394
+ assert _extract_components(reactions[1].products) == [
395
+ {"species name": "B", "coefficient": 1.2}
396
+ ]
397
+ assert reactions[1].A == 29.3
398
+ assert reactions[1].B == -1.5
399
+ assert reactions[1].C == -101.2 / 1.380649e-23
400
+ assert reactions[1].D == 82.6
401
+ assert reactions[1].E == -0.98
402
+ assert reactions[1].name == "my other arrhenius"
403
+ assert reactions[1].other_properties == {}
404
+
405
+
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
+ def _validate_emission(reactions):
476
+ assert reactions[0].type == mc.ReactionType.Emission
477
+ assert reactions[0].gas_phase == "gas"
478
+ assert _extract_components(reactions[0].products) == [
479
+ {"species name": "B", "coefficient": 1}
480
+ ]
481
+ assert reactions[0].scaling_factor == 12.3
482
+ assert reactions[0].name == "my emission"
483
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
484
+
485
+
486
+ def _validate_first_order_loss(reactions):
487
+ assert reactions[0].type == mc.ReactionType.FirstOrderLoss
488
+ assert reactions[0].gas_phase == "gas"
489
+ assert _extract_components(reactions[0].reactants) == [
490
+ {"species name": "C", "coefficient": 1}
491
+ ]
492
+ assert reactions[0].scaling_factor == 12.3
493
+ assert reactions[0].name == "my first order loss"
494
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
495
+
496
+
497
+ def _validate_photolysis(reactions):
498
+ assert reactions[0].type == mc.ReactionType.Photolysis
499
+ assert reactions[0].gas_phase == "gas"
500
+ assert _extract_components(reactions[0].reactants) == [
501
+ {"species name": "B", "coefficient": 1}
502
+ ]
503
+ assert _extract_components(reactions[0].products) == [
504
+ {"species name": "C", "coefficient": 1}
505
+ ]
506
+ assert reactions[0].scaling_factor == 12.3
507
+ assert reactions[0].name == "photo B"
508
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
509
+
510
+
511
+ def _validate_surface(reactions):
512
+ assert reactions[0].type == mc.ReactionType.Surface
513
+ assert reactions[0].gas_phase == "gas"
514
+ assert _extract_components([reactions[0].gas_phase_species]) == [
515
+ {"species name": "A", "coefficient": 1}
516
+ ]
517
+ assert reactions[0].reaction_probability == 2.0e-2
518
+ assert _extract_components(reactions[0].gas_phase_products) == [
519
+ {"species name": "B", "coefficient": 1},
520
+ {"species name": "C", "coefficient": 1},
521
+ ]
522
+ assert reactions[0].condensed_phase == "surface reacting phase"
523
+ assert reactions[0].name == "my surface"
524
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
525
+
526
+
527
+ def _validate_troe(reactions):
528
+ assert reactions[0].type == mc.ReactionType.Troe
529
+ assert reactions[0].gas_phase == "gas"
530
+ assert _extract_components(reactions[0].reactants) == [
531
+ {"species name": "B", "coefficient": 1},
532
+ {"species name": "M", "coefficient": 1},
533
+ ]
534
+ assert _extract_components(reactions[0].products) == [
535
+ {"species name": "C", "coefficient": 1}
536
+ ]
537
+ assert reactions[0].k0_A == 1.2e-12
538
+ assert reactions[0].k0_B == 167
539
+ assert reactions[0].k0_C == 3
540
+ assert reactions[0].kinf_A == 136
541
+ assert reactions[0].kinf_B == 5
542
+ assert reactions[0].kinf_C == 24
543
+ assert reactions[0].Fc == 0.9
544
+ assert reactions[0].N == 0.8
545
+ assert reactions[0].name == "my troe"
546
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
547
+
548
+
549
+ def _validate_ternary_chemical_activation(reactions):
550
+ assert reactions[0].type == mc.ReactionType.TernaryChemicalActivation
551
+ assert reactions[0].gas_phase == "gas"
552
+ assert _extract_components(reactions[0].reactants) == [
553
+ {"species name": "B", "coefficient": 1},
554
+ {"species name": "M", "coefficient": 1},
555
+ ]
556
+ assert _extract_components(reactions[0].products) == [
557
+ {"species name": "C", "coefficient": 1}
558
+ ]
559
+ assert reactions[0].k0_A == 32.1
560
+ assert reactions[0].k0_B == -2.3
561
+ assert reactions[0].k0_C == 102.3
562
+ assert reactions[0].kinf_A == 63.4
563
+ assert reactions[0].kinf_B == -1.3
564
+ assert reactions[0].kinf_C == 908.5
565
+ assert reactions[0].Fc == 1.3
566
+ assert reactions[0].N == 32.1
567
+ assert reactions[0].name == "my ternary chemical activation"
568
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
569
+
570
+
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
+ def _validate_branched_no_ro2(reactions):
594
+ assert reactions[0].type == mc.ReactionType.Branched
595
+ assert reactions[0].gas_phase == "gas"
596
+ assert _extract_components(reactions[0].reactants) == [
597
+ {"species name": "A", "coefficient": 1}
598
+ ]
599
+ assert _extract_components(reactions[0].alkoxy_products) == [
600
+ {"species name": "B", "coefficient": 1}
601
+ ]
602
+ assert _extract_components(reactions[0].nitrate_products) == [
603
+ {"species name": "C", "coefficient": 1}
604
+ ]
605
+ assert reactions[0].X == 1.2e-4
606
+ assert reactions[0].Y == 167
607
+ assert reactions[0].a0 == 0.15
608
+ assert reactions[0].n == 9
609
+ assert reactions[0].name == "my branched"
610
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
611
+
612
+
613
+ def _validate_tunneling(reactions):
614
+ assert reactions[0].type == mc.ReactionType.Tunneling
615
+ assert reactions[0].gas_phase == "gas"
616
+ assert _extract_components(reactions[0].reactants) == [
617
+ {"species name": "B", "coefficient": 1}
618
+ ]
619
+ assert _extract_components(reactions[0].products) == [
620
+ {"species name": "C", "coefficient": 1}
621
+ ]
622
+ assert reactions[0].A == 123.45
623
+ assert reactions[0].B == 1200.0
624
+ assert reactions[0].C == 1.0e8
625
+ assert reactions[0].name == "my tunneling"
626
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
627
+
628
+
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
+ def _validate_user_defined(reactions):
638
+ assert reactions[0].type == mc.ReactionType.UserDefined
639
+ assert reactions[0].gas_phase == "gas"
640
+ assert _extract_components(reactions[0].reactants) == [
641
+ {"species name": "A", "coefficient": 1},
642
+ {"species name": "B", "coefficient": 1},
643
+ ]
644
+ assert _extract_components(reactions[0].products) == [
645
+ {"species name": "C", "coefficient": 1.3}
646
+ ]
647
+ assert reactions[0].scaling_factor == 12.3
648
+ assert reactions[0].name == "my user defined"
649
+ # assert reactions[0].other_properties == {}
650
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
651
+
652
+
653
+ def validate_full_v1_mechanism(mechanism):
654
+ assert mechanism is not None
655
+ assert mechanism.name == "Full Configuration"
656
+ assert len(mechanism.species) == 11
657
+ _validate_species(mechanism.species)
658
+ assert len(mechanism.phases) == 4
659
+ _validate_phases(mechanism.phases)
660
+ assert len(mechanism.reactions.aqueous_equilibrium) == 1
661
+ _validate_aqueous_equilibrium(mechanism.reactions.aqueous_equilibrium)
662
+ assert len(mechanism.reactions.arrhenius) == 2
663
+ _validate_arrhenius(mechanism.reactions.arrhenius)
664
+ assert len(mechanism.reactions.branched) == 1
665
+ _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
+ assert len(mechanism.reactions.emission) == 1
673
+ _validate_emission(mechanism.reactions.emission)
674
+ assert len(mechanism.reactions.first_order_loss) == 1
675
+ _validate_first_order_loss(mechanism.reactions.first_order_loss)
676
+ assert len(mechanism.reactions.photolysis) == 1
677
+ _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
+ assert len(mechanism.reactions.surface) == 1
681
+ _validate_surface(mechanism.reactions.surface)
682
+ assert len(mechanism.reactions.troe) == 1
683
+ _validate_troe(mechanism.reactions.troe)
684
+ assert len(mechanism.reactions.ternary_chemical_activation) == 1
685
+ _validate_ternary_chemical_activation(mechanism.reactions.ternary_chemical_activation)
686
+ assert len(mechanism.reactions.tunneling) == 1
687
+ _validate_tunneling(mechanism.reactions.tunneling)
688
+ assert len(mechanism.reactions.wet_deposition) == 1
689
+ _validate_wet_deposition(mechanism.reactions.wet_deposition)
690
+ assert len(mechanism.reactions.user_defined) == 1
691
+ _validate_user_defined(mechanism.reactions.user_defined)
692
+ assert mechanism.version.major == 1
693
+ assert mechanism.version.minor == 0
694
+ assert mechanism.version.patch == 0
695
+ assert len(mechanism.reactions) == 16
696
+ for reaction in mechanism.reactions:
697
+ assert reaction is not None
698
+ assert isinstance(reaction.type, mc.ReactionType)