# -*- coding: utf-8
"""Module of class Motor.
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/power/motor.py
SPDX-License-Identifier: MIT
"""
from tespy.components.component import Component
from tespy.components.component import component_registry
from tespy.tools.data_containers import ComponentCharacteristics as dc_cc
from tespy.tools.data_containers import ComponentProperties as dc_cp
[docs]
@component_registry
class Motor(Component):
r"""
A motor converts electrical energy into mechanical energy.
**Mandatory Equations**
- None
**Optional Equations**
- :py:meth:`tespy.components.power.motor.Motor.eta_func`
- :py:meth:`tespy.components.power.motor.Motor.delta_power_func`
- :py:meth:`tespy.components.power.motor.Motor.eta_char_func`
Inlets/Outlets
- None
Optional inlets/outlets
- power_in
- power_out
Image
.. image:: /api/_images/Motor.svg
:alt: flowsheet of the motor
:align: center
:class: only-light
.. image:: /api/_images/Motor_darkmode.svg
:alt: flowsheet of the motor
:align: center
:class: only-dark
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.
eta : float, dict
Outlet to inlet efficiency, :math:`\eta/1`
delta_power : float, dict
Fixed power offset, :math:`\text{delta_power}/\text{W}`
eta_char : tespy.tools.characteristics.CharLine, dict
Characteristic line for efficiency to power as function of design
efficiency.
Example
-------
A compressor provides compressed air which is used in a compressed air
distribution system. The energy is provided by an electrical motor.
>>> from tespy.components import Sink, Source, Compressor, Motor, PowerSource
>>> from tespy.connections import Connection, PowerConnection
>>> from tespy.networks import Network
>>> import os
>>> nw = Network(iterinfo=False)
>>> nw.units.set_defaults(**{
... "pressure": "bar", "temperature": "degC"
... })
>>> so = Source('source')
>>> si = Sink('sink')
>>> compressor = Compressor('compressor')
Ambient air flows into the compressor and is ejected at 4 bar. We can set
the system up without the use of any of the power components.
>>> c1 = Connection(so, 'out1', compressor, 'in1')
>>> c2 = Connection(compressor, 'out1', si, 'in1')
>>> nw.add_conns(c1, c2)
>>> c1.set_attr(fluid={'air': 1}, T=25, p=1, m=1)
>>> c2.set_attr(p=4)
>>> compressor.set_attr(eta_s=0.8)
>>> nw.solve('design')
We can add the Motor and a PowerSource and then connect these parts to
the compressor.
>>> motor = Motor('motor')
>>> power_source = PowerSource('power source')
>>> e1 = PowerConnection(power_source, 'power', motor, 'power_in')
>>> e2 = PowerConnection(motor, 'power_out', compressor, 'power')
>>> nw.add_conns(e1, e2)
Now we have added two variables to our problem (the power flows of e1 and
e2), but only one equation (the power balance for the compressor). The
connection between the two power flows can be made through specifying the
efficiency of the motor:
>>> motor.set_attr(eta=.98)
>>> nw.solve('design')
>>> nw.assert_convergence()
>>> round(e2.E.val_SI) == round(compressor.P.val)
True
>>> round(e1.E.val_SI) == round(compressor.P.val / 0.98)
True
We could also specify the electrical energy instead of fixing the air
mass flow to calculate the resulting air mass flow:
>>> e1.set_attr(E=1e5)
>>> c1.set_attr(m=None)
>>> nw.solve('design')
>>> round(c1.m.val, 3)
0.539
Or, fix both (electrical and mechanical power flows) and leave open the
motor efficiency:
>>> e2.set_attr(E=0.9e5)
>>> motor.set_attr(eta=None)
>>> nw.solve('design')
>>> round(motor.eta.val, 2)
0.9
>>> e2.set_attr(E=None)
>>> motor.set_attr(delta_power=5e3)
>>> nw.solve('design')
>>> round(motor.eta.val, 3)
0.95
"""
[docs]
def powerinlets(self):
return ["power_in"]
[docs]
def poweroutlets(self):
return ["power_out"]
[docs]
@staticmethod
def get_mandatory_constraints():
return {}
[docs]
def get_parameters(self):
return {
"eta": dc_cp(**{
"structure_matrix": self.eta_structure_matrix,
"func": self.eta_func,
"dependents": self.eta_dependents,
"num_eq_sets": 1,
"max_val": 1,
"min_val": 0,
"quantity": "efficiency",
"description": "efficiency"
}),
"delta_power": dc_cp(**{
"structure_matrix": self.delta_power_structure_matrix,
"func": self.delta_power_func,
"dependents": self.delta_power_dependents,
"num_eq_sets": 1,
"min_val": 0,
"quantity": "power",
"description": "inlet to outlet power difference"
}),
"eta_char": dc_cc(**{
"func": self.eta_char_func,
"dependents": self.eta_char_dependents,
"num_eq_sets": 1,
"description": "efficiency lookup table for offdesign"
})
}
[docs]
def eta_func(self):
r"""
Equation for efficiency of the component
Returns
-------
residual : float
Residual value of equation
.. math::
0=\dot E_\text{in} \cdot \eta - \dot E_\text{out}
"""
return (
self.power_inl[0].E.val_SI * self.eta.val_SI
- self.power_outl[0].E.val_SI
)
[docs]
def eta_structure_matrix(self, k):
self._structure_matrix[k, self.power_inl[0].E.sm_col] = self.eta.val_SI
self._structure_matrix[k, self.power_outl[0].E.sm_col] = -1
[docs]
def eta_dependents(self):
return [self.power_inl[0].E, self.power_outl[0].E]
[docs]
def delta_power_func(self):
r"""
Equation for power delta of the component
Returns
-------
residual : float
Residual value of equation
.. math::
0=\dot E_\text{in} - \dot E_\text{out} - \Delta \dot E
"""
return (
self.power_inl[0].E.val_SI - self.power_outl[0].E.val_SI
- self.delta_power.val_SI
)
[docs]
def delta_power_structure_matrix(self, k):
self._structure_matrix[k, self.power_inl[0].E.sm_col] = 1
self._structure_matrix[k, self.power_outl[0].E.sm_col] = -1
self._rhs[k] = self.delta_power.val_SI
[docs]
def delta_power_dependents(self):
return [self.power_inl[0].E, self.power_outl[0].E]
[docs]
def eta_char_func(self):
r"""
Equation for efficiency characteristics of the component
Returns
-------
residual : float
Residual value of equation
.. math::
0=\dot E_\text{in} \cdot \eta_\text{design} \cdot
f\left(\frac{\dot E_\text{in}}{\dot E_\text{in,design}}\right)
- \dot E_\text{out}
"""
expr = self.power_inl[0].E.val_SI / self.power_inl[0].E.design
f = self.eta_char.char_func.evaluate(expr)
return (
self.power_inl[0].E.val_SI * self.eta.design * f
- self.power_outl[0].E.val_SI
)
[docs]
def eta_char_dependents(self):
return [self.power_inl[0].E, self.power_outl[0].E]
[docs]
def calc_parameters(self):
self.eta.val_SI = self.power_outl[0].E.val_SI / self.power_inl[0].E.val_SI
self.delta_power.val_SI = (
self.power_inl[0].E.val_SI - self.power_outl[0].E.val_SI
)