Thermal Engineering Systems in Python (TESPy). This package provides a powerful simulation toolkit for thermal engineering plants such as power plants, district heating systems or heat pumps.

oemof, updated 🕥 2023-03-19 16:43:46

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 <>_ and can be used as a standalone package.

.. figure:: :align: center

With the TESPy package you are able to calculate stationary operation in order to design the process of thermal energy systems. From that point it is possible to simulate the offdesign behavior of your plant using underlying characteristics for each of the plants components. The package includes basic components, such as turbines, pumps, compressors, heat exchangers, pipes, mixers and splitters as well as some advanced components (derivatives of heat exchangers, drum).

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:

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
  • Postprocessing features like exergy analysis and fluid property plotting

.. start-badges

.. list-table:: :stub-columns: 1

* - docs
  - |docs|
* - tests
  - |pytests| |checks| |packaging| |coveralls|
* - package
  - | |version| |wheel| |supported-versions| |commits-since|
* - reference
  - |joss| |zenodo|

.. |docs| image:: :target: :alt: Documentation Status

.. |pytests| image:: :target: :alt: tox pytest

.. |checks| image:: :target: :alt: tox checks

.. |packaging| image:: :target: :alt: packaging

.. |coveralls| image:: :alt: Coverage Status :target:

.. |version| image:: :alt: PyPI Package latest release :target:

.. |wheel| image:: :alt: PyPI Wheel :target:

.. |supported-versions| image:: :alt: Supported Python versions :target:

.. |commits-since| image:: :alt: Commits since latest release :target:

.. |zenodo| image:: :alt: Release archive :target:

.. |joss| image:: :alt: Software Paper in JOSS :target:

.. end-badges


You can find the full documentation at readthedocs <>. Use the project site <> of readthedocs to choose the version of the documentation. Go to the download page <>_ to download different versions and formats (pdf, html, epub) of the documentation.

To get the latest news visit and follow our website <>_.

Installing TESPy

If you have a working Python3 environment, use pypi to install the latest tespy version:

.. code:: bash

pip install tespy

If you want to use the latest features, you might want to install the developer version. See section Developing TESPy <>_ for more information. The developer version is not recommended for productive use.

Get in touch

Online "Stammtisch"

We have decided to start a reoccurring "Stammtisch" meeting for all interested TESPy users and (potential) developers. You are invited to join us on every 3rd Monday of a month at 17:00 CE(S)T for a casual get together. The first meeting will be held at June, 20, 2022. The intent of this meeting is to establish a more active and well connected network of TESPy users and developers.

If you are interested, you can simply join the meeting at We are looking forward to seeing you!

User forum

We have implemented a discussion room on GitHub <>__ as user forum. If you have issues with setting up your model or any other question about using the software, you are invited to start a discussion there.


For a short introduction on how TESPy works and how you can use it, we provide an extensive user guide <>__. You can download all python scripts of the examples and tutorials from this GitHub repository. They are included in the "tutorial" directory.


The scope and functionalities of TESPy have been documented in a paper published in the Journal of Open Source Software with an OpenAccess license. Download the paper from As TESPy is a free software, we kindly ask that you add a reference to TESPy if you use the software for your scientific work. Please cite the article with the BibTeX citation below.

BibTeX citation::

    doi = {10.21105/joss.02178},
    year = {2020},
    publisher = {The Open Journal},
    volume = {5},
    number = {49},
    pages = {2178},
    author = {Francesco Witte and Ilja Tuschy},
    title = {{TESPy}: {T}hermal {E}ngineering {S}ystems in {P}ython},
    journal = {Journal of Open Source Software}

Furthermore, a paper on the exergy analysis feature has been published in the mdpi journal energies. You can download the pdf at If you are using this feature specifically, you can reference it with the following BibTeX citation:

BibTeX citation::

    doi = {10.3390/en15114087},
    year = {2022},
    publisher = {The Open Journal},
    volume = {15},
    number = {11},
    article-number = {4087},
    issn = {1996-1073},
    author = {Witte, Francesco and Hofmann, Mathias and Meier, Julius and Tuschy, Ilja and Tsatsaronis, George},
    title = {Generic and Open-Source Exergy Analysis&mdash;Extending the Simulation Framework TESPy},
    journal = {Energies}

Additionally, you have the possibility to cite a specific version of TESPy to make your work reproducible. The source code of every version is published on zenodo. Find your version here:


Copyright (c) 2017-2022 oemof developer group

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.



Heat exchanger in part load: Singularity in jacobian matrix

opened on 2023-03-15 14:11:32 by YoannUniKS

Dear all,

I use tespy to calculate the kA value of a gas/water heat exchanger in part load conditions. Here is a minimal code I'm using to define the heat exchanger at design conditions, following the tespy documentation:

