exerpy 0.0.1__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.
- exerpy/__init__.py +12 -0
- exerpy/analyses.py +1711 -0
- exerpy/components/__init__.py +16 -0
- exerpy/components/combustion/__init__.py +0 -0
- exerpy/components/combustion/base.py +248 -0
- exerpy/components/component.py +126 -0
- exerpy/components/heat_exchanger/__init__.py +0 -0
- exerpy/components/heat_exchanger/base.py +449 -0
- exerpy/components/heat_exchanger/condenser.py +323 -0
- exerpy/components/heat_exchanger/simple.py +358 -0
- exerpy/components/heat_exchanger/steam_generator.py +264 -0
- exerpy/components/helpers/__init__.py +0 -0
- exerpy/components/helpers/cycle_closer.py +104 -0
- exerpy/components/nodes/__init__.py +0 -0
- exerpy/components/nodes/deaerator.py +318 -0
- exerpy/components/nodes/drum.py +164 -0
- exerpy/components/nodes/flash_tank.py +89 -0
- exerpy/components/nodes/mixer.py +332 -0
- exerpy/components/piping/__init__.py +0 -0
- exerpy/components/piping/valve.py +394 -0
- exerpy/components/power_machines/__init__.py +0 -0
- exerpy/components/power_machines/generator.py +168 -0
- exerpy/components/power_machines/motor.py +173 -0
- exerpy/components/turbomachinery/__init__.py +0 -0
- exerpy/components/turbomachinery/compressor.py +318 -0
- exerpy/components/turbomachinery/pump.py +310 -0
- exerpy/components/turbomachinery/turbine.py +351 -0
- exerpy/data/Ahrendts.json +90 -0
- exerpy/functions.py +637 -0
- exerpy/parser/__init__.py +0 -0
- exerpy/parser/from_aspen/__init__.py +0 -0
- exerpy/parser/from_aspen/aspen_config.py +61 -0
- exerpy/parser/from_aspen/aspen_parser.py +721 -0
- exerpy/parser/from_ebsilon/__init__.py +38 -0
- exerpy/parser/from_ebsilon/check_ebs_path.py +74 -0
- exerpy/parser/from_ebsilon/ebsilon_config.py +1055 -0
- exerpy/parser/from_ebsilon/ebsilon_functions.py +181 -0
- exerpy/parser/from_ebsilon/ebsilon_parser.py +660 -0
- exerpy/parser/from_ebsilon/utils.py +79 -0
- exerpy/parser/from_tespy/tespy_config.py +23 -0
- exerpy-0.0.1.dist-info/METADATA +158 -0
- exerpy-0.0.1.dist-info/RECORD +44 -0
- exerpy-0.0.1.dist-info/WHEEL +4 -0
- exerpy-0.0.1.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import Any
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
from CoolProp.CoolProp import PropsSI as CP
|
|
6
|
+
|
|
7
|
+
from . import __ebsilon_available__
|
|
8
|
+
from .utils import EpGasTableStub
|
|
9
|
+
from .utils import EpSteamTableStub
|
|
10
|
+
from .utils import require_ebsilon
|
|
11
|
+
|
|
12
|
+
# Import Ebsilon classes if available
|
|
13
|
+
if __ebsilon_available__:
|
|
14
|
+
from EbsOpen import EpGasTable
|
|
15
|
+
from EbsOpen import EpSteamTable
|
|
16
|
+
else:
|
|
17
|
+
EpSteamTable = EpSteamTableStub
|
|
18
|
+
EpGasTable = EpGasTableStub
|
|
19
|
+
|
|
20
|
+
from exerpy.functions import convert_to_SI
|
|
21
|
+
|
|
22
|
+
from .ebsilon_config import substance_mapping
|
|
23
|
+
from .ebsilon_config import unit_id_to_string
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@require_ebsilon
|
|
27
|
+
def calc_X_from_PT(app: Any, pipe: Any, property: str, pressure: float, temperature: float) -> Optional[float]:
|
|
28
|
+
"""
|
|
29
|
+
Calculate a thermodynamic property (enthalpy or entropy) for a given stream based on pressure and temperature.
|
|
30
|
+
|
|
31
|
+
This method takes pressure and temperature values and calculates the specified property for any fluid stream.
|
|
32
|
+
It automatically handles the composition of the stream by setting up appropriate fluid properties and analysis
|
|
33
|
+
parameters based on the stream's fluid type and composition.
|
|
34
|
+
|
|
35
|
+
Parameters
|
|
36
|
+
----------
|
|
37
|
+
app : Ebsilon application instance
|
|
38
|
+
The Ebsilon application used for creating fluid and analysis objects.
|
|
39
|
+
pipe : Stream object
|
|
40
|
+
The stream object containing fluid and composition information.
|
|
41
|
+
property : str
|
|
42
|
+
The thermodynamic property to calculate, either 'H' for enthalpy or 'S' for entropy.
|
|
43
|
+
pressure : float
|
|
44
|
+
The pressure value (in bar).
|
|
45
|
+
temperature : float
|
|
46
|
+
The temperature value (in °C).
|
|
47
|
+
|
|
48
|
+
Returns
|
|
49
|
+
-------
|
|
50
|
+
float
|
|
51
|
+
The calculated value of the specified property (in J/kg for enthalpy, J/kgK for entropy).
|
|
52
|
+
Returns None if an invalid property is specified or an error occurs during calculation.
|
|
53
|
+
|
|
54
|
+
Raises
|
|
55
|
+
------
|
|
56
|
+
Exception
|
|
57
|
+
Logs an error and returns None if any exception occurs during property calculation.
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
# Create a new FluidData object
|
|
61
|
+
fd = app.NewFluidData()
|
|
62
|
+
|
|
63
|
+
# Retrieve the fluid type from the stream
|
|
64
|
+
fd.FluidType = (pipe.Kind-1000)
|
|
65
|
+
|
|
66
|
+
if fd.FluidType == 3 or fd.FluidType == 4: # steam or water
|
|
67
|
+
t_sat = CP('T', 'P', pressure, 'Q', 0, 'water')
|
|
68
|
+
if temperature > t_sat:
|
|
69
|
+
fd.FluidType = 3 # steam
|
|
70
|
+
fd.SteamTable = EpSteamTable.epSteamTableFromSuperiorModel
|
|
71
|
+
fdAnalysis = app.NewFluidAnalysis()
|
|
72
|
+
else:
|
|
73
|
+
fd.FluidType == 4 # water
|
|
74
|
+
fdAnalysis = app.NewFluidAnalysis()
|
|
75
|
+
|
|
76
|
+
elif fd.FluidType == 15: # 2PhaseLiquid
|
|
77
|
+
fd.Medium = pipe.FMED.Value
|
|
78
|
+
fdAnalysis = app.NewFluidAnalysis()
|
|
79
|
+
|
|
80
|
+
elif fd.FluidType == 16: # 2PhaseGaseous
|
|
81
|
+
fd.Medium = pipe.FMED.Value
|
|
82
|
+
fdAnalysis = app.NewFluidAnalysis()
|
|
83
|
+
|
|
84
|
+
elif fd.FluidType == 17: # Salt water
|
|
85
|
+
fd.Medium = pipe.FMED.Value
|
|
86
|
+
fdAnalysis = app.NewFluidAnalysis()
|
|
87
|
+
|
|
88
|
+
else: # flue gas, air etc.
|
|
89
|
+
fd.GasTable = EpGasTable.epGasTableFromSuperiorModel
|
|
90
|
+
|
|
91
|
+
# Set up the fluid analysis based on stream composition
|
|
92
|
+
fdAnalysis = app.NewFluidAnalysis()
|
|
93
|
+
|
|
94
|
+
# Iterate through the substance_mapping and get the corresponding value from the pipe
|
|
95
|
+
for substance_key, ep_substance_id in substance_mapping.items():
|
|
96
|
+
fraction = getattr(pipe, substance_key).Value # Dynamically access the fraction
|
|
97
|
+
if fraction > 0: # Only set substances with non-zero fractions
|
|
98
|
+
fdAnalysis.SetSubstance(ep_substance_id, fraction)
|
|
99
|
+
|
|
100
|
+
# Set the analysis in the FluidData object
|
|
101
|
+
fd.SetAnalysis(fdAnalysis)
|
|
102
|
+
|
|
103
|
+
# Validate property input
|
|
104
|
+
if property not in ['S', 'H']:
|
|
105
|
+
logging.error('Invalid property selected. You can choose between "H" (enthalpy) and "S" (entropy).')
|
|
106
|
+
return None
|
|
107
|
+
|
|
108
|
+
try:
|
|
109
|
+
# Calculate the property based on the input property type
|
|
110
|
+
if property == 'S': # Entropy
|
|
111
|
+
res = fd.PropertyS_OF_PT(pressure * 1e-5, temperature - 273.15) # Ebsilon works with °C and bar
|
|
112
|
+
res_SI = res * 1e3 # Convert kJ/kgK to J/kgK
|
|
113
|
+
elif property == 'H': # Enthalpy
|
|
114
|
+
res = fd.PropertyH_OF_PT(pressure * 1e-5, temperature - 273.15) # Ebsilon works with °C and bar
|
|
115
|
+
res_SI = res * 1e3 # Convert kJ/kg to J/kg
|
|
116
|
+
|
|
117
|
+
return res_SI
|
|
118
|
+
|
|
119
|
+
except Exception as e:
|
|
120
|
+
logging.error(f"An error occurred during property calculation: {e}")
|
|
121
|
+
return None
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
@require_ebsilon
|
|
125
|
+
def calc_eT(app: Any, pipe: Any, pressure: float, Tamb: float, pamb: float) -> float:
|
|
126
|
+
"""
|
|
127
|
+
Calculate the thermal component of physical exergy.
|
|
128
|
+
|
|
129
|
+
Parameters
|
|
130
|
+
----------
|
|
131
|
+
app : Ebsilon application instance
|
|
132
|
+
The Ebsilon application instance.
|
|
133
|
+
pipe : Stream object
|
|
134
|
+
The stream object containing thermodynamic properties.
|
|
135
|
+
pressure : float
|
|
136
|
+
The pressure value (in bar).
|
|
137
|
+
Tamb : float
|
|
138
|
+
The ambient temperature (in K).
|
|
139
|
+
pamb : float
|
|
140
|
+
The ambient pressure (in Pa).
|
|
141
|
+
|
|
142
|
+
Returns
|
|
143
|
+
-------
|
|
144
|
+
float
|
|
145
|
+
The thermal exergy component (in J/kg).
|
|
146
|
+
"""
|
|
147
|
+
h_i = convert_to_SI('h', pipe.H.Value, unit_id_to_string.get(pipe.H.Dimension, "Unknown")) # in SI unit [J / kg]
|
|
148
|
+
s_i = convert_to_SI('s', pipe.S.Value, unit_id_to_string.get(pipe.S.Dimension, "Unknown")) # in SI unit [J / kgK]
|
|
149
|
+
h_A = calc_X_from_PT(app, pipe, 'H', pressure, Tamb) # in SI unit [J / kg]
|
|
150
|
+
s_A = calc_X_from_PT(app, pipe, 'S', pressure, Tamb) # in SI unit [J / kgK]
|
|
151
|
+
eT = h_i - h_A - Tamb * (s_i - s_A) # in SI unit [J / kg]
|
|
152
|
+
|
|
153
|
+
return eT
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
@require_ebsilon
|
|
157
|
+
def calc_eM(app: Any, pipe: Any, pressure: float, Tamb: float, pamb: float) -> float:
|
|
158
|
+
"""
|
|
159
|
+
Calculate the mechanical component of physical exergy.
|
|
160
|
+
|
|
161
|
+
Parameters
|
|
162
|
+
----------
|
|
163
|
+
app : Ebsilon application instance
|
|
164
|
+
The Ebsilon application instance.
|
|
165
|
+
pipe : Stream object
|
|
166
|
+
The stream object containing thermodynamic properties.
|
|
167
|
+
pressure : float
|
|
168
|
+
The pressure value (in bar).
|
|
169
|
+
Tamb : float
|
|
170
|
+
The ambient temperature (in K).
|
|
171
|
+
pamb : float
|
|
172
|
+
The ambient pressure (in Pa).
|
|
173
|
+
|
|
174
|
+
Returns
|
|
175
|
+
-------
|
|
176
|
+
float
|
|
177
|
+
The mechanical exergy component (in J/kg).
|
|
178
|
+
"""
|
|
179
|
+
eM = convert_to_SI('e', pipe.E.Value, unit_id_to_string.get(pipe.E.Dimension, "Unknown")) - calc_eT(app, pipe, pressure, Tamb, pamb)
|
|
180
|
+
|
|
181
|
+
return eM
|