-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmetrics.py
More file actions
151 lines (121 loc) · 6.12 KB
/
metrics.py
File metadata and controls
151 lines (121 loc) · 6.12 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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import torch
from torch_geometric.datasets import OPFDataset
from torch_geometric.loader import DataLoader
from torch_geometric.nn import GraphConv, to_hetero
from torchmetrics import MetricCollection
from opf_dataset_utils.metrics.aggregation import AggregationTypes
from opf_dataset_utils.metrics.cost import OptimalityGap
from opf_dataset_utils.metrics.inequality.bound_types import BoundTypes
from opf_dataset_utils.metrics.inequality.branch_power import BranchPowerInequalityError
from opf_dataset_utils.metrics.inequality.generator_power import (
GeneratorPowerInequalityError,
)
from opf_dataset_utils.metrics.inequality.voltage import (
VoltageAngleDifferenceInequalityError,
VoltageMagnitudeInequalityError,
)
from opf_dataset_utils.metrics.power import Power, PowerTypes
from opf_dataset_utils.metrics.power_flow import PowerFlowError
from opf_dataset_utils.metrics.variable.generator_power import GeneratorPowerError
from opf_dataset_utils.metrics.variable.voltage import (
VoltageAngleError,
VoltageMagnitudeError,
)
def create_opf_metrics(split: str) -> MetricCollection:
metric_dict = {}
for aggr in AggregationTypes:
metric_dict[f"{split}/{aggr} optimality gap [%]"] = OptimalityGap(aggr=aggr)
metric_dict[f"{split}/{aggr} absolute branch power inequality error [kVA]"] = BranchPowerInequalityError(
aggr=aggr, value_type="absolute", unit="kilo"
)
metric_dict[f"{split}/{aggr} relative branch power inequality error [%]"] = BranchPowerInequalityError(
aggr=aggr, value_type="relative"
)
metric_dict[f"{split}/{aggr} absolute voltage magnitude error [per-unit]"] = VoltageMagnitudeError(
aggr=aggr, value_type="absolute"
)
metric_dict[f"{split}/{aggr} relative voltage magnitude error [%]"] = VoltageMagnitudeError(
aggr=aggr, value_type="relative"
)
metric_dict[f"{split}/{aggr} absolute voltage angle error [deg]"] = VoltageAngleError(
aggr=aggr, value_type="absolute", unit="degree"
)
metric_dict[f"{split}/{aggr} relative voltage angle error [%]"] = VoltageAngleError(
aggr=aggr, value_type="relative"
)
for power_type in [PowerTypes.ACTIVE, PowerTypes.REACTIVE]:
metric_dict[f"{split}/{aggr} absolute {power_type} generator power error [kVA]"] = GeneratorPowerError(
aggr=aggr, power_type=power_type, unit="kilo", value_type="absolute"
)
metric_dict[f"{split}/{aggr} relative {power_type} generator power error [%]"] = GeneratorPowerError(
aggr=aggr, power_type=power_type, value_type="relative"
)
for power_type in PowerTypes:
metric_dict[f"{split}/{aggr} absolute {power_type} power flow error [kVA]"] = PowerFlowError(
aggr=aggr, power_type=power_type, unit="kilo", value_type="absolute"
)
metric_dict[f"{split}/{aggr} relative {power_type} power flow error [%]"] = PowerFlowError(
aggr=aggr, power_type=power_type, value_type="relative"
)
metric_dict[f"{split}/{aggr} {power_type} power [kVA]"] = Power(
aggr=aggr, power_type=power_type, unit="kilo"
)
for bound_type in BoundTypes:
metric_dict[
f"{split}/{aggr} absolute {bound_type} voltage magnitude inequality error [per-unit]"
] = VoltageMagnitudeInequalityError(aggr=aggr, bound_type=bound_type, value_type="absolute")
metric_dict[
f"{split}/{aggr} relative {bound_type} voltage magnitude inequality error [%]"
] = VoltageMagnitudeInequalityError(aggr=aggr, bound_type=bound_type, value_type="relative")
metric_dict[
f"{split}/{aggr} absolute {bound_type} voltage angle difference error [deg]"
] = VoltageAngleDifferenceInequalityError(
aggr=aggr, bound_type=bound_type, value_type="absolute", unit="degree"
)
metric_dict[
f"{split}/{aggr} relative {bound_type} voltage angle difference error [%]"
] = VoltageAngleDifferenceInequalityError(aggr=aggr, bound_type=bound_type, value_type="relative")
for power_type in [PowerTypes.ACTIVE, PowerTypes.REACTIVE]:
metric_dict[
f"{split}/{aggr} absolute {bound_type} {power_type} generator power inequality error [kVA]"
] = GeneratorPowerInequalityError(
aggr=aggr, bound_type=bound_type, value_type="absolute", power_type=power_type, unit="kilo"
)
metric_dict[
f"{split}/{aggr} relative {bound_type} {power_type} generator power inequality error [%]"
] = GeneratorPowerInequalityError(
aggr=aggr, bound_type=bound_type, value_type="relative", power_type=power_type
)
return MetricCollection(metric_dict)
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 main():
"""
Calculate the power flow errors 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():
untrained_predictions = untrained_model(batch.x_dict, batch.edge_index_dict)
metrics = create_opf_metrics("val").to(device)
metrics(batch, untrained_predictions)
metric_values = metrics.compute()
for name, value in metric_values.items():
print(f"\t{name:<75}: {value:>.5f}")
if __name__ == "__main__":
main()