From 718ab10425de913cbcfe4a275b129e63f7cf0f12 Mon Sep 17 00:00:00 2001 From: Thijs Baaijen <13253091+Thijss@users.noreply.github.com> Date: Wed, 7 May 2025 14:42:51 +0200 Subject: [PATCH] Add workshop draft Signed-off-by: Thijs Baaijen <13253091+Thijss@users.noreply.github.com> --- workshop/__init__.py | 0 workshop/routes.py | 73 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 workshop/__init__.py create mode 100644 workshop/routes.py diff --git a/workshop/__init__.py b/workshop/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/workshop/routes.py b/workshop/routes.py new file mode 100644 index 0000000..cdd015a --- /dev/null +++ b/workshop/routes.py @@ -0,0 +1,73 @@ +""" +Definitions: + +- Feeder branch: A branch that connects a substation to a distribution network. +- Route: A path of nodes with a single feeder branch. + + +""" + +from power_grid_model_ds import Grid +from power_grid_model_ds._core.model.arrays import LineArray, NodeArray + +# NodeArray.station_name? + + +class NoCandidateNodesError(Exception): + """Exception raised when no candidate nodes are found for a new substation.""" + + +def build_new_substation(grid: Grid, location: tuple[float, float]) -> None: + """Build a new substation at the given location. + + (Create a substation node at the given location) + """ + + +def get_all_routes(grid: Grid, substation_node: NodeArray) -> list[NodeArray]: + """Get all routes that originate from a given substation node.""" + + +def transfer_routes(grid: Grid, old_substation: NodeArray, new_substation: NodeArray) -> None: + """Migrate a subset of the routes of the old substation to the new substation. + Each route can be migrated fully or partially. + + """ + routes = get_all_routes(grid, old_substation) + for route in routes: + try: + connection_point = find_connection_point(route, old_substation, new_substation) + except NoCandidateNodesError: + continue + + connect_to_route(grid, route, new_substation) + + +def find_connection_point(route: NodeArray, old_substation: NodeArray, new_substation: NodeArray) -> NodeArray: + """Calculate the connection point for the new route. + This should be the geographically closest node to the new substation. + + Should raise NoCandidateNodesError if all nodes in the route are geographically closer to the old substation. + """ + + +def connect_to_route(grid: Grid, connection_point: NodeArray, new_substation: NodeArray) -> None: + """Connect the new substation node to the connection point. + + 1. Create a new line that connects the two nodes + 2. Deactivate the line that connects the connection point to the old substation + """ + + +def optimize_route_transfer(grid: Grid, connection_point: NodeArray) -> None: + """Attempt to optimize the route transfer moving the naturally open point (NOP) upstream towards the old substation. + This way, the new substation will take over more nodes of the original route. + + Note that a node cannot be taken over if that results in a capacity issue on the grid. + """ + + +def check_for_capacity_issues(grid: Grid) -> tuple[NodeArray, LineArray]: + """Check for capacity issues on the grid. + Return the nodes and lines that with capacity issues. + """