pyreactlab-core 0.1.0__py3-none-any.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.
- pyreactlab_core/__init__.py +25 -0
- pyreactlab_core/app.py +123 -0
- pyreactlab_core/configs/__init__.py +0 -0
- pyreactlab_core/configs/constants.py +40 -0
- pyreactlab_core/configs/info.py +12 -0
- pyreactlab_core/core/__init__.py +1 -0
- pyreactlab_core/core/chem_react.py +839 -0
- pyreactlab_core/docs/__init__.py +14 -0
- pyreactlab_core/docs/chem_balance.py +719 -0
- pyreactlab_core/docs/chem_utils.py +114 -0
- pyreactlab_core/models/__init__.py +0 -0
- pyreactlab_core/models/reaction.py +174 -0
- pyreactlab_core/utils/__init__.py +0 -0
- pyreactlab_core/utils/tools.py +30 -0
- pyreactlab_core-0.1.0.dist-info/METADATA +179 -0
- pyreactlab_core-0.1.0.dist-info/RECORD +19 -0
- pyreactlab_core-0.1.0.dist-info/WHEEL +5 -0
- pyreactlab_core-0.1.0.dist-info/licenses/LICENSE +201 -0
- pyreactlab_core-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# import libs
|
|
2
|
+
import logging
|
|
3
|
+
from typing import List, Optional
|
|
4
|
+
# locals
|
|
5
|
+
from ..models.reaction import Reaction
|
|
6
|
+
|
|
7
|
+
# NOTE: configure logger
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def build_stoichiometry_matrix(reactions: List[Reaction]):
|
|
12
|
+
'''
|
|
13
|
+
Build stoichiometry matrix for reactions
|
|
14
|
+
|
|
15
|
+
Parameters
|
|
16
|
+
----------
|
|
17
|
+
reactions : List[Reaction]
|
|
18
|
+
List of Reaction instances
|
|
19
|
+
|
|
20
|
+
Returns
|
|
21
|
+
-------
|
|
22
|
+
component_list: list
|
|
23
|
+
component list
|
|
24
|
+
component_dict: dict
|
|
25
|
+
component dict
|
|
26
|
+
comp_list: list
|
|
27
|
+
component list
|
|
28
|
+
comp_coeff: list
|
|
29
|
+
component coefficient
|
|
30
|
+
component_state_list: list
|
|
31
|
+
component state list
|
|
32
|
+
'''
|
|
33
|
+
try:
|
|
34
|
+
# SECTION: extract reaction results
|
|
35
|
+
# NOTE: reaction num
|
|
36
|
+
reaction_num = len(reactions)
|
|
37
|
+
|
|
38
|
+
# NOTE: component list
|
|
39
|
+
component_list = []
|
|
40
|
+
|
|
41
|
+
# NOTE: component state list
|
|
42
|
+
component_state_list = []
|
|
43
|
+
|
|
44
|
+
# SECTION: Iterate over reactions and extract reactants and products
|
|
45
|
+
for item in reactions:
|
|
46
|
+
# get components
|
|
47
|
+
_components = item.all_components
|
|
48
|
+
# store
|
|
49
|
+
component_list.extend(_components)
|
|
50
|
+
|
|
51
|
+
# remove duplicate
|
|
52
|
+
component_list = list(set(component_list))
|
|
53
|
+
|
|
54
|
+
# component id: key, value
|
|
55
|
+
component_dict = {}
|
|
56
|
+
|
|
57
|
+
# loop over component list
|
|
58
|
+
for i, item in enumerate(component_list):
|
|
59
|
+
component_dict[item] = i
|
|
60
|
+
|
|
61
|
+
# SECTION: Initialize the component list
|
|
62
|
+
comp_list = [
|
|
63
|
+
{i: 0.0 for i in component_dict.keys()} for _ in range(reaction_num)
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
# SECTION: Iterate over reactions and components
|
|
67
|
+
for j, reaction in enumerate(reactions):
|
|
68
|
+
for item in component_dict.keys():
|
|
69
|
+
# NOTE: Check reactants
|
|
70
|
+
for reactant in reactions[j].reactants:
|
|
71
|
+
# matching state
|
|
72
|
+
if reactant['molecule_state'] == item:
|
|
73
|
+
comp_list[j][item] = -1 * \
|
|
74
|
+
float(reactant['coefficient'])
|
|
75
|
+
|
|
76
|
+
# >> component state list
|
|
77
|
+
component_state_list.append(
|
|
78
|
+
(
|
|
79
|
+
reactant['molecule'],
|
|
80
|
+
reactant['state'],
|
|
81
|
+
reactant['molecule_state']
|
|
82
|
+
)
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
# NOTE: Check products
|
|
86
|
+
for product in reactions[j].products:
|
|
87
|
+
# matching state
|
|
88
|
+
if product['molecule_state'] == item:
|
|
89
|
+
comp_list[j][item] = float(product['coefficient'])
|
|
90
|
+
|
|
91
|
+
# >> component state list
|
|
92
|
+
component_state_list.append(
|
|
93
|
+
(
|
|
94
|
+
product['molecule'],
|
|
95
|
+
product['state'],
|
|
96
|
+
product['molecule_state']
|
|
97
|
+
)
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
# Convert comp_list to comp_matrix
|
|
101
|
+
comp_coeff = [
|
|
102
|
+
[comp_list[j][item] for item in component_dict.keys()] for j in range(reaction_num)
|
|
103
|
+
]
|
|
104
|
+
|
|
105
|
+
# res
|
|
106
|
+
return {
|
|
107
|
+
"component_list": component_list,
|
|
108
|
+
"component_dict": component_dict,
|
|
109
|
+
"component_state_list": component_state_list,
|
|
110
|
+
"comp_list": comp_list,
|
|
111
|
+
"comp_coeff": comp_coeff,
|
|
112
|
+
}
|
|
113
|
+
except Exception as e:
|
|
114
|
+
raise Exception(f"Error defining component ID: {e}")
|
|
File without changes
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# import libs
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
|
|
4
|
+
from typing import Any, Dict, Optional, List
|
|
5
|
+
from pydantic import BaseModel, Field, computed_field, model_validator
|
|
6
|
+
# local imports
|
|
7
|
+
from ..core.chem_react import (
|
|
8
|
+
ChemReact,
|
|
9
|
+
ReactionMode,
|
|
10
|
+
PhaseRule
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Reaction(BaseModel):
|
|
15
|
+
"""
|
|
16
|
+
A class representing a chemical reaction, including its analysis and properties.
|
|
17
|
+
|
|
18
|
+
Attributes
|
|
19
|
+
----------
|
|
20
|
+
name : str
|
|
21
|
+
The name of the reaction.
|
|
22
|
+
reaction : str
|
|
23
|
+
The chemical reaction equation as a string.
|
|
24
|
+
reaction_mode_symbol : Optional[ReactionMode]
|
|
25
|
+
The symbol used to separate reactants and products in a reaction equation.
|
|
26
|
+
analysis : Dict[str, Any]
|
|
27
|
+
A dictionary containing the analysis results of the reaction.
|
|
28
|
+
|
|
29
|
+
Properties
|
|
30
|
+
----------
|
|
31
|
+
symbolic_reaction : str
|
|
32
|
+
The symbolic representation of the balanced reaction.
|
|
33
|
+
symbolic_unbalanced_reaction : str
|
|
34
|
+
The symbolic representation of the unbalanced reaction.
|
|
35
|
+
reactants_names : list[str]
|
|
36
|
+
A list of names of the reactants in the reaction.
|
|
37
|
+
products_names : list[str]
|
|
38
|
+
A list of names of the products in the reaction.
|
|
39
|
+
products : List[Dict[str, Any]]
|
|
40
|
+
A list of dictionaries representing the products of the reaction.
|
|
41
|
+
reactants : List[Dict[str, Any]]
|
|
42
|
+
A list of dictionaries representing the reactants of the reaction.
|
|
43
|
+
reaction_coefficients : Dict[str, float]
|
|
44
|
+
A dictionary of reaction coefficients for each component.
|
|
45
|
+
reaction_stoichiometry : Dict[str, float]
|
|
46
|
+
A dictionary representing the stoichiometry of the reaction.
|
|
47
|
+
reaction_stoichiometry_matrix : list[float]
|
|
48
|
+
A list representing the stoichiometry matrix of the reaction.
|
|
49
|
+
carbon_count : int
|
|
50
|
+
The total number of carbon atoms in the reaction.
|
|
51
|
+
reaction_state : str
|
|
52
|
+
The state of the reaction (e.g., "balanced", "unbalanced").
|
|
53
|
+
reaction_phase : Optional[PhaseRule]
|
|
54
|
+
The phase rule of the reaction, if applicable.
|
|
55
|
+
state_count : Dict[str, int]
|
|
56
|
+
A dictionary counting the states of components in the reaction.
|
|
57
|
+
component_ids : Dict[str, int]
|
|
58
|
+
A dictionary mapping component names to their IDs.
|
|
59
|
+
all_components : list[str]
|
|
60
|
+
A list of all component names involved in the reaction.
|
|
61
|
+
|
|
62
|
+
Methods
|
|
63
|
+
-------
|
|
64
|
+
_run_existing_analysis(self) -> Reaction
|
|
65
|
+
Validates and analyzes the reaction after initialization.
|
|
66
|
+
"""
|
|
67
|
+
name: str
|
|
68
|
+
reaction: str
|
|
69
|
+
reaction_mode_symbol: Optional[ReactionMode] = Field(
|
|
70
|
+
default=None,
|
|
71
|
+
description="The symbol used to separate reactants and products in a reaction equation."
|
|
72
|
+
)
|
|
73
|
+
analysis: Dict[str, Any] = Field(default_factory=dict)
|
|
74
|
+
|
|
75
|
+
@model_validator(mode="after")
|
|
76
|
+
def _run_existing_analysis(self):
|
|
77
|
+
# NOTE: check reaction mode symbol
|
|
78
|
+
if "<=>" in self.reaction:
|
|
79
|
+
self.reaction_mode_symbol = "<=>"
|
|
80
|
+
elif "=>" in self.reaction:
|
|
81
|
+
self.reaction_mode_symbol = "=>"
|
|
82
|
+
elif "=" in self.reaction:
|
|
83
|
+
self.reaction_mode_symbol = "="
|
|
84
|
+
else:
|
|
85
|
+
raise ValueError(
|
|
86
|
+
f"Invalid reaction format in reaction: {self.reaction}"
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
# NOTE: analyze reaction
|
|
90
|
+
util = ChemReact(reaction_mode_symbol=self.reaction_mode_symbol)
|
|
91
|
+
|
|
92
|
+
# NOTE: perform analysis
|
|
93
|
+
self.analysis = util.analyze_reaction(
|
|
94
|
+
reaction_pack={
|
|
95
|
+
"name": self.name,
|
|
96
|
+
"reaction": self.reaction
|
|
97
|
+
},
|
|
98
|
+
)
|
|
99
|
+
return self
|
|
100
|
+
|
|
101
|
+
@computed_field
|
|
102
|
+
@property
|
|
103
|
+
def symbolic_reaction(self) -> str:
|
|
104
|
+
return self.analysis.get("symbolic_reaction", "")
|
|
105
|
+
|
|
106
|
+
@computed_field
|
|
107
|
+
@property
|
|
108
|
+
def symbolic_unbalanced_reaction(self) -> str:
|
|
109
|
+
return self.analysis.get("symbolic_unbalanced_reaction", "")
|
|
110
|
+
|
|
111
|
+
@computed_field
|
|
112
|
+
@property
|
|
113
|
+
def reactants_names(self) -> list[str]:
|
|
114
|
+
return self.analysis.get("reactants_names", [])
|
|
115
|
+
|
|
116
|
+
@computed_field
|
|
117
|
+
@property
|
|
118
|
+
def products_names(self) -> list[str]:
|
|
119
|
+
return self.analysis.get("products_names", [])
|
|
120
|
+
|
|
121
|
+
@computed_field
|
|
122
|
+
@property
|
|
123
|
+
def products(self) -> List[Dict[str, Any]]:
|
|
124
|
+
return self.analysis.get("products", [])
|
|
125
|
+
|
|
126
|
+
@computed_field
|
|
127
|
+
@property
|
|
128
|
+
def reactants(self) -> List[Dict[str, Any]]:
|
|
129
|
+
return self.analysis.get("reactants", [])
|
|
130
|
+
|
|
131
|
+
@computed_field
|
|
132
|
+
@property
|
|
133
|
+
def reaction_coefficients(self) -> Dict[str, float]:
|
|
134
|
+
return self.analysis.get("reaction_coefficients", {})
|
|
135
|
+
|
|
136
|
+
@computed_field
|
|
137
|
+
@property
|
|
138
|
+
def reaction_stoichiometry(self) -> Dict[str, float]:
|
|
139
|
+
return self.analysis.get("reaction_stoichiometry", {})
|
|
140
|
+
|
|
141
|
+
@computed_field
|
|
142
|
+
@property
|
|
143
|
+
def reaction_stoichiometry_matrix(self) -> list[float]:
|
|
144
|
+
return self.analysis.get("reaction_stoichiometry_matrix", [])
|
|
145
|
+
|
|
146
|
+
@computed_field
|
|
147
|
+
@property
|
|
148
|
+
def carbon_count(self) -> int:
|
|
149
|
+
return self.analysis.get("carbon_count", 0)
|
|
150
|
+
|
|
151
|
+
@computed_field
|
|
152
|
+
@property
|
|
153
|
+
def reaction_state(self) -> str:
|
|
154
|
+
return self.analysis.get("reaction_state", "unknown")
|
|
155
|
+
|
|
156
|
+
@computed_field
|
|
157
|
+
@property
|
|
158
|
+
def reaction_phase(self) -> Optional[PhaseRule]:
|
|
159
|
+
return self.analysis.get("reaction_phase", None)
|
|
160
|
+
|
|
161
|
+
@computed_field
|
|
162
|
+
@property
|
|
163
|
+
def state_count(self) -> Dict[str, int]:
|
|
164
|
+
return self.analysis.get("state_count", {})
|
|
165
|
+
|
|
166
|
+
@computed_field
|
|
167
|
+
@property
|
|
168
|
+
def component_ids(self) -> Dict[str, int]:
|
|
169
|
+
return self.analysis.get("component_ids", {})
|
|
170
|
+
|
|
171
|
+
@computed_field
|
|
172
|
+
@property
|
|
173
|
+
def all_components(self) -> list[str]:
|
|
174
|
+
return self.analysis.get("all_components", [])
|
|
File without changes
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# import libs
|
|
2
|
+
import logging
|
|
3
|
+
from typing import Literal, Optional
|
|
4
|
+
|
|
5
|
+
# setup logger
|
|
6
|
+
logger = logging.getLogger(__name__)
|
|
7
|
+
|
|
8
|
+
# NOTE: check if value is number
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def is_number(value: str) -> bool:
|
|
12
|
+
try:
|
|
13
|
+
float(value)
|
|
14
|
+
return True
|
|
15
|
+
except (ValueError, TypeError):
|
|
16
|
+
return False
|
|
17
|
+
|
|
18
|
+
# NOTE: check if value is integer
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def is_integer(value: str) -> bool:
|
|
22
|
+
try:
|
|
23
|
+
num = float(value) # handles "10", "10.5", "1e-3", etc.
|
|
24
|
+
except (ValueError, TypeError):
|
|
25
|
+
return False
|
|
26
|
+
|
|
27
|
+
if num.is_integer(): # built-in float method
|
|
28
|
+
return True
|
|
29
|
+
else:
|
|
30
|
+
return False
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyreactlab-core
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: pyreactlab-core is the core foundation of the PyReactLab ecosystem, offering shared data structures and algorithms for chemical reaction representation, stoichiometry, and reaction analysis.
|
|
5
|
+
Author-email: Sina Gilassi <sina.gilassi@gmail.com>
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/sinagilassi/PyReactLab-Core
|
|
8
|
+
Project-URL: Documentation, https://pyreactlab-core.readthedocs.io/en/latest/
|
|
9
|
+
Project-URL: Source, https://github.com/sinagilassi/PyReactLab-Core
|
|
10
|
+
Project-URL: Tracker, https://github.com/sinagilassi/PyReactLab-Core/issues
|
|
11
|
+
Keywords: chemical-engineering,chemical-reactions,reaction-representation,reaction-stoichiometry,reaction-analysis
|
|
12
|
+
Classifier: Development Status :: 1 - Planning
|
|
13
|
+
Classifier: Intended Audience :: Education
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Operating System :: Unix
|
|
16
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
17
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
18
|
+
Requires-Python: >=3.11
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: numpy>=2.4.0
|
|
22
|
+
Requires-Dist: pydantic>=2.12.5
|
|
23
|
+
Requires-Dist: pydantic-settings>=2.12.0
|
|
24
|
+
Requires-Dist: scipy>=1.16.3
|
|
25
|
+
Dynamic: license-file
|
|
26
|
+
|
|
27
|
+
# 🧪 PyReactLab-Core
|
|
28
|
+
|
|
29
|
+
[](https://pepy.tech/projects/pyreactlab-core)
|
|
30
|
+

|
|
31
|
+

|
|
32
|
+

|
|
33
|
+

|
|
34
|
+
|
|
35
|
+
**PyReactLab-Core** is the core foundation of the PyReactLab ecosystem, offering shared data structures and algorithms for chemical reaction representation, stoichiometry, and reaction analysis.
|
|
36
|
+
|
|
37
|
+
## ✨ Features
|
|
38
|
+
|
|
39
|
+
- **⚗️ Reaction Representation**: Define and manipulate chemical reactions with ease.
|
|
40
|
+
- **⚖️ Stoichiometry Calculations**: Perform stoichiometric calculations for reactions.
|
|
41
|
+
- **🔬 Reaction Analysis**: Analyze reaction properties and behaviors.
|
|
42
|
+
- **🧩 Extensible Design**: Built to be extended by other PyReactLab modules.
|
|
43
|
+
|
|
44
|
+
## 📦 Installation
|
|
45
|
+
|
|
46
|
+
You can install PyReactLab-Core via pip:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install pyreactlab-core
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## 🚀 Usage
|
|
53
|
+
|
|
54
|
+
### Introduce a reaction
|
|
55
|
+
|
|
56
|
+
A typical reaction can be introduced as follows:
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from pyreactlab_core import Reaction
|
|
60
|
+
|
|
61
|
+
reaction = Reaction(
|
|
62
|
+
name="Combustion of Methane",
|
|
63
|
+
reaction="CO2(g) + 3H2(g) => CH3OH(g) + H2O(g)"
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
# print analysis
|
|
67
|
+
print(
|
|
68
|
+
f"[bold underline]Reaction Analysis for: {reaction_1.name}[/bold underline]")
|
|
69
|
+
print(f"Reaction: {reaction_1.reaction}")
|
|
70
|
+
print(f"Reactants: {reaction_1.reactants}")
|
|
71
|
+
print(f"Products: {reaction_1.products}")
|
|
72
|
+
print(f"Reaction Coefficients: {reaction_1.reaction_coefficients}")
|
|
73
|
+
print(f"Reaction Stoichiometry: {reaction_1.reaction_stoichiometry}")
|
|
74
|
+
print(f"State Counts: {reaction_1.state_count}")
|
|
75
|
+
print(f"Reaction Phase: {reaction_1.reaction_phase}")
|
|
76
|
+
print(f"Reaction State: {reaction_1.reaction_state}")
|
|
77
|
+
print(f"Carbon Count: {reaction_1.carbon_count}")
|
|
78
|
+
print(f"Reactants Names: {reaction_1.reactants_names}")
|
|
79
|
+
print(f"Products Names: {reaction_1.products_names}")
|
|
80
|
+
|
|
81
|
+
# results:
|
|
82
|
+
# Reaction: CO2(g) + 3H2(g) => CH3OH(g) + H2O(g)
|
|
83
|
+
# Component IDs: {'CO2-g': 1, 'H2-g': 2, 'CH3OH-g': 3, 'H2O-g': 4}
|
|
84
|
+
# Reaction Mode Symbol: =>
|
|
85
|
+
# Symbolic Unbalanced Reaction: CO2 + H2 => CH3OH + H2O
|
|
86
|
+
# Symbolic Reaction: CO2 + 3.0H2 => CH3OH + H2O
|
|
87
|
+
# Reactants: [{'coefficient': 1.0, 'molecule': 'CO2', 'state': 'g', 'molecule_state': 'CO2-g'}, {'coefficient': 3.0, 'molecule': 'H2', 'state': 'g', 'molecule_state': 'H2-g'}]
|
|
88
|
+
# Products: [{'coefficient': 1.0, 'molecule': 'CH3OH', 'state': 'g', 'molecule_state': 'CH3OH-g'}, {'coefficient': 1.0, 'molecule': 'H2O', 'state': 'g', 'molecule_state': 'H2O-g'}]
|
|
89
|
+
# Reaction Coefficients: 2.0
|
|
90
|
+
# Reaction Stoichiometry: {'CO2-g': -1.0, 'H2-g': -3.0, 'CH3OH-g': 1.0, 'H2O-g': 1.0}
|
|
91
|
+
# State Counts: {'g': 4, 'l': 0, 'aq': 0, 's': 0}
|
|
92
|
+
# Reaction Phase: gas
|
|
93
|
+
# Reaction State: {'CO2-g': 'g', 'H2-g': 'g', 'CH3OH-g': 'g', 'H2O-g': 'g'}
|
|
94
|
+
# Carbon Count: {'CO2-g': 1.0, 'H2-g': 0.0, 'CH3OH-g': 1.0, 'H2O-g': 0.0}
|
|
95
|
+
# Reactants Names: ['CO2-g', 'H2-g']
|
|
96
|
+
# Products Names: ['CH3OH-g', 'H2O-g']
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Stoichiometric Balance
|
|
100
|
+
|
|
101
|
+
You can check if a reaction is balanced:
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
from pyreactlab_core import Reaction
|
|
105
|
+
from pyreactlab_core.core import balance
|
|
106
|
+
|
|
107
|
+
# define a reaction
|
|
108
|
+
reaction = Reaction(
|
|
109
|
+
name="Combustion of Methane",
|
|
110
|
+
reaction="CO2(g) + 3H2(g) => CH3OH(g) + H2O(g)"
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
# balance the reaction automatically
|
|
114
|
+
balanced_reaction = balance(reaction)
|
|
115
|
+
print(f"Balanced Reaction: {balanced_reaction.reaction}")
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Stoichiometric Matrix
|
|
119
|
+
|
|
120
|
+
You can create a stoichiometric matrix for a list of reactions:
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
from pyreactlab_core import Reaction
|
|
124
|
+
from pyreactlab_core import rxn, rxn_stoichiometry, rxns_stoichiometry
|
|
125
|
+
|
|
126
|
+
# NOTE: define reaction string
|
|
127
|
+
reaction_1 = "CO2(g) + 3H2(g) => CH3OH(g) + H2O(g)"
|
|
128
|
+
name_1 = "CO2 Hydrogenation to Methanol"
|
|
129
|
+
|
|
130
|
+
# second reaction
|
|
131
|
+
reaction_2 = "C2H4(g) + H2(g) => C2H6(g)"
|
|
132
|
+
name_2 = "Ethylene Hydrogenation to Ethane"
|
|
133
|
+
|
|
134
|
+
# NOTE: create reaction instance
|
|
135
|
+
rxn_1: Reaction = rxn(
|
|
136
|
+
reaction_str=reaction_1,
|
|
137
|
+
name=name_1
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
rxn_2: Reaction = rxn(
|
|
141
|
+
reaction_str=reaction_2,
|
|
142
|
+
name=name_2
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
# NOTE: Get stoichiometry matrices for multiple reactions
|
|
146
|
+
reactions_list = [rxn_1, rxn_2]
|
|
147
|
+
stoichiometry_matrices = rxns_stoichiometry(
|
|
148
|
+
reactions=reactions_list,
|
|
149
|
+
)
|
|
150
|
+
# log
|
|
151
|
+
print(stoichiometry_matrices)
|
|
152
|
+
|
|
153
|
+
# results:
|
|
154
|
+
# {
|
|
155
|
+
# 'components': ['CO2-g', 'H2O-g', 'C2H4-g', 'H2-g', 'CH3OH-g', 'C2H6-g'],
|
|
156
|
+
# 'component_ids': {'CO2-g': 0, 'H2O-g': 1, 'C2H4-g': 2, 'H2-g': 3, 'CH3OH-g': 4, 'C2H6-g': 5},
|
|
157
|
+
# 'stoichiometry_matrices_list': [[-1.0, 1.0, 0.0, -3.0, 1.0, 0.0], [0.0, 0.0, -1.0, -1.0, 0.0, 1.0]],
|
|
158
|
+
# 'stoichiometry_matrices_dict': [
|
|
159
|
+
# {'CO2-g': -1.0, 'H2O-g': 1.0, 'C2H4-g': 0.0, 'H2-g': -3.0, 'CH3OH-g': 1.0, 'C2H6-g': 0.0},
|
|
160
|
+
# {'CO2-g': 0.0, 'H2O-g': 0.0, 'C2H4-g': -1.0, 'H2-g': -1.0, 'CH3OH-g': 0.0, 'C2H6-g': 1.0}
|
|
161
|
+
# ]
|
|
162
|
+
# }
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## 🤝 Contributing
|
|
166
|
+
|
|
167
|
+
Contributions are highly welcome — bug fixes, new calculation routines, mixture models, extended unit tests, documentation, etc.
|
|
168
|
+
|
|
169
|
+
## 📝 License
|
|
170
|
+
|
|
171
|
+
This project is distributed under the Apache License, Version 2.0, which grants you broad freedom to use, modify, and integrate the software into your own applications or projects, provided that you comply with the conditions outlined in the license. Although Apache 2.0 does not require users to retain explicit author credit beyond standard copyright and license notices, I kindly request that if you incorporate this work into your own software, you acknowledge Sina Gilassi as the original author. Referencing the original repository or documentation is appreciated, as it helps recognize the effort invested in developing and maintaining this project.
|
|
172
|
+
|
|
173
|
+
## ❓ FAQ
|
|
174
|
+
|
|
175
|
+
For any question, contact me on [LinkedIn](https://www.linkedin.com/in/sina-gilassi/)
|
|
176
|
+
|
|
177
|
+
## 👨💻 Authors
|
|
178
|
+
|
|
179
|
+
- [@sinagilassi](https://www.github.com/sinagilassi)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
pyreactlab_core/__init__.py,sha256=JGNJu9kdkUlIjNog8OXeCHCpnB9nJfClHqW-BcqoGxQ,453
|
|
2
|
+
pyreactlab_core/app.py,sha256=HWVXNpFHqKWqf5TUaym9SCUjAxEDRYEWCU-EPK-Yi5g,3605
|
|
3
|
+
pyreactlab_core/configs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
pyreactlab_core/configs/constants.py,sha256=8dpnVqnYwu5On1IH7toELWvNHp4BLgpLnhTRDobKVis,1295
|
|
5
|
+
pyreactlab_core/configs/info.py,sha256=uvzRSHbrnPlbzSn-rGNE11Htq6pIK-N9f0eE8NhD3Oo,448
|
|
6
|
+
pyreactlab_core/core/__init__.py,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
|
7
|
+
pyreactlab_core/core/chem_react.py,sha256=nMvAfZxw5OysSeYIhg82iaKil59Obc6dCMmq1CoKllw,31174
|
|
8
|
+
pyreactlab_core/docs/__init__.py,sha256=Q_nWMKjz40OCw-WsSHu-8Aenvj1_yY_N47VnCpzeMTA,262
|
|
9
|
+
pyreactlab_core/docs/chem_balance.py,sha256=qU035GBsFvFoEQCV_596OTGtFRqlnfMm4mXimqLdd5M,21503
|
|
10
|
+
pyreactlab_core/docs/chem_utils.py,sha256=jTyo-iMXs4JNqenZJ-g7Np_0SLfWGmu2trPUjWQZMzI,3603
|
|
11
|
+
pyreactlab_core/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
+
pyreactlab_core/models/reaction.py,sha256=LiUKwoiKy_49WBboYPsZWyyFzVp9E1pv6JxoluQgC8U,5818
|
|
13
|
+
pyreactlab_core/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
+
pyreactlab_core/utils/tools.py,sha256=P8fwEYzXVteRb76BGT6IDtDQj2UJfEiZfyij5OzbA_k,638
|
|
15
|
+
pyreactlab_core-0.1.0.dist-info/licenses/LICENSE,sha256=HrhfyXIkWY2tGFK11kg7vPCqhgh5DcxleloqdhrpyMY,11558
|
|
16
|
+
pyreactlab_core-0.1.0.dist-info/METADATA,sha256=IZyxyYBC6_ZaqrKvHtkrdG-l4Zkfrydkj1jb6KkYHog,7286
|
|
17
|
+
pyreactlab_core-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
18
|
+
pyreactlab_core-0.1.0.dist-info/top_level.txt,sha256=OTJ7aN0HVzzbIM1yAOk9UGg0v4AvpshSY86msqB7uiM,16
|
|
19
|
+
pyreactlab_core-0.1.0.dist-info/RECORD,,
|