tespy.components.heat_exchangers package

tespy.components.heat_exchangers.base module

Module of class HeatExchanger.

This file is part of project TESPy (github.com/oemof/tespy). It’s copyrighted by the contributors recorded in the version control history of the file, available from its original location tespy/components/heat_exchangers/base.py

SPDX-License-Identifier: MIT

class tespy.components.heat_exchangers.base.HeatExchanger(label, **kwargs)[source]

Bases: Component

Class for counter flow heat exchanger.

The component HeatExchanger is the parent class for the components:

flowsheet of the heatexchanger flowsheet of the heatexchanger

Ports

  • Fluid inlets: in1, in2

  • Fluid outlets: out1, out2

Mandatory Equations

Parameters:
  • char_warnings (bool) – Ignore warnings on default characteristics usage for this component.

  • design (list) – List containing design parameters (stated as String).

  • design_path (str) – Path to the components design case.

  • dp1 (float, dict) – Hot side inlet to outlet absolute pressure change. Quantity: pressure_difference. Equation: dp_structure_matrix.

  • dp2 (float, dict) – Cold side inlet to outlet absolute pressure change. Quantity: pressure_difference. Equation: dp_structure_matrix.

  • eff_cold (float, dict) – Heat exchanger effectiveness for cold side. Quantity: efficiency. Equation: eff_cold_func.

  • eff_hot (float, dict) – Heat exchanger effectiveness for hot side. Quantity: efficiency. Equation: eff_hot_func.

  • eff_max (float, dict) – Maximum heat exchanger effectiveness. Quantity: efficiency. Equation: eff_max_func.

  • kA (float, dict) – Deprecated, use UA instead. Quantity: heat_transfer_coefficient.

  • kA_char (GroupedComponentCharacteristics) – Deprecated, use UA_char instead. Elements: kA_char1, kA_char2.

  • kA_char1 (tespy.tools.characteristics.CharLine, dict) – Deprecated, use UA_char1 instead.

  • kA_char2 (tespy.tools.characteristics.CharLine, dict) – Deprecated, use UA_char2 instead.

  • label (str) – The label of the component.

  • lmtd (float, dict) – Effective logarithmic mean temperature difference |Q|/UA. Quantity: temperature_difference.

  • local_design (bool) – Treat this component in design mode in an offdesign calculation.

  • local_offdesign (bool) – Treat this component in offdesign mode in a design calculation.

  • offdesign (list) – List containing offdesign parameters (stated as String).

  • pr1 (float, dict) – Hot side outlet to inlet pressure ratio. Quantity: ratio. Equation: pr_structure_matrix.

  • pr2 (float, dict) – Cold side outlet to inlet pressure ratio. Quantity: ratio. Equation: pr_structure_matrix.

  • printout (bool) – Include this component in the network’s results printout.

  • Q (float, dict) – Heat transfer from hot side. Quantity: heat. Equation: energy_balance_hot_func.

  • td_log (float, dict) – Deprecated, use lmtd instead. Quantity: temperature_difference.

  • ttd_l (float, dict) – Terminal temperature difference at hot side outlet to cold side inlet. Quantity: temperature_difference. Equation: ttd_l_func.

  • ttd_min (float, dict) – Minimum terminal temperature difference. Quantity: temperature_difference. Equation: ttd_min_func.

  • ttd_u (float, dict) – Terminal temperature difference at hot side inlet to cold side outlet. Quantity: temperature_difference. Equation: ttd_u_func.

  • UA (float, dict) – Heat transfer coefficient considering terminal temperature differences. Quantity: heat_transfer_coefficient. Equation: UA_func.

  • UA_char (GroupedComponentCharacteristics) – Equation for heat transfer based on UA and modification factor. Elements: UA_char1, UA_char2. Equation: UA_char_func.

  • UA_char1 (tespy.tools.characteristics.CharLine, dict) – Hot side UA modification lookup table for offdesign.

  • UA_char2 (tespy.tools.characteristics.CharLine, dict) – Cold side UA modification lookup table for offdesign.

  • zeta1 (float, dict) – Deprecated, use zeta1_d4 instead.

  • zeta1_d4 (float, dict) – Hot side geometry-independent friction coefficient zeta/D^4 for pressure loss calculation. Equation: zeta_d4_func.

  • zeta2 (float, dict) – Deprecated, use zeta2_d4 instead.

  • zeta2_d4 (float, dict) – Cold side geometry-independent friction coefficient zeta/D^4 for pressure loss calculation. Equation: zeta_d4_func.

Notes

Note

The HeatExchanger and subclasses ( tespy.components.heat_exchangers.condenser.Condenser, tespy.components.heat_exchangers.desuperheater.Desuperheater) are countercurrent heat exchangers. Equations (kA, ttd_u, ttd_l) do not work for directcurrent and crosscurrent or combinations of different types.

Example

A water cooling is installed to transfer heat from hot exhaust air. The heat exchanger is designed for a terminal temperature difference of 5 K. From this, it is possible to calculate the heat transfer coefficient and predict water and air outlet temperature in offdesign operation.

>>> from tespy.components import Sink, Source, HeatExchanger
>>> from tespy.connections import Connection
>>> from tespy.networks import Network
>>> nw = Network(iterinfo=False)
>>> nw.units.set_defaults(**{
...     "pressure": "bar", "pressure_difference": "bar",
...     "temperature": "degC", "enthalpy": "kJ/kg",
...     "heat_transfer_coefficient": "kW/K"
... })
>>> exhaust_hot = Source('Exhaust air outlet')
>>> exhaust_cold = Sink('Exhaust air inlet')
>>> cw_cold = Source('cooling water inlet')
>>> cw_hot = Sink('cooling water outlet')
>>> he = HeatExchanger('waste heat exchanger')
>>> ex_he = Connection(exhaust_hot, 'out1', he, 'in1')
>>> he_ex = Connection(he, 'out1', exhaust_cold, 'in1')
>>> cw_he = Connection(cw_cold, 'out1', he, 'in2')
>>> he_cw = Connection(he, 'out2', cw_hot, 'in1')
>>> nw.add_conns(ex_he, he_ex, cw_he, he_cw)

The volumetric flow of the air is at 100 l/s. After designing the component it is possible to predict the temperature at different flow rates or different inlet temperatures of the exhaust air.

>>> he.set_attr(
...     pr1=0.98, pr2=0.98, ttd_u=5,
...     design=['pr1', 'pr2', 'ttd_u'],
...     offdesign=['zeta1_d4', 'zeta2_d4', 'UA_char']
... )
>>> cw_he.set_attr(
...     fluid={'water': 1}, T=10, p=3, offdesign=['m']
... )
>>> ex_he.set_attr(fluid={'air': 1}, v=0.1, T=35)
>>> he_ex.set_attr(T=17.5, p=1, design=['T'])
>>> nw.solve('design')
>>> design_state = nw.save(as_dict=True)
>>> round(ex_he.T.val - he_cw.T.val, 0)
5.0
>>> ex_he.set_attr(v=0.075)
>>> nw.solve('offdesign', design_path=design_state)
>>> round(he_cw.T.val, 1)
27.5
>>> round(he_ex.T.val, 1)
14.4
>>> ex_he.set_attr(v=0.1, T=40)
>>> nw.solve('offdesign', design_path=design_state)
>>> round(he_cw.T.val, 1)
33.9
>>> round(he_ex.T.val, 1)
18.8
UA_char_dependents()[source]
UA_char_func()[source]

Calculate heat transfer from heat transfer coefficient characteristic.

Returns:

residual (float) – Residual value of equation.

\[ \begin{align}\begin{aligned}0 = \dot{m}_{in,1} \cdot \left( h_{out,1} - h_{in,1}\right) + UA_{design} \cdot f_{UA} \cdot \frac{T_{out,1} - T_{in,2} - T_{in,1} + T_{out,2}} {\ln{\frac{T_{out,1} - T_{in,2}}{T_{in,1} - T_{out,2}}}}\\f_{UA} = \frac{2}{\frac{1}{f_1\left( expr_1\right)} + \frac{1}{f_2\left( expr_2\right)}}\end{aligned}\end{align} \]

Note

For standard functions f1 and f2 see module tespy.data.

UA_dependents()[source]
UA_deriv(increment_filter, k, dependents=None)[source]

Partial derivatives of heat transfer coefficient function.

Parameters:
  • increment_filter (ndarray) – Matrix for filtering non-changing variables.

  • k (int) – Position of derivatives in Jacobian matrix (k-th equation).

UA_func()[source]

Calculate heat transfer from heat transfer coefficient.

Returns:

residual (float) – Residual value of equation.

\[0 = \dot{m}_{in,1} \cdot \left( h_{out,1} - h_{in,1}\right) + UA \cdot \frac{T_{out,1} - T_{in,2} - T_{in,1} + T_{out,2}} {\ln{\frac{T_{out,1} - T_{in,2}}{T_{in,1} - T_{out,2}}}}\]

calc_dh_max_cold()[source]

Calculate the theoretical maximum enthalpy increase on the cold side

Returns:

float – Maximum cold side enthalpy increase.

\[h\left(p_{out,2}, T_{in,1}\right) - h_{in,2}\]

calc_dh_max_hot()[source]

Calculate the theoretical maximum enthalpy decrease on the hot side

Returns:

float – Maximum hot side enthalpy decrease.

\[h\left(p_{out,1}, T_{in,2}\right) - h_{in,1}\]

calc_sections(postprocess=True)[source]

Calculate the sections of the heat exchanger. For the base class, these are only points at the edges

Returns:

tuple – Cumulated heat transfer over sections, temperature at steps hot side, temperature at steps cold side, heat transfer per section, logarithmic temperature per section

calculate_td_log()[source]

Method to calculate logarithmic temperature difference during iteration. It returns the minimal temperature difference value instead of the logarithmic temperature difference if the minimal temperature difference is negative during iteration to progress in convergence

eff_cold_dependents()[source]
eff_cold_func()[source]

Equation for cold side heat exchanger effectiveness.

Returns:

residual (float) – Residual value of equation.

\[0 = \text{eff}_\text{cold} \cdot \left(h\left(p_{out,2}, T_{in,1} \right) - h_{in,2}\right) - \left( h_{out,2} - h_{in,2} \right)\]

eff_hot_dependents()[source]
eff_hot_func()[source]

Equation for hot side heat exchanger effectiveness.

Returns:

residual (float) – Residual value of equation.

\[0 = \text{eff}_\text{hot} \cdot \left(h\left(p_{out,1}, T_{in,2}\right) - h_{in,1}\right) - \left( h_{out,1} - h_{in,1}\right)\]

eff_max_dependents()[source]
eff_max_func()[source]

Equation for maximum heat exchanger effectiveness.

Note

This functions works on what is larger: hot side or cold side effectiveness. It may cause numerical issues, if applied, when one of both sides’ effectiveness is already predetermined, e.g. by temperature specifications.

Returns:

residual (float) – Residual value of equation.

\[0 = \text{eff}_\text{max} - \text{max} \left(\text{eff}_\text{hot},\text{eff}_\text{cold}\right)\]

energy_balance_dependents()[source]
energy_balance_func()[source]

Equation for heat exchanger energy balance.

Returns:

residual (float) – Residual value of equation.

\[0 = \dot{m}_{in,1} \cdot \left(h_{out,1} - h_{in,1} \right) + \dot{m}_{in,2} \cdot \left(h_{out,2} - h_{in,2} \right)\]

energy_balance_hot_dependents()[source]
energy_balance_hot_func()[source]

Equation for hot side heat exchanger energy balance.

Returns:

residual (float) – Residual value of equation.

\[0 =\dot{m}_{in,1} \cdot \left(h_{out,1}-h_{in,1}\right)-\dot{Q}\]

entropy_balance()[source]

Calculate entropy balance of a heat exchanger.

The allocation of the entropy streams due to heat exchanged and due to irreversibility is performed by solving for T on both sides of the heat exchanger:

\[h_\text{out} - h_\text{in} = \int_\text{in}^\text{out} v \cdot dp - \int_\text{in}^\text{out} T \cdot ds\]

