Skip to content

Commit

Permalink
Add check if network components are connected
Browse files Browse the repository at this point in the history
  • Loading branch information
lumbric committed Apr 11, 2024
1 parent ae816d0 commit c5d97dc
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 0 deletions.
11 changes: 11 additions & 0 deletions syfop/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,23 @@ def __init__(
self.time_coords = time_coords

self._check_consistent_time_coords(nodes, time_coords)
self._check_all_nodes_connected(nodes)

self.nodes = nodes
self.nodes_dict = {node.name: node for node in nodes}

self.model = self._generate_optimization_model(nodes, solver_dir)

def _check_all_nodes_connected(self, nodes):
"""Check if graph of node forms a connected network."""
graph = self._create_graph(nodes)
components = list(nx.weakly_connected_components(graph))
if len(components) > 1:
raise ValueError(
"network is not connected, there are multiple components: "
f"{', '.join(str(component) for component in components)}"
)

def _check_consistent_time_coords(self, nodes, time_coords):
# all time series need to be defined on the same coordinates otherwise vector comparison
# will lead to empty constraints
Expand Down
25 changes: 25 additions & 0 deletions tests/test_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,31 @@ def test_empty_network():
Network([])


def test_unconnected_nodes():
"""Nodes that are not connected should raise an error."""
wind = NodeScalableInput(
name="wind",
input_profile=const_time_series(0.5),
costs=1,
output_unit="MW",
)
demand = NodeFixOutput(
name="demand",
inputs=[],
input_commodities="electricity",
output_flow=const_time_series(5.0),
costs=0,
output_unit="MW",
)

# is the order of components deterministic here? would need to know how networkx checks it, but
# I guess it should be fine... if the test fails because it sais "demand", "wind" instead of
# "wind", "demand", then just remove the rest of the error_msg stating the nodes
error_msg = "network is not connected, there are multiple components: {'wind'}, {'demand'}"
with pytest.raises(ValueError, match=error_msg):
Network([wind, demand])


def test_node_with_same_name():
"""Nodes with the same name should raise an error."""
wind = NodeScalableInput(
Expand Down

0 comments on commit c5d97dc

Please sign in to comment.