-
Notifications
You must be signed in to change notification settings - Fork 466
/
results_branch.py
314 lines (266 loc) · 12.2 KB
/
results_branch.py
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
# -*- coding: utf-8 -*-
# Copyright (c) 2016-2019 by University of Kassel and Fraunhofer Institute for Energy Economics
# and Energy System Technology (IEE), Kassel. All rights reserved.
import numpy as np
import pandas as pd
from pandapower.auxiliary import _sum_by_group
from pandapower.pypower.idx_brch import F_BUS, T_BUS, PF, QF, PT, QT, BR_R
from pandapower.pypower.idx_bus import BASE_KV, VM, VA
def _get_branch_results(net, ppc, bus_lookup_aranged, pq_buses):
"""
Extract the bus results and writes it in the Dataframe net.res_line and net.res_trafo.
INPUT:
**results** - the result of runpf loadflow calculation
**p** - the dict to dump the "res_line" and "res_trafo" Dataframe
"""
i_ft, s_ft = _get_branch_flows(ppc)
_get_line_results(net, ppc, i_ft)
_get_trafo_results(net, ppc, s_ft, i_ft)
_get_trafo3w_results(net, ppc, s_ft, i_ft)
_get_impedance_results(net, ppc, i_ft)
_get_xward_branch_results(net, ppc, bus_lookup_aranged, pq_buses)
_get_switch_results(net, i_ft)
def _get_branch_flows(ppc):
br_idx = ppc["branch"][:, (F_BUS, T_BUS)].real.astype(int)
vm_ft = ppc["bus"][br_idx, VM] * ppc["bus"][br_idx, BASE_KV]
s_ft = np.sqrt(ppc["branch"][:, (PF, PT)].real ** 2 +
ppc["branch"][:, (QF, QT)].real ** 2)
i_ft = s_ft / vm_ft / np.sqrt(3)
return i_ft, s_ft
def _get_line_results(net, ppc, i_ft):
# create res_line_vals which are written to the pandas dataframe
ac = net["_options"]["ac"]
if not "line" in net._pd2ppc_lookups["branch"]:
return
f, t = net._pd2ppc_lookups["branch"]["line"]
pf_mw = ppc["branch"][f:t, PF].real
q_from_mvar = ppc["branch"][f:t, QF].real
p_from_mw = pf_mw
pt_mw = ppc["branch"][f:t, PT].real
q_to_mvar = ppc["branch"][f:t, QT].real
p_to_mw = pt_mw
if ac:
pl_mw = pf_mw + pt_mw
ql_mvar = q_from_mvar + q_to_mvar
else:
pl_mw = np.zeros_like(pf_mw)
ql_mvar = np.zeros_like(q_from_mvar)
with np.errstate(invalid='ignore'):
i_ka = np.max(i_ft[f:t], axis=1)
i_from_ka = i_ft[f:t][:, 0]
i_to_ka = i_ft[f:t][:, 1]
line_df = net["line"]
i_max = line_df["max_i_ka"].values * line_df["df"].values * line_df["parallel"].values
from_bus = ppc["branch"][f:t, F_BUS].real.astype(int)
to_bus = ppc["branch"][f:t, T_BUS].real.astype(int)
# write to line
res_line_df = net["res_line"]
res_line_df["p_from_mw"].values[:] = p_from_mw
res_line_df["q_from_mvar"].values[:] = q_from_mvar
res_line_df["p_to_mw"].values[:] = p_to_mw
res_line_df["q_to_mvar"].values[:] = q_to_mvar
res_line_df["pl_mw"].values[:] = pl_mw
res_line_df["ql_mvar"].values[:] = ql_mvar
res_line_df["i_from_ka"].values[:] = i_from_ka
res_line_df["i_to_ka"].values[:] = i_to_ka
res_line_df["i_ka"].values[:] = i_ka
res_line_df["vm_from_pu"].values[:] = ppc["bus"][from_bus, VM]
res_line_df["va_from_degree"].values[:] = ppc["bus"][from_bus, VA]
res_line_df["vm_to_pu"].values[:] = ppc["bus"][to_bus, VM]
res_line_df["va_to_degree"].values[:] = ppc["bus"][to_bus, VA]
res_line_df["loading_percent"].values[:] = i_ka / i_max * 100
# if consider_line_temperature, add resulting r_ohm_per_km to net.res_line
if net["_options"]["consider_line_temperature"]:
base_kv = ppc["bus"][from_bus, BASE_KV]
baseR = np.square(base_kv) / net.sn_mva
length_km = line_df.length_km.values
parallel = line_df.parallel.values
res_line_df["r_ohm_per_km"] = ppc["branch"][f:t, BR_R].real / length_km * baseR * parallel
def _get_trafo_results(net, ppc, s_ft, i_ft):
ac = net["_options"]["ac"]
trafo_loading = net["_options"]["trafo_loading"]
if not "trafo" in net._pd2ppc_lookups["branch"]:
return
f, t = net._pd2ppc_lookups["branch"]["trafo"]
p_hv_mw = ppc["branch"][f:t, PF].real
p_lv_mw = ppc["branch"][f:t, PT].real
if ac:
q_hv_mvar = ppc["branch"][f:t, QF].real
q_lv_mvar = ppc["branch"][f:t, QT].real
pl_mw = p_hv_mw + p_lv_mw
ql_mvar = q_hv_mvar + q_lv_mvar
else:
q_hv_mvar = np.zeros_like(p_hv_mw)
q_lv_mvar = np.zeros_like(p_lv_mw)
pl_mw = np.zeros_like(p_lv_mw)
ql_mvar = np.zeros_like(p_lv_mw)
i_hv_ka = i_ft[:, 0][f:t]
i_lv_ka = i_ft[:, 1][f:t]
if trafo_loading == "current":
trafo_df = net["trafo"]
vns = np.vstack([trafo_df["vn_hv_kv"].values, trafo_df["vn_lv_kv"].values]).T
lds_trafo = i_ft[f:t] * vns * np.sqrt(3) / trafo_df["sn_mva"].values[:, np.newaxis] * 100.
with np.errstate(invalid='ignore'):
ld_trafo = np.max(lds_trafo, axis=1)
elif trafo_loading == "power":
ld_trafo = np.max(s_ft[f:t] / net["trafo"]["sn_mva"].values[:, np.newaxis] * 100., axis=1)
else:
raise ValueError(
"Unknown transformer loading parameter %s - choose 'current' or 'power'" % trafo_loading)
if any(net["trafo"]["df"].values <= 0):
raise UserWarning('Transformer rating factor df must be positive. Transformers with false '
'rating factors: %s' % net["trafo"].query('df<=0').index.tolist())
loading_percent = \
ld_trafo / net["trafo"]["parallel"].values / net["trafo"]["df"].values
hv_buses = ppc["branch"][f:t, F_BUS].real.astype(int)
lv_buses = ppc["branch"][f:t, T_BUS].real.astype(int)
# write results to trafo dataframe
res_trafo_df = net["res_trafo"]
res_trafo_df["p_hv_mw"].values[:] = p_hv_mw
res_trafo_df["q_hv_mvar"].values[:] = q_hv_mvar
res_trafo_df["p_lv_mw"].values[:] = p_lv_mw
res_trafo_df["q_lv_mvar"].values[:] = q_lv_mvar
res_trafo_df["pl_mw"].values[:] = pl_mw
res_trafo_df["ql_mvar"].values[:] = ql_mvar
res_trafo_df["i_hv_ka"].values[:] = i_hv_ka
res_trafo_df["i_lv_ka"].values[:] = i_lv_ka
res_trafo_df["vm_hv_pu"].values[:] = ppc["bus"][hv_buses, VM]
res_trafo_df["va_hv_degree"].values[:] = ppc["bus"][hv_buses, VA]
res_trafo_df["vm_lv_pu"].values[:] = ppc["bus"][lv_buses, VM]
res_trafo_df["va_lv_degree"].values[:] = ppc["bus"][lv_buses, VA]
res_trafo_df["loading_percent"].values[:] = loading_percent
def _get_trafo3w_results(net, ppc, s_ft, i_ft):
trafo_loading = net["_options"]["trafo_loading"]
ac = net["_options"]["ac"]
if not "trafo3w" in net._pd2ppc_lookups["branch"]:
return
f, t = net._pd2ppc_lookups["branch"]["trafo3w"]
hv = int(f + (t - f) / 3)
mv = int(f + 2 * (t - f) / 3)
lv = t
phv_mw = ppc["branch"][f:hv, PF].real
pmv_mw = ppc["branch"][hv:mv, PT].real
plv_mw = ppc["branch"][mv:lv, PT].real
p_hv_mw = phv_mw
p_mv_mw = pmv_mw
p_lv_mw = plv_mw
if ac:
q_hv_mvar = ppc["branch"][f:hv, QF].real
q_mv_mvar = ppc["branch"][hv:mv, QT].real
q_lv_mvar = ppc["branch"][mv:lv, QT].real
pl_mw = phv_mw + pmv_mw + plv_mw
ql_mvar = q_hv_mvar + q_mv_mvar + q_lv_mvar
else:
zeros = np.zeros_like(phv_mw)
q_hv_mvar = zeros
q_mv_mvar = zeros
q_lv_mvar = zeros
pl_mw = zeros
ql_mvar = zeros
i_h = i_ft[:, 0][f:hv]
i_m = i_ft[:, 1][hv:mv]
i_l = i_ft[:, 1][mv:lv]
t3 = net["trafo3w"]
if trafo_loading == "current":
ld_h = i_h * t3["vn_hv_kv"].values * np.sqrt(3) / t3["sn_hv_mva"].values * 100
ld_m = i_m * t3["vn_mv_kv"].values * np.sqrt(3) / t3["sn_mv_mva"].values * 100
ld_l = i_l * t3["vn_lv_kv"].values * np.sqrt(3) / t3["sn_lv_mva"].values * 100
with np.errstate(invalid='ignore'):
ld_trafo = np.max(np.vstack([ld_h, ld_m, ld_l]), axis=0)
elif trafo_loading == "power":
ld_h = s_ft[:, 0][f:hv] / t3["sn_hv_mva"].values * 100.
ld_m = s_ft[:, 1][hv:mv] / t3["sn_mv_mva"].values * 100.
ld_l = s_ft[:, 1][mv:lv] / t3["sn_lv_mva"].values * 100.
ld_trafo = np.max(np.vstack([ld_h, ld_m, ld_l]), axis=0)
else:
raise ValueError(
"Unknown transformer loading parameter %s - choose 'current' or 'power'" % trafo_loading)
loading_percent = ld_trafo
hv_buses = ppc["branch"][f:hv, F_BUS].real.astype(int)
aux_buses = ppc["branch"][f:hv, T_BUS].real.astype(int)
mv_buses = ppc["branch"][hv:mv, T_BUS].real.astype(int)
lv_buses = ppc["branch"][mv:lv, T_BUS].real.astype(int)
# write results to trafo3w dataframe
res_trafo3w_df = net["res_trafo3w"]
res_trafo3w_df["p_hv_mw"].values[:] = p_hv_mw
res_trafo3w_df["q_hv_mvar"].values[:] = q_hv_mvar
res_trafo3w_df["p_mv_mw"].values[:] = p_mv_mw
res_trafo3w_df["q_mv_mvar"].values[:] = q_mv_mvar
res_trafo3w_df["p_lv_mw"].values[:] = p_lv_mw
res_trafo3w_df["q_lv_mvar"].values[:] = q_lv_mvar
res_trafo3w_df["pl_mw"].values[:] = pl_mw
res_trafo3w_df["ql_mvar"].values[:] = ql_mvar
res_trafo3w_df["i_hv_ka"].values[:] = i_h
res_trafo3w_df["i_mv_ka"].values[:] = i_m
res_trafo3w_df["i_lv_ka"].values[:] = i_l
res_trafo3w_df["vm_hv_pu"].values[:] = ppc["bus"][hv_buses, VM]
res_trafo3w_df["va_hv_degree"].values[:] = ppc["bus"][hv_buses, VA]
res_trafo3w_df["vm_mv_pu"].values[:] = ppc["bus"][mv_buses, VM]
res_trafo3w_df["va_mv_degree"].values[:] = ppc["bus"][mv_buses, VA]
res_trafo3w_df["vm_lv_pu"].values[:] = ppc["bus"][lv_buses, VM]
res_trafo3w_df["va_lv_degree"].values[:] = ppc["bus"][lv_buses, VA]
res_trafo3w_df["va_internal_degree"].values[:] = ppc["bus"][aux_buses, VA]
res_trafo3w_df["vm_internal_pu"].values[:] = ppc["bus"][aux_buses, VM]
res_trafo3w_df["loading_percent"].values[:] = loading_percent
def _get_impedance_results(net, ppc, i_ft):
ac = net["_options"]["ac"]
if not "impedance" in net._pd2ppc_lookups["branch"]:
return
f, t = net._pd2ppc_lookups["branch"]["impedance"]
pf_mw = ppc["branch"][f:t, (PF)].real
pt_mw = ppc["branch"][f:t, (PT)].real
p_from_mw = pf_mw
p_to_mw = pt_mw
if ac:
q_from_mvar = ppc["branch"][f:t, (QF)].real
q_to_mvar = ppc["branch"][f:t, (QT)].real
ql_mvar = q_from_mvar + q_to_mvar
pl_mw = pf_mw + pt_mw
else:
zeros = np.zeros_like(p_from_mw)
# this looks like a pyramid
q_from_mvar = zeros
q_to_mvar = zeros
ql_mvar = zeros
pl_mw = zeros
# zeros
i_from_ka = i_ft[f:t][:, 0]
i_to_ka = i_ft[f:t][:, 1]
# write to impedance
res_impediance_df = net["res_impedance"]
res_impediance_df["p_from_mw"].values[:] = p_from_mw
res_impediance_df["q_from_mvar"].values[:] = q_from_mvar
res_impediance_df["p_to_mw"].values[:] = p_to_mw
res_impediance_df["q_to_mvar"].values[:] = q_to_mvar
res_impediance_df["pl_mw"].values[:] = pl_mw
res_impediance_df["ql_mvar"].values[:] = ql_mvar
res_impediance_df["i_from_ka"].values[:] = i_from_ka
res_impediance_df["i_to_ka"].values[:] = i_to_ka
def _get_xward_branch_results(net, ppc, bus_lookup_aranged, pq_buses):
ac = net["_options"]["ac"]
if not "xward" in net._pd2ppc_lookups["branch"]:
return
f, t = net._pd2ppc_lookups["branch"]["xward"]
p_branch_xward = ppc["branch"][f:t, PF].real
net["res_xward"]["p_mw"].values[:] = net["res_xward"]["p_mw"].values + p_branch_xward
if ac:
q_branch_xward = ppc["branch"][f:t, QF].real
net["res_xward"]["q_mvar"].values[:] = net["res_xward"]["q_mvar"].values + q_branch_xward
else:
q_branch_xward = np.zeros(len(p_branch_xward))
b_pp, p, q = _sum_by_group(net["xward"]["bus"].values, p_branch_xward, q_branch_xward)
b_ppc = bus_lookup_aranged[b_pp]
pq_buses[b_ppc, 0] += p
pq_buses[b_ppc, 1] += q
aux_buses = net["_pd2ppc_lookups"]["bus"][net["_pd2ppc_lookups"]["aux"]["xward"]]
net["res_xward"]["va_internal_degree"].values[:] = ppc["bus"][aux_buses, VA]
net["res_xward"]["vm_internal_pu"].values[:] = ppc["bus"][aux_buses, VM]
net["res_xward"].index = net["xward"].index
def _get_switch_results(net, i_ft):
if not "switch" in net._pd2ppc_lookups["branch"]:
return
f, t = net._pd2ppc_lookups["branch"]["switch"]
with np.errstate(invalid='ignore'):
i_ka = np.max(i_ft[f:t], axis=1)
net["res_switch"] = pd.DataFrame(data=i_ka, columns=["i_ka"],
index=net.switch[net._impedance_bb_switches].index)