1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 """Prints power flow results.
18 """
19
20 from sys import stdout
21
22 from numpy import \
23 ones, zeros, r_, sort, exp, pi, diff, arange, min, \
24 argmin, argmax, logical_or, real, imag, any
25
26 from numpy import flatnonzero as find
27
28 from idx_bus import BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, VA, \
29 VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN
30 from idx_gen import GEN_BUS, PG, QG, QMAX, QMIN, VG, GEN_STATUS, \
31 PMAX, PMIN, MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN
32 from idx_brch import F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, \
33 TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST
34
35 from isload import isload
36 from run_userfcn import run_userfcn
37 from ppoption import ppoption
38
39
40 -def printpf(baseMVA, bus=None, gen=None, branch=None, f=None, success=None,
41 et=None, fd=None, ppopt=None):
42 """Prints power flow results.
43
44 Prints power flow and optimal power flow results to C{fd} (a file
45 descriptor which defaults to C{stdout}), with the details of what
46 gets printed controlled by the optional C{ppopt} argument, which is a
47 PYPOWER options vector (see L{ppoption} for details).
48
49 The data can either be supplied in a single C{results} dict, or
50 in the individual arguments: C{baseMVA}, C{bus}, C{gen}, C{branch}, C{f},
51 C{success} and C{et}, where C{f} is the OPF objective function value,
52 C{success} is C{True} if the solution converged and C{False} otherwise,
53 and C{et} is the elapsed time for the computation in seconds. If C{f} is
54 given, it is assumed that the output is from an OPF run, otherwise it is
55 assumed to be a simple power flow run.
56
57 Examples::
58 ppopt = ppoptions(OUT_GEN=1, OUT_BUS=0, OUT_BRANCH=0)
59 fd = open(fname, 'w+b')
60 results = runopf(ppc)
61 printpf(results)
62 printpf(results, fd)
63 printpf(results, fd, ppopt)
64 printpf(baseMVA, bus, gen, branch, f, success, et)
65 printpf(baseMVA, bus, gen, branch, f, success, et, fd)
66 printpf(baseMVA, bus, gen, branch, f, success, et, fd, ppopt)
67 fd.close()
68
69 @author: Ray Zimmerman (PSERC Cornell)
70 @author: Richard Lincoln
71 """
72
73
74 if isinstance(baseMVA, dict):
75 have_results_struct = 1
76 results = baseMVA
77 if gen is None:
78 ppopt = ppoption()
79 else:
80 ppopt = gen
81 if (ppopt['OUT_ALL'] == 0) and (ppopt['OUT_RAW'] == 0):
82 return
83 if bus is None:
84 fd = stdout
85 else:
86 fd = bus
87 baseMVA, bus, gen, branch, success, et = \
88 results["baseMVA"], results["bus"], results["gen"], \
89 results["branch"], results["success"], results["et"]
90 if 'f' in results:
91 f = results["f"]
92 else:
93 f = None
94 else:
95 have_results_struct = 0
96 if ppopt is None:
97 ppopt = ppoption()
98 if fd is None:
99 fd = stdout
100 if ppopt['OUT_ALL'] == 0 and ppopt['OUT_RAW'] == 0:
101 return
102
103 isOPF = f is not None
104
105
106 isDC = ppopt['PF_DC']
107 OUT_ALL = ppopt['OUT_ALL']
108 OUT_ANY = OUT_ALL == 1
109 OUT_SYS_SUM = (OUT_ALL == 1) or ((OUT_ALL == -1) and ppopt['OUT_SYS_SUM'])
110 OUT_AREA_SUM = (OUT_ALL == 1) or ((OUT_ALL == -1) and ppopt['OUT_AREA_SUM'])
111 OUT_BUS = (OUT_ALL == 1) or ((OUT_ALL == -1) and ppopt['OUT_BUS'])
112 OUT_BRANCH = (OUT_ALL == 1) or ((OUT_ALL == -1) and ppopt['OUT_BRANCH'])
113 OUT_GEN = (OUT_ALL == 1) or ((OUT_ALL == -1) and ppopt['OUT_GEN'])
114 OUT_ANY = OUT_ANY | ((OUT_ALL == -1) and
115 (OUT_SYS_SUM or OUT_AREA_SUM or OUT_BUS or
116 OUT_BRANCH or OUT_GEN))
117
118 if OUT_ALL == -1:
119 OUT_ALL_LIM = ppopt['OUT_ALL_LIM']
120 elif OUT_ALL == 1:
121 OUT_ALL_LIM = 2
122 else:
123 OUT_ALL_LIM = 0
124
125 OUT_ANY = OUT_ANY or (OUT_ALL_LIM >= 1)
126 if OUT_ALL_LIM == -1:
127 OUT_V_LIM = ppopt['OUT_V_LIM']
128 OUT_LINE_LIM = ppopt['OUT_LINE_LIM']
129 OUT_PG_LIM = ppopt['OUT_PG_LIM']
130 OUT_QG_LIM = ppopt['OUT_QG_LIM']
131 else:
132 OUT_V_LIM = OUT_ALL_LIM
133 OUT_LINE_LIM = OUT_ALL_LIM
134 OUT_PG_LIM = OUT_ALL_LIM
135 OUT_QG_LIM = OUT_ALL_LIM
136
137 OUT_ANY = OUT_ANY or ((OUT_ALL_LIM == -1) and (OUT_V_LIM or OUT_LINE_LIM or OUT_PG_LIM or OUT_QG_LIM))
138 OUT_RAW = ppopt['OUT_RAW']
139 ptol = 1e-6
140
141
142 i2e = bus[:, BUS_I].astype(int)
143 e2i = zeros(max(i2e) + 1, int)
144 e2i[i2e] = arange(bus.shape[0])
145
146
147 nb = bus.shape[0]
148 nl = branch.shape[0]
149 ng = gen.shape[0]
150
151
152 if isDC:
153 bus[:, r_[QD, BS]] = zeros((nb, 2))
154 gen[:, r_[QG, QMAX, QMIN]] = zeros((ng, 3))
155 branch[:, r_[BR_R, BR_B]] = zeros((nl, 2))
156
157
158 ties = find(bus[e2i[branch[:, F_BUS].astype(int)], BUS_AREA] !=
159 bus[e2i[branch[:, T_BUS].astype(int)], BUS_AREA])
160
161 tap = ones(nl)
162 xfmr = find(branch[:, TAP])
163 tap[xfmr] = branch[xfmr, TAP]
164 tap = tap * exp(1j * pi / 180 * branch[:, SHIFT])
165 nzld = find((bus[:, PD] != 0.0) | (bus[:, QD] != 0.0))
166 sorted_areas = sort(bus[:, BUS_AREA])
167
168 s_areas = sorted_areas[r_[1, find(diff(sorted_areas)) + 1]]
169 nzsh = find((bus[:, GS] != 0.0) | (bus[:, BS] != 0.0))
170 allg = find( ~isload(gen) )
171 ong = find( (gen[:, GEN_STATUS] > 0) & ~isload(gen) )
172 onld = find( (gen[:, GEN_STATUS] > 0) & isload(gen) )
173 V = bus[:, VM] * exp(-1j * pi / 180 * bus[:, VA])
174 out = find(branch[:, BR_STATUS] == 0)
175 nout = len(out)
176 if isDC:
177 loss = zeros(nl)
178 else:
179 loss = baseMVA * abs(V[e2i[ branch[:, F_BUS].astype(int) ]] / tap -
180 V[e2i[ branch[:, T_BUS].astype(int) ]])**2 / \
181 (branch[:, BR_R] - 1j * branch[:, BR_X])
182
183 fchg = abs(V[e2i[ branch[:, F_BUS].astype(int) ]] / tap)**2 * branch[:, BR_B] * baseMVA / 2
184 tchg = abs(V[e2i[ branch[:, T_BUS].astype(int) ]] )**2 * branch[:, BR_B] * baseMVA / 2
185 loss[out] = zeros(nout)
186 fchg[out] = zeros(nout)
187 tchg[out] = zeros(nout)
188
189
190 if OUT_ANY:
191
192 if success:
193 fd.write('\nConverged in %.2f seconds' % et)
194 else:
195 fd.write('\nDid not converge (%.2f seconds)\n' % et)
196
197
198 if isOPF:
199 fd.write('\nObjective Function Value = %.2f $/hr' % f)
200
201 if OUT_SYS_SUM:
202 fd.write('\n================================================================================')
203 fd.write('\n| System Summary |')
204 fd.write('\n================================================================================')
205 fd.write('\n\nHow many? How much? P (MW) Q (MVAr)')
206 fd.write('\n--------------------- ------------------- ------------- -----------------')
207 fd.write('\nBuses %6d Total Gen Capacity %7.1f %7.1f to %.1f' % (nb, sum(gen[allg, PMAX]), sum(gen[allg, QMIN]), sum(gen[allg, QMAX])))
208 fd.write('\nGenerators %5d On-line Capacity %7.1f %7.1f to %.1f' % (len(allg), sum(gen[ong, PMAX]), sum(gen[ong, QMIN]), sum(gen[ong, QMAX])))
209 fd.write('\nCommitted Gens %5d Generation (actual) %7.1f %7.1f' % (len(ong), sum(gen[ong, PG]), sum(gen[ong, QG])))
210 fd.write('\nLoads %5d Load %7.1f %7.1f' % (len(nzld)+len(onld), sum(bus[nzld, PD])-sum(gen[onld, PG]), sum(bus[nzld, QD])-sum(gen[onld, QG])))
211 fd.write('\n Fixed %5d Fixed %7.1f %7.1f' % (len(nzld), sum(bus[nzld, PD]), sum(bus[nzld, QD])))
212 fd.write('\n Dispatchable %5d Dispatchable %7.1f of %-7.1f%7.1f' % (len(onld), -sum(gen[onld, PG]), -sum(gen[onld, PMIN]), -sum(gen[onld, QG])))
213 fd.write('\nShunts %5d Shunt (inj) %7.1f %7.1f' % (len(nzsh),
214 -sum(bus[nzsh, VM]**2 * bus[nzsh, GS]), sum(bus[nzsh, VM]**2 * bus[nzsh, BS]) ))
215 fd.write('\nBranches %5d Losses (I^2 * Z) %8.2f %8.2f' % (nl, sum(loss.real), sum(loss.imag) ))
216 fd.write('\nTransformers %5d Branch Charging (inj) - %7.1f' % (len(xfmr), sum(fchg) + sum(tchg) ))
217 fd.write('\nInter-ties %5d Total Inter-tie Flow %7.1f %7.1f' % (len(ties), sum(abs(branch[ties, PF]-branch[ties, PT])) / 2, sum(abs(branch[ties, QF]-branch[ties, QT])) / 2))
218 fd.write('\nAreas %5d' % len(s_areas))
219 fd.write('\n')
220 fd.write('\n Minimum Maximum')
221 fd.write('\n ------------------------- --------------------------------')
222 minv = min(bus[:, VM])
223 mini = argmin(bus[:, VM])
224 maxv = max(bus[:, VM])
225 maxi = argmax(bus[:, VM])
226 fd.write('\nVoltage Magnitude %7.3f p.u. @ bus %-4d %7.3f p.u. @ bus %-4d' % (minv, bus[mini, BUS_I], maxv, bus[maxi, BUS_I]))
227 minv = min(bus[:, VA])
228 mini = argmin(bus[:, VA])
229 maxv = max(bus[:, VA])
230 maxi = argmax(bus[:, VA])
231 fd.write('\nVoltage Angle %8.2f deg @ bus %-4d %8.2f deg @ bus %-4d' % (minv, bus[mini, BUS_I], maxv, bus[maxi, BUS_I]))
232 if not isDC:
233 maxv = max(loss.real)
234 maxi = argmax(loss.real)
235 fd.write('\nP Losses (I^2*R) - %8.2f MW @ line %d-%d' % (maxv, branch[maxi, F_BUS], branch[maxi, T_BUS]))
236 maxv = max(loss.imag)
237 maxi = argmax(loss.imag)
238 fd.write('\nQ Losses (I^2*X) - %8.2f MVAr @ line %d-%d' % (maxv, branch[maxi, F_BUS], branch[maxi, T_BUS]))
239 if isOPF:
240 minv = min(bus[:, LAM_P])
241 mini = argmin(bus[:, LAM_P])
242 maxv = max(bus[:, LAM_P])
243 maxi = argmax(bus[:, LAM_P])
244 fd.write('\nLambda P %8.2f $/MWh @ bus %-4d %8.2f $/MWh @ bus %-4d' % (minv, bus[mini, BUS_I], maxv, bus[maxi, BUS_I]))
245 minv = min(bus[:, LAM_Q])
246 mini = argmin(bus[:, LAM_Q])
247 maxv = max(bus[:, LAM_Q])
248 maxi = argmax(bus[:, LAM_Q])
249 fd.write('\nLambda Q %8.2f $/MWh @ bus %-4d %8.2f $/MWh @ bus %-4d' % (minv, bus[mini, BUS_I], maxv, bus[maxi, BUS_I]))
250 fd.write('\n')
251
252 if OUT_AREA_SUM:
253 fd.write('\n================================================================================')
254 fd.write('\n| Area Summary |')
255 fd.write('\n================================================================================')
256 fd.write('\nArea # of # of Gens # of Loads # of # of # of # of')
257 fd.write('\n Num Buses Total Online Total Fixed Disp Shunt Brchs Xfmrs Ties')
258 fd.write('\n---- ----- ----- ------ ----- ----- ----- ----- ----- ----- -----')
259 for i in range(len(s_areas)):
260 a = s_areas[i]
261 ib = find(bus[:, BUS_AREA] == a)
262 ig = find((bus[e2i[gen[:, GEN_BUS].astype(int)], BUS_AREA] == a) & ~isload(gen))
263 igon = find((bus[e2i[gen[:, GEN_BUS].astype(int)], BUS_AREA] == a) & (gen[:, GEN_STATUS] > 0) & ~isload(gen))
264 ildon = find((bus[e2i[gen[:, GEN_BUS].astype(int)], BUS_AREA] == a) & (gen[:, GEN_STATUS] > 0) & isload(gen))
265 inzld = find((bus[:, BUS_AREA] == a) & logical_or(bus[:, PD], bus[:, QD]))
266 inzsh = find((bus[:, BUS_AREA] == a) & logical_or(bus[:, GS], bus[:, BS]))
267 ibrch = find((bus[e2i[branch[:, F_BUS].astype(int)], BUS_AREA] == a) & (bus[e2i[branch[:, T_BUS].astype(int)], BUS_AREA] == a))
268 in_tie = find((bus[e2i[branch[:, F_BUS].astype(int)], BUS_AREA] == a) & (bus[e2i[branch[:, T_BUS].astype(int)], BUS_AREA] != a))
269 out_tie = find((bus[e2i[branch[:, F_BUS].astype(int)], BUS_AREA] != a) & (bus[e2i[branch[:, T_BUS].astype(int)], BUS_AREA] == a))
270 if not any(xfmr + 1):
271 nxfmr = 0
272 else:
273 nxfmr = len(find((bus[e2i[branch[xfmr, F_BUS].astype(int)], BUS_AREA] == a) & (bus[e2i[branch[xfmr, T_BUS].astype(int)], BUS_AREA] == a)))
274 fd.write('\n%3d %6d %5d %5d %5d %5d %5d %5d %5d %5d %5d' %
275 (a, len(ib), len(ig), len(igon), \
276 len(inzld)+len(ildon), len(inzld), len(ildon), \
277 len(inzsh), len(ibrch), nxfmr, len(in_tie)+len(out_tie)))
278
279 fd.write('\n---- ----- ----- ------ ----- ----- ----- ----- ----- ----- -----')
280 fd.write('\nTot: %6d %5d %5d %5d %5d %5d %5d %5d %5d %5d' %
281 (nb, len(allg), len(ong), len(nzld)+len(onld),
282 len(nzld), len(onld), len(nzsh), nl, len(xfmr), len(ties)))
283 fd.write('\n')
284 fd.write('\nArea Total Gen Capacity On-line Gen Capacity Generation')
285 fd.write('\n Num MW MVAr MW MVAr MW MVAr')
286 fd.write('\n---- ------ ------------------ ------ ------------------ ------ ------')
287 for i in range(len(s_areas)):
288 a = s_areas[i]
289 ig = find((bus[e2i[gen[:, GEN_BUS].astype(int)], BUS_AREA] == a) & ~isload(gen))
290 igon = find((bus[e2i[gen[:, GEN_BUS].astype(int)], BUS_AREA] == a) & (gen[:, GEN_STATUS] > 0) & ~isload(gen))
291 fd.write('\n%3d %7.1f %7.1f to %-7.1f %7.1f %7.1f to %-7.1f %7.1f %7.1f' %
292 (a, sum(gen[ig, PMAX]), sum(gen[ig, QMIN]), sum(gen[ig, QMAX]),
293 sum(gen[igon, PMAX]), sum(gen[igon, QMIN]), sum(gen[igon, QMAX]),
294 sum(gen[igon, PG]), sum(gen[igon, QG]) ))
295
296 fd.write('\n---- ------ ------------------ ------ ------------------ ------ ------')
297 fd.write('\nTot: %7.1f %7.1f to %-7.1f %7.1f %7.1f to %-7.1f %7.1f %7.1f' %
298 (sum(gen[allg, PMAX]), sum(gen[allg, QMIN]), sum(gen[allg, QMAX]),
299 sum(gen[ong, PMAX]), sum(gen[ong, QMIN]), sum(gen[ong, QMAX]),
300 sum(gen[ong, PG]), sum(gen[ong, QG]) ))
301 fd.write('\n')
302 fd.write('\nArea Disp Load Cap Disp Load Fixed Load Total Load')
303 fd.write('\n Num MW MVAr MW MVAr MW MVAr MW MVAr')
304 fd.write('\n---- ------ ------ ------ ------ ------ ------ ------ ------')
305 Qlim = (gen[:, QMIN] == 0) * gen[:, QMAX] + (gen[:, QMAX] == 0) * gen[:, QMIN]
306 for i in range(len(s_areas)):
307 a = s_areas[i]
308 ildon = find((bus[e2i[gen[:, GEN_BUS].astype(int)], BUS_AREA] == a) & (gen[:, GEN_STATUS] > 0) & isload(gen))
309 inzld = find((bus[:, BUS_AREA] == a) & logical_or(bus[:, PD], bus[:, QD]))
310 fd.write('\n%3d %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f' %
311 (a, -sum(gen[ildon, PMIN]),
312 -sum(Qlim[ildon]),
313 -sum(gen[ildon, PG]), -sum(gen[ildon, QG]),
314 sum(bus[inzld, PD]), sum(bus[inzld, QD]),
315 -sum(gen[ildon, PG]) + sum(bus[inzld, PD]),
316 -sum(gen[ildon, QG]) + sum(bus[inzld, QD]) ))
317
318 fd.write('\n---- ------ ------ ------ ------ ------ ------ ------ ------')
319 fd.write('\nTot: %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f' %
320 (-sum(gen[onld, PMIN]),
321 -sum(Qlim[onld]),
322 -sum(gen[onld, PG]), -sum(gen[onld, QG]),
323 sum(bus[nzld, PD]), sum(bus[nzld, QD]),
324 -sum(gen[onld, PG]) + sum(bus[nzld, PD]),
325 -sum(gen[onld, QG]) + sum(bus[nzld, QD])) )
326 fd.write('\n')
327 fd.write('\nArea Shunt Inj Branch Series Losses Net Export')
328 fd.write('\n Num MW MVAr Charging MW MVAr MW MVAr')
329 fd.write('\n---- ------ ------ -------- ------ ------ ------ ------')
330 for i in range(len(s_areas)):
331 a = s_areas[i]
332 inzsh = find((bus[:, BUS_AREA] == a) & logical_or(bus[:, GS], bus[:, BS]))
333 ibrch = find((bus[e2i[branch[:, F_BUS].astype(int)], BUS_AREA] == a) & (bus[e2i[branch[:, T_BUS].astype(int)], BUS_AREA] == a) & branch[:, BR_STATUS].astype(bool))
334 in_tie = find((bus[e2i[branch[:, F_BUS].astype(int)], BUS_AREA] != a) & (bus[e2i[branch[:, T_BUS].astype(int)], BUS_AREA] == a) & branch[:, BR_STATUS].astype(bool))
335 out_tie = find((bus[e2i[branch[:, F_BUS].astype(int)], BUS_AREA] == a) & (bus[e2i[branch[:, T_BUS].astype(int)], BUS_AREA] != a) & branch[:, BR_STATUS].astype(bool))
336 fd.write('\n%3d %7.1f %7.1f %7.1f %7.2f %7.2f %7.1f %7.1f' %
337 (a, -sum(bus[inzsh, VM]**2 * bus[inzsh, GS]),
338 sum(bus[inzsh, VM]**2 * bus[inzsh, BS]),
339 sum(fchg[ibrch]) + sum(tchg[ibrch]) + sum(fchg[out_tie]) + sum(tchg[in_tie]),
340 sum(real(loss[ibrch])) + sum(real(loss[r_[in_tie, out_tie]])) / 2,
341 sum(imag(loss[ibrch])) + sum(imag(loss[r_[in_tie, out_tie]])) / 2,
342 sum(branch[in_tie, PT])+sum(branch[out_tie, PF]) - sum(real(loss[r_[in_tie, out_tie]])) / 2,
343 sum(branch[in_tie, QT])+sum(branch[out_tie, QF]) - sum(imag(loss[r_[in_tie, out_tie]])) / 2 ))
344
345 fd.write('\n---- ------ ------ -------- ------ ------ ------ ------')
346 fd.write('\nTot: %7.1f %7.1f %7.1f %7.2f %7.2f - -' %
347 (-sum(bus[nzsh, VM]**2 * bus[nzsh, GS]),
348 sum(bus[nzsh, VM]**2 * bus[nzsh, BS]),
349 sum(fchg) + sum(tchg), sum(real(loss)), sum(imag(loss)) ))
350 fd.write('\n')
351
352
353 if OUT_GEN:
354 if isOPF:
355 genlamP = bus[e2i[gen[:, GEN_BUS].astype(int)], LAM_P]
356 genlamQ = bus[e2i[gen[:, GEN_BUS].astype(int)], LAM_Q]
357
358 fd.write('\n================================================================================')
359 fd.write('\n| Generator Data |')
360 fd.write('\n================================================================================')
361 fd.write('\n Gen Bus Status Pg Qg ')
362 if isOPF: fd.write(' Lambda ($/MVA-hr)')
363 fd.write('\n # # (MW) (MVAr) ')
364 if isOPF: fd.write(' P Q ')
365 fd.write('\n---- ----- ------ -------- --------')
366 if isOPF: fd.write(' -------- --------')
367 for k in range(len(ong)):
368 i = ong[k]
369 fd.write('\n%3d %6d %2d ' % (i, gen[i, GEN_BUS], gen[i, GEN_STATUS]))
370 if (gen[i, GEN_STATUS] > 0) & logical_or(gen[i, PG], gen[i, QG]):
371 fd.write('%10.2f%10.2f' % (gen[i, PG], gen[i, QG]))
372 else:
373 fd.write(' - - ')
374 if isOPF: fd.write('%10.2f%10.2f' % (genlamP[i], genlamQ[i]))
375
376 fd.write('\n -------- --------')
377 fd.write('\n Total: %9.2f%10.2f' % (sum(gen[ong, PG]), sum(gen[ong, QG])))
378 fd.write('\n')
379 if any(onld + 1):
380 fd.write('\n================================================================================')
381 fd.write('\n| Dispatchable Load Data |')
382 fd.write('\n================================================================================')
383 fd.write('\n Gen Bus Status Pd Qd ')
384 if isOPF: fd.write(' Lambda ($/MVA-hr)')
385 fd.write('\n # # (MW) (MVAr) ')
386 if isOPF: fd.write(' P Q ')
387 fd.write('\n---- ----- ------ -------- --------')
388 if isOPF: fd.write(' -------- --------')
389 for k in range(len(onld)):
390 i = onld[k]
391 fd.write('\n%3d %6d %2d ' % (i, gen[i, GEN_BUS], gen[i, GEN_STATUS]))
392 if (gen[i, GEN_STATUS] > 0) & logical_or(gen[i, PG], gen[i, QG]):
393 fd.write('%10.2f%10.2f' % (-gen[i, PG], -gen[i, QG]))
394 else:
395 fd.write(' - - ')
396
397 if isOPF: fd.write('%10.2f%10.2f' % (genlamP[i], genlamQ[i]))
398 fd.write('\n -------- --------')
399 fd.write('\n Total: %9.2f%10.2f' % (-sum(gen[onld, PG]), -sum(gen[onld, QG])))
400 fd.write('\n')
401
402
403 if OUT_BUS:
404 fd.write('\n================================================================================')
405 fd.write('\n| Bus Data |')
406 fd.write('\n================================================================================')
407 fd.write('\n Bus Voltage Generation Load ')
408 if isOPF: fd.write(' Lambda($/MVA-hr)')
409 fd.write('\n # Mag(pu) Ang(deg) P (MW) Q (MVAr) P (MW) Q (MVAr)')
410 if isOPF: fd.write(' P Q ')
411 fd.write('\n----- ------- -------- -------- -------- -------- --------')
412 if isOPF: fd.write(' ------- -------')
413 for i in range(nb):
414 fd.write('\n%5d%7.3f%9.3f' % tuple(bus[i, [BUS_I, VM, VA]]))
415 g = find((gen[:, GEN_STATUS] > 0) & (gen[:, GEN_BUS] == bus[i, BUS_I]) &
416 ~isload(gen))
417 ld = find((gen[:, GEN_STATUS] > 0) & (gen[:, GEN_BUS] == bus[i, BUS_I]) &
418 isload(gen))
419 if any(g + 1):
420 fd.write('%10.2f%10.2f' % (sum(gen[g, PG]), sum(gen[g, QG])))
421 else:
422 fd.write(' - - ')
423
424 if logical_or(bus[i, PD], bus[i, QD]) | any(ld + 1):
425 if any(ld + 1):
426 fd.write('%10.2f*%9.2f*' % (bus[i, PD] - sum(gen[ld, PG]),
427 bus[i, QD] - sum(gen[ld, QG])))
428 else:
429 fd.write('%10.2f%10.2f ' % tuple(bus[i, [PD, QD]]))
430 else:
431 fd.write(' - - ')
432 if isOPF:
433 fd.write('%9.3f' % bus[i, LAM_P])
434 if abs(bus[i, LAM_Q]) > ptol:
435 fd.write('%8.3f' % bus[i, LAM_Q])
436 else:
437 fd.write(' -')
438 fd.write('\n -------- -------- -------- --------')
439 fd.write('\n Total: %9.2f %9.2f %9.2f %9.2f' %
440 (sum(gen[ong, PG]), sum(gen[ong, QG]),
441 sum(bus[nzld, PD]) - sum(gen[onld, PG]),
442 sum(bus[nzld, QD]) - sum(gen[onld, QG])))
443 fd.write('\n')
444
445
446 if OUT_BRANCH:
447 fd.write('\n================================================================================')
448 fd.write('\n| Branch Data |')
449 fd.write('\n================================================================================')
450 fd.write('\nBrnch From To From Bus Injection To Bus Injection Loss (I^2 * Z) ')
451 fd.write('\n # Bus Bus P (MW) Q (MVAr) P (MW) Q (MVAr) P (MW) Q (MVAr)')
452 fd.write('\n----- ----- ----- -------- -------- -------- -------- -------- --------')
453 for i in range(nl):
454 fd.write('\n%4d%7d%7d%10.2f%10.2f%10.2f%10.2f%10.3f%10.2f' %
455 (i, branch[i, F_BUS], branch[i, T_BUS],
456 branch[i, PF], branch[i, QF], branch[i, PT], branch[i, QT],
457 loss[i].real, loss[i].imag))
458 fd.write('\n -------- --------')
459 fd.write('\n Total:%10.3f%10.2f' %
460 (sum(real(loss)), sum(imag(loss))))
461 fd.write('\n')
462
463
464 if isOPF:
465 ctol = ppopt['OPF_VIOLATION']
466
467 if (not isDC) & (OUT_V_LIM == 2 | (OUT_V_LIM == 1 &
468 (any(bus[:, VM] < bus[:, VMIN] + ctol) |
469 any(bus[:, VM] > bus[:, VMAX] - ctol) |
470 any(bus[:, MU_VMIN] > ptol) |
471 any(bus[:, MU_VMAX] > ptol)))):
472 fd.write('\n================================================================================')
473 fd.write('\n| Voltage Constraints |')
474 fd.write('\n================================================================================')
475 fd.write('\nBus # Vmin mu Vmin |V| Vmax Vmax mu')
476 fd.write('\n----- -------- ----- ----- ----- --------')
477 for i in range(nb):
478 if (OUT_V_LIM == 2) | (OUT_V_LIM == 1 &
479 ((bus[i, VM] < bus[i, VMIN] + ctol) |
480 (bus[i, VM] > bus[i, VMAX] - ctol) |
481 (bus[i, MU_VMIN] > ptol) |
482 (bus[i, MU_VMAX] > ptol))):
483 fd.write('\n%5d' % bus[i, BUS_I])
484 if ((bus[i, VM] < bus[i, VMIN] + ctol) |
485 (bus[i, MU_VMIN] > ptol)):
486 fd.write('%10.3f' % bus[i, MU_VMIN])
487 else:
488 fd.write(' - ')
489
490 fd.write('%8.3f%7.3f%7.3f' % tuple(bus[i, [VMIN, VM, VMAX]]))
491 if (bus[i, VM] > bus[i, VMAX] - ctol) | (bus[i, MU_VMAX] > ptol):
492 fd.write('%10.3f' % bus[i, MU_VMAX])
493 else:
494 fd.write(' - ')
495 fd.write('\n')
496
497
498 if (OUT_PG_LIM == 2) | \
499 ((OUT_PG_LIM == 1) & (any(gen[ong, PG] < gen[ong, PMIN] + ctol) |
500 any(gen[ong, PG] > gen[ong, PMAX] - ctol) |
501 any(gen[ong, MU_PMIN] > ptol) |
502 any(gen[ong, MU_PMAX] > ptol))) | \
503 ((not isDC) & ((OUT_QG_LIM == 2) |
504 ((OUT_QG_LIM == 1) & (any(gen[ong, QG] < gen[ong, QMIN] + ctol) |
505 any(gen[ong, QG] > gen[ong, QMAX] - ctol) |
506 any(gen[ong, MU_QMIN] > ptol) |
507 any(gen[ong, MU_QMAX] > ptol))))):
508 fd.write('\n================================================================================')
509 fd.write('\n| Generation Constraints |')
510 fd.write('\n================================================================================')
511
512 if (OUT_PG_LIM == 2) | ((OUT_PG_LIM == 1) &
513 (any(gen[ong, PG] < gen[ong, PMIN] + ctol) |
514 any(gen[ong, PG] > gen[ong, PMAX] - ctol) |
515 any(gen[ong, MU_PMIN] > ptol) |
516 any(gen[ong, MU_PMAX] > ptol))):
517 fd.write('\n Gen Bus Active Power Limits')
518 fd.write('\n # # Pmin mu Pmin Pg Pmax Pmax mu')
519 fd.write('\n---- ----- ------- -------- -------- -------- -------')
520 for k in range(len(ong)):
521 i = ong[k]
522 if (OUT_PG_LIM == 2) | ((OUT_PG_LIM == 1) &
523 ((gen[i, PG] < gen[i, PMIN] + ctol) |
524 (gen[i, PG] > gen[i, PMAX] - ctol) |
525 (gen[i, MU_PMIN] > ptol) | (gen[i, MU_PMAX] > ptol))):
526 fd.write('\n%4d%6d ' % (i, gen[i, GEN_BUS]))
527 if (gen[i, PG] < gen[i, PMIN] + ctol) | (gen[i, MU_PMIN] > ptol):
528 fd.write('%8.3f' % gen[i, MU_PMIN])
529 else:
530 fd.write(' - ')
531 if gen[i, PG]:
532 fd.write('%10.2f%10.2f%10.2f' % tuple(gen[i, [PMIN, PG, PMAX]]))
533 else:
534 fd.write('%10.2f - %10.2f' % tuple(gen[i, [PMIN, PMAX]]))
535 if (gen[i, PG] > gen[i, PMAX] - ctol) | (gen[i, MU_PMAX] > ptol):
536 fd.write('%9.3f' % gen[i, MU_PMAX])
537 else:
538 fd.write(' - ')
539 fd.write('\n')
540
541
542 if (not isDC) & ((OUT_QG_LIM == 2) | ((OUT_QG_LIM == 1) &
543 (any(gen[ong, QG] < gen[ong, QMIN] + ctol) |
544 any(gen[ong, QG] > gen[ong, QMAX] - ctol) |
545 any(gen[ong, MU_QMIN] > ptol) |
546 any(gen[ong, MU_QMAX] > ptol)))):
547 fd.write('\nGen Bus Reactive Power Limits')
548 fd.write('\n # # Qmin mu Qmin Qg Qmax Qmax mu')
549 fd.write('\n--- --- ------- -------- -------- -------- -------')
550 for k in range(len(ong)):
551 i = ong[k]
552 if (OUT_QG_LIM == 2) | ((OUT_QG_LIM == 1) &
553 ((gen[i, QG] < gen[i, QMIN] + ctol) |
554 (gen[i, QG] > gen[i, QMAX] - ctol) |
555 (gen[i, MU_QMIN] > ptol) |
556 (gen[i, MU_QMAX] > ptol))):
557 fd.write('\n%3d%5d' % (i, gen[i, GEN_BUS]))
558 if (gen[i, QG] < gen[i, QMIN] + ctol) | (gen[i, MU_QMIN] > ptol):
559 fd.write('%8.3f' % gen[i, MU_QMIN])
560 else:
561 fd.write(' - ')
562 if gen[i, QG]:
563 fd.write('%10.2f%10.2f%10.2f' % tuple(gen[i, [QMIN, QG, QMAX]]))
564 else:
565 fd.write('%10.2f - %10.2f' % tuple(gen[i, [QMIN, QMAX]]))
566
567 if (gen[i, QG] > gen[i, QMAX] - ctol) | (gen[i, MU_QMAX] > ptol):
568 fd.write('%9.3f' % gen[i, MU_QMAX])
569 else:
570 fd.write(' - ')
571 fd.write('\n')
572
573
574 if (OUT_PG_LIM == 2) | (OUT_QG_LIM == 2) | \
575 ((OUT_PG_LIM == 1) & (any(gen[onld, PG] < gen[onld, PMIN] + ctol) |
576 any(gen[onld, PG] > gen[onld, PMAX] - ctol) |
577 any(gen[onld, MU_PMIN] > ptol) |
578 any(gen[onld, MU_PMAX] > ptol))) | \
579 ((OUT_QG_LIM == 1) & (any(gen[onld, QG] < gen[onld, QMIN] + ctol) |
580 any(gen[onld, QG] > gen[onld, QMAX] - ctol) |
581 any(gen[onld, MU_QMIN] > ptol) |
582 any(gen[onld, MU_QMAX] > ptol))):
583 fd.write('\n================================================================================')
584 fd.write('\n| Dispatchable Load Constraints |')
585 fd.write('\n================================================================================')
586 if (OUT_PG_LIM == 2) | ((OUT_PG_LIM == 1) &
587 (any(gen[onld, PG] < gen[onld, PMIN] + ctol) |
588 any(gen[onld, PG] > gen[onld, PMAX] - ctol) |
589 any(gen[onld, MU_PMIN] > ptol) |
590 any(gen[onld, MU_PMAX] > ptol))):
591 fd.write('\nGen Bus Active Power Limits')
592 fd.write('\n # # Pmin mu Pmin Pg Pmax Pmax mu')
593 fd.write('\n--- --- ------- -------- -------- -------- -------')
594 for k in range(len(onld)):
595 i = onld[k]
596 if (OUT_PG_LIM == 2) | ((OUT_PG_LIM == 1) &
597 ((gen[i, PG] < gen[i, PMIN] + ctol) |
598 (gen[i, PG] > gen[i, PMAX] - ctol) |
599 (gen[i, MU_PMIN] > ptol) |
600 (gen[i, MU_PMAX] > ptol))):
601 fd.write('\n%3d%5d' % (i, gen[i, GEN_BUS]))
602 if (gen[i, PG] < gen[i, PMIN] + ctol) | (gen[i, MU_PMIN] > ptol):
603 fd.write('%8.3f' % gen[i, MU_PMIN])
604 else:
605 fd.write(' - ')
606 if gen[i, PG]:
607 fd.write('%10.2f%10.2f%10.2f' % gen[i, [PMIN, PG, PMAX]])
608 else:
609 fd.write('%10.2f - %10.2f' % gen[i, [PMIN, PMAX]])
610
611 if (gen[i, PG] > gen[i, PMAX] - ctol) | (gen[i, MU_PMAX] > ptol):
612 fd.write('%9.3f' % gen[i, MU_PMAX])
613 else:
614 fd.write(' - ')
615 fd.write('\n')
616
617
618 if (not isDC) & ((OUT_QG_LIM == 2) | ((OUT_QG_LIM == 1) &
619 (any(gen[onld, QG] < gen[onld, QMIN] + ctol) |
620 any(gen[onld, QG] > gen[onld, QMAX] - ctol) |
621 any(gen[onld, MU_QMIN] > ptol) |
622 any(gen[onld, MU_QMAX] > ptol)))):
623 fd.write('\nGen Bus Reactive Power Limits')
624 fd.write('\n # # Qmin mu Qmin Qg Qmax Qmax mu')
625 fd.write('\n--- --- ------- -------- -------- -------- -------')
626 for k in range(len(onld)):
627 i = onld[k]
628 if (OUT_QG_LIM == 2) | ((OUT_QG_LIM == 1) &
629 ((gen[i, QG] < gen[i, QMIN] + ctol) |
630 (gen[i, QG] > gen[i, QMAX] - ctol) |
631 (gen[i, MU_QMIN] > ptol) |
632 (gen[i, MU_QMAX] > ptol))):
633 fd.write('\n%3d%5d' % (i, gen(i, GEN_BUS)))
634 if (gen[i, QG] < gen[i, QMIN] + ctol) | (gen[i, MU_QMIN] > ptol):
635 fd.write('%8.3f' % gen[i, MU_QMIN])
636 else:
637 fd.write(' - ')
638
639 if gen[i, QG]:
640 fd.write('%10.2f%10.2f%10.2f' % gen[i, [QMIN, QG, QMAX]])
641 else:
642 fd.write('%10.2f - %10.2f' % gen[i, [QMIN, QMAX]])
643
644 if (gen[i, QG] > gen[i, QMAX] - ctol) | (gen[i, MU_QMAX] > ptol):
645 fd.write('%9.3f' % gen[i, MU_QMAX])
646 else:
647 fd.write(' - ')
648 fd.write('\n')
649
650
651 if (ppopt['OPF_FLOW_LIM'] == 1) | isDC:
652 Ff = branch[:, PF]
653 Ft = branch[:, PT]
654 str = '\n # Bus Pf mu Pf |Pmax| Pt Pt mu Bus'
655 elif ppopt['OPF_FLOW_LIM'] == 2:
656 Ff = abs( (branch[:, PF] + 1j * branch[:, QF]) / V[e2i[branch[:, F_BUS].astype(int)]] )
657 Ft = abs( (branch[:, PT] + 1j * branch[:, QT]) / V[e2i[branch[:, T_BUS].astype(int)]] )
658 str = '\n # Bus |If| mu |If| |Imax| |It| |It| mu Bus'
659 else:
660 Ff = abs(branch[:, PF] + 1j * branch[:, QF])
661 Ft = abs(branch[:, PT] + 1j * branch[:, QT])
662 str = '\n # Bus |Sf| mu |Sf| |Smax| |St| |St| mu Bus'
663
664 if (OUT_LINE_LIM == 2) | ((OUT_LINE_LIM == 1) &
665 (any((branch[:, RATE_A] != 0) & (abs(Ff) > branch[:, RATE_A] - ctol)) |
666 any((branch[:, RATE_A] != 0) & (abs(Ft) > branch[:, RATE_A] - ctol)) |
667 any(branch[:, MU_SF] > ptol) |
668 any(branch[:, MU_ST] > ptol))):
669 fd.write('\n================================================================================')
670 fd.write('\n| Branch Flow Constraints |')
671 fd.write('\n================================================================================')
672 fd.write('\nBrnch From "From" End Limit "To" End To')
673 fd.write(str)
674 fd.write('\n----- ----- ------- -------- -------- -------- ------- -----')
675 for i in range(nl):
676 if (OUT_LINE_LIM == 2) | ((OUT_LINE_LIM == 1) &
677 (((branch[i, RATE_A] != 0) & (abs(Ff[i]) > branch[i, RATE_A] - ctol)) |
678 ((branch[i, RATE_A] != 0) & (abs(Ft[i]) > branch[i, RATE_A] - ctol)) |
679 (branch[i, MU_SF] > ptol) | (branch[i, MU_ST] > ptol))):
680 fd.write('\n%4d%7d' % (i, branch[i, F_BUS]))
681 if (Ff[i] > branch[i, RATE_A] - ctol) | (branch[i, MU_SF] > ptol):
682 fd.write('%10.3f' % branch[i, MU_SF])
683 else:
684 fd.write(' - ')
685
686 fd.write('%9.2f%10.2f%10.2f' %
687 (Ff[i], branch[i, RATE_A], Ft[i]))
688 if (Ft[i] > branch[i, RATE_A] - ctol) | (branch[i, MU_ST] > ptol):
689 fd.write('%10.3f' % branch[i, MU_ST])
690 else:
691 fd.write(' - ')
692 fd.write('%6d' % branch[i, T_BUS])
693 fd.write('\n')
694
695
696 if have_results_struct & results.has_key('userfcn'):
697 run_userfcn(results["userfcn"], 'printpf', results, fd, ppopt)
698
699
700 if OUT_RAW:
701 fd.write('---------- raw PB::Soln data below ----------\n')
702 fd.write('bus\n')
703 if isOPF:
704 fd.write('%d\t%d\t%g\t%g\t%g\t%g\t%g\t%g\n' %
705 bus[:, [BUS_I, BUS_TYPE, VM, VA, LAM_P, LAM_Q, MU_VMAX, MU_VMIN]].T)
706
707 fd.write('branch\n')
708 fd.write('%d\t%g\t%g\t%g\t%g\t%g\t%g\n' %
709 r_[range(nl), branch[:, [PF, QF, PT, QT, MU_SF, MU_ST]]].T)
710
711 fd.write('gen\n')
712 fd.write('%d\t%g\t%g\t%g\t%d\t%g\t%g\t%g\t%g\n' %
713 r_[range(ng), gen[:, [PG, QG, VG, GEN_STATUS, MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN]]])
714 else:
715 fd.write('%d\t%d\t%f\t%f\t%d\t%d\t%d\t%d\n' %
716 r_[bus[:, [BUS_I, BUS_TYPE, VM, VA]], zeros((nb, 4))])
717
718 fd.write('branch\n')
719 fd.write('%d\t%f\t%f\t%f\t%f\t%d\t%d\n' %
720 r_[range(nl), branch[:, [PF, QF, PT, QT]], zeros((nl, 2))])
721
722 fd.write('gen\n')
723 fd.write('%d\t%f\t%f\t%f\t%d\t%d\t%d\t%d\t%d\n' %
724 r_[range(ng), gen[:, [PG, QG, VG, GEN_STATUS]], zeros((ng, 4))])
725 fd.write('end\n')
726 fd.write('---------- raw PB::Soln data above ----------\n')
727