musica 0.12.1__cp311-cp311-win_arm64.whl → 0.13.0__cp311-cp311-win_arm64.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.cp311-win_amd64.pyd +0 -0
- musica/_version.py +1 -1
- musica/binding_common.cpp +6 -9
- musica/binding_common.hpp +17 -1
- musica/examples/__init__.py +1 -1
- musica/examples/carma_aluminum.py +1 -0
- musica/examples/carma_sulfate.py +1 -0
- musica/examples/sulfate_box_model.py +2 -2
- musica/examples/ts1_latin_hypercube.py +1 -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_carma_aluminum.py +2 -1
- musica/test/integration/test_carma_sulfate.py +2 -1
- musica/test/integration/test_chapman.py +2 -2
- musica/test/integration/test_sulfate_box_model.py +1 -1
- 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 +338 -0
- musica/test/unit/test_util_full_mechanism.py +78 -298
- musica/tools/prepare_build_environment_linux.sh +7 -25
- musica/tuvx.cpp +94 -15
- musica/tuvx.py +92 -22
- musica/types.py +28 -17
- {musica-0.12.1.dist-info → musica-0.13.0.dist-info}/METADATA +15 -14
- musica-0.13.0.dist-info/RECORD +80 -0
- {musica-0.12.1.dist-info → musica-0.13.0.dist-info}/WHEEL +1 -1
- 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.1.dist-info/RECORD +0 -69
- {musica-0.12.1.dist-info → musica-0.13.0.dist-info}/entry_points.txt +0 -0
- {musica-0.12.1.dist-info → musica-0.13.0.dist-info}/licenses/AUTHORS.md +0 -0
- {musica-0.12.1.dist-info → musica-0.13.0.dist-info}/licenses/LICENSE +0 -0
musica/grid_map.py
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# Copyright (C) 2023-2025 National Center for Atmospheric Research
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
"""
|
|
4
|
+
TUV-x GridMap class.
|
|
5
|
+
|
|
6
|
+
This module provides a class for managing collections of TUV-x grids.
|
|
7
|
+
The GridMap class allows dictionary-style access to grids using (name, units) tuples as keys.
|
|
8
|
+
|
|
9
|
+
Note: TUV-x is only available on macOS and Linux platforms.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from typing import Iterator, Sequence
|
|
13
|
+
from . import backend
|
|
14
|
+
from .grid import Grid
|
|
15
|
+
|
|
16
|
+
_backend = backend.get_backend()
|
|
17
|
+
|
|
18
|
+
GridMap = _backend._tuvx._GridMap if backend.tuvx_available() else None
|
|
19
|
+
|
|
20
|
+
if backend.tuvx_available():
|
|
21
|
+
original_init = GridMap.__init__
|
|
22
|
+
|
|
23
|
+
def __init__(self, **kwargs):
|
|
24
|
+
"""Initialize a GridMap instance.
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
**kwargs: Additional arguments passed to the C++ constructor
|
|
28
|
+
"""
|
|
29
|
+
original_init(self, **kwargs)
|
|
30
|
+
|
|
31
|
+
GridMap.__init__ = __init__
|
|
32
|
+
|
|
33
|
+
def __str__(self):
|
|
34
|
+
"""User-friendly string representation."""
|
|
35
|
+
return f"GridMap(num_grids={len(self)})"
|
|
36
|
+
|
|
37
|
+
GridMap.__str__ = __str__
|
|
38
|
+
|
|
39
|
+
def __repr__(self):
|
|
40
|
+
"""Detailed string representation for debugging."""
|
|
41
|
+
grid_details = []
|
|
42
|
+
for i in range(len(self)):
|
|
43
|
+
grid = self.get_grid_by_index(i)
|
|
44
|
+
grid_details.append(f"({grid.name}, {grid.units})")
|
|
45
|
+
return f"GridMap(grids={grid_details})"
|
|
46
|
+
|
|
47
|
+
GridMap.__repr__ = __repr__
|
|
48
|
+
|
|
49
|
+
def __len__(self):
|
|
50
|
+
"""Return the number of grids in the map."""
|
|
51
|
+
return self.get_number_of_grids()
|
|
52
|
+
|
|
53
|
+
GridMap.__len__ = __len__
|
|
54
|
+
|
|
55
|
+
def __bool__(self):
|
|
56
|
+
"""Return True if the map has any grids."""
|
|
57
|
+
return len(self) > 0
|
|
58
|
+
|
|
59
|
+
GridMap.__bool__ = __bool__
|
|
60
|
+
|
|
61
|
+
def __getitem__(self, key) -> Grid:
|
|
62
|
+
"""Get a grid using dictionary-style access with (name, units) tuple as key.
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
key: A tuple of (grid_name, grid_units)
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
The requested Grid object
|
|
69
|
+
|
|
70
|
+
Raises:
|
|
71
|
+
KeyError: If no grid matches the given name and units
|
|
72
|
+
TypeError: If key is not a tuple of (str, str)
|
|
73
|
+
"""
|
|
74
|
+
if not isinstance(key, tuple) or len(key) != 2:
|
|
75
|
+
raise TypeError("Grid access requires a tuple of (name, units)")
|
|
76
|
+
name, units = key
|
|
77
|
+
try:
|
|
78
|
+
return self.get_grid(name, units)
|
|
79
|
+
except Exception as e:
|
|
80
|
+
raise KeyError(f"No grid found with name='{name}' and units='{units}'") from e
|
|
81
|
+
|
|
82
|
+
GridMap.__getitem__ = __getitem__
|
|
83
|
+
|
|
84
|
+
def __setitem__(self, key, grid):
|
|
85
|
+
"""Add a grid to the map using dictionary-style access.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
key: A tuple of (grid_name, grid_units)
|
|
89
|
+
grid: The Grid object to add
|
|
90
|
+
|
|
91
|
+
Raises:
|
|
92
|
+
TypeError: If key is not a tuple, or if key components are not strings
|
|
93
|
+
TypeError: If grid is not a Grid object
|
|
94
|
+
ValueError: If grid name/units don't match the key
|
|
95
|
+
"""
|
|
96
|
+
if not isinstance(key, tuple) or len(key) != 2:
|
|
97
|
+
raise TypeError("Grid assignment requires a tuple of (name, units)")
|
|
98
|
+
name, units = key
|
|
99
|
+
if not isinstance(name, str):
|
|
100
|
+
raise TypeError("Grid name must be a string")
|
|
101
|
+
if not isinstance(units, str):
|
|
102
|
+
raise TypeError("Grid units must be a string")
|
|
103
|
+
if not isinstance(grid, Grid):
|
|
104
|
+
raise TypeError("Value must be a Grid object")
|
|
105
|
+
if grid.name != name or grid.units != units:
|
|
106
|
+
raise ValueError("Grid name/units must match the key tuple")
|
|
107
|
+
self.add_grid(grid)
|
|
108
|
+
|
|
109
|
+
GridMap.__setitem__ = __setitem__
|
|
110
|
+
|
|
111
|
+
def __iter__(self) -> Iterator:
|
|
112
|
+
"""Return an iterator over (name, units) tuples of all grids."""
|
|
113
|
+
for i in range(len(self)):
|
|
114
|
+
grid = self.get_grid_by_index(i)
|
|
115
|
+
yield (grid.name, grid.units)
|
|
116
|
+
|
|
117
|
+
GridMap.__iter__ = __iter__
|
|
118
|
+
|
|
119
|
+
def __contains__(self, key) -> bool:
|
|
120
|
+
"""Check if a grid with given name and units exists in the map.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
key: A tuple of (grid_name, grid_units)
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
True if a matching grid exists, False otherwise
|
|
127
|
+
"""
|
|
128
|
+
if not isinstance(key, tuple) or len(key) != 2:
|
|
129
|
+
return False
|
|
130
|
+
name, units = key
|
|
131
|
+
try:
|
|
132
|
+
grid = self.get_grid(str(name), str(units))
|
|
133
|
+
return grid is not None
|
|
134
|
+
except (ValueError, KeyError):
|
|
135
|
+
return False
|
|
136
|
+
|
|
137
|
+
GridMap.__contains__ = __contains__
|
|
138
|
+
|
|
139
|
+
def clear(self):
|
|
140
|
+
"""Remove all grids from the map."""
|
|
141
|
+
while len(self) > 0:
|
|
142
|
+
self.remove_grid_by_index(0)
|
|
143
|
+
|
|
144
|
+
GridMap.clear = clear
|
|
145
|
+
|
|
146
|
+
def items(self):
|
|
147
|
+
"""Return an iterator over (key, grid) pairs, where key is (name, units)."""
|
|
148
|
+
for i in range(len(self)):
|
|
149
|
+
grid = self.get_grid_by_index(i)
|
|
150
|
+
yield ((grid.name, grid.units), grid)
|
|
151
|
+
|
|
152
|
+
GridMap.items = items
|
|
153
|
+
|
|
154
|
+
def keys(self):
|
|
155
|
+
"""Return an iterator over grid keys (name, units) tuples."""
|
|
156
|
+
for i in range(len(self)):
|
|
157
|
+
grid = self.get_grid_by_index(i)
|
|
158
|
+
yield (grid.name, grid.units)
|
|
159
|
+
|
|
160
|
+
GridMap.keys = keys
|
|
161
|
+
|
|
162
|
+
def values(self):
|
|
163
|
+
"""Return an iterator over Grid objects in the map."""
|
|
164
|
+
for i in range(len(self)):
|
|
165
|
+
yield self.get_grid_by_index(i)
|
|
166
|
+
|
|
167
|
+
GridMap.values = values
|
|
@@ -1 +1,18 @@
|
|
|
1
|
-
from .
|
|
1
|
+
from .arrhenius import Arrhenius
|
|
2
|
+
from .branched import Branched
|
|
3
|
+
from .emission import Emission
|
|
4
|
+
from .first_order_loss import FirstOrderLoss
|
|
5
|
+
from .mechanism import Mechanism
|
|
6
|
+
from .ancillary import Version, Parser, ReactionType
|
|
7
|
+
from .phase import Phase
|
|
8
|
+
from .phase_species import PhaseSpecies
|
|
9
|
+
from .photolysis import Photolysis
|
|
10
|
+
from .reaction_component import ReactionComponent
|
|
11
|
+
from .reactions import Reactions
|
|
12
|
+
from .species import Species
|
|
13
|
+
from .surface import Surface
|
|
14
|
+
from .taylor_series import TaylorSeries
|
|
15
|
+
from .ternary_chemical_activation import TernaryChemicalActivation
|
|
16
|
+
from .troe import Troe
|
|
17
|
+
from .tunneling import Tunneling
|
|
18
|
+
from .user_defined import UserDefined
|
|
@@ -2,18 +2,120 @@ from typing import Optional, Any, Dict, List, Union, Tuple
|
|
|
2
2
|
from .. import backend
|
|
3
3
|
from .phase import Phase
|
|
4
4
|
from .species import Species
|
|
5
|
-
from .
|
|
6
|
-
from .utils import _add_other_properties
|
|
5
|
+
from .utils import _add_other_properties, _remove_empty_keys
|
|
7
6
|
from ..constants import BOLTZMANN
|
|
7
|
+
from .reaction_component import ReactionComponent
|
|
8
|
+
from .ancillary import ReactionType
|
|
8
9
|
|
|
9
10
|
_backend = backend.get_backend()
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
Arrhenius = _backend._mechanism_configuration._Arrhenius
|
|
12
|
+
|
|
13
|
+
original_init = Arrhenius.__init__
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@property
|
|
17
|
+
def type(self):
|
|
18
|
+
"""Get the reaction type."""
|
|
19
|
+
return ReactionType.Arrhenius
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def __init__(
|
|
23
|
+
self,
|
|
24
|
+
name: Optional[str] = None,
|
|
25
|
+
A: Optional[float] = None,
|
|
26
|
+
B: Optional[float] = None,
|
|
27
|
+
C: Optional[float] = None,
|
|
28
|
+
Ea: Optional[float] = None,
|
|
29
|
+
D: Optional[float] = None,
|
|
30
|
+
E: Optional[float] = None,
|
|
31
|
+
reactants: Optional[List[Union[Species,
|
|
32
|
+
Tuple[float, Species]]]] = None,
|
|
33
|
+
products: Optional[List[Union[Species, Tuple[float, Species]]]] = None,
|
|
34
|
+
gas_phase: Optional[Phase] = None,
|
|
35
|
+
other_properties: Optional[Dict[str, Any]] = None,
|
|
36
|
+
):
|
|
37
|
+
"""
|
|
38
|
+
Initializes the Arrhenius object with the given parameters.
|
|
13
39
|
|
|
40
|
+
Args:
|
|
41
|
+
name (str): The name of the Arrhenius rate constant.
|
|
42
|
+
A (float): Pre-exponential factor [(mol m-3)^(n-1)s-1] where n is the number of reactants.
|
|
43
|
+
B (float): Temperature exponent [unitless].
|
|
44
|
+
C (float): Exponential term [K-1].
|
|
45
|
+
Ea (float): Activation energy [J molecule-1].
|
|
46
|
+
D (float): Reference Temperature [K].
|
|
47
|
+
E (float): Pressure scaling term [Pa-1].
|
|
48
|
+
reactants (List[Union[Species, Tuple[float, Species]]]): A list of reactants involved in the reaction.
|
|
49
|
+
products (List[Union[Species, Tuple[float, Species]]]): A list of products formed in the reaction.
|
|
50
|
+
gas_phase (Phase): The gas phase in which the reaction occurs.
|
|
51
|
+
other_properties (Dict[str, Any]): A dictionary of other properties of the Arrhenius rate constant.
|
|
52
|
+
"""
|
|
53
|
+
original_init(self)
|
|
54
|
+
|
|
55
|
+
# Validate mutually exclusive parameters
|
|
56
|
+
if C is not None and Ea is not None:
|
|
57
|
+
raise ValueError("Cannot specify both C and Ea.")
|
|
58
|
+
if Ea is not None:
|
|
59
|
+
C = -Ea / BOLTZMANN
|
|
60
|
+
|
|
61
|
+
self.name = name if name is not None else self.name
|
|
62
|
+
self.A = A if A is not None else self.A
|
|
63
|
+
self.B = B if B is not None else self.B
|
|
64
|
+
self.C = C if C is not None else self.C
|
|
65
|
+
self.D = D if D is not None else self.D
|
|
66
|
+
self.E = E if E is not None else self.E
|
|
67
|
+
self.gas_phase = gas_phase.name if gas_phase is not None else self.gas_phase
|
|
68
|
+
self.other_properties = other_properties if other_properties is not None else self.other_properties
|
|
69
|
+
self.reactants = (
|
|
70
|
+
[
|
|
71
|
+
(
|
|
72
|
+
ReactionComponent(r.name)
|
|
73
|
+
if isinstance(r, Species)
|
|
74
|
+
else ReactionComponent(r[1].name, r[0])
|
|
75
|
+
)
|
|
76
|
+
for r in reactants
|
|
77
|
+
]
|
|
78
|
+
if reactants is not None
|
|
79
|
+
else self.reactants
|
|
80
|
+
)
|
|
81
|
+
self.products = (
|
|
82
|
+
[
|
|
83
|
+
(
|
|
84
|
+
ReactionComponent(p.name)
|
|
85
|
+
if isinstance(p, Species)
|
|
86
|
+
else ReactionComponent(p[1].name, p[0])
|
|
87
|
+
)
|
|
88
|
+
for p in products
|
|
89
|
+
]
|
|
90
|
+
if products is not None
|
|
91
|
+
else self.products
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def serialize(self) -> Dict:
|
|
96
|
+
"""
|
|
97
|
+
Serialize the Arrhenius object to a dictionary using only Python-visible data.
|
|
14
98
|
|
|
15
|
-
|
|
99
|
+
Returns:
|
|
100
|
+
Dict: A dictionary representation of the Arrhenius object.
|
|
16
101
|
"""
|
|
102
|
+
serialize_dict = {
|
|
103
|
+
"type": "ARRHENIUS",
|
|
104
|
+
"name": self.name,
|
|
105
|
+
"A": self.A,
|
|
106
|
+
"B": self.B,
|
|
107
|
+
"C": self.C,
|
|
108
|
+
"D": self.D,
|
|
109
|
+
"E": self.E,
|
|
110
|
+
"reactants": [r.serialize() for r in self.reactants],
|
|
111
|
+
"products": [r.serialize() for r in self.products],
|
|
112
|
+
"gas phase": self.gas_phase,
|
|
113
|
+
}
|
|
114
|
+
_add_other_properties(serialize_dict, self.other_properties)
|
|
115
|
+
return _remove_empty_keys(serialize_dict)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
Arrhenius.__doc__ = """
|
|
17
119
|
A class representing an Arrhenius rate constant.
|
|
18
120
|
|
|
19
121
|
k = A * exp( C / T ) * ( T / D )^B * exp( 1 - E * P )
|
|
@@ -42,266 +144,6 @@ class Arrhenius:
|
|
|
42
144
|
other_properties (Dict[str, Any]): A dictionary of other properties of the Arrhenius rate constant.
|
|
43
145
|
"""
|
|
44
146
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
A: Optional[float] = None,
|
|
49
|
-
B: Optional[float] = None,
|
|
50
|
-
C: Optional[float] = None,
|
|
51
|
-
Ea: Optional[float] = None,
|
|
52
|
-
D: Optional[float] = None,
|
|
53
|
-
E: Optional[float] = None,
|
|
54
|
-
reactants: Optional[List[Union[Species,
|
|
55
|
-
Tuple[float, Species]]]] = None,
|
|
56
|
-
products: Optional[List[Union[Species, Tuple[float, Species]]]] = None,
|
|
57
|
-
gas_phase: Optional[Phase] = None,
|
|
58
|
-
other_properties: Optional[Dict[str, Any]] = None,
|
|
59
|
-
):
|
|
60
|
-
"""
|
|
61
|
-
Initializes the Arrhenius object with the given parameters.
|
|
62
|
-
|
|
63
|
-
Args:
|
|
64
|
-
name (str): The name of the Arrhenius rate constant.
|
|
65
|
-
A (float): Pre-exponential factor [(mol m-3)^(n-1)s-1] where n is the number of reactants.
|
|
66
|
-
B (float): Temperature exponent [unitless].
|
|
67
|
-
C (float): Exponential term [K-1].
|
|
68
|
-
Ea (float): Activation energy [J molecule-1].
|
|
69
|
-
D (float): Reference Temperature [K].
|
|
70
|
-
E (float): Pressure scaling term [Pa-1].
|
|
71
|
-
reactants (List[Union[Species, Tuple[float, Species]]]): A list of reactants involved in the reaction.
|
|
72
|
-
products (List[Union[Species, Tuple[float, Species]]]): A list of products formed in the reaction.
|
|
73
|
-
gas_phase (Phase): The gas phase in which the reaction occurs.
|
|
74
|
-
other_properties (Dict[str, Any]): A dictionary of other properties of the Arrhenius rate constant.
|
|
75
|
-
"""
|
|
76
|
-
# Create the internal C++ instance
|
|
77
|
-
self._instance = _Arrhenius()
|
|
78
|
-
|
|
79
|
-
# Validate mutually exclusive parameters
|
|
80
|
-
if C is not None and Ea is not None:
|
|
81
|
-
raise ValueError("Cannot specify both C and Ea.")
|
|
82
|
-
|
|
83
|
-
# Set all parameters
|
|
84
|
-
if name is not None:
|
|
85
|
-
self.name = name
|
|
86
|
-
if A is not None:
|
|
87
|
-
self.A = A
|
|
88
|
-
if B is not None:
|
|
89
|
-
self.B = B
|
|
90
|
-
if Ea is not None:
|
|
91
|
-
self.C = -Ea / BOLTZMANN
|
|
92
|
-
elif C is not None:
|
|
93
|
-
self.C = C
|
|
94
|
-
if D is not None:
|
|
95
|
-
self.D = D
|
|
96
|
-
if E is not None:
|
|
97
|
-
self.E = E
|
|
98
|
-
if reactants is not None:
|
|
99
|
-
self.reactants = reactants
|
|
100
|
-
if products is not None:
|
|
101
|
-
self.products = products
|
|
102
|
-
if gas_phase is not None:
|
|
103
|
-
self.gas_phase = gas_phase
|
|
104
|
-
if other_properties is not None:
|
|
105
|
-
self.other_properties = other_properties
|
|
106
|
-
|
|
107
|
-
# Property delegation to self._instance
|
|
108
|
-
@property
|
|
109
|
-
def name(self) -> str:
|
|
110
|
-
"""Get the name of the Arrhenius rate constant."""
|
|
111
|
-
return self._instance.name
|
|
112
|
-
|
|
113
|
-
@name.setter
|
|
114
|
-
def name(self, value: str):
|
|
115
|
-
"""Set the name of the Arrhenius rate constant."""
|
|
116
|
-
self._instance.name = value
|
|
117
|
-
|
|
118
|
-
@property
|
|
119
|
-
def A(self) -> float:
|
|
120
|
-
"""Get the pre-exponential factor."""
|
|
121
|
-
return self._instance.A
|
|
122
|
-
|
|
123
|
-
@A.setter
|
|
124
|
-
def A(self, value: float):
|
|
125
|
-
"""Set the pre-exponential factor."""
|
|
126
|
-
self._instance.A = value
|
|
127
|
-
|
|
128
|
-
@property
|
|
129
|
-
def B(self) -> float:
|
|
130
|
-
"""Get the temperature exponent."""
|
|
131
|
-
return self._instance.B
|
|
132
|
-
|
|
133
|
-
@B.setter
|
|
134
|
-
def B(self, value: float):
|
|
135
|
-
"""Set the temperature exponent."""
|
|
136
|
-
self._instance.B = value
|
|
137
|
-
|
|
138
|
-
@property
|
|
139
|
-
def C(self) -> float:
|
|
140
|
-
"""Get the exponential term."""
|
|
141
|
-
return self._instance.C
|
|
142
|
-
|
|
143
|
-
@C.setter
|
|
144
|
-
def C(self, value: float):
|
|
145
|
-
"""Set the exponential term."""
|
|
146
|
-
self._instance.C = value
|
|
147
|
-
|
|
148
|
-
@property
|
|
149
|
-
def D(self) -> float:
|
|
150
|
-
"""Get the reference temperature."""
|
|
151
|
-
return self._instance.D
|
|
152
|
-
|
|
153
|
-
@D.setter
|
|
154
|
-
def D(self, value: float):
|
|
155
|
-
"""Set the reference temperature."""
|
|
156
|
-
self._instance.D = value
|
|
157
|
-
|
|
158
|
-
@property
|
|
159
|
-
def E(self) -> float:
|
|
160
|
-
"""Get the pressure scaling term."""
|
|
161
|
-
return self._instance.E
|
|
162
|
-
|
|
163
|
-
@E.setter
|
|
164
|
-
def E(self, value: float):
|
|
165
|
-
"""Set the pressure scaling term."""
|
|
166
|
-
self._instance.E = value
|
|
167
|
-
|
|
168
|
-
@property
|
|
169
|
-
def reactants(self) -> List[Union[Species, Tuple[float, Species]]]:
|
|
170
|
-
"""Get the reactants as Python objects."""
|
|
171
|
-
# Convert from C++ _ReactionComponent objects to Python Species objects
|
|
172
|
-
result = []
|
|
173
|
-
for rc in self._instance.reactants:
|
|
174
|
-
if hasattr(rc, 'coefficient') and rc.coefficient != 1.0:
|
|
175
|
-
# Create a tuple with coefficient and species
|
|
176
|
-
species = Species(name=rc.species_name)
|
|
177
|
-
result.append((rc.coefficient, species))
|
|
178
|
-
else:
|
|
179
|
-
# Just the species
|
|
180
|
-
species = Species(name=rc.species_name)
|
|
181
|
-
result.append(species)
|
|
182
|
-
return result
|
|
183
|
-
|
|
184
|
-
@reactants.setter
|
|
185
|
-
def reactants(self, value: List[Union[Species, Tuple[float, Species]]]):
|
|
186
|
-
"""Set the reactants, converting from Python to C++ objects."""
|
|
187
|
-
cpp_reactants = []
|
|
188
|
-
for r in value:
|
|
189
|
-
if isinstance(r, Species):
|
|
190
|
-
cpp_reactants.append(_ReactionComponent(r.name))
|
|
191
|
-
elif isinstance(r, tuple) and len(r) == 2:
|
|
192
|
-
coefficient, species = r
|
|
193
|
-
cpp_reactants.append(_ReactionComponent(species.name, coefficient))
|
|
194
|
-
else:
|
|
195
|
-
raise ValueError(f"Invalid reactant format: {r}")
|
|
196
|
-
self._instance.reactants = cpp_reactants
|
|
197
|
-
|
|
198
|
-
@property
|
|
199
|
-
def products(self) -> List[Union[Species, Tuple[float, Species]]]:
|
|
200
|
-
"""Get the products as Python objects."""
|
|
201
|
-
# Convert from C++ _ReactionComponent objects to Python Species objects
|
|
202
|
-
result = []
|
|
203
|
-
for rc in self._instance.products:
|
|
204
|
-
if hasattr(rc, 'coefficient') and rc.coefficient != 1.0:
|
|
205
|
-
# Create a tuple with coefficient and species
|
|
206
|
-
species = Species(name=rc.species_name)
|
|
207
|
-
result.append((rc.coefficient, species))
|
|
208
|
-
else:
|
|
209
|
-
# Just the species
|
|
210
|
-
species = Species(name=rc.species_name)
|
|
211
|
-
result.append(species)
|
|
212
|
-
return result
|
|
213
|
-
|
|
214
|
-
@products.setter
|
|
215
|
-
def products(self, value: List[Union[Species, Tuple[float, Species]]]):
|
|
216
|
-
"""Set the products, converting from Python to C++ objects."""
|
|
217
|
-
cpp_products = []
|
|
218
|
-
for p in value:
|
|
219
|
-
if isinstance(p, Species):
|
|
220
|
-
cpp_products.append(_ReactionComponent(p.name))
|
|
221
|
-
elif isinstance(p, tuple) and len(p) == 2:
|
|
222
|
-
coefficient, species = p
|
|
223
|
-
cpp_products.append(_ReactionComponent(species.name, coefficient))
|
|
224
|
-
else:
|
|
225
|
-
raise ValueError(f"Invalid product format: {p}")
|
|
226
|
-
self._instance.products = cpp_products
|
|
227
|
-
|
|
228
|
-
@property
|
|
229
|
-
def gas_phase(self) -> str:
|
|
230
|
-
"""Get the gas phase name."""
|
|
231
|
-
return self._instance.gas_phase
|
|
232
|
-
|
|
233
|
-
@gas_phase.setter
|
|
234
|
-
def gas_phase(self, value: Union[Phase, str]):
|
|
235
|
-
"""Set the gas phase."""
|
|
236
|
-
if isinstance(value, Phase):
|
|
237
|
-
self._instance.gas_phase = value.name
|
|
238
|
-
elif isinstance(value, str):
|
|
239
|
-
self._instance.gas_phase = value
|
|
240
|
-
else:
|
|
241
|
-
raise ValueError(f"Invalid gas_phase type: {type(value)}")
|
|
242
|
-
|
|
243
|
-
@property
|
|
244
|
-
def other_properties(self) -> Dict[str, Any]:
|
|
245
|
-
"""Get the other properties."""
|
|
246
|
-
return self._instance.other_properties
|
|
247
|
-
|
|
248
|
-
@other_properties.setter
|
|
249
|
-
def other_properties(self, value: Dict[str, Any]):
|
|
250
|
-
"""Set the other properties."""
|
|
251
|
-
self._instance.other_properties = value
|
|
252
|
-
|
|
253
|
-
@property
|
|
254
|
-
def type(self):
|
|
255
|
-
"""Get the reaction type."""
|
|
256
|
-
return ReactionType.Arrhenius
|
|
257
|
-
|
|
258
|
-
def _create_serialize_dict(self, instance) -> Dict:
|
|
259
|
-
"""
|
|
260
|
-
Helper method to create the serialization dictionary.
|
|
261
|
-
|
|
262
|
-
Args:
|
|
263
|
-
instance: The instance to serialize (either self._instance or a _Arrhenius object).
|
|
264
|
-
|
|
265
|
-
Returns:
|
|
266
|
-
Dict: Base serialization dictionary.
|
|
267
|
-
"""
|
|
268
|
-
return {
|
|
269
|
-
"type": "ARRHENIUS",
|
|
270
|
-
"name": instance.name,
|
|
271
|
-
"A": instance.A,
|
|
272
|
-
"B": instance.B,
|
|
273
|
-
"C": instance.C,
|
|
274
|
-
"D": instance.D,
|
|
275
|
-
"E": instance.E,
|
|
276
|
-
"reactants": ReactionComponentSerializer.serialize_list_reaction_components(instance.reactants),
|
|
277
|
-
"products": ReactionComponentSerializer.serialize_list_reaction_components(instance.products),
|
|
278
|
-
"gas phase": instance.gas_phase,
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
def serialize(self) -> Dict:
|
|
282
|
-
"""
|
|
283
|
-
Serialize the Arrhenius object to a dictionary using only Python-visible data.
|
|
284
|
-
|
|
285
|
-
Returns:
|
|
286
|
-
Dict: A dictionary representation of the Arrhenius object.
|
|
287
|
-
"""
|
|
288
|
-
serialize_dict = self._create_serialize_dict(self._instance)
|
|
289
|
-
_add_other_properties(serialize_dict, self.other_properties)
|
|
290
|
-
return serialize_dict
|
|
291
|
-
|
|
292
|
-
@staticmethod
|
|
293
|
-
def serialize_static(instance) -> Dict:
|
|
294
|
-
"""
|
|
295
|
-
Static serialize method for compatibility with C++ _Arrhenius objects.
|
|
296
|
-
|
|
297
|
-
Args:
|
|
298
|
-
instance: The _Arrhenius instance to serialize.
|
|
299
|
-
|
|
300
|
-
Returns:
|
|
301
|
-
Dict: A dictionary representation of the Arrhenius object.
|
|
302
|
-
"""
|
|
303
|
-
# Create a temporary Arrhenius object to use the helper method
|
|
304
|
-
temp_arrhenius = Arrhenius()
|
|
305
|
-
serialize_dict = temp_arrhenius._create_serialize_dict(instance)
|
|
306
|
-
_add_other_properties(serialize_dict, instance.other_properties)
|
|
307
|
-
return serialize_dict
|
|
147
|
+
Arrhenius.__init__ = __init__
|
|
148
|
+
Arrhenius.serialize = serialize
|
|
149
|
+
Arrhenius.type = type
|