Skip to content

Commit

Permalink
Disentagle hydro-group for simple heat exchangers
Browse files Browse the repository at this point in the history
  • Loading branch information
fwitte committed Sep 25, 2023
1 parent d2fc29d commit 44d474f
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 171 deletions.
55 changes: 23 additions & 32 deletions src/tespy/components/heat_exchangers/parabolic_trough.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ class ParabolicTrough(SimpleHeatExchanger):
- :py:meth:`tespy.components.component.Component.pr_func`
- :py:meth:`tespy.components.component.Component.zeta_func`
- :py:meth:`tespy.components.heat_exchangers.simple.SimpleHeatExchanger.energy_balance_func`
- :py:meth:`tespy.components.heat_exchangers.simple.SimpleHeatExchanger.hydro_group_func`
- :py:meth:`tespy.components.heat_exchangers.simple.SimpleHeatExchanger.darcy_group_func`
- :py:meth:`tespy.components.heat_exchangers.simple.SimpleHeatExchanger.hw_group_func`
- :py:meth:`tespy.components.heat_exchangers.parabolic_trough.ParabolicTrough.energy_group_func`
Inlets/Outlets
Expand Down Expand Up @@ -98,13 +99,18 @@ class ParabolicTrough(SimpleHeatExchanger):
Length of the absorber tube, :math:`L/\text{m}`.
ks : float, dict, :code:`"var"`
Tube's roughness, :math:`ks/\text{m}` for darcy friction,
:math:`ks/\text{1}` for hazen-williams equation.
Pipe's roughness, :math:`ks/\text{m}`.
hydro_group : str, dict
Parametergroup for pressure drop calculation based on pipes dimensions.
Choose 'HW' for hazen-williams equation, else darcy friction factor is
used.
darcy_group : str, dict
Parametergroup for pressure drop calculation based on pipes dimensions
using darcy weissbach equation.
ks_HW : float, dict, :code:`"var"`
Pipe's roughness, :math:`ks/\text{1}`.
hw_group : str, dict
Parametergroup for pressure drop calculation based on pipes dimensions
using hazen williams equation.
E : float, dict, :code:`"var"`
Direct irradiance to tilted collector,
Expand Down Expand Up @@ -182,7 +188,7 @@ class ParabolicTrough(SimpleHeatExchanger):
>>> pt.set_attr(pr=1, aoi=aoi, doc=1,
... Tamb=20, A=1, eta_opt=0.816, c_1=0.0622, c_2=0.00023, E=E,
... iam_1=-1.59e-3, iam_2=9.77e-5)
>>> inc.set_attr(fluid={'S800': 1}, fluid_back_ends={'S800': 'INCOMP'}, T=220, p=2)
>>> inc.set_attr(fluid={'INCOMP::S800': 1}, T=220, p=2)
>>> outg.set_attr(T=260)
>>> nw.solve('design')
>>> round(pt.Q.val, 0)
Expand Down Expand Up @@ -220,23 +226,11 @@ def component():
return 'parabolic trough'

