musica 0.11.1.4__cp39-cp39-win32.whl → 0.12.0__cp39-cp39-win32.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 (39) hide show
  1. musica/_musica.cp39-win32.pyd +0 -0
  2. musica/_version.py +1 -1
  3. musica/constants.py +3 -0
  4. musica/mechanism_configuration/__init__.py +1 -0
  5. musica/mechanism_configuration/aqueous_equilibrium.py +101 -0
  6. musica/mechanism_configuration/arrhenius.py +121 -0
  7. musica/mechanism_configuration/branched.py +116 -0
  8. musica/mechanism_configuration/condensed_phase_arrhenius.py +116 -0
  9. musica/mechanism_configuration/condensed_phase_photolysis.py +91 -0
  10. musica/mechanism_configuration/emission.py +67 -0
  11. musica/mechanism_configuration/first_order_loss.py +67 -0
  12. musica/mechanism_configuration/henrys_law.py +85 -0
  13. musica/mechanism_configuration/mechanism_configuration.py +161 -0
  14. musica/mechanism_configuration/phase.py +43 -0
  15. musica/mechanism_configuration/photolysis.py +83 -0
  16. musica/mechanism_configuration/reactions.py +61 -0
  17. musica/mechanism_configuration/simpol_phase_transfer.py +88 -0
  18. musica/mechanism_configuration/species.py +72 -0
  19. musica/mechanism_configuration/surface.py +89 -0
  20. musica/mechanism_configuration/troe.py +137 -0
  21. musica/mechanism_configuration/tunneling.py +103 -0
  22. musica/mechanism_configuration/user_defined.py +83 -0
  23. musica/mechanism_configuration/utils.py +10 -0
  24. musica/mechanism_configuration/wet_deposition.py +49 -0
  25. musica/mechanism_configuration.cpp +0 -1
  26. musica/test/examples/v1/full_configuration/full_configuration.json +30 -15
  27. musica/test/examples/v1/full_configuration/full_configuration.yaml +16 -1
  28. musica/test/test_analytical.py +1 -1
  29. musica/test/test_parser.py +3 -639
  30. musica/test/test_serializer.py +69 -0
  31. musica/test/test_util_full_mechanism.py +668 -0
  32. musica/types.py +1 -4
  33. {musica-0.11.1.4.dist-info → musica-0.12.0.dist-info}/METADATA +61 -46
  34. musica-0.12.0.dist-info/RECORD +57 -0
  35. musica-0.12.0.dist-info/licenses/AUTHORS.md +59 -0
  36. musica/mechanism_configuration.py +0 -1291
  37. musica-0.11.1.4.dist-info/RECORD +0 -33
  38. {musica-0.11.1.4.dist-info → musica-0.12.0.dist-info}/WHEEL +0 -0
  39. {musica-0.11.1.4.dist-info → musica-0.12.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,668 @@
1
+ from musica.mechanism_configuration import *
2
+ from musica import _ReactionType
3
+
4
+
5
+ def get_fully_defined_mechanism():
6
+ # Chemical species
7
+ A = Species(name="A", other_properties={"__absolute tolerance": "1.0e-30"})
8
+ B = Species(name="B", tracer_type="AEROSOL")
9
+ C = Species(name="C", tracer_type="THIRD_BODY")
10
+ M = Species(name="M")
11
+ H2O2 = Species(
12
+ name="H2O2",
13
+ HLC_298K_mol_m3_Pa=1.011596348,
14
+ HLC_exponential_factor_K=6340,
15
+ diffusion_coefficient_m2_s=1.46e-05,
16
+ N_star=1.74,
17
+ molecular_weight_kg_mol=0.0340147,
18
+ density_kg_m3=1000.0,
19
+ other_properties={"__absolute tolerance": "1.0e-10"},
20
+ )
21
+ ethanol = Species(
22
+ name="ethanol",
23
+ diffusion_coefficient_m2_s=0.95e-05,
24
+ N_star=2.55,
25
+ molecular_weight_kg_mol=0.04607,
26
+ other_properties={"__absolute tolerance": "1.0e-20"},
27
+ )
28
+ ethanol_aq = Species(
29
+ name="ethanol_aq",
30
+ molecular_weight_kg_mol=0.04607,
31
+ density_kg_m3=1000.0,
32
+ other_properties={"__absolute tolerance": "1.0e-20"},
33
+ )
34
+ H2O2_aq = Species(
35
+ name="H2O2_aq",
36
+ molecular_weight_kg_mol=0.0340147,
37
+ density_kg_m3=1000.0,
38
+ other_properties={"__absolute tolerance": "1.0e-10"},
39
+ )
40
+ H2O_aq = Species(
41
+ name="H2O_aq",
42
+ density_kg_m3=1000.0,
43
+ molecular_weight_kg_mol=0.01801,
44
+ )
45
+ aerosol_stuff = Species(
46
+ name="aerosol stuff",
47
+ molecular_weight_kg_mol=0.5,
48
+ density_kg_m3=1000.0,
49
+ other_properties={"__absolute tolerance": "1.0e-20"},
50
+ )
51
+ more_aerosol_stuff = Species(
52
+ name="more aerosol stuff",
53
+ molecular_weight_kg_mol=0.2,
54
+ density_kg_m3=1000.0,
55
+ other_properties={"__absolute tolerance": "1.0e-20"},
56
+ )
57
+
58
+ # Chemical phases
59
+ gas = Phase(name="gas", species=[A, B, C, ethanol])
60
+ aqueous_aerosol = Phase(
61
+ name="aqueous aerosol",
62
+ species=[H2O2_aq, H2O_aq, ethanol_aq, A, B, C],
63
+ other_properties = {"__irrelevant": "2"},
64
+ )
65
+ surface_reacting_phase = Phase(
66
+ name="surface reacting phase",
67
+ species=[aerosol_stuff, more_aerosol_stuff]
68
+ )
69
+ cloud = Phase(name="cloud", species=[B, C])
70
+
71
+ # Reactions
72
+ my_arrhenius = Arrhenius(
73
+ name="my arrhenius",
74
+ A=32.1, B=-2.3, C=102.3, D=63.4, E=-1.3,
75
+ gas_phase=gas,
76
+ reactants=[B],
77
+ products=[C],
78
+ other_properties = {"__irrelevant": "2"},
79
+ )
80
+
81
+ my_other_arrhenius = Arrhenius(
82
+ name="my other arrhenius",
83
+ A=29.3, B=-1.5, Ea=101.2, D=82.6, E=-0.98,
84
+ gas_phase=gas,
85
+ reactants=[A],
86
+ products=[(1.2, B)]
87
+ )
88
+
89
+ my_condensed_arrhenius = CondensedPhaseArrhenius(
90
+ name="my condensed arrhenius",
91
+ aerosol_phase=aqueous_aerosol,
92
+ aerosol_phase_water=H2O_aq,
93
+ A=123.45,
94
+ B=1.3,
95
+ Ea=123.45,
96
+ D=300.0,
97
+ E=0.6e-5,
98
+ reactants=[H2O2_aq, H2O_aq],
99
+ products=[ethanol_aq],
100
+ other_properties = {"__irrelevant": "2"},
101
+ )
102
+
103
+ my_other_condensed_arrhenius = CondensedPhaseArrhenius(
104
+ name="my other condensed arrhenius",
105
+ aerosol_phase=aqueous_aerosol,
106
+ aerosol_phase_water=H2O_aq,
107
+ A=123.45,
108
+ B=1.3,
109
+ C=123.45,
110
+ D=300.0,
111
+ E=0.6e-5,
112
+ reactants=[H2O2_aq, H2O_aq],
113
+ products=[ethanol_aq]
114
+ )
115
+
116
+ my_troe = Troe(
117
+ name="my troe",
118
+ gas_phase=gas,
119
+ k0_A=1.2e-12,
120
+ k0_B=167,
121
+ k0_C=3,
122
+ kinf_A=136,
123
+ kinf_B=5,
124
+ kinf_C=24,
125
+ Fc=0.9,
126
+ N=0.8,
127
+ reactants=[B, M],
128
+ products=[C],
129
+ other_properties = {"__irrelevant": "2"},
130
+ )
131
+
132
+ my_branched = Branched(
133
+ name="my branched",
134
+ gas_phase=gas,
135
+ reactants=[A],
136
+ alkoxy_products=[B],
137
+ nitrate_products=[C],
138
+ X=1.2e-4,
139
+ Y=167,
140
+ a0=0.15,
141
+ n=9,
142
+ other_properties = {"__irrelevant": "2"},
143
+ )
144
+
145
+ my_tunneling = Tunneling(
146
+ name="my tunneling",
147
+ gas_phase=gas,
148
+ reactants=[B],
149
+ products=[C],
150
+ A=123.45,
151
+ B=1200.0,
152
+ C=1.0e8,
153
+ other_properties = {"__irrelevant": "2"},
154
+ )
155
+
156
+ my_surface = Surface(
157
+ name="my surface",
158
+ gas_phase=gas,
159
+ gas_phase_species=A,
160
+ reaction_probability=2.0e-2,
161
+ gas_phase_products=[B, C],
162
+ aerosol_phase=surface_reacting_phase,
163
+ other_properties = {"__irrelevant": "2"},
164
+ )
165
+
166
+ photo_B = Photolysis(
167
+ name="photo B",
168
+ gas_phase=gas,
169
+ reactants=[B],
170
+ products=[C],
171
+ scaling_factor=12.3,
172
+ other_properties = {"__irrelevant": "2"},
173
+ )
174
+
175
+ condensed_photo_B = CondensedPhasePhotolysis(
176
+ name="condensed photo B",
177
+ aerosol_phase=aqueous_aerosol,
178
+ aerosol_phase_water=H2O_aq,
179
+ reactants=[H2O2_aq],
180
+ products=[ethanol_aq],
181
+ scaling_factor=12.3,
182
+ other_properties = {"__irrelevant": "2"},
183
+ )
184
+
185
+ my_emission = Emission(
186
+ name="my emission",
187
+ gas_phase=gas,
188
+ products=[B],
189
+ scaling_factor=12.3,
190
+ other_properties = {"__irrelevant": "2"},
191
+ )
192
+
193
+ my_first_order_loss = FirstOrderLoss(
194
+ name="my first order loss",
195
+ gas_phase=gas,
196
+ reactants=[C],
197
+ scaling_factor=12.3,
198
+ other_properties = {"__irrelevant": "2"},
199
+ )
200
+
201
+ my_aqueous_equilibrium = AqueousEquilibrium(
202
+ name="my aqueous eq",
203
+ aerosol_phase=aqueous_aerosol,
204
+ aerosol_phase_water=H2O_aq,
205
+ A=1.14e-2,
206
+ C=2300.0,
207
+ k_reverse=0.32,
208
+ reactants=[(2, A)],
209
+ products=[B, C],
210
+ other_properties = {"__irrelevant": "2"},
211
+ )
212
+
213
+ my_wet_deposition = WetDeposition(
214
+ name="rxn cloud",
215
+ aerosol_phase=cloud,
216
+ scaling_factor=12.3,
217
+ other_properties = {"__irrelevant": "2"},
218
+ )
219
+
220
+ my_henrys_law = HenrysLaw(
221
+ name="my henry's law",
222
+ gas_phase=gas,
223
+ gas_phase_species=H2O2,
224
+ aerosol_phase=aqueous_aerosol,
225
+ aerosol_phase_species=H2O2_aq,
226
+ aerosol_phase_water=H2O_aq,
227
+ other_properties = {"__irrelevant": "2"},
228
+ )
229
+
230
+ my_simpol_phase_transfer = SimpolPhaseTransfer(
231
+ name="my simpol",
232
+ gas_phase=gas,
233
+ gas_phase_species=ethanol,
234
+ aerosol_phase=aqueous_aerosol,
235
+ aerosol_phase_species=ethanol_aq,
236
+ B=[-1.97e03, 2.91e00, 1.96e-03, -4.96e-01],
237
+ other_properties = {"__irrelevant": "2"},
238
+ )
239
+
240
+ user_defined = UserDefined(
241
+ name="my user defined",
242
+ gas_phase=gas,
243
+ reactants=[A, B],
244
+ products=[(1.3, C)],
245
+ scaling_factor=12.3,
246
+ other_properties = {"__irrelevant": "2"}
247
+ )
248
+
249
+ # Mechanism
250
+ return Mechanism(
251
+ name="Full Configuration",
252
+ species=[A, B, C, M, H2O2, ethanol, ethanol_aq, H2O2_aq, H2O_aq,
253
+ aerosol_stuff, more_aerosol_stuff],
254
+ phases=[gas, aqueous_aerosol, surface_reacting_phase, cloud],
255
+ reactions=[my_arrhenius, my_other_arrhenius, my_condensed_arrhenius,
256
+ my_other_condensed_arrhenius, my_troe, my_branched,
257
+ my_tunneling, my_surface, photo_B, condensed_photo_B,
258
+ my_emission, my_first_order_loss, my_aqueous_equilibrium,
259
+ my_wet_deposition, my_henrys_law, my_simpol_phase_transfer,
260
+ user_defined],
261
+ version=Version(1, 0, 0),
262
+ )
263
+
264
+
265
+ def _validate_species(species):
266
+ # Define the expected species and their required attributes
267
+ expected_species = {
268
+ "A": {"other_properties": {"__absolute tolerance": "1e-30"}},
269
+ "B": {"tracer_type": "AEROSOL"},
270
+ "C": {"tracer_type": "THIRD_BODY"},
271
+ "M": {},
272
+ "H2O2": {
273
+ "HLC_298K_mol_m3_Pa": 1.011596348,
274
+ "HLC_exponential_factor_K": 6340,
275
+ "diffusion_coefficient_m2_s": 1.46e-05,
276
+ "N_star": 1.74,
277
+ "molecular_weight_kg_mol": 0.0340147,
278
+ "density_kg_m3": 1000.0,
279
+ "other_properties": {"__absolute tolerance": "1e-10"},
280
+ },
281
+ "ethanol": {
282
+ "diffusion_coefficient_m2_s": 0.95e-05,
283
+ "N_star": 2.55,
284
+ "molecular_weight_kg_mol": 0.04607,
285
+ "other_properties": {"__absolute tolerance": "1e-20"},
286
+ },
287
+ "ethanol_aq": {
288
+ "molecular_weight_kg_mol": 0.04607,
289
+ "density_kg_m3": 1000.0,
290
+ "other_properties": {"__absolute tolerance": "1e-20"},
291
+ },
292
+ "H2O2_aq": {
293
+ "molecular_weight_kg_mol": 0.0340147,
294
+ "density_kg_m3": 1000.0,
295
+ "other_properties": {"__absolute tolerance": "1e-10"},
296
+ },
297
+ "H2O_aq": {
298
+ "density_kg_m3": 1000.0,
299
+ "molecular_weight_kg_mol": 0.01801,
300
+ },
301
+ "aerosol stuff": {
302
+ "molecular_weight_kg_mol": 0.5,
303
+ "density_kg_m3": 1000.0,
304
+ "other_properties": {"__absolute tolerance": "1e-20"},
305
+ },
306
+ "more aerosol stuff": {
307
+ "molecular_weight_kg_mol": 0.2,
308
+ "density_kg_m3": 1000.0,
309
+ "other_properties": {"__absolute tolerance": "1e-20"},
310
+ },
311
+ }
312
+
313
+ # Create a dictionary for quick lookup of species by name
314
+ species_dict = {sp.name: sp for sp in species}
315
+
316
+ # Validate each expected species
317
+ for name, attributes in expected_species.items():
318
+ assert name in species_dict, f"Species '{name}' is missing."
319
+ for attr, expected_value in attributes.items():
320
+ assert hasattr(
321
+ species_dict[name], attr
322
+ ), f"Attribute '{attr}' is missing for species '{name}'."
323
+ got_value = getattr(species_dict[name], attr)
324
+ # Handle special cases for floating-point representation
325
+ if isinstance(got_value, str) and ".0e" in got_value:
326
+ got_value = got_value.replace(".0e", "e")
327
+ elif isinstance(got_value, dict):
328
+ def replace_in_dict(d):
329
+ for key, value in d.items():
330
+ if isinstance(value, str) and ".0e" in value:
331
+ d[key] = value.replace(".0e", "e")
332
+ elif isinstance(value, dict):
333
+ replace_in_dict(value)
334
+ replace_in_dict(got_value)
335
+ assert got_value == expected_value, (
336
+ f"Attribute '{attr}' for species '{name}' has value "
337
+ f"{got_value}, expected {expected_value}."
338
+ )
339
+
340
+
341
+ def _validate_phases(phases):
342
+ # Define the expected phases and their associated species
343
+ expected_phases = {
344
+ "gas": ["A", "B", "C", "ethanol"],
345
+ "aqueous aerosol": ["H2O2_aq", "H2O_aq", "ethanol_aq", "A", "B", "C"],
346
+ "surface reacting phase": ["aerosol stuff", "more aerosol stuff"],
347
+ "cloud": ["B", "C"],
348
+ }
349
+
350
+ # Create a dictionary for quick lookup of phases by name
351
+ phases_dict = {phase.name: phase for phase in phases}
352
+
353
+ # Validate each expected phase
354
+ for name, expected_species in expected_phases.items():
355
+ assert name in phases_dict, f"Phase '{name}' is missing."
356
+ assert hasattr(
357
+ phases_dict[name], "species"
358
+ ), f"Phase '{name}' does not have a 'species' attribute."
359
+ phase_species = getattr(phases_dict[name], "species")
360
+ assert set(phase_species) == set(expected_species), (
361
+ f"Phase '{name}' has species {phase_species}, "
362
+ f"expected {expected_species}."
363
+ )
364
+
365
+
366
+ def _extract_components(components):
367
+ return [
368
+ {"species name": component.species_name, "coefficient": component.coefficient}
369
+ for component in components
370
+ ]
371
+
372
+ def _validate_arrhenius(reactions):
373
+ assert reactions[0].type == ReactionType.Arrhenius
374
+ assert _extract_components(reactions[0].reactants) == [
375
+ {"species name": "B", "coefficient": 1}
376
+ ]
377
+ assert _extract_components(reactions[0].products) == [
378
+ {"species name": "C", "coefficient": 1}
379
+ ]
380
+ assert reactions[0].A == 32.1
381
+ assert reactions[0].B == -2.3
382
+ assert reactions[0].C == 102.3
383
+ assert reactions[0].D == 63.4
384
+ assert reactions[0].E == -1.3
385
+ assert reactions[0].name == "my arrhenius"
386
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
387
+ assert reactions[1].type == ReactionType.Arrhenius
388
+ assert _extract_components(reactions[1].reactants) == [
389
+ {"species name": "A", "coefficient": 1}
390
+ ]
391
+ assert _extract_components(reactions[1].products) == [
392
+ {"species name": "B", "coefficient": 1.2}
393
+ ]
394
+ assert reactions[1].A == 29.3
395
+ assert reactions[1].B == -1.5
396
+ assert reactions[1].C == -101.2 / 1.380649e-23
397
+ assert reactions[1].D == 82.6
398
+ assert reactions[1].E == -0.98
399
+ assert reactions[1].name == "my other arrhenius"
400
+ assert reactions[1].other_properties == {}
401
+
402
+
403
+ def _validate_henrys_law(reactions):
404
+ assert reactions[0].type == ReactionType.HenrysLaw
405
+ assert reactions[0].gas_phase == "gas"
406
+ assert _extract_components([reactions[0].gas_phase_species]) == [
407
+ {"species name": "H2O2", "coefficient": 1}
408
+ ]
409
+ assert reactions[0].aerosol_phase == "aqueous aerosol"
410
+ assert _extract_components([reactions[0].aerosol_phase_species]) == [
411
+ {"species name": "H2O2_aq", "coefficient": 1}
412
+ ]
413
+ assert reactions[0].aerosol_phase_water == "H2O_aq"
414
+ assert reactions[0].name == "my henry's law"
415
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
416
+
417
+
418
+ def _validate_simpol_phase_transfer(reactions):
419
+ assert reactions[0].type == ReactionType.SimpolPhaseTransfer
420
+ assert reactions[0].gas_phase == "gas"
421
+ assert _extract_components([reactions[0].gas_phase_species]) == [
422
+ {"species name": "ethanol", "coefficient": 1}
423
+ ]
424
+ assert reactions[0].aerosol_phase == "aqueous aerosol"
425
+ assert _extract_components([reactions[0].aerosol_phase_species]) == [
426
+ {"species name": "ethanol_aq", "coefficient": 1}
427
+ ]
428
+ assert reactions[0].B == [-1.97e03, 2.91e00, 1.96e-03, -4.96e-01]
429
+ assert reactions[0].name == "my simpol"
430
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
431
+
432
+
433
+ def _validate_aqueous_equilibrium(reactions):
434
+ assert reactions[0].type == ReactionType.AqueousEquilibrium
435
+ assert reactions[0].aerosol_phase == "aqueous aerosol"
436
+ assert reactions[0].aerosol_phase_water == "H2O_aq"
437
+ assert reactions[0].A == 1.14e-2
438
+ assert reactions[0].C == 2300.0
439
+ assert reactions[0].k_reverse == 0.32
440
+ assert _extract_components(reactions[0].reactants) == [
441
+ {"species name": "A", "coefficient": 2}
442
+ ]
443
+ assert _extract_components(reactions[0].products) == [
444
+ {"species name": "B", "coefficient": 1},
445
+ {"species name": "C", "coefficient": 1},
446
+ ]
447
+ assert reactions[0].name == "my aqueous eq"
448
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
449
+
450
+
451
+ def _validate_condensed_phase_arrhenius(reactions):
452
+ for reaction in reactions:
453
+ assert reaction.type == ReactionType.CondensedPhaseArrhenius
454
+ assert reaction.aerosol_phase == "aqueous aerosol"
455
+ assert reaction.aerosol_phase_water == "H2O_aq"
456
+ assert reaction.A == 123.45
457
+ assert reaction.B == 1.3
458
+ assert reaction.D == 300.0
459
+ assert reaction.E == 0.6e-5
460
+ assert _extract_components(reaction.reactants) == [
461
+ {"species name": "H2O2_aq", "coefficient": 1},
462
+ {"species name": "H2O_aq", "coefficient": 1},
463
+ ]
464
+ assert _extract_components(reaction.products) == [
465
+ {"species name": "ethanol_aq", "coefficient": 1}
466
+ ]
467
+ assert reactions[0].name == "my condensed arrhenius"
468
+ assert reactions[0].C == -123.45 / 1.380649e-23
469
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
470
+ assert reactions[1].name == "my other condensed arrhenius"
471
+ assert reactions[1].C == 123.45
472
+
473
+
474
+ def _validate_condensed_phase_photolysis(reactions):
475
+ assert reactions[0].type == ReactionType.CondensedPhasePhotolysis
476
+ assert reactions[0].aerosol_phase == "aqueous aerosol"
477
+ assert reactions[0].aerosol_phase_water == "H2O_aq"
478
+ assert _extract_components(reactions[0].reactants) == [
479
+ {"species name": "H2O2_aq", "coefficient": 1}
480
+ ]
481
+ assert _extract_components(reactions[0].products) == [
482
+ {"species name": "ethanol_aq", "coefficient": 1}
483
+ ]
484
+ assert reactions[0].scaling_factor == 12.3
485
+ assert reactions[0].name == "condensed photo B"
486
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
487
+
488
+
489
+ def _validate_emission(reactions):
490
+ assert reactions[0].type == ReactionType.Emission
491
+ assert reactions[0].gas_phase == "gas"
492
+ assert _extract_components(reactions[0].products) == [
493
+ {"species name": "B", "coefficient": 1}
494
+ ]
495
+ assert reactions[0].scaling_factor == 12.3
496
+ assert reactions[0].name == "my emission"
497
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
498
+
499
+
500
+ def _validate_first_order_loss(reactions):
501
+ assert reactions[0].type == ReactionType.FirstOrderLoss
502
+ assert reactions[0].gas_phase == "gas"
503
+ assert _extract_components(reactions[0].reactants) == [
504
+ {"species name": "C", "coefficient": 1}
505
+ ]
506
+ assert reactions[0].scaling_factor == 12.3
507
+ assert reactions[0].name == "my first order loss"
508
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
509
+
510
+
511
+ def _validate_photolysis(reactions):
512
+ assert reactions[0].type == ReactionType.Photolysis
513
+ assert reactions[0].gas_phase == "gas"
514
+ assert _extract_components(reactions[0].reactants) == [
515
+ {"species name": "B", "coefficient": 1}
516
+ ]
517
+ assert _extract_components(reactions[0].products) == [
518
+ {"species name": "C", "coefficient": 1}
519
+ ]
520
+ assert reactions[0].scaling_factor == 12.3
521
+ assert reactions[0].name == "photo B"
522
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
523
+
524
+
525
+ def _validate_surface(reactions):
526
+ assert reactions[0].type == ReactionType.Surface
527
+ assert reactions[0].gas_phase == "gas"
528
+ assert _extract_components([reactions[0].gas_phase_species]) == [
529
+ {"species name": "A", "coefficient": 1}
530
+ ]
531
+ assert reactions[0].reaction_probability == 2.0e-2
532
+ assert _extract_components(reactions[0].gas_phase_products) == [
533
+ {"species name": "B", "coefficient": 1},
534
+ {"species name": "C", "coefficient": 1},
535
+ ]
536
+ assert reactions[0].aerosol_phase == "surface reacting phase"
537
+ assert reactions[0].name == "my surface"
538
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
539
+
540
+
541
+ def _validate_troe(reactions):
542
+ assert reactions[0].type == ReactionType.Troe
543
+ assert reactions[0].gas_phase == "gas"
544
+ assert _extract_components(reactions[0].reactants) == [
545
+ {"species name": "B", "coefficient": 1},
546
+ {"species name": "M", "coefficient": 1},
547
+ ]
548
+ assert _extract_components(reactions[0].products) == [
549
+ {"species name": "C", "coefficient": 1}
550
+ ]
551
+ assert reactions[0].k0_A == 1.2e-12
552
+ assert reactions[0].k0_B == 167
553
+ assert reactions[0].k0_C == 3
554
+ assert reactions[0].kinf_A == 136
555
+ assert reactions[0].kinf_B == 5
556
+ assert reactions[0].kinf_C == 24
557
+ assert reactions[0].Fc == 0.9
558
+ assert reactions[0].N == 0.8
559
+ assert reactions[0].name == "my troe"
560
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
561
+
562
+
563
+ def _validate_branched_no_ro2(reactions):
564
+ assert reactions[0].type == ReactionType.Branched
565
+ assert reactions[0].gas_phase == "gas"
566
+ assert _extract_components(reactions[0].reactants) == [
567
+ {"species name": "A", "coefficient": 1}
568
+ ]
569
+ assert _extract_components(reactions[0].alkoxy_products) == [
570
+ {"species name": "B", "coefficient": 1}
571
+ ]
572
+ assert _extract_components(reactions[0].nitrate_products) == [
573
+ {"species name": "C", "coefficient": 1}
574
+ ]
575
+ assert reactions[0].X == 1.2e-4
576
+ assert reactions[0].Y == 167
577
+ assert reactions[0].a0 == 0.15
578
+ assert reactions[0].n == 9
579
+ assert reactions[0].name == "my branched"
580
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
581
+
582
+
583
+ def _validate_tunneling(reactions):
584
+ assert reactions[0].type == ReactionType.Tunneling
585
+ assert reactions[0].gas_phase == "gas"
586
+ assert _extract_components(reactions[0].reactants) == [
587
+ {"species name": "B", "coefficient": 1}
588
+ ]
589
+ assert _extract_components(reactions[0].products) == [
590
+ {"species name": "C", "coefficient": 1}
591
+ ]
592
+ assert reactions[0].A == 123.45
593
+ assert reactions[0].B == 1200.0
594
+ assert reactions[0].C == 1.0e8
595
+ assert reactions[0].name == "my tunneling"
596
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
597
+
598
+
599
+ def _validate_wet_deposition(reactions):
600
+ assert reactions[0].type == ReactionType.WetDeposition
601
+ assert reactions[0].name == "rxn cloud"
602
+ assert reactions[0].aerosol_phase == "cloud"
603
+ assert reactions[0].scaling_factor == 12.3
604
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
605
+
606
+
607
+ def _validate_user_defined(reactions):
608
+ assert reactions[0].type == ReactionType.UserDefined
609
+ assert reactions[0].gas_phase == "gas"
610
+ assert _extract_components(reactions[0].reactants) == [
611
+ {"species name": "A", "coefficient": 1},
612
+ {"species name": "B", "coefficient": 1},
613
+ ]
614
+ assert _extract_components(reactions[0].products) == [
615
+ {"species name": "C", "coefficient": 1.3}
616
+ ]
617
+ assert reactions[0].scaling_factor == 12.3
618
+ assert reactions[0].name == "my user defined"
619
+ # assert reactions[0].other_properties == {}
620
+ assert reactions[0].other_properties == {"__irrelevant": "2"}
621
+
622
+
623
+ def validate_full_v1_mechanism(mechanism):
624
+ assert mechanism is not None
625
+ assert mechanism.name == "Full Configuration"
626
+ assert len(mechanism.species) == 11
627
+ _validate_species(mechanism.species)
628
+ assert len(mechanism.phases) == 4
629
+ _validate_phases(mechanism.phases)
630
+ assert len(mechanism.reactions.aqueous_equilibrium) == 1
631
+ _validate_aqueous_equilibrium(mechanism.reactions.aqueous_equilibrium)
632
+ assert len(mechanism.reactions.arrhenius) == 2
633
+ _validate_arrhenius(mechanism.reactions.arrhenius)
634
+ assert len(mechanism.reactions.branched) == 1
635
+ _validate_branched_no_ro2(mechanism.reactions.branched)
636
+ assert len(mechanism.reactions.condensed_phase_arrhenius) == 2
637
+ _validate_condensed_phase_arrhenius(mechanism.reactions.condensed_phase_arrhenius)
638
+ assert len(mechanism.reactions.condensed_phase_photolysis) == 1
639
+ _validate_condensed_phase_photolysis(
640
+ mechanism.reactions.condensed_phase_photolysis
641
+ )
642
+ assert len(mechanism.reactions.emission) == 1
643
+ _validate_emission(mechanism.reactions.emission)
644
+ assert len(mechanism.reactions.first_order_loss) == 1
645
+ _validate_first_order_loss(mechanism.reactions.first_order_loss)
646
+ assert len(mechanism.reactions.henrys_law) == 1
647
+ _validate_henrys_law(mechanism.reactions.henrys_law)
648
+ assert len(mechanism.reactions.photolysis) == 1
649
+ _validate_photolysis(mechanism.reactions.photolysis)
650
+ assert len(mechanism.reactions.simpol_phase_transfer) == 1
651
+ _validate_simpol_phase_transfer(mechanism.reactions.simpol_phase_transfer)
652
+ assert len(mechanism.reactions.surface) == 1
653
+ _validate_surface(mechanism.reactions.surface)
654
+ assert len(mechanism.reactions.troe) == 1
655
+ _validate_troe(mechanism.reactions.troe)
656
+ assert len(mechanism.reactions.tunneling) == 1
657
+ _validate_tunneling(mechanism.reactions.tunneling)
658
+ assert len(mechanism.reactions.wet_deposition) == 1
659
+ _validate_wet_deposition(mechanism.reactions.wet_deposition)
660
+ assert len(mechanism.reactions.user_defined) == 1
661
+ _validate_user_defined(mechanism.reactions.user_defined)
662
+ assert mechanism.version.major == 1
663
+ assert mechanism.version.minor == 0
664
+ assert mechanism.version.patch == 0
665
+ assert len(mechanism.reactions) == 17
666
+ for reaction in mechanism.reactions:
667
+ assert reaction is not None
668
+ assert isinstance(reaction.type, _ReactionType)
musica/types.py CHANGED
@@ -20,10 +20,7 @@ from musica import (
20
20
  _user_defined_rate_parameters_ordering,
21
21
  )
22
22
  import musica.mechanism_configuration as mc
23
-
24
- AVOGADRO = 6.02214076e23 # mol^-1
25
- BOLTZMANN = 1.380649e-23 # J K^-1
26
- GAS_CONSTANT = AVOGADRO * BOLTZMANN # J K^-1 mol^-1
23
+ from musica.constants import GAS_CONSTANT
27
24
 
28
25
  FilePath = Union[str, "PathLike[str]"]
29
26