Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix/bidirectional #628

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from
6 changes: 3 additions & 3 deletions doc/source/pipeflow/calculation_modes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ variations are very small.
The user has to decide if these assumptions are suitable for his purposes. In future, pandapipes
will be extended in order to make sure that calculated temperatures also effect hydraulic fluid
properties. To activate temperature calculation, the pipe flow option "mode" has to be set
to "all" or "heat". If heat is chosen, the user has to provide a solution vector of the hydraulics calculation manually.
to "sequential", "bidirectional" or "heat". If heat is chosen, the user has to provide a solution vector of the hydraulics calculation manually.


Hydraulic calculations for incompressible media
Expand Down Expand Up @@ -92,8 +92,8 @@ In gas flows, the velocity is typically not constant along a pipeline. For this
tables for pipes show more entries in comparison with the result tables for incompressible media.


Temperature calculations (pipeflow option: mode = "all" or mode = "heat")
=========================================================================
Temperature calculations (pipeflow option: mode = "sequential", mode = "bidrectional" or mode = "heat")
=======================================================================================================

Important parameters of the network main components (junctions and pipes) needed for the calculation
are listed in the following table. The :ref:`component section <components>` of this manual contains
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
import numpy as np

from pandapipes.component_models.abstract_models.base_component import Component
from pandapipes.idx_branch import MDOTINIT, branch_cols
from pandapipes.pf.pipeflow_setup import get_table_number, get_lookup
from pandapipes.idx_branch import MDOTINIT, branch_cols, TEXT
from pandapipes.pf.pipeflow_setup import get_table_number, get_lookup, get_net_option

try:
import pandaplan.core.pplog as logging
Expand Down Expand Up @@ -89,6 +89,7 @@ def create_pit_branch_entries(cls, net, branch_pit):
to_nodes = junction_idx_lookup[net[cls.table_name()][tn_col].values]
branch_component_pit[:, :] = np.array([branch_table_nr] + [0] * (branch_cols - 1))
branch_component_pit[:, MDOTINIT] = 0.1
branch_component_pit[:, TEXT] = get_net_option(net, 'ambient_temperature')
return branch_component_pit, node_pit, from_nodes, to_nodes

@classmethod
Expand Down
94 changes: 54 additions & 40 deletions src/pandapipes/component_models/abstract_models/circulation_pump.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@

import numpy as np

from pandapipes.component_models.abstract_models.branch_wzerolength_models import \
BranchWZeroLengthComponent
from pandapipes.component_models.component_toolbox import set_fixed_node_entries, \
get_mass_flow_at_nodes
from pandapipes.idx_branch import D, AREA, ACTIVE
from pandapipes.idx_node import PINIT
from pandapipes.pf.pipeflow_setup import get_lookup
from pandapipes.component_models.abstract_models.branch_wzerolength_models import BranchWZeroLengthComponent
from pandapipes.component_models.component_toolbox import set_fixed_node_entries, standard_branch_wo_internals_result_lookup
from pandapipes.idx_branch import D, AREA, PUMP_TYPE, CIRC, LOAD_VEC_BRANCHES_T, TO_NODE, JAC_DERIV_DTOUT, JAC_DERIV_DT, MDOTINIT
from pandapipes.idx_node import MDOTSLACKINIT, CIRC_PUMP_OCCURENCE, EXT_GRID_OCCURENCE
from pandapipes.pf.pipeflow_setup import get_fluid
from pandapipes.pf.result_extraction import extract_branch_results_without_internals

