|
25 | 25 | "id": "d5e1958f", |
26 | 26 | "metadata": {}, |
27 | 27 | "source": [ |
28 | | - "# ⚡ Advanced Power Grid Workshop: Solving an Overload Scenario\n", |
| 28 | + "# ⚡ Advanced PGM-DS Workshop: Solving an Overload Scenario\n", |
29 | 29 | "\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", |
31 | 31 | "\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", |
33 | 33 | "\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", |
35 | 35 | "\n", |
36 | 36 | "## 🎯 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" |
42 | 40 | ] |
43 | 41 | }, |
44 | 42 | { |
|
63 | 61 | "metadata": {}, |
64 | 62 | "source": [ |
65 | 63 | "# 🧪 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", |
67 | 65 | "\n", |
68 | | - "You’ll subclass NodeArray and LineArray to add:\n", |
| 66 | + "We subclass NodeArray and LineArray to add:\n", |
69 | 67 | "\n", |
70 | 68 | "- x, y coordinates for spatial logic and plotting\n", |
71 | 69 | "- u for node voltage results\n", |
|
118 | 116 | "source": [ |
119 | 117 | "# 🏗️ Step 2: Load and Prepare the Grid\n", |
120 | 118 | "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!)" |
121 | 120 | ] |
122 | 121 | }, |
123 | 122 | { |
|
150 | 149 | "# 🧯 Step 3: Detect the Overload\n", |
151 | 150 | "This is your first excercise.\n", |
152 | 151 | "\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", |
156 | 153 | "\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", |
159 | 155 | "\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" |
161 | 159 | ] |
162 | 160 | }, |
163 | 161 | { |
|
175 | 173 | } |
176 | 174 | ], |
177 | 175 | "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", |
183 | 176 | "# Hint: You can use the `is_overloaded` property of the `MyLineArray` class to check for overloaded lines.\n", |
184 | 177 | "# Hint: https://power-grid-model-ds.readthedocs.io/en/stable/quick_start.html#performing-power-flow-calculations\n", |
185 | 178 | "\n", |
|
217 | 210 | "metadata": {}, |
218 | 211 | "source": [ |
219 | 212 | "# 🧭 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", |
221 | 215 | "\n", |
222 | 216 | "\n", |
223 | 217 | "\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", |
225 | 220 | "\n", |
226 | 221 | "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", |
230 | 223 | "\n", |
231 | 224 | "This substation will act as a new injection point for rerouting load.\n" |
232 | 225 | ] |
|
253 | 246 | "id": "8f2b17e3", |
254 | 247 | "metadata": {}, |
255 | 248 | "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", |
258 | 251 | "\n", |
259 | 252 | "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." |
265 | 256 | ] |
266 | 257 | }, |
267 | 258 | { |
|
275 | 266 | "# 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", |
276 | 267 | "\n", |
277 | 268 | "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", |
279 | 270 | "\n", |
280 | 271 | "# %load solutions/advanced_5_1_get_all_congested_routes.py" |
281 | 272 | ] |
|
310 | 301 | "id": "a75e9b73", |
311 | 302 | "metadata": {}, |
312 | 303 | "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." |
314 | 307 | ] |
315 | 308 | }, |
316 | 309 | { |
|
334 | 327 | "id": "4a9ef582", |
335 | 328 | "metadata": {}, |
336 | 329 | "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", |
339 | 332 | "\n", |
340 | 333 | "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", |
343 | 337 | "- Confirm the overload is resolved\n", |
344 | 338 | "\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", |
346 | 340 | "\n" |
347 | 341 | ] |
348 | 342 | }, |
|
354 | 348 | "outputs": [], |
355 | 349 | "source": [ |
356 | 350 | "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", |
358 | 352 | " This way, the new substation will take over more nodes of the original route.\n", |
359 | 353 | " \"\"\"\n", |
360 | 354 | " # Get the path from the connection point to the old substation\n", |
|
456 | 450 | "# ✅ Wrap-Up\n", |
457 | 451 | "You’ve just:\n", |
458 | 452 | "\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", |
462 | 456 | "\n", |
463 | 457 | "We hope you enjoyed working with Power Grid Model DS and would love to hear your feedback" |
464 | 458 | ] |
465 | 459 | } |
466 | 460 | ], |
467 | 461 | "metadata": { |
468 | 462 | "kernelspec": { |
469 | | - "display_name": ".venv", |
| 463 | + "display_name": "power-grid-model-workshop", |
470 | 464 | "language": "python", |
471 | 465 | "name": "python3" |
472 | 466 | }, |
|
480 | 474 | "name": "python", |
481 | 475 | "nbconvert_exporter": "python", |
482 | 476 | "pygments_lexer": "ipython3", |
483 | | - "version": "3.12.6" |
| 477 | + "version": "undefined.undefined.undefined" |
484 | 478 | } |
485 | 479 | }, |
486 | 480 | "nbformat": 4, |
|
0 commit comments