As solving \(\int_\text{in}^\text{out} v \cdot dp\) for non isobaric processes would require perfect process knowledge (the path) on how specific volume and pressure change throughout the component, the heat transfer is split into three separate virtual processes for both sides:

  • in->in*: decrease pressure to \(p_\text{in*}=p_\text{in}\cdot\sqrt{\frac{p_\text{out}}{p_\text{in}}}\) without changing enthalpy.

  • in*->out* transfer heat without changing pressure. \(h_\text{out*}-h_\text{in*}=h_\text{out}-h_\text{in}\)

  • out*->out decrease pressure to outlet pressure \(p_\text{out}\) without changing enthalpy.

Note

The entropy balance makes the following parameter available:

\[\begin{split}\text{S\_Q1}=\dot{m} \cdot \left(s_\text{out*,1}-s_\text{in*,1} \right)\\ \text{S\_Q2}=\dot{m} \cdot \left(s_\text{out*,2}-s_\text{in*,2} \right)\\ \text{S\_Qirr}=\text{S\_Q2} - \text{S\_Q1}\\ \text{S\_irr1}=\dot{m} \cdot \left(s_\text{out,1}-s_\text{in,1} \right) - \text{S\_Q1}\\ \text{S\_irr2}=\dot{m} \cdot \left(s_\text{out,2}-s_\text{in,2} \right) - \text{S\_Q2}\\ \text{S\_irr}=\sum \dot{S}_\text{irr}\\ \text{T\_mQ1}=\frac{\dot{Q}}{\text{S\_Q1}}\\ \text{T\_mQ2}=\frac{\dot{Q}}{\text{S\_Q2}}\end{split}\]
get_bypass_constraints()[source]
get_mandatory_constraints()[source]
get_parameters()[source]
get_plotting_data()[source]

Generate a dictionary containing FluProDia plotting information.

Returns:

data (dict) – A nested dictionary containing the keywords required by the calc_individual_isoline method of the FluidPropertyDiagram class. First level keys are the connection index (‘in1’ -> ‘out1’, therefore 1 etc.).

initialise_source(c, key)[source]

Return a starting value for pressure and enthalpy at outlet.

Parameters:
  • c (tespy.connections.connection.Connection) – Connection to perform initialisation on.

  • key (str) – Fluid property to retrieve.

Returns:

val (float) – Starting value for pressure/enthalpy in SI units.

initialise_target(c, key)[source]

Return a starting value for pressure and enthalpy at inlet.

Parameters:
  • c (tespy.connections.connection.Connection) – Connection to perform initialisation on.

  • key (str) – Fluid property to retrieve.

Returns:

val (float) – Starting value for pressure/enthalpy in SI units.

static inlets()[source]
static outlets()[source]
ttd_l_dependents()[source]
ttd_l_func()[source]

Equation for lower terminal temperature difference.

Returns:

residual (float) – Residual value of equation.

\[0 = ttd_{l} - T_{out,1} + T_{in,2}\]

ttd_min_dependents()[source]
ttd_min_func()[source]

Equation for minimum terminal temperature difference.

Returns:

residual (float) – Residual value of equation.

\[ttd_{l} = T_{out,1} - T_{in,2} ttd_{u} = T_{in,1} - T_{out,2} 0 = \text{min}\left(ttd_{u}, ttd_{l}\right)\]

ttd_u_dependents()[source]
ttd_u_func()[source]

Equation for upper terminal temperature difference.

Returns:

residual (float) – Residual value of equation.

\[0 = ttd_{u} - T_{in,1} + T_{out,2}\]

tespy.components.heat_exchangers.condenser module

Module of class Condenser.

This file is part of project TESPy (github.com/oemof/tespy). It’s copyrighted by the contributors recorded in the version control history of the file, available from its original location tespy/components/heat_exchangers/condenser.py

SPDX-License-Identifier: MIT

class tespy.components.heat_exchangers.condenser.Condenser(label, **kwargs)[source]

Bases: HeatExchanger

A Condenser cools a fluid until it is in liquid state.

The condensing fluid is cooled by the cold side fluid. The fluid on the hot side of the condenser must be pure. Subcooling is available.

flowsheet of the condenser flowsheet of the condenser

Ports

  • Fluid inlets: in1, in2

  • Fluid outlets: out1, out2

Mandatory Equations

Parameters:
  • char_warnings (bool) – Ignore warnings on default characteristics usage for this component.

  • design (list) – List containing design parameters (stated as String).

  • design_path (str) – Path to the components design case.

  • dp1 (float, dict) – Hot side inlet to outlet absolute pressure change. Quantity: pressure_difference. Equation: dp_structure_matrix.

  • dp2 (float, dict) – Cold side inlet to outlet absolute pressure change. Quantity: pressure_difference. Equation: dp_structure_matrix.

  • eff_cold (float, dict) – Heat exchanger effectiveness for cold side. Quantity: efficiency. Equation: eff_cold_func.

  • eff_hot (float, dict) – Heat exchanger effectiveness for hot side. Quantity: efficiency. Equation: eff_hot_func.

  • eff_max (float, dict) – Maximum heat exchanger effectiveness. Quantity: efficiency. Equation: eff_max_func.

  • kA (float, dict) – Deprecated, use UA instead. Quantity: heat_transfer_coefficient.

  • kA_char (GroupedComponentCharacteristics) – Deprecated, use UA_char instead. Elements: kA_char1, kA_char2.

  • kA_char1 (tespy.tools.characteristics.CharLine, dict) – Deprecated, use UA_char1 instead.

  • kA_char2 (tespy.tools.characteristics.CharLine, dict) – Deprecated, use UA_char2 instead.

  • label (str) – The label of the component.

  • lmtd (float, dict) – Effective logarithmic mean temperature difference |Q|/UA. Quantity: temperature_difference.

  • local_design (bool) – Treat this component in design mode in an offdesign calculation.

  • local_offdesign (bool) – Treat this component in offdesign mode in a design calculation.

  • offdesign (list) – List containing offdesign parameters (stated as String).

  • pr1 (float, dict) – Hot side outlet to inlet pressure ratio. Quantity: ratio. Equation: pr_structure_matrix.

  • pr2 (float, dict) – Cold side outlet to inlet pressure ratio. Quantity: ratio. Equation: pr_structure_matrix.

  • printout (bool) – Include this component in the network’s results printout.

  • Q (float, dict) – Heat transfer from hot side. Quantity: heat. Equation: energy_balance_hot_func.

  • subcooling (bool) – Allow subcooling in the condenser. Equation: subcooling_func.

  • td_log (float, dict) – Deprecated, use lmtd instead. Quantity: temperature_difference.

  • ttd_l (float, dict) – Terminal temperature difference at hot side outlet to cold side inlet. Quantity: temperature_difference. Equation: ttd_l_func.

  • ttd_min (float, dict) – Minimum terminal temperature difference. Quantity: temperature_difference. Equation: ttd_min_func.

  • ttd_u (float, dict) – Terminal temperature difference at hot side inlet to cold side outlet. Quantity: temperature_difference. Equation: ttd_u_func.

  • UA (float, dict) – Heat transfer coefficient considering terminal temperature differences. Quantity: heat_transfer_coefficient. Equation: UA_func.

  • UA_char (GroupedComponentCharacteristics) – Equation for heat transfer based on UA and modification factor. Elements: UA_char1, UA_char2. Equation: UA_char_func.

  • UA_char1 (tespy.tools.characteristics.CharLine, dict) – Hot side UA modification lookup table for offdesign.

  • UA_char2 (tespy.tools.characteristics.CharLine, dict) – Cold side UA modification lookup table for offdesign.

  • zeta1 (float, dict) – Deprecated, use zeta1_d4 instead.

  • zeta1_d4 (float, dict) – Hot side geometry-independent friction coefficient zeta/D^4 for pressure loss calculation. Equation: zeta_d4_func.

  • zeta2 (float, dict) – Deprecated, use zeta2_d4 instead.

  • zeta2_d4 (float, dict) – Cold side geometry-independent friction coefficient zeta/D^4 for pressure loss calculation. Equation: zeta_d4_func.

Notes

Note

The condenser has an additional equation for enthalpy at hot side outlet: The fluid leaves the component in saturated liquid state. If subcooling is activated, it is possible to specify the enthalpy at the outgoing connection manually.

It has a different calculation method for given heat transfer coefficient and upper terminal temperature difference: These parameters refer to the condensing temperature, even if the fluid on the hot side enters the component in superheated state.

Example

Air is used to condensate water in a condenser. 1 kg/s waste steam is chilled with a terminal temperature difference of 15 K.

>>> from tespy.components import Sink, Source, Condenser
>>> from tespy.connections import Connection
>>> from tespy.networks import Network
>>> from tespy.tools.fluid_properties import T_sat_p
>>> nw = Network(m_range=[0.01, 1000], iterinfo=False)
>>> nw.units.set_defaults(**{
...     "pressure": "bar", "pressure_difference": "bar",
...     "temperature": "degC", "enthalpy": "kJ/kg"
... })
>>> amb_in = Source('ambient air inlet')
>>> amb_out = Sink('air outlet')
>>> waste_steam = Source('waste steam')
>>> c = Sink('condensate sink')
>>> cond = Condenser('condenser')
>>> amb_he = Connection(amb_in, 'out1', cond, 'in2')
>>> he_amb = Connection(cond, 'out2', amb_out, 'in1')
>>> ws_he = Connection(waste_steam, 'out1', cond, 'in1')
>>> he_c = Connection(cond, 'out1', c, 'in1')
>>> nw.add_conns(amb_he, he_amb, ws_he, he_c)

The air flow can not be controlled, thus is constant in offdesign operation. If the waste steam mass flow or the ambient air temperature change, the outlet temperature of the air will change, too.

>>> cond.set_attr(pr1=0.98, pr2=0.999, ttd_u=15, design=['pr2', 'ttd_u'],
... offdesign=['zeta2_d4', 'UA_char'])
>>> ws_he.set_attr(fluid={'water': 1}, h=2700, m=1)
>>> amb_he.set_attr(fluid={'air': 1}, T=20, offdesign=['v'])
>>> he_amb.set_attr(p=1, T=40, design=['T'])
>>> nw.solve('design')
>>> design_state = nw.save(as_dict=True)
>>> round(amb_he.v.val, 2)
103.17
>>> round(ws_he.T.val - he_amb.T.val, 1)
66.9
>>> round(ws_he.calc_T_sat() - 273.15 - he_amb.T.val, 1)
15.0
>>> ws_he.set_attr(m=0.7)
>>> amb_he.set_attr(T=30)
>>> nw.solve('offdesign', design_path=design_state)
>>> round(ws_he.T.val - he_amb.T.val, 1)
62.5
>>> round(ws_he.calc_T_sat() - 273.15 - he_amb.T.val, 1)
11.3

It is possible to activate subcooling. The difference to boiling point temperature is specified to 5 K.

>>> cond.set_attr(subcooling=True)
>>> he_c.set_attr(td_bubble=5)
>>> nw.solve('offdesign', design_path=design_state)
>>> round(ws_he.T.val - he_amb.T.val, 1)
62.5
>>> round(ws_he.calc_T_sat() - 273.15 - he_amb.T.val, 1)
13.4
UA_char_func()[source]

Calculate heat transfer from heat transfer coefficient characteristic.

Returns:

residual (float) – Residual value of equation.

\[ \begin{align}\begin{aligned}0 = \dot{m}_{in,1} \cdot \left( h_{out,1} - h_{in,1}\right) + UA_{design} \cdot f_{UA} \cdot \frac{T_{out,1} - T_{in,2} - T_{sat} \left(p_{in,1}\right) + T_{out,2}} {\ln{\frac{T_{out,1} - T_{in,2}} {T_{sat} \left(p_{in,1}\right) - T_{out,2}}}}\\f_{UA} = \frac{2}{\frac{1}{f_1 \left( expr_1\right)} + \frac{1}{f_2 \left( expr_2\right)}}\end{aligned}\end{align} \]

Note

For standard functions f1 and f2 see module tespy.data.

calculate_td_log()[source]

Method to calculate logarithmic temperature difference during iteration. It returns the minimal temperature difference value instead of the logarithmic temperature difference if the minimal temperature difference is negative during iteration to progress in convergence

convergence_check()[source]
get_parameters()[source]
initialise_source(c, key)[source]

Return a starting value for pressure and enthalpy at outlet.

Parameters:
  • c (tespy.connections.connection.Connection) – Connection to perform initialisation on.

  • key (str) – Fluid property to retrieve.

Returns:

val (float) – Starting value for pressure/enthalpy in SI units.