try:
import pandaplan.core.pplog as logging
Expand Down Expand Up @@ -40,7 +39,14 @@ def get_result_table(cls, net):
if False, returns columns as tuples also specifying the dtypes
:rtype: (list, bool)
"""
return ["mdot_flow_kg_per_s", "deltap_bar"], True
if get_fluid(net).is_gas:
output = ["v_from_m_per_s", "v_to_m_per_s", "v_mean_m_per_s", "p_from_bar", "p_to_bar", "t_from_k",
"t_to_k", "mdot_from_kg_per_s", "mdot_to_kg_per_s", "vdot_norm_m3_per_s", "reynolds", "lambda",
"normfactor_from", "normfactor_to", "qext_w"]
else:
output = ["v_mean_m_per_s", "p_from_bar", "p_to_bar", "t_from_k", "t_to_k", "mdot_from_kg_per_s",
"mdot_to_kg_per_s", "vdot_norm_m3_per_s", "reynolds", "lambda", "qext_w"]
return output, True

@classmethod
def active_identifier(cls):
Expand Down Expand Up @@ -73,8 +79,8 @@ def create_pit_node_entries(cls, net, node_pit):
# TODO: there should be a warning, if any p_bar value is not given or any of the types does
# not contain "p", as this should not be allowed for this component
press = circ_pump_tbl.p_flow_bar.values
set_fixed_node_entries(net, node_pit, junction, circ_pump_tbl.type.values, press,
circ_pump_tbl.t_flow_k.values, cls.get_connected_node_type())
set_fixed_node_entries(net, node_pit, junction, circ_pump_tbl.type.values, press, circ_pump_tbl.t_flow_k.values,
cls.get_connected_node_type())
return circ_pump_tbl, press

@classmethod
Expand All @@ -90,7 +96,41 @@ def create_pit_branch_entries(cls, net, branch_pit):
circ_pump_pit = super().create_pit_branch_entries(net, branch_pit)
circ_pump_pit[:, D] = 0.1
circ_pump_pit[:, AREA] = circ_pump_pit[:, D] ** 2 * np.pi / 4
circ_pump_pit[:, ACTIVE] = False
circ_pump_pit[:, PUMP_TYPE] = CIRC
return circ_pump_pit

@classmethod
def adaption_after_derivatives_hydraulic(cls, net, branch_pit, node_pit, idx_lookups, options):
"""
Function which creates pit branch entries with a specific table.
:param net: The pandapipes network
:type net: pandapipesNet
:param branch_pit:
:type branch_pit:
:return: No Output.
"""
f, t = idx_lookups[cls.table_name()]
circ_pump_pit = branch_pit[f:t, :]
tn = circ_pump_pit[:, TO_NODE].astype(np.int32)
mask = node_pit[tn, CIRC_PUMP_OCCURENCE] == node_pit[tn, EXT_GRID_OCCURENCE]
node_pit[tn[mask], MDOTSLACKINIT] = 0
return circ_pump_pit

@classmethod
def adaption_after_derivatives_thermal(cls, net, branch_pit, node_pit, idx_lookups, options):
"""
Function which creates pit branch entries with a specific table.
:param net: The pandapipes network
:type net: pandapipesNet
:param branch_pit:
:type branch_pit:
:return: No Output.
"""
f, t = idx_lookups[cls.table_name()]
circ_pump_pit = branch_pit[f:t, :]
circ_pump_pit[:, LOAD_VEC_BRANCHES_T] = 0
circ_pump_pit[:, JAC_DERIV_DTOUT] = 1
circ_pump_pit[:, JAC_DERIV_DT] = 0

@classmethod
def extract_results(cls, net, options, branch_results, mode):
Expand All @@ -107,34 +147,8 @@ def extract_results(cls, net, options, branch_results, mode):
:type options:
:return: No Output.
"""
circ_pump_tbl = net[cls.table_name()]

if len(circ_pump_tbl) == 0:
return

res_table = net["res_" + cls.table_name()]

branch_pit = net['_pit']['branch']
node_pit = net["_pit"]["node"]

junction_lookup = get_lookup(net, "node", "index")[
cls.get_connected_node_type().table_name()]
fn_col, tn_col = cls.from_to_node_cols()
# get indices in internal structure for flow_junctions in circ_pump tables which are
# "active"
flow_junctions = circ_pump_tbl[tn_col].values
flow_nodes = junction_lookup[flow_junctions]
in_service = circ_pump_tbl.in_service.values
p_grids = np.isin(circ_pump_tbl.type.values, ["p", "pt"]) & in_service
sum_mass_flows, inverse_nodes, counts = get_mass_flow_at_nodes(net, node_pit, branch_pit,
flow_nodes[p_grids], cls)

# positive results mean that the circ_pump feeds in, negative means that the ext grid
# extracts (like a load)
res_table["mdot_flow_kg_per_s"].values[p_grids] = - (sum_mass_flows / counts)[inverse_nodes]

return_junctions = circ_pump_tbl[fn_col].values
return_nodes = junction_lookup[return_junctions]
required_results_hyd, required_results_ht = standard_branch_wo_internals_result_lookup(net)

deltap_bar = node_pit[flow_nodes, PINIT] - node_pit[return_nodes, PINIT]
res_table["deltap_bar"].values[in_service] = deltap_bar[in_service]
extract_branch_results_without_internals(net, branch_results, required_results_hyd, required_results_ht,
cls.table_name(), mode)
8 changes: 4 additions & 4 deletions src/pandapipes/component_models/component_toolbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,10 @@ def set_entry_check_repeat(pit, column, entry, repeat_number, repeated=True):


def set_fixed_node_entries(net, node_pit, junctions, eg_types, p_values, t_values, node_comp,
mode="all"):
mode="sequential"):
junction_idx_lookups = get_lookup(net, "node", "index")[node_comp.table_name()]
for eg_type in ("p", "t"):
if eg_type not in mode and mode != "all":
if eg_type not in mode and mode != "sequential" and mode!= "bidrectional":
continue
if eg_type == "p":
val_col, type_col, eg_count_col, typ, valid_types, values = \
Expand Down Expand Up @@ -200,7 +200,7 @@ def standard_branch_wo_internals_result_lookup(net):
return required_results_hyd, required_results_ht


def get_component_array(net, component_name, component_type="branch", only_active=True):
def get_component_array(net, component_name, component_type="branch", mode='hydraulics', only_active=True):
"""
Returns the internal array of a component.

Expand All @@ -218,5 +218,5 @@ def get_component_array(net, component_name, component_type="branch", only_activ
f_all, t_all = get_lookup(net, component_type, "from_to")[component_name]
if not only_active:
return net["_pit"]["components"][component_name]
in_service_elm = get_lookup(net, component_type, "active_hydraulics")[f_all:t_all]
in_service_elm = get_lookup(net, component_type, "active_%s"%mode)[f_all:t_all]
return net["_pit"]["components"][component_name][in_service_elm]
Loading
Loading