Skip to content

Commit

Permalink
Added unsupplied_junctions and elements_on_path to pandapipes
Browse files Browse the repository at this point in the history
  • Loading branch information
Moritz Franz committed Jan 16, 2024
1 parent 613fe60 commit 3a15834
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 0 deletions.
23 changes: 23 additions & 0 deletions src/pandapipes/test/topology/test_graph_searches.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

import pandapipes.networks as nw
import pandapipes.topology as top
import networkx as nx
import pytest


def test_connected_components():
Expand All @@ -18,3 +20,24 @@ def test_connected_components():
assert len(list(top.connected_components(mg))) == 6
mg = top.create_nxgraph(net, include_pipes=False, include_valves=False)
assert len(list(top.connected_components(mg))) == 8


def test_unsupplied_buses_with_in_service():
net = nw.gas_versatility()
assert top.unsupplied_junctions(net) == set()
net.pipe.loc[7, "in_service"] = False
assert top.unsupplied_junctions(net) == {8}


def test_elements_on_path():
net = nw.gas_versatility()
for multi in [True, False]:
mg = top.create_nxgraph(net, multi=multi)
path = nx.shortest_path(mg, 0, 6)
assert top.elements_on_path(mg, path, "pipe") == [0, 9]
assert top.elements_on_path(mg, path) == [0, 9]
assert top.elements_on_path(mg, path, "valve") == []
assert top.elements_on_path(mg, path, "pump") == [0]
with pytest.raises(ValueError) as exception_info:
top.elements_on_path(mg, path, element="source")
assert str(exception_info.value) == "Invalid element type source"
1 change: 1 addition & 0 deletions src/pandapipes/topology/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
# Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

from pandapipes.topology.create_graph import *
from pandapipes.topology.topology_toolbox import *
from pandapipes.topology.graph_searches import *
from pandapower.topology.graph_searches import connected_component, connected_components
74 changes: 74 additions & 0 deletions src/pandapipes/topology/graph_searches.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import networkx as nx
import pandas as pd
from pandapipes.topology.create_graph import create_nxgraph
from pandapipes.topology.topology_toolbox import get_all_branch_component_table_names


def calc_distance_to_junction(net, junction, notravjunctions=None, nogojunctions=None,
Expand Down Expand Up @@ -78,6 +79,79 @@ def calc_minimum_distance_to_junctions(net, junctions, notravjunctions=None, nog
return pd.Series(nx.single_source_dijkstra_path_length(mg, junction))


def unsupplied_junctions(net, mg=None, slacks=None, respect_valves=True):
"""
Finds junctions, that are not connected to an external grid.
INPUT:
**net** (pandapipesNet) - variable that contains a pandapipes network
OPTIONAL:
**mg** (NetworkX graph) - NetworkX Graph or MultiGraph that represents a pandapipes network.
**in_service_only** (boolean, False) - Defines whether only in service junctions should be
included in unsupplied_junctions.
**slacks** (set, None) - junctions which are considered as root / slack junctions. If None, all
existing slack junctions are considered.
**respect_valves** (boolean, True) - Fixes how to consider valves - only in case of no
given mg.
OUTPUT:
**uj** (set) - unsupplied junctions
EXAMPLE:
import pandapipes.topology as top
top.unsupplied_junctions(net)
"""

mg = mg or create_nxgraph(net, respect_status_valves=respect_valves)
if slacks is None:
slacks = set(net.ext_grid[net.ext_grid.in_service].junction.values)
not_supplied = set()
for cc in nx.connected_components(mg):
if not set(cc) & slacks:
not_supplied.update(set(cc))
return not_supplied


def elements_on_path(mg, path, element="pipe"):
"""
Finds all elements that connect a given path of junctions.
INPUT:
**mg** (NetworkX graph) - NetworkX Graph or MultiGraph that represents a pandapipes network.
**path** (list) - List of connected junctions.
**element** (string, "l") - element type of type BranchComponent
**multi** (boolean, True) - True: Applied on a NetworkX MultiGraph
False: Applied on a NetworkX Graph
OUTPUT:
**elements** (list) - Returns a list of all elements on the path.
EXAMPLE:
import topology as top
mg = top.create_nxgraph(net)
elements = top.elements_on_path(mg, [4, 5, 6])
"""
table_names = get_all_branch_component_table_names()
if element not in table_names:
raise ValueError("Invalid element type %s" % element)
if isinstance(mg, nx.MultiGraph):
return [edge[1] for b1, b2 in zip(path, path[1:]) for edge in mg.get_edge_data(b1, b2).keys()
if edge[0] == element]
else:
return [mg.get_edge_data(b1, b2)["key"][1] for b1, b2 in zip(path, path[1:])
if mg.get_edge_data(b1, b2)["key"][0] == element]


if __name__ == '__main__':
import pandapipes.networks as nw
net = nw.gas_meshed_delta()
Expand Down
42 changes: 42 additions & 0 deletions src/pandapipes/topology/topology_toolbox.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Copyright (c) 2020-2024 by Fraunhofer Institute for Energy Economics
# 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.

from pandapipes.component_models.abstract_models.branch_models import BranchComponent


def get_all_branch_component_models():
"""
Get all models of available branch components
:return: branch model
:rtype: list
"""
def get_all_subclasses(cls):
all_subclasses = list()
for subclass in cls.__subclasses__():
all_subclasses.append(subclass)
all_subclasses.extend(get_all_subclasses(subclass))
return all_subclasses

all_branch_components = get_all_subclasses(BranchComponent)
filtered = list()
for bc in all_branch_components:
try:
bc.table_name()
filtered.append(bc)
except Exception as e:
# component does not have a table_name implemented
continue
return filtered


def get_all_branch_component_table_names():
"""
Get all table names of available branch components
:return: table names
:rtype: list
"""
cm = get_all_branch_component_models()
return [c.table_name() for c in cm]

0 comments on commit 3a15834

Please sign in to comment.