subcooling_dependents()[source]
subcooling_func()[source]

Equation for hot side outlet state.

Returns:

residual (float) – Residual value of equation.

\[0=h_{out,1} -h\left(p_{out,1}, x=0 \right)\]

Note

This equation is applied in case subcooling is False!

ttd_u_dependents()[source]
ttd_u_func()[source]

Equation for upper terminal temperature difference.

Returns:

residual (float) – Residual value of equation.

\[0 = ttd_{u} - T_{sat} \left(p_{in,1}\right) + T_{out,2}\]

Note

The upper terminal temperature difference ttd_u refers to boiling temperature at hot side inlet.

tespy.components.heat_exchangers.desuperheater module

Module of class Desuperheater.

This file is part of project TESPy (github.com/oemof/tespy). It’s copyrighted by the contributors recorded in the version control history of the file, available from its original location tespy/components/heat_exchangers/desuperheater.py

SPDX-License-Identifier: MIT

class tespy.components.heat_exchangers.desuperheater.Desuperheater(label, **kwargs)[source]

Bases: HeatExchanger

The Desuperheater cools a fluid to the saturated gas state.

flowsheet of the desuperheater flowsheet of the desuperheater

Ports

  • Fluid inlets: in1, in2

  • Fluid outlets: out1, out2

Mandatory Equations

Parameters:
  • char_warnings (bool) – Ignore warnings on default characteristics usage for this component.

  • design (list) – List containing design parameters (stated as String).

  • design_path (str) – Path to the components design case.

  • dp1 (float, dict) – Hot side inlet to outlet absolute pressure change. Quantity: pressure_difference. Equation: dp_structure_matrix.

  • dp2 (float, dict) – Cold side inlet to outlet absolute pressure change. Quantity: pressure_difference. Equation: dp_structure_matrix.

  • eff_cold (float, dict) – Heat exchanger effectiveness for cold side. Quantity: efficiency. Equation: eff_cold_func.

  • eff_hot (float, dict) – Heat exchanger effectiveness for hot side. Quantity: efficiency. Equation: eff_hot_func.

  • eff_max (float, dict) – Maximum heat exchanger effectiveness. Quantity: efficiency. Equation: eff_max_func.

  • kA (float, dict) – Deprecated, use UA instead. Quantity: heat_transfer_coefficient.

  • kA_char (GroupedComponentCharacteristics) – Deprecated, use UA_char instead. Elements: kA_char1, kA_char2.

  • kA_char1 (tespy.tools.characteristics.CharLine, dict) – Deprecated, use UA_char1 instead.

  • kA_char2 (tespy.tools.characteristics.CharLine, dict) – Deprecated, use UA_char2 instead.

  • label (str) – The label of the component.

  • lmtd (float, dict) – Effective logarithmic mean temperature difference |Q|/UA. Quantity: temperature_difference.

  • local_design (bool) – Treat this component in design mode in an offdesign calculation.

  • local_offdesign (bool) – Treat this component in offdesign mode in a design calculation.

  • offdesign (list) – List containing offdesign parameters (stated as String).

  • pr1 (float, dict) – Hot side outlet to inlet pressure ratio. Quantity: ratio. Equation: pr_structure_matrix.

  • pr2 (float, dict) – Cold side outlet to inlet pressure ratio. Quantity: ratio. Equation: pr_structure_matrix.

  • printout (bool) – Include this component in the network’s results printout.

  • Q (float, dict) – Heat transfer from hot side. Quantity: heat. Equation: energy_balance_hot_func.

  • td_log (float, dict) – Deprecated, use lmtd instead. Quantity: temperature_difference.

  • ttd_l (float, dict) – Terminal temperature difference at hot side outlet to cold side inlet. Quantity: temperature_difference. Equation: ttd_l_func.

  • ttd_min (float, dict) – Minimum terminal temperature difference. Quantity: temperature_difference. Equation: ttd_min_func.

  • ttd_u (float, dict) – Terminal temperature difference at hot side inlet to cold side outlet. Quantity: temperature_difference. Equation: ttd_u_func.

  • UA (float, dict) – Heat transfer coefficient considering terminal temperature differences. Quantity: heat_transfer_coefficient. Equation: UA_func.

  • UA_char (GroupedComponentCharacteristics) – Equation for heat transfer based on UA and modification factor. Elements: UA_char1, UA_char2. Equation: UA_char_func.

  • UA_char1 (tespy.tools.characteristics.CharLine, dict) – Hot side UA modification lookup table for offdesign.

  • UA_char2 (tespy.tools.characteristics.CharLine, dict) – Cold side UA modification lookup table for offdesign.

  • zeta1 (float, dict) – Deprecated, use zeta1_d4 instead.

  • zeta1_d4 (float, dict) – Hot side geometry-independent friction coefficient zeta/D^4 for pressure loss calculation. Equation: zeta_d4_func.

  • zeta2 (float, dict) – Deprecated, use zeta2_d4 instead.

  • zeta2_d4 (float, dict) – Cold side geometry-independent friction coefficient zeta/D^4 for pressure loss calculation. Equation: zeta_d4_func.

Notes

Note

The desuperheater has an additional equation for enthalpy at hot side outlet: The fluid leaves the component in saturated gas state.

Example

Overheated ethanol is cooled with water in a heat exchanger until it reaches the state of saturated gas.

>>> from tespy.components import Sink, Source, Desuperheater
>>> from tespy.connections import Connection
>>> from tespy.networks import Network
>>> nw = Network(iterinfo=False)
>>> nw.units.set_defaults(**{
...     "pressure": "bar", "pressure_difference": "bar",
...     "temperature": "degC", "enthalpy": "kJ/kg", "volumetric_flow": "l/s"
... })
>>> et_in = Source('ethanol inlet')
>>> et_out = Sink('ethanol outlet')
>>> cw_in = Source('cooling water inlet')
>>> cw_out = Sink('cooling water outlet')
>>> desu = Desuperheater('desuperheater')
>>> et_de = Connection(et_in, 'out1', desu, 'in1')
>>> de_et = Connection(desu, 'out1', et_out, 'in1')
>>> cw_de = Connection(cw_in, 'out1', desu, 'in2')
>>> de_cw = Connection(desu, 'out2', cw_out, 'in1')
>>> nw.add_conns(et_de, de_et, cw_de, de_cw)

The cooling water enters the component at 15 °C. 10 l/s of ethanol is cooled from 100 K above boiling point. The water flow rate is at 1 l/s. Knowing the component’s design parameters it is possible to predict behavior at different inlet temperatures or different volumetric flow of ethanol. Controlling the ethanol’s state at the outlet is only possible, if the cooling water flow rate is adjusted accordingly.

>>> desu.set_attr(
...     pr1=0.99, pr2=0.98, design=['pr1', 'pr2'],
...     offdesign=['zeta1_d4', 'zeta2_d4', 'UA_char']
... )
>>> cw_de.set_attr(fluid={'water': 1}, T=15, v=1, design=['v'])
>>> de_cw.set_attr(p=1)
>>> et_de.set_attr(fluid={'ethanol': 1}, td_dew=100, v=10)
>>> de_et.set_attr(p=1)
>>> nw.solve('design')
>>> design_state = nw.save(as_dict=True)
>>> round(de_cw.T.val, 1)
15.5
>>> round(de_et.x.val, 1)
1.0
>>> et_de.set_attr(v=12)
>>> nw.solve('offdesign', design_path=design_state)
>>> round(cw_de.v.val, 2)
1.94
>>> et_de.set_attr(v=7)
>>> nw.solve('offdesign', init_path=design_state, design_path=design_state)
>>> round(cw_de.v.val, 2)
0.41
get_mandatory_constraints()[source]
initialise_source(c, key)[source]

Return a starting value for pressure and enthalpy at outlet.

Parameters:
  • c (tespy.connections.connection.Connection) – Connection to perform initialisation on.

  • key (str) – Fluid property to retrieve.

Returns:

val (float) – Starting value for pressure/enthalpy in SI units.

saturated_gas_dependents()[source]
saturated_gas_deriv(increment_filter, k, dependents=None)[source]

Partial derivatives of saturated gas at hot side outlet function.

Parameters:
  • increment_filter (ndarray) – Matrix for filtering non-changing variables.

  • k (int) – Position of derivatives in Jacobian matrix (k-th equation).

saturated_gas_func()[source]

Calculate hot side outlet state.

Returns:

residual (float) – Residual value of equation

\[0 = h_{out,1} - h\left(p_{out,1}, x=1 \right)\]

tespy.components.heat_exchangers.movingboundary module

Module of class MovingBoundaryHeatExchanger.

This file is part of project TESPy (github.com/oemof/tespy). It’s copyrighted by the contributors recorded in the version control history of the file, available from its original location tespy/components/heat_exchangers/movingboundary.py

SPDX-License-Identifier: MIT

class tespy.components.heat_exchangers.movingboundary.MovingBoundaryHeatExchanger(label, **kwargs)[source]

Bases: SectionedHeatExchanger

Class for counter flow heat exchanger with UA sections.

The heat exchanger is internally discretized into multiple sections, which are defined by phase changes. The component assumes, that a pressure drop is linear to the change in enthalpy, meaning the phase boundary identification is done iteratively. In principle the implementations follows [34].

flowsheet of the movingboundaryheatexchanger flowsheet of the movingboundaryheatexchanger

Ports

  • Fluid inlets: in1, in2

  • Fluid outlets: out1, out2

Mandatory Equations

Parameters:
  • alpha_ratio (float, dict) – Secondary to refrigerant side convective heat transfer coefficient ratio. Quantity: ratio.

  • area_ratio (float, dict) – Secondary to refrigerant side heat transfer area ratio. Quantity: ratio.

  • char_warnings (bool) – Ignore warnings on default characteristics usage for this component.

  • design (list) – List containing design parameters (stated as String).

  • design_path (str) – Path to the components design case.

  • dp1 (float, dict) – Hot side inlet to outlet absolute pressure change. Quantity: pressure_difference. Equation: dp_structure_matrix.

  • dp2 (float, dict) – Cold side inlet to outlet absolute pressure change. Quantity: pressure_difference. Equation: dp_structure_matrix.

  • eff_cold (float, dict) – Heat exchanger effectiveness for cold side. Quantity: efficiency. Equation: eff_cold_func.

  • eff_hot (float, dict) – Heat exchanger effectiveness for hot side. Quantity: efficiency. Equation: eff_hot_func.

  • eff_max (float, dict) – Maximum heat exchanger effectiveness. Quantity: efficiency. Equation: eff_max_func.

  • kA (float, dict) – Deprecated, use UA instead. Quantity: heat_transfer_coefficient.

  • kA_char (GroupedComponentCharacteristics) – Deprecated, use UA_char instead. Elements: kA_char1, kA_char2.

  • kA_char1 (tespy.tools.characteristics.CharLine, dict) – Deprecated, use UA_char1 instead.

  • kA_char2 (tespy.tools.characteristics.CharLine, dict) – Deprecated, use UA_char2 instead.

  • label (str) – The label of the component.

  • lmtd (float, dict) – Effective logarithmic mean temperature difference |Q|/UA. Quantity: temperature_difference.

  • local_design (bool) – Treat this component in design mode in an offdesign calculation.

  • local_offdesign (bool) – Treat this component in offdesign mode in a design calculation.

  • offdesign (list) – List containing offdesign parameters (stated as String).

  • pr1 (float, dict) – Hot side outlet to inlet pressure ratio. Quantity: ratio. Equation: pr_structure_matrix.

  • pr2 (float, dict) – Cold side outlet to inlet pressure ratio. Quantity: ratio. Equation: pr_structure_matrix.

  • printout (bool) – Include this component in the network’s results printout.

  • Q (float, dict) – Heat transfer from hot side. Quantity: heat. Equation: energy_balance_hot_func.

  • re_exp_r (float, dict) – Reynolds exponent for UA modification based on refrigerant side mass flow.

  • re_exp_sf (float, dict) – Reynolds exponent for UA modification based on secondary fluid side mass flow.

  • refrigerant_index (int) – Side on which the refrigerant is flowing (0: hot, 1:cold).

  • td_log (float, dict) – Deprecated, use lmtd instead. Quantity: temperature_difference.

  • td_pinch (float, dict) – Equation for minimum pinch. Quantity: temperature_difference. Equation: td_pinch_func.

  • ttd_l (float, dict) – Terminal temperature difference at hot side outlet to cold side inlet. Quantity: temperature_difference. Equation: ttd_l_func.

  • ttd_min (float, dict) – Minimum terminal temperature difference. Quantity: temperature_difference. Equation: ttd_min_func.

  • ttd_u (float, dict) – Terminal temperature difference at hot side inlet to cold side outlet. Quantity: temperature_difference. Equation: ttd_u_func.

  • UA (float, dict) – Sum of UA values of all sections of heat exchanger. Quantity: heat_transfer_coefficient. Equation: UA_func.

  • UA_cecchinato (GroupedComponentProperties) – Equation for UA modification in offdesign. Elements: re_exp_r, re_exp_sf, alpha_ratio, area_ratio. Equation: UA_cecchinato_func.

  • UA_char (GroupedComponentCharacteristics) – Equation for sectioned UA modification based on characteristic lines. Elements: UA_char1, UA_char2. Equation: UA_char_func.

  • UA_char1 (tespy.tools.characteristics.CharLine, dict) – Hot side UA modification lookup table for offdesign.

  • UA_char2 (tespy.tools.characteristics.CharLine, dict) – Cold side UA modification lookup table for offdesign.

  • zeta1 (float, dict) – Deprecated, use zeta1_d4 instead.

  • zeta1_d4 (float, dict) – Hot side geometry-independent friction coefficient zeta/D^4 for pressure loss calculation. Equation: zeta_d4_func.

  • zeta2 (float, dict) – Deprecated, use zeta2_d4 instead.

  • zeta2_d4 (float, dict) – Cold side geometry-independent friction coefficient zeta/D^4 for pressure loss calculation. Equation: zeta_d4_func.

