Source code for tespy.tools.plotting
# -*- coding: utf-8
"""Module for cycle plotting data extraction.
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/tools/plotting.py
SPDX-License-Identifier: MIT
"""
import numpy as np
from tespy.tools.fluid_properties import T_mix_ph
from tespy.tools.fluid_properties import s_mix_ph
[docs]
def get_plotting_data(nw, connection_label):
"""
Retrieve the process information and all state points of the fluid in a
given part of the network identified by a connection label.
Parameters
----------
nw : tespy.networks.network.Network
Network object.
connection_label : str
Label of any connection in the desired part of the network.
Returns
-------
tuple
Tuple with dictionary of process line data that are passed to the
:code:`calc_individual_isoline` method of :code:`fluprodia` and process
points dictionary with the state information.
"""
# these need to be imported here as there will be circular imports
# otherwise
from tespy.components.basics.source import Source
from tespy.components.heat_exchangers.base import HeatExchanger
from tespy.components.nodes.drum import Drum
branch_label = _get_wrapper_by_connection_label(
nw.fluid_wrapper_branches, connection_label
)
connections = nw.fluid_wrapper_branches[branch_label]["connections"]
components = nw.fluid_wrapper_branches[branch_label]["components"]
points = {}
processes = {}
for component in components:
data = component.get_plotting_data()
if data is None:
if isinstance(component, Source):
processes[component.label] = None
continue
if isinstance(component, HeatExchanger):
if component.inl[0] in connections and component.inl[1] in connections:
processes[f"{component.label}_hot"] = data[1]
processes[f"{component.label}_cold"] = data[2]
elif component.inl[0] in connections:
processes[component.label] = data[1]
else:
processes[component.label] = data[2]
elif component.num_i == 1 and component.num_o == 1:
processes[component.label] = data[1]
elif isinstance(component, Drum):
processes[f"{component.label}_1"] = data[1]
processes[f"{component.label}_2"] = data[2]
else:
for key, value in data.items():
processes[f"{component.label}_{key}"] = value
points = {
c.label: {
key.replace("vol", "v"): c.get_attr(key).val
for key in ["p", "h", "T", "s", "vol"]
}
for c in connections
}
return processes, points
def _get_wrapper_by_connection(wrappers, connection):
"""Get the wrapper branch which holds the specified connection object
Parameters
----------
wrappers : dict
Dictionary of network fluid property wrapper branches
connection : tespy.connections.connection.Connection
Connection object to find wrapper branch for.
Returns
-------
str
Key of the wrapper branch
"""
for wrapper, data in wrappers.items():
if connection in data["connections"]:
return wrapper
def _get_wrapper_by_connection_label(wrappers, label):
"""Get the wrapper branch which holds the specified connection label
Parameters
----------
wrappers : dict
Dictionary of network fluid property wrapper branches
label : str
Connection label to find wrapper branch for.
Returns
-------
str
Key of the wrapper branch
"""
for wrapper, data in wrappers.items():
connection_labels = [c.label for c in data["connections"]]
if label in connection_labels:
return wrapper
[docs]
def get_heatexchanger_secondary_Ts(nw, connection_label):
"""
Get the **fake** process lines and points to visualize heat exchange to
secondary fluids of a cycle.
Temperature values are taken from the secondary side and they are matched
to the entropy values of the primary side (the branch the connection label)
was specified for.
Parameters
----------
nw : tespy.networks.network.Network
Network object.
connection_label : str
Label of any connection in the desired part of the network.
Returns
-------
tuple
Tuple with dictionary of process line data of the secondary sides of
heat exchangers and process points dictionary with the state
information to plot the secondary sides in a Ts diagram
"""
# these need to be imported here as there will be circular imports
# otherwise
from tespy.components.heat_exchangers.base import HeatExchanger
from tespy.components.heat_exchangers.parallel import ParallelFlowHeatExchanger
branch_label = _get_wrapper_by_connection_label(
nw.fluid_wrapper_branches, connection_label
)
connections = nw.fluid_wrapper_branches[branch_label]["connections"]
components = nw.fluid_wrapper_branches[branch_label]["components"]
other_processes = {}
other_points = {}
for component in components:
if not isinstance(component, HeatExchanger):
continue
elif component.inl[0] in connections and component.inl[1] in connections:
continue
elif component.inl[0] in connections:
connection_idx = 1
else:
connection_idx = 0
connection_in = component.inl[connection_idx]
connection_out = component.outl[connection_idx]
wrapper = _get_wrapper_by_connection(
nw.fluid_wrapper_branches, connection_in
)
if wrapper not in other_processes:
other_processes[wrapper] = {}
other_points[wrapper] = {}
p_range = np.linspace(connection_in.p.val_SI, connection_out.p.val_SI)
h_range = np.linspace(connection_in.h.val_SI, connection_out.h.val_SI)
c = connection_in
ureg = nw.units._ureg
T_range = ureg.Quantity(
np.array([
T_mix_ph(p, h, c.fluid_data, c.mixing_rule)
for p, h in zip(p_range, h_range)
]),
"K"
).to(c.T.unit).magnitude
label_inflow = connection_in.label
label_outflow = connection_out.label
other_points[wrapper][label_inflow] = {"T": T_range[0]}
other_points[wrapper][label_outflow] = {"T": T_range[-1]}
# is comes from other side
connection_in = component.inl[1 - connection_idx]
connection_out = component.outl[1 - connection_idx]
p_range = np.linspace(connection_in.p.val_SI, connection_out.p.val_SI)
h_range = np.linspace(connection_in.h.val_SI, connection_out.h.val_SI)
c = connection_in
s_range = ureg.Quantity(
np.array([
s_mix_ph(p, h, c.fluid_data, c.mixing_rule)
for p, h in zip(p_range, h_range)
]),
"J/(kgK)"
).to(c.s.unit).magnitude
if isinstance(component, ParallelFlowHeatExchanger):
other_points[wrapper][label_inflow]["s"] = s_range[0]
other_points[wrapper][label_outflow]["s"] = s_range[-1]
else:
other_points[wrapper][label_inflow]["s"] = s_range[-1]
other_points[wrapper][label_outflow]["s"] = s_range[0]
s_range = s_range[::-1]
other_processes[wrapper][component.label] = {
"T": T_range,
"s": s_range
}
return other_processes, other_points