musica 0.12.2__cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.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 (105) hide show
  1. musica/CMakeLists.txt +68 -0
  2. musica/__init__.py +11 -0
  3. musica/_musica.cpython-39-aarch64-linux-gnu.so +0 -0
  4. musica/_version.py +1 -0
  5. musica/backend.py +41 -0
  6. musica/binding_common.cpp +33 -0
  7. musica/binding_common.hpp +7 -0
  8. musica/carma.cpp +911 -0
  9. musica/carma.py +1729 -0
  10. musica/constants.py +3 -0
  11. musica/cpu_binding.cpp +11 -0
  12. musica/cuda.cpp +12 -0
  13. musica/cuda.py +13 -0
  14. musica/examples/__init__.py +1 -0
  15. musica/examples/carma_aluminum.py +124 -0
  16. musica/examples/carma_sulfate.py +246 -0
  17. musica/examples/examples.py +165 -0
  18. musica/examples/sulfate_box_model.py +439 -0
  19. musica/examples/ts1_latin_hypercube.py +245 -0
  20. musica/gpu_binding.cpp +11 -0
  21. musica/main.py +89 -0
  22. musica/mechanism_configuration/__init__.py +1 -0
  23. musica/mechanism_configuration/aqueous_equilibrium.py +274 -0
  24. musica/mechanism_configuration/arrhenius.py +307 -0
  25. musica/mechanism_configuration/branched.py +299 -0
  26. musica/mechanism_configuration/condensed_phase_arrhenius.py +309 -0
  27. musica/mechanism_configuration/condensed_phase_photolysis.py +88 -0
  28. musica/mechanism_configuration/emission.py +71 -0
  29. musica/mechanism_configuration/first_order_loss.py +174 -0
  30. musica/mechanism_configuration/henrys_law.py +44 -0
  31. musica/mechanism_configuration/mechanism_configuration.py +234 -0
  32. musica/mechanism_configuration/phase.py +47 -0
  33. musica/mechanism_configuration/photolysis.py +88 -0
  34. musica/mechanism_configuration/reactions.py +73 -0
  35. musica/mechanism_configuration/simpol_phase_transfer.py +217 -0
  36. musica/mechanism_configuration/species.py +91 -0
  37. musica/mechanism_configuration/surface.py +94 -0
  38. musica/mechanism_configuration/ternary_chemical_activation.py +352 -0
  39. musica/mechanism_configuration/troe.py +352 -0
  40. musica/mechanism_configuration/tunneling.py +250 -0
  41. musica/mechanism_configuration/user_defined.py +88 -0
  42. musica/mechanism_configuration/utils.py +10 -0
  43. musica/mechanism_configuration/wet_deposition.py +52 -0
  44. musica/mechanism_configuration.cpp +607 -0
  45. musica/musica.cpp +201 -0
  46. musica/test/examples/v1/full_configuration/full_configuration.json +466 -0
  47. musica/test/examples/v1/full_configuration/full_configuration.yaml +295 -0
  48. musica/test/integration/test_analytical.py +324 -0
  49. musica/test/integration/test_carma.py +227 -0
  50. musica/test/integration/test_carma_aluminum.py +12 -0
  51. musica/test/integration/test_carma_sulfate.py +17 -0
  52. musica/test/integration/test_chapman.py +139 -0
  53. musica/test/integration/test_sulfate_box_model.py +34 -0
  54. musica/test/integration/test_tuvx.py +62 -0
  55. musica/test/unit/test_parser.py +64 -0
  56. musica/test/unit/test_serializer.py +69 -0
  57. musica/test/unit/test_state.py +325 -0
  58. musica/test/unit/test_util_full_mechanism.py +698 -0
  59. musica/tools/prepare_build_environment_linux.sh +32 -0
  60. musica/tools/prepare_build_environment_macos.sh +1 -0
  61. musica/tools/repair_wheel_gpu.sh +40 -0
  62. musica/tuvx.cpp +93 -0
  63. musica/tuvx.py +199 -0
  64. musica/types.py +407 -0
  65. musica-0.12.2.dist-info/METADATA +473 -0
  66. musica-0.12.2.dist-info/RECORD +105 -0
  67. musica-0.12.2.dist-info/WHEEL +6 -0
  68. musica-0.12.2.dist-info/entry_points.txt +3 -0
  69. musica-0.12.2.dist-info/licenses/AUTHORS.md +59 -0
  70. musica-0.12.2.dist-info/licenses/LICENSE +201 -0
  71. musica.libs/libaec-34bb4966.so.0.0.8 +0 -0
  72. musica.libs/libblas-8ed0a6f9.so.3.8.0 +0 -0
  73. musica.libs/libbrotlicommon-b6e6c8bd.so.1.0.6 +0 -0
  74. musica.libs/libbrotlidec-5094ef0a.so.1.0.6 +0 -0
  75. musica.libs/libcom_err-4b53f6ce.so.2.1 +0 -0
  76. musica.libs/libcrypt-258f54d5.so.1.1.0 +0 -0
  77. musica.libs/libcrypto-3dc39733.so.1.1.1k +0 -0
  78. musica.libs/libcurl-37295c13.so.4.5.0 +0 -0
  79. musica.libs/libdf-9661c601.so.0.0.0 +0 -0
  80. musica.libs/libgfortran-e1b7dfc8.so.5.0.0 +0 -0
  81. musica.libs/libgssapi_krb5-fe951f80.so.2.2 +0 -0
  82. musica.libs/libhdf5-463e48d5.so.103.1.0 +0 -0
  83. musica.libs/libhdf5_hl-74316838.so.100.1.2 +0 -0
  84. musica.libs/libidn2-1b2a13b7.so.0.3.6 +0 -0
  85. musica.libs/libjpeg-ee25248c.so.62.2.0 +0 -0
  86. musica.libs/libk5crypto-84470bb3.so.3.1 +0 -0
  87. musica.libs/libkeyutils-fe6e95a9.so.1.6 +0 -0
  88. musica.libs/libkrb5-26ef5d84.so.3.3 +0 -0
  89. musica.libs/libkrb5support-875e89dc.so.0.1 +0 -0
  90. musica.libs/liblapack-8d137073.so.3.8.0 +0 -0
  91. musica.libs/liblber-2-86b08e65.4.so.2.10.9 +0 -0
  92. musica.libs/libldap-2-5c1dd279.4.so.2.10.9 +0 -0
  93. musica.libs/libmfhdf-9c336c5f.so.0.0.0 +0 -0
  94. musica.libs/libnetcdf-71a067be.so.15.0.1 +0 -0
  95. musica.libs/libnetcdff-6a455dd4.so.7.0.0 +0 -0
  96. musica.libs/libnghttp2-3a94c239.so.14.17.0 +0 -0
  97. musica.libs/libpcre2-8-8701a61e.so.0.7.1 +0 -0
  98. musica.libs/libpsl-130094ea.so.5.3.1 +0 -0
  99. musica.libs/libsasl2-076b3c1f.so.3.0.0 +0 -0
  100. musica.libs/libselinux-5700a1fd.so.1 +0 -0
  101. musica.libs/libssh-5abd6818.so.4.8.7 +0 -0
  102. musica.libs/libssl-b6e07dfa.so.1.1.1k +0 -0
  103. musica.libs/libsz-81b556a2.so.2.0.1 +0 -0
  104. musica.libs/libtirpc-1fa9018c.so.3.0.0 +0 -0
  105. musica.libs/libunistring-be03fd41.so.2.1.0 +0 -0