Notes

Note

The equations only apply to counter-current heat exchangers.

Example

Water vapor should be cooled down, condensed and then further subcooled. For this air is heated up from 15 °C to 25 °C.

>>> from tespy.components import Source, Sink, MovingBoundaryHeatExchanger
>>> from tespy.connections import Connection
>>> from tespy.networks import Network
>>> import numpy as np
>>> nw = Network()
>>> nw.units.set_defaults(**{
...     "pressure": "bar", "pressure_difference": "bar",
...     "temperature": "degC"
... })
>>> nw.iterinfo = False
>>> so1 = Source("vapor source")
>>> so2 = Source("air source")
>>> cd = MovingBoundaryHeatExchanger("condenser")
>>> si1 = Sink("water sink")
>>> si2 = Sink("air sink")
>>> c1 = Connection(so1, "out1", cd, "in1", label="1")
>>> c2 = Connection(cd, "out1", si1, "in1", label="2")
>>> c11 = Connection(so2, "out1", cd, "in2", label="11")
>>> c12 = Connection(cd, "out2", si2, "in1", label="12")
>>> nw.add_conns(c1, c2, c11, c12)

To generate good guess values, first we run the simulation with fixed pressure on the water side. The water enters at superheated vapor state with 15 °C superheating and leaves it with 10 °C subcooling.

>>> c1.set_attr(fluid={"Water": 1}, p=1, td_dew=15, m=1)
>>> c2.set_attr(td_bubble=15)
>>> c11.set_attr(fluid={"Air": 1}, p=1, T=15)
>>> c12.set_attr(T=25)
>>> cd.set_attr(pr1=1, pr2=1)
>>> nw.solve("design")

Now we can remove the pressure specifications on the air side and impose the minimum pinch instead, which will determine the actual water condensation pressure.

>>> c1.set_attr(p=None)
>>> cd.set_attr(td_pinch=5)
>>> nw.solve("design")
>>> round(c1.p.val, 3)
0.056
>>> round(c1.T.val, 1)
50.0

We can also see the temperature differences in all sections of the heat exchanger. Since the water vapor is cooled, condensed and then subcooled, while the air does not change phase, three sections will form:

>>> Q_sections, T_steps_hot, T_steps_cold, Q_per_section, td_log_per_section = cd.calc_sections()
>>> delta_T_between_sections = T_steps_hot - T_steps_cold
>>> [round(float(dT), 2) for dT in delta_T_between_sections]
[5.0, 19.75, 10.11, 25.0]

We can see that the lowest delta T is the first one. This is the delta T between the hot side outlet and the cold side inlet, which can also be seen if we have a look at the network’s results.

>>> ();nw.print_results();()
(...)

If we change the subcooling degree at the water outlet, the condensation pressure and pinch will move.

>>> c2.set_attr(td_bubble=5)
>>> nw.solve("design")
>>> round(c1.p.val, 3)
0.042
>>> Q_sections, T_steps_hot, T_steps_cold, Q_per_section, td_log_per_section = cd.calc_sections()
>>> delta_T_between_sections = T_steps_hot - T_steps_cold
>>> [round(float(dT), 2) for dT in delta_T_between_sections]
[9.88, 14.8, 5.0, 19.88]

Finally, in contrast to the baseclass HeatExchanger kA value, the UA value takes into account the heat transfer per section and calculates the heat transfer coefficient as the sum of all sections, while the kA value only takes into account the inlet and outlet temperatures and the total heat transfer.

>>> round(cd.kA.val)
173307
>>> round(cd.UA.val)
273449

It is also possible to apply a partload modification to UA following the implementation of [21]. For this you have to specify UA_cecchinato as offdesign parameter and along with it, values for

  • refrigerant side Reynolds exponent

  • secondary fluid side Reynolds exponent

  • secondary fluid to refrigerant area ratio

  • secondary fluid to refrigerant alpha (heat transfer coefficient) ratio

  • the refrigerant index (which side of the heat exchanger is passed by the refrigerant)

>>> design_state = nw.save(as_dict=True)
>>> cd.set_attr(
...     area_ratio=20,        # typical for a finned heat exchanger
...     alpha_ratio=1e-2,     # alpha for water side is higher
...     re_exp_r=0.8,
...     re_exp_sf=0.55,
...     refrigerant_index=0,  # water is refrigerant in this case
...     design=["td_pinch"],
...     offdesign=["UA_cecchinato"]
... )
>>> nw.solve("offdesign", design_path=design_state)

Without modifying any parameter, pinch and UA should be identical to design conditions.

>>> round(cd.td_pinch.val, 2)
5.0
>>> round(cd.UA.val)
273449

With change in operating conditions, e.g. reduction of heat transfer we’d typically observe lower pinch, if the heat transfer reduces faster than the UA value does.

>>> c1.set_attr(m=0.8)
>>> nw.solve("offdesign", design_path=design_state)
>>> round(cd.Q.val_SI / cd.Q.design, 2)
0.8
>>> round(cd.UA.val_SI / cd.UA.design, 2)
0.88
>>> round(cd.td_pinch.val, 2)
4.3
get_parameters()[source]

tespy.components.heat_exchangers.parabolic_trough module

Module of class ParabolicTrough.

This file is part of project TESPy (github.com/oemof/tespy). It’s copyrighted by the contributors recorded in the version control history of the file, available from its original location tespy/components/heat_exchangers/parabolic_trough.py

SPDX-License-Identifier: MIT

class tespy.components.heat_exchangers.parabolic_trough.ParabolicTrough(label, **kwargs)[source]

Bases: SimpleHeatExchanger

The ParabolicTrough calculates heat output from irradiance.

flowsheet of the parabolictrough flowsheet of the parabolictrough

Ports

  • Fluid inlets: in1

  • Fluid outlets: out1

  • Power inlets: heat

  • Power outlets: heat

  • Heat inlets: heat

  • Heat outlets: heat

Mandatory Equations

When a power or heat connector is attached:

Parameters:
  • A (float, dict, "var") – Area of the parabolic trough. Quantity: area. Can be set as a system variable by passing "var" as its value.

  • aoi (float, dict) – Angle of incidence. Quantity: angle.

  • c_1 (float, dict) – Thermal loss coefficient 1.

  • c_2 (float, dict) – Thermal loss coefficient 2.

  • char_warnings (bool) – Ignore warnings on default characteristics usage for this component.

  • D (float, dict, "var") – Diameter of channel. Quantity: length. Can be set as a system variable by passing "var" as its value.

  • darcy_group (GroupedComponentProperties) – Darcy-Weißbach equation for pressure loss. Elements: L, ks, D. Equation: darcy_func.

  • design (list) – List containing design parameters (stated as String).

  • design_path (str) – Path to the components design case.

  • dissipative (bool) – Description missing.

  • doc (float, dict) – Degree of cleanliness. Quantity: ratio.

  • dp (float, dict) – Inlet to outlet absolute pressure change. Quantity: pressure_difference. Equation: dp_structure_matrix.

  • E (float, dict, "var") – Solar irradiation to the parabolic trough. Quantity: heat. Can be set as a system variable by passing "var" as its value.

  • energy_group (GroupedComponentProperties) – Energy balance equation of the parabolic trough. Elements: E, eta_opt, aoi, doc, c_1, c_2, iam_1, iam_2, A, Tamb. Equation: energy_group_func.

  • eta_opt (float, dict) – Optical efficiency. Quantity: efficiency.

  • hw_group (GroupedComponentProperties) – Hazen-Williams equation for pressure loss. Elements: L, ks_HW, D. Equation: hazen_williams_func.

  • iam_1 (float, dict) – Incidence angle modifier 1.

  • iam_2 (float, dict) – Incidence angle modifier 2.

  • ks (float, dict, "var") – Roughness of wall material. Quantity: length. Can be set as a system variable by passing "var" as its value.

  • ks_HW (float, dict, "var") – Hazen-Williams roughness. Can be set as a system variable by passing "var" as its value.

  • L (float, dict, "var") – Length of channel. Quantity: length. Can be set as a system variable by passing "var" as its value.

  • label (str) – The label of the component.

  • local_design (bool) – Treat this component in design mode in an offdesign calculation.

  • local_offdesign (bool) – Treat this component in offdesign mode in a design calculation.

  • offdesign (list) – List containing offdesign parameters (stated as String).

  • power_connector_location (str) – Description missing.

  • pr (float, dict) – Outlet to inlet pressure ratio. Quantity: ratio. Equation: pr_structure_matrix.

  • printout (bool) – Include this component in the network’s results printout.

  • Q (float, dict) – Heat transfer. Quantity: heat. Equation: energy_balance_func.

  • Q_loss (float, dict) – Heat dissipation. Quantity: heat.

  • Tamb (float, dict) – Ambient temperature. Quantity: temperature.

  • zeta (float, dict) – Deprecated, use zeta_d4 instead.

  • zeta_d4 (float, dict) – Geometry-independent friction coefficient zeta/D^4 for pressure loss calculation. Equation: zeta_d4_func.

Example

A parabolic trough is installed using S800 as thermo-fluid. First, the operation conditions from [35] are reproduced. Therefore, the direct normal irradiance \(\dot{E}_\text{DNI}\) is at 1000 \(\frac{\text{W}}{\text{m}^2}\) at an angle of incidence \(aoi\) at 20 °. This means, the direct irradiance to the parabolic trough \(E\) is at \(\dot{E}_{DNI} \cdot cos\left(20^\circ\right)\).

>>> from tespy.components import Sink, Source, ParabolicTrough
>>> from tespy.connections import Connection
>>> from tespy.networks import Network
>>> import math
>>> nw = Network(iterinfo=False)
>>> nw.units.set_defaults(**{
...     "pressure": "bar", "pressure_difference": "bar",
...     "temperature": "degC", "enthalpy": "kJ/kg"
... })
>>> so = Source('source')
>>> si = Sink('sink')
>>> pt = ParabolicTrough('parabolic trough collector')
>>> inc = Connection(so, 'out1', pt, 'in1')
>>> outg = Connection(pt, 'out1', si, 'in1')
>>> nw.add_conns(inc, outg)

The pressure ratio is at a constant level of 1. However, it is possible to specify the pressure losses from the absorber tube length, roughness and diameter, too. The aperture surface \(A\) is specified to 1 \(\text{m}^2\) for simplicity reasons.

>>> aoi = 20
>>> E = 1000 * math.cos(aoi / 180 * math.pi)
>>> 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={'INCOMP::S800': 1}, T=220, p=10)
>>> outg.set_attr(T=260)
>>> nw.solve('design')
>>> round(pt.Q.val, 0)
736.0

For example, it is possible to calculate the aperture area of the parabolic trough given the total heat production, outflow temperature and mass flow.

