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:
ComponentClass for counter flow heat exchanger.
The component HeatExchanger is the parent class for the components:
tespy.components.heat_exchangers.desuperheater.Desuperheatertespy.components.heat_exchangers.movingboundary.MovingBoundaryHeatExchanger
Mandatory Equations
fluid:
tespy.components.component.Component.variable_equality_structure_matrix()mass flow:
tespy.components.component.Component.variable_equality_structure_matrix()tespy.components.heat_exchangers.base.HeatExchanger.energy_balance_func()
Optional Equations
tespy.components.heat_exchangers.base.HeatExchanger.energy_balance_hot_func()tespy.components.heat_exchangers.base.HeatExchanger.kA_func()tespy.components.heat_exchangers.base.HeatExchanger.kA_char_func()tespy.components.heat_exchangers.base.HeatExchanger.ttd_u_func()tespy.components.heat_exchangers.base.HeatExchanger.ttd_l_func()tespy.components.heat_exchangers.base.HeatExchanger.ttd_min_func()tespy.components.heat_exchangers.base.HeatExchanger.eff_cold_func()tespy.components.heat_exchangers.base.HeatExchanger.eff_hot_func()tespy.components.heat_exchangers.base.HeatExchanger.eff_max_func()
For hot and cold side individually:
Inlets/Outlets
in1, in2 (index 1: hot side, index 2: cold side)
out1, out2 (index 1: hot side, index 2: cold side)
Image
- Parameters:
label (str) – The label of the component.
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.
local_offdesign (boolean) – Treat this component in offdesign mode in a design calculation.
local_design (boolean) – Treat this component in design mode in an offdesign calculation.
char_warnings (boolean) – Ignore warnings on default characteristics usage for this component.
printout (boolean) – Include this component in the network’s results printout.
Q (float, dict) – Heat transfer, \(Q/\text{W}\).
pr1 (float, dict,
"var") – Outlet to inlet pressure ratio at hot side, \(pr/1\).pr2 (float, dict,
"var") – Outlet to inlet pressure ratio at cold side, \(pr/1\).dp1 (float, dict,
"var") – Inlet to outlet pressure delta at hot side, unit is the network’s pressure unit!.dp2 (float, dict,
"var") – Inlet to outlet pressure delta at cold side, unit is the network’s pressure unit!.zeta1 (float, dict,
"var") – Geometry independent friction coefficient at hot side, \(\frac{\zeta}{D^4}/\frac{1}{\text{m}^4}\).zeta2 (float, dict,
"var") – Geometry independent friction coefficient at cold side, \(\frac{\zeta}{D^4}/\frac{1}{\text{m}^4}\).ttd_l (float, dict) – Lower terminal temperature difference \(ttd_\mathrm{l}/\text{K}\).
ttd_u (float, dict) – Upper terminal temperature difference \(ttd_\mathrm{u}/\text{K}\).
ttd_min (float, dict) – Minumum terminal temperature difference \(ttd_\mathrm{min}/\text{K}\).
eff_cold (float, dict) – Cold side heat exchanger effectiveness \(eff_\text{cold}/\text{1}\).
eff_hot (float, dict) – Hot side heat exchanger effectiveness \(eff_\text{hot}/\text{1}\).
eff_max (float, dict) – Max value of hot and cold side heat exchanger effectiveness values \(eff_\text{max}/\text{1}\).
kA (float, dict) – Area independent heat transfer coefficient, \(kA/\frac{\text{W}}{\text{K}}\).
kA_char (dict) – Area independent heat transfer coefficient characteristic.
kA_char1 (tespy.tools.characteristics.CharLine, dict) – Characteristic line for hot side heat transfer coefficient.
kA_char2 (tespy.tools.characteristics.CharLine, dict) – Characteristic line for cold side heat transfer coefficient.
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 >>> import os >>> nw = Network(iterinfo=False) >>> nw.units.set_defaults(**{ ... "pressure": "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', 'zeta2', 'kA_char']) >>> cw_he.set_attr(fluid={'water': 1}, T=10, p=3, ... offdesign=['m']) >>> he_cw.set_attr(h0=1e2) >>> 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') >>> nw.save('tmp.json') >>> round(ex_he.T.val - he_cw.T.val, 0) 5.0 >>> ex_he.set_attr(v=0.075) >>> nw.solve('offdesign', design_path='tmp.json') >>> 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='tmp.json') >>> round(he_cw.T.val, 1) 33.9 >>> round(he_ex.T.val, 1) 18.8 >>> os.remove("tmp.json")
- bus_deriv(bus)[source]¶
Calculate partial derivatives of the bus function.
- Parameters:
bus (tespy.connections.bus.Bus) – TESPy bus object.
- Returns:
deriv (ndarray) – Matrix of partial derivatives.
- bus_func(bus)[source]¶
Calculate the value of the bus function.
- Parameters:
bus (tespy.connections.bus.Bus) – TESPy bus object.
- Returns:
val (float) – Value of energy transfer \(\dot{E}\). This value is passed to
tespy.components.component.Component.calc_bus_value()for value manipulation according to the specified characteristic line of the bus.\[\dot{E} = \dot{m}_{in,1} \cdot \left( h_{out,1} - h_{in,1} \right)\]
- calc_dh_max_cold()[source]¶
Calculate the theoretical maximum enthalpy increase on the cold side
- Returns:
float – Maxmium 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 – Maxmium hot side enthalpy decrease.
\[h\left(p_{out,1}, T_{in,2}\right) - h_{in,1}\]
- 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_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_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_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_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_\mathrm{out} - h_\mathrm{in} = \int_\mathrm{in}^\mathrm{out} v \cdot dp - \int_\mathrm{in}^\mathrm{out} T \cdot ds\]As solving \(\int_\mathrm{in}^\mathrm{out} 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 splitted into three separate virtual processes for both sides:
in->in*: decrease pressure to \(p_\mathrm{in*}=p_\mathrm{in}\cdot\sqrt{\frac{p_\mathrm{out}}{p_\mathrm{in}}}\) without changing enthalpy.
in*->out* transfer heat without changing pressure. \(h_\mathrm{out*}-h_\mathrm{in*}=h_\mathrm{out}-h_\mathrm{in}\)
out*->out decrease pressure to outlet pressure \(p_\mathrm{out}\) without changing enthalpy.
Note
The entropy balance makes the follwing parameter available:
\[\begin{split}\text{S\_Q1}=\dot{m} \cdot \left(s_\mathrm{out*,1}-s_\mathrm{in*,1} \right)\\ \text{S\_Q2}=\dot{m} \cdot \left(s_\mathrm{out*,2}-s_\mathrm{in*,2} \right)\\ \text{S\_Qirr}=\text{S\_Q2} - \text{S\_Q1}\\ \text{S\_irr1}=\dot{m} \cdot \left(s_\mathrm{out,1}-s_\mathrm{in,1} \right) - \text{S\_Q1}\\ \text{S\_irr2}=\dot{m} \cdot \left(s_\mathrm{out,2}-s_\mathrm{in,2} \right) - \text{S\_Q2}\\ \text{S\_irr}=\sum \dot{S}_\mathrm{irr}\\ \text{T\_mQ1}=\frac{\dot{Q}}{\text{S\_Q1}}\\ \text{T\_mQ2}=\frac{\dot{Q}}{\text{S\_Q2}}\end{split}\]
- exergy_balance(T0)[source]¶
Calculate exergy balance of a heat exchanger.
- Parameters:
T0 (float) – Ambient temperature T0 / K.
Note
\[ \begin{align}\begin{aligned}\begin{split}\dot{E}_\mathrm{P} = \begin{cases} \dot{E}_\mathrm{out,2}^\mathrm{T} - \dot{E}_\mathrm{in,2}^\mathrm{T} & T_\mathrm{in,1}, T_\mathrm{in,2}, T_\mathrm{out,1}, T_\mathrm{out,2} > T_0\\ \dot{E}_\mathrm{out,1}^\mathrm{T} - \dot{E}_\mathrm{in,1}^\mathrm{T} & T_0 \geq T_\mathrm{in,1}, T_\mathrm{in,2}, T_\mathrm{out,1}, T_\mathrm{out,2}\\ \dot{E}_\mathrm{out,1}^\mathrm{T} + \dot{E}_\mathrm{out,2}^\mathrm{T} & T_\mathrm{in,1}, T_\mathrm{out,2} > T_0 \geq T_\mathrm{in,2}, T_\mathrm{out,1}\\ \dot{E}_\mathrm{out,1}^\mathrm{T} & T_\mathrm{in,1} > T_0 \geq T_\mathrm{in,2}, T_\mathrm{out,1}, T_\mathrm{out,2}\\ \text{not defined (nan)} & T_\mathrm{in,1}, T_\mathrm{out,1} > T_0 \geq T_\mathrm{in,2}, T_\mathrm{out,2}\\ \dot{E}_\mathrm{out,2}^\mathrm{T} & T_\mathrm{in,1}, T_\mathrm{out,1}, T_\mathrm{out,2} \geq T_0 > T_\mathrm{in,2}\\ \end{cases}\end{split}\\\begin{split}\dot{E}_\mathrm{F} = \begin{cases} \dot{E}_\mathrm{in,1}^\mathrm{PH} - \dot{E}_\mathrm{out,1}^\mathrm{PH} + \dot{E}_\mathrm{in,2}^\mathrm{M} - \dot{E}_\mathrm{out,2}^\mathrm{M} & T_\mathrm{in,1}, T_\mathrm{in,2}, T_\mathrm{out,1}, T_\mathrm{out,2} > T_0\\ \dot{E}_\mathrm{in,2}^\mathrm{PH} - \dot{E}_\mathrm{out,2}^\mathrm{PH} + \dot{E}_\mathrm{in,1}^\mathrm{M} - \dot{E}_\mathrm{out,1}^\mathrm{M} & T_0 \geq T_\mathrm{in,1}, T_\mathrm{in,2}, T_\mathrm{out,1}, T_\mathrm{out,2}\\ \dot{E}_\mathrm{in,1}^\mathrm{PH} + \dot{E}_\mathrm{in,2}^\mathrm{PH} - \dot{E}_\mathrm{out,1}^\mathrm{M} - \dot{E}_\mathrm{out,2}^\mathrm{M} & T_\mathrm{in,1}, T_\mathrm{out,2} > T_0 \geq T_\mathrm{in,2}, T_\mathrm{out,1}\\ \dot{E}_\mathrm{in,1}^\mathrm{PH} + \dot{E}_\mathrm{in,2}^\mathrm{PH} - \dot{E}_\mathrm{out,2}^\mathrm{PH} - \dot{E}_\mathrm{out,1}^\mathrm{M} & T_\mathrm{in,1} > T_0 \geq T_\mathrm{in,2}, T_\mathrm{out,1}, T_\mathrm{out,2}\\ \dot{E}_\mathrm{in,1}^\mathrm{PH} - \dot{E}_\mathrm{out,1}^\mathrm{PH} + \dot{E}_\mathrm{in,2}^\mathrm{PH} - \dot{E}_\mathrm{out,2}^\mathrm{PH} & T_\mathrm{in,1}, T_\mathrm{out,1} > T_0 \geq T_\mathrm{in,2}, T_\mathrm{out,2}\\ \dot{E}_\mathrm{in,1}^\mathrm{PH} - \dot{E}_\mathrm{out,1}^\mathrm{PH} + \dot{E}_\mathrm{in,2}^\mathrm{PH} - \dot{E}_\mathrm{out,2}^\mathrm{M} & T_\mathrm{in,1}, T_\mathrm{out,1}, T_\mathrm{out,2} \geq T_0 > T_\mathrm{in,2}\\ \end{cases}\end{split}\end{aligned}\end{align} \]
- 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_isolinemethod of theFluidPropertyDiagramclass. First level keys are the connection index (‘in1’ -> ‘out1’, therefore1etc.).
- 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.
- kA_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) + kA_{design} \cdot f_{kA} \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_{kA} = \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.
- kA_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).
- kA_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) + kA \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}}}}\]
- 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}\]
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:
HeatExchangerA 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.
Mandatory Equations
fluid:
tespy.components.component.Component.variable_equality_structure_matrix()mass flow:
tespy.components.component.Component.variable_equality_structure_matrix()tespy.components.heat_exchangers.base.HeatExchanger.energy_balance_func()condensate outlet state, function can be disabled by specifying
set_attr(subcooling=True)tespy.components.heat_exchangers.condenser.Condenser.subcooling_func()
Optional Equations
The
Condenserclass uses an individual definition for the calculation of the logarithmic temperature differencetespy.components.heat_exchangers.base.HeatExchanger.energy_balance_hot_func()tespy.components.heat_exchangers.base.HeatExchanger.kA_func()tespy.components.heat_exchangers.base.HeatExchanger.kA_char_func()tespy.components.heat_exchangers.base.HeatExchanger.ttd_u_func()tespy.components.heat_exchangers.base.HeatExchanger.ttd_l_func()tespy.components.heat_exchangers.base.HeatExchanger.ttd_min_func()tespy.components.heat_exchangers.base.HeatExchanger.eff_cold_func()tespy.components.heat_exchangers.base.HeatExchanger.eff_hot_func()tespy.components.heat_exchangers.base.HeatExchanger.eff_max_func()
For hot and cold side individually:
Inlets/Outlets
in1, in2 (index 1: hot side, index 2: cold side)
out1, out2 (index 1: hot side, index 2: cold side)
Image
- Parameters:
label (str) – The label of the component.
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.
local_offdesign (boolean) – Treat this component in offdesign mode in a design calculation.
local_design (boolean) – Treat this component in design mode in an offdesign calculation.
char_warnings (boolean) – Ignore warnings on default characteristics usage for this component.
printout (boolean) – Include this component in the network’s results printout.
Q (float, dict) – Heat transfer, \(Q/\text{W}\).
pr1 (float, dict,
"var") – Outlet to inlet pressure ratio at hot side, \(pr/1\).pr2 (float, dict,
"var") – Outlet to inlet pressure ratio at cold side, \(pr/1\).dp1 (float, dict,
"var") – Inlet to outlet pressure delta at hot side, unit is the network’s pressure unit!.dp2 (float, dict,
"var") – Inlet to outlet pressure delta at cold side, unit is the network’s pressure unit!.zeta1 (float, dict,
"var") – Geometry independent friction coefficient at hot side, \(\frac{\zeta}{D^4}/\frac{1}{\text{m}^4}\).zeta2 (float, dict,
"var") – Geometry independent friction coefficient at cold side, \(\frac{\zeta}{D^4}/\frac{1}{\text{m}^4}\).ttd_l (float, dict) – Lower terminal temperature difference \(ttd_\mathrm{l}/\text{K}\).
ttd_u (float, dict) – Upper terminal temperature difference (referring to saturation temprature of condensing fluid) \(ttd_\mathrm{u}/\text{K}\).
ttd_min (float, dict) – Minumum terminal temperature difference \(ttd_\mathrm{min}/\text{K}\).
eff_cold (float, dict) – Cold side heat exchanger effectiveness \(eff_\text{cold}/\text{1}\).
eff_hot (float, dict) – Hot side heat exchanger effectiveness \(eff_\text{hot}/\text{1}\).
eff_max (float, dict) – Max value of hot and cold side heat exchanger effectiveness values \(eff_\text{max}/\text{1}\).
kA (float, dict) – Area independent heat transfer coefficient, \(kA/\frac{\text{W}}{\text{K}}\).
kA_char (tespy.tools.data_containers.SimpleDataContainer) – Area independent heat transfer coefficient characteristic.
kA_char1 (tespy.tools.characteristics.CharLine, dict) – Characteristic line for hot side heat transfer coefficient.
kA_char2 (tespy.tools.characteristics.CharLine, dict) – Characteristic line for cold side heat transfer coefficient.
subcooling (boolean) – Enable/disable subcooling, default value: disabled.
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 possible to specify the enthalpy at the outgoing connection manually.
It has different calculation method for given heat transfer coefficient and upper terminal temperature dierence: 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 >>> import os >>> nw = Network(m_range=[0.01, 1000], iterinfo=False) >>> nw.units.set_defaults(**{ ... "pressure": "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', 'kA_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') >>> nw.save('tmp.json') >>> 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='tmp.json') >>> 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='tmp.json') >>> 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 >>> os.remove('tmp.json')
- 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.
- kA_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) + kA_{design} \cdot f_{kA} \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_{kA} = \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.
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:
HeatExchangerThe Desuperheater cools a fluid to the saturated gas state.
Mandatory Equations
fluid:
tespy.components.component.Component.variable_equality_structure_matrix()mass flow:
tespy.components.component.Component.variable_equality_structure_matrix()tespy.components.heat_exchangers.base.HeatExchanger.energy_balance_func()tespy.components.heat_exchangers.desuperheater.Desuperheater.saturated_gas_func()
Optional Equations
tespy.components.heat_exchangers.base.HeatExchanger.energy_balance_hot_func()tespy.components.heat_exchangers.base.HeatExchanger.kA_func()tespy.components.heat_exchangers.base.HeatExchanger.kA_char_func()tespy.components.heat_exchangers.base.HeatExchanger.ttd_u_func()tespy.components.heat_exchangers.base.HeatExchanger.ttd_l_func()tespy.components.heat_exchangers.base.HeatExchanger.ttd_min_func()tespy.components.heat_exchangers.base.HeatExchanger.eff_cold_func()tespy.components.heat_exchangers.base.HeatExchanger.eff_hot_func()tespy.components.heat_exchangers.base.HeatExchanger.eff_max_func()
For hot and cold side individually:
Inlets/Outlets
in1, in2 (index 1: hot side, index 2: cold side)
out1, out2 (index 1: hot side, index 2: cold side)
Image
- Parameters:
label (str) – The label of the component.
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.
local_offdesign (boolean) – Treat this component in offdesign mode in a design calculation.
local_design (boolean) – Treat this component in design mode in an offdesign calculation.
char_warnings (boolean) – Ignore warnings on default characteristics usage for this component.
printout (boolean) – Include this component in the network’s results printout.
Q (float, dict) – Heat transfer, \(Q/\text{W}\).
pr1 (float, dict,
"var") – Outlet to inlet pressure ratio at hot side, \(pr/1\).pr2 (float, dict,
"var") – Outlet to inlet pressure ratio at cold side, \(pr/1\).zeta1 (float, dict,
"var") – Geometry independent friction coefficient at hot side, \(\frac{\zeta}{D^4}/\frac{1}{\text{m}^4}\).zeta2 (float, dict,
"var") – Geometry independent friction coefficient at cold side, \(\frac{\zeta}{D^4}/\frac{1}{\text{m}^4}\).ttd_l (float, dict) – Lower terminal temperature difference \(ttd_\mathrm{l}/\text{K}\).
ttd_u (float, dict) – Upper terminal temperature difference \(ttd_\mathrm{u}/\text{K}\).
kA (float, dict) – Area independent heat transfer coefficient, \(kA/\frac{\text{W}}{\text{K}}\).
kA_char1 (tespy.tools.characteristics.CharLine, dict) – Characteristic line for hot side heat transfer coefficient.
kA_char2 (tespy.tools.characteristics.CharLine, dict) – Characteristic line for cold side heat transfer coefficient.
Note
The desuperheater has an additional equation for enthalpy at hot side outlet: The fluid leaves the component in saturated gas state.
Example
Overheated enthanol 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 >>> import os >>> nw = Network(iterinfo=False) >>> nw.units.set_defaults(**{ ... "pressure": "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', 'zeta2', 'kA_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') >>> nw.save('tmp.json') >>> 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='tmp.json') >>> round(cw_de.v.val, 2) 1.94 >>> et_de.set_attr(v=7) >>> nw.solve('offdesign', init_path='tmp.json', design_path='tmp.json') >>> round(cw_de.v.val, 2) 0.41 >>> os.remove('tmp.json')
- 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.
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:
SectionedHeatExchangerClass 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 [26].
Mandatory Equations
fluid:
tespy.components.component.Component.variable_equality_structure_matrix()mass flow:
tespy.components.component.Component.variable_equality_structure_matrix()tespy.components.heat_exchangers.base.HeatExchanger.energy_balance_func()
Optional Equations
tespy.components.heat_exchangers.base.HeatExchanger.energy_balance_hot_func()tespy.components.heat_exchangers.sectioned.SectionedHeatExchanger.UA_func()tespy.components.heat_exchangers.sectioned.SectionedHeatExchanger.td_pinch_func()tespy.components.heat_exchangers.sectioned.SectionedHeatExchanger.UA_cecchinato_func()tespy.components.heat_exchangers.base.HeatExchanger.ttd_u_func()tespy.components.heat_exchangers.base.HeatExchanger.ttd_l_func()tespy.components.heat_exchangers.base.HeatExchanger.ttd_min_func()tespy.components.heat_exchangers.base.HeatExchanger.eff_cold_func()tespy.components.heat_exchangers.base.HeatExchanger.eff_hot_func()tespy.components.heat_exchangers.base.HeatExchanger.eff_max_func()
For hot and cold side individually:
Inlets/Outlets
in1, in2 (index 1: hot side, index 2: cold side)
out1, out2 (index 1: hot side, index 2: cold side)
Image
- Parameters:
label (str) – The label of the component.
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.
local_offdesign (boolean) – Treat this component in offdesign mode in a design calculation.
local_design (boolean) – Treat this component in design mode in an offdesign calculation.
char_warnings (boolean) – Ignore warnings on default characteristics usage for this component.
printout (boolean) – Include this component in the network’s results printout.
Q (float, dict) – Heat transfer, \(Q/\text{W}\).
pr1 (float, dict,
"var") – Outlet to inlet pressure ratio at hot side, \(pr/1\).pr2 (float, dict,
"var") – Outlet to inlet pressure ratio at cold side, \(pr/1\).dp1 (float, dict,
"var") – Inlet to outlet pressure delta at hot side, unit is the network’s pressure unit!.dp2 (float, dict,
"var") – Inlet to outlet pressure delta at cold side, unit is the network’s pressure unit!.zeta1 (float, dict,
"var") – Geometry independent friction coefficient at hot side, \(\frac{\zeta}{D^4}/\frac{1}{\text{m}^4}\).zeta2 (float, dict,
"var") – Geometry independent friction coefficient at cold side, \(\frac{\zeta}{D^4}/\frac{1}{\text{m}^4}\).ttd_l (float, dict) – Lower terminal temperature difference \(ttd_\text{l}/\text{K}\).
ttd_u (float, dict) – Upper terminal temperature difference \(ttd_\text{u}/\text{K}\).
ttd_min (float, dict) – Minimum terminal temperature difference \(ttd_\text{min}/\text{K}\).
eff_cold (float, dict) – Cold side heat exchanger effectiveness \(eff_\text{cold}/\text{1}\).
eff_hot (float, dict) – Hot side heat exchanger effectiveness \(eff_\text{hot}/\text{1}\).
eff_max (float, dict) – Max value of hot and cold side heat exchanger effectiveness values \(eff_\text{max}/\text{1}\).
UA (float, dict) – Sum of UA in all sections of the heat exchanger.
td_pinch (float, dict) – Value of the lowest delta T between hot side and cold side at the different sections.
UA_cecchinato (dict) – Group specification for partload UA modification according to [24], for usage see details in the
tespy.components.heat_exchangers.movingboundary.MovingBoundaryHeatExchanger.UA_cecchinato_func(). This method can only be used in offdesign simulations!alpha_ration (float) – Secondary fluid to refrigerant heat transfer coefficient ratio.
area_ration (float) – Secondary fluid to refrigerant heat transfer area ratio.
re_exp_r (float) – Reynolds exponent for refrigerant side.
re_exp_sf (float) – Reynolds exponent for secondary fluid side.
refrigerant_index (int) – Connection index for the refrigerant side, 0 if refrigerant is on hot side, 1 if refrigerant is on cold side.
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", "temperature": "degC" ... }) >>> nw.set_attr(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
HeatExchangerkA 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 [24]. For this you have to specify
UA_cecchinatoas offdesign parameter and along with it, values forrefrigerant 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)
>>> import os >>> nw.save("design.json") >>> 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.json")
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.json") >>> 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 >>> os.remove("design.json")
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:
SimpleHeatExchangerThe ParabolicTrough calculates heat output from irradiance.
Mandatory Equations
fluid:
tespy.components.component.Component.variable_equality_structure_matrix()mass flow:
tespy.components.component.Component.variable_equality_structure_matrix()
Optional Equations
tespy.components.heat_exchangers.simple.SimpleHeatExchanger.energy_balance_func()tespy.components.heat_exchangers.simple.SimpleHeatExchanger.darcy_func()tespy.components.heat_exchangers.simple.SimpleHeatExchanger.hazen_williams_func()tespy.components.heat_exchangers.parabolic_trough.ParabolicTrough.energy_group_func()
Inlets/Outlets
in1
out1
Image
- Parameters:
label (str) – The label of the component.
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.
local_offdesign (boolean) – Treat this component in offdesign mode in a design calculation.
local_design (boolean) – Treat this component in design mode in an offdesign calculation.
char_warnings (boolean) – Ignore warnings on default characteristics usage for this component.
printout (boolean) – Include this component in the network’s results printout.
Q (float, dict,
"var") – Heat transfer, \(Q/\text{W}\).pr (float, dict,
"var") – Outlet to inlet pressure ratio, \(pr/1\).zeta (float, dict,
"var") – Geometry independent friction coefficient, \(\frac{\zeta}{D^4}/\frac{1}{\text{m}^4}\).D (float, dict,
"var") – Diameter of the absorber tube, \(D/\text{m}\).L (float, dict,
"var") – Length of the absorber tube, \(L/\text{m}\).ks (float, dict,
"var") – Pipe’s roughness, \(ks/\text{m}\).darcy_group (str, dict) – Parametergroup for pressure drop calculation based on pipes dimensions using darcy weissbach equation.
ks_HW (float, dict,
"var") – Pipe’s roughness, \(ks/\text{1}\).hw_group (str, dict) – Parametergroup for pressure drop calculation based on pipes dimensions using hazen williams equation.
E (float, dict,
"var") – Direct irradiance to tilted collector, \(E/\frac{\text{W}}{\text{m}^2}\).aoi (float, dict,
"var") – Angle of incidience, \(aoi/^\circ\).doc (float, dict,
"var") – Degree of cleanliness (1: full absorption, 0: no absorption), \(X\).eta_opt (float, dict,
"var") – (constant) optical losses due to surface reflection, \(\eta_{opt}\).c_1 (float, dict,
"var") – Linear thermal loss key figure, \(c_1/\frac{\text{W}}{\text{K} \cdot \text{m}^2}\).c_2 (float, dict,
"var") – Quadratic thermal loss key figure, \(c_2/\frac{\text{W}}{\text{K}^2 \cdot \text{m}^2}\).iam_1 (float, dict,
"var") – Linear incidence angle modifier, \(iam_1/\frac{1}{^\circ}\).iam_2 (float, dict,
"var") – Quadratic incidence angle modifier, \(iam_2/\left(\frac{1}{^\circ}\right)^2\).A (float, dict,
"var") – Collector aperture surface area \(A/\text{m}^2\).Tamb (float, dict) – Ambient temperature, provide parameter in network’s temperature unit.
energy_group (str, dict) – Parametergroup for energy balance of solarthermal collector.
Example
A parabolic trough is installed using S800 as thermo-fluid. First, the operation conditions from [27] are reproduced. Therefore, the direct normal irradiance \(\dot{E}_\mathrm{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", "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
- 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: [27].
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:
HeatExchangerClass for parallel flow heat exchanger.
Mandatory Equations
fluid:
tespy.components.component.Component.variable_equality_structure_matrix()mass flow:
tespy.components.component.Component.variable_equality_structure_matrix()tespy.components.heat_exchangers.base.HeatExchanger.energy_balance_func()
Optional Equations
tespy.components.heat_exchangers.base.HeatExchanger.energy_balance_hot_func()tespy.components.heat_exchangers.base.HeatExchanger.kA_func()tespy.components.heat_exchangers.base.HeatExchanger.kA_char_func()tespy.components.heat_exchangers.base.HeatExchanger.ttd_u_func()tespy.components.heat_exchangers.base.HeatExchanger.ttd_l_func()
For hot and cold side individually:
Inlets/Outlets
in1, in2 (index 1: hot side, index 2: cold side)
out1, out2 (index 1: hot side, index 2: cold side)
Image
- Parameters:
label (str) – The label of the component.
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.
local_offdesign (boolean) – Treat this component in offdesign mode in a design calculation.
local_design (boolean) – Treat this component in design mode in an offdesign calculation.
char_warnings (boolean) – Ignore warnings on default characteristics usage for this component.
printout (boolean) – Include this component in the network’s results printout.
Q (float, dict) – Heat transfer, \(Q/\text{W}\).
pr1 (float, dict) – Outlet to inlet pressure ratio at hot side, \(pr/1\).
pr2 (float, dict) – Outlet to inlet pressure ratio at cold side, \(pr/1\).
dp1 (float, dict,) – Inlet to outlet pressure delta at hot side, \(dp/\text{Pa}\)
dp2 (float, dict) – Inlet to outlet pressure delta at cold side, \(dp\text{Pa}\).
zeta1 (float, dict) – Geometry independent friction coefficient at hot side, \(\frac{\zeta}{D^4}/\frac{1}{\text{m}^4}\).
zeta2 (float, dict) – Geometry independent friction coefficient at cold side, \(\frac{\zeta}{D^4}/\frac{1}{\text{m}^4}\).
ttd_l (float, dict) – Initial terminal temperature difference, referring to the temperature difference between the two inlets of the heat exchanger, \(ttd_\mathrm{l}/\text{K}\).
ttd_u (float, dict) – Final terminal temperature difference, referring to the temperature difference between the two outlets of the heat exchanger, \(ttd_\mathrm{u}/\text{K}\).
kA (float, dict) – Area independent heat transfer coefficient, \(kA/\frac{\text{W}}{\text{K}}\).
kA_char (dict) – Area independent heat transfer coefficient characteristic.
kA_char1 (tespy.tools.characteristics.CharLine, dict) – Characteristic line for hot side heat transfer coefficient.
kA_char2 (tespy.tools.characteristics.CharLine, dict) – Characteristic line for cold side heat transfer coefficient.
Note
The
ParallelFlowHeatExchangerimplements 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 >>> import os >>> nw = Network(iterinfo=False) >>> nw.units.set_defaults(**{ ... "pressure": "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_uof 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 coefficientkAas 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
kAvalue instead of the final pinch and then resolve again.>>> he.set_attr(design=["ttd_u"], offdesign=["kA"]) >>> nw.save("design.json") >>> nw.solve("offdesign", design_path="design.json") >>> round(he.kA.val_SI / he.kA.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.json") >>> round(c2.T.val, 2) 38.69 >>> c3.set_attr(v=2500, T=8) >>> nw.solve("offdesign", design_path="design.json") >>> round(c2.T.val, 2) 44.0 >>> os.remove("design.json")
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:
HeatExchangerClass 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 on the model implemented by [28].
Mandatory Equations
fluid:
tespy.components.component.Component.variable_equality_structure_matrix()mass flow:
tespy.components.component.Component.variable_equality_structure_matrix()tespy.components.heat_exchangers.base.HeatExchanger.energy_balance_func()
Optional Equations
tespy.components.heat_exchangers.base.HeatExchanger.energy_balance_hot_func()tespy.components.heat_exchangers.sectioned.SectionedHeatExchanger.UA_func()tespy.components.heat_exchangers.sectioned.SectionedHeatExchanger.td_pinch_func()tespy.components.heat_exchangers.sectioned.SectionedHeatExchanger.UA_cecchinato_func()tespy.components.heat_exchangers.base.HeatExchanger.ttd_u_func()tespy.components.heat_exchangers.base.HeatExchanger.ttd_l_func()tespy.components.heat_exchangers.base.HeatExchanger.ttd_min_func()tespy.components.heat_exchangers.base.HeatExchanger.eff_cold_func()tespy.components.heat_exchangers.base.HeatExchanger.eff_hot_func()tespy.components.heat_exchangers.base.HeatExchanger.eff_max_func()
For hot and cold side individually:
Inlets/Outlets
in1, in2 (index 1: hot side, index 2: cold side)
out1, out2 (index 1: hot side, index 2: cold side)
Image
- Parameters:
label (str) – The label of the component.
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.
local_offdesign (boolean) – Treat this component in offdesign mode in a design calculation.
local_design (boolean) – Treat this component in design mode in an offdesign calculation.
char_warnings (boolean) – Ignore warnings on default characteristics usage for this component.
printout (boolean) – Include this component in the network’s results printout.
Q (float, dict) – Heat transfer, \(Q/\text{W}\).
pr1 (float, dict,
"var") – Outlet to inlet pressure ratio at hot side, \(pr/1\).pr2 (float, dict,
"var") – Outlet to inlet pressure ratio at cold side, \(pr/1\).dp1 (float, dict,
"var") – Inlet to outlet pressure delta at hot side, unit is the network’s pressure unit!.dp2 (float, dict,
"var") – Inlet to outlet pressure delta at cold side, unit is the network’s pressure unit!.zeta1 (float, dict,
"var") – Geometry independent friction coefficient at hot side, \(\frac{\zeta}{D^4}/\frac{1}{\text{m}^4}\).zeta2 (float, dict,
"var") – Geometry independent friction coefficient at cold side, \(\frac{\zeta}{D^4}/\frac{1}{\text{m}^4}\).ttd_l (float, dict) – Lower terminal temperature difference \(ttd_\mathrm{l}/\text{K}\).
ttd_u (float, dict) – Upper terminal temperature difference \(ttd_\mathrm{u}/\text{K}\).
ttd_min (float, dict) – Minimum terminal temperature difference \(ttd_\mathrm{min}/\text{K}\).
eff_cold (float, dict) – Cold side heat exchanger effectiveness \(eff_\text{cold}/\text{1}\).
eff_hot (float, dict) – Hot side heat exchanger effectiveness \(eff_\text{hot}/\text{1}\).
eff_max (float, dict) – Max value of hot and cold side heat exchanger effectiveness values \(eff_\text{max}/\text{1}\).
UA (float, dict) – Sum of UA in all sections of the heat exchanger.
td_pinch (float, dict) – Value of the lowest delta T between hot side and cold side at the different sections.
num_sections (int) – Number of sections.
UA_cecchinato (dict) – Group specification for partload UA modification according to [24], for usage see details in the
tespy.components.heat_exchangers.sectioned.SectionedHeatExchanger.UA_cecchinato_func(). This method can only be used in offdesign simulations!alpha_ration (float) – Secondary fluid to refrigerant heat transfer coefficient ratio.
area_ration (float) – Secondary fluid to refrigerant heat transfer area ratio.
re_exp_r (float) – Reynolds exponent for refrigerant side.
re_exp_sf (float) – Reynolds exponent for secondary fluid side.
refrigerant_index (int) – Connection index for the refrigerant side, 0 if refrigerant is on hot side, 1 if refrigerant is on cold side.
Note
The equations only apply to counter-current heat exchangers.
Example
Water vapor should be cooled down, condensed and then further subcooled. For his 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", "temperature": "degC" ... }) >>> nw.set_attr(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
HeatExchangerkA 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 [24]. For this you have to specify
UA_cecchinatoas offdesign parameter and along with it, values forrefrigerant 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)
>>> import os >>> nw.save("design.json") >>> 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.json")
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.json") >>> 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 >>> os.remove("design.json")
- UA_cecchinato_func()[source]¶
Method to calculate heat transfer via UA design with modification for part load according to [24]. 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_func(**kwargs)[source]¶
Residual method for fixed heat transfer coefficient UA.
- Returns:
residual (float) – Residual value of equation.
\[0 = UA - \sum UA_\text{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_sections(postprocess=True)[source]¶
Calculate the sections of the heat exchanger.
- Returns:
tuple – Cumulated heat transfer over sections, temperature at steps hot side, temperature at steps cold side, heat transfer per section
- 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:
ComponentA basic heat exchanger representing a heat source or heat sink.
The component SimpleHeatExchanger is the parent class for the components:
tespy.components.heat_exchangers.solar_collector.SolarCollectortespy.components.heat_exchangers.parabolic_trough.ParabolicTrough
Mandatory Equations
fluid:
tespy.components.component.Component.variable_equality_structure_matrix()mass flow:
tespy.components.component.Component.variable_equality_structure_matrix()
Optional Equations
tespy.components.heat_exchangers.simple.SimpleHeatExchanger.energy_balance_func()tespy.components.heat_exchangers.simple.SimpleHeatExchanger.darcy_func()tespy.components.heat_exchangers.simple.SimpleHeatExchanger.hazen_williams_func()tespy.components.heat_exchangers.simple.SimpleHeatExchanger.kA_group_func()tespy.components.heat_exchangers.simple.SimpleHeatExchanger.kA_char_group_func()
Inlets/Outlets
in1
out1
Image
- Parameters:
label (str) – The label of the component.
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.
local_offdesign (boolean) – Treat this component in offdesign mode in a design calculation.
local_design (boolean) – Treat this component in design mode in an offdesign calculation.
char_warnings (boolean) – Ignore warnings on default characteristics usage for this component.
printout (boolean) – Include this component in the network’s results printout.
Q (float, dict,
"var") – Heat transfer, \(Q/\text{W}\).pr (float, dict,
"var") – Outlet to inlet pressure ratio, \(pr/1\).zeta (float, dict,
"var") – Geometry independent friction coefficient, \(\frac{\zeta}{D^4}/\frac{1}{\text{m}^4}\).D (float, dict,
"var") – Diameter of the pipes, \(D/\text{m}\).L (float, dict,
"var") – Length of the pipes, \(L/\text{m}\).ks (float, dict,
"var") – Pipe’s roughness, \(ks/\text{m}\).darcy_group (str, dict) – Parametergroup for pressure drop calculation based on pipes dimensions using darcy weissbach equation.
ks_HW (float, dict,
"var") – Pipe’s roughness, \(ks/\text{1}\).hw_group (str, dict) – Parametergroup for pressure drop calculation based on pipes dimensions using hazen williams equation.
kA (float, dict,
"var") – Area independent heat transfer coefficient, \(kA/\frac{\text{W}}{\text{K}}\).kA_char (tespy.tools.characteristics.CharLine, dict) – Characteristic line for heat transfer coefficient.
Tamb (float, dict) – Ambient temperature, provide parameter in network’s temperature unit.
kA_group (str, dict) – Parametergroup for heat transfer calculation from ambient temperature and area independent heat transfer coefficient kA.
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 coeffiecient, it is possible to predict heat transfer.
>>> from tespy.components import Sink, Source, SimpleHeatExchanger >>> from tespy.connections import Connection >>> from tespy.networks import Network >>> import os >>> nw = Network(iterinfo=False) >>> nw.units.set_defaults(**{ ... "pressure": "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', 'kA_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') >>> nw.save('tmp.json') >>> 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='tmp.json') >>> 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='tmp.json') >>> round(heat_sink.Q.val, 1) -47275.8 >>> round(outg.T.val, 1) 140.0 >>> os.remove('tmp.json')
Use of the PowerConnection¶
Single sided heat exchangers can also connect to a
PowerConnection. In this case the heat exchanger represents a heat source from the perspective of thePowerConnection, meaning, we need aPowerSinkcomponent as target of that connection. To utilize the component in this connects, it is required to set thepower_connector_location, in this case it should be the'outlet'.>>> from tespy.connections import PowerConnection >>> from tespy.components import PowerSink >>> ambient = PowerSink('ambient heat dissipation') >>> heat_sink.set_attr(power_connector_location='outlet')
Then we can create and add the
PowerConnection. We run a new design calculation, because the old design case did not inlcude thePowerConnection. The energy value will be identical to the heat transfer of the pipe.>>> h1 = PowerConnection(heat_sink, 'heat', ambient, 'power', label='h1') >>> nw.add_conns(h1) >>> nw.solve('design') >>> round(h1.E.val) == round(-heat_sink.Q.val) True
- bus_deriv(bus)[source]¶
Calculate partial derivatives of the bus function.
- Parameters:
bus (tespy.connections.bus.Bus) – TESPy bus object.
- Returns:
deriv (ndarray) – Matrix of partial derivatives.
- bus_func(bus)[source]¶
Calculate the value of the bus function.
- Parameters:
bus (tespy.connections.bus.Bus) – TESPy bus object.
- Returns:
val (float) – Value of energy transfer \(\dot{E}\). This value is passed to
tespy.components.component.Component.calc_bus_value()for value manipulation according to the specified characteristic line of the bus.\[\dot{E} = \dot{m}_{in} \cdot \left( h_{out} - h_{in} \right)\]
- 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_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}\]
- 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_\mathrm{out} - h_\mathrm{in} = \int_\mathrm{out}^\mathrm{in} v \cdot dp - \int_\mathrm{out}^\mathrm{in} T \cdot ds\]As solving \(\int_\mathrm{out}^\mathrm{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 splitted into three separate virtual processes:
in->in*: decrease pressure to \(p_\mathrm{in*}=p_\mathrm{in}\cdot\sqrt{\frac{p_\mathrm{out}}{p_\mathrm{in}}}\) without changing enthalpy.
in*->out* transfer heat without changing pressure. \(h_\mathrm{out*}-h_\mathrm{in*}=h_\mathrm{out}-h_\mathrm{in}\)
out*->out decrease pressure to outlet pressure \(p_\mathrm{out}\) without changing enthalpy.
Note
The entropy balance makes the follwing parameter available:
\[\begin{split}\text{S\_Q}=\dot{m} \cdot \left(s_\mathrm{out*}-s_\mathrm{in*} \right)\\ \text{S\_irr}=\dot{m} \cdot \left(s_\mathrm{out}-s_\mathrm{in} \right) - \text{S\_Q}\\ \text{T\_mQ}=\frac{\dot{Q}}{\text{S\_Q}}\end{split}\]
- exergy_balance(T0)[source]¶
Calculate exergy balance of a simple heat exchanger.
The exergy of heat is calculated by allocation of thermal and mechanical share of exergy in the physical exergy. Depending on the temperature levels at the inlet and outlet of the heat exchanger as well as the direction of heat transfer (input or output) fuel and product exergy are calculated as follows.
- Parameters:
T0 (float) – Ambient temperature T0 / K.
Note
If the fluid transfers heat to the ambient, you can specify
mysimpleheatexchanger.set_attr(dissipative=False)if you do NOT want the exergy production nan (only applicable in case \(\dot{Q}<0\)).\[ \begin{align}\begin{aligned}\begin{split}\dot{E}_\mathrm{P} = \begin{cases} \begin{cases} \begin{cases} \text{not defined (nan)} & \text{if dissipative}\\ \dot{E}_\mathrm{in}^\mathrm{T} - \dot{E}_\mathrm{out}^\mathrm{T} & \text{else}\\ \end{cases} & T_\mathrm{in}, T_\mathrm{out} \geq T_0\\ \dot{E}_\mathrm{out}^\mathrm{T} & T_\mathrm{in} \geq T_0 > T_\mathrm{out}\\ \dot{E}_\mathrm{out}^\mathrm{T} - \dot{E}_\mathrm{in}^\mathrm{T} & T_0 \geq T_\mathrm{in}, T_\mathrm{out}\\ \end{cases} & \dot{Q} < 0\\\end{split}\\\begin{split}\begin{cases} \dot{E}_\mathrm{out}^\mathrm{PH} - \dot{E}_\mathrm{in}^\mathrm{PH} & T_\mathrm{in}, T_\mathrm{out} \geq T_0\\ \dot{E}_\mathrm{in}^\mathrm{T} + \dot{E}_\mathrm{out}^\mathrm{T} & T_\mathrm{out} > T_0 \geq T_\mathrm{in}\\ \dot{E}_\mathrm{in}^\mathrm{T} - \dot{E}_\mathrm{out}^\mathrm{T} + \dot{E}_\mathrm{out}^\mathrm{M} - \dot{E}_\mathrm{in}^\mathrm{M} + & T_0 \geq T_\mathrm{in}, T_\mathrm{out}\\ \end{cases} & \dot{Q} > 0\\ \end{cases}\end{split}\\\begin{split}\dot{E}_\mathrm{F} = \begin{cases} \begin{cases} \dot{E}_\mathrm{in}^\mathrm{PH} - \dot{E}_\mathrm{out}^\mathrm{PH} & T_\mathrm{in}, T_\mathrm{out} \geq T_0\\ \dot{E}_\mathrm{in}^\mathrm{T} + \dot{E}_\mathrm{in}^\mathrm{M} + \dot{E}_\mathrm{out}^\mathrm{T} - \dot{E}_\mathrm{out}^\mathrm{M} & T_\mathrm{in} \geq T_0 > T_\mathrm{out}\\ \dot{E}_\mathrm{out}^\mathrm{T} - \dot{E}_\mathrm{in}^\mathrm{T} + \dot{E}_\mathrm{in}^\mathrm{M} - \dot{E}_\mathrm{out}^\mathrm{M} + & T_0 \geq T_\mathrm{in}, T_\mathrm{out}\\ \end{cases} & \dot{Q} < 0\\\end{split}\\\begin{split}\begin{cases} \dot{E}_\mathrm{out}^\mathrm{T} - \dot{E}_\mathrm{in}^\mathrm{T} & T_\mathrm{in}, T_\mathrm{out} \geq T_0\\ \dot{E}_\mathrm{in}^\mathrm{T} + \dot{E}_\mathrm{in}^\mathrm{M} - \dot{E}_\mathrm{out}^\mathrm{M} & T_\mathrm{out} > T_0 \geq T_\mathrm{in}\\ \dot{E}_\mathrm{in}^\mathrm{T}-\dot{E}_\mathrm{out}^\mathrm{T} & T_0 \geq T_\mathrm{in}, T_\mathrm{out}\\ \end{cases} & \dot{Q} > 0\\ \end{cases}\end{split}\\\begin{split}\dot{E}_\mathrm{bus} = \begin{cases} \begin{cases} \dot{E}_\mathrm{P} & \text{other cases}\\ \dot{E}_\mathrm{in}^\mathrm{T} & T_\mathrm{in} \geq T_0 > T_\mathrm{out}\\ \end{cases} & \dot{Q} < 0\\ \dot{E}_\mathrm{F} & \dot{Q} > 0\\ \end{cases}\end{split}\end{aligned}\end{align} \]
- 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_isolinemethod of theFluidPropertyDiagramclass. First level keys are the connection index (‘in1’ -> ‘out1’, therefore1etc.).
- 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}\)
- 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}\]
- kA_char_group_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} \cdot \left( h_{out} - h_{in}\right) + kA_{design} \cdot f_{kA} \cdot \Delta T_{log}\\\begin{split}\Delta T_{log} = \begin{cases} \frac{T_{in}-T_{out}}{\ln{\frac{T_{in}-T_{amb}} {T_{out}-T_{amb}}}} & T_{in} > T_{out} \\ \frac{T_{out}-T_{in}}{\ln{\frac{T_{out}-T_{amb}} {T_{in}-T_{amb}}}} & T_{in} < T_{out}\\ 0 & T_{in} = T_{out} \end{cases}\end{split}\\f_{kA} = \frac{2}{1 + \frac{1}{f\left( expr\right)}}\\T_{amb}: \text{ambient temperature}\end{aligned}\end{align} \]
Note
For standard function of fkA see module tespy.data.
- kA_group_func()[source]¶
Calculate heat transfer from heat transfer coefficient.
- Returns:
residual (float) – Residual value of equation.
\[ \begin{align}\begin{aligned}0 = \dot{m}_{in} \cdot \left( h_{out} - h_{in}\right) + kA \cdot \Delta T_{log}\\\begin{split}\Delta T_{log} = \begin{cases} \frac{T_{in}-T_{out}}{\ln{\frac{T_{in}-T_{amb}} {T_{out}-T_{amb}}}} & T_{in} > T_{out} \\ \frac{T_{out}-T_{in}}{\ln{\frac{T_{out}-T_{amb}} {T_{in}-T_{amb}}}} & T_{in} < T_{out}\\ 0 & T_{in} = T_{out} \end{cases}\end{split}\\T_{amb}: \text{ambient temperature}\end{aligned}\end{align} \]
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:
SimpleHeatExchangerThe solar collector calculates heat output from irradiance.
Mandatory Equations
fluid:
tespy.components.component.Component.variable_equality_structure_matrix()mass flow:
tespy.components.component.Component.variable_equality_structure_matrix()
Optional Equations
tespy.components.heat_exchangers.simple.SimpleHeatExchanger.energy_balance_func()tespy.components.heat_exchangers.simple.SimpleHeatExchanger.darcy_func()tespy.components.heat_exchangers.simple.SimpleHeatExchanger.hazen_williams_func()tespy.components.heat_exchangers.solar_collector.SolarCollector.energy_group_func()
Inlets/Outlets
in1
out1
Image
- Parameters:
label (str) – The label of the component.
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.
local_offdesign (boolean) – Treat this component in offdesign mode in a design calculation.
local_design (boolean) – Treat this component in design mode in an offdesign calculation.
char_warnings (boolean) – Ignore warnings on default characteristics usage for this component.
printout (boolean) – Include this component in the network’s results printout.
Q (float, dict,
"var") – Heat transfer, \(Q/\text{W}\).pr (float, dict,
"var") – Outlet to inlet pressure ratio, \(pr/1\).zeta (float, dict,
"var") – Geometry independent friction coefficient, \(\frac{\zeta}{D^4}/\frac{1}{\text{m}^4}\).D (float, dict,
"var") – Diameter of the pipes, \(D/\text{m}\).L (float, dict,
"var") – Length of the pipes, \(L/\text{m}\).ks (float, dict,
"var") – Pipe’s roughness, \(ks/\text{m}\).darcy_group (str, dict) – Parametergroup for pressure drop calculation based on pipes dimensions using darcy weissbach equation.
ks_HW (float, dict,
"var") – Pipe’s roughness, \(ks/\text{1}\).hw_group (str, dict) – Parametergroup for pressure drop calculation based on pipes dimensions using hazen williams equation.
E (float, dict,
"var") – irradiance at tilted collector surface area, \(E/\frac{\text{W}}{\text{m}^2}\).eta_opt (float, dict,
"var") – optical loss at surface cover, \(\eta_{opt}\).lkf_lin (float, dict,
"var") – Linear thermal loss key figure, \(\alpha_1/\frac{\text{W}}{\text{K} \cdot \text{m}^2}\).lkf_quad (float, dict,
"var") – Quadratic thermal loss key figure, \(\alpha_2/\frac{\text{W}}{\text{K}^2 \cdot \text{m}^2}\).A (float, dict,
"var") – Collector surface area \(A/\text{m}^2\).Tamb (float, dict) – Ambient temperature, provide parameter in network’s temperature unit.
energy_group (str, dict) – Parametergroup for energy balance of solarthermal collector.
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 >>> import os >>> nw = Network(iterinfo=False) >>> nw.units.set_defaults(**{ ... "pressure": "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'], ... 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 calulate 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') >>> nw.save('tmp.json') >>> round(sc.A.val, 1) 14.5 >>> sc.set_attr(A=sc.A.val, E=5e2, Tamb=20) >>> nw.solve('offdesign', design_path='tmp.json') >>> round(sc.Q.val, 1) 6083.8 >>> round(outg.T.val, 1) 70.5 >>> os.remove('tmp.json')
- 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: [29].