-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinequality_errors.py
More file actions
129 lines (102 loc) · 4.85 KB
/
Copy pathinequality_errors.py
File metadata and controls
129 lines (102 loc) · 4.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
from typing import Dict
import torch
from torch_geometric.data import HeteroData
from torch_geometric.datasets import OPFDataset
from torch_geometric.loader import DataLoader
from torch_geometric.nn import GraphConv, to_hetero
from opf_dataset_utils.enumerations import EdgeTypes
from opf_dataset_utils.errors.inequality.branch_power import (
calculate_branch_power_errors_from,
calculate_branch_power_errors_to,
)
from opf_dataset_utils.errors.inequality.generator_power import (
calculate_lower_active_power_errors,
calculate_lower_reactive_power_errors,
calculate_upper_active_power_errors,
calculate_upper_reactive_power_errors,
)
from opf_dataset_utils.errors.inequality.voltage import (
calculate_lower_voltage_angle_difference_errors,
calculate_lower_voltage_magnitude_errors,
calculate_upper_voltage_angle_difference_errors,
calculate_upper_voltage_magnitude_errors,
)
class Model(torch.nn.Module):
def __init__(self):
super().__init__()
self.conv1 = GraphConv(-1, 16)
self.conv2 = GraphConv(16, 2)
def forward(self, x, edge_index):
x = self.conv1(x, edge_index).relu()
x = self.conv2(x, edge_index)
return x
def print_max_errors(data: HeteroData, predictions: Dict):
# voltage
spacing = (30, 25, 25)
print(
f"{'Upper Vm:':{spacing[0]}} {calculate_upper_voltage_magnitude_errors(data, predictions).abs().max().item():{spacing[1]}} {'[p.u.]':{spacing[2]}}"
)
print(
f"{'Lower Vm:':{spacing[0]}} {calculate_lower_voltage_magnitude_errors(data, predictions).abs().max().item():{spacing[1]}} {'[p.u.]':{spacing[2]}}"
)
print(
f"{'Upper Va diff. (transformers):':{spacing[0]}} {calculate_upper_voltage_angle_difference_errors(data, predictions, EdgeTypes.TRANSFORMER).abs().max().item():{spacing[1]}} {'[rad]':{spacing[2]}}"
)
print(
f"{'Upper Va diff. (AC lines):':{spacing[0]}} {calculate_upper_voltage_angle_difference_errors(data, predictions, EdgeTypes.AC_LINE).abs().max().item():{spacing[1]}} {'[rad]':{spacing[2]}}"
)
print(
f"{'Lower Va diff. (transformers):':{spacing[0]}} {calculate_lower_voltage_angle_difference_errors(data, predictions, EdgeTypes.TRANSFORMER).abs().max().item():{spacing[1]}} {'[rad]':{spacing[2]}}"
)
print(
f"{'Lower Va diff. (AC lines):':{spacing[0]}} {calculate_lower_voltage_angle_difference_errors(data, predictions, EdgeTypes.AC_LINE).abs().max().item():{spacing[1]}} {'[rad]':{spacing[2]}}"
)
# generator power
print(
f"{'Upper Pg:':{spacing[0]}} {calculate_upper_active_power_errors(data, predictions).abs().max().item():{spacing[1]}} {'[p.u.]':{spacing[2]}}"
)
print(
f"{'Lower Pg:':{spacing[0]}} {calculate_lower_active_power_errors(data, predictions).abs().max().item():{spacing[1]}} {'[p.u.]':{spacing[2]}}"
)
print(
f"{'Upper Qg:':{spacing[0]}} {calculate_upper_reactive_power_errors(data, predictions).abs().max().item():{spacing[1]}} {'[p.u.]':{spacing[2]}}"
)
print(
f"{'Lower Qg:':{spacing[0]}} {calculate_lower_reactive_power_errors(data, predictions).abs().max().item():{spacing[1]}} {'[p.u.]':{spacing[2]}}"
)
# branch (apparent) power
print(
f"{'Upper S_ij (transformers):':{spacing[0]}} {calculate_branch_power_errors_from(data, predictions, EdgeTypes.TRANSFORMER).abs().max().item():{spacing[1]}} {'[p.u.]':{spacing[2]}}"
)
print(
f"{'Upper S_ij (AC lines):':{spacing[0]}} {calculate_branch_power_errors_from(data, predictions, EdgeTypes.AC_LINE).abs().max().item():{spacing[1]}} {'[p.u.]':{spacing[2]}}"
)
print(
f"{'Upper S_ji (transformers):':{spacing[0]}} {calculate_branch_power_errors_to(data, predictions, EdgeTypes.TRANSFORMER).abs().max().item():{spacing[1]}} {'[p.u.]':{spacing[2]}}"
)
print(
f"{'Upper S_ji (AC lines):':{spacing[0]}} {calculate_branch_power_errors_to(data, predictions, EdgeTypes.AC_LINE).abs().max().item():{spacing[1]}} {'[p.u.]':{spacing[2]}}"
)
def main():
"""
Calculate the various inequality violations of the solution and an untrained model.
Returns
-------
"""
dataset = OPFDataset(
"data", case_name="pglib_opf_case14_ieee", split="val", topological_perturbations=False, num_groups=1
)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
loader = DataLoader(dataset, batch_size=32, shuffle=True)
batch = next(iter(loader)).to(device)
untrained_model = to_hetero(Model(), batch.metadata())
untrained_model.to(device)
with torch.no_grad():
predictions = untrained_model(batch.x_dict, batch.edge_index_dict)
print("\nWorst case violations:\n")
print("Solution:\n")
print_max_errors(batch, batch.y_dict)
print("\nUntrained model:\n")
print_max_errors(batch, predictions)
if __name__ == "__main__":
main()