exerpy 0.0.1__py3-none-any.whl → 0.0.2__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 +1 -1
- exerpy/components/combustion/base.py +104 -79
- exerpy/components/heat_exchanger/base.py +439 -169
- exerpy/components/heat_exchanger/condenser.py +268 -117
- exerpy/components/heat_exchanger/simple.py +414 -164
- exerpy/components/heat_exchanger/steam_generator.py +110 -85
- exerpy/components/nodes/deaerator.py +48 -47
- exerpy/components/nodes/mixer.py +50 -49
- exerpy/components/piping/valve.py +40 -24
- exerpy/parser/from_ebsilon/ebsilon_config.py +1 -1
- {exerpy-0.0.1.dist-info → exerpy-0.0.2.dist-info}/METADATA +4 -4
- {exerpy-0.0.1.dist-info → exerpy-0.0.2.dist-info}/RECORD +14 -14
- {exerpy-0.0.1.dist-info → exerpy-0.0.2.dist-info}/WHEEL +0 -0
- {exerpy-0.0.1.dist-info → exerpy-0.0.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -9,17 +9,11 @@ from exerpy.components.component import component_registry
|
|
|
9
9
|
@component_registry
|
|
10
10
|
class HeatExchanger(Component):
|
|
11
11
|
r"""
|
|
12
|
-
Class for exergy analysis of heat exchangers.
|
|
12
|
+
Class for exergy and exergoeconomic analysis of heat exchangers.
|
|
13
13
|
|
|
14
|
-
This class performs exergy analysis calculations for heat
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
Stream 0 represents the hot stream and stream 1 represents the cold stream.
|
|
18
|
-
|
|
19
|
-
Parameters
|
|
20
|
-
----------
|
|
21
|
-
**kwargs : dict
|
|
22
|
-
Arbitrary keyword arguments passed to parent class.
|
|
14
|
+
This class performs exergy and exergoeconomic analysis calculations for heat exchanger components,
|
|
15
|
+
accounting for two inlet and two outlet streams across various temperature regimes, including
|
|
16
|
+
above and below ambient temperature, and optional dissipative behavior.
|
|
23
17
|
|
|
24
18
|
Attributes
|
|
25
19
|
----------
|
|
@@ -32,133 +26,228 @@ class HeatExchanger(Component):
|
|
|
32
26
|
epsilon : float
|
|
33
27
|
Exergetic efficiency of the component :math:`\varepsilon` in :math:`-`.
|
|
34
28
|
inl : dict
|
|
35
|
-
Dictionary containing inlet
|
|
36
|
-
temperature, mass flows, and specific exergies.
|
|
29
|
+
Dictionary containing inlet stream data with mass flows and specific exergies.
|
|
37
30
|
outl : dict
|
|
38
|
-
Dictionary containing outlet
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
Case 2 - **All streams below or at ambient temperature**:
|
|
58
|
-
|
|
59
|
-
.. math::
|
|
60
|
-
\dot{E}_\mathrm{P} &= \dot{m}_{\mathrm{out,0}} \cdot e^\mathrm{T}_{\mathrm{out,0}}
|
|
61
|
-
- \dot{m}_{\mathrm{in,0}} \cdot e^\mathrm{T}_{\mathrm{in,0}}\\
|
|
62
|
-
\dot{E}_\mathrm{F} &= \dot{m}_{\mathrm{in,1}} \cdot e^\mathrm{PH}_{\mathrm{in,1}}
|
|
63
|
-
- \dot{m}_{\mathrm{out,1}} \cdot e^\mathrm{PH}_{\mathrm{out,1}} +
|
|
64
|
-
\dot{m}_{\mathrm{in,0}} \cdot e^\mathrm{M}_{\mathrm{in,0}}
|
|
65
|
-
- \dot{m}_{\mathrm{out,0}} \cdot e^\mathrm{M}_{\mathrm{out,0}}
|
|
66
|
-
|
|
67
|
-
Case 3 - **Hot stream inlet/outlet above ambient, cold stream inlet/outlet below ambient**:
|
|
68
|
-
|
|
69
|
-
.. math::
|
|
70
|
-
\dot{E}_\mathrm{P} &= \dot{m}_{\mathrm{out,0}} \cdot e^\mathrm{T}_{\mathrm{out,0}}
|
|
71
|
-
+ \dot{m}_{\mathrm{out,1}} \cdot e^\mathrm{T}_{\mathrm{out,1}}\\
|
|
72
|
-
\dot{E}_\mathrm{F} &= \dot{m}_{\mathrm{in,0}} \cdot e^\mathrm{PH}_{\mathrm{in,0}}
|
|
73
|
-
+ \dot{m}_{\mathrm{in,1}} \cdot e^\mathrm{PH}_{\mathrm{in,1}}
|
|
74
|
-
- (\dot{m}_{\mathrm{out,0}} \cdot e^\mathrm{M}_{\mathrm{out,0}}
|
|
75
|
-
+ \dot{m}_{\mathrm{out,1}} \cdot e^\mathrm{M}_{\mathrm{out,1}})
|
|
76
|
-
|
|
77
|
-
Case 4 - **First inlet above ambient, all other streams below or at ambient**:
|
|
78
|
-
|
|
79
|
-
.. math::
|
|
80
|
-
\dot{E}_\mathrm{P} &= \dot{m}_{\mathrm{out,0}} \cdot e^\mathrm{T}_{\mathrm{out,0}}\\
|
|
81
|
-
\dot{E}_\mathrm{F} &= \dot{m}_{\mathrm{in,0}} \cdot e^\mathrm{PH}_{\mathrm{in,0}}
|
|
82
|
-
+ \dot{m}_{\mathrm{in,1}} \cdot e^\mathrm{PH}_{\mathrm{in,1}}
|
|
83
|
-
- (\dot{m}_{\mathrm{out,1}} \cdot e^\mathrm{PH}_{\mathrm{out,1}}
|
|
84
|
-
+ \dot{m}_{\mathrm{out,0}} \cdot e^\mathrm{M}_{\mathrm{out,0}})
|
|
85
|
-
|
|
86
|
-
Case 5 - **Hot stream inlet/outlet above ambient, cold stream inlet/outlet below or at ambient**:
|
|
87
|
-
|
|
88
|
-
.. math::
|
|
89
|
-
\dot{E}_\mathrm{P} &= \mathrm{NaN}\\
|
|
90
|
-
\dot{E}_\mathrm{F} &= \dot{m}_{\mathrm{in,0}} \cdot e^\mathrm{PH}_{\mathrm{in,0}}
|
|
91
|
-
- \dot{m}_{\mathrm{out,0}} \cdot e^\mathrm{PH}_{\mathrm{out,0}}
|
|
92
|
-
+ \dot{m}_{\mathrm{in,1}} \cdot e^\mathrm{PH}_{\mathrm{in,1}}
|
|
93
|
-
- \dot{m}_{\mathrm{out,1}} \cdot e^\mathrm{PH}_{\mathrm{out,1}}
|
|
94
|
-
|
|
95
|
-
Case 6 - **Second outlet above ambient, all others below or at ambient**:
|
|
96
|
-
|
|
97
|
-
.. math::
|
|
98
|
-
\dot{E}_\mathrm{P} &= \dot{m}_{\mathrm{out,1}} \cdot e^\mathrm{T}_{\mathrm{out,1}}\\
|
|
99
|
-
\dot{E}_\mathrm{F} &= \dot{m}_{\mathrm{in,0}} \cdot e^\mathrm{PH}_{\mathrm{in,0}}
|
|
100
|
-
- \dot{m}_{\mathrm{out,0}} \cdot e^\mathrm{PH}_{\mathrm{out,0}}
|
|
101
|
-
+ \dot{m}_{\mathrm{in,1}} \cdot e^\mathrm{PH}_{\mathrm{in,1}}
|
|
102
|
-
- \dot{m}_{\mathrm{out,1}} \cdot e^\mathrm{M}_{\mathrm{out,1}}
|
|
103
|
-
|
|
104
|
-
Note that in Case 5, the exergy product :math:`\dot{E}_\mathrm{P}` is undefined (NaN),
|
|
105
|
-
leading to an exergy destruction equal to the exergy fuel:
|
|
106
|
-
:math:`\dot{E}_\mathrm{D} = \dot{E}_\mathrm{F}`.
|
|
107
|
-
|
|
108
|
-
The exergy destruction is calculated as:
|
|
109
|
-
|
|
110
|
-
.. math::
|
|
111
|
-
\dot{E}_\mathrm{D} = \dot{E}_\mathrm{F} - \dot{E}_\mathrm{P}
|
|
112
|
-
|
|
113
|
-
And the exergetic efficiency as:
|
|
114
|
-
|
|
115
|
-
.. math::
|
|
116
|
-
\varepsilon = \frac{\dot{E}_\mathrm{P}}{\dot{E}_\mathrm{F}}
|
|
117
|
-
|
|
118
|
-
Where:
|
|
119
|
-
- :math:`e^\mathrm{T}`: Thermal exergy
|
|
120
|
-
- :math:`e^\mathrm{PH}`: Physical exergy
|
|
121
|
-
- :math:`e^\mathrm{M}`: Mechanical exergy
|
|
31
|
+
Dictionary containing outlet stream data with mass flows and specific exergies.
|
|
32
|
+
Z_costs : float
|
|
33
|
+
Investment cost rate of the component in currency/h.
|
|
34
|
+
C_P : float
|
|
35
|
+
Cost of product stream :math:`\dot{C}_P` in currency/h.
|
|
36
|
+
C_F : float
|
|
37
|
+
Cost of fuel stream :math:`\dot{C}_F` in currency/h.
|
|
38
|
+
C_D : float
|
|
39
|
+
Cost of exergy destruction :math:`\dot{C}_D` in currency/h.
|
|
40
|
+
c_P : float
|
|
41
|
+
Specific cost of product stream (currency per unit exergy).
|
|
42
|
+
c_F : float
|
|
43
|
+
Specific cost of fuel stream (currency per unit exergy).
|
|
44
|
+
r : float
|
|
45
|
+
Relative cost difference, :math:`(c_P - c_F)/c_F`.
|
|
46
|
+
f : float
|
|
47
|
+
Exergoeconomic factor, :math:`\dot{Z}/(\dot{Z} + \dot{C}_D)`.
|
|
48
|
+
Ex_C_col : dict
|
|
49
|
+
Custom cost coefficients collection passed via `kwargs`.
|
|
122
50
|
"""
|
|
123
51
|
|
|
124
52
|
def __init__(self, **kwargs):
|
|
125
|
-
r"""
|
|
53
|
+
r"""
|
|
54
|
+
Initialize the heat exchanger component.
|
|
55
|
+
|
|
56
|
+
Parameters
|
|
57
|
+
----------
|
|
58
|
+
**kwargs : dict
|
|
59
|
+
Arbitrary keyword arguments. Recognized keys:
|
|
60
|
+
- dissipative (bool): whether component has dissipative behavior, default False
|
|
61
|
+
- Ex_C_col (dict): custom cost coefficients, default {}
|
|
62
|
+
- Z_costs (float): investment cost rate in currency/h, default 0.0
|
|
63
|
+
"""
|
|
126
64
|
self.dissipative = False
|
|
127
65
|
super().__init__(**kwargs)
|
|
128
66
|
|
|
129
67
|
def calc_exergy_balance(self, T0: float, p0: float, split_physical_exergy) -> None:
|
|
130
68
|
r"""
|
|
131
|
-
|
|
69
|
+
Compute the exergy balance of the heat exchanger.
|
|
70
|
+
|
|
71
|
+
Case 1: All streams above ambient temperature
|
|
72
|
+
|
|
73
|
+
If `split_physical_exergy=True`:
|
|
74
|
+
|
|
75
|
+
.. math::
|
|
76
|
+
|
|
77
|
+
\dot{E}_{\mathrm{P}}
|
|
78
|
+
= \dot{E}^{\mathrm{T}}_{\mathrm{out},2}
|
|
79
|
+
- \dot{E}^{\mathrm{T}}_{\mathrm{in},2}
|
|
80
|
+
|
|
81
|
+
.. math::
|
|
82
|
+
|
|
83
|
+
\dot{E}_{\mathrm{F}}
|
|
84
|
+
= \dot{E}^{\mathrm{PH}}_{\mathrm{in},1}
|
|
85
|
+
- \dot{E}^{\mathrm{PH}}_{\mathrm{out},1}
|
|
86
|
+
+ \bigl(\dot{E}^{\mathrm{M}}_{\mathrm{in},2}
|
|
87
|
+
- \dot{E}^{\mathrm{M}}_{\mathrm{out},2}\bigr)
|
|
88
|
+
|
|
89
|
+
Else:
|
|
90
|
+
|
|
91
|
+
.. math::
|
|
92
|
+
|
|
93
|
+
\dot{E}_{\mathrm{P}}
|
|
94
|
+
= \dot{E}^{\mathrm{PH}}_{\mathrm{out},2}
|
|
95
|
+
- \dot{E}^{\mathrm{PH}}_{\mathrm{in},2}
|
|
96
|
+
|
|
97
|
+
.. math::
|
|
98
|
+
|
|
99
|
+
\dot{E}_{\mathrm{F}}
|
|
100
|
+
= \dot{E}^{\mathrm{PH}}_{\mathrm{in},1}
|
|
101
|
+
- \dot{E}^{\mathrm{PH}}_{\mathrm{out},1}
|
|
102
|
+
|
|
103
|
+
Case 2: All streams below or equal to ambient temperature
|
|
104
|
+
|
|
105
|
+
If `split_physical_exergy=True`:
|
|
106
|
+
|
|
107
|
+
.. math::
|
|
108
|
+
\dot{E}_{\mathrm{P}}
|
|
109
|
+
= \dot{E}^{\mathrm{T}}_{\mathrm{out},1}
|
|
110
|
+
- \dot{E}^{\mathrm{T}}_{\mathrm{in},1}
|
|
111
|
+
|
|
112
|
+
.. math::
|
|
113
|
+
|
|
114
|
+
\dot{E}_{\mathrm{F}}
|
|
115
|
+
= \dot{E}^{\mathrm{PH}}_{\mathrm{in},2}
|
|
116
|
+
- \dot{E}^{\mathrm{PH}}_{\mathrm{out},2}
|
|
117
|
+
+ \bigl(\dot{E}^{\mathrm{M}}_{\mathrm{in},1}
|
|
118
|
+
- \dot{E}^{\mathrm{M}}_{\mathrm{out},1}\bigr)
|
|
119
|
+
|
|
120
|
+
Else
|
|
121
|
+
|
|
122
|
+
.. math::
|
|
123
|
+
\dot{E}_{\mathrm{P}}
|
|
124
|
+
= \dot{E}^{\mathrm{PH}}_{\mathrm{out},1}
|
|
125
|
+
- \dot{E}^{\mathrm{PH}}_{\mathrm{in},1}
|
|
126
|
+
|
|
127
|
+
.. math::
|
|
128
|
+
\dot{E}_{\mathrm{F}}
|
|
129
|
+
= \dot{E}^{\mathrm{PH}}_{\mathrm{in},2}
|
|
130
|
+
- \dot{E}^{\mathrm{PH}}_{\mathrm{out},2}
|
|
131
|
+
|
|
132
|
+
Case 3: Both stream crossing ambient temperature
|
|
133
|
+
|
|
134
|
+
If `split_physical_exergy=True`:
|
|
135
|
+
|
|
136
|
+
.. math::
|
|
137
|
+
\dot{E}_{\mathrm{P}}
|
|
138
|
+
= \dot{E}^{\mathrm{T}}_{\mathrm{out},1}
|
|
139
|
+
+ \dot{E}^{\mathrm{T}}_{\mathrm{out},2}
|
|
140
|
+
|
|
141
|
+
.. math::
|
|
142
|
+
\dot{E}_{\mathrm{F}}
|
|
143
|
+
= \dot{E}^{\mathrm{PH}}_{\mathrm{in},1}
|
|
144
|
+
+ \dot{E}^{\mathrm{PH}}_{\mathrm{in},2}
|
|
145
|
+
- \bigl(\dot{E}^{\mathrm{M}}_{\mathrm{out},1}
|
|
146
|
+
+ \dot{E}^{\mathrm{M}}_{\mathrm{out},2}\bigr)
|
|
132
147
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
148
|
+
Else:
|
|
149
|
+
|
|
150
|
+
.. math::
|
|
151
|
+
\dot{E}_{\mathrm{P}}
|
|
152
|
+
= \dot{E}^{\mathrm{T}}_{\mathrm{out},1}
|
|
153
|
+
+ \dot{E}^{\mathrm{T}}_{\mathrm{out},2}
|
|
154
|
+
|
|
155
|
+
.. math::
|
|
156
|
+
\dot{E}_{\mathrm{F}}
|
|
157
|
+
= \dot{E}^{\mathrm{PH}}_{\mathrm{in},1}
|
|
158
|
+
+ \dot{E}^{\mathrm{PH}}_{\mathrm{in},2}
|
|
159
|
+
|
|
160
|
+
Case 4: Only the hot inlet above ambient temperature
|
|
161
|
+
|
|
162
|
+
If `split_physical_exergy=True`:
|
|
163
|
+
|
|
164
|
+
.. math::
|
|
165
|
+
\dot{E}_{\mathrm{P}}
|
|
166
|
+
= \dot{E}^{\mathrm{T}}_{\mathrm{out},1}
|
|
167
|
+
|
|
168
|
+
.. math::
|
|
169
|
+
\dot{E}_{\mathrm{F}}
|
|
170
|
+
= \bigl(\dot{E}^{\mathrm{PH}}_{\mathrm{in},1}
|
|
171
|
+
+ \dot{E}^{\mathrm{PH}}_{\mathrm{in},2}\bigr)
|
|
172
|
+
- \bigl(\dot{E}^{\mathrm{PH}}_{\mathrm{out},2}
|
|
173
|
+
+ \dot{E}^{\mathrm{M}}_{\mathrm{out},1}\bigr)
|
|
174
|
+
|
|
175
|
+
Else:
|
|
176
|
+
|
|
177
|
+
.. math::
|
|
178
|
+
\dot{E}_{\mathrm{P}}
|
|
179
|
+
= \dot{E}^{\mathrm{PH}}_{\mathrm{out},1}
|
|
180
|
+
|
|
181
|
+
.. math::
|
|
182
|
+
\dot{E}_{\mathrm{F}}
|
|
183
|
+
= \bigl(\dot{E}^{\mathrm{PH}}_{\mathrm{in},1}
|
|
184
|
+
+ \dot{E}^{\mathrm{PH}}_{\mathrm{in},2}\bigr)
|
|
185
|
+
- \dot{E}^{\mathrm{PH}}_{\mathrm{out},2}
|
|
186
|
+
|
|
187
|
+
Case 5: Only the cold inlet below ambient temperature
|
|
188
|
+
|
|
189
|
+
If `split_physical_exergy=True`:
|
|
190
|
+
|
|
191
|
+
.. math::
|
|
192
|
+
\dot{E}_{\mathrm{P}}
|
|
193
|
+
= \dot{E}^{\mathrm{T}}_{\mathrm{out},2}
|
|
194
|
+
|
|
195
|
+
.. math::
|
|
196
|
+
\dot{E}_{\mathrm{F}}
|
|
197
|
+
= \bigl(\dot{E}^{\mathrm{PH}}_{\mathrm{in},1}
|
|
198
|
+
- \dot{E}^{\mathrm{PH}}_{\mathrm{out},1}\bigr)
|
|
199
|
+
+ \bigl(\dot{E}^{\mathrm{PH}}_{\mathrm{in},2}
|
|
200
|
+
- \dot{E}^{\mathrm{M}}_{\mathrm{out},2}\bigr)
|
|
201
|
+
|
|
202
|
+
Else:
|
|
203
|
+
|
|
204
|
+
.. math::
|
|
205
|
+
\dot{E}_{\mathrm{P}}
|
|
206
|
+
= \dot{E}^{\mathrm{PH}}_{\mathrm{out},2}
|
|
207
|
+
|
|
208
|
+
.. math::
|
|
209
|
+
\dot{E}_{\mathrm{F}}
|
|
210
|
+
= \bigl(\dot{E}^{\mathrm{PH}}_{\mathrm{in},1}
|
|
211
|
+
- \dot{E}^{\mathrm{PH}}_{\mathrm{out},1}\bigr)
|
|
212
|
+
+ \dot{E}^{\mathrm{PH}}_{\mathrm{in},2}
|
|
213
|
+
|
|
214
|
+
Case 6: Hot stream always above and cold stream always below ambiente temperature (dissipative case):
|
|
215
|
+
|
|
216
|
+
.. math::
|
|
217
|
+
\dot{E}_{\mathrm{P}} = \mathrm{NaN}
|
|
218
|
+
|
|
219
|
+
.. math::
|
|
220
|
+
\dot{E}_{\mathrm{F}}
|
|
221
|
+
= \bigl(\dot{E}^{\mathrm{PH}}_{\mathrm{in},1}
|
|
222
|
+
- \dot{E}^{\mathrm{PH}}_{\mathrm{out},1}\bigr)
|
|
223
|
+
- \dot{E}^{\mathrm{PH}}_{\mathrm{out},2}
|
|
224
|
+
+ \dot{E}^{\mathrm{PH}}_{\mathrm{in},2}
|
|
225
|
+
|
|
226
|
+
If `dissipative` is `True`, the component is treated as dissipative:
|
|
227
|
+
|
|
228
|
+
.. math::
|
|
229
|
+
\dot{E}_{\mathrm{P}} = \mathrm{NaN}
|
|
230
|
+
|
|
231
|
+
.. math::
|
|
232
|
+
\dot{E}_{\mathrm{F}}
|
|
233
|
+
= \bigl(\dot{E}^{\mathrm{PH}}_{\mathrm{in},1}
|
|
234
|
+
- \dot{E}^{\mathrm{PH}}_{\mathrm{out},1}\bigr)
|
|
235
|
+
- \dot{E}^{\mathrm{PH}}_{\mathrm{out},2}
|
|
236
|
+
+ \dot{E}^{\mathrm{PH}}_{\mathrm{in},2}
|
|
136
237
|
|
|
137
238
|
Parameters
|
|
138
239
|
----------
|
|
139
240
|
T0 : float
|
|
140
|
-
Ambient temperature
|
|
241
|
+
Ambient temperature (K).
|
|
141
242
|
p0 : float
|
|
142
|
-
Ambient pressure
|
|
243
|
+
Ambient pressure (Pa).
|
|
143
244
|
split_physical_exergy : bool
|
|
144
|
-
|
|
245
|
+
Whether to split thermal and mechanical exergy.
|
|
145
246
|
|
|
146
247
|
Raises
|
|
147
248
|
------
|
|
148
249
|
ValueError
|
|
149
|
-
If
|
|
150
|
-
|
|
151
|
-
Notes
|
|
152
|
-
-----
|
|
153
|
-
This method updates the following component attributes:
|
|
154
|
-
- E_P (Exergy product)
|
|
155
|
-
- E_F (Exergy fuel)
|
|
156
|
-
- E_D (Exergy destruction)
|
|
157
|
-
- epsilon (Exergetic efficiency)
|
|
158
|
-
|
|
159
|
-
The calculation requires two inlet and two outlet streams, and their
|
|
160
|
-
temperature relationships with ambient temperature determine which case
|
|
161
|
-
of exergy analysis is applied.
|
|
250
|
+
If required inlets or outlets are missing.
|
|
162
251
|
"""
|
|
163
252
|
# Ensure that the component has both inlet and outlet streams
|
|
164
253
|
if len(self.inl) < 2 or len(self.outl) < 2:
|
|
@@ -190,7 +279,7 @@ class HeatExchanger(Component):
|
|
|
190
279
|
self.E_P = self.outl[0]['m'] * self.outl[0]['e_PH'] - self.inl[0]['m'] * self.inl[0]['e_PH']
|
|
191
280
|
self.E_F = self.inl[1]['m'] * self.inl[1]['e_PH'] - self.outl[1]['m'] * self.outl[1]['e_PH']
|
|
192
281
|
|
|
193
|
-
# Case 3:
|
|
282
|
+
# Case 3: Both stream crossing T0 (hot inlet and cold outlet > T0, hot outlet and cold inlet <= T0)
|
|
194
283
|
elif (self.inl[0]['T'] > T0 and self.outl[1]['T'] > T0 and
|
|
195
284
|
self.outl[0]['T'] <= T0 and self.inl[1]['T'] <= T0):
|
|
196
285
|
if split_physical_exergy:
|
|
@@ -203,7 +292,7 @@ class HeatExchanger(Component):
|
|
|
203
292
|
self.E_P = self.outl[0]['m'] * self.outl[0]['e_PH'] + self.outl[1]['m'] * self.outl[1]['e_PH']
|
|
204
293
|
self.E_F = self.inl[0]['m'] * self.inl[0]['e_PH'] + self.inl[1]['m'] * self.inl[1]['e_PH']
|
|
205
294
|
|
|
206
|
-
# Case 4:
|
|
295
|
+
# Case 4: Only hot inlet > T0
|
|
207
296
|
elif (self.inl[0]['T'] > T0 and self.inl[1]['T'] <= T0 and
|
|
208
297
|
self.outl[0]['T'] <= T0 and self.outl[1]['T'] <= T0):
|
|
209
298
|
if split_physical_exergy:
|
|
@@ -217,15 +306,9 @@ class HeatExchanger(Component):
|
|
|
217
306
|
self.E_F = self.inl[0]['m'] * self.inl[0]['e_PH'] + (
|
|
218
307
|
self.inl[1]['m'] * self.inl[1]['e_PH'] - self.outl[1]['m'] * self.outl[1]['e_PH'])
|
|
219
308
|
|
|
220
|
-
# Case 5:
|
|
221
|
-
elif (self.inl[0][
|
|
222
|
-
|
|
223
|
-
self.E_P = np.nan
|
|
224
|
-
self.E_F = self.inl[0]['m'] * self.inl[0]['e_PH'] - self.outl[0]['m'] * self.outl[0]['e_PH'] + (
|
|
225
|
-
self.inl[1]['m'] * self.inl[1]['e_PH'] - self.outl[1]['m'] * self.outl[1]['e_PH'])
|
|
226
|
-
|
|
227
|
-
# Case 6: Cold inlet is lower ambient, others higher
|
|
228
|
-
else:
|
|
309
|
+
# Case 5: Only cold inlet <= T0
|
|
310
|
+
elif (self.inl[0]["T"] > T0 and self.inl[1]["T"] <= T0 and
|
|
311
|
+
self.outl[0]["T"] > T0 and self.outl[1]["T"] > T0):
|
|
229
312
|
if split_physical_exergy:
|
|
230
313
|
self.E_P = self.outl[1]['m'] * self.outl[1]['e_T']
|
|
231
314
|
self.E_F = self.inl[0]['m'] * self.inl[0]['e_PH'] - self.outl[0]['m'] * self.outl[0]['e_PH'] + (
|
|
@@ -236,6 +319,21 @@ class HeatExchanger(Component):
|
|
|
236
319
|
self.E_P = self.outl[1]['m'] * self.outl[1]['e_PH']
|
|
237
320
|
self.E_F = self.inl[0]['m'] * self.inl[0]['e_PH'] - self.outl[0]['m'] * self.outl[0]['e_PH'] + (
|
|
238
321
|
self.inl[1]['m'] * self.inl[1]['e_PH'])
|
|
322
|
+
|
|
323
|
+
# Case 6: hot stream always above T0, cold stream always below T0 (dissipative case)
|
|
324
|
+
elif (self.inl[0]["T"] > T0 and self.inl[1]["T"] <= T0 and
|
|
325
|
+
self.outl[0]["T"] > T0 and self.outl[1]["T"] <= T0):
|
|
326
|
+
self.E_P = np.nan
|
|
327
|
+
self.E_F = self.inl[0]['m'] * self.inl[0]['e_PH'] - self.outl[0]['m'] * self.outl[0]['e_PH'] + (
|
|
328
|
+
self.inl[1]['m'] * self.inl[1]['e_PH'] - self.outl[1]['m'] * self.outl[1]['e_PH'])
|
|
329
|
+
|
|
330
|
+
logging.warning(f"Component {self.name} is dissipative. This component should be " \
|
|
331
|
+
"handled with the `dissipative` flag set to True.")
|
|
332
|
+
|
|
333
|
+
# Case 7: Not implemented case
|
|
334
|
+
else:
|
|
335
|
+
logging.error(f"The heat exchanger {self.name} has an unexpected temperature configuration. "
|
|
336
|
+
"Please check the inlet and outlet temperatures.")
|
|
239
337
|
|
|
240
338
|
else:
|
|
241
339
|
self.E_F = (
|
|
@@ -261,34 +359,106 @@ class HeatExchanger(Component):
|
|
|
261
359
|
|
|
262
360
|
|
|
263
361
|
def aux_eqs(self, A, b, counter, T0, equations, chemical_exergy_enabled):
|
|
264
|
-
"""
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
362
|
+
r"""
|
|
363
|
+
Add auxiliary cost equations for the heat exchanger.
|
|
364
|
+
|
|
365
|
+
This method appends rows to the cost matrix to enforce:
|
|
366
|
+
|
|
367
|
+
Case 1: All streams above ambient temperature
|
|
368
|
+
|
|
369
|
+
F rule for thermal exergy of the hot stream:
|
|
370
|
+
|
|
371
|
+
.. math::
|
|
372
|
+
-\frac{1}{\dot{E}^{\mathrm{T}}_{\mathrm{out},1}}\,\dot{C}^{\mathrm{T}}_{\mathrm{out},1}
|
|
373
|
+
+ \frac{1}{\dot{E}^{\mathrm{T}}_{\mathrm{in},1}}\,\dot{C}^{\mathrm{T}}_{\mathrm{in},1}
|
|
374
|
+
= 0
|
|
375
|
+
|
|
376
|
+
Case 2: All streams below or equal to ambient temperature
|
|
377
|
+
|
|
378
|
+
F rule for thermal exergy of the cold stream:
|
|
379
|
+
|
|
380
|
+
.. math::
|
|
381
|
+
-\frac{1}{\dot{E}^{\mathrm{T}}_{\mathrm{out},2}}\,\dot{C}^{\mathrm{T}}_{\mathrm{out},2}
|
|
382
|
+
+ \frac{1}{\dot{E}^{\mathrm{T}}_{\mathrm{in},2}}\,\dot{C}^{\mathrm{T}}_{\mathrm{in},2}
|
|
383
|
+
= 0
|
|
384
|
+
|
|
385
|
+
Case 3: Both stream crossing ambient temperature
|
|
386
|
+
|
|
387
|
+
P rule for thermal exergy of both outlets:
|
|
388
|
+
|
|
389
|
+
.. math::
|
|
390
|
+
-\frac{1}{\dot{E}^{\mathrm{T}}_{\mathrm{out},1}}\,\dot{C}^{\mathrm{T}}_{\mathrm{out},1}
|
|
391
|
+
+ \frac{1}{\dot{E}^{\mathrm{T}}_{\mathrm{out},2}}\,\dot{C}^{\mathrm{T}}_{\mathrm{out},2}
|
|
392
|
+
= 0
|
|
393
|
+
|
|
394
|
+
Case 4: Only the hot inlet above ambient temperature
|
|
395
|
+
|
|
396
|
+
F rule for thermal exergy of the cold stream:
|
|
397
|
+
|
|
398
|
+
.. math::
|
|
399
|
+
-\frac{1}{\dot{E}^{\mathrm{T}}_{\mathrm{out},2}}\,\dot{C}^{\mathrm{T}}_{\mathrm{out},2}
|
|
400
|
+
+ \frac{1}{\dot{E}^{\mathrm{T}}_{\mathrm{in},2}}\,\dot{C}^{\mathrm{T}}_{\mathrm{in},2}
|
|
401
|
+
= 0
|
|
402
|
+
|
|
403
|
+
Case 5: Only the cold inlet below ambient temperature
|
|
404
|
+
|
|
405
|
+
F rule for thermal exergy of the hot stream:
|
|
406
|
+
|
|
407
|
+
.. math::
|
|
408
|
+
-\frac{1}{\dot{E}^{\mathrm{T}}_{\mathrm{out},1}}\,\dot{C}^{\mathrm{T}}_{\mathrm{out},1}
|
|
409
|
+
+ \frac{1}{\dot{E}^{\mathrm{T}}_{\mathrm{in},1}}\,\dot{C}^{\mathrm{T}}_{\mathrm{in},1}
|
|
410
|
+
= 0
|
|
411
|
+
|
|
412
|
+
Case 6: Hot stream always above and cold stream always below ambiente temperature (dissipative case):
|
|
413
|
+
|
|
414
|
+
The dissipative is not handeld here!
|
|
415
|
+
|
|
416
|
+
For all cases, the mechanical and chemical exergy costs are handled as follows:
|
|
417
|
+
|
|
418
|
+
F rule for mechanical exergy of the hot stream:
|
|
419
|
+
|
|
420
|
+
.. math::
|
|
421
|
+
-\frac{1}{\dot{E}^{\mathrm{M}}_{\mathrm{out},i}}\,\dot{C}^{\mathrm{M}}_{\mathrm{out},i}
|
|
422
|
+
+ \frac{1}{\dot{E}^{\mathrm{M}}_{\mathrm{in},i}}\,\dot{C}^{\mathrm{M}}_{\mathrm{in},i}
|
|
423
|
+
= 0
|
|
424
|
+
|
|
425
|
+
F rule for chemical exergy on hot branch:
|
|
426
|
+
|
|
427
|
+
.. math::
|
|
428
|
+
-\frac{1}{\dot{E}^{\mathrm{CH}}_{\mathrm{out},i}}\,\dot{C}^{\mathrm{CH}}_{\mathrm{out},i}
|
|
429
|
+
+ \frac{1}{\dot{E}^{\mathrm{CH}}_{\mathrm{in},i}}\,\dot{C}^{\mathrm{CH}}_{\mathrm{in},i}
|
|
430
|
+
= 0
|
|
431
|
+
|
|
268
432
|
Parameters
|
|
269
433
|
----------
|
|
270
434
|
A : numpy.ndarray
|
|
271
|
-
|
|
435
|
+
Current cost matrix.
|
|
272
436
|
b : numpy.ndarray
|
|
273
|
-
|
|
437
|
+
Current RHS vector.
|
|
274
438
|
counter : int
|
|
275
|
-
|
|
439
|
+
Starting row index for auxiliary equations.
|
|
276
440
|
T0 : float
|
|
277
|
-
|
|
278
|
-
equations : dict
|
|
279
|
-
|
|
441
|
+
Ambient temperature (K).
|
|
442
|
+
equations : dict or list
|
|
443
|
+
Structure for equation labels.
|
|
280
444
|
chemical_exergy_enabled : bool
|
|
281
|
-
|
|
445
|
+
Must be True to include chemical exergy mixing.
|
|
446
|
+
|
|
282
447
|
Returns
|
|
283
448
|
-------
|
|
284
449
|
A : numpy.ndarray
|
|
285
|
-
Updated
|
|
450
|
+
Updated cost matrix.
|
|
286
451
|
b : numpy.ndarray
|
|
287
|
-
Updated
|
|
452
|
+
Updated RHS vector.
|
|
288
453
|
counter : int
|
|
289
|
-
Updated row
|
|
290
|
-
equations : dict
|
|
291
|
-
Updated
|
|
454
|
+
Updated row index after adding equations.
|
|
455
|
+
equations : dict or list
|
|
456
|
+
Updated labels.
|
|
457
|
+
|
|
458
|
+
Raises
|
|
459
|
+
------
|
|
460
|
+
ValueError
|
|
461
|
+
If required cost variable indices are missing.
|
|
292
462
|
"""
|
|
293
463
|
# Equality equation for mechanical and chemical exergy costs.
|
|
294
464
|
def set_equal(A, row, in_item, out_item, var):
|
|
@@ -351,30 +521,31 @@ class HeatExchanger(Component):
|
|
|
351
521
|
elif all([c["T"] <= T0 for c in list(self.inl.values()) + list(self.outl.values())]):
|
|
352
522
|
set_thermal_f_cold(A, counter + 0)
|
|
353
523
|
equations[counter] = f"aux_f_rule_cold_{self.name}"
|
|
354
|
-
# Case 3:
|
|
524
|
+
# Case 3: Both stream crossing T0 (hot inlet and cold outlet > T0, hot outlet and cold inlet <= T0)
|
|
355
525
|
elif (self.inl[0]["T"] > T0 and self.outl[1]["T"] > T0 and
|
|
356
526
|
self.outl[0]["T"] <= T0 and self.inl[1]["T"] <= T0):
|
|
357
527
|
set_thermal_p_rule(A, counter + 0)
|
|
358
528
|
equations[counter] = f"aux_p_rule_{self.name}"
|
|
359
|
-
# Case 4:
|
|
529
|
+
# Case 4: Only hot inlet > T0
|
|
360
530
|
elif (self.inl[0]["T"] > T0 and self.inl[1]["T"] <= T0 and
|
|
361
531
|
self.outl[0]["T"] <= T0 and self.outl[1]["T"] <= T0):
|
|
362
532
|
set_thermal_f_cold(A, counter + 0)
|
|
363
533
|
equations[counter] = f"aux_f_rule_cold_{self.name}"
|
|
364
|
-
# Case 5:
|
|
534
|
+
# Case 5: Only cold inlet <= T0
|
|
365
535
|
elif (self.inl[0]["T"] > T0 and self.inl[1]["T"] <= T0 and
|
|
366
536
|
self.outl[0]["T"] > T0 and self.outl[1]["T"] > T0):
|
|
367
537
|
set_thermal_f_hot(A, counter + 0)
|
|
368
538
|
equations[counter] = f"aux_f_rule_hot_{self.name}"
|
|
369
|
-
# Case 6:
|
|
539
|
+
# Case 6: hot stream always above T0, cold stream always below T0 (dissipative case)
|
|
370
540
|
elif (self.inl[0]["T"] > T0 and self.inl[1]["T"] <= T0 and
|
|
371
541
|
self.outl[0]["T"] > T0 and self.outl[1]["T"] <= T0):
|
|
372
|
-
|
|
542
|
+
logging.warning(f"Component {self.name} is dissipative. This component should be " \
|
|
543
|
+
"handled with the `dissipative` flag set to True.")
|
|
373
544
|
return
|
|
374
|
-
# Case 7:
|
|
375
|
-
else:
|
|
376
|
-
|
|
377
|
-
|
|
545
|
+
# Case 7: Not implemented case
|
|
546
|
+
else:
|
|
547
|
+
logging.error(f"The heat exchanger {self.name} has an unexpected temperature configuration. "
|
|
548
|
+
"Please check the inlet and outlet temperatures.")
|
|
378
549
|
|
|
379
550
|
# Mechanical equations (always added)
|
|
380
551
|
set_equal(A, counter + 1, self.inl[0], self.outl[0], "M")
|
|
@@ -399,48 +570,147 @@ class HeatExchanger(Component):
|
|
|
399
570
|
return A, b, counter + num_aux_eqs, equations
|
|
400
571
|
|
|
401
572
|
def exergoeconomic_balance(self, T0):
|
|
402
|
-
"""
|
|
403
|
-
Perform exergoeconomic balance
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
573
|
+
r"""
|
|
574
|
+
Perform exergoeconomic cost balance for the heat exchanger.
|
|
575
|
+
|
|
576
|
+
.. math::
|
|
577
|
+
\dot{C}^{\mathrm{T}}_{\mathrm{in},1}
|
|
578
|
+
+ \dot{C}^{\mathrm{M}}_{\mathrm{in},1}
|
|
579
|
+
+ \dot{C}^{\mathrm{T}}_{\mathrm{in},2}
|
|
580
|
+
+ \dot{C}^{\mathrm{M}}_{\mathrm{in},2}
|
|
581
|
+
- \dot{C}^{\mathrm{T}}_{\mathrm{out},1}
|
|
582
|
+
- \dot{C}^{\mathrm{M}}_{\mathrm{out},1}
|
|
583
|
+
- \dot{C}^{\mathrm{T}}_{\mathrm{out},2}
|
|
584
|
+
- \dot{C}^{\mathrm{M}}_{\mathrm{out},2}
|
|
585
|
+
+ \dot{Z}
|
|
586
|
+
= 0
|
|
587
|
+
|
|
588
|
+
In case the chemical exergy of the streams is know:
|
|
589
|
+
|
|
590
|
+
.. math::
|
|
591
|
+
\dot{C}^{\mathrm{CH}}_{\mathrm{in},1} =
|
|
592
|
+
\dot{C}^{\mathrm{CH}}_{\mathrm{out},1}
|
|
593
|
+
|
|
594
|
+
.. math::
|
|
595
|
+
\dot{C}^{\mathrm{CH}}_{\mathrm{in},2} =
|
|
596
|
+
\dot{C}^{\mathrm{CH}}_{\mathrm{out},2}
|
|
597
|
+
|
|
598
|
+
This method computes cost coefficients and ratios:
|
|
599
|
+
|
|
600
|
+
Case 1: All streams above ambient temperature
|
|
601
|
+
|
|
602
|
+
.. math::
|
|
603
|
+
\dot{C}_P = \dot{C}^{\mathrm{T}}_{\mathrm{out},2}
|
|
604
|
+
- \dot{C}^{\mathrm{T}}_{\mathrm{in},2}
|
|
605
|
+
|
|
606
|
+
.. math::
|
|
607
|
+
\dot{C}_F = \dot{C}^{\mathrm{PH}}_{\mathrm{in},1}
|
|
608
|
+
- \dot{C}^{\mathrm{PH}}_{\mathrm{out},1}
|
|
609
|
+
+ \bigl(\dot{C}^{\mathrm{M}}_{\mathrm{in},2}
|
|
610
|
+
- \dot{C}^{\mathrm{M}}_{\mathrm{out},2}\bigr)
|
|
611
|
+
|
|
612
|
+
Case 2: All streams below or equal to ambient temperature
|
|
613
|
+
|
|
614
|
+
.. math::
|
|
615
|
+
\dot{C}_P = \dot{C}^{\mathrm{T}}_{\mathrm{out},1}
|
|
616
|
+
- \dot{C}^{\mathrm{T}}_{\mathrm{in},1}
|
|
617
|
+
|
|
618
|
+
.. math::
|
|
619
|
+
\dot{C}_F = \dot{C}^{\mathrm{PH}}_{\mathrm{in},2}
|
|
620
|
+
- \dot{C}^{\mathrm{PH}}_{\mathrm{out},2}
|
|
621
|
+
+ \bigl(\dot{C}^{\mathrm{M}}_{\mathrm{in},1}
|
|
622
|
+
- \dot{C}^{\mathrm{M}}_{\mathrm{out},1}\bigr)
|
|
623
|
+
|
|
624
|
+
Case 3: Both stream crossing ambient temperature
|
|
625
|
+
|
|
626
|
+
.. math::
|
|
627
|
+
\dot{C}_P = \dot{C}^{\mathrm{T}}_{\mathrm{out},1}
|
|
628
|
+
+ \dot{C}^{\mathrm{T}}_{\mathrm{out},2}
|
|
629
|
+
|
|
630
|
+
.. math::
|
|
631
|
+
\dot{C}_F = \dot{C}^{\mathrm{PH}}_{\mathrm{in},1}
|
|
632
|
+
+ \dot{C}^{\mathrm{PH}}_{\mathrm{in},2}
|
|
633
|
+
- \bigl(\dot{C}^{\mathrm{M}}_{\mathrm{out},1}
|
|
634
|
+
+ \dot{C}^{\mathrm{M}}_{\mathrm{out},2}\bigr)
|
|
635
|
+
|
|
636
|
+
Case 4: Only the hot inlet above ambient temperature
|
|
637
|
+
|
|
638
|
+
.. math::
|
|
639
|
+
\dot{C}_P = \dot{C}^{\mathrm{T}}_{\mathrm{out},1}
|
|
640
|
+
|
|
641
|
+
.. math::
|
|
642
|
+
\dot{C}_F = \bigl(\dot{C}^{\mathrm{PH}}_{\mathrm{in},1}
|
|
643
|
+
+ \dot{C}^{\mathrm{PH}}_{\mathrm{in},2}\bigr)
|
|
644
|
+
- \bigl(\dot{C}^{\mathrm{PH}}_{\mathrm{out},2}
|
|
645
|
+
+ \dot{C}^{\mathrm{M}}_{\mathrm{out},1}\bigr)
|
|
646
|
+
|
|
647
|
+
Case 5: Only the cold inlet below ambient temperature
|
|
648
|
+
|
|
649
|
+
.. math::
|
|
650
|
+
\dot{C}_P = \dot{C}^{\mathrm{T}}_{\mathrm{out},2}
|
|
651
|
+
|
|
652
|
+
.. math::
|
|
653
|
+
\dot{C}_F = \dot{C}^{\mathrm{PH}}_{\mathrm{in},1}
|
|
654
|
+
- \dot{C}^{\mathrm{PH}}_{\mathrm{out},1}
|
|
655
|
+
+ \bigl(\dot{C}^{\mathrm{PH}}_{\mathrm{in},2}
|
|
656
|
+
- \dot{C}^{\mathrm{M}}_{\mathrm{out},2}\bigr)
|
|
657
|
+
|
|
658
|
+
Case 6: Hot stream always above and cold stream always below ambient temperature (dissipative case):
|
|
659
|
+
|
|
660
|
+
.. math::
|
|
661
|
+
\dot{C}_P = \mathrm{NaN}
|
|
662
|
+
|
|
663
|
+
.. math::
|
|
664
|
+
\dot{C}_F = \bigl(\dot{C}^{\mathrm{PH}}_{\mathrm{in},1}
|
|
665
|
+
- \dot{C}^{\mathrm{PH}}_{\mathrm{out},1}\bigr)
|
|
666
|
+
- \dot{C}^{\mathrm{PH}}_{\mathrm{out},2}
|
|
667
|
+
+ \dot{C}^{\mathrm{PH}}_{\mathrm{in},2}
|
|
411
668
|
|
|
412
669
|
Parameters
|
|
413
670
|
----------
|
|
414
671
|
T0 : float
|
|
415
|
-
Ambient temperature
|
|
416
|
-
|
|
417
|
-
Notes
|
|
418
|
-
-----
|
|
419
|
-
The exergoeconomic balance considers thermal (T), chemical (CH),
|
|
420
|
-
and mechanical (M) exergy components for the inlet and outlet streams.
|
|
672
|
+
Ambient temperature (K).
|
|
421
673
|
"""
|
|
674
|
+
# Case 1: All streams are above the ambient temperature
|
|
422
675
|
if all([c["T"] > T0 for c in list(self.inl.values()) + list(self.outl.values())]):
|
|
423
676
|
self.C_P = self.outl[1]["C_T"] - self.inl[1]["C_T"]
|
|
424
677
|
self.C_F = self.inl[0]["C_PH"] - self.outl[0]["C_PH"] + (
|
|
425
678
|
self.inl[1]["C_M"] - self.outl[1]["C_M"])
|
|
679
|
+
# Case 2: All streams are below or equal to the ambient temperature
|
|
426
680
|
elif all([c["T"] <= T0 for c in list(self.inl.values()) + list(self.outl.values())]):
|
|
427
681
|
self.C_P = self.outl[0]["C_T"] - self.inl[0]["C_T"]
|
|
428
682
|
self.C_F = self.inl[1]["C_PH"] - self.outl[1]["C_PH"] + (
|
|
429
683
|
self.inl[0]["C_M"] - self.outl[0]["C_M"])
|
|
684
|
+
# Case 3: Both stream crossing T0 (hot inlet and cold outlet > T0, hot outlet and cold inlet <= T0)
|
|
430
685
|
elif (self.inl[0]["T"] > T0 and self.outl[1]["T"] > T0 and
|
|
431
686
|
self.outl[0]["T"] <= T0 and self.inl[1]["T"] <= T0):
|
|
432
687
|
self.C_P = self.outl[0]["C_T"] + self.outl[1]["C_T"]
|
|
433
688
|
self.C_F = self.inl[0]["C_PH"] + self.inl[1]["C_PH"] - (
|
|
434
689
|
self.outl[0]["C_M"] + self.outl[1]["C_M"])
|
|
690
|
+
# Case 4: Only hot inlet > T0
|
|
435
691
|
elif (self.inl[0]["T"] > T0 and self.inl[1]["T"] <= T0 and
|
|
436
692
|
self.outl[0]["T"] <= T0 and self.outl[1]["T"] <= T0):
|
|
437
693
|
self.C_P = self.outl[0]["C_T"]
|
|
438
694
|
self.C_F = self.inl[0]["C_PH"] + self.inl[1]["C_PH"] - (
|
|
439
695
|
self.outl[1]["C_PH"] + self.outl[0]["C_M"])
|
|
440
|
-
|
|
696
|
+
# Case 5: Only cold inlet <= T0
|
|
697
|
+
elif (self.inl[0]["T"] > T0 and self.inl[1]["T"] <= T0 and
|
|
698
|
+
self.outl[0]["T"] > T0 and self.outl[1]["T"] > T0):
|
|
441
699
|
self.C_P = self.outl[1]["C_T"]
|
|
442
700
|
self.C_F = self.inl[0]["C_PH"] - self.outl[0]["C_PH"] + (
|
|
443
701
|
self.inl[1]["C_PH"] - self.outl[1]["C_M"])
|
|
702
|
+
# Case 6: hot stream always above T0, cold stream always below T0 (dissipative case)
|
|
703
|
+
elif (self.inl[0]["T"] > T0 and self.inl[1]["T"] <= T0 and
|
|
704
|
+
self.outl[0]["T"] > T0 and self.outl[1]["T"] <= T0):
|
|
705
|
+
logging.warning(f"Component {self.name} is dissipative. This component should be " \
|
|
706
|
+
"handled with the `dissipative` flag set to True.")
|
|
707
|
+
self.C_P = np.nan
|
|
708
|
+
self.C_F = self.inl[0]["C_PH"] - self.outl[0]["C_PH"] + (
|
|
709
|
+
self.inl[1]["C_PH"] - self.outl[1]["C_PH"])
|
|
710
|
+
# Case 7: Not implemented case
|
|
711
|
+
else:
|
|
712
|
+
logging.error(f"The heat exchanger {self.name} has an unexpected temperature configuration. "
|
|
713
|
+
"Please check the inlet and outlet temperatures.")
|
|
444
714
|
|
|
445
715
|
self.c_F = self.C_F / self.E_F
|
|
446
716
|
self.c_P = self.C_P / self.E_P
|