```python from tespy.components import Sink, Source, HeatExchanger from tespy.connections import Connection from tespy.networks import Network

nw = Network(fluids=['water', 'methane'], T_unit='C', p_unit='bar', m_unit='t / h', v_unit='m3 / h', h_unit='kJ / kg', iterinfo=False)

Defining components

pri_in = Source('Primary side inlet') pri_out = Sink('Primary side outlet') sec_in = Source('Secondary side inlet') sec_out = Sink('Secondary side outlet') he = HeatExchanger('heat exchanger')

Defining connections

pri_he = Connection(pri_in, 'out1', he, 'in1') he_pri = Connection(he, 'out1', pri_out, 'in1') sec_he = Connection(sec_in, 'out1', he, 'in2') he_sec = Connection(he, 'out2', sec_out, 'in1')

nw.add_conns(pri_he, he_pri, sec_he, he_sec)

Gas side

pu = 80 #bar Tu = 5 #°C Td = 40 #°C dpg = 0.3 # bar

Water side

pin = 2.5 #bar Tin = 55 #°C Tout = 35 #°C dpw = 0.4 #bar

Vdot = 1000

set design attributes

he.set_attr(pr1=(pin-dpw)/pin, pr2=(pu-dpg)/pu, ttd_u=Tin-Td, design=['pr1', 'pr2', 'ttd_u'], offdesign=['zeta1', 'zeta2', 'kA_char'])

pri_he.set_attr(fluid={'water': 1, 'methane':0}, state='l', p=pin, T=Tin, design=['v']) sec_he.set_attr(fluid={'water': 0, 'methane': 1}, state='g', T=Tu, v=Vdot, p=pu) he_pri.set_attr(T=Tout, design=['T'])


print('Design: \nVdot (gas): {a:0.1f} m³/h'.format(a=sec_he.v.val), '\nT (gas), in: {a:0.1f} °C, out: {b:0.1f} °C'.format(a=sec_he.T.val, b=he_sec.T.val), '\nVdot (water): {a:0.1f} m³/h'.format(a=pri_he.v.val), '\nT (water), in: {a:0.1f} °C, out: {b:0.1f} °C'.format(a=pri_he.T.val, b=he_pri.T.val), '\nkA: {a:0.1f} W/K'.format(a=he.kA.val)) ```

Design: Vdot (gas): 1000.0 m³/h T (gas), in: 5.0 °C, out: 40.0 °C Vdot (water): 81.2 m³/h T (water), in: 55.0 °C, out: 35.0 °C kA: 85904.0 W/K

So far so good. The design point is defined. I now want to evaluate the kA value under part load (reduced flow rate on the gas side). Here the flow rate is reduced at 50% of its nominal value, other parameters are kept constant:

```python Vdot = 500

pri_he.set_attr(T=55) he_sec.set_attr(T=40) sec_he.set_attr(v=Vdot, T=5, p=80)

nw.solve(mode='offdesign', design_path='design_test')

print('\nOffdesign: \nVdot (gas): {a:0.1f} m³/h'.format(a=sec_he.v.val), '\nT (gas), in: {a:0.1f} °C, out: {b:0.1f} °C'.format(a=sec_he.T.val, b=he_sec.T.val), '\nVdot (water): {a:0.1f} m³/h'.format(a=pri_he.v.val), '\nT (water), in: {a:0.1f} °C, out: {b:0.1f} °C'.format(a=pri_he.T.val, b=he_pri.T.val), '\nkA: {a:0.1f} W/K'.format(a=he.kA.val)) ```

Offdesign: Vdot (gas): 500.0 m³/h T (gas), in: 5.0 °C, out: 40.0 °C Vdot (water): 26.9 m³/h T (water), in: 55.0 °C, out: 24.9 °C kA: 53547.7 W/K

Here again, no problem, the code works. However when the flow rate is too low, as here below, 16 % of the nominal flow rate, I get an error:

```python Vdot = 160

pri_he.set_attr(T=55) he_sec.set_attr(T=40) sec_he.set_attr(v=Vdot, T=5, p=80)

nw.solve(mode='offdesign', design_path='design_test')

print('\nOffdesign: \nVdot (gas): {a:0.1f} m³/h'.format(a=sec_he.v.val), '\nT (gas), in: {a:0.1f} °C, out: {b:0.1f} °C'.format(a=sec_he.T.val, b=he_sec.T.val), '\nVdot (water): {a:0.1f} m³/h'.format(a=pri_he.v.val), '\nT (water), in: {a:0.1f} °C, out: {b:0.1f} °C'.format(a=pri_he.T.val, b=he_pri.T.val), '\nkA: {a:0.1f} W/K'.format(a=he.kA.val)) ```