def get_parameters(self):
return {
'Q': dc_cp(
deriv=self.energy_balance_deriv,
latex=self.energy_balance_func_doc, num_eq=1,
func=self.energy_balance_func),
'pr': dc_cp(
min_val=1e-4, max_val=1, num_eq=1,
deriv=self.pr_deriv, latex=self.pr_func_doc,
func=self.pr_func, func_params={'pr': 'pr'}),
'zeta': dc_cp(
min_val=0, max_val=1e15, num_eq=1,
deriv=self.zeta_deriv, func=self.zeta_func,
latex=self.zeta_func_doc,
func_params={'zeta': 'zeta'}),
'D': dc_cp(min_val=1e-2, max_val=2, d=1e-4),
'L': dc_cp(min_val=1e-1, d=1e-3),
'ks': dc_cp(val=1e-4, min_val=1e-7, max_val=1e-3, d=1e-8),
data = super().get_parameters()
for k in ["kA_group", "kA_char_group", "kA", "kA_char"]:
del data[k]

data.update({
'E': dc_cp(min_val=0), 'A': dc_cp(min_val=0),
'eta_opt': dc_cp(min_val=0, max_val=1),
'c_1': dc_cp(min_val=0), 'c_2': dc_cp(min_val=0),
Expand All @@ -245,17 +239,14 @@ def get_parameters(self):
'doc': dc_cp(min_val=0, max_val=1),
'Tamb': dc_cp(),
'Q_loss': dc_cp(max_val=0, val=0),
'dissipative': dc_simple(val=True),
'hydro_group': dc_gcp(
elements=['L', 'ks', 'D'], num_eq=1,
latex=self.hydro_group_func_doc,
func=self.hydro_group_func, deriv=self.hydro_group_deriv),
'energy_group': dc_gcp(
elements=['E', 'eta_opt', 'aoi', 'doc', 'c_1', 'c_2', 'iam_1',
'iam_2', 'A', 'Tamb'], num_eq=1,
latex=self.energy_group_func_doc,
func=self.energy_group_func, deriv=self.energy_group_deriv)
}
func=self.energy_group_func, deriv=self.energy_group_deriv
)
})
return data

