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

Feature/circ pump branch model #517

Open
wants to merge 39 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
7acdd48
enable multiple creation of heat exchanger
Jan 31, 2023
b5deb90
Merge pull request #1 from senergyNets/workshop
SimonRubenDrauz Jan 31, 2023
d7cc21d
adapted changelog and added doc for multiple heat exchanger
Jan 31, 2023
4efccce
Merge branch 'develop' into develop
SimonRubenDrauz Jan 31, 2023
fed9fc7
not heat pumps, but heat exchanger
Jan 31, 2023
61b54e0
Merge branch 'develop' into workshop
SimonRubenDrauz Jan 31, 2023
b393069
Merge remote-tracking branch 'origin/workshop' into workshop
Jan 31, 2023
a06532e
workshop material
Jan 31, 2023
9c954dc
workshop material
Feb 1, 2023
95e8aef
create a mutlinet simulation
Feb 1, 2023
fa26dbb
Merge remote-tracking branch 'origin/develop' into workshop
Feb 1, 2023
5664c1f
Merge remote-tracking branch 'senergy/bugfix/multiple_pumps' into dev…
Feb 1, 2023
430cab1
Merge remote-tracking branch 'senergy/bugfix/multiple_pumps' into wor…
Feb 1, 2023
9b8ecef
workshop preparation
Feb 2, 2023
938625c
Merge branch 'develop' of github:e2niee/pandapipes into develop
Feb 2, 2023
b7041d2
further workshop updates
Feb 2, 2023
2b1ebfc
starting multinet
Feb 2, 2023
dcc730f
multinet finalization
Feb 2, 2023
2caccd3
Merge remote-tracking branch 'origin/develop' into workshop
Feb 3, 2023
283face
adding projects from scratch
Feb 3, 2023
a77342a
adapting circulation pumps to be full branch components and cleaning …
Feb 8, 2023
af9a336
bugfix in retrieving qext_w
Feb 8, 2023
35928c5
- removing cp in the equations as it makes NR instable
Feb 10, 2023
fbcd13b
Merge remote-tracking branch 'senergy/workshop' into feature/circ_pum…
Feb 11, 2023
c8b5f81
removing workshop files
Jun 9, 2023
6e8f003
Merge branch 'develop' into feature/circ_pump_branch_model
SimonRubenDrauz Jun 9, 2023
64f7712
resetting setup.py
Jun 9, 2023
ef85aad
commenting build system matrix
Dec 21, 2023
fd28d8e
introducing bidirectional calculation
SimonRubenDrauz Apr 18, 2024
5c6c870
avoiding one-line if-conditions
SimonRubenDrauz Apr 20, 2024
52c47c8
std method not working, removed
SimonRubenDrauz Apr 20, 2024
580593a
Merge remote-tracking branch 'origin/develop' into feature/circ_pump_…
SimonRubenDrauz Apr 22, 2024
840c2f8
merge develop and further adaptions
SimonRubenDrauz Apr 23, 2024
4fbe9cb
bugfix
SimonRubenDrauz Apr 23, 2024
8a8d94f
Merge remote-tracking branch 'pp_fork/develop' into feature/circ_pump…
SimonRubenDrauz Apr 24, 2024
feb302e
required test adaption to ensure test passing
SimonRubenDrauz Apr 24, 2024
f195ece
- no mass creation in circ pumps
SimonRubenDrauz Apr 24, 2024
96da8d4
- mass at slack as one variable
SimonRubenDrauz Apr 24, 2024
adc00fc
pandapower release fail
SimonRubenDrauz Apr 24, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
long_description_content_type='text/x-rst',
url='http://www.pandapipes.org',
license='BSD',
install_requires=["pandapower>=2.14.6", "matplotlib", "shapely"],
install_requires=["pandapower==2.14.6", "matplotlib", "shapely"],
extras_require={"docs": ["numpydoc", "sphinx", "sphinx_rtd_theme", "sphinxcontrib.bibtex"],
"plotting": ["plotly", "igraph"],
"test": ["pytest", "pytest-xdist", "nbmake"],
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
92 changes: 52 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
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(), circ_pump=True)
return circ_pump_tbl, press

@classmethod
Expand All @@ -90,7 +96,39 @@ 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

@classmethod
def extract_results(cls, net, options, branch_results, mode):
Expand All @@ -107,34 +145,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)
40 changes: 15 additions & 25 deletions src/pandapipes/component_models/circulation_pump_mass_component.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@
# and Energy System Technology (IEE), Kassel, and University of Kassel. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

import numpy as np
from numpy import dtype

