257 |
202 |
|
# ppc["branch"][:, IKSS_T] = abs(ikss_all_t[:, bus_idx] / baseI[tb]) |
258 |
203 |
|
calc_branch_results(net, ppc, V) |
259 |
204 |
|
|
|
205 |
+ |
def _calc_single_bus_sc_no_y_inv(net, ppc, bus): |
|
206 |
+ |
# Vectorized for multiple bus |
|
207 |
+ |
if bus is None: |
|
208 |
+ |
# Slice(None) is equal to : select |
|
209 |
+ |
bus_idx = slice(None) |
|
210 |
+ |
else: |
|
211 |
+ |
bus_idx = net._pd2ppc_lookups["bus"][bus] #bus where the short-circuit is calculated (j) |
260 |
212 |
|
|
261 |
|
- |
from pandapower.pypower.pfsoln import pfsoln as pfsoln_pypower |
262 |
|
- |
from pandapower.pf.ppci_variables import _get_pf_variables_from_ppci |
|
213 |
+ |
ybus = ppc["internal"]["Ybus"] |
|
214 |
+ |
ybus_fact = ppc["internal"]["ybus_fact"] |
|
215 |
+ |
# case = net._options["case"] |
|
216 |
+ |
baseI = ppc["internal"]["baseI"] |
|
217 |
+ |
# vqj = ppc["bus"][:, C_MIN] if case == "min" else ppc["bus"][:, C_MAX] #this is the source voltage in per unit (VQj) |
|
218 |
+ |
|
|
219 |
+ |
# Solve Ikss from voltage source |
|
220 |
+ |
n_bus = ybus.shape[0] |
|
221 |
+ |
|
|
222 |
+ |
# ybus_sub_mask = (np.arange(ybus.shape[0]) != bus_idx) |
|
223 |
+ |
# V_ikss = np.zeros(n_bus, dtype=np.complex) |
|
224 |
+ |
# V_ikss[bus_idx] = vqj[bus_idx] |
|
225 |
+ |
|
|
226 |
+ |
# # Solve Ax = b |
|
227 |
+ |
# b = np.zeros(n_bus-1, dtype=np.complex) -\ |
|
228 |
+ |
# (ybus[:, ~ybus_sub_mask].toarray())[ybus_sub_mask].ravel() * V_ikss[bus_idx] |
|
229 |
+ |
# ybus_sub = ybus[ybus_sub_mask, :][:, ybus_sub_mask] |
|
230 |
+ |
# x = spsolve(ybus_sub, b) |
|
231 |
+ |
|
|
232 |
+ |
# V_ikss[ybus_sub_mask] = x |
|
233 |
+ |
# I_ikss = np.zeros(n_bus, dtype=np.complex) |
|
234 |
+ |
# I_ikss[bus_idx] = np.dot(ybus[bus_idx, :].toarray(), V_ikss) |
|
235 |
+ |
# V = V_ikss |
|
236 |
+ |
|
|
237 |
+ |
# Version 2 |
|
238 |
+ |
I_ikss = np.zeros(n_bus, dtype=np.complex) |
|
239 |
+ |
I_ikss[bus_idx] = ppc["bus"][bus_idx, IKSS1] |
|
240 |
+ |
V_ikss = ybus_fact(I_ikss * baseI) |
|
241 |
+ |
V = V_ikss |
|
242 |
+ |
|
|
243 |
+ |
#TODO include current sources |
|
244 |
+ |
current_sources = any(ppc["bus"][:, IKCV]) > 0 |
|
245 |
+ |
if current_sources: |
|
246 |
+ |
current = -ppc["bus"][:, IKCV] |
|
247 |
+ |
current[bus_idx] += ppc["bus"][bus_idx, IKSS2] |
|
248 |
+ |
V_source = ybus_fact(current) |
|
249 |
+ |
V += V_source |
|
250 |
+ |
|
|
251 |
+ |
calc_branch_results(net, ppc, V) |
263 |
252 |
|
|
264 |
253 |
|
|
265 |
254 |
|
def calc_branch_results(net, ppci, V): |
266 |
255 |
|
Ybus = ppci["internal"]["Ybus"] |
267 |
256 |
|
Yf = ppci["internal"]["Yf"] |
268 |
257 |
|
Yt = ppci["internal"]["Yt"] |
269 |
|
- |
baseMVA, bus, gen, branch, ref, _, pq, _, _, V0, ref_gens = _get_pf_variables_from_ppci(ppci) |
|
258 |
+ |
baseMVA, bus, gen, branch, ref, _, _, _, _, _, ref_gens = _get_pf_variables_from_ppci(ppci) |
270 |
259 |
|
bus, gen, branch = pfsoln_pypower(baseMVA, bus, gen, branch, Ybus, Yf, Yt, V, ref, ref_gens) |
271 |
260 |
|
ppci["bus"], ppci["gen"], ppci["branch"] = bus, gen, branch |
|
261 |
+ |
|
|
262 |
+ |
|
|
263 |
+ |
def _calc_branch_currents(net, ppc, bus): |
|
264 |
+ |
# Vectorized for multiple bus |
|
265 |
+ |
if bus is None: |
|
266 |
+ |
# Slice(None) is equal to select all |
|
267 |
+ |
bus = net.bus.index |
|
268 |
+ |
|
|
269 |
+ |
bus_idx = net._pd2ppc_lookups["bus"][bus] |
|
270 |
+ |
# Select only in service bus for sc calculation |
|
271 |
+ |
bus_idx = bus_idx[bus_idx < ppc['bus'].shape[0]] |
|
272 |
+ |
n_sc_bus = np.shape(bus_idx)[0] |
|
273 |
+ |
|
|
274 |
+ |
case = net._options["case"] |
|
275 |
+ |
|
|
276 |
+ |
Yf = ppc["internal"]["Yf"] |
|
277 |
+ |
Yt = ppc["internal"]["Yt"] |
|
278 |
+ |
baseI = ppc["internal"]["baseI"] |
|
279 |
+ |
n_bus = ppc["bus"].shape[0] |
|
280 |
+ |
fb = np.real(ppc["branch"][:, 0]).astype(int) |
|
281 |
+ |
tb = np.real(ppc["branch"][:, 1]).astype(int) |
|
282 |
+ |
minmax = np.nanmin if case == "min" else np.nanmax |
|
283 |
+ |
|
|
284 |
+ |
# calculate voltage source branch current |
|
285 |
+ |
if net["_options"]["inverse_y"]: |
|
286 |
+ |
Zbus = ppc["internal"]["Zbus"] |
|
287 |
+ |
V_ikss = (ppc["bus"][:, IKSS1] * baseI) * Zbus |
|
288 |
+ |
V_ikss = V_ikss[:, bus_idx] |
|
289 |
+ |
else: |
|
290 |
+ |
ybus_fact = ppc["internal"]["ybus_fact"] |
|
291 |
+ |
V_ikss = np.zeros((n_bus, n_sc_bus), dtype=np.complex) |
|
292 |
+ |
for ix, b in enumerate(bus_idx): |
|
293 |
+ |
ikss = np.zeros(n_bus, dtype=np.complex) |
|
294 |
+ |
ikss[b] = ppc["bus"][b, IKSS1] * baseI[b] |
|
295 |
+ |
V_ikss[:, ix] = ybus_fact(ikss) |
|
296 |
+ |
|
|
297 |
+ |
ikss1_all_f = np.conj(Yf.dot(V_ikss)) |
|
298 |
+ |
ikss1_all_t = np.conj(Yt.dot(V_ikss)) |
|
299 |
+ |
ikss1_all_f[abs(ikss1_all_f) < 1e-10] = 0. |
|
300 |
+ |
ikss1_all_t[abs(ikss1_all_t) < 1e-10] = 0. |
|
301 |
+ |
|
|
302 |
+ |
# add current source branch current if there is one |
|
303 |
+ |
current_sources = any(ppc["bus"][:, IKCV]) > 0 |
|
304 |
+ |
if current_sources: |
|
305 |
+ |
current = np.tile(-ppc["bus"][:, IKCV], (n_sc_bus, 1)) |
|
306 |
+ |
for ix, b in enumerate(bus_idx): |
|
307 |
+ |
current[ix, b] += ppc["bus"][b, IKSS2] |
|
308 |
+ |
|
|
309 |
+ |
# calculate voltage source branch current |
|
310 |
+ |
if net["_options"]["inverse_y"]: |
|
311 |
+ |
Zbus = ppc["internal"]["Zbus"] |
|
312 |
+ |
V = np.dot((current * baseI), Zbus).T |
|
313 |
+ |
else: |
|
314 |
+ |
ybus_fact = ppc["internal"]["ybus_fact"] |
|
315 |
+ |
V = np.zeros((n_bus, n_sc_bus), dtype=np.complex) |
|
316 |
+ |
for ix, b in enumerate(bus_idx): |
|
317 |
+ |
V[:, ix] = ybus_fact(current[ix, :] * baseI[b]) |
|
318 |
+ |
|
|
319 |
+ |
fb = np.real(ppc["branch"][:, 0]).astype(int) |
|
320 |
+ |
tb = np.real(ppc["branch"][:, 1]).astype(int) |
|
321 |
+ |
ikss2_all_f = np.conj(Yf.dot(V)) |
|
322 |
+ |
ikss2_all_t = np.conj(Yt.dot(V)) |
|
323 |
+ |
|
|
324 |
+ |
ikss_all_f = abs(ikss1_all_f + ikss2_all_f) |
|
325 |
+ |
ikss_all_t = abs(ikss1_all_t + ikss2_all_t) |
|
326 |
+ |
else: |
|
327 |
+ |
ikss_all_f = abs(ikss1_all_f) |
|
328 |
+ |
ikss_all_t = abs(ikss1_all_t) |
|
329 |
+ |
|
|
330 |
+ |
if net._options["return_all_currents"]: |
|
331 |
+ |
ppc["internal"]["branch_ikss_f"] = ikss_all_f / baseI[fb, None] |
|
332 |
+ |
ppc["internal"]["branch_ikss_t"] = ikss_all_t / baseI[tb, None] |
|
333 |
+ |
else: |
|
334 |
+ |
ikss_all_f[abs(ikss_all_f) < 1e-10] = np.nan |
|
335 |
+ |
ikss_all_t[abs(ikss_all_t) < 1e-10] = np.nan |
|
336 |
+ |
ppc["branch"][:, IKSS_F] = np.nan_to_num(minmax(ikss_all_f, axis=1) / baseI[fb]) |
|
337 |
+ |
ppc["branch"][:, IKSS_T] = np.nan_to_num(minmax(ikss_all_t, axis=1) / baseI[tb]) |
|
338 |
+ |
|
|
339 |
+ |
if net._options["ip"]: |
|
340 |
+ |
kappa = ppc["bus"][:, KAPPA] |
|
341 |
+ |
if current_sources: |
|
342 |
+ |
ip_all_f = np.sqrt(2) * (ikss1_all_f * kappa[bus_idx] + ikss2_all_f) |
|
343 |
+ |
ip_all_t = np.sqrt(2) * (ikss1_all_t * kappa[bus_idx] + ikss2_all_t) |
|
344 |
+ |
else: |
|
345 |
+ |
ip_all_f = np.sqrt(2) * ikss1_all_f * kappa[bus_idx] |
|
346 |
+ |
ip_all_t = np.sqrt(2) * ikss1_all_t * kappa[bus_idx] |
|
347 |
+ |
|
|
348 |
+ |
if net._options["return_all_currents"]: |
|
349 |
+ |
ppc["internal"]["branch_ip_f"] = abs(ip_all_f) / baseI[fb, None] |
|
350 |
+ |
ppc["internal"]["branch_ip_t"] = abs(ip_all_t) / baseI[tb, None] |
|
351 |
+ |
else: |
|
352 |
+ |
ip_all_f[abs(ip_all_f) < 1e-10] = np.nan |
|
353 |
+ |
ip_all_t[abs(ip_all_t) < 1e-10] = np.nan |
|
354 |
+ |
ppc["branch"][:, IP_F] = np.nan_to_num(minmax(abs(ip_all_f), axis=1) / baseI[fb]) |
|
355 |
+ |
ppc["branch"][:, IP_T] = np.nan_to_num(minmax(abs(ip_all_t), axis=1) / baseI[tb]) |
|
356 |
+ |
|
|
357 |
+ |
if net._options["ith"]: |
|
358 |
+ |
n = 1 |
|
359 |
+ |
m = ppc["bus"][bus_idx, M] |
|
360 |
+ |
ith_all_f = ikss_all_f * np.sqrt(m + n) |
|
361 |
+ |
ith_all_t = ikss_all_t * np.sqrt(m + n) |
|
362 |
+ |
|
|
363 |
+ |
if net._options["return_all_currents"]: |
|
364 |
+ |
ppc["internal"]["branch_ith_f"] = ith_all_f / baseI[fb, None] |
|
365 |
+ |
ppc["internal"]["branch_ith_t"] = ith_all_t / baseI[tb, None] |
|
366 |
+ |
else: |
|
367 |
+ |
ppc["branch"][:, ITH_F] = np.nan_to_num(minmax(ith_all_f, axis=1) / baseI[fb]) |
|
368 |
+ |
ppc["branch"][:, ITH_T] = np.nan_to_num(minmax(ith_all_t, axis=1) / baseI[fb]) |