>>> pt.set_attr(A='var', Q=5e6, Tamb=25)
>>> inc.set_attr(T=None)
>>> outg.set_attr(T=350, m=20)
>>> nw.solve('design')
>>> round(inc.T.val, 0)
229.0
>>> round(pt.A.val, 0)
6862.0

Given this design, it is possible to calculate the outlet temperature as well as the heat transfer at different operating points.

>>> aoi = 30
>>> E = 800 * math.cos(aoi / 180 * math.pi)
>>> pt.set_attr(A=pt.A.val, aoi=aoi, Q=None, E=E)
>>> inc.set_attr(T=150)
>>> outg.set_attr(T=None)
>>> nw.solve('design')
>>> round(outg.T.val, 0)
244.0
>>> round(pt.Q.val, 0)
3602817.0
calc_parameters()[source]

Postprocessing parameter calculation.

convergence_check()[source]
energy_group_dependents()[source]
energy_group_func()[source]

Equation for solar collector energy balance.

Returns:

residual (float) – Residual value of equation.

\[\begin{split}\begin{split} T_m = & \frac{T_{out} + T_{in}}{2}\\ iam = & 1 - iam_1 \cdot |aoi| - iam_2 \cdot aoi^2\\ 0 = & \dot{m} \cdot \left( h_{out} - h_{in} \right)\\ & - A \cdot \left[E \cdot \eta_{opt} \cdot doc^{1.5} \cdot iam \right. \\ & \left. - c_1 \cdot \left(T_m - T_{amb} \right) - c_2 \cdot \left(T_m - T_{amb}\right)^2 \vphantom{ \eta_{opt} \cdot doc^{1.5}} \right] \end{split}\end{split}\]

Reference: [35].

get_parameters()[source]

tespy.components.heat_exchangers.parallel module

Module of class ParallelFlowHeatExchanger.

This file is part of project TESPy (github.com/oemof/tespy). It’s copyrighted by the contributors recorded in the version control history of the file, available from its original location tespy/components/heat_exchangers/parallel.py

SPDX-License-Identifier: MIT

class tespy.components.heat_exchangers.parallel.ParallelFlowHeatExchanger(label, **kwargs)[source]

Bases: HeatExchanger

Class for parallel flow heat exchanger.

flowsheet of the parallelflowheatexchanger flowsheet of the parallelflowheatexchanger

Ports

  • Fluid inlets: in1, in2

  • Fluid outlets: out1, out2

Mandatory Equations

Parameters:
  • char_warnings (bool) – Ignore warnings on default characteristics usage for this component.

  • design (list) – List containing design parameters (stated as String).

  • design_path (str) – Path to the components design case.

  • dp1 (float, dict) – Hot side inlet to outlet absolute pressure change. Quantity: pressure_difference. Equation: dp_structure_matrix.

  • dp2 (float, dict) – Cold side inlet to outlet absolute pressure change. Quantity: pressure_difference. Equation: dp_structure_matrix.

  • kA (float, dict) – Deprecated, use UA instead. Quantity: heat_transfer_coefficient.

  • kA_char (GroupedComponentCharacteristics) – Deprecated, use UA_char instead. Elements: kA_char1, kA_char2.

  • kA_char1 (tespy.tools.characteristics.CharLine, dict) – Deprecated, use UA_char1 instead.

  • kA_char2 (tespy.tools.characteristics.CharLine, dict) – Deprecated, use UA_char2 instead.

  • label (str) – The label of the component.

  • lmtd (float, dict) – Effective logarithmic mean temperature difference |Q|/UA. Quantity: temperature_difference.

  • local_design (bool) – Treat this component in design mode in an offdesign calculation.

  • local_offdesign (bool) – Treat this component in offdesign mode in a design calculation.

  • offdesign (list) – List containing offdesign parameters (stated as String).

  • pr1 (float, dict) – Hot side outlet to inlet pressure ratio. Quantity: ratio. Equation: pr_structure_matrix.

  • pr2 (float, dict) – Cold side outlet to inlet pressure ratio. Quantity: ratio. Equation: pr_structure_matrix.

  • printout (bool) – Include this component in the network’s results printout.

  • Q (float, dict) – Heat transfer from hot side. Quantity: heat. Equation: energy_balance_hot_func.

  • td_log (float, dict) – Deprecated, use lmtd instead. Quantity: temperature_difference.

  • ttd_l (float, dict) – Terminal temperature difference at hot side outlet to cold side inlet. Quantity: temperature_difference. Equation: ttd_l_func.

  • ttd_u (float, dict) – Terminal temperature difference at hot side inlet to cold side outlet. Quantity: temperature_difference. Equation: ttd_u_func.

  • UA (float, dict) – Heat transfer coefficient considering terminal temperature differences. Quantity: heat_transfer_coefficient. Equation: UA_func.

  • UA_char (GroupedComponentCharacteristics) – Equation for heat transfer based on UA and modification factor. Elements: UA_char1, UA_char2. Equation: UA_char_func.

  • UA_char1 (tespy.tools.characteristics.CharLine, dict) – Hot side UA modification lookup table for offdesign.

  • UA_char2 (tespy.tools.characteristics.CharLine, dict) – Cold side UA modification lookup table for offdesign.

  • zeta1 (float, dict) – Deprecated, use zeta1_d4 instead.

  • zeta1_d4 (float, dict) – Hot side geometry-independent friction coefficient zeta/D^4 for pressure loss calculation. Equation: zeta_d4_func.

  • zeta2 (float, dict) – Deprecated, use zeta2_d4 instead.

  • zeta2_d4 (float, dict) – Cold side geometry-independent friction coefficient zeta/D^4 for pressure loss calculation. Equation: zeta_d4_func.

Notes

Note

The ParallelFlowHeatExchanger implements parallel flow of both streams, meaning the streams enter with a high temperature difference and then gradually reduce their temperature difference to each other. The initial temperature difference is the maximum temperature difference, the final temperature difference is the minimum temperature difference.

Example

Water at 75 °C is used to heat up an air stream 2500 l/s from 10 °C to 35 °C.

>>> from tespy.components import Sink, Source, ParallelFlowHeatExchanger
>>> from tespy.connections import Connection
>>> from tespy.networks import Network
>>> nw = Network(iterinfo=False)
>>> nw.units.set_defaults(**{
...     "pressure": "bar", "pressure_difference": "bar",
...     "temperature": "degC", "enthalpy": "kJ/kg",
...     "volumetric_flow": "l/s", "heat_transfer_coefficient": "kW/K"
... })
>>> feed_water = Source("Feed water inlet")
>>> return_water = Sink("Water outlet")
>>> air_inlet = Source("Fresh air inlet")
>>> air_warm = Sink("Air outlet")
>>> he = ParallelFlowHeatExchanger("heat exchanger")
>>> c1 = Connection(feed_water, 'out1', he, 'in1')
>>> c2 = Connection(he, 'out1', return_water, 'in1')
>>> c3 = Connection(air_inlet, 'out1', he, 'in2')
>>> c4 = Connection(he, 'out2', air_warm, 'in1')
>>> nw.add_conns(c1, c2, c3, c4)

We assume pressure losses of 10 mbar on the air side, and 100 mbar on the water side. Depending on our specifications we can calculate:

  • What is the temperature of the water leaving the heat exchanger, or

  • What is the required mass flow of water to heat up the air

Let’s first assume, that a final pinch ttd_u of 7.5 K is desired, meaning, the water should leave the heat exchanger with a temperature higher than the air by 7.5 K. With that, we will get the water flow, and also the heat transfer coefficient kA as a result.

Note

Note, that for specification of initial or final pinch temperature differences, it is often important to start the calculation with a good initial guess. In this case, we know that the water will be in liquid state, therefore we can

  • either specify the outlet enthalpy initial guess to be liquid,

  • the state at the water outlet to be "l",

  • or use "INCOMP::Water" as fluid, since this uses liquid phase only.

>>> he.set_attr(dp1=0.1, dp2=0.01, ttd_u=7.5)
>>> c1.set_attr(fluid={"INCOMP::Water": 1}, T=70, p=1.3)
>>> c3.set_attr(fluid={"air": 1}, T=10, p=1.02, v=2500)
>>> c4.set_attr(T=35)
>>> nw.solve("design")
>>> round(c1.v.val, 2)
0.7
>>> round(he.kA.val, 2)
3.13

Now, it might be interesting to see what happens under different operation conditions after we have designed the system. For that, we can assume that the heat transfer coefficient is constant. First we just fix the UA value instead of the final pinch and then resolve again.

>>> he.set_attr(design=["ttd_u"], offdesign=["UA"])
>>> design_state = nw.save(as_dict=True)
>>> nw.solve("offdesign", design_path=design_state)
>>> round(he.UA.val_SI / he.UA.design, 1)
1.0

Now, let’s see what happens under different operating conditions. First we change the air volumetric flow, then we change the air temperature to check what happens to the outflow temperature of the water.

>>> c3.set_attr(v=2000)
>>> nw.solve("offdesign", design_path=design_state)
>>> round(c2.T.val, 2)
38.69
>>> c3.set_attr(v=2500, T=8)
>>> nw.solve("offdesign", design_path=design_state)
>>> round(c2.T.val, 2)
44.0
calculate_td_log()[source]

Method to calculate logarithmic temperature difference during iteration. It returns the minimal temperature difference value instead of the logarithmic temperature difference if the minimal temperature difference is negative during iteration to progress in convergence

get_parameters()[source]
ttd_l_dependents()[source]
ttd_l_func()[source]

Equation for lower terminal temperature difference.

Returns:

residual (float) – Residual value of equation.

\[0 = ttd_{l} - T_{out,1} + T_{in,2}\]

ttd_u_dependents()[source]
ttd_u_func()[source]

Equation for upper terminal temperature difference.

Returns:

residual (float) – Residual value of equation.

\[0 = ttd_{u} - T_{in,1} + T_{out,2}\]

tespy.components.heat_exchangers.sectioned module

Module of class SectionedHeatExchanger.

This file is part of project TESPy (github.com/oemof/tespy). It’s copyrighted by the contributors recorded in the version control history of the file, available from its original location tespy/components/heat_exchangers/sectioned.py

SPDX-License-Identifier: MIT

class tespy.components.heat_exchangers.sectioned.SectionedHeatExchanger(label, **kwargs)[source]

Bases: HeatExchanger

Class for counter flow heat exchanger with UA sections.

The heat exchanger is internally discretized into 51 sections of equal heat transfer. The number of section can be adjusted by the user. It is based a combination of the moving boundary approach by [34] and discretization in [36].

flowsheet of the sectionedheatexchanger flowsheet of the sectionedheatexchanger

Ports

  • Fluid inlets: in1, in2

  • Fluid outlets: out1, out2

Mandatory Equations

