tespy 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- TESPy-0.0.1/PKG-INFO +56 -0
- TESPy-0.0.1/README.rst +46 -0
- TESPy-0.0.1/TESPy.egg-info/PKG-INFO +56 -0
- TESPy-0.0.1/TESPy.egg-info/SOURCES.txt +17 -0
- TESPy-0.0.1/TESPy.egg-info/dependency_links.txt +1 -0
- TESPy-0.0.1/TESPy.egg-info/requires.txt +5 -0
- TESPy-0.0.1/TESPy.egg-info/top_level.txt +1 -0
- TESPy-0.0.1/setup.cfg +8 -0
- TESPy-0.0.1/setup.py +23 -0
- TESPy-0.0.1/tespy/__init__.py +12 -0
- TESPy-0.0.1/tespy/components/__init__.py +4 -0
- TESPy-0.0.1/tespy/components/characteristics.py +394 -0
- TESPy-0.0.1/tespy/components/components.py +5324 -0
- TESPy-0.0.1/tespy/components/subsystems.py +524 -0
- TESPy-0.0.1/tespy/connections.py +387 -0
- TESPy-0.0.1/tespy/csv_reader.py +86 -0
- TESPy-0.0.1/tespy/helpers.py +875 -0
- TESPy-0.0.1/tespy/networks.py +2288 -0
TESPy-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
Metadata-Version: 1.0
|
|
2
|
+
Name: TESPy
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Thermal Engineering Systems in Python (TESPy)
|
|
5
|
+
Home-page: http://github.com/oemof/tespy
|
|
6
|
+
Author: Francesco Witte
|
|
7
|
+
Author-email: francesco.witte@web.de
|
|
8
|
+
License: GPL-3.0
|
|
9
|
+
Description: 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 System Modeling Framework <https://oemof.org/>`_ and can be used as a standalone package.
|
|
10
|
+
|
|
11
|
+
With the TESPy package you are able to calculate stationary operation in order to design the process of your plant. From that point it is possible to calculate the offdesign behaviour of your plant using underlying characteristics for each of the plants components. For now, the package inlcudes basic components, such as turbines, pumps, compressors, heat exchangers, pipes, mixers and splitters as well as some advanced components (derivatives of heat exchangers, drum).
|
|
12
|
+
|
|
13
|
+
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: https://guides.github.com/activities/hello-world/
|
|
14
|
+
|
|
15
|
+
.. contents::
|
|
16
|
+
:depth: 1
|
|
17
|
+
:local:
|
|
18
|
+
:backlinks: top
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
Documentation
|
|
22
|
+
=============
|
|
23
|
+
|
|
24
|
+
You can find the full documentation at `readthedocs <http://tespy.readthedocs.org>`_. Use the `project site <http://readthedocs.org/projects/tespy>`_ of readthedocs to choose the version of the documentation. Go to the `download page <http://readthedocs.org/projects/tespy/downloads/>`_ to download different versions and formats (pdf, html, epub) of the documentation. Currently, only the dev branch is available.
|
|
25
|
+
|
|
26
|
+
To get the latest news visit and follow our `website <https://www.oemof.org>`_.
|
|
27
|
+
|
|
28
|
+
Installing TESPy
|
|
29
|
+
================
|
|
30
|
+
|
|
31
|
+
If you have a working Python3 environment, use pypi to install the latest tespy version: Clone the github repository and then run:
|
|
32
|
+
|
|
33
|
+
.. code:: bash
|
|
34
|
+
|
|
35
|
+
pip install -e path/to/the/repository
|
|
36
|
+
|
|
37
|
+
If you want to use the latest features, you might want to install the **developer version**. See section `'Developing TESPy' <http://tespy.readthedocs.io/en/latest/developing_oemof.html>`_ for more information. The developer version is not recommended for productive use.
|
|
38
|
+
|
|
39
|
+
Examples
|
|
40
|
+
========
|
|
41
|
+
|
|
42
|
+
For a short introduction on how TESPy works and how you can use it, we provid a short `Introduction <http://tespy.readthedocs.io/en/dev/introduction.html>`_.You can download the python scripts of the example plants from the tespy.examples folder.
|
|
43
|
+
|
|
44
|
+
License
|
|
45
|
+
=======
|
|
46
|
+
|
|
47
|
+
Copyright (C) 2018 oemof developing group
|
|
48
|
+
|
|
49
|
+
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
50
|
+
|
|
51
|
+
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
52
|
+
|
|
53
|
+
You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
Platform: UNKNOWN
|
TESPy-0.0.1/README.rst
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
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 System Modeling Framework <https://oemof.org/>`_ and can be used as a standalone package.
|
|
2
|
+
|
|
3
|
+
With the TESPy package you are able to calculate stationary operation in order to design the process of your plant. From that point it is possible to calculate the offdesign behaviour of your plant using underlying characteristics for each of the plants components. For now, the package inlcudes basic components, such as turbines, pumps, compressors, heat exchangers, pipes, mixers and splitters as well as some advanced components (derivatives of heat exchangers, drum).
|
|
4
|
+
|
|
5
|
+
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: https://guides.github.com/activities/hello-world/
|
|
6
|
+
|
|
7
|
+
.. contents::
|
|
8
|
+
:depth: 1
|
|
9
|
+
:local:
|
|
10
|
+
:backlinks: top
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
Documentation
|
|
14
|
+
=============
|
|
15
|
+
|
|
16
|
+
You can find the full documentation at `readthedocs <http://tespy.readthedocs.org>`_. Use the `project site <http://readthedocs.org/projects/tespy>`_ of readthedocs to choose the version of the documentation. Go to the `download page <http://readthedocs.org/projects/tespy/downloads/>`_ to download different versions and formats (pdf, html, epub) of the documentation. Currently, only the dev branch is available.
|
|
17
|
+
|
|
18
|
+
To get the latest news visit and follow our `website <https://www.oemof.org>`_.
|
|
19
|
+
|
|
20
|
+
Installing TESPy
|
|
21
|
+
================
|
|
22
|
+
|
|
23
|
+
If you have a working Python3 environment, use pypi to install the latest tespy version: Clone the github repository and then run:
|
|
24
|
+
|
|
25
|
+
.. code:: bash
|
|
26
|
+
|
|
27
|
+
pip install -e path/to/the/repository
|
|
28
|
+
|
|
29
|
+
If you want to use the latest features, you might want to install the **developer version**. See section `'Developing TESPy' <http://tespy.readthedocs.io/en/latest/developing_oemof.html>`_ for more information. The developer version is not recommended for productive use.
|
|
30
|
+
|
|
31
|
+
Examples
|
|
32
|
+
========
|
|
33
|
+
|
|
34
|
+
For a short introduction on how TESPy works and how you can use it, we provid a short `Introduction <http://tespy.readthedocs.io/en/dev/introduction.html>`_.You can download the python scripts of the example plants from the tespy.examples folder.
|
|
35
|
+
|
|
36
|
+
License
|
|
37
|
+
=======
|
|
38
|
+
|
|
39
|
+
Copyright (C) 2018 oemof developing group
|
|
40
|
+
|
|
41
|
+
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
42
|
+
|
|
43
|
+
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
44
|
+
|
|
45
|
+
You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.
|
|
46
|
+
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
Metadata-Version: 1.0
|
|
2
|
+
Name: TESPy
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Thermal Engineering Systems in Python (TESPy)
|
|
5
|
+
Home-page: http://github.com/oemof/tespy
|
|
6
|
+
Author: Francesco Witte
|
|
7
|
+
Author-email: francesco.witte@web.de
|
|
8
|
+
License: GPL-3.0
|
|
9
|
+
Description: 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 System Modeling Framework <https://oemof.org/>`_ and can be used as a standalone package.
|
|
10
|
+
|
|
11
|
+
With the TESPy package you are able to calculate stationary operation in order to design the process of your plant. From that point it is possible to calculate the offdesign behaviour of your plant using underlying characteristics for each of the plants components. For now, the package inlcudes basic components, such as turbines, pumps, compressors, heat exchangers, pipes, mixers and splitters as well as some advanced components (derivatives of heat exchangers, drum).
|
|
12
|
+
|
|
13
|
+
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: https://guides.github.com/activities/hello-world/
|
|
14
|
+
|
|
15
|
+
.. contents::
|
|
16
|
+
:depth: 1
|
|
17
|
+
:local:
|
|
18
|
+
:backlinks: top
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
Documentation
|
|
22
|
+
=============
|
|
23
|
+
|
|
24
|
+
You can find the full documentation at `readthedocs <http://tespy.readthedocs.org>`_. Use the `project site <http://readthedocs.org/projects/tespy>`_ of readthedocs to choose the version of the documentation. Go to the `download page <http://readthedocs.org/projects/tespy/downloads/>`_ to download different versions and formats (pdf, html, epub) of the documentation. Currently, only the dev branch is available.
|
|
25
|
+
|
|
26
|
+
To get the latest news visit and follow our `website <https://www.oemof.org>`_.
|
|
27
|
+
|
|
28
|
+
Installing TESPy
|
|
29
|
+
================
|
|
30
|
+
|
|
31
|
+
If you have a working Python3 environment, use pypi to install the latest tespy version: Clone the github repository and then run:
|
|
32
|
+
|
|
33
|
+
.. code:: bash
|
|
34
|
+
|
|
35
|
+
pip install -e path/to/the/repository
|
|
36
|
+
|
|
37
|
+
If you want to use the latest features, you might want to install the **developer version**. See section `'Developing TESPy' <http://tespy.readthedocs.io/en/latest/developing_oemof.html>`_ for more information. The developer version is not recommended for productive use.
|
|
38
|
+
|
|
39
|
+
Examples
|
|
40
|
+
========
|
|
41
|
+
|
|
42
|
+
For a short introduction on how TESPy works and how you can use it, we provid a short `Introduction <http://tespy.readthedocs.io/en/dev/introduction.html>`_.You can download the python scripts of the example plants from the tespy.examples folder.
|
|
43
|
+
|
|
44
|
+
License
|
|
45
|
+
=======
|
|
46
|
+
|
|
47
|
+
Copyright (C) 2018 oemof developing group
|
|
48
|
+
|
|
49
|
+
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
50
|
+
|
|
51
|
+
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
52
|
+
|
|
53
|
+
You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
Platform: UNKNOWN
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
README.rst
|
|
2
|
+
setup.cfg
|
|
3
|
+
setup.py
|
|
4
|
+
TESPy.egg-info/PKG-INFO
|
|
5
|
+
TESPy.egg-info/SOURCES.txt
|
|
6
|
+
TESPy.egg-info/dependency_links.txt
|
|
7
|
+
TESPy.egg-info/requires.txt
|
|
8
|
+
TESPy.egg-info/top_level.txt
|
|
9
|
+
tespy/__init__.py
|
|
10
|
+
tespy/connections.py
|
|
11
|
+
tespy/csv_reader.py
|
|
12
|
+
tespy/helpers.py
|
|
13
|
+
tespy/networks.py
|
|
14
|
+
tespy/components/__init__.py
|
|
15
|
+
tespy/components/characteristics.py
|
|
16
|
+
tespy/components/components.py
|
|
17
|
+
tespy/components/subsystems.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
tespy
|
TESPy-0.0.1/setup.cfg
ADDED
TESPy-0.0.1/setup.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def read(fname):
|
|
6
|
+
return open(os.path.join(os.path.dirname(__file__), fname)).read()
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
setup(name='TESPy',
|
|
10
|
+
version='0.0.1',
|
|
11
|
+
description='Thermal Engineering Systems in Python (TESPy)',
|
|
12
|
+
url='http://github.com/oemof/tespy',
|
|
13
|
+
author='Francesco Witte',
|
|
14
|
+
author_email='francesco.witte@web.de',
|
|
15
|
+
long_description=read('README.rst'),
|
|
16
|
+
license='GPL-3.0',
|
|
17
|
+
packages=['tespy', 'tespy.components'],
|
|
18
|
+
python_requires='>=3',
|
|
19
|
+
install_requires=['CoolProp >= 6.1.0',
|
|
20
|
+
'matplotlib >= 2.0.2',
|
|
21
|
+
'numpy >= 1.13.3',
|
|
22
|
+
'pandas >= 0.19.2',
|
|
23
|
+
'scipy >= 0.19.1'])
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""
|
|
2
|
+
.. moduleauthor:: Francesco Witte <francesco.witte@hs-flensburg.de>
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from tespy.components import (components as cmp,
|
|
7
|
+
characteristics as cmp_char,
|
|
8
|
+
subsystems as subsys)
|
|
9
|
+
from tespy import connections as con
|
|
10
|
+
from tespy import helpers as hlp
|
|
11
|
+
from tespy import networks as nwk
|
|
12
|
+
from tespy import csv_reader as csv_r
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
"""
|
|
2
|
+
.. module:: components.characteristics
|
|
3
|
+
:synopsis:
|
|
4
|
+
|
|
5
|
+
.. moduleauthor:: Francesco Witte <francesco.witte@hs-flensburg.de>
|
|
6
|
+
|
|
7
|
+
**TODO**
|
|
8
|
+
|
|
9
|
+
- add documentation
|
|
10
|
+
|
|
11
|
+
**Improvements**
|
|
12
|
+
|
|
13
|
+
- build generic architecture for characteristics
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from scipy.interpolate import interp1d
|
|
17
|
+
import numpy as np
|
|
18
|
+
import matplotlib.pyplot as plt
|
|
19
|
+
import pandas as pd
|
|
20
|
+
import copy
|
|
21
|
+
import math
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def find_length(xs, ys):
|
|
25
|
+
dx = np.diff(xs)
|
|
26
|
+
dy = np.diff(ys)
|
|
27
|
+
return np.sum(np.sqrt(dx ** 2 + dy ** 2))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class compressor:
|
|
31
|
+
r"""
|
|
32
|
+
|
|
33
|
+
generic characteristic map for axial compressors
|
|
34
|
+
|
|
35
|
+
- links mass flow to pressure rise and isentropic efficiency
|
|
36
|
+
- includes a vigv angle
|
|
37
|
+
|
|
38
|
+
the map can be plotted using :code:`map.plot()`
|
|
39
|
+
|
|
40
|
+
**literature**
|
|
41
|
+
|
|
42
|
+
compressor map:
|
|
43
|
+
|
|
44
|
+
- Marcin Plis, Henryk Rusinowski (2016): Mathematical modeling of an
|
|
45
|
+
axial compressor in a gas turbine cycle. Journal of Power
|
|
46
|
+
Technologies 96 (3), pp. 194-199.
|
|
47
|
+
|
|
48
|
+
vigv:
|
|
49
|
+
|
|
50
|
+
- GasTurb GmbH (2015): GasTurb 12.
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
def __init__(self, ** kwargs):
|
|
54
|
+
|
|
55
|
+
self.raw_data = None
|
|
56
|
+
self.beta = None
|
|
57
|
+
|
|
58
|
+
for key in kwargs:
|
|
59
|
+
if key in self.keywordargs():
|
|
60
|
+
self.__dict__.update({key: kwargs[key]})
|
|
61
|
+
|
|
62
|
+
for key in self.keywordargs():
|
|
63
|
+
if self.__dict__[key] is None:
|
|
64
|
+
self.__dict__.update({key: self.default(key)})
|
|
65
|
+
|
|
66
|
+
self.pr = copy.deepcopy(self.raw_data)
|
|
67
|
+
self.eta = copy.deepcopy(self.raw_data)
|
|
68
|
+
|
|
69
|
+
# create lut for each speedline
|
|
70
|
+
self.pr_lut = {}
|
|
71
|
+
self.eta_lut = {}
|
|
72
|
+
for key in sorted(self.raw_data):
|
|
73
|
+
# pressure ratio
|
|
74
|
+
x = [it[0] for it in self.raw_data[key]]
|
|
75
|
+
y = [it[1] for it in self.raw_data[key]]
|
|
76
|
+
# sorted values of x and y
|
|
77
|
+
self.pr[key] = interp1d(x, y, 'linear')
|
|
78
|
+
y = self.pr[key].y
|
|
79
|
+
x = self.pr[key].x
|
|
80
|
+
l = np.insert(np.cumsum(np.sqrt(np.diff(x) ** 2 +
|
|
81
|
+
np.diff(y) ** 2)), 0, 0)
|
|
82
|
+
self.pr_lut[key] = pd.DataFrame({'x': x, 'y': y}, index=l)
|
|
83
|
+
|
|
84
|
+
# add values for beta lines
|
|
85
|
+
for i in np.linspace(0, self.pr_lut[key].index[-1], self.beta):
|
|
86
|
+
if i not in self.pr_lut[key].index:
|
|
87
|
+
self.pr_lut[key].loc[i] = [np.nan, np.nan]
|
|
88
|
+
|
|
89
|
+
self.pr_lut[key] = self.pr_lut[key].sort_index()
|
|
90
|
+
self.pr_lut[key] = self.pr_lut[key].interpolate(method='index')
|
|
91
|
+
|
|
92
|
+
# isentropic efficiency
|
|
93
|
+
x = [it[0] for it in self.raw_data[key]]
|
|
94
|
+
y = [it[2] for it in self.raw_data[key]]
|
|
95
|
+
# sorted values of x and y
|
|
96
|
+
self.eta[key] = interp1d(x, y, 'linear')
|
|
97
|
+
y = self.eta[key].y
|
|
98
|
+
x = self.eta[key].x
|
|
99
|
+
l = np.insert(np.cumsum(np.sqrt(np.diff(x) ** 2 +
|
|
100
|
+
np.diff(y) ** 2)), 0, 0)
|
|
101
|
+
self.eta_lut[key] = pd.DataFrame({'x': x, 'y': y}, index=l)
|
|
102
|
+
|
|
103
|
+
# add values for beta lines
|
|
104
|
+
for i in np.linspace(0, self.eta_lut[key].index[-1], self.beta):
|
|
105
|
+
if i not in self.eta_lut[key].index:
|
|
106
|
+
self.eta_lut[key].loc[i] = [np.nan, np.nan]
|
|
107
|
+
|
|
108
|
+
self.eta_lut[key] = self.eta_lut[key].sort_index()
|
|
109
|
+
self.eta_lut[key] = self.eta_lut[key].interpolate(method='index')
|
|
110
|
+
|
|
111
|
+
self.pr_beta = {}
|
|
112
|
+
self.eta_beta = {}
|
|
113
|
+
for i in range(self.beta):
|
|
114
|
+
x = []
|
|
115
|
+
y = []
|
|
116
|
+
for key in sorted(self.raw_data):
|
|
117
|
+
x += [self.pr_lut[key].loc[np.linspace(
|
|
118
|
+
0, self.pr_lut[key].index[-1], self.beta
|
|
119
|
+
)[i]].x]
|
|
120
|
+
y += [self.pr_lut[key].loc[np.linspace(
|
|
121
|
+
0, self.pr_lut[key].index[-1], self.beta
|
|
122
|
+
)[i]].y]
|
|
123
|
+
self.pr_beta[i] = pd.DataFrame({'x': x, 'y': y},
|
|
124
|
+
index=sorted(self.raw_data))
|
|
125
|
+
x = []
|
|
126
|
+
y = []
|
|
127
|
+
for key in sorted(self.raw_data):
|
|
128
|
+
x += [self.eta_lut[key].loc[np.linspace(
|
|
129
|
+
0, self.eta_lut[key].index[-1], self.beta
|
|
130
|
+
)[i]].x]
|
|
131
|
+
y += [self.eta_lut[key].loc[np.linspace(
|
|
132
|
+
0, self.eta_lut[key].index[-1], self.beta
|
|
133
|
+
)[i]].y]
|
|
134
|
+
self.eta_beta[i] = pd.DataFrame({'x': x, 'y': y},
|
|
135
|
+
index=sorted(self.raw_data))
|
|
136
|
+
|
|
137
|
+
# allowed keyword arguments
|
|
138
|
+
def keywordargs(self):
|
|
139
|
+
return ['raw_data', 'beta']
|
|
140
|
+
|
|
141
|
+
# default values
|
|
142
|
+
def default(self, key):
|
|
143
|
+
"""
|
|
144
|
+
source of map:
|
|
145
|
+
Marcin Plis, Henryk Rusinowski (2016): Mathematical modeling of an
|
|
146
|
+
axial compressor in a gas turbine cycle. Journal of Power
|
|
147
|
+
Technologies 96 (3), pp. 194-199.
|
|
148
|
+
"""
|
|
149
|
+
|
|
150
|
+
# default map
|
|
151
|
+
default_map = {}
|
|
152
|
+
default_map[1.062] = [[1.045, 1.441, 0.879], [1.056, 0.805, 0.887],
|
|
153
|
+
[1.052, 1.176, 0.925]]
|
|
154
|
+
|
|
155
|
+
default_map[1.029] = [[1.014, 1.340, 0.948], [1.026, 1.082, 0.967],
|
|
156
|
+
[1.036, 0.767, 0.868]]
|
|
157
|
+
|
|
158
|
+
default_map[1.000] = [[0.948, 1.195, 0.956], [0.961, 1.176, 0.958],
|
|
159
|
+
[0.974, 1.151, 0.962], [0.987, 1.101, 0.981],
|
|
160
|
+
[0.994, 1.057, 0.992], [1.000, 1.000, 1.000],
|
|
161
|
+
[1.005, 0.893, 0.9909], [1.006, 0.748, 0.914]]
|
|
162
|
+
|
|
163
|
+
default_map[0.971] = [[0.874, 1.050, 0.977], [0.909, 1.019, 0.977],
|
|
164
|
+
[0.922, 1.000, 0.987], [0.935, 0.969, 1.004],
|
|
165
|
+
[0.948, 0.918, 1.008], [0.961, 0.861, 1.004],
|
|
166
|
+
[0.964, 0.672, 0.920]]
|
|
167
|
+
|
|
168
|
+
default_map[0.946] = [[0.767, 0.931, 0.891], [0.819, 0.912, 1.002],
|
|
169
|
+
[0.838, 0.893, 1.013], [0.858, 0.861, 1.017],
|
|
170
|
+
[0.871, 0.817, 1.017], [0.877, 0.767, 1.013],
|
|
171
|
+
[0.880, 0.616, 0.925]]
|
|
172
|
+
|
|
173
|
+
default_map[0.870] = [[0.59, 0.65, 0.887], [0.618, 0.641, 0.929],
|
|
174
|
+
[0.657, 0.616, 0.962], [0.676, 0.597, 0.969],
|
|
175
|
+
[0.7, 0.553, 0.975], [0.702, 0.528, 0.967],
|
|
176
|
+
[0.709, 0.477, 0.948], [0.713, 0.37, 0.887]]
|
|
177
|
+
|
|
178
|
+
default_map[0.810] = [[0.46, 0.502, 0.872], [0.534, 0.483, 0.918],
|
|
179
|
+
[0.573, 0.452, 0.948], [0.586, 0.424, 0.944],
|
|
180
|
+
[0.599, 0.38, 0.925], [0.605, 0.348, 0.906],
|
|
181
|
+
[0.612, 0.276, 0.879]]
|
|
182
|
+
|
|
183
|
+
default_val = {
|
|
184
|
+
'raw_data': default_map,
|
|
185
|
+
'beta': 10
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return default_val[key]
|
|
189
|
+
|
|
190
|
+
# adding speedlines to the compressor map
|
|
191
|
+
def add_speedline(self, n):
|
|
192
|
+
n = round(n, 3)
|
|
193
|
+
if n not in self.pr.keys():
|
|
194
|
+
if n > max(self.pr.keys()) or n < min(self.pr.keys()):
|
|
195
|
+
return
|
|
196
|
+
|
|
197
|
+
x = []
|
|
198
|
+
y = []
|
|
199
|
+
for i in range(self.beta):
|
|
200
|
+
self.pr_beta[i].loc[n] = [np.nan, np.nan]
|
|
201
|
+
self.pr_beta[i] = self.pr_beta[i].sort_index()
|
|
202
|
+
self.pr_beta[i] = self.pr_beta[i].interpolate(method='index')
|
|
203
|
+
x += [self.pr_beta[i].loc[n].x]
|
|
204
|
+
y += [self.pr_beta[i].loc[n].y]
|
|
205
|
+
|
|
206
|
+
self.pr[n] = interp1d(x, y, 'linear')
|
|
207
|
+
|
|
208
|
+
x = []
|
|
209
|
+
y = []
|
|
210
|
+
for i in range(self.beta):
|
|
211
|
+
self.eta_beta[i].loc[n] = [np.nan, np.nan]
|
|
212
|
+
self.eta_beta[i] = self.eta_beta[i].sort_index()
|
|
213
|
+
self.eta_beta[i] = self.eta_beta[i].interpolate(method='index')
|
|
214
|
+
x += [self.eta_beta[i].loc[n].x]
|
|
215
|
+
y += [self.eta_beta[i].loc[n].y]
|
|
216
|
+
|
|
217
|
+
self.eta[n] = interp1d(x, y, 'linear')
|
|
218
|
+
|
|
219
|
+
# get speedline as interpolation object
|
|
220
|
+
def get_speedline(self, n, vigv):
|
|
221
|
+
"""
|
|
222
|
+
source of speedline adaption by igv:
|
|
223
|
+
GasTurb GmbH (2015): GasTurb 12.
|
|
224
|
+
"""
|
|
225
|
+
n = round(n, 3)
|
|
226
|
+
self.add_speedline(n)
|
|
227
|
+
pr = interp1d(self.pr[n].x * (1 - vigv / 100),
|
|
228
|
+
self.pr[n].y * (1 - vigv / 100), 'linear')
|
|
229
|
+
eta = interp1d(self.eta[n].x * (1 - vigv / 100),
|
|
230
|
+
self.eta[n].y * (1 - vigv ** 2 / 10000), 'linear')
|
|
231
|
+
return pr, eta
|
|
232
|
+
|
|
233
|
+
# calculate feasible vigv angles for given speedline and non dimensional mass flow
|
|
234
|
+
def get_vigv_range(self, n, m):
|
|
235
|
+
n = round(n, 3)
|
|
236
|
+
if n not in self.pr.keys():
|
|
237
|
+
self.add_speedline(n)
|
|
238
|
+
|
|
239
|
+
vigv_min = 100 * (1 - m / self.eta_beta[0].loc[n].x)
|
|
240
|
+
vigv_max = 100 * (1 - m / self.eta_beta[self.beta - 1].loc[n].x)
|
|
241
|
+
|
|
242
|
+
return vigv_min, vigv_max
|
|
243
|
+
|
|
244
|
+
# get pressure ratio
|
|
245
|
+
def get_pr(self, n, m, vigv):
|
|
246
|
+
return self.get_speedline(n, vigv)[0](m)
|
|
247
|
+
|
|
248
|
+
# get isentropic efficiency
|
|
249
|
+
def get_eta(self, n, m, vigv):
|
|
250
|
+
return self.get_speedline(n, vigv)[1](m)
|
|
251
|
+
|
|
252
|
+
# calculate vigv angle for given speedline, non dimensional mass flow and pressure ratio
|
|
253
|
+
def get_vigv(self, n, m, p):
|
|
254
|
+
n = round(n, 3)
|
|
255
|
+
if n not in self.pr.keys():
|
|
256
|
+
self.add_speedline(n)
|
|
257
|
+
|
|
258
|
+
tolerance = 1e-12
|
|
259
|
+
d = 1e-3
|
|
260
|
+
res = 1
|
|
261
|
+
deriv = 1
|
|
262
|
+
|
|
263
|
+
vigv_range = self.get_vigv_range(n, m)
|
|
264
|
+
vigv = (vigv_range[0] + vigv_range[1]) / 2
|
|
265
|
+
vigv_hist = [vigv]
|
|
266
|
+
z_hist = [res / deriv]
|
|
267
|
+
|
|
268
|
+
while abs(res) >= tolerance:
|
|
269
|
+
try:
|
|
270
|
+
res = p - self.get_pr(n, m, vigv)
|
|
271
|
+
deriv = ((self.get_pr(n, m, vigv + d) -
|
|
272
|
+
self.get_pr(n, m, vigv - d)) / (2 * d))
|
|
273
|
+
vigv += res / deriv
|
|
274
|
+
z_hist += [res / deriv]
|
|
275
|
+
except:
|
|
276
|
+
if vigv < vigv_range[0]:
|
|
277
|
+
vigv = vigv_range[0] + 1e-2
|
|
278
|
+
if vigv > vigv_range[1]:
|
|
279
|
+
vigv = vigv_range[1] - 1e-2
|
|
280
|
+
|
|
281
|
+
vigv_hist += [vigv]
|
|
282
|
+
|
|
283
|
+
if ((len(vigv_hist) > 10 and
|
|
284
|
+
vigv_hist[(len(vigv_hist) - 10):] == 10 * [vigv_hist[-1]]) or
|
|
285
|
+
(len(z_hist) > 5 and
|
|
286
|
+
z_hist[(len(z_hist) - 5):] == 5 * [z_hist[-1]])):
|
|
287
|
+
raise ValueError('Given pressure ratio can not be archieved'
|
|
288
|
+
' with given speedline.')
|
|
289
|
+
|
|
290
|
+
# print(time.time() - tmp)
|
|
291
|
+
return vigv
|
|
292
|
+
|
|
293
|
+
# plot the compressor map
|
|
294
|
+
def plot(self):
|
|
295
|
+
fig, ax1 = plt.subplots()
|
|
296
|
+
ax2 = ax1.twinx()
|
|
297
|
+
for i in range(self.beta):
|
|
298
|
+
ax1.plot(self.pr_beta[i].x, self.pr_beta[i].y, 'xk', ms=3)
|
|
299
|
+
|
|
300
|
+
for i in range(self.beta):
|
|
301
|
+
ax2.plot(self.eta_beta[i].x, self.eta_beta[i].y, 'xr', ms=3)
|
|
302
|
+
|
|
303
|
+
ax1.set_ylabel('$p$ / $p_\mathrm{ref}$')
|
|
304
|
+
ax2.set_ylabel('$\eta$ / $\eta_\mathrm{ref}$')
|
|
305
|
+
ax1.set_xlabel('$m$ / $m_\mathrm{ref}$')
|
|
306
|
+
ax2.set_ylim([0, 1.1])
|
|
307
|
+
ax1.set_ylim([0, 2])
|
|
308
|
+
plt.sca(ax1)
|
|
309
|
+
plt.show()
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
class pump:
|
|
313
|
+
r"""
|
|
314
|
+
|
|
315
|
+
generic characteristic for pumps
|
|
316
|
+
|
|
317
|
+
- links isentropic efficiency :math:`\eta_{s,p}` to volumetric flow
|
|
318
|
+
:math:`\dot{V}`
|
|
319
|
+
- uses a distorted quadratic function:
|
|
320
|
+
|
|
321
|
+
.. math::
|
|
322
|
+
|
|
323
|
+
\eta_{s,p} = \left( a \cdot \dot{V}^2 + b \cdot \dot{V} \right) \cdot
|
|
324
|
+
e^{k \cdot \dot{V}}
|
|
325
|
+
|
|
326
|
+
- function parameters are deriven from design status
|
|
327
|
+
- specific rotational speed :math:`n_q`:
|
|
328
|
+
|
|
329
|
+
.. math::
|
|
330
|
+
|
|
331
|
+
n_q = \frac{n \cdot \sqrt{\dot{V}}}{H^{0,75}}
|
|
332
|
+
|
|
333
|
+
.. note::
|
|
334
|
+
|
|
335
|
+
The calculation with pump characteristics is unstable, better use
|
|
336
|
+
constant value for isentropic efficiency!
|
|
337
|
+
|
|
338
|
+
**literature**
|
|
339
|
+
|
|
340
|
+
- Wolfgang Wesche (2012): Radiale Kreiselpumpen - Berechnung und
|
|
341
|
+
Konstruktion der hydrodynamischen Komponenten. Berlin: Springer.
|
|
342
|
+
"""
|
|
343
|
+
|
|
344
|
+
def __init__(self, v_opt, eta_s, H_opt):
|
|
345
|
+
|
|
346
|
+
n_q = 3000 * math.sqrt(v_opt) / ((H_opt) ** 0.75)
|
|
347
|
+
v_0 = v_opt * 3.1 * n_q ** (-0.15)
|
|
348
|
+
self.k = (v_0 - 2 * v_opt) / (v_opt ** 2 - v_0 * v_opt)
|
|
349
|
+
self.a = eta_s / ((v_opt ** 2 - v_0 * v_opt) *
|
|
350
|
+
math.exp(self.k * v_opt))
|
|
351
|
+
self.b = -self.a * v_0
|
|
352
|
+
|
|
353
|
+
def eta(self, v):
|
|
354
|
+
return (self.a * v ** 2 + self.b * v) * math.exp(self.k * v)
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
class turbine:
|
|
358
|
+
r"""
|
|
359
|
+
|
|
360
|
+
generic characteristics for turbine isentropic efficiency
|
|
361
|
+
|
|
362
|
+
- links isentropic efficiency :math:`\eta_\mathrm{s,t}` to keyfigure
|
|
363
|
+
:math:`\nu`
|
|
364
|
+
|
|
365
|
+
.. math::
|
|
366
|
+
|
|
367
|
+
\eta_\mathrm{s,t}=f\left(\frac{\nu}{\nu_\mathrm{ref}} \right)
|
|
368
|
+
|
|
369
|
+
\frac{\nu}{\nu_\mathrm{ref}}=\frac{\sqrt{\Delta h_\mathrm{s,ref}}}
|
|
370
|
+
{\sqrt{\Delta h_\mathrm{s}}}
|
|
371
|
+
|
|
372
|
+
- values from Traupel (see literature)
|
|
373
|
+
- maximum value of isentropic efficiency in characteristic is assigned to
|
|
374
|
+
isentropic efficiency in reference state with
|
|
375
|
+
:math:`\frac{\nu}{\nu_{ref}}=1`.
|
|
376
|
+
|
|
377
|
+
**literature**
|
|
378
|
+
|
|
379
|
+
- Walter Traupel (2001): Thermische Turbomaschinen Band 2. Berlin: Spinger.
|
|
380
|
+
"""
|
|
381
|
+
|
|
382
|
+
def __init__(self, eta_s0):
|
|
383
|
+
|
|
384
|
+
self.nu = np.array([0.0, 0.2, 0.4, 0.6, 0.8, 1.0])
|
|
385
|
+
self.eta_s = np.array([0.0, 0.6, 0.85, 0.875, 0.75, 0.5])
|
|
386
|
+
self.char = interp1d(self.nu, self.eta_s, kind='cubic')
|
|
387
|
+
self.nu = np.linspace(self.nu[0], self.nu[-1], 1001)
|
|
388
|
+
self.eta_s = self.char(self.nu)
|
|
389
|
+
self.char = interp1d(self.nu, self.eta_s /
|
|
390
|
+
self.eta_s[np.argmax(self.char(self.nu))],
|
|
391
|
+
kind='linear')
|
|
392
|
+
|
|
393
|
+
def eta(self, nu):
|
|
394
|
+
return self.char(nu)
|