Singularity in jacobian matrix, calculation aborted! Make sure your network does not have any linear dependencies in the parametrisation. Other reasons might be -> given temperature with given pressure in two phase region, try setting enthalpy instead or provide accurate starting value for pressure. -> given logarithmic temperature differences or kA-values for heat exchangers, -> support better starting values. -> bad starting value for fuel mass flow of combustion chamber, provide small (near to zero, but not zero) starting value.

I have two questions regarding these results. 1/ It is unclear what is causing the error in the last case, is there a way to "help" the algorithm find a solution? 2/ I am actually calculating the kA value for several thousand operating points and I get the message above for maybe 10 % of them. From nw.solve() I'm getting the error message, but it is of no practical use when working with so many values. Is there an output variable from the function that I can use telling me that the calculation was not successful? I could not find that. I would use it in a first step to sort out the points where the calculation did not work.

Thanks in advance!

Calculation of td_log in heat exchangers with constant temperature difference

opened on 2023-02-24 16:10:08 by fwitte

Discussed in

Originally posted by **dk-teknologisk-enp** February 24, 2023 Currently it seems that if ttd_u == ttd_l for a heat exchanger, then td_log ends up as nan, and thus also the kA. However, this is a perfectly valid situation, for example in a heat exchanger with purely boiling/condensing on both sides. I suggest making the following changes to, such that td_log is set to the constant temperature difference in case ttd_u == ttd_l: ![image]( (

Flexible logging functionality

opened on 2023-02-13 13:40:55 by jowr

Hi and thank you for all the work you put into this library - very much appreciated.

We currently build a UI around the core functionality of TESPy and I thus need to capture some of the logging and printing output - either for rerouting it to the UI or for reporting progress, errors and results.

While working on this, I noticed that TESPy uses the root node logger from the logging framework. Would it be OK if I submitted a PR covering the following two points:

  1. Replace the root logger with a named logger (from the logging framework) that can be accessed and modified using a unique ID like TESPyRoot for example.
  2. Include the option to provide call-back functions to retrieve status messages instead of printing these messages directly to stdout?

FutureWarning: In future versions `DataFrame.to_latex` is expected to utilise the base implementation of `Styler.to_latex`

opened on 2023-02-09 06:25:10 by fwitte

Discussed in

Features/chemical exergy

opened on 2023-02-07 08:23:14 by aburabazam

Adding chemical exergy to the data structure and the Sankey diagram.

  • Exergy can now be divided into chemical and physical exergy
  • This refers to the class ExergyAnalysis in
  • Added columns to dictionary self.sankey_data
  • Sankey data for components will be filled with chem. and phys. exergy
  • Function generate_plotly_sankey_input was adapted to differentiate between chemical and physical exergy
  • This is a further development of KarimHShawky work in the closed issue #326

Make the fluid property back-end flexible

opened on 2023-01-29 11:22:21 by fwitte

There is a lot of issues with the fluid property back-end that hinder (easy) integration of new features, such as the incompressible mixtures, all sorts of CoolProp inbuilt mixtures and stuff like absorption heat pumps etc.. This PR will make a lot of breaking changes to the current structure but provide an easily adaptable back-end later.


TESPy version 0.6.2 2022-10-14 16:22:41

Hotfix for version 0.6.1, which did not allow to delete connections and readd them later.

TESPy version 0.6.1 - Leidenfrost's Library 2022-10-02 09:18:15

The new version of TESPy features a refurbished and modernized documentation as well as some smaller new features and bug fixes. Python versions > 3.8 are now supported as well! Check it out at!

To upgrade pip install tespy --upgrade

TESPy version 0.6.0 - Colored Chemicals 2022-05-15 09:22:20

TESPy version 0.6.0 drops support for few used features (stoichiometric combustion chamber and TESPy fluid). A new component - the diabatic combustion chamber - has been added and some bugs have been fixed. Check out the new features here.

TESPy version 0.5.1 - Exciting Exergy 2022-01-16 10:40:28

This release ships with some improvements in the documentation and bug fixes in the exergy analysis module. Check out What's New.

TESPy version 0.5.0 - Davis' Domain 2021-09-29 10:29:23

The latest TESPy version features a brand new tutorial: an exergy analysis of a ground coupled heat pump. On top of that minor bug fixes and adjustments have been applied. Check out What's New.

TESPy version 0.4.4 - Reynolds' Reminiscence 2021-07-14 10:09:23

Mainly minor bugs have been fixed in this release. See all the changes at readthedocs.

Use pip install tespy --upgrade to upgrade to the latest version!

oemof community

Open Energy Modelling Framework - A modular open source framework to model energy supply systems

GitHub Repository Homepage

thermodynamics process-engineering cooling heating energy-system powerplant python simulation exergy refrigeration thermodynamic-cycles