Skip to content

Commit c498ab0

Browse files
committed
add asym line to assymetric calculations examples
Signed-off-by: leovsch <leo.25.1996@gmail.com>
1 parent 345ae21 commit c498ab0

File tree

6 files changed

+363
-7
lines changed

6 files changed

+363
-7
lines changed

docs/examples/Asymmetric Line.ipynb

+337
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
{
2+
"cells": [
3+
{
4+
"attachments": {},
5+
"cell_type": "markdown",
6+
"id": "89cf2628",
7+
"metadata": {},
8+
"source": [
9+
"# Asym Line Example\n",
10+
"\n",
11+
"In this notebook we will present examples of asymmetric lines in `power-grid-model`. \n",
12+
"\n",
13+
"Different input formats are covered. We will do one-time power flow calculation and one-time state estimation.\n",
14+
"\n",
15+
"This notebook serves as an example of how to use the Python API. For detailed API documentation, refer to\n",
16+
"[Python API reference](../api_reference/python-api-reference.md)\n",
17+
"and [Native Data Interface](../advanced_documentation/native-data-interface.md).\n",
18+
"\n",
19+
"## Asym Line\n",
20+
"\n",
21+
"Asym Line is described as a pi model in `power-grid-model`, and it belongs to the `branch` component type which connects two nodes with possibly different voltage levels.\n",
22+
"\n",
23+
"### Example Network\n",
24+
"\n",
25+
"We use a simple network with 3 nodes, 1 source, 1 load and 2 asym lines. As shown below:\n",
26+
"\n",
27+
"```txt\n",
28+
" source_1 --- node_2 --- asym_line_3 --- node_4 --- asym_line_5 --- node_6 --- load_7\n",
29+
"```"
30+
]
31+
},
32+
{
33+
"cell_type": "code",
34+
"execution_count": 1,
35+
"id": "ae11dc9a",
36+
"metadata": {},
37+
"outputs": [],
38+
"source": [
39+
"# some basic imports\n",
40+
"import numpy as np\n",
41+
"import pandas as pd\n",
42+
"\n",
43+
"from power_grid_model import LoadGenType, DatasetType, ComponentType\n",
44+
"from power_grid_model import PowerGridModel, CalculationMethod, CalculationType, MeasuredTerminalType\n",
45+
"from power_grid_model import initialize_array"
46+
]
47+
},
48+
{
49+
"attachments": {},
50+
"cell_type": "markdown",
51+
"id": "f983cef7",
52+
"metadata": {},
53+
"source": [
54+
"### Input Dataset\n",
55+
"\n",
56+
"We create an input dataset by using the helper function `initialize_array`. \n",
57+
"\n",
58+
"Please refer to [Components](../user_manual/components.md) for detailed explanation of all component types and their input/output attributes."
59+
]
60+
},
61+
{
62+
"cell_type": "code",
63+
"execution_count": 2,
64+
"id": "6f008736",
65+
"metadata": {},
66+
"outputs": [],
67+
"source": [
68+
"# node\n",
69+
"node = initialize_array(DatasetType.input, ComponentType.node, 3)\n",
70+
"node[\"id\"] = np.array([2, 4, 6])\n",
71+
"node[\"u_rated\"] = [1e3, 1e3, 1e3]\n",
72+
"\n",
73+
"# load\n",
74+
"asym_load = initialize_array(DatasetType.input, ComponentType.asym_load, 1)\n",
75+
"asym_load[\"id\"] = [7]\n",
76+
"asym_load[\"node\"] = [6]\n",
77+
"asym_load[\"status\"] = [1]\n",
78+
"asym_load[\"type\"] = [LoadGenType.const_power]\n",
79+
"asym_load[\"p_specified\"] = [[1000.0, 2000.0, 3000.0]]\n",
80+
"asym_load[\"q_specified\"] = [[1000.0, 2000.0, 3000.0]]\n",
81+
"\n",
82+
"# source\n",
83+
"source = initialize_array(DatasetType.input, ComponentType.source, 1)\n",
84+
"source[\"id\"] = [1]\n",
85+
"source[\"node\"] = [2]\n",
86+
"source[\"status\"] = [1]\n",
87+
"source[\"u_ref\"] = [1.0]\n",
88+
"\n",
89+
"# asym_line\n",
90+
"asym_line = initialize_array(DatasetType.input, ComponentType.asym_line, 2)\n",
91+
"asym_line[\"id\"] = [3, 5]\n",
92+
"asym_line[\"from_node\"] = [2, 4]\n",
93+
"asym_line[\"to_node\"] = [4, 6]\n",
94+
"asym_line[\"from_status\"] = [1, 1]\n",
95+
"asym_line[\"to_status\"] = [1, 1]\n",
96+
"asym_line[\"r_aa\"] = [0.6904, 0.6904]\n",
97+
"asym_line[\"r_ba\"] = [0.0495, 0.0495]\n",
98+
"asym_line[\"r_bb\"] = [0.6904, 0.6904]\n",
99+
"asym_line[\"r_ca\"] = [0.0492, 0.0492]\n",
100+
"asym_line[\"r_cb\"] = [0.0495, 0.0495]\n",
101+
"asym_line[\"r_cc\"] = [0.6904, 0.6904]\n",
102+
"asym_line[\"r_na\"] = [0.0495, np.nan]\n",
103+
"asym_line[\"r_nb\"] = [0.0492, np.nan]\n",
104+
"asym_line[\"r_nc\"] = [0.0495, np.nan]\n",
105+
"asym_line[\"r_nn\"] = [0.6904, np.nan]\n",
106+
"asym_line[\"x_aa\"] = [0.8316, 0.8316]\n",
107+
"asym_line[\"x_ba\"] = [0.7559, 0.7559]\n",
108+
"asym_line[\"x_bb\"] = [0.8316, 0.8316]\n",
109+
"asym_line[\"x_ca\"] = [0.7339, 0.7339]\n",
110+
"asym_line[\"x_cb\"] = [0.7559, 0.7559]\n",
111+
"asym_line[\"x_cc\"] = [0.8316, 0.8316]\n",
112+
"asym_line[\"x_na\"] = [0.7559, np.nan]\n",
113+
"asym_line[\"x_nb\"] = [0.7339, np.nan]\n",
114+
"asym_line[\"x_nc\"] = [0.7559, np.nan]\n",
115+
"asym_line[\"x_nn\"] = [0.8316, np.nan]\n",
116+
"asym_line[\"c0\"] = [0.32e-9, np.nan]\n",
117+
"asym_line[\"c1\"] = [0.54e-9, np.nan]\n",
118+
"asym_line[\"c_aa\"] = [np.nan, 0.3200e-09]\n",
119+
"asym_line[\"c_ba\"] = [np.nan, 0.5400e-09]\n",
120+
"asym_line[\"c_bb\"] = [np.nan, 0.3200e-09]\n",
121+
"asym_line[\"c_ca\"] = [np.nan, 0.7600e-09]\n",
122+
"asym_line[\"c_cb\"] = [np.nan, 0.5400e-09]\n",
123+
"asym_line[\"c_cc\"] = [np.nan, 0.3200e-09]\n",
124+
"asym_line[\"i_n\"] = [1000, 1000]\n",
125+
"\n",
126+
"# all\n",
127+
"input_data = {\n",
128+
" ComponentType.node: node,\n",
129+
" ComponentType.asym_line: asym_line,\n",
130+
" ComponentType.asym_load: asym_load,\n",
131+
" ComponentType.source: source,\n",
132+
"}"
133+
]
134+
},
135+
{
136+
"cell_type": "markdown",
137+
"id": "d16f9dea",
138+
"metadata": {},
139+
"source": [
140+
"**We can print the input dataset by converting the numpy array to dataframe.**"
141+
]
142+
},
143+
{
144+
"cell_type": "code",
145+
"execution_count": 3,
146+
"id": "37749c7c",
147+
"metadata": {},
148+
"outputs": [
149+
{
150+
"name": "stdout",
151+
"output_type": "stream",
152+
"text": [
153+
" id from_node to_node from_status to_status r_aa r_ba r_bb \\\n",
154+
"0 3 2 4 1 1 0.6904 0.0495 0.6904 \n",
155+
"1 5 4 6 1 1 0.6904 0.0495 0.6904 \n",
156+
"\n",
157+
" r_ca r_cb ... x_nn c_aa c_ba c_bb \\\n",
158+
"0 0.0492 0.0495 ... 0.8316 NaN NaN NaN \n",
159+
"1 0.0492 0.0495 ... NaN 3.200000e-10 5.400000e-10 3.200000e-10 \n",
160+
"\n",
161+
" c_ca c_cb c_cc c0 c1 \\\n",
162+
"0 NaN NaN NaN 3.200000e-10 5.400000e-10 \n",
163+
"1 7.600000e-10 5.400000e-10 3.200000e-10 NaN NaN \n",
164+
"\n",
165+
" i_n \n",
166+
"0 1000.0 \n",
167+
"1 1000.0 \n",
168+
"\n",
169+
"[2 rows x 34 columns]\n"
170+
]
171+
}
172+
],
173+
"source": [
174+
"print(pd.DataFrame(input_data[ComponentType.asym_line]))"
175+
]
176+
},
177+
{
178+
"cell_type": "markdown",
179+
"id": "47a9c257",
180+
"metadata": {},
181+
"source": [
182+
"### One-time Power Flow Calculation\n",
183+
"\n",
184+
"You can call the method `calculate_power_flow` to do a one-time calculation based on the current network data in the model.\n",
185+
"\n",
186+
"For detailed explanation of the arguments, batch calculations and asymmetric calculations, we refer to the [Power Flow Example](./Power%20Flow%20Example.ipynb) and [Asymmetric Calculation Example](./Asymmetric%20Calculation%20Example.ipynb). "
187+
]
188+
},
189+
{
190+
"cell_type": "code",
191+
"execution_count": 4,
192+
"id": "7bb0f998",
193+
"metadata": {},
194+
"outputs": [
195+
{
196+
"name": "stdout",
197+
"output_type": "stream",
198+
"text": [
199+
"------node voltage result------\n",
200+
" 0 1 2\n",
201+
"0 577.350081 577.349890 577.349692\n",
202+
"1 577.543188 574.815533 571.914289\n",
203+
"2 579.346994 570.159376 567.087326\n",
204+
"------node angle result------\n",
205+
" 0 1 2\n",
206+
"0 -2.686835e-07 -2.094396 2.094394\n",
207+
"1 4.811479e-05 -2.087729 2.097964\n",
208+
"2 2.919948e-03 -2.079969 2.097696\n"
209+
]
210+
}
211+
],
212+
"source": [
213+
"# validation (optional)\n",
214+
"from power_grid_model.validation import assert_valid_input_data\n",
215+
"\n",
216+
"assert_valid_input_data(input_data=input_data, calculation_type=CalculationType.power_flow)\n",
217+
"\n",
218+
"# construction\n",
219+
"model = PowerGridModel(input_data)\n",
220+
"\n",
221+
"# one-time power flow calculation\n",
222+
"output_data = model.calculate_power_flow(\n",
223+
" symmetric=False, error_tolerance=1e-8, max_iterations=20, calculation_method=CalculationMethod.newton_raphson\n",
224+
")\n",
225+
"\n",
226+
"# result dataset\n",
227+
"print(\"------node voltage result------\")\n",
228+
"print(pd.DataFrame(output_data[ComponentType.node][\"u\"]))\n",
229+
"print(\"------node angle result------\")\n",
230+
"print(pd.DataFrame(output_data[ComponentType.node][\"u_angle\"]))"
231+
]
232+
},
233+
{
234+
"attachments": {},
235+
"cell_type": "markdown",
236+
"id": "682c1c48",
237+
"metadata": {},
238+
"source": [
239+
"### One-time State Estimation\n",
240+
"Below we present a simple example of state estimation for a network with two asym lines. \n",
241+
"\n",
242+
"NOTE: In `power-grid-model`, asym lines belong to `branch` component type, therefore the `measured_terminal_type` of power sensors should be assigned to `MeasuredTerminalType.branch_from/_to`.\n",
243+
"\n",
244+
"For detailed explanation of the arguments, batch calculations and asymmetric calculations, we refer to the [State Estimation Example](./State%20Estimation%20Example.ipynb) and [Asymmetric Calculation Example](./Asymmetric%20Calculation%20Example.ipynb)."
245+
]
246+
},
247+
{
248+
"cell_type": "code",
249+
"execution_count": 5,
250+
"id": "f0c8c3e8",
251+
"metadata": {},
252+
"outputs": [
253+
{
254+
"name": "stdout",
255+
"output_type": "stream",
256+
"text": [
257+
"------node result------\n",
258+
" 0 1 2\n",
259+
"0 1000.000001 999.999991 1000.000007\n",
260+
"1 1000.000019 999.999988 999.999997\n",
261+
"2 1000.000001 999.999999 999.999999\n"
262+
]
263+
}
264+
],
265+
"source": [
266+
"# voltage sensor\n",
267+
"asym_voltage_sensor = initialize_array(DatasetType.input, ComponentType.asym_voltage_sensor, 1)\n",
268+
"asym_voltage_sensor[\"id\"] = [8]\n",
269+
"asym_voltage_sensor[\"measured_object\"] = [6]\n",
270+
"asym_voltage_sensor[\"u_sigma\"] = [1.0]\n",
271+
"asym_voltage_sensor[\"u_measured\"] = [[1000, 1000, 1000]]\n",
272+
"\n",
273+
"# power sensor\n",
274+
"asym_power_sensor = initialize_array(DatasetType.input, ComponentType.asym_power_sensor, 4)\n",
275+
"asym_power_sensor[\"id\"] = [9, 10, 11, 12]\n",
276+
"asym_power_sensor[\"measured_object\"] = [3, 3, 5, 5]\n",
277+
"asym_power_sensor[\"measured_terminal_type\"] = [\n",
278+
" MeasuredTerminalType.branch_from,\n",
279+
" MeasuredTerminalType.branch_to,\n",
280+
" MeasuredTerminalType.branch_from,\n",
281+
" MeasuredTerminalType.branch_to,\n",
282+
"]\n",
283+
"asym_power_sensor[\"power_sigma\"] = [500.0, 500.0, 500.0, 500.0]\n",
284+
"asym_power_sensor[\"p_measured\"] = [[1000, 2000, 3000], [1000, 2000, 3000], [1000, 2000, 3000], [1000, 2000, 3000]]\n",
285+
"asym_power_sensor[\"q_measured\"] = [[1000, 2000, 3000], [1000, 2000, 3000], [1000, 2000, 3000], [1000, 2000, 3000]]\n",
286+
"\n",
287+
"# use components from former input dataset cell.\n",
288+
"input_data2 = {\n",
289+
" ComponentType.node: node,\n",
290+
" ComponentType.asym_line: asym_line,\n",
291+
" ComponentType.asym_load: asym_load,\n",
292+
" ComponentType.source: source,\n",
293+
" ComponentType.asym_voltage_sensor: asym_voltage_sensor,\n",
294+
" ComponentType.asym_power_sensor: asym_power_sensor,\n",
295+
"}\n",
296+
"\n",
297+
"# validation (optional)\n",
298+
"from power_grid_model.validation import assert_valid_input_data\n",
299+
"\n",
300+
"assert_valid_input_data(input_data=input_data2, calculation_type=CalculationType.state_estimation)\n",
301+
"\n",
302+
"# construction\n",
303+
"model2 = PowerGridModel(input_data2)\n",
304+
"\n",
305+
"# one-time state estimation\n",
306+
"output_data2 = model2.calculate_state_estimation(\n",
307+
" symmetric=False, error_tolerance=1e-8, max_iterations=20, calculation_method=CalculationMethod.iterative_linear\n",
308+
")\n",
309+
"\n",
310+
"# result dataset\n",
311+
"print(\"------node result------\")\n",
312+
"print(pd.DataFrame(output_data2[ComponentType.node][\"u\"]))"
313+
]
314+
}
315+
],
316+
"metadata": {
317+
"kernelspec": {
318+
"display_name": "venv",
319+
"language": "python",
320+
"name": "python3"
321+
},
322+
"language_info": {
323+
"codemirror_mode": {
324+
"name": "ipython",
325+
"version": 3
326+
},
327+
"file_extension": ".py",
328+
"mimetype": "text/x-python",
329+
"name": "python",
330+
"nbconvert_exporter": "python",
331+
"pygments_lexer": "ipython3",
332+
"version": "3.12.0"
333+
}
334+
},
335+
"nbformat": 4,
336+
"nbformat_minor": 5
337+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
2+
3+
SPDX-License-Identifier: MPL-2.0

docs/index.md

+1
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ examples/Make Test Dataset.ipynb
9494
examples/Asymmetric Calculation Example.ipynb
9595
examples/Transformer Examples.ipynb
9696
examples/Generic Branch Example.ipynb
97+
examples/Asymmetric Line.ipynb
9798
```
9899

99100
```{toctree}

src/power_grid_model/validation/_validation.py

+16-3
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,9 @@ def assert_valid_data_structure(data: Dataset, data_type: DatasetType) -> None:
199199
f"Unexpected Numpy array ({array.dtype}) for '{component}' {data_type}_data "
200200
"(should be a Numpy structured array)."
201201
)
202-
raise TypeError(f"Unexpected Numpy structured array; (expected = {dtype}, actual = {array.dtype}).")
202+
raise TypeError(
203+
f"Unexpected Numpy structured array; (expected = {dtype}, actual = {array.dtype}). For component '{component}'."
204+
)
203205
else:
204206
raise TypeError(
205207
f"Unexpected data type {type(array).__name__} for '{component}' {data_type}_data "
@@ -875,6 +877,7 @@ def validate_generic_power_sensor(data: SingleDataset, component: ComponentType)
875877
ref_components=[
876878
ComponentType.node,
877879
ComponentType.line,
880+
ComponentType.asym_line,
878881
ComponentType.generic_branch,
879882
ComponentType.transformer,
880883
ComponentType.three_winding_transformer,
@@ -890,14 +893,24 @@ def validate_generic_power_sensor(data: SingleDataset, component: ComponentType)
890893
data,
891894
component,
892895
field="measured_object",
893-
ref_components=[ComponentType.line, ComponentType.generic_branch, ComponentType.transformer],
896+
ref_components=[
897+
ComponentType.line,
898+
ComponentType.asym_line,
899+
ComponentType.generic_branch,
900+
ComponentType.transformer,
901+
],
894902
measured_terminal_type=MeasuredTerminalType.branch_from,
895903
)
896904
errors += _all_valid_ids(
897905
data,
898906
component,
899907
field="measured_object",
900-
ref_components=[ComponentType.line, ComponentType.generic_branch, ComponentType.transformer],
908+
ref_components=[
909+
ComponentType.line,
910+
ComponentType.asym_line,
911+
ComponentType.generic_branch,
912+
ComponentType.transformer,
913+
],
901914
measured_terminal_type=MeasuredTerminalType.branch_to,
902915
)
903916
errors += _all_valid_ids(

0 commit comments

Comments
 (0)