Transformer Example
In this notebook we will present examples of transformers in power-grid-model
.
Both two-winding transformer and three-winding transformer are covered. We will do one-time power flow calculation and one-time state estimation for both types of tranformers.
This notebook serves as an example of how to use the Python API. For detailed API documentation, refer to Python API reference and Native Data Interface.
Transformer (Two-winding Transformer)
Transformer 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.
Example Network
We use a simple network with 2 nodes, 1 source, 1 load and 1 transformer. As shown below:
source_1 --- node_2 --- transformer_3 --- node_4 --- load_5
# some basic imports
import numpy as np
import warnings
with warnings.catch_warnings(action="ignore", category=DeprecationWarning):
# suppress warning about pyarrow as future required dependency
import pandas as pd
from power_grid_model import LoadGenType
from power_grid_model import PowerGridModel, CalculationMethod, CalculationType, MeasuredTerminalType
from power_grid_model import initialize_array
Input Dataset
We create an input dataset by using the helper function initialize_array
.
Please refer to Components for detailed explanation of all component types and their input/output attributes.
# node
node = initialize_array("input", "node", 2)
node["id"] = np.array([2, 4])
node["u_rated"] = [1e4, 4e2]
# load
sym_load = initialize_array("input", "sym_load", 1)
sym_load["id"] = [5]
sym_load["node"] = [4]
sym_load["status"] = [1]
sym_load["type"] = [LoadGenType.const_power]
sym_load["p_specified"] = [1e3]
sym_load["q_specified"] = [5e3]
# source
source = initialize_array("input", "source", 1)
source["id"] = [1]
source["node"] = [2]
source["status"] = [1]
source["u_ref"] = [1.0]
# transformer
transformer = initialize_array("input", "transformer", 1)
transformer["id"] = [3]
transformer["from_node"] = [2]
transformer["to_node"] = [4]
transformer["from_status"] = [1]
transformer["to_status"] = [1]
transformer["u1"] = [1e4]
transformer["u2"] = [4e2]
transformer["sn"] = [1e5]
transformer["uk"] = [0.1]
transformer["pk"] = [1e3]
transformer["i0"] = [1.0e-6]
transformer["p0"] = [0.1]
transformer["winding_from"] = [2]
transformer["winding_to"] = [1]
transformer["clock"] = [5]
transformer["tap_side"] = [0]
transformer["tap_pos"] = [3]
transformer["tap_min"] = [-11]
transformer["tap_max"] = [9]
transformer["tap_size"] = [100]
# all
input_data = {
"node": node,
"transformer": transformer,
"sym_load": sym_load,
"source": source
}
We can print the input dataset by converting the numpy array to dataframe.
print(pd.DataFrame(input_data["transformer"]))
id from_node to_node from_status to_status u1 u2 sn \
0 3 2 4 1 1 10000.0 400.0 100000.0
uk pk ... tap_nom tap_size uk_min uk_max pk_min pk_max \
0 0.1 1000.0 ... -128 100.0 NaN NaN NaN NaN
r_grounding_from x_grounding_from r_grounding_to x_grounding_to
0 NaN NaN NaN NaN
[1 rows x 29 columns]
One-time Power Flow Calculation
You can call the method calculate_power_flow
to do a one-time calculation based on the current network data in the model.
For detailed explanation of the arguments, batch calculations and asymmetric calculations, we refer to the Power Flow Example and Asymmetric Calculation Example.
# validation (optional)
from power_grid_model.validation import assert_valid_input_data
assert_valid_input_data(input_data=input_data, calculation_type=CalculationType.power_flow)
# construction
model = PowerGridModel(input_data)
# one-time power flow calculation
output_data = model.calculate_power_flow(
symmetric=True,
error_tolerance=1e-8,
max_iterations=20,
calculation_method=CalculationMethod.newton_raphson
)
# result dataset
print("------node result------")
print(pd.DataFrame(output_data["node"]))
------node result------
id energized u_pu u u_angle p \
0 2 1 0.999999 9999.994897 -4.976260e-08 1002.882212
1 4 1 0.965618 386.247005 -2.618522e+00 -1000.000000
q
0 5027.744841
1 -5000.000000
One-time State Estimation
Below we present a simple example of state estimation for a network with a two-winding transformer.
NOTE: In power-grid-model
, two-winding transformers belong to branch
component type, therefore the measured_terminal_type
of power sensors should be assigned to MeasuredTerminalType.branch_from/_to
.
For detailed explanation of the arguments, batch calculations and asymmetric calculations, we refer to the State Estimation Example and Asymmetric Calculation Example.
# voltage sensor
sym_voltage_sensor = initialize_array("input", "sym_voltage_sensor", 2)
sym_voltage_sensor["id"] = [6, 7]
sym_voltage_sensor["measured_object"] = [2, 4]
sym_voltage_sensor["u_sigma"] = [1.0, 1.0]
sym_voltage_sensor["u_measured"] = [1e5, 4e2]
# power sensor
sym_power_sensor = initialize_array("input", "sym_power_sensor", 2)
sym_power_sensor["id"] = [8, 9]
sym_power_sensor["measured_object"] = [3, 3]
sym_power_sensor["measured_terminal_type"] = [
MeasuredTerminalType.branch_from,
MeasuredTerminalType.branch_to,
]
sym_power_sensor["power_sigma"] = [1.0, 1.0]
sym_power_sensor["p_measured"] = [2e6, 1e5]
sym_power_sensor["q_measured"] = [2e7, 1e6]
# use components from former input dataset cell.
input_data2 = {
"node": node,
"transformer": transformer,
"sym_load": sym_load,
"source": source,
"sym_voltage_sensor": sym_voltage_sensor,
"sym_power_sensor": sym_power_sensor,
}
# validation (optional)
from power_grid_model.validation import assert_valid_input_data
assert_valid_input_data(input_data=input_data2, calculation_type=CalculationType.state_estimation)
# construction
model2 = PowerGridModel(input_data2)
# one-time state estimation
output_data2 = model2.calculate_state_estimation(
symmetric=True,
error_tolerance=1e-8,
max_iterations=20,
calculation_method=CalculationMethod.iterative_linear
)
# result dataset
print("------node result------")
print(pd.DataFrame(output_data2["node"]))
------node result------
id energized u_pu u u_angle p \
0 2 1 9.987392 99873.919714 0.000000 470658.914282
1 4 1 9.209290 3683.716125 -2.617974 -446912.927660
q
0 4.700696e+06
1 -4.464515e+06
Three-Winding Transformer
Three-winding transformer is described as 3 transformers of pi model each connected together in star configuration, and it belongs to the branch3
component type which connects three nodes with possibly different voltage levels.
Example Network
We use a simple network with 3 nodes, 1 source, 1 load and 1 three-winding transformer. As shown below:
source_1 --- node_2 --- three_winding_transformer_3 --- node_4 --- load_5
|
-------------------node_6 --- load_7
Input Dataset
We use the helper function initialize_array
to create an input dataset.
Please refer to Components for detailed explanation of all component types and their input/output attributes.
# node
node = initialize_array("input", "node", 3)
node["id"] = np.array([2, 4, 6])
node["u_rated"] = [1e4, 1e2, 1e2]
# load
sym_load = initialize_array("input", "sym_load", 2)
sym_load["id"] = [5, 7]
sym_load["node"] = [4, 6]
sym_load["status"] = [1]
sym_load["type"] = [LoadGenType.const_power]
sym_load["p_specified"] = [1e3, 1e3]
sym_load["q_specified"] = [5e3, 5e3]
# source
source = initialize_array("input", "source", 1)
source["id"] = [1]
source["node"] = [2]
source["status"] = [1]
source["u_ref"] = [1.0]
# three-winding transformer
three_winding_transformer = initialize_array("input", "three_winding_transformer", 1)
three_winding_transformer["id"] = [3]
three_winding_transformer["node_1"] = [2]
three_winding_transformer["node_2"] = [4]
three_winding_transformer["node_3"] = [6]
three_winding_transformer["status_1"] = [1]
three_winding_transformer["status_2"] = [1]
three_winding_transformer["status_3"] = [1]
three_winding_transformer["u1"] = [1e4]
three_winding_transformer["u2"] = [1e2]
three_winding_transformer["u3"] = [1e2]
three_winding_transformer["sn_1"] = [1e5]
three_winding_transformer["sn_2"] = [1e5]
three_winding_transformer["sn_3"] = [1e5]
three_winding_transformer["uk_12"] = [0.09]
three_winding_transformer["uk_13"] = [0.06]
three_winding_transformer["uk_23"] = [0.06]
three_winding_transformer["pk_12"] = [1e3]
three_winding_transformer["pk_13"] = [1e3]
three_winding_transformer["pk_23"] = [1e3]
three_winding_transformer["i0"] = [0]
three_winding_transformer["p0"] = [0]
three_winding_transformer["winding_1"] = [2]
three_winding_transformer["winding_2"] = [1]
three_winding_transformer["winding_3"] = [1]
three_winding_transformer["clock_12"] = [5]
three_winding_transformer["clock_13"] = [5]
three_winding_transformer["tap_side"] = [0]
three_winding_transformer["tap_pos"] = [0]
three_winding_transformer["tap_min"] = [-10]
three_winding_transformer["tap_max"] = [10]
three_winding_transformer["tap_nom"] = [0]
three_winding_transformer["tap_size"] = [1380]
# all
input_data3 = {
"node": node,
"three_winding_transformer": three_winding_transformer,
"sym_load": sym_load,
"source": source
}
One-time power flow calculation
# validation (optional)
from power_grid_model.validation import assert_valid_input_data
assert_valid_input_data(input_data=input_data3, calculation_type=CalculationType.power_flow)
# construction
model3 = PowerGridModel(input_data3)
# one-time power flow calculation
output_data3 = model3.calculate_power_flow(
symmetric=True,
error_tolerance=1e-8,
max_iterations=20,
calculation_method=CalculationMethod.newton_raphson)
# result dataset
print("------node result------")
print(pd.DataFrame(output_data3["node"]))
------node result------
id energized u_pu u u_angle p \
0 2 1 0.999999 9999.989788 -9.966674e-08 2007.896574
1 4 1 0.993097 99.309655 -2.618590e+00 -1000.000000
2 6 1 0.994637 99.463733 -2.618281e+00 -1000.000000
q
0 10062.592544
1 -5000.000000
2 -5000.000000
One-time State Estimation
Below we present a simple example of state estimation for a network with a three-winding transformer.
NOTE: In power-grid-model
, three-winding transformers belong to branch3
component type, therefore the measured_terminal_type
of power sensors should be assigned to MeasuredTerminalType.branch3_1/_2/_3
.
For detailed explanation of the arguments, batch calculations and asymmetric calculations, we refer to the State Estimation Example and Asymmetric Calculation Example.
# voltage sensor
sym_voltage_sensor = initialize_array("input", "sym_voltage_sensor", 3)
sym_voltage_sensor["id"] = [8, 9, 10]
sym_voltage_sensor["measured_object"] = [2, 4, 6]
sym_voltage_sensor["u_sigma"] = [1.0, 1.0, 1.0]
sym_voltage_sensor["u_measured"] = [1e4, 1e2, 1e2]
# power sensor
sym_power_sensor = initialize_array("input", "sym_power_sensor", 3)
sym_power_sensor["id"] = [11, 12, 13]
sym_power_sensor["measured_object"] = [3, 3, 3]
sym_power_sensor["measured_terminal_type"] = [
MeasuredTerminalType.branch3_1,
MeasuredTerminalType.branch3_2,
MeasuredTerminalType.branch3_3,
]
sym_power_sensor["power_sigma"] = [1.0, 1.0, 1.0]
sym_power_sensor["p_measured"] = [2e3, 1e3, 1e3]
sym_power_sensor["q_measured"] = [1e4, 5e3, 5e3]
# use components from the one-time power flow calculation with three-winding transformer
input_data4 = {
"node": node,
"three_winding_transformer": three_winding_transformer,
"sym_load": sym_load,
"source": source,
"sym_voltage_sensor": sym_voltage_sensor,
"sym_power_sensor": sym_power_sensor,
}
# validation (optional)
from power_grid_model.validation import assert_valid_input_data
assert_valid_input_data(input_data=input_data4, calculation_type=CalculationType.state_estimation)
# construction
model4 = PowerGridModel(input_data4)
# one-time state estimation
output_data4 = model4.calculate_state_estimation(
symmetric=True,
error_tolerance=1e-8,
max_iterations=20,
calculation_method=CalculationMethod.iterative_linear
)
# result dataset
print("------three-winding transformer result------")
print(pd.DataFrame(output_data4["three_winding_transformer"]))
------three-winding transformer result------
id energized loading p_1 q_1 i_1 s_1 \
0 3 1 0.033993 667.156598 3333.23678 0.196261 3399.347785
p_2 q_2 i_2 s_2 p_3 q_3 \
0 -333.400686 -1662.691395 9.813068 1695.788516 -332.889246 -1663.677083
i_3 s_3
0 9.813068 1696.654557