def energy_group_func(self):
r"""
Expand Down
186 changes: 89 additions & 97 deletions src/tespy/components/heat_exchangers/simple.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ class SimpleHeatExchanger(Component):
- :py:meth:`tespy.components.component.Component.pr_func`
- :py:meth:`tespy.components.component.Component.zeta_func`
- :py:meth:`tespy.components.heat_exchangers.simple.SimpleHeatExchanger.energy_balance_func`
- :py:meth:`tespy.components.heat_exchangers.simple.SimpleHeatExchanger.hydro_group_func`
- :py:meth:`tespy.components.heat_exchangers.simple.SimpleHeatExchanger.darcy_group_func`
- :py:meth:`tespy.components.heat_exchangers.simple.SimpleHeatExchanger.hw_group_func`
- :py:meth:`tespy.components.heat_exchangers.simple.SimpleHeatExchanger.kA_group_func`
- :py:meth:`tespy.components.heat_exchangers.simple.SimpleHeatExchanger.kA_char_group_func`
Expand Down Expand Up @@ -112,13 +113,18 @@ class SimpleHeatExchanger(Component):
Length of the pipes, :math:`L/\text{m}`.
ks : float, dict, :code:`"var"`
Pipe's roughness, :math:`ks/\text{m}` for darcy friction,
:math:`ks/\text{1}` for hazen-williams equation.
Pipe's roughness, :math:`ks/\text{m}`.
hydro_group : str, dict
Parametergroup for pressure drop calculation based on pipes dimensions.
Choose 'HW' for hazen-williams equation, else darcy friction factor is
used.
darcy_group : str, dict
Parametergroup for pressure drop calculation based on pipes dimensions
using darcy weissbach equation.
ks_HW : float, dict, :code:`"var"`
Pipe's roughness, :math:`ks/\text{1}`.
hw_group : str, dict
Parametergroup for pressure drop calculation based on pipes dimensions
using hazen williams equation.
kA : float, dict, :code:`"var"`
Area independent heat transfer coefficient,
Expand Down Expand Up @@ -213,13 +219,18 @@ def get_parameters(self):
'D': dc_cp(min_val=1e-2, max_val=2, d=1e-4),
'L': dc_cp(min_val=1e-1, d=1e-3),
'ks': dc_cp(val=1e-4, min_val=1e-7, max_val=1e-3, d=1e-8),
'ks_HW': dc_cp(val=10, min_val=1e-1, max_val=1e3, d=1e-2),
'kA': dc_cp(min_val=0, d=1),
'kA_char': dc_cc(param='m'), 'Tamb': dc_cp(),
'dissipative': dc_simple(val=True),
'hydro_group': dc_gcp(
'darcy_group': dc_gcp(
elements=['L', 'ks', 'D'], num_eq=1,
latex=self.hydro_group_func_doc,
func=self.hydro_group_func, deriv=self.hydro_group_deriv),
latex=self.darcy_func_doc,
func=self.darcy_func, deriv=self.darcy_deriv),
'hw_group': dc_gcp(
elements=['L', 'ks_HW', 'D'], num_eq=1,
latex=self.hazen_williams_func_doc,
func=self.hazen_williams_func, deriv=self.hazen_williams_deriv),
'kA_group': dc_gcp(
elements=['kA', 'Tamb'], num_eq=1,
latex=self.kA_group_func_doc,
Expand Down Expand Up @@ -304,91 +315,6 @@ def energy_balance_deriv(self, increment_filter, k):
if self.Q.is_var:
self.jacobian[k, self.Q.J_col] = -1

def hydro_group_func(self):
r"""
Equation for pressure drop calculation.
Returns
-------
residual : float
Residual value of corresponding equation:
- :py:meth:`tespy.components.heat_exchangers.simple.SimpleHeatExchanger.darcy_func`
- :py:meth:`tespy.components.heat_exchangers.simple.SimpleHeatExchanger.hazen_williams_func`
"""
# hazen williams equation
if self.hydro_group.method == 'HW':
return self.hazen_williams_func()
# darcy friction factor
else:
return self.darcy_func()

def hydro_group_func_doc(self, label):
r"""
Equation for pressure drop calculation.
Parameters
----------
label : str
Label for equation.
Returns
-------
latex : str
LaTeX code of equations applied.
"""
# hazen williams equation
if self.hydro_group.method == 'HW':
msg = (
"The Hazen-Williams equation will be accessible through its "
"own ks-value in the next major version. That means, you will "
"not need to specify hydro_group='HW' and ks. Instead of ks "
"specify ks_HW"
)
warnings.warn(msg, FutureWarning)
return self.hazen_williams_func_doc(label)
# darcy friction factor
else:
return self.darcy_func_doc(label)

def hydro_group_deriv(self, increment_filter, k):
r"""
Calculate partial derivatives of hydro group (pressure drop).
Parameters
----------
increment_filter : ndarray
Matrix for filtering non-changing variables.
k : int
Position of derivatives in Jacobian matrix (k-th equation).
"""
# hazen williams equation
if self.hydro_group.method == 'HW':
func = self.hazen_williams_func
# darcy friction factor
else:
func = self.darcy_func
i = self.inl[0]
o = self.outl[0]
if self.is_variable(i.m, increment_filter):
self.jacobian[k, i.m.J_col] = self.numeric_deriv(func, 'm', i)
if self.is_variable(i.p, increment_filter):
self.jacobian[k, i.p.J_col] = self.numeric_deriv(func, 'p', i)
if self.is_variable(i.h, increment_filter):
self.jacobian[k, i.h.J_col] = self.numeric_deriv(func, 'h', i)
if self.is_variable(o.p, increment_filter):
self.jacobian[k, o.p.J_col] = self.numeric_deriv(func, 'p', o)
if self.is_variable(o.h, increment_filter):
self.jacobian[k, o.h.J_col] = self.numeric_deriv(func, 'h', o)
# custom variables of hydro group
for variable_name in self.hydro_group.elements:
parameter = self.get_attr(variable_name)
if parameter.is_var:
self.jacobian[k, parameter.J_col] = (
self.numeric_deriv(func, variable_name, None)
)

def darcy_func(self):
r"""
Equation for pressure drop calculation from darcy friction factor.
Expand Down Expand Up @@ -456,6 +382,39 @@ def darcy_func_doc(self, label):
)
return generate_latex_eq(self, latex, label)