Parameters:
  • alpha_ratio (float, dict) – Secondary to refrigerant side convective heat transfer coefficient ratio. Quantity: ratio.

  • area_ratio (float, dict) – Secondary to refrigerant side heat transfer area ratio. Quantity: ratio.

  • char_warnings (bool) – Ignore warnings on default characteristics usage for this component.

  • design (list) – List containing design parameters (stated as String).

  • design_path (str) – Path to the components design case.

  • dp1 (float, dict) – Hot side inlet to outlet absolute pressure change. Quantity: pressure_difference. Equation: dp_structure_matrix.

  • dp2 (float, dict) – Cold side inlet to outlet absolute pressure change. Quantity: pressure_difference. Equation: dp_structure_matrix.

  • eff_cold (float, dict) – Heat exchanger effectiveness for cold side. Quantity: efficiency. Equation: eff_cold_func.

  • eff_hot (float, dict) – Heat exchanger effectiveness for hot side. Quantity: efficiency. Equation: eff_hot_func.

  • eff_max (float, dict) – Maximum heat exchanger effectiveness. Quantity: efficiency. Equation: eff_max_func.

  • kA (float, dict) – Deprecated, use UA instead. Quantity: heat_transfer_coefficient.

  • kA_char (GroupedComponentCharacteristics) – Deprecated, use UA_char instead. Elements: kA_char1, kA_char2.

  • kA_char1 (tespy.tools.characteristics.CharLine, dict) – Deprecated, use UA_char1 instead.

  • kA_char2 (tespy.tools.characteristics.CharLine, dict) – Deprecated, use UA_char2 instead.

  • label (str) – The label of the component.

  • lmtd (float, dict) – Effective logarithmic mean temperature difference |Q|/UA. Quantity: temperature_difference.

  • local_design (bool) – Treat this component in design mode in an offdesign calculation.

  • local_offdesign (bool) – Treat this component in offdesign mode in a design calculation.

  • num_sections (int) – Number of sections of the heat exchanger.

  • offdesign (list) – List containing offdesign parameters (stated as String).

  • pr1 (float, dict) – Hot side outlet to inlet pressure ratio. Quantity: ratio. Equation: pr_structure_matrix.

  • pr2 (float, dict) – Cold side outlet to inlet pressure ratio. Quantity: ratio. Equation: pr_structure_matrix.

  • printout (bool) – Include this component in the network’s results printout.

  • Q (float, dict) – Heat transfer from hot side. Quantity: heat. Equation: energy_balance_hot_func.

  • re_exp_r (float, dict) – Reynolds exponent for UA modification based on refrigerant side mass flow.

  • re_exp_sf (float, dict) – Reynolds exponent for UA modification based on secondary fluid side mass flow.

  • refrigerant_index (int) – Side on which the refrigerant is flowing (0: hot, 1:cold).

  • td_log (float, dict) – Deprecated, use lmtd instead. Quantity: temperature_difference.

  • td_pinch (float, dict) – Equation for minimum pinch. Quantity: temperature_difference. Equation: td_pinch_func.

  • ttd_l (float, dict) – Terminal temperature difference at hot side outlet to cold side inlet. Quantity: temperature_difference. Equation: ttd_l_func.

  • ttd_min (float, dict) – Minimum terminal temperature difference. Quantity: temperature_difference. Equation: ttd_min_func.

  • ttd_u (float, dict) – Terminal temperature difference at hot side inlet to cold side outlet. Quantity: temperature_difference. Equation: ttd_u_func.

  • UA (float, dict) – Sum of UA values of all sections of heat exchanger. Quantity: heat_transfer_coefficient. Equation: UA_func.

  • UA_cecchinato (GroupedComponentProperties) – Equation for UA modification in offdesign. Elements: re_exp_r, re_exp_sf, alpha_ratio, area_ratio. Equation: UA_cecchinato_func.

  • UA_char (GroupedComponentCharacteristics) – Equation for sectioned UA modification based on characteristic lines. Elements: UA_char1, UA_char2. Equation: UA_char_func.

  • UA_char1 (tespy.tools.characteristics.CharLine, dict) – Hot side UA modification lookup table for offdesign.

  • UA_char2 (tespy.tools.characteristics.CharLine, dict) – Cold side UA modification lookup table for offdesign.

  • zeta1 (float, dict) – Deprecated, use zeta1_d4 instead.

  • zeta1_d4 (float, dict) – Hot side geometry-independent friction coefficient zeta/D^4 for pressure loss calculation. Equation: zeta_d4_func.

  • zeta2 (float, dict) – Deprecated, use zeta2_d4 instead.

  • zeta2_d4 (float, dict) – Cold side geometry-independent friction coefficient zeta/D^4 for pressure loss calculation. Equation: zeta_d4_func.

Notes

Note

The equations only apply to counter-current heat exchangers.

Example

Water vapor should be cooled down, condensed and then further subcooled. For this, air is heated up from 15 °C to 25 °C.

>>> from tespy.components import Source, Sink, SectionedHeatExchanger
>>> from tespy.connections import Connection
>>> from tespy.networks import Network
>>> import numpy as np
>>> nw = Network()
>>> nw.units.set_defaults(**{
...     "pressure": "bar", "pressure_difference": "bar",
...     "temperature": "degC"
... })
>>> nw.iterinfo = False
>>> so1 = Source("vapor source")
>>> so2 = Source("air source")
>>> cd = SectionedHeatExchanger("condenser")
>>> si1 = Sink("water sink")
>>> si2 = Sink("air sink")
>>> c1 = Connection(so1, "out1", cd, "in1", label="1")
>>> c2 = Connection(cd, "out1", si1, "in1", label="2")
>>> c11 = Connection(so2, "out1", cd, "in2", label="11")
>>> c12 = Connection(cd, "out2", si2, "in1", label="12")
>>> nw.add_conns(c1, c2, c11, c12)

To generate good guess values, first we run the simulation with fixed pressure on the water side. The water enters at superheated vapor state with 15 °C superheating and leaves it with 10 °C subcooling.

>>> c1.set_attr(fluid={"Water": 1}, td_dew=15, m=1)
>>> c2.set_attr(td_bubble=15, p=1)
>>> c11.set_attr(fluid={"Air": 1}, T=15)
>>> c12.set_attr(T=25, p=1)
>>> cd.set_attr(dp1=0.0, dp2=0.0)
>>> nw.solve("design")

Now we can remove the pressure specifications on the air side and impose the minimum pinch instead, which will determine the actual water condensation pressure.

>>> c2.set_attr(p=None)
>>> cd.set_attr(td_pinch=5)
>>> nw.solve("design")
>>> round(c1.p.val, 3)
0.056
>>> round(c1.T.val, 1)
50.0

We can also see the temperature differences in all sections of the heat exchanger. Since the water vapor is cooled, condensed and then subcooled, while the air does not change phase, three sections will form:

>>> Q_sections, T_steps_hot, T_steps_cold, Q_per_section, td_log_per_section = cd.calc_sections()
>>> delta_T_between_sections = T_steps_hot - T_steps_cold
>>> delta_T_list = [round(float(dT), 2) for dT in delta_T_between_sections]
>>> delta_T_list[:6]
[5.0, 16.8, 19.75, 19.6, 19.4, 19.2]

We can see that the lowest delta T is the first one. This is the delta T between the hot side outlet and the cold side inlet, which can also be seen if we have a look at the network’s results.

>>> ();nw.print_results();()
(...)

If we change the subcooling degree at the water outlet, the condensation pressure and pinch will move.

>>> c2.set_attr(td_bubble=5)
>>> nw.solve("design")
>>> round(c1.p.val, 3)
0.042
>>> Q_sections, T_steps_hot, T_steps_cold, Q_per_section, td_log_per_section = cd.calc_sections()
>>> delta_T_between_sections = T_steps_hot - T_steps_cold
>>> delta_T_list = [round(float(dT), 2) for dT in delta_T_between_sections]
>>> delta_T_list[:6]
[9.88, 14.8, 14.68, 14.48, 14.28, 14.08]

Finally, in contrast to the baseclass HeatExchanger kA value, the UA value takes into account the heat transfer per section and calculates the heat transfer coefficient as the sum of all sections, while the kA value only takes into account the inlet and outlet temperatures and the total heat transfer.

>>> round(cd.kA.val)
173307
>>> round(cd.UA.val)
273456

It is also possible to apply a part-load modification to UA following the implementation of [21]. For this you have to specify UA_cecchinato as offdesign parameter and along with it, values for

  • refrigerant side Reynolds exponent

  • secondary fluid side Reynolds exponent

  • secondary fluid to refrigerant area ratio

  • secondary fluid to refrigerant alpha (heat transfer coefficient) ratio

  • the refrigerant index (which side of the heat exchanger is passed by the refrigerant)

>>> design_state = nw.save(as_dict=True)
>>> cd.set_attr(
...     area_ratio=20,        # typical for a finned heat exchanger
...     alpha_ratio=1e-2,     # alpha for water side is higher
...     re_exp_r=0.8,
...     re_exp_sf=0.55,
...     refrigerant_index=0,  # water is refrigerant in this case
...     design=["td_pinch"],
...     offdesign=["UA_cecchinato"]
... )
>>> nw.solve("offdesign", design_path=design_state)

Without modifying any parameter, pinch and UA should be identical to design conditions.

>>> round(cd.td_pinch.val, 2)
5.0
>>> round(cd.UA.val)
273456

With change in operating conditions, e.g. reduction of heat transfer we’d typically observe lower pinch, if the heat transfer reduces faster than the UA value does.

>>> c1.set_attr(m=0.8)
>>> nw.solve("offdesign", design_path=design_state)
>>> round(cd.Q.val_SI / cd.Q.design, 2)
0.8
>>> round(cd.UA.val_SI / cd.UA.design, 2)
0.88
>>> round(cd.td_pinch.val, 2)
4.3

Second Example

A transcritical gas cooler designed to cool CO2 from 160°C to approximately 50°C while water is heated from 10°C to 60°C. The heat exchanger uses characteristic lines (kA_char1 and kA_char2) to scale the heat transfer coefficient in offdesign operation as mass flow varies.

This two-stage approach improves convergence:

  • Stage 1: Design with fixed pressures to establish initial guess values

  • Stage 2: Offdesign with characteristic line scaling for part-load analysis

>>> from tespy.components import Source, Sink, SectionedHeatExchanger
>>> from tespy.connections import Connection
>>> from tespy.networks import Network
>>> from tespy.tools.characteristics import CharLine, load_default_char

Set up the network with appropriate units:

>>> nw = Network()
>>> nw.units.set_defaults(**{
...     "pressure": "bar", "pressure_difference": "bar",
...     "temperature": "degC", "mass_flow": "kg/s"
... })
>>> nw.iterinfo = False

Create network components: two sources (CO2 and water inlets), the heat exchanger, and two sinks (outlets):

>>> so_co2 = Source("CO2 source")
>>> so_water = Source("Water source")
>>> hx = SectionedHeatExchanger("transcritical gas cooler")
>>> si_co2 = Sink("CO2 sink")
>>> si_water = Sink("Water sink")

Create connections with counter-current arrangement (CO2 on side 1, water on side 2):

>>> c1 = Connection(so_co2, "out1", hx, "in1", label="CO2_in")
>>> c2 = Connection(hx, "out1", si_co2, "in1", label="CO2_out")
>>> c11 = Connection(so_water, "out1", hx, "in2", label="water_in")
>>> c12 = Connection(hx, "out2", si_water, "in1", label="water_out")
>>> nw.add_conns(c1, c2, c11, c12)

Stage 1: Design calculation with fixed pressures

First, we solve with fixed pressures on both sides to generate good initial guess values. This improves convergence for the complex transcritical cycle.

Set CO2 inlet at 165 bar and 160°C (transcritical supercritical state):

>>> c1.set_attr(
...     fluid={"CO2": 1},
...     p=165,
...     T=160,
...     m=3.5
... )

Set water inlet at 5 bar and 10°C (cold inlet for cooling):

>>> c11.set_attr(
...     fluid={"Water": 1},
...     p=5,
...     T=10
... )

Specify water outlet temperature target at 60°C:

>>> c12.set_attr(T=60)

Configure heat exchanger with fixed pressures and initial pinch point:

>>> hx.set_attr(
...     td_pinch=20,
...     pr1=1,
...     pr2=1,
...     num_sections=10
... )

Solve the design point and save results:

>>> nw.solve('design')
>>> design_state = nw.save(as_dict=True)

After design computation, the CO2 outlet state is:

>>> round(c2.p.val, 1)
165.0
>>> round(c2.T.val, 1)
30.0

Stage 2: Offdesign analysis with UA_char characteristic scaling

Now we activate characteristic line-based scaling. Load the default characteristic line for heat exchangers:

>>> UA_char = load_default_char(
...     "HeatExchanger", "UA_char1", "DEFAULT", CharLine
... )

Reconfigure heat exchanger to use characteristic lines for UA scaling in offdesign operation:

>>> hx.set_attr(
...     UA_char1=UA_char,
...     UA_char2=UA_char,
...     design=['td_pinch'],
...     offdesign=['UA_char']
... )

When offdesign is set to ['UA_char'], the solver automatically scales the UA value based on the characteristic curve during part-load operation. Verify offdesign setup by solving at design conditions. The design UA value is approximately 23.4 kW/K and pinch is 20.0 K:

>>> nw.solve('offdesign', design_path=design_state)
>>> round(hx.UA.val / 1e3, 2)
23.42
>>> round(hx.td_pinch.val, 1)
20.0

Characteristic line scaling at part-load conditions

With variable mass flow, the UA value scales according to the characteristic curve. At 80 % mass flow, heat transfer reduces to roughly 83 % while UA reduces by 9.5 % following the characteristic scaling:

>>> c1.set_attr(m=2.8)
>>> nw.solve('offdesign', design_path=design_state)
>>> round(hx.Q.val_SI / hx.Q.design, 2)
0.83
>>> round(hx.UA.val_SI / hx.UA.design, 2)
0.91

