23
23
from tespy .tools .document_models import generate_latex_eq
24
24
from tespy .tools .fluid_properties import h_mix_pT
25
25
from tespy .tools .fluid_properties import s_mix_ph
26
+ from tespy .tools .helpers import convert_from_SI
27
+ from tespy .tools .helpers import convert_to_SI
26
28
27
29
28
30
@component_registry
@@ -46,13 +48,16 @@ class HeatExchanger(Component):
46
48
- :py:meth:`tespy.components.heat_exchangers.base.HeatExchanger.kA_char_func`
47
49
- :py:meth:`tespy.components.heat_exchangers.base.HeatExchanger.ttd_u_func`
48
50
- :py:meth:`tespy.components.heat_exchangers.base.HeatExchanger.ttd_l_func`
51
+ - :py:meth:`tespy.components.heat_exchangers.base.HeatExchanger.ttd_min_func`
49
52
- :py:meth:`tespy.components.heat_exchangers.base.HeatExchanger.eff_cold_func`
50
53
- :py:meth:`tespy.components.heat_exchangers.base.HeatExchanger.eff_hot_func`
51
54
- :py:meth:`tespy.components.heat_exchangers.base.HeatExchanger.eff_max_func`
52
55
- hot side :py:meth:`tespy.components.component.Component.pr_func`
53
56
- cold side :py:meth:`tespy.components.component.Component.pr_func`
54
57
- hot side :py:meth:`tespy.components.component.Component.zeta_func`
55
58
- cold side :py:meth:`tespy.components.component.Component.zeta_func`
59
+ - hot side :py:meth:`tespy.components.component.Component.dp_func`
60
+ - cold side :py:meth:`tespy.components.component.Component.dp_func`
56
61
57
62
Inlets/Outlets
58
63
@@ -106,6 +111,12 @@ class HeatExchanger(Component):
106
111
pr2 : float, dict, :code:`"var"`
107
112
Outlet to inlet pressure ratio at cold side, :math:`pr/1`.
108
113
114
+ dp1 : float, dict, :code:`"var"`
115
+ Inlet to outlet pressure delta at hot side, :math:`dp/\text{Pa}`.
116
+
117
+ dp2 : float, dict, :code:`"var"`
118
+ Inlet to outlet pressure delta at cold side, :math:`dp/\text{Pa}`.
119
+
109
120
zeta1 : float, dict, :code:`"var"`
110
121
Geometry independent friction coefficient at hot side,
111
122
:math:`\frac{\zeta}{D^4}/\frac{1}{\text{m}^4}`.
@@ -120,6 +131,9 @@ class HeatExchanger(Component):
120
131
ttd_u : float, dict
121
132
Upper terminal temperature difference :math:`ttd_\mathrm{u}/\text{K}`.
122
133
134
+ ttd_min : float, dict
135
+ Minumum terminal temperature difference :math:`ttd_\mathrm{min}/\text{K}`.
136
+
123
137
eff_cold : float, dict
124
138
Cold side heat exchanger effectiveness :math:`eff_\text{cold}/\text{1}`.
125
139
@@ -229,6 +243,9 @@ def get_parameters(self):
229
243
'ttd_l' : dc_cp (
230
244
min_val = 0 , num_eq = 1 , func = self .ttd_l_func ,
231
245
deriv = self .ttd_l_deriv , latex = self .ttd_l_func_doc ),
246
+ 'ttd_min' : dc_cp (
247
+ min_val = 0 , num_eq = 1 , func = self .ttd_min_func ,
248
+ deriv = self .ttd_min_deriv ),
232
249
'pr1' : dc_cp (
233
250
min_val = 1e-4 , max_val = 1 , num_eq = 1 , deriv = self .pr_deriv ,
234
251
latex = self .pr_func_doc ,
@@ -237,6 +254,14 @@ def get_parameters(self):
237
254
min_val = 1e-4 , max_val = 1 , num_eq = 1 , latex = self .pr_func_doc ,
238
255
deriv = self .pr_deriv , func = self .pr_func ,
239
256
func_params = {'pr' : 'pr2' , 'inconn' : 1 , 'outconn' : 1 }),
257
+ 'dp1' : dc_cp (
258
+ min_val = 0 , max_val = 10000 , num_eq = 1 ,
259
+ deriv = self .dp_deriv , func = self .dp_func ,
260
+ func_params = {'dp' : 'dp1' , 'inconn' : 0 , 'outconn' : 0 }),
261
+ 'dp2' : dc_cp (
262
+ min_val = 0 , max_val = 10000 , num_eq = 1 ,
263
+ deriv = self .dp_deriv , func = self .dp_func ,
264
+ func_params = {'dp' : 'dp2' , 'inconn' : 1 , 'outconn' : 1 }),
240
265
'zeta1' : dc_cp (
241
266
min_val = 0 , max_val = 1e15 , num_eq = 1 , latex = self .zeta_func_doc ,
242
267
deriv = self .zeta_deriv , func = self .zeta_func ,
@@ -285,6 +310,15 @@ def inlets():
285
310
def outlets ():
286
311
return ['out1' , 'out2' ]
287
312
313
+ def preprocess (self , num_nw_vars ):
314
+ super ().preprocess (num_nw_vars )
315
+
316
+ if self .dp1 .is_set :
317
+ self .dp1 .val_SI = convert_to_SI ('p' , self .dp1 .val , self .inl [0 ].p .unit )
318
+
319
+ if self .dp2 .is_set :
320
+ self .dp2 .val_SI = convert_to_SI ('p' , self .dp2 .val , self .inl [1 ].p .unit )
321
+
288
322
def energy_balance_func (self ):
289
323
r"""
290
324
Equation for heat exchanger energy balance.
@@ -706,6 +740,56 @@ def ttd_l_deriv(self, increment_filter, k):
706
740
if self .is_variable (c .h , increment_filter ):
707
741
self .jacobian [k , c .h .J_col ] = self .numeric_deriv (f , 'h' , c )
708
742
743
+ def ttd_min_func (self ):
744
+ r"""
745
+ Equation for upper terminal temperature difference.
746
+
747
+ Returns
748
+ -------
749
+ residual : float
750
+ Residual value of equation.
751
+
752
+ .. math::
753
+
754
+ ttd_{l} = T_{out,1} - T_{in,2}
755
+ ttd_{u} = T_{in,1} - T_{out,2}
756
+ 0 = \text{min}\left(ttd_{u}, ttd_{l}\right)
757
+
758
+ """
759
+ i = self .inl [1 ]
760
+ o = self .outl [0 ]
761
+ T_i2 = i .calc_T ()
762
+ T_o1 = o .calc_T ()
763
+
764
+ i = self .inl [0 ]
765
+ o = self .outl [1 ]
766
+ T_i1 = i .calc_T ()
767
+ T_o2 = o .calc_T ()
768
+
769
+ ttd_l = T_o1 - T_i2
770
+ ttd_u = T_i1 - T_o2
771
+
772
+ return self .ttd_min .val - min (ttd_l , ttd_u )
773
+
774
+ def ttd_min_deriv (self , increment_filter , k ):
775
+ """
776
+ Calculate partial derivates of minimum terminal temperature function.
777
+
778
+ Parameters
779
+ ----------
780
+ increment_filter : ndarray
781
+ Matrix for filtering non-changing variables.
782
+
783
+ k : int
784
+ Position of derivatives in Jacobian matrix (k-th equation).
785
+ """
786
+ f = self .ttd_min_func
787
+ for c in self .inl + self .outl :
788
+ if self .is_variable (c .p , increment_filter ):
789
+ self .jacobian [k , c .p .J_col ] = self .numeric_deriv (f , 'p' , c )
790
+ if self .is_variable (c .h , increment_filter ):
791
+ self .jacobian [k , c .h .J_col ] = self .numeric_deriv (f , 'h' , c )
792
+
709
793
def calc_dh_max_cold (self ):
710
794
r"""Calculate the theoretical maximum enthalpy increase on the cold side
711
795
@@ -1030,20 +1114,26 @@ def initialise_target(self, c, key):
1030
1114
1031
1115
def calc_parameters (self ):
1032
1116
r"""Postprocessing parameter calculation."""
1033
- # component parameters
1034
1117
self .Q .val = self .inl [0 ].m .val_SI * (
1035
1118
self .outl [0 ].h .val_SI - self .inl [0 ].h .val_SI
1036
1119
)
1037
1120
self .ttd_u .val = self .inl [0 ].T .val_SI - self .outl [1 ].T .val_SI
1038
1121
self .ttd_l .val = self .outl [0 ].T .val_SI - self .inl [1 ].T .val_SI
1122
+ self .ttd_min .val = min (self .ttd_u .val , self .ttd_min .val )
1039
1123
1040
1124
# pr and zeta
1041
1125
for i in range (2 ):
1042
- self .get_attr ('pr' + str (i + 1 )).val = (
1043
- self .outl [i ].p .val_SI / self .inl [i ].p .val_SI )
1044
- self .get_attr ('zeta' + str (i + 1 )).val = self .calc_zeta (
1126
+ self .get_attr (f'pr{ i + 1 } ' ).val = (
1127
+ self .outl [i ].p .val_SI / self .inl [i ].p .val_SI
1128
+ )
1129
+ self .get_attr (f'zeta{ i + 1 } ' ).val = self .calc_zeta (
1045
1130
self .inl [i ], self .outl [i ]
1046
1131
)
1132
+ self .get_attr (f'dp{ i + 1 } ' ).val_SI = (
1133
+ self .inl [i ].p .val_SI - self .outl [i ].p .val_SI )
1134
+ self .get_attr (f'dp{ i + 1 } ' ).val = convert_from_SI (
1135
+ 'p' , self .get_attr (f'dp{ i + 1 } ' ).val_SI , self .inl [i ].p .unit
1136
+ )
1047
1137
1048
1138
# kA and logarithmic temperature difference
1049
1139
if self .ttd_u .val < 0 or self .ttd_l .val < 0 :
0 commit comments