|
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", |
|
119 | 117 | "# 🏗️ Step 2: Load and Prepare the Grid\n", |
120 | 118 | "Goal: Load a synthetic medium-voltage grid from the provided data.\n", |
121 | 119 | "\n", |
122 | | - "You'll use pandas to load the data from included CSV files and then:\n", |
| 120 | + "We use pandas to load the data from included CSV files and then:\n", |
123 | 121 | "- Create an empty Grid object using your custom MyGrid class\n", |
124 | 122 | "- Create and fill NodeArray, LineArray and LoadArray objects with data from the CSV files and append them to your Grid\n", |
125 | 123 | "- Using a SourceArray, add a voltage source to each substation in the Grid\n", |
126 | | - "- You’ll then compute a power flow on the synthetic grid to get realistic line currents" |
| 124 | + "- You’ll then compute a power flow on the synthetic grid to get realistic line currents\n", |
| 125 | + "\n", |
| 126 | + "(Code is already given in helper.py file, please take a look to see how the grid data is loaded!)" |
127 | 127 | ] |
128 | 128 | }, |
129 | 129 | { |
|
152 | 152 | "metadata": {}, |
153 | 153 | "source": [ |
154 | 154 | "# 🧯 Step 3: Detect the Overload\n", |
155 | | - "Goal: Identify which line(s) are exceeding their rated current.\n", |
| 155 | + "Goal: Identify which line(s) are exceeding their rated current (the `i_n` property).\n", |
156 | 156 | "\n", |
157 | | - "You’ll:\n", |
| 157 | + "You can do this step by step (don't forget to check the PGM-DS documentation):\n", |
158 | 158 | "\n", |
159 | | - "- Use the .is_overloaded property to find the problem\n", |
160 | | - "- Isolate the feeder route to the affected line\n", |
161 | | - "\n", |
162 | | - "This gives a clear target for where you need to intervene." |
| 159 | + "1. Use the PowerGridModelInterface to calculate power flow\n", |
| 160 | + "2. Update the Grid object with the calculated values\n", |
| 161 | + "3. Return the lines (LineArray) that are overloaded" |
163 | 162 | ] |
164 | 163 | }, |
165 | 164 | { |
|
177 | 176 | } |
178 | 177 | ], |
179 | 178 | "source": [ |
180 | | - "# Check the grid for capacity issues\n", |
181 | | - "# 1. Use the PowerGridModelInterface to calculate power flow\n", |
182 | | - "# 2. Update the grid with the calculated values\n", |
183 | | - "# 3. Return the lines (LineArray) that are overloaded\n", |
184 | | - "\n", |
185 | 179 | "# Hint: You can use the `is_overloaded` property of the `MyLineArray` class to check for overloaded lines.\n", |
186 | 180 | "# Hint: https://power-grid-model-ds.readthedocs.io/en/stable/quick_start.html#performing-power-flow-calculations\n", |
187 | 181 | "\n", |
|
211 | 205 | "metadata": {}, |
212 | 206 | "source": [ |
213 | 207 | "# 🧭 Step 4: Plan a Relief Strategy\n", |
| 208 | + "\n", |
| 209 | + "If you visualize the grid and highlight the overloaded cables, this is what you will see:\n", |
| 210 | + "\n", |
214 | 211 | "\n", |
215 | 212 | "\n", |
216 | | - "Goal: Place a second substation near the overloaded path.\n", |
| 213 | + "Goal: Place a second substation near the overloaded path. In the next steps we will use this substation to relieve overloaded cables.\n", |
217 | 214 | "\n", |
218 | 215 | "You’ll:\n", |
219 | | - "- Add a new substation at a specified location\n", |
220 | | - "- Connect it to the closest node in the network\n", |
221 | | - "- Visually inspect the grid with visualize()\n", |
| 216 | + "- Create a new substations using the NodeArrayobject at the correct location.\n", |
222 | 217 | "\n", |
223 | 218 | "This substation will act as a new injection point for rerouting load.\n" |
224 | 219 | ] |
|
245 | 240 | "id": "8f2b17e3", |
246 | 241 | "metadata": {}, |
247 | 242 | "source": [ |
248 | | - "# 🔗 Step 5: Trace and Analyze the Overloaded Route\n", |
249 | | - "Goal: Identify a switchable line along the route from the new node to the old substation.\n", |
| 243 | + "# 🔗 Step 5: Analyze and Connect the Overloaded Route\n", |
| 244 | + "Goal: Identify the best way to connect the new substation to the overloaded routes.\n", |
250 | 245 | "\n", |
251 | 246 | "You’ll:\n", |
252 | | - "- Use the graph interface to trace the shortest path from the new substation to the original\n", |
253 | | - "- Calculate cumulative load along the path\n", |
254 | | - "- Find a cut point where the remaining load toward the old substation is < 2 MW\n", |
255 | | - "\n", |
256 | | - "This ensures you relieve the feeder while maintaining supply continuity." |
| 247 | + "- Compute which routes (/feeders) are overloaded to see where we need to invervene.\n", |
| 248 | + "- Find which node on an overloaded route is geographically closed to the new substation.\n", |
| 249 | + "- Create a new cable to connect the closest node to the new substation." |
257 | 250 | ] |
258 | 251 | }, |
259 | 252 | { |
|
267 | 260 | "# 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", |
268 | 261 | "\n", |
269 | 262 | "def get_all_congested_routes(grid: Grid) -> list[NodeArray]:\n", |
270 | | - " \"\"\"Get all routes that originate from a given substation node.\"\"\"\n", |
| 263 | + " \"\"\"Get all nodes on routes that contain an overloaded line.\"\"\"\n", |
271 | 264 | "\n", |
272 | 265 | "# %load solutions/advanced_5_1_get_all_congested_routes.py" |
273 | 266 | ] |
|
302 | 295 | "id": "a75e9b73", |
303 | 296 | "metadata": {}, |
304 | 297 | "source": [ |
305 | | - "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." |
| 298 | + "Finally we build a function that creates a new line between the connection point and the new substation.\n", |
| 299 | + "\n", |
| 300 | + "❗ 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." |
306 | 301 | ] |
307 | 302 | }, |
308 | 303 | { |
|
326 | 321 | "id": "4a9ef582", |
327 | 322 | "metadata": {}, |
328 | 323 | "source": [ |
329 | | - "# ✂️ Step 6: Open the Right Line\n", |
330 | | - "Goal: Deactivate a line to offload the original feeder.\n", |
| 324 | + "# 🔌 Step 6: Open the Right Line\n", |
| 325 | + "Goal: Find the optimal line to open to relieve the original overloaded feeder.\n", |
331 | 326 | "\n", |
332 | 327 | "You’ll:\n", |
333 | | - "- Identify and deactivate the line between two nodes on the critical path\n", |
334 | | - "- Rerun power flow after the switch\n", |
| 328 | + "- Trace a path from the newly created cable to the old substation\n", |
| 329 | + "- Evaluate each line on the path by running `check_for_capacity_issues()` and find the optimal line to open\n", |
| 330 | + "- Open the correct line\n", |
335 | 331 | "- Confirm the overload is resolved\n", |
336 | 332 | "\n", |
337 | | - "This final step demonstrates how network topology and load can be managed dynamically with switching and distributed generation.\n", |
| 333 | + "This final step demonstrates how network topology can be programmatically optimized using the Power Grid Model Data Science toolkit!\n", |
338 | 334 | "\n" |
339 | 335 | ] |
340 | 336 | }, |
|
346 | 342 | "outputs": [], |
347 | 343 | "source": [ |
348 | 344 | "def optimize_route_transfer(grid: Grid, connection_point: NodeArray, new_substation: NodeArray) -> None:\n", |
349 | | - " \"\"\"Attempt to optimize the route transfer moving the naturally open point (NOP) upstream towards the old substation.\n", |
| 345 | + " \"\"\"Attempt to optimize the route transfer moving the normally open point (NOP) upstream towards the old substation.\n", |
350 | 346 | " This way, the new substation will take over more nodes of the original route.\n", |
351 | 347 | " \"\"\"\n", |
352 | 348 | " # Get the path from the connection point to the old substation\n", |
|
448 | 444 | "# ✅ Wrap-Up\n", |
449 | 445 | "You’ve just:\n", |
450 | 446 | "\n", |
451 | | - "Diagnosed a power system constraint\n", |
452 | | - "- Planned and executed a grid topology change\n", |
453 | | - "- Verified success with power flow simulations\n", |
| 447 | + "- Loaded a grid topology and grid loads from a file\n", |
| 448 | + "- Analyse grid components that are or will soon be overloaded using load flow analysis\n", |
| 449 | + "- Automatically optimize a solution to relieve (future) congestions on the energy grid\n", |
454 | 450 | "\n", |
455 | 451 | "We hope you enjoyed working with Power Grid Model DS and would love to hear your feedback" |
456 | 452 | ] |
457 | 453 | } |
458 | 454 | ], |
459 | 455 | "metadata": { |
460 | 456 | "kernelspec": { |
461 | | - "display_name": ".venv", |
| 457 | + "display_name": "power-grid-model-workshop", |
462 | 458 | "language": "python", |
463 | 459 | "name": "python3" |
464 | 460 | }, |
|
472 | 468 | "name": "python", |
473 | 469 | "nbconvert_exporter": "python", |
474 | 470 | "pygments_lexer": "ipython3", |
475 | | - "version": "3.12.6" |
| 471 | + "version": "undefined.undefined.undefined" |
476 | 472 | } |
477 | 473 | }, |
478 | 474 | "nbformat": 4, |
|
0 commit comments