The pinch point decreases to 15.3 K when heat transfer reduces faster than the characteristic-based UA scaling:

>>> round(hx.td_pinch.val, 1)
15.3

The UA_char parameter allows automatic part-load scaling of UA, following the same principle as the standard HeatExchanger component (tespy.components.heat_exchangers.base.HeatExchanger). UA_cecchinato requires the specification of Reynolds number exponents, area ratio and alpha ratio of the involved fluids.

UA_cecchinato_func()[source]

Method to calculate heat transfer via UA design with modification for part load according to [21]. UA is determined over the UA values of the sections of the heat exchanger.

Note

You need to specify a couple of parameters to use this method. The values depend on the context, as they define relations between the refrigerant and the secondary fluid. For an evaporator the refrigerant is the cold side, for a condenser it is the hot side. You can check the linked publication for reference values.

  • alpha_ratio: Ratio of secondary fluid to refrigerant heat transfer coefficient

  • area_ratio: Ratio of secondary fluid to refrigerant area

  • re_exp_sf: Reynolds exponent for the secondary fluid mass flow

  • re_exp_r: Reynolds exponent for the refrigerant mass flow

The modification factor for UA is calculated as follows

\[f_\text{UA}=\frac{ 1 + \frac{\alpha_\text{sf}}{\alpha_\text{r}} \cdot\frac{A_\text{sf}}{A_\text{r}} }{ \frac{\dot m_\text{sf}}{\dot m_\text{sf,ref}}^{-Re_\text{sf}} + \frac{\alpha_\text{sf}}{\alpha_\text{r}} \cdot\frac{A_\text{sf}}{A_\text{r}} \cdot\frac{\dot m_\text{r}}{\dot m_\text{r,ref}}^{-Re_\text{r}} }\]
Returns:

float – residual value of equation

\[0 = UA_\text{ref} \cdot f_\text{UA} - \sum UA_\text{i}\]

UA_char_func()[source]

Calculate offdesign UA from characteristic lines analogous to standard heat exchanger UA_char, but for the sectioned heat exchanger.

Returns:

float – Residual value of equation:

\[0 = UA_\text{design} * f_\text{UA} - \sum\left(UA_{i}\right)\]

UA_dependents()[source]
UA_func(**kwargs)[source]

Residual method for fixed heat transfer coefficient UA.

Returns:

residual (float) – Residual value of equation.

\[0 = UA - \sum UA_{i}\]

calc_UA(sections)[source]

Calculate the sum of UA for all sections in the heat exchanger

Returns:

float – Sum of UA values of all heat exchanger sections.

calc_parameters()[source]

Postprocessing parameter calculation.

Each ComponentProperties whose calc attribute is set is called here in topological order (respecting calc_deps dependencies).

Note

Two patterns exist for calc methods, and it is important to keep them distinct:

Pattern A - solver variables only (p, h, m, fluid composition, connection energies E): methods like _calc_P() read only quantities that are unknowns of the solver, therefore these methods can also be used in the residual calculations during iterations.

Pattern B - derived properties (T, v, x, …): methods like _calc_ttd_u or _calc_td_log call helpers such as calc_T() which rely on values that are computed during connection postprocessing (e.g. connection.T.val_SI). These methods must only be called in postprocessing, never during iteration, because the derived values are not yet available.

When adding a new calc method, choose Pattern A if the result depends solely on solver variables; choose Pattern B otherwise, and make sure no caller invokes it during iteration.

calc_td_pinch(T_steps_hot, T_steps_cold)[source]

Calculate the pinch point temperature difference

Returns:

float – Value of the pinch point temperature difference

get_parameters()[source]
td_pinch_dependents()[source]
td_pinch_func()[source]

Equation for minimal pinch temperature difference of sections.

Returns:

residual (float) – Residual value of equation.

\[0 = td_\text{pinch} - min(td_\text{i})\]

tespy.components.heat_exchangers.sectioned.identify_step_at_saturation(x, p_in, h_in, delta_p, delta_h, Q, fluid_data)[source]

Method to identify the step corresponding to a saturation line assuming the change of pressure delta p is linear to the change of enthalpy delta h.

\[\Delta h \cdot \left(p_\text{sat} - p_\text{in}\right) = \Delta p \cdot \left(h_\left[p_\text{sat}, Q\right] - h_\text{in} \right)\]
Parameters:
  • x (float) – Step to solve for

  • p_in (float) – pressure at inlet

  • h_in (float) – enthalpy at inlet

  • delta_p (float) – overall pressure difference

  • delta_h (float) – overall enthalpy difference

  • Q (float) – vapor mass fraction (0 for bubble line, 1 for dew line)

  • fluid_data (dict) – fluid_data dictionary

Returns:

float – residual of equation

tespy.components.heat_exchangers.simple module

Module of class SimpleHeatExchanger.

This file is part of project TESPy (github.com/oemof/tespy). It’s copyrighted by the contributors recorded in the version control history of the file, available from its original location tespy/components/heat_exchangers/simple.py

SPDX-License-Identifier: MIT

class tespy.components.heat_exchangers.simple.SimpleHeatExchanger(label, **kwargs)[source]

Bases: Component

A basic heat exchanger representing a heat source or heat sink.

The component SimpleHeatExchanger is the parent class for the components:

Ports

  • Fluid inlets: in1

  • Fluid outlets: out1

  • Power inlets: heat

  • Power outlets: heat

  • Heat inlets: heat

  • Heat outlets: heat

Mandatory Equations

When a power or heat connector is attached:

Parameters:
  • char_warnings (bool) – Ignore warnings on default characteristics usage for this component.

  • D (float, dict, "var") – Diameter of channel. Quantity: length. Can be set as a system variable by passing "var" as its value.

  • darcy_group (GroupedComponentProperties) – Darcy-Weißbach equation for pressure loss. Elements: L, ks, D. Equation: darcy_func.

  • design (list) – List containing design parameters (stated as String).

  • design_path (str) – Path to the components design case.

  • dissipative (bool) – Description missing.

  • dp (float, dict) – Inlet to outlet absolute pressure change. Quantity: pressure_difference. Equation: dp_structure_matrix.

  • hw_group (GroupedComponentProperties) – Hazen-Williams equation for pressure loss. Elements: L, ks_HW, D. Equation: hazen_williams_func.

  • kA (float, dict, "var") – Deprecated, use UA instead. Quantity: heat_transfer_coefficient. Can be set as a system variable by passing "var" as its value.

  • kA_char (tespy.tools.characteristics.CharLine, dict) – Deprecated, use UA_char instead.

  • kA_char_group (GroupedComponentProperties) – Deprecated, use UA_char_group instead. Elements: kA_char, Tamb.

  • kA_group (GroupedComponentProperties) – Deprecated, use UA_group instead. Elements: kA, Tamb.

  • ks (float, dict, "var") – Roughness of wall material. Quantity: length. Can be set as a system variable by passing "var" as its value.

  • ks_HW (float, dict, "var") – Hazen-Williams roughness. Can be set as a system variable by passing "var" as its value.

  • L (float, dict, "var") – Length of channel. Quantity: length. Can be set as a system variable by passing "var" as its value.

  • label (str) – The label of the component.

  • lmtd (float, dict) – Effective logarithmic mean temperature difference |Q|/UA. Quantity: temperature_difference.

  • local_design (bool) – Treat this component in design mode in an offdesign calculation.

  • local_offdesign (bool) – Treat this component in offdesign mode in a design calculation.

  • offdesign (list) – List containing offdesign parameters (stated as String).

  • power_connector_location (str) – Description missing.

  • pr (float, dict) – Outlet to inlet pressure ratio. Quantity: ratio. Equation: pr_structure_matrix.

  • printout (bool) – Include this component in the network’s results printout.

  • Q (float, dict) – Heat transfer. Quantity: heat. Equation: energy_balance_func.

  • Tamb (float, dict) – Ambient temperature. Quantity: temperature.

  • UA (float, dict, "var") – Heat transfer coefficient considering ambient temperature. Quantity: heat_transfer_coefficient. Can be set as a system variable by passing "var" as its value.

  • UA_char (tespy.tools.characteristics.CharLine, dict) – Heat transfer coefficient lookup table for offdesign.

  • UA_char_group (GroupedComponentProperties) – Heat transfer from design heat transfer coefficient, modifier lookup table and ambient temperature. Elements: UA_char, Tamb. Equation: UA_char_group_func.

  • UA_group (GroupedComponentProperties) – Equation for heat transfer based on ambient temperature and heat transfer coefficient. Elements: UA, Tamb. Equation: UA_group_func.

  • zeta (float, dict) – Deprecated, use zeta_d4 instead.

  • zeta_d4 (float, dict) – Geometry-independent friction coefficient zeta/D^4 for pressure loss calculation. Equation: zeta_d4_func.

Example

The SimpleHeatExchanger can be used as a sink or source of heat. This component does not simulate the secondary side of the heat exchanger. It is possible to calculate the pressure ratio with the Darcy-Weisbach equation or in case of liquid water use the Hazen-Williams equation. Also, given ambient temperature and the heat transfer coefficient, it is possible to predict heat transfer.

>>> from tespy.components import Sink, Source, SimpleHeatExchanger
>>> from tespy.connections import Connection
>>> from tespy.networks import Network
>>> nw = Network(iterinfo=False)
>>> nw.units.set_defaults(**{
...     "pressure": "bar", "pressure_difference": "bar",
...     "temperature": "degC", "enthalpy": "kJ/kg"
... })
>>> so1 = Source('source 1')
>>> si1 = Sink('sink 1')
>>> heat_sink = SimpleHeatExchanger('heat sink')
>>> heat_sink.set_attr(Tamb=10, pr=0.95, design=['pr'],
... offdesign=['zeta_d4', 'UA_char'])
>>> inc = Connection(so1, 'out1', heat_sink, 'in1')
>>> outg = Connection(heat_sink, 'out1', si1, 'in1')
>>> nw.add_conns(inc, outg)

It is possible to determine the amount of heat transferred when the fluid enters the heat sink at a temperature of 200 °C and is cooled down to 150 °C. Given an ambient temperature of 10 °C this also determines the heat transfer coefficient to the ambient. Assuming a characteristic function for the heat transfer coefficient we can predict the heat transferred at variable flow rates.

>>> inc.set_attr(fluid={'N2': 1}, m=1, T=200, p=5)
>>> outg.set_attr(T=150, design=['T'])
>>> nw.solve('design')
>>> design_state = nw.save(as_dict=True)
>>> round(heat_sink.Q.val, 0)
-52581.0
>>> round(heat_sink.kA.val, 0)
321.0
>>> inc.set_attr(m=1.25)
>>> nw.solve('offdesign', design_path=design_state)
>>> round(heat_sink.Q.val, 0)
-56599.0
>>> round(outg.T.val, 1)
156.9
>>> inc.set_attr(m=0.75)
>>> nw.solve('offdesign', design_path=design_state)
>>> round(heat_sink.Q.val, 1)
-47275.8
>>> round(outg.T.val, 1)
140.0

Use of the HeatConnection

Single sided heat exchangers can also connect to a HeatConnection. The component auto-detects whether the connection is on the inlet or outlet side - no prior declaration is needed.

>>> from tespy.connections import HeatConnection
>>> from tespy.components import HeatSink
>>> ambient = HeatSink('ambient heat dissipation')

Create and add the HeatConnection as an outlet. We run a new design calculation, because the old design case did not include the HeatConnection. The energy value will be identical to the heat transfer of the component.

>>> h1 = HeatConnection(heat_sink, 'heat', ambient, 'heat', label='h1')
>>> nw.add_conns(h1)
>>> nw.solve('design')
>>> round(h1.E.val) == round(-heat_sink.Q.val)
True
UA_char_group_dependents()[source]
UA_char_group_func()[source]

Calculate heat transfer from heat transfer coefficient characteristic.

Returns:

residual (float) – Residual value of equation.

\[0 = \dot{m}_{in} \cdot \left( h_{out} - h_{in}\right) + UA_{design} \cdot f_{UA} \cdot \Delta T_{log}\]

UA_group_dependents()[source]
UA_group_func()[source]

Calculate heat transfer from heat transfer coefficient.

Returns:

residual (float) – Residual value of equation.

\[0 = \dot{m}_{in} \cdot \left( h_{out} - h_{in}\right) + UA \cdot \Delta T_{log}\]

