Skip to content

Commit 11b5cda

Browse files
Merge branch 'feature/power-grid-model-ds-workshop' of https://github.com/PowerGridModel/power-grid-model-workshop into feature/power-grid-model-ds-workshop
2 parents 4f21787 + 8beaafa commit 11b5cda

File tree

2 files changed

+42
-48
lines changed

2 files changed

+42
-48
lines changed

power-grid-model-ds/advanced.ipynb

Lines changed: 41 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,18 @@
2525
"id": "d5e1958f",
2626
"metadata": {},
2727
"source": [
28-
"# ⚡ Advanced Power Grid Workshop: Solving an Overload Scenario\n",
28+
"# ⚡ Advanced PGM-DS Workshop: Solving an Overload Scenario\n",
2929
"\n",
30-
"You're a senior grid analyst at GridNova Utilities, overseeing a legacy radial distribution network in a semi-rural region. Recently, customer load growth has increased dramatically, particularly in areas served by a single long feeder. This has pushed some branches past their capacity, triggering repeated overloads.\n",
30+
"You're a senior grid analyst at GridNova Utilities, responsible for operating a legacy distribution grid in a rural area. The grid is radially operated, with some cables inactive as back-up in case failures. Recently, customer load growth has increased dramatically, particularly in areas served by several long feeders. This has pushed some branches past their capacity, triggering repeated overloads.\n",
3131
"\n",
32-
"Your task: augment the grid by adding a second substation and relieving the overloaded feeder through targeted switching.\n",
32+
"Your task: upgrade the grid by adding a second substation and relieving the overloaded feeder through new connections to the new substation.\n",
3333
"\n",
34-
"This hands-on simulation walks you through each step of diagnosing, planning, and solving this overload using the Power Grid Model DS library.\n",
34+
"This hands-on simulation walks you through each step of diagnosing, planning, and solving this overload using the Power Grid Model Data Science library.\n",
3535
"\n",
3636
"## 🎯 Workshop Goals\n",
37-
"- Detect a line overload after load increase.\n",
38-
"- Find a suitable node to connect a new substation.\n",
39-
"- Trace the overloaded route.\n",
40-
"- Strategically open a line to reroute power and relieve the feeder.\n",
41-
"\n"
37+
"- Detect a line overload using PGM load flow calculations.\n",
38+
"- Find a suitable node to create a connection to the new substation.\n",
39+
"- Strategically open a line to reroute power and relieve the feeder.\n"
4240
]
4341
},
4442
{
@@ -63,9 +61,9 @@
6361
"metadata": {},
6462
"source": [
6563
"# 🧪 Step 1: Extend the Data Model\n",
66-
"Goal: Add coordinate fields and tracking for simulated voltages and line currents.\n",
64+
"Goal: Add coordinate fields to nodes and fields for tracking simulated voltages and line currents.\n",
6765
"\n",
68-
"You’ll subclass NodeArray and LineArray to add:\n",
66+
"We subclass NodeArray and LineArray to add:\n",
6967
"\n",
7068
"- x, y coordinates for spatial logic and plotting\n",
7169
"- u for node voltage results\n",
@@ -118,6 +116,7 @@
118116
"source": [
119117
"# 🏗️ Step 2: Load and Prepare the Grid\n",
120118
"Goal: Load a synthetic medium-voltage grid from the provided data"
119+
"(Code is already given in helper.py file, take a look to see how the grid data is loaded!)"
121120
]
122121
},
123122
{
@@ -150,14 +149,13 @@
150149
"# 🧯 Step 3: Detect the Overload\n",
151150
"This is your first excercise.\n",
152151
"\n",
153-
"Goal: Identify which line(s) are exceeding their rated current.\n",
154-
"\n",
155-
"You’ll:\n",
152+
"Goal: Identify which line(s) are exceeding their rated current (the `i_n` property).\n",
156153
"\n",
157-
"- Use the .is_overloaded property to find the problem\n",
158-
"- Isolate the feeder route to the affected line\n",
154+
"You can do this step by step (don't forget to check the PGM-DS documentation):\n",
159155
"\n",
160-
"This gives a clear target for where you need to intervene."
156+
"1. Use the PowerGridModelInterface to calculate power flow\n",
157+
"2. Update the Grid object with the calculated values\n",
158+
"3. Return the lines (LineArray) that are overloaded"
161159
]
162160
},
163161
{
@@ -175,11 +173,6 @@
175173
}
176174
],
177175
"source": [
178-
"# Check the grid for capacity issues\n",
179-
"# 1. Use the PowerGridModelInterface to calculate power flow\n",
180-
"# 2. Update the grid with the calculated values\n",
181-
"# 3. Return the lines (LineArray) that are overloaded\n",
182-
"\n",
183176
"# Hint: You can use the `is_overloaded` property of the `MyLineArray` class to check for overloaded lines.\n",
184177
"# Hint: https://power-grid-model-ds.readthedocs.io/en/stable/quick_start.html#performing-power-flow-calculations\n",
185178
"\n",
@@ -217,16 +210,16 @@
217210
"metadata": {},
218211
"source": [
219212
"# 🧭 Step 4: Plan a Relief Strategy\n",
220-
"We found out the north west part of the area is overloaded. To relieve the problem we will build a new substation near the overloaded area and connect part of the grid there.\n",
213+
"\n",
214+
"If you visualize the grid and highlight the overloaded cables, this is what you will see:\n",
221215
"\n",
222216
"![input_network_with_overload.png](input_network_with_overload.png)\n",
223217
"\n",
224-
"Goal: Place a second substation near the overloaded paths.\n",
218+
"We found out the north west part of the area is overloaded.\n",
219+
"Goal: Place a second substation near the overloaded path. In the next steps we will use this substation to relieve overloaded cables.\n",
225220
"\n",
226221
"You’ll:\n",
227-
"- Add a new substation at a specified location\n",
228-
"- Connect it to the closest node in the network\n",
229-
"- Visually inspect the grid with visualize()\n",
222+
"- Create a new substations using the NodeArrayobject at the correct location.\n",
230223
"\n",
231224
"This substation will act as a new injection point for rerouting load.\n"
232225
]
@@ -253,15 +246,13 @@
253246
"id": "8f2b17e3",
254247
"metadata": {},
255248
"source": [
256-
"# 🔗 Step 5: Trace and Analyze the Overloaded Route\n",
257-
"Goal: Identify a switchable line along the route from the new node to the old substation.\n",
249+
"# 🔗 Step 5: Analyze and Connect the Overloaded Route\n",
250+
"Goal: Identify the best way to connect the new substation to the overloaded routes.\n",
258251
"\n",
259252
"You’ll:\n",
260-
"- Use the graph interface to trace the shortest path from the new substation to the original\n",
261-
"- Calculate cumulative load along the path\n",
262-
"- Find a cut point where the remaining load toward the old substation is < 2 MW\n",
263-
"\n",
264-
"This ensures you relieve the feeder while maintaining supply continuity."
253+
"- Compute which routes (/feeders) are overloaded to see where we need to invervene.\n",
254+
"- Find which node on an overloaded route is geographically closed to the new substation.\n",
255+
"- Create a new cable to connect the closest node to the new substation."
265256
]
266257
},
267258
{
@@ -275,7 +266,7 @@
275266
"# Hint: The arrays in the grid have a filter option, https://power-grid-model-ds.readthedocs.io/en/stable/examples/model/array_examples.html#using-filters\n",
276267
"\n",
277268
"def get_all_congested_routes(grid: Grid) -> list[NodeArray]:\n",
278-
" \"\"\"Get all routes that originate from a given substation node.\"\"\"\n",
269+
" \"\"\"Get all nodes on routes that contain an overloaded line.\"\"\"\n",
279270
"\n",
280271
"# %load solutions/advanced_5_1_get_all_congested_routes.py"
281272
]
@@ -310,7 +301,9 @@
310301
"id": "a75e9b73",
311302
"metadata": {},
312303
"source": [
313-
"Finally we build a function that creates a new line between the connection point and the new substation. We will first create it with an open connection and optimize the opening in the next step."
304+
"Finally we build a function that creates a new line between the connection point and the new substation.\n",
305+
"\n",
306+
"❗ IMPORTANT ❗ The new line should first be created with an open connection; we will optimize the location of the line opening in the next step."
314307
]
315308
},
316309
{
@@ -334,15 +327,16 @@
334327
"id": "4a9ef582",
335328
"metadata": {},
336329
"source": [
337-
"# ✂️ Step 6: Open the Right Line\n",
338-
"Goal: Deactivate a line to offload the original feeder.\n",
330+
"# 🔌 Step 6: Open the Right Line\n",
331+
"Goal: Find the optimal line to open to relieve the original overloaded feeder.\n",
339332
"\n",
340333
"You’ll:\n",
341-
"- Identify and deactivate the line between two nodes on the critical path\n",
342-
"- Rerun power flow after the switch\n",
334+
"- Trace a path from the newly created cable to the old substation\n",
335+
"- Evaluate each line on the path by running `check_for_capacity_issues()` and find the optimal line to open\n",
336+
"- Open the correct line\n",
343337
"- Confirm the overload is resolved\n",
344338
"\n",
345-
"This final step demonstrates how network topology and load can be managed dynamically with switching and distributed generation.\n",
339+
"This final step demonstrates how network topology can be programmatically optimized using the Power Grid Model Data Science toolkit!\n",
346340
"\n"
347341
]
348342
},
@@ -354,7 +348,7 @@
354348
"outputs": [],
355349
"source": [
356350
"def optimize_route_transfer(grid: Grid, connection_point: NodeArray, new_substation: NodeArray) -> None:\n",
357-
" \"\"\"Attempt to optimize the route transfer moving the naturally open point (NOP) upstream towards the old substation.\n",
351+
" \"\"\"Attempt to optimize the route transfer moving the normally open point (NOP) upstream towards the old substation.\n",
358352
" This way, the new substation will take over more nodes of the original route.\n",
359353
" \"\"\"\n",
360354
" # Get the path from the connection point to the old substation\n",
@@ -456,17 +450,17 @@
456450
"# ✅ Wrap-Up\n",
457451
"You’ve just:\n",
458452
"\n",
459-
"Diagnosed a power system constraint\n",
460-
"- Planned and executed a grid topology change\n",
461-
"- Verified success with power flow simulations\n",
453+
"- Loaded a grid topology and grid loads from a file\n",
454+
"- Analyse grid components that are or will soon be overloaded using load flow analysis\n",
455+
"- Automatically optimize a solution to relieve (future) congestions on the energy grid\n",
462456
"\n",
463457
"We hope you enjoyed working with Power Grid Model DS and would love to hear your feedback"
464458
]
465459
}
466460
],
467461
"metadata": {
468462
"kernelspec": {
469-
"display_name": ".venv",
463+
"display_name": "power-grid-model-workshop",
470464
"language": "python",
471465
"name": "python3"
472466
},
@@ -480,7 +474,7 @@
480474
"name": "python",
481475
"nbconvert_exporter": "python",
482476
"pygments_lexer": "ipython3",
483-
"version": "3.12.6"
477+
"version": "undefined.undefined.undefined"
484478
}
485479
},
486480
"nbformat": 4,

power-grid-model-ds/solutions/advanced_5_1_get_all_congested_routes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
def get_all_congested_routes(grid: Grid) -> list[NodeArray]:
2-
"""Get all routes that originate from a given substation node."""
2+
"""Get all nodes on routes that contain an overloaded line."""
33
grid.set_feeder_ids()
44
lines_with_congestion = check_for_capacity_issues(grid)
55
feeder_branch_ids_with_congestion = np.unique(lines_with_congestion['feeder_branch_id'])

0 commit comments

Comments
 (0)