def darcy_deriv(self, increment_filter, k):
r"""
Calculate partial derivatives of hydro group (pressure drop).
Parameters
----------
increment_filter : ndarray
Matrix for filtering non-changing variables.
k : int
Position of derivatives in Jacobian matrix (k-th equation).
"""
func = self.darcy_func
i = self.inl[0]
o = self.outl[0]
if self.is_variable(i.m, increment_filter):
self.jacobian[k, i.m.J_col] = self.numeric_deriv(func, 'm', i)
if self.is_variable(i.p, increment_filter):
self.jacobian[k, i.p.J_col] = self.numeric_deriv(func, 'p', i)
if self.is_variable(i.h, increment_filter):
self.jacobian[k, i.h.J_col] = self.numeric_deriv(func, 'h', i)
if self.is_variable(o.p, increment_filter):
self.jacobian[k, o.p.J_col] = self.numeric_deriv(func, 'p', o)
if self.is_variable(o.h, increment_filter):
self.jacobian[k, o.h.J_col] = self.numeric_deriv(func, 'h', o)
# custom variables of hydro group
for variable_name in self.darcy_group.elements:
parameter = self.get_attr(variable_name)
if parameter.is_var:
self.jacobian[k, parameter.J_col] = (
self.numeric_deriv(func, variable_name, None)
)

def hazen_williams_func(self):
r"""
Equation for pressure drop calculation from Hazen-Williams equation.
Expand Down Expand Up @@ -493,7 +452,7 @@ def hazen_williams_func(self):
return (
(i.p.val_SI - o.p.val_SI) * np.sign(i.m.val_SI) -
(10.67 * abs(i.m.val_SI) ** 1.852 * self.L.val /
(self.ks.val ** 1.852 * self.D.val ** 4.871)) *
(self.ks_HW.val ** 1.852 * self.D.val ** 4.871)) *
(9.81 * ((v_i + v_o) / 2) ** 0.852))

def hazen_williams_func_doc(self, label):
Expand All @@ -518,6 +477,39 @@ def hazen_williams_func_doc(self, label):
)
return generate_latex_eq(self, latex, label)

def hazen_williams_deriv(self, increment_filter, k):
r"""
Calculate partial derivatives of hydro group (pressure drop).
Parameters
----------
increment_filter : ndarray
Matrix for filtering non-changing variables.
k : int
Position of derivatives in Jacobian matrix (k-th equation).
"""
func = self.hazen_williams_func
i = self.inl[0]
o = self.outl[0]
if self.is_variable(i.m, increment_filter):
self.jacobian[k, i.m.J_col] = self.numeric_deriv(func, 'm', i)
if self.is_variable(i.p, increment_filter):
self.jacobian[k, i.p.J_col] = self.numeric_deriv(func, 'p', i)
if self.is_variable(i.h, increment_filter):
self.jacobian[k, i.h.J_col] = self.numeric_deriv(func, 'h', i)
if self.is_variable(o.p, increment_filter):
self.jacobian[k, o.p.J_col] = self.numeric_deriv(func, 'p', o)
if self.is_variable(o.h, increment_filter):
self.jacobian[k, o.h.J_col] = self.numeric_deriv(func, 'h', o)
# custom variables of hydro group
for variable_name in self.hw_group.elements:
parameter = self.get_attr(variable_name)
if parameter.is_var:
self.jacobian[k, parameter.J_col] = (
self.numeric_deriv(func, variable_name, None)
)

def kA_group_func(self):
r"""
Calculate heat transfer from heat transfer coefficient.
Expand Down Expand Up @@ -1089,7 +1081,7 @@ def exergy_balance(self, T0):
"chemical": np.nan, "physical": np.nan, "massless": np.nan
}
elif self.Q.val > 0:
if self.inl[0].T.val_SI >= T0 and self.outl[0].T.val_SI >= T0:
if self.inl[0].T.val_SI >= T0 - 1e-6 and self.outl[0].T.val_SI >= T0 - 1e-6:
self.E_P = self.outl[0].Ex_physical - self.inl[0].Ex_physical
self.E_F = self.outl[0].Ex_therm - self.inl[0].Ex_therm
self.E_bus = {
Expand Down
Loading

0 comments on commit 44d474f

Please sign in to comment.