# -*- coding: utf-8
"""Module of class Turbomachine.
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/turbomachinery/base.py
SPDX-License-Identifier: MIT
"""
from tespy.components.component import Component
from tespy.components.component import component_registry
from tespy.tools.data_containers import ComponentMandatoryConstraints as dc_cmc
from tespy.tools.data_containers import ComponentProperties as dc_cp
from tespy.tools.helpers import _numeric_deriv
[docs]
@component_registry
class Turbomachine(Component):
r"""
Parent class for compressor, pump and turbine.
**Mandatory Equations**
- mass flow: :py:meth:`tespy.components.component.Component.variable_equality_structure_matrix`
- fluid: :py:meth:`tespy.components.component.Component.variable_equality_structure_matrix`
**Optional Equations**
- :py:meth:`tespy.components.component.Component.pr_structure_matrix`
- :py:meth:`tespy.components.component.Component.dp_structure_matrix`
- :py:meth:`tespy.components.turbomachinery.base.Turbomachine.energy_balance_func`
Inlets/Outlets
- in1
- out1
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.
P : float, dict
Power, :math:`P/\text{W}`
pr : float, dict
Outlet to inlet pressure ratio, :math:`pr/1`
dp : float, dict
Inlet to outlet pressure difference, :math:`dp/\text{p}_\text{unit}`
Is specified in the Network's pressure unit
Example
-------
For an example please refer to:
- :class:`tespy.components.turbomachinery.compressor.Compressor`
- :class:`tespy.components.turbomachinery.pump.Pump`
- :class:`tespy.components.turbomachinery.turbine.Turbine`
- :class:`tespy.components.turbomachinery.steam_turbine.SteamTurbine`
"""
[docs]
def get_parameters(self):
return {
'P': dc_cp(
num_eq_sets=1,
func=self.energy_balance_func,
dependents=self.energy_balance_dependents,
quantity="power",
description="power input/output of the component"
),
'pr': dc_cp(
num_eq_sets=1,
func_params={'pr': 'pr'},
structure_matrix=self.pr_structure_matrix,
quantity="ratio",
description="outlet to inlet pressure ratio"
),
'dp': dc_cp(
num_eq_sets=1,
structure_matrix=self.dp_structure_matrix,
func_params={'dp': 'dp'},
quantity="pressure",
description="inlet to outlet absolute pressure change"
)
}
[docs]
def get_bypass_constraints(self):
return {
'mass_flow_constraints': dc_cmc(**{
'structure_matrix': self.variable_equality_structure_matrix,
'num_eq_sets': self.num_i,
'func_params': {'variable': 'm'}
}),
'pressure_constraints': dc_cmc(**{
'structure_matrix': self.variable_equality_structure_matrix,
'num_eq_sets': self.num_i,
'func_params': {'variable': 'p'}
}),
'enthalpy_constraints': dc_cmc(**{
'structure_matrix': self.variable_equality_structure_matrix,
'num_eq_sets': self.num_i,
'func_params': {'variable': 'h'}
}),
'fluid_constraints': dc_cmc(**{
'structure_matrix': self.variable_equality_structure_matrix,
'num_eq_sets': self.num_i,
'func_params': {'variable': 'fluid'}
})
}
[docs]
@staticmethod
def inlets():
return ['in1']
[docs]
@staticmethod
def outlets():
return ['out1']
[docs]
def energy_balance_func(self):
r"""
Calculate energy balance of a turbomachine.
Returns
-------
residual : float
Residual value of turbomachine energy balance
.. math::
0=\dot{m}_{in}\cdot\left(h_{out}-h_{in}\right)-P
"""
return (
self.inl[0].m.val_SI
* (self.outl[0].h.val_SI - self.inl[0].h.val_SI) - self.P.val_SI
)
[docs]
def energy_balance_dependents(self):
return [
self.inl[0].m,
self.inl[0].h,
self.outl[0].h,
]
[docs]
def bus_func(self, bus):
r"""
Calculate the value of the bus function.
Parameters
----------
bus : tespy.connections.bus.Bus
TESPy bus object.
Returns
-------
residual : float
Value of energy transfer :math:`\dot{E}`. This value is passed to
:py:meth:`tespy.components.component.Component.calc_bus_value`
for value manipulation according to the specified characteristic
line of the bus.
.. math::
\dot{E} = \dot{m}_{in} \cdot \left(h_{out} - h_{in} \right)
"""
return self.inl[0].m.val_SI * (
self.outl[0].h.val_SI - self.inl[0].h.val_SI
)
[docs]
def bus_deriv(self, bus):
r"""
Calculate partial derivatives of the bus function.
Parameters
----------
bus : tespy.connections.bus.Bus
TESPy bus object.
Returns
-------
deriv : ndarray
Matrix of partial derivatives.
"""
f = self.calc_bus_value
if self.inl[0].m.is_var:
if self.inl[0].m.J_col not in bus.jacobian:
bus.jacobian[self.inl[0].m.J_col] = 0
bus.jacobian[self.inl[0].m.J_col] -= _numeric_deriv(self.inl[0].m._reference_container, f, bus=bus)
if self.inl[0].h.is_var:
if self.inl[0].h.J_col not in bus.jacobian:
bus.jacobian[self.inl[0].h.J_col] = 0
bus.jacobian[self.inl[0].h.J_col] -= _numeric_deriv(self.inl[0].h._reference_container, f, bus=bus)
if self.outl[0].h.is_var:
if self.outl[0].h.J_col not in bus.jacobian:
bus.jacobian[self.outl[0].h.J_col] = 0
bus.jacobian[self.outl[0].h.J_col] -= _numeric_deriv(self.outl[0].h._reference_container, f, bus=bus)
[docs]
def calc_parameters(self):
r"""Postprocessing parameter calculation."""
self.P.val_SI = self.inl[0].m.val_SI * (
self.outl[0].h.val_SI - self.inl[0].h.val_SI)
self.pr.val_SI = self.outl[0].p.val_SI / self.inl[0].p.val_SI
self.dp.val_SI = self.inl[0].p.val_SI - self.outl[0].p.val_SI
[docs]
def entropy_balance(self):
r"""
Calculate entropy balance of turbomachine.
Note
----
The entropy balance makes the follwing parameter available:
.. math::
\text{S\_irr}=\dot{m} \cdot \left(s_\mathrm{out}-s_\mathrm{in}
\right)\\
"""
self.S_irr = self.inl[0].m.val_SI * (
self.outl[0].s.val_SI - self.inl[0].s.val_SI
)
[docs]
def get_plotting_data(self):
"""Generate a dictionary containing FluProDia plotting information.
Returns
-------
data : dict
A nested dictionary containing the keywords required by the
:code:`calc_individual_isoline` method of the
:code:`FluidPropertyDiagram` class. First level keys are the
connection index ('in1' -> 'out1', therefore :code:`1` etc.).
"""
return {
1: {
'isoline_property': 's',
'isoline_value': self.inl[0].s.val,
'isoline_value_end': self.outl[0].s.val,
'starting_point_property': 'v',
'starting_point_value': self.inl[0].vol.val,
'ending_point_property': 'v',
'ending_point_value': self.outl[0].vol.val
}
}