from pandapipes.component_models.junction_component import Junction
from pandapipes.component_models.abstract_models.circulation_pump import CirculationPump
from pandapipes.idx_node import LOAD
from pandapipes.pf.internals_toolbox import _sum_by_group
from pandapipes.pf.pipeflow_setup import get_lookup
from pandapipes.pf.pipeflow_setup import get_net_option
from pandapipes.component_models.junction_component import Junction
from pandapipes.idx_branch import JAC_DERIV_DP, JAC_DERIV_DP1, JAC_DERIV_DM, MDOTINIT, \
LOAD_VEC_BRANCHES

try:
import pandaplan.core.pplog as logging
Expand Down Expand Up @@ -51,24 +48,17 @@ def active_identifier(cls):
return "in_service"

@classmethod
def create_pit_node_entries(cls, net, node_pit):
"""
Function which creates pit node entries.
def create_pit_branch_entries(cls, net, branch_pit):
circ_pump_pit = super().create_pit_branch_entries(net, branch_pit)
circ_pump_pit[:, MDOTINIT] = net[cls.table_name()].mdot_flow_kg_per_s.values

:param net: The pandapipes network
:type net: pandapipesNet
:param node_pit:
:type node_pit:
:return: No Output.
"""
circ_pump, _ = super().create_pit_node_entries(net, node_pit)

mf = np.nan_to_num(circ_pump.mdot_flow_kg_per_s.values)
mass_flow_loads = mf * circ_pump.in_service.values
juncts, loads_sum = _sum_by_group(get_net_option(net, "use_numba"),
circ_pump.return_junction.values, mass_flow_loads)
junction_idx_lookups = get_lookup(net, "node", "index")[
cls.get_connected_node_type().table_name()]
index = junction_idx_lookups[juncts]
node_pit[index, LOAD] += loads_sum
@classmethod
def adaption_after_derivatives_hydraulic(cls, net, branch_pit, node_pit, idx_lookups, options):
# set all pressure derivatives to 0 and velocity to 1; load vector must be 0, as no change
# of velocity is allowed during the pipeflow iteration
circ_pump_pit = super().adaption_after_derivatives_hydraulic(net, branch_pit, node_pit, idx_lookups, options)
circ_pump_pit[:, JAC_DERIV_DP] = 0
circ_pump_pit[:, JAC_DERIV_DP1] = 0
circ_pump_pit[:, JAC_DERIV_DM] = 1
circ_pump_pit[:, LOAD_VEC_BRANCHES] = 0

Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from numpy import dtype

from pandapipes.component_models.abstract_models.circulation_pump import CirculationPump
from pandapipes.component_models.component_toolbox import set_fixed_node_entries
from pandapipes.component_models.junction_component import Junction
from pandapipes.idx_branch import JAC_DERIV_DP, JAC_DERIV_DP1, PL

try:
import pandaplan.core.pplog as logging
Expand All @@ -29,14 +29,8 @@ def get_component_input(cls):
:return:
:rtype:
"""
return [("name", dtype(object)),
("return_junction", "u4"),
("flow_junction", "u4"),
("p_flow_bar", "f8"),
("t_flow_k", "f8"),
("plift_bar", "f8"),
("in_service", 'bool'),
("type", dtype(object))]
return [("name", dtype(object)), ("return_junction", "u4"), ("flow_junction", "u4"), ("p_flow_bar", "f8"),
("t_flow_k", "f8"), ("plift_bar", "f8"), ("in_service", 'bool'), ("type", dtype(object))]

@classmethod
def active_identifier(cls):
Expand All @@ -47,19 +41,23 @@ def get_connected_node_type(cls):
return Junction

@classmethod
def create_pit_node_entries(cls, net, node_pit):
def create_pit_branch_entries(cls, net, branch_pit):
"""
Function which creates pit node entries.

Function which creates pit branch entries with a specific table.
:param net: The pandapipes network
:type net: pandapipesNet
:param node_pit:
:type node_pit:
:param branch_pit:
:type branch_pit:
:return: No Output.
"""
circ_pump, press = super().create_pit_node_entries(net, node_pit)
circ_pump_pit = super().create_pit_branch_entries(net, branch_pit)
circ_pump_pit[:, PL] = net[cls.table_name()]['plift_bar'].values
return circ_pump_pit

junction = circ_pump[cls.from_to_node_cols()[0]].values
p_in = press - circ_pump.plift_bar.values
set_fixed_node_entries(net, node_pit, junction, circ_pump.type.values, p_in, None,
cls.get_connected_node_type(), "p")
@classmethod
def adaption_after_derivatives_hydraulic(cls, net, branch_pit, node_pit, idx_lookups, options):
# set all pressure derivatives to 0 and velocity to 1; load vector must be 0, as no change
# of velocity is allowed during the pipeflow iteration
circ_pump_pit = super().adaption_after_derivatives_hydraulic(net, branch_pit, node_pit, idx_lookups, options)
circ_pump_pit[:, JAC_DERIV_DP] = 1
circ_pump_pit[:, JAC_DERIV_DP1] = -1
Loading
Loading