Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
fwitte committed Dec 4, 2024
2 parents fc7dd13 + c5ca7bc commit a1880e7
Show file tree
Hide file tree
Showing 11 changed files with 275 additions and 90 deletions.
18 changes: 10 additions & 8 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
Thermal Engineering Systems in Python
=====================================
TESPy stands for "Thermal Engineering Systems in Python" and provides a
powerful simulation toolkit for thermal engineering plants such as power
plants, district heating systems or heat pumps. It is an external extension
module within the Open Energy Modelling Framework `oemof <https://oemof.org/>`_
and can be used as a standalone package.
powerful simulation toolkit for thermal engineering plants such as various
types of power plants (including organic rankine cycles), heat pumps or
refrigeration machines. Due to its flexibility it is actually possible to
model any kind of thermal energy conversion process, this also includes energy
balancing of industrial processes, district heating or HVAC systems. It is
part of the Open Energy Modelling Framework `oemof <https://oemof.org/>`_ and
can be used as a standalone package.

.. figure:: https://raw.githubusercontent.com/oemof/tespy/9915f013c40fe418947a6e4c1fd0cd0eba45893c/docs/api/_images/logo_tespy_big.svg
:align: center
Expand All @@ -28,10 +31,9 @@ Key Features
============
* **Open** Source
* **Generic** thermal engineering applications
* **Automatic** model documentation in LaTeX for high transparency and
reproducibility
* **Extendable** framework for the implementation of custom components and
component groups
* **Extendable** framework for the implementation of custom components, fluid
property formulations and equations
* **Integration** of optimization capabilities through an API to pygmo
* **Postprocessing** features like exergy analysis and fluid property plotting

.. start-badges
Expand Down
22 changes: 12 additions & 10 deletions docs/introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ Thermal Engineering Systems in Python
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

TESPy stands for "Thermal Engineering Systems in Python" and provides a
powerful simulation toolkit for thermal engineering plants such as power
plants, district heating systems or heat pumps. It is an external extension
module within the Open Energy Modeling Framework `oemof <https://oemof.org/>`_
and can be used as a standalone package.
powerful simulation toolkit for thermal engineering plants such as various
types of power plants (including organic rankine cycles), heat pumps or
refrigeration machines. Due to its flexibility it is actually possible to
model any kind of thermal energy conversion process, this also includes energy
balancing of industrial processes, district heating or HVAC systems. It is
part of the Open Energy Modelling Framework `oemof <https://oemof.org/>`_ and
can be used as a standalone package.

.. image:: /_static/images/logo_tespy_big.svg
:align: center
Expand All @@ -28,18 +31,17 @@ mixers and splitters as well as some advanced components
Everybody is welcome to use and/or develop TESPy. Contribution is already
possible on a low level by simply fixing typos in TESPy's documentation or
rephrasing sections which are unclear. If you want to support us that way
please fork the TESPy repository to your own GitHub account and make
changes as described in the GitHub guidelines:
please fork the `TESPy repository <https://github.com/oemof/tespy>`_ to your
own GitHub account and make changes as described in the GitHub guidelines:
https://guides.github.com/activities/hello-world/

Key Features
============
* **Open** Source
* **Generic** thermal engineering applications
* **Automatic** model documentation in LaTeX for high transparency and
reproducibility
* **Extendable** framework for the implementation of custom components and
component groups
* **Extendable** framework for the implementation of custom components, fluid
property formulations and equations
* **Integration** of optimization capabilities through an API to pygmo
* **Postprocessing** features like exergy analysis and fluid property plotting

Quick installation
Expand Down
1 change: 1 addition & 0 deletions docs/whats_new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ What's New

Discover notable new features and improvements in each release

.. include:: whats_new/v0-7-8.rst
.. include:: whats_new/v0-7-7.rst
.. include:: whats_new/v0-7-6-001.rst
.. include:: whats_new/v0-7-6.rst
Expand Down
4 changes: 2 additions & 2 deletions docs/whats_new/v0-7-7.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Under development
+++++++++++++++++
v0.7.7 - Newton's Nature (October, 27, 2024)
++++++++++++++++++++++++++++++++++++++++++++

Bug Fixes
#########
Expand Down
14 changes: 14 additions & 0 deletions docs/whats_new/v0-7-8.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
v0.7.8 - Newton's Nature (December, 04, 2024)
+++++++++++++++++++++++++++++++++++++++++++++

New Features
############
- The `HeatExchanger` class now has three new attributes, :code:`dp1`,
:code:`dp2` (hot side and cold side pressure drop in network pressure unit)
as well as :code:`ttd_min` for the minimal value of the terminal temperature
diference values
(`PR #581 <https://github.com/oemof/tespy/pull/581>`__).

Contributors
############
- Francesco Witte (`@fwitte <https://github.com/fwitte>`__)
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ exclude = ["docs/_build"]

