Conversation
Signed-off-by: Thijs Baaijen <13253091+Thijss@users.noreply.github.com>
Signed-off-by: Thijs Baaijen <13253091+Thijss@users.noreply.github.com>
Signed-off-by: Thijs Baaijen <13253091+Thijss@users.noreply.github.com>
…tests Signed-off-by: Thijs Baaijen <13253091+Thijss@users.noreply.github.com>
… source connection issues Signed-off-by: Thijs Baaijen <13253091+Thijss@users.noreply.github.com>
Signed-off-by: Thijs Baaijen <13253091+Thijss@users.noreply.github.com>
Signed-off-by: Thijs Baaijen <13253091+Thijss@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR adds a new utility function fix_branch_orientations() to automatically orient all branches in a grid away from source nodes. The function ensures that in a radial network topology, all branches flow outward from the sources, which is important for power flow calculations and network analysis.
Changes:
- Added
fix_branch_orientations()utility function that reorients branches to flow away from sources - Added
has_parallel_edges()method to the graph model interface to detect parallel edges - Added comprehensive test coverage for both new features
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/power_grid_model_ds/utils.py | New file containing the fix_branch_orientations() function and helper functions for branch orientation fixing |
| src/power_grid_model_ds/_core/model/graphs/models/base.py | Added abstract method has_parallel_edges() to the base graph model interface |
| src/power_grid_model_ds/_core/model/graphs/models/rustworkx.py | Implemented has_parallel_edges() by delegating to rustworkx's built-in method |
| tests/unit/test_utils.py | New test file with comprehensive tests for fix_branch_orientations() covering basic functionality, dry-run mode, cycle detection, connected sources, and parallel edges |
| tests/unit/model/graphs/test_graph_model.py | Added tests for has_parallel_edges() method, including both same-direction and reversed parallel edges |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Thijs Baaijen <13253091+Thijss@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Thijs Baaijen <13253091+Thijss@users.noreply.github.com>
Signed-off-by: Thijs Baaijen <13253091+Thijss@users.noreply.github.com>
Signed-off-by: Thijs Baaijen <13253091+Thijss@users.noreply.github.com>
jaapschoutenalliander
left a comment
There was a problem hiding this comment.
I have some input on the setup but overall it looks good and I think it is a useful util function
| if set(nodes_in_order) & set(other_source_nodes): | ||
| raise GraphError("Cannot fix branch orientations if source is connected to other sources") | ||
|
|
||
| connected_branches = grid.branches.filter( |
There was a problem hiding this comment.
Do we consider branches that have a single status to 0 in need to be directed with from_status=1? Such that
[from_node]<from_status> ----> <to_status> [to_node]
[101] 1 -----> 1 [102] 1 <----- 0 [103] 1 <---- 1 [104]
gets corrected to
[101] 1 -----> 1 [102] 1 -----> 0 [103] 1 <---- 1 [104]
There was a problem hiding this comment.
This would involve the complete_graph too, so quite some work to implement now. I'd prefer to add this in a second iteration
There was a problem hiding this comment.
I am not sure it would involve the complete graph though, in this case the nodes in order are the same.
A filter like this would return the branches to switch I think:
grid.branches.filter(from_status=0, to_status=1, to_node=nodes_in_order).exclude(from_node=nodes_in_order)
There was a problem hiding this comment.
Hmm, so any branch that matches this filter should be reversed?
There was a problem hiding this comment.
I am not entirely sure this works
There was a problem hiding this comment.
Yeah, I think this could be a nice addition.
Signed-off-by: Thijs Baaijen <13253091+Thijss@users.noreply.github.com>
Signed-off-by: Thijs Baaijen <13253091+Thijss@users.noreply.github.com>
Signed-off-by: Thijs Baaijen <13253091+Thijss@users.noreply.github.com>
|
vincentkoppen
left a comment
There was a problem hiding this comment.
Looks good!
Some remarks, but nice functionality to add :)
| if set(nodes_in_order) & set(other_source_nodes): | ||
| raise GraphError("Cannot fix branch orientations if source is connected to other sources") | ||
|
|
||
| connected_branches = grid.branches.filter( |
There was a problem hiding this comment.
Yeah, I think this could be a nice addition.
| from_index = nodes_in_order.index(from_node) | ||
| to_index = nodes_in_order.index(to_node) |
There was a problem hiding this comment.
Nit: performance wise the .index is quite inefficient. I think it just loops over the list over and over again.
Instead we could make a dictionary once and use that for the lookup (which is O(1))?
node_rank = {node: index for index,node in enumerate(nodes_in_order)
...
for branch in connected_branced:
...
if node_rank[from_node] > node_rank[to_node]]
...
| from power_grid_model_ds._core.model.grids.base import Grid | ||
|
|
||
|
|
||
| def set_branch_orientations(grid: Grid, dry_run: bool = False) -> list[int]: |
There was a problem hiding this comment.
Interface wise I'm not entirely sure on the dry_run yet.
Do we want to support a dry-run, or instead just make the _get_reverted_branches_for_source available publicly as well?
-> If we do we might want to change the interface to:
--- get_reverted_branches(grid) (so the loop moves to this function)
--- set_branch_orientations(grid) (no dry-run argument)



Add new utilty function:
Todo
Piggyback
BaseGraph.has_parallel_edges()Performance
I did some testing on our production data