@@ -0,0 +1,73 @@
1
+ from typing import Optional, Any, Dict, List, Union
2
+ from .. import backend
3
+ from .species import Species, _Species
4
+ from .utils import _remove_empty_keys
5
+
6
+ _backend = backend.get_backend()
7
+ ReactionType = _backend._mechanism_configuration._ReactionType
8
+ _Reactions = _backend._mechanism_configuration._Reactions
9
+ _ReactionsIterator = _backend._mechanism_configuration._ReactionsIterator
10
+
11
+
12
+ class Reactions(_Reactions):
13
+ """
14
+ A class representing a collection of reactions in a chemical mechanism.
15
+
16
+ Attributes:
17
+ reactions (List[Any]): A list of reactions in the mechanism.
18
+ """
19
+
20
+ def __init__(
21
+ self,
22
+ reactions: Optional[List[Any]] = None,
23
+ ):
24
+ """
25
+ Initializes the Reactions object with the given parameters.
26
+
27
+ Args:
28
+ reactions (List[]): A list of reactions in the mechanism.
29
+ """
30
+ # Convert Python Arrhenius objects to C++ _Arrhenius objects for the C++ constructor
31
+ if reactions is not None:
32
+ cpp_reactions = []
33
+ for reaction in reactions:
34
+ if hasattr(reaction, '_instance'):
35
+ # This is a Python wrapper around a C++ object, use the internal instance
36
+ cpp_reactions.append(reaction._instance)
37
+ else:
38
+ # This is already a C++ object or other supported type
39
+ cpp_reactions.append(reaction)
40
+ super().__init__(cpp_reactions)
41
+ else:
42
+ super().__init__(reactions)
43
+
44
+
45
+ class ReactionsIterator(_ReactionsIterator):
46
+ """
47
+ An iterator for the Reactions class.
48
+ """
49
+
50
+
51
+ class ReactionComponentSerializer():
52
+ """
53
+ A class for serializing reaction components.
54
+ """
55
+
56
+ @staticmethod
57
+ def serialize_reaction_component(rc) -> Union[Dict, str]:
58
+ if isinstance(rc, Species) or isinstance(rc, _Species):
59
+ return rc.name
60
+
61
+ return _remove_empty_keys({
62
+ "species name": rc.species_name,
63
+ "coefficient": rc.coefficient,
64
+ "other_properties": rc.other_properties,
65
+ })
66
+
67
+ @staticmethod
68
+ def serialize_list_reaction_components(reaction_component_list) -> List[Union[Dict, str]]:
69
+ ret = []
70
+ for rc in reaction_component_list:
71
+ ret.append(
72
+ ReactionComponentSerializer.serialize_reaction_component(rc))
73
+ return ret
@@ -0,0 +1,217 @@
1
+ from .utils import _add_other_properties
2
+ from .species import Species
3
+ from .phase import Phase
4
+ from typing import Optional, Any, Dict, List, Union, Tuple
5
+ from .. import backend
6
+
7
+ _backend = backend.get_backend()
8
+ _SimpolPhaseTransfer = _backend._mechanism_configuration._SimpolPhaseTransfer
9
+ _ReactionComponent = _backend._mechanism_configuration._ReactionComponent
10
+ ReactionType = _backend._mechanism_configuration._ReactionType
11
+
12
+
13
+ class SimpolPhaseTransfer:
14
+ """
15
+ A class representing a simplified phase transfer reaction rate constant.
16
+
17
+ Attributes:
18
+ name (str): The name of the simplified phase transfer reaction rate constant.
19
+ gas_phase (Phase): The gas phase in which the reaction occurs.
20
+ gas_phase_species (Union[Species, Tuple[float, Species]]): The gas phase species involved in the reaction.
21
+ condensed_phase (Phase): The condensed phase in which the reaction occurs.
22
+ condensed_phase_species (Union[Species, Tuple[float, Species]]): The condensed phase species involved in the reaction.
23
+ B (List[float]): The B parameters [unitless].
24
+ other_properties (Dict[str, Any]): A dictionary of other properties of the simplified phase transfer reaction rate constant.
25
+ """
26
+
27
+ def __init__(
28
+ self,
29
+ name: Optional[str] = None,
30
+ gas_phase: Optional[Phase] = None,
31
+ gas_phase_species: Optional[Union[Species,
32
+ Tuple[float, Species]]] = None,
33
+ condensed_phase: Optional[Phase] = None,
34
+ condensed_phase_species: Optional[Union[Species,
35
+ Tuple[float, Species]]] = None,
36
+ B: Optional[List[float]] = None,
37
+ other_properties: Optional[Dict[str, Any]] = None,
38
+ ):
39
+ """
40
+ Initializes the SimpolPhaseTransfer object with the given parameters.
41
+
42
+ Args:
43
+ name (str): The name of the simplified phase transfer reaction rate constant.
44
+ gas_phase (Phase): The gas phase in which the reaction occurs.
45
+ gas_phase_species (Union[Species, Tuple[float, Species]]): The gas phase species involved in the reaction.
46
+ condensed_phase (Phase): The condensed phase in which the reaction occurs.
47
+ condensed_phase_species (Union[Species, Tuple[float, Species]]): The condensed phase species involved in the reaction.
48
+ B (List[float]): The B parameters [unitless].
49
+ other_properties (Dict[str, Any]): A dictionary of other properties of the simplified phase transfer reaction rate constant.
50
+ """
51
+ # Create the internal C++ instance
52
+ self._instance = _SimpolPhaseTransfer()
53
+
54
+ # Set all parameters
55
+ if name is not None:
56
+ self.name = name
57
+ if gas_phase is not None:
58
+ self.gas_phase = gas_phase
59
+ if gas_phase_species is not None:
60
+ self.gas_phase_species = gas_phase_species
61
+ if condensed_phase is not None:
62
+ self.condensed_phase = condensed_phase
63
+ if condensed_phase_species is not None:
64
+ self.condensed_phase_species = condensed_phase_species
65
+ if B is not None:
66
+ self.B = B
67
+ if other_properties is not None:
68
+ self.other_properties = other_properties
69
+
70
+ # Property delegation to self._instance
71
+ @property
72
+ def name(self) -> str:
73
+ """Get the name of the simplified phase transfer reaction rate constant."""
74
+ return self._instance.name
75
+
76
+ @name.setter
77
+ def name(self, value: str):
78
+ """Set the name of the simplified phase transfer reaction rate constant."""
79
+ self._instance.name = value
80
+
81
+ @property
82
+ def gas_phase(self) -> str:
83
+ """Get the gas phase name."""
84
+ return self._instance.gas_phase
85
+
86
+ @gas_phase.setter
87
+ def gas_phase(self, value: Union[Phase, str]):
88
+ """Set the gas phase."""
89
+ if isinstance(value, Phase):
90
+ self._instance.gas_phase = value.name
91
+ elif isinstance(value, str):
92
+ self._instance.gas_phase = value
93
+ else:
94
+ raise ValueError(f"Invalid gas_phase type: {type(value)}")
95
+
96
+ @property
97
+ def gas_phase_species(self) -> Union[Species, Tuple[float, Species]]:
98
+ """Get the gas phase species as Python object."""
99
+ rc = self._instance.gas_phase_species
100
+ if hasattr(rc, 'coefficient') and rc.coefficient != 1.0:
101
+ # Create a tuple with coefficient and species
102
+ species = Species(name=rc.species_name)
103
+ return (rc.coefficient, species)
104
+ else:
105
+ # Just the species
106
+ return Species(name=rc.species_name)
107
+
108
+ @gas_phase_species.setter
109
+ def gas_phase_species(self, value: Union[Species, Tuple[float, Species]]):
110
+ """Set the gas phase species, converting from Python to C++ object."""
111
+ if isinstance(value, Species):
112
+ self._instance.gas_phase_species = _ReactionComponent(value.name)
113
+ elif isinstance(value, tuple) and len(value) == 2:
114
+ coefficient, species = value
115
+ self._instance.gas_phase_species = _ReactionComponent(species.name, coefficient)
116
+ else:
117
+ raise ValueError(f"Invalid gas_phase_species format: {value}")
118
+
119
+ @property
120
+ def condensed_phase(self) -> str:
121
+ """Get the condensed phase name."""
122
+ return self._instance.condensed_phase
123
+
124
+ @condensed_phase.setter
125
+ def condensed_phase(self, value: Union[Phase, str]):
126
+ """Set the condensed phase."""
127
+ if isinstance(value, Phase):
128
+ self._instance.condensed_phase = value.name
129
+ elif isinstance(value, str):
130
+ self._instance.condensed_phase = value
131
+ else:
132
+ raise ValueError(f"Invalid condensed_phase type: {type(value)}")
133
+
134
+ @property
135
+ def condensed_phase_species(self) -> Union[Species, Tuple[float, Species]]:
136
+ """Get the condensed phase species as Python object."""
137
+ rc = self._instance.condensed_phase_species
138
+ if hasattr(rc, 'coefficient') and rc.coefficient != 1.0:
139
+ # Create a tuple with coefficient and species
140
+ species = Species(name=rc.species_name)
141
+ return (rc.coefficient, species)
142
+ else:
143
+ # Just the species
144
+ return Species(name=rc.species_name)
145
+
146
+ @condensed_phase_species.setter
147
+ def condensed_phase_species(self, value: Union[Species, Tuple[float, Species]]):
148
+ """Set the condensed phase species, converting from Python to C++ object."""
149
+ if isinstance(value, Species):
150
+ self._instance.condensed_phase_species = _ReactionComponent(value.name)
151
+ elif isinstance(value, tuple) and len(value) == 2:
152
+ coefficient, species = value
153
+ self._instance.condensed_phase_species = _ReactionComponent(species.name, coefficient)
154
+ else:
155
+ raise ValueError(f"Invalid condensed_phase_species format: {value}")
156
+
157
+ @property
158
+ def B(self) -> List[float]:
159
+ """Get the B parameters."""
160
+ return self._instance.B
161
+
162
+ @B.setter
163
+ def B(self, value: List[float]):
164
+ """Set the B parameters with validation."""
165
+ if not isinstance(value, list) or len(value) != 4:
166
+ raise ValueError("B must be a list of 4 elements.")
167
+ self._instance.B = value
168
+
169
+ @property
170
+ def other_properties(self) -> Dict[str, Any]:
171
+ """Get the other properties."""
172
+ return self._instance.other_properties
173
+
174
+ @other_properties.setter
175
+ def other_properties(self, value: Dict[str, Any]):
176
+ """Set the other properties."""
177
+ self._instance.other_properties = value
178
+
179
+ @property
180
+ def type(self):
181
+ """Get the reaction type."""
182
+ return ReactionType.SimpolPhaseTransfer
183
+
184
+ def serialize(self) -> Dict:
185
+ """
186
+ Serialize the SimpolPhaseTransfer object to a dictionary using only Python-visible data.
187
+
188
+ Returns:
189
+ Dict: A dictionary representation of the SimpolPhaseTransfer object.
190
+ """
191
+ serialize_dict = {
192
+ "type": "SIMPOL_PHASE_TRANSFER",
193
+ "name": self._instance.name,
194
+ "gas phase": self._instance.gas_phase,
195
+ "gas-phase species": self._instance.gas_phase_species.species_name,
196
+ "condensed phase": self._instance.condensed_phase,
197
+ "condensed-phase species": self._instance.condensed_phase_species.species_name,
198
+ "B": self._instance.B,
199
+ }
200
+ _add_other_properties(serialize_dict, self.other_properties)
201
+ return serialize_dict
202
+
203
+ @staticmethod
204
+ def serialize_static(instance) -> Dict:
205
+ """
206
+ Static serialize method for compatibility with C++ _SimpolPhaseTransfer objects.
207
+
208
+ Args:
209
+ instance: The _SimpolPhaseTransfer instance to serialize.
210
+
211
+ Returns:
212
+ Dict: A dictionary representation of the SimpolPhaseTransfer object.
213
+ """
214
+ # Create a local copy to call serialize
215
+ temp_obj = SimpolPhaseTransfer()
216
+ temp_obj._instance = instance
217
+ return temp_obj.serialize()
@@ -0,0 +1,91 @@
1
+ from typing import Optional, Any, Dict
2
+ from .. import backend
3
+ from .utils import _add_other_properties, _remove_empty_keys
4
+ from enum import Enum
5
+
6
+ _backend = backend.get_backend()
7
+ _Species = _backend._mechanism_configuration._Species
8
+
9
+
10
+ class Species(_Species):
11
+ """
12
+ A class representing a species in a chemical mechanism.
13
+
14
+ Attributes:
15
+ name (str): The name of the species.
16
+ HLC_298K_mol_m3_Pa (float): Henry's Law Constant at 298K [mol m-3 Pa-1]
17
+ HLC_exponential_factor_K: Henry's Law Constant exponential factor [K]
18
+ diffusion_coefficient_m2_s (float): Diffusion coefficient [m2 s-1]
19
+ N_star (float): A parameter used to calculate the mass accomodation factor (Ervens et al., 2003)
20
+ molecular_weight_kg_mol (float): Molecular weight [kg mol-1]
21
+ density_kg_m3 (float): Density [kg m-3]
22
+ tracer_type (str): Type of tracer: 'THIRD_BODY' or None [Deprecated, use is_third_body instead]
23
+ constant_concentration_mol_m3 (float): Constant concentration of the species (mol m-3)
24
+ constant_mixing_ratio_mol_mol (float): Constant mixing ratio of the species (mol mol-1)
25
+ is_third_body (bool): Whether the species is a third body.
26
+ other_properties (Dict[str, Any]): A dictionary of other properties of the species.
27
+ """
28
+
29
+ def __init__(
30
+ self,
31
+ name: Optional[str] = None,
32
+ HLC_298K_mol_m3_Pa: Optional[float] = None,
33
+ HLC_exponential_factor_K: Optional[float] = None,
34
+ diffusion_coefficient_m2_s: Optional[float] = None,
35
+ N_star: Optional[float] = None,
36
+ molecular_weight_kg_mol: Optional[float] = None,
37
+ density_kg_m3: Optional[float] = None,
38
+ tracer_type: Optional[str] = None, # Deprecated use is_third_body instead
39
+ constant_concentration_mol_m3: Optional[float] = None,
40
+ constant_mixing_ratio_mol_mol: Optional[float] = None,
41
+ is_third_body: Optional[bool] = False,
42
+ other_properties: Optional[Dict[str, Any]] = None,
43
+ ):
44
+ """
45
+ Initializes the Species object with the given parameters.
46
+
47
+ Args:
48
+ name (str): The name of the species.
49
+ HLC_298K_mol_m3_Pa (float): Henry's Law Constant at 298K [mol m-3 Pa-1]
50
+ HLC_exponential_factor_K: Henry's Law Constant exponential factor [K]
51
+ diffusion_coefficient_m2_s (float): Diffusion coefficient [m2 s-1]
52
+ N_star (float): A parameter used to calculate the mass accomodation factor (Ervens et al., 2003)
53
+ molecular_weight_kg_mol (float): Molecular weight [kg mol-1]
54
+ density_kg_m3 (float): Density [kg m-3]
55
+ tracer_type (str): Type of tracer: 'THIRD_BODY' or None [Deprecated, use is_third_body instead]
56
+ constant_concentration_mol_m3 (float): Constant concentration of the species (mol m-3)
57
+ constant_mixing_ratio_mol_mol (float): Constant mixing ratio of the species (mol mol-1)
58
+ is_third_body (bool): Whether the species is a third body.
59
+ other_properties (Dict[str, Any]): A dictionary of other properties of the species.
60
+ """
61
+ super().__init__()
62
+ self.name = name if name is not None else self.name
63
+ self.HLC_298K_mol_m3_Pa = HLC_298K_mol_m3_Pa if HLC_298K_mol_m3_Pa is not None else self.HLC_298K_mol_m3_Pa
64
+ self.HLC_exponential_factor_K = HLC_exponential_factor_K if HLC_exponential_factor_K is not None else self.HLC_exponential_factor_K
65
+ self.diffusion_coefficient_m2_s = diffusion_coefficient_m2_s if diffusion_coefficient_m2_s is not None else self.diffusion_coefficient_m2_s
66
+ self.N_star = N_star if N_star is not None else self.N_star
67
+ self.molecular_weight_kg_mol = molecular_weight_kg_mol if molecular_weight_kg_mol is not None else self.molecular_weight_kg_mol
68
+ self.density_kg_m3 = density_kg_m3 if density_kg_m3 is not None else self.density_kg_m3
69
+ self.tracer_type = tracer_type if tracer_type is not None else self.tracer_type
70
+ self.constant_concentration_mol_m3 = constant_concentration_mol_m3 if constant_concentration_mol_m3 is not None else self.constant_concentration_mol_m3
71
+ self.constant_mixing_ratio_mol_mol = constant_mixing_ratio_mol_mol if constant_mixing_ratio_mol_mol is not None else self.constant_mixing_ratio_mol_mol
72
+ self.is_third_body = is_third_body if is_third_body is not None else self.is_third_body
73
+ self.other_properties = other_properties if other_properties is not None else self.other_properties
74
+
75
+ @staticmethod
76
+ def serialize(instance) -> Dict:
77
+ serialize_dict = {
78
+ "name": instance.name,
79
+ "HLC(298K) [mol m-3 Pa-1]": instance.HLC_298K_mol_m3_Pa,
80
+ "HLC exponential factor [K]": instance.HLC_exponential_factor_K,
81
+ "diffusion coefficient [m2 s-1]": instance.diffusion_coefficient_m2_s,
82
+ "N star": instance.N_star,
83
+ "molecular weight [kg mol-1]": instance.molecular_weight_kg_mol,
84
+ "density [kg m-3]": instance.density_kg_m3,
85
+ "tracer type": instance.tracer_type,
86
+ "constant concentration [mol m-3]": instance.constant_concentration_mol_m3,
87
+ "constant mixing ratio [mol mol-1]": instance.constant_mixing_ratio_mol_mol,
88
+ "is third body": instance.is_third_body,
89
+ }
90
+ _add_other_properties(serialize_dict, instance.other_properties)
91
+ return _remove_empty_keys(serialize_dict)
@@ -0,0 +1,94 @@
1
+ from typing import Optional, Any, Dict, List, Union, Tuple
2
+ from .. import backend
3
+ from .phase import Phase
4
+ from .species import Species
5
+ from .reactions import ReactionComponentSerializer
6
+ from .utils import _add_other_properties
7
+
8
+ _backend = backend.get_backend()
9
+ _Surface = _backend._mechanism_configuration._Surface
10
+ _ReactionComponent = _backend._mechanism_configuration._ReactionComponent
11
+
12
+
13
+ class Surface(_Surface):
14
+ """
15
+ A class representing a surface in a chemical mechanism.
16
+
17
+ (TODO: get details from MusicBox)
18
+
19
+ Attributes:
20
+ name (str): The name of the surface.
21
+ reaction_probability (float): The probability of a reaction occurring on the surface.
22
+ gas_phase_species (Union[Species, Tuple[float, Species]]): The gas phase species involved in the reaction.
23
+ gas_phase_products (List[Union[Species, Tuple[float, Species]]]): The gas phase products formed in the reaction.
24
+ gas_phase (Phase): The gas phase in which the reaction occurs.
25
+ condensed_phase (Phase): The condensed phase in which the reaction occurs.
26
+ other_properties (Dict[str, Any]): A dictionary of other properties of the surface.
27
+ """
28
+
29
+ def __init__(
30
+ self,
31
+ name: Optional[str] = None,
32
+ reaction_probability: Optional[float] = None,
33
+ gas_phase_species: Optional[Union[Species,
34
+ Tuple[float, Species]]] = None,
35
+ gas_phase_products: Optional[
36
+ List[Union[Species, Tuple[float, Species]]]
37
+ ] = None,
38
+ gas_phase: Optional[Phase] = None,
39
+ condensed_phase: Optional[Phase] = None,
40
+ other_properties: Optional[Dict[str, Any]] = None,
41
+ ):
42
+ """
43
+ Initializes the Surface object with the given parameters.
44
+
45
+ Args:
46
+ name (str): The name of the surface.
47
+ reaction_probability (float): The probability of a reaction occurring on the surface.
48
+ gas_phase_species (Union[Species, Tuple[float, Species]]): The gas phase species involved in the reaction.
49
+ gas_phase_products (List[Union[Species, Tuple[float, Species]]]): The gas phase products formed in the reaction.
50
+ gas_phase (Phase): The gas phase in which the reaction occurs.
51
+ condensed_phase (Phase): The condensed phase in which the reaction occurs.
52
+ other_properties (Dict[str, Any]): A dictionary of other properties of the surface.
53
+ """
54
+ super().__init__()
55
+ self.name = name if name is not None else self.name
56
+ self.reaction_probability = reaction_probability if reaction_probability is not None else self.reaction_probability
57
+ self.gas_phase_species = (
58
+ (
59
+ _ReactionComponent(gas_phase_species.name)
60
+ if isinstance(gas_phase_species, Species)
61
+ else _ReactionComponent(gas_phase_species[1].name, gas_phase_species[0])
62
+ )
63
+ if gas_phase_species is not None
64
+ else self.gas_phase_species
65
+ )
66
+ self.gas_phase_products = (
67
+ [
68
+ (
69
+ _ReactionComponent(p.name)
70
+ if isinstance(p, Species)
71
+ else _ReactionComponent(p[1].name, p[0])
72
+ )
73
+ for p in gas_phase_products
74
+ ]
75
+ if gas_phase_products is not None
76
+ else self.gas_phase_products
77
+ )
78
+ self.gas_phase = gas_phase.name if gas_phase is not None else self.gas_phase
79
+ self.condensed_phase = condensed_phase.name if condensed_phase is not None else self.condensed_phase
80
+ self.other_properties = other_properties if other_properties is not None else self.other_properties
81
+
82
+ @staticmethod
83
+ def serialize(instance) -> Dict:
84
+ serialize_dict = {
85
+ "type": "SURFACE",
86
+ "name": instance.name,
87
+ "reaction probability": instance.reaction_probability,
88
+ "gas-phase species": instance.gas_phase_species.species_name,
89
+ "gas-phase products": ReactionComponentSerializer.serialize_list_reaction_components(instance.gas_phase_products),
90
+ "gas phase": instance.gas_phase,
91
+ "condensed phase": instance.condensed_phase,
92
+ }
93
+ _add_other_properties(serialize_dict, instance.other_properties)
94
+ return serialize_dict