[project]
name = "tespy"
version = "0.7.7"
version = "0.7.8"
description = "Thermal Engineering Systems in Python (TESPy)"
readme = "README.rst"
authors = [
Expand Down
2 changes: 1 addition & 1 deletion src/tespy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import os

__datapath__ = os.path.join(importlib.resources.files("tespy"), "data")
__version__ = '0.7.7 - Newton\'s Nature'
__version__ = '0.7.8 - Newton\'s Nature'

# tespy data and connections import
from . import connections # noqa: F401
Expand Down
58 changes: 58 additions & 0 deletions src/tespy/components/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -1230,3 +1230,61 @@ def zeta_deriv(self, increment_filter, k, zeta='', inconn=0, outconn=0):
# custom variable zeta
if data.is_var:
self.jacobian[k, data.J_col] = self.numeric_deriv(f, zeta, None, **kwargs)

def dp_func(self, dp=None, inconn=None, outconn=None):
"""Calculate residual value of pressure difference function.
Parameters
----------
dp : str
Component parameter to evaluate the dp_func on, e.g.
:code:`dp1`.
inconn : int
Connection index of inlet.
outconn : int
Connection index of outlet.
Returns
-------
residual : float
Residual value of function.
.. math::
0 = p_{in} - p_{out} - dp
"""
inlet_conn = self.inl[inconn]
outlet_conn = self.outl[outconn]
dp_value = self.get_attr(dp).val_SI
return inlet_conn.p.val_SI - outlet_conn.p.val_SI - dp_value

def dp_deriv(self, increment_filter, k, dp=None, inconn=None, outconn=None):
r"""
Calculate residual value of pressure difference function.
Parameters
----------
increment_filter : ndarray
Matrix for filtering non-changing variables.
k : int
Position of equation in Jacobian matrix.
dp : str
Component parameter to evaluate the dp_func on, e.g.
:code:`dp1`.
inconn : int
Connection index of inlet.
outconn : int
Connection index of outlet.
"""
inlet_conn = self.inl[inconn]
outlet_conn = self.outl[outconn]
if inlet_conn.p.is_var:
self.jacobian[k, inlet_conn.p.J_col] = 1
if outlet_conn.p.is_var:
self.jacobian[k, outlet_conn.p.J_col] = -1
98 changes: 94 additions & 4 deletions src/tespy/components/heat_exchangers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from tespy.tools.document_models import generate_latex_eq
from tespy.tools.fluid_properties import h_mix_pT
from tespy.tools.fluid_properties import s_mix_ph
from tespy.tools.helpers import convert_from_SI
from tespy.tools.helpers import convert_to_SI


@component_registry
Expand All @@ -46,13 +48,16 @@ class HeatExchanger(Component):
- :py:meth:`tespy.components.heat_exchangers.base.HeatExchanger.kA_char_func`
- :py:meth:`tespy.components.heat_exchangers.base.HeatExchanger.ttd_u_func`
- :py:meth:`tespy.components.heat_exchangers.base.HeatExchanger.ttd_l_func`
- :py:meth:`tespy.components.heat_exchangers.base.HeatExchanger.ttd_min_func`
- :py:meth:`tespy.components.heat_exchangers.base.HeatExchanger.eff_cold_func`
- :py:meth:`tespy.components.heat_exchangers.base.HeatExchanger.eff_hot_func`
- :py:meth:`tespy.components.heat_exchangers.base.HeatExchanger.eff_max_func`
- hot side :py:meth:`tespy.components.component.Component.pr_func`
- cold side :py:meth:`tespy.components.component.Component.pr_func`
- hot side :py:meth:`tespy.components.component.Component.zeta_func`
- cold side :py:meth:`tespy.components.component.Component.zeta_func`
- hot side :py:meth:`tespy.components.component.Component.dp_func`
- cold side :py:meth:`tespy.components.component.Component.dp_func`
Inlets/Outlets
Expand Down Expand Up @@ -106,6 +111,12 @@ class HeatExchanger(Component):
pr2 : float, dict, :code:`"var"`
Outlet to inlet pressure ratio at cold side, :math:`pr/1`.
dp1 : float, dict, :code:`"var"`
Inlet to outlet pressure delta at hot side, :math:`dp/\text{Pa}`.
dp2 : float, dict, :code:`"var"`
Inlet to outlet pressure delta at cold side, :math:`dp/\text{Pa}`.
zeta1 : float, dict, :code:`"var"`
Geometry independent friction coefficient at hot side,
:math:`\frac{\zeta}{D^4}/\frac{1}{\text{m}^4}`.
Expand All @@ -120,6 +131,9 @@ class HeatExchanger(Component):
ttd_u : float, dict
Upper terminal temperature difference :math:`ttd_\mathrm{u}/\text{K}`.
ttd_min : float, dict
Minumum terminal temperature difference :math:`ttd_\mathrm{min}/\text{K}`.
eff_cold : float, dict
Cold side heat exchanger effectiveness :math:`eff_\text{cold}/\text{1}`.
Expand Down Expand Up @@ -229,6 +243,9 @@ def get_parameters(self):
'ttd_l': dc_cp(
min_val=0, num_eq=1, func=self.ttd_l_func,
deriv=self.ttd_l_deriv, latex=self.ttd_l_func_doc),
'ttd_min': dc_cp(
min_val=0, num_eq=1, func=self.ttd_min_func,
deriv=self.ttd_min_deriv),
'pr1': dc_cp(
min_val=1e-4, max_val=1, num_eq=1, deriv=self.pr_deriv,
latex=self.pr_func_doc,
Expand All @@ -237,6 +254,14 @@ def get_parameters(self):
min_val=1e-4, max_val=1, num_eq=1, latex=self.pr_func_doc,
deriv=self.pr_deriv, func=self.pr_func,
func_params={'pr': 'pr2', 'inconn': 1, 'outconn': 1}),
'dp1': dc_cp(
min_val=0, max_val=10000, num_eq=1,
deriv=self.dp_deriv, func=self.dp_func,
func_params={'dp': 'dp1', 'inconn': 0, 'outconn': 0}),
'dp2': dc_cp(
min_val=0, max_val=10000, num_eq=1,
deriv=self.dp_deriv, func=self.dp_func,
func_params={'dp': 'dp2', 'inconn': 1, 'outconn': 1}),
'zeta1': dc_cp(
min_val=0, max_val=1e15, num_eq=1, latex=self.zeta_func_doc,
deriv=self.zeta_deriv, func=self.zeta_func,
Expand Down Expand Up @@ -285,6 +310,15 @@ def inlets():
def outlets():
return ['out1', 'out2']

def preprocess(self, num_nw_vars):
super().preprocess(num_nw_vars)

if self.dp1.is_set:
self.dp1.val_SI = convert_to_SI('p', self.dp1.val, self.inl[0].p.unit)

if self.dp2.is_set:
self.dp2.val_SI = convert_to_SI('p', self.dp2.val, self.inl[1].p.unit)

def energy_balance_func(self):
r"""
Equation for heat exchanger energy balance.
Expand Down Expand Up @@ -706,6 +740,56 @@ def ttd_l_deriv(self, increment_filter, k):
if self.is_variable(c.h, increment_filter):
self.jacobian[k, c.h.J_col] = self.numeric_deriv(f, 'h', c)

def ttd_min_func(self):
r"""
Equation for upper terminal temperature difference.
Returns
-------
residual : float
Residual value of equation.
.. math::
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)
"""
i = self.inl[1]
o = self.outl[0]
T_i2 = i.calc_T()
T_o1 = o.calc_T()

i = self.inl[0]
o = self.outl[1]
T_i1 = i.calc_T()
T_o2 = o.calc_T()

ttd_l = T_o1 - T_i2
ttd_u = T_i1 - T_o2

return self.ttd_min.val - min(ttd_l, ttd_u)

def ttd_min_deriv(self, increment_filter, k):
"""
Calculate partial derivates of minimum terminal temperature function.
Parameters
----------
increment_filter : ndarray
Matrix for filtering non-changing variables.
k : int
Position of derivatives in Jacobian matrix (k-th equation).
"""
f = self.ttd_min_func
for c in self.inl + self.outl:
if self.is_variable(c.p, increment_filter):
self.jacobian[k, c.p.J_col] = self.numeric_deriv(f, 'p', c)
if self.is_variable(c.h, increment_filter):
self.jacobian[k, c.h.J_col] = self.numeric_deriv(f, 'h', c)

def calc_dh_max_cold(self):
r"""Calculate the theoretical maximum enthalpy increase on the cold side
Expand Down Expand Up @@ -1030,20 +1114,26 @@ def initialise_target(self, c, key):

def calc_parameters(self):
r"""Postprocessing parameter calculation."""
# component parameters
self.Q.val = self.inl[0].m.val_SI * (
self.outl[0].h.val_SI - self.inl[0].h.val_SI
)
self.ttd_u.val = self.inl[0].T.val_SI - self.outl[1].T.val_SI
self.ttd_l.val = self.outl[0].T.val_SI - self.inl[1].T.val_SI
self.ttd_min.val = min(self.ttd_u.val, self.ttd_min.val)

# pr and zeta
for i in range(2):
self.get_attr('pr' + str(i + 1)).val = (
self.outl[i].p.val_SI / self.inl[i].p.val_SI)
self.get_attr('zeta' + str(i + 1)).val = self.calc_zeta(
self.get_attr(f'pr{i + 1}').val = (
self.outl[i].p.val_SI / self.inl[i].p.val_SI
)
self.get_attr(f'zeta{i + 1}').val = self.calc_zeta(
self.inl[i], self.outl[i]
)
self.get_attr(f'dp{i + 1}').val_SI = (
self.inl[i].p.val_SI - self.outl[i].p.val_SI)
self.get_attr(f'dp{i + 1}').val = convert_from_SI(
'p', self.get_attr(f'dp{i + 1}').val_SI, self.inl[i].p.unit
)

# kA and logarithmic temperature difference
if self.ttd_u.val < 0 or self.ttd_l.val < 0:
Expand Down
Loading

0 comments on commit a1880e7

Please sign in to comment.