calc_parameters()[source]

Postprocessing parameter calculation.

convergence_check()[source]
darcy_dependents()[source]
darcy_func()[source]

Equation for pressure drop calculation from darcy friction factor.

Returns:

residual (float) – Residual value of equation.

\[ \begin{align}\begin{aligned}\begin{split}0 = p_{in} - p_{out} - \frac{8 \cdot |\dot{m}_{in}| \cdot \dot{m}_{in} \cdot \frac{v_{in}+v_{out}}{2} \cdot L \cdot \lambda\left(Re, ks, D\right)}{\pi^2 \cdot D^5}\\\end{split}\\\begin{split}Re = \frac{4 \cdot |\dot{m}_{in}|}{\pi \cdot D \cdot \frac{\eta_{in}+\eta_{out}}{2}}\\ \eta: \text{dynamic viscosity}\\ v: \text{specific volume}\\ \lambda: \text{darcy friction factor}\end{split}\end{aligned}\end{align} \]

energy_balance_dependents()[source]
energy_balance_func()[source]

Equation for pressure drop calculation.

Returns:

residual (float) – Residual value of equation:

\[0 =\dot{m}_{in}\cdot\left( h_{out}-h_{in}\right) -\dot{Q}\]

energy_connector_balance_func()[source]
energy_connector_dependents()[source]
entropy_balance()[source]

Calculate entropy balance of a simple heat exchanger.

The allocation of the entropy streams due to heat exchanged and due to irreversibility is performed by solving for T:

\[h_\text{out} - h_\text{in} = \int_\text{out}^\text{in} v \cdot dp - \int_\text{out}^\text{in} T \cdot ds\]

As solving \(\int_\text{out}^\text{in} v \cdot dp\) for non isobaric processes would require perfect process knowledge (the path) on how specific volume and pressure change throught the component, the heat transfer is split into three separate virtual processes:

  • in->in*: decrease pressure to \(p_\text{in*}=p_\text{in}\cdot\sqrt{\frac{p_\text{out}}{p_\text{in}}}\) without changing enthalpy.

  • in*->out* transfer heat without changing pressure. \(h_\text{out*}-h_\text{in*}=h_\text{out}-h_\text{in}\)

  • out*->out decrease pressure to outlet pressure \(p_\text{out}\) without changing enthalpy.

Note

The entropy balance makes the following parameter available:

\[\begin{split}\text{S\_Q}=\dot{m} \cdot \left(s_\text{out*}-s_\text{in*} \right)\\ \text{S\_irr}=\dot{m} \cdot \left(s_\text{out}-s_\text{in} \right) - \text{S\_Q}\\ \text{T\_mQ}=\frac{\dot{Q}}{\text{S\_Q}}\end{split}\]
get_bypass_constraints()[source]
get_mandatory_constraints()[source]
get_parameters()[source]
get_plotting_data()[source]

Generate a dictionary containing FluProDia plotting information.

Returns:

data (dict) – A nested dictionary containing the keywords required by the calc_individual_isoline method of the FluidPropertyDiagram class. First level keys are the connection index (‘in1’ -> ‘out1’, therefore 1 etc.).

hazen_williams_dependents()[source]
hazen_williams_func()[source]

Equation for pressure drop calculation from Hazen-Williams equation.

Returns:

residual (float) – Residual value of equation.

\[ \begin{align}\begin{aligned}0 = \left(p_{in} - p_{out} \right) \cdot \left(-1\right)^i - \frac{10.67 \cdot |\dot{m}_{in}| ^ {1.852} \cdot L}{ks^{1.852} \cdot D^{4.871}} \cdot g \cdot \left(\frac{v_{in} + v_{out}}{2}\right)^{0.852}\\\begin{split}i = \begin{cases} 0 & \dot{m}_{in} \geq 0\\ 1 & \dot{m}_{in} < 0 \end{cases}\end{split}\end{aligned}\end{align} \]

Note

Gravity \(g\) is set to \(9.81 \frac{m}{s^2}\)

static heatinlets()[source]
static heatoutlets()[source]
initialise_source(c, key)[source]

Return a starting value for pressure and enthalpy the outlets.

Parameters:
  • c (tespy.connections.connection.Connection) – Connection to perform initialisation on.

  • key (str) – Fluid property to retrieve.

Returns:

val (float) – Starting value for pressure/enthalpy in SI units.

\[\begin{split}val = \begin{cases} \begin{cases} 1 \cdot 10^5 \; \frac{\text{J}}{\text{kg}} & \dot{Q} < 0\\ 3 \cdot 10^5 \; \frac{\text{J}}{\text{kg}} & \dot{Q} = 0\\ 5 \cdot 10^5 \; \frac{\text{J}}{\text{kg}} & \dot{Q} > 0 \end{cases} & \text{key = 'h'}\\ \; \; \; \; 10^5 \text{Pa} & \text{key = 'p'} \end{cases}\end{split}\]

initialise_target(c, key)[source]

Return a starting value for pressure and enthalpy the inlets.

Parameters:
  • c (tespy.connections.connection.Connection) – Connection to perform initialisation on.

  • key (str) – Fluid property to retrieve.

Returns:

val (float) – Starting value for pressure/enthalpy in SI units.

\[\begin{split}val = \begin{cases} 1 \cdot 10^5 & \text{key = 'p'}\\ \begin{cases} 5 \cdot 10^5 & \dot{Q} < 0\\ 3 \cdot 10^5 & \dot{Q} = 0\\ 1 \cdot 10^5 & \dot{Q} > 0 \end{cases} & \text{key = 'h'}\\ \end{cases}\end{split}\]

static inlets()[source]
static outlets()[source]
static powerinlets()[source]
static poweroutlets()[source]
set_attr(**kwargs)[source]

Set, reset or unset attributes of a component for provided arguments.

Parameters:
  • design (list) – List containing design parameters (stated as String).

  • offdesign (list) – List containing offdesign parameters (stated as String).

  • design_path (str) – Path to the components design case.

  • **kwargs – See the class documentation of desired component for available keywords.

Note

Allowed keywords in kwargs are obtained from class documentation as all components share the tespy.components.component.Component.set_attr() method.

tespy.components.heat_exchangers.solar_collector module

Module of class SolarCollector.

This file is part of project TESPy (github.com/oemof/tespy). It’s copyrighted by the contributors recorded in the version control history of the file, available from its original location tespy/components/heat_exchangers/solar_collector.py

SPDX-License-Identifier: MIT

class tespy.components.heat_exchangers.solar_collector.SolarCollector(label, **kwargs)[source]

Bases: SimpleHeatExchanger

The solar collector calculates heat output from irradiance.

flowsheet of the solarcollector flowsheet of the solarcollector

Ports

  • Fluid inlets: in1

  • Fluid outlets: out1

  • Power inlets: heat

  • Power outlets: heat

  • Heat inlets: heat

  • Heat outlets: heat

Mandatory Equations

When a power or heat connector is attached:

Parameters:
  • A (float, dict, "var") – Area of the solar collector. Quantity: area. Can be set as a system variable by passing "var" as its value.

  • char_warnings (bool) – Ignore warnings on default characteristics usage for this component.

  • D (float, dict, "var") – Diameter of channel. Quantity: length. Can be set as a system variable by passing "var" as its value.

  • darcy_group (GroupedComponentProperties) – Darcy-Weißbach equation for pressure loss. Elements: L, ks, D. Equation: darcy_func.

  • design (list) – List containing design parameters (stated as String).

  • design_path (str) – Path to the components design case.

  • dissipative (bool) – Description missing.

  • dp (float, dict) – Inlet to outlet absolute pressure change. Quantity: pressure_difference. Equation: dp_structure_matrix.

  • E (float, dict, "var") – Solar irradiation to the solar collector. Quantity: heat. Can be set as a system variable by passing "var" as its value.

  • energy_group (GroupedComponentProperties) – Energy balance equation of the solar collector. Elements: E, eta_opt, lkf_lin, lkf_quad, A, Tamb. Equation: energy_group_func.

  • eta_opt (float, dict) – Optical efficiency. Quantity: efficiency.

  • hw_group (GroupedComponentProperties) – Hazen-Williams equation for pressure loss. Elements: L, ks_HW, D. Equation: hazen_williams_func.

  • ks (float, dict, "var") – Roughness of wall material. Quantity: length. Can be set as a system variable by passing "var" as its value.

  • ks_HW (float, dict, "var") – Hazen-Williams roughness. Can be set as a system variable by passing "var" as its value.

  • L (float, dict, "var") – Length of channel. Quantity: length. Can be set as a system variable by passing "var" as its value.

  • label (str) – The label of the component.

  • lkf_lin (float, dict) – Linear heat loss factor.

  • lkf_quad (float, dict) – Quadratic heat loss factor.

  • local_design (bool) – Treat this component in design mode in an offdesign calculation.

  • local_offdesign (bool) – Treat this component in offdesign mode in a design calculation.

  • offdesign (list) – List containing offdesign parameters (stated as String).

  • power_connector_location (str) – Description missing.

  • pr (float, dict) – Outlet to inlet pressure ratio. Quantity: ratio. Equation: pr_structure_matrix.

  • printout (bool) – Include this component in the network’s results printout.

  • Q (float, dict) – Heat transfer. Quantity: heat. Equation: energy_balance_func.

  • Q_loss (float, dict) – Heat dissipation. Quantity: heat.

  • Tamb (float, dict) – Ambient air temperature. Quantity: temperature.

  • zeta (float, dict) – Deprecated, use zeta_d4 instead.

  • zeta_d4 (float, dict) – Geometry-independent friction coefficient zeta/D^4 for pressure loss calculation. Equation: zeta_d4_func.

Example

The solar collector is used to calculate heat transferred to the heating system from irradiance on a tilted plane. For instance, it is possible to calculate the collector surface area required to transfer a specific amount of heat at a given irradiance. The collector parameters are the linear and the quadratic loss keyfigure as well as the optical effifiency.

>>> from tespy.components import Sink, Source, SolarCollector
>>> from tespy.connections import Connection
>>> from tespy.networks import Network
>>> nw = Network(iterinfo=False)
>>> nw.units.set_defaults(**{
...     "pressure": "bar", "pressure_difference": "bar",
...     "temperature": "degC", "enthalpy": "kJ/kg"
... })
>>> so = Source('source')
>>> si = Sink('sink')
>>> sc = SolarCollector('solar collector')
>>> sc.set_attr(pr=0.95, Q=1e4, design=['pr', 'Q'], offdesign=['zeta_d4'],
...     Tamb=25, A='var', eta_opt=0.92, lkf_lin=1, lkf_quad=0.005, E=8e2)
>>> inc = Connection(so, 'out1', sc, 'in1')
>>> outg = Connection(sc, 'out1', si, 'in1')
>>> nw.add_conns(inc, outg)

The outlet temperature should be at 90 °C at a constant mass flow, which is determined in the design calculation. In offdesign operation (at a different irradiance) using the calculated surface area and mass flow, it is possible to predict the outlet temperature. It would instead be possible to calculate the change in mass flow required to hold the specified outlet temperature, too.

>>> inc.set_attr(fluid={'H2O': 1}, T=40, p=3, offdesign=['m'])
>>> outg.set_attr(T=90, design=['T'])
>>> nw.solve('design')
>>> design_state = nw.save(as_dict=True)
>>> round(sc.A.val, 1)
14.5
>>> sc.set_attr(A=sc.A.val, E=5e2, Tamb=20)
>>> nw.solve('offdesign', design_path=design_state)
>>> round(sc.Q.val, 1)
6083.8
>>> round(outg.T.val, 1)
70.5
calc_parameters()[source]

Postprocessing parameter calculation.

convergence_check()[source]
energy_group_dependents()[source]
energy_group_func()[source]

Equation for solar collector energy balance.

Returns:

residual (float) – Residual value of equation.

\[\begin{split}\begin{split} 0 = & \dot{m} \cdot \left( h_{out} - h_{in} \right)\\ & - A \cdot \left[E \cdot \eta_{opt} - \alpha_1 \cdot \left(T_m - T_{amb} \right) - \alpha_2 \cdot \left(T_m - T_{amb}\right)^2 \right]\\ T_m = & \frac{T_{out} + T_{in}}{2}\\ \end{split}\end{split}\]

Reference: [37].

get_parameters()[source]