Package pypower :: Module printpf
[hide private]
[frames] | no frames]

Source Code for Module pypower.printpf

  1  # Copyright (C) 1996-2011 Power System Engineering Research Center (PSERC) 
  2  # Copyright (C) 2011 Richard Lincoln 
  3  # 
  4  # PYPOWER is free software: you can redistribute it and/or modify 
  5  # it under the terms of the GNU General Public License as published 
  6  # by the Free Software Foundation, either version 3 of the License, 
  7  # or (at your option) any later version. 
  8  # 
  9  # PYPOWER is distributed in the hope that it will be useful, 
 10  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 11  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
 12  # GNU General Public License for more details. 
 13  # 
 14  # You should have received a copy of the GNU General Public License 
 15  # along with PYPOWER. If not, see <http://www.gnu.org/licenses/>. 
 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 ##----- initialization ----- 73 ## default arguments 74 if isinstance(baseMVA, dict): 75 have_results_struct = 1 76 results = baseMVA 77 if gen is None: 78 ppopt = ppoption() ## use default options 79 else: 80 ppopt = gen 81 if (ppopt['OUT_ALL'] == 0) and (ppopt['OUT_RAW'] == 0): 82 return ## nothin' to see here, bail out now 83 if bus is None: 84 fd = stdout ## print to stdout by default 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() ## use default options 98 if fd is None: 99 fd = stdout ## print to stdout by default 100 if ppopt['OUT_ALL'] == 0 and ppopt['OUT_RAW'] == 0: 101 return ## nothin' to see here, bail out now 102 103 isOPF = f is not None ## FALSE -> only simple PF data, TRUE -> OPF data 104 105 ## options 106 isDC = ppopt['PF_DC'] ## use DC formulation? 107 OUT_ALL = ppopt['OUT_ALL'] 108 OUT_ANY = OUT_ALL == 1 ## set to true if any pretty output is to be generated 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 ## tolerance for displaying shadow prices 140 141 ## create map of external bus numbers to bus indices 142 i2e = bus[:, BUS_I].astype(int) 143 e2i = zeros(max(i2e) + 1, int) 144 e2i[i2e] = arange(bus.shape[0]) 145 146 ## sizes of things 147 nb = bus.shape[0] ## number of buses 148 nl = branch.shape[0] ## number of branches 149 ng = gen.shape[0] ## number of generators 150 151 ## zero out some data to make printout consistent for DC case 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 ## parameters 158 ties = find(bus[e2i[branch[:, F_BUS].astype(int)], BUS_AREA] != 159 bus[e2i[branch[:, T_BUS].astype(int)], BUS_AREA]) 160 ## area inter-ties 161 tap = ones(nl) ## default tap ratio = 1 for lines 162 xfmr = find(branch[:, TAP]) ## indices of transformers 163 tap[xfmr] = branch[xfmr, TAP] ## include transformer tap ratios 164 tap = tap * exp(1j * pi / 180 * branch[:, SHIFT]) ## add phase shifters 165 nzld = find((bus[:, PD] != 0.0) | (bus[:, QD] != 0.0)) 166 sorted_areas = sort(bus[:, BUS_AREA]) 167 ## area numbers 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) ## out-of-service branches 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 ##----- print the stuff ----- 190 if OUT_ANY: 191 ## convergence & elapsed time 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 ## objective function value 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 ## generator data 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 ## bus data 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 ## branch data 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 ##----- constraint data ----- 464 if isOPF: 465 ctol = ppopt['OPF_VIOLATION'] ## constraint violation tolerance 466 ## voltage constraints 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 ## generator P constraints 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 ## generator Q constraints 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 ## dispatchable load P constraints 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 ## dispatchable load Q constraints 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 ## line flow constraints 651 if (ppopt['OPF_FLOW_LIM'] == 1) | isDC: ## P limit 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: ## |I| limit 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: ## |S| limit 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 ## execute userfcn callbacks for 'printpf' stage 696 if have_results_struct & results.has_key('userfcn'): 697 run_userfcn(results["userfcn"], 'printpf', results, fd, ppopt) 698 699 ## print raw data for Perl database interface 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