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

Source Code for Module pypower.savecase

  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  """Saves a PYPOWER case file. 
 18  """ 
 19   
 20  from sys import stderr 
 21   
 22  from os.path import basename 
 23   
 24  from numpy import array, c_, r_, any 
 25  from scipy.io import savemat 
 26   
 27  from run_userfcn import run_userfcn 
 28   
 29  from pypower.idx_bus import MU_VMIN, VMIN 
 30  from pypower.idx_gen import PMIN, MU_PMAX, MU_PMIN, MU_QMIN, MU_QMAX, APF 
 31  from pypower.idx_brch import \ 
 32      MU_ST, MU_SF, BR_STATUS, PF, PT, QT, QF, ANGMAX, MU_ANGMAX 
 33  from pypower.idx_area import PRICE_REF_BUS 
 34  from pypower.idx_cost import MODEL, NCOST, PW_LINEAR, POLYNOMIAL 
 35   
 36   
37 -def savecase(fname, ppc, comment=None, version='2'):
38 """Saves a PYPOWER case file, given a filename and the data. 39 40 Writes a PYPOWER case file, given a filename and data dict. The C{fname} 41 parameter is the name of the file to be created or overwritten. Returns 42 the filename, with extension added if necessary. The optional C{comment} 43 argument is either string (single line comment) or a list of strings which 44 are inserted as comments. When using a PYPOWER case dict, if the 45 optional C{version} argument is '1' it will modify the data matrices to 46 version 1 format before saving. 47 48 @author: Carlos E. Murillo-Sanchez (PSERC Cornell & Universidad 49 Autonoma de Manizales) 50 @author: Ray Zimmerman (PSERC Cornell) 51 @author: Richard Lincoln 52 """ 53 ppc_ver = ppc["version"] = version 54 baseMVA, bus, gen, branch = \ 55 ppc["baseMVA"], ppc["bus"], ppc["gen"], ppc["branch"] 56 areas = ppc["areas"] if "areas" in ppc else None 57 gencost = ppc["gencost"] if "gencost" in ppc else None 58 59 ## modifications for version 1 format 60 if ppc_ver == "1": 61 raise NotImplementedError 62 # ## remove extra columns of gen 63 # if gen.shape[1] >= MU_QMIN: 64 # gen = c_[gen[:, :PMIN], gen[:, MU_PMAX:MU_QMIN]] 65 # else: 66 # gen = gen[:, :PMIN] 67 # ## use the version 1 values for column names 68 # shift = MU_PMAX - PMIN - 1 69 # tmp = array([MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN]) - shift 70 # MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN = tmp 71 # 72 # ## remove extra columns of branch 73 # if branch.shape[1] >= MU_ST: 74 # branch = c_[branch[:, :BR_STATUS], branch[:, PF:MU_ST]] 75 # elif branch.shape[1] >= QT: 76 # branch = c_[branch[:, :BR_STATUS], branch[:, PF:QT]] 77 # else: 78 # branch = branch[:, :BR_STATUS] 79 # ## use the version 1 values for column names 80 # shift = PF - BR_STATUS - 1 81 # tmp = array([PF, QF, PT, QT, MU_SF, MU_ST]) - shift 82 # PF, QF, PT, QT, MU_SF, MU_ST = tmp 83 84 ## verify valid filename 85 l = len(fname) 86 rootname = "" 87 if l > 2: 88 if fname[-3:] == ".py": 89 rootname = fname[:-3] 90 extension = ".py" 91 elif l > 4: 92 if fname[-4:] == ".mat": 93 rootname = fname[:-4] 94 extension = ".mat" 95 96 if not rootname: 97 rootname = fname 98 extension = ".py" 99 fname = rootname + extension 100 101 indent = ' ' # four spaces 102 indent2 = indent + indent 103 104 ## open and write the file 105 if extension == ".mat": ## MAT-file 106 savemat(fname, ppc) 107 else: ## Python file 108 try: 109 fd = open(fname, "wb") 110 except Exception, detail: 111 stderr.write("savecase: %s.\n" % detail) 112 return fname 113 114 ## function header, etc. 115 if ppc_ver == "1": 116 raise NotImplementedError 117 # if (areas != None) and (gencost != None) and (len(gencost) > 0): 118 # fd.write('function [baseMVA, bus, gen, branch, areas, gencost] = %s\n' % rootname) 119 # else: 120 # fd.write('function [baseMVA, bus, gen, branch] = %s\n' % rootname) 121 # prefix = '' 122 else: 123 fd.write('def %s():\n' % basename(rootname)) 124 prefix = 'ppc' 125 if comment: 126 if isinstance(comment, basestring): 127 fd.write('#%s\n' % comment) 128 elif isinstance(comment, list): 129 for c in comment: 130 fd.write('#%s\n' % c) 131 fd.write('\n%s## PYPOWER Case Format : Version %s\n' % (indent, ppc_ver)) 132 if ppc_ver != "1": 133 fd.write("%sppc = {'version': '%s'}\n" % (indent, ppc_ver)) 134 fd.write('\n%s##----- Power Flow Data -----##\n' % indent) 135 fd.write('%s## system MVA base\n' % indent) 136 fd.write("%s%s['baseMVA'] = %g\n" % (indent, prefix, baseMVA)) 137 138 ## bus data 139 ncols = bus.shape[1] 140 fd.write('\n%s## bus data\n' % indent) 141 fd.write('%s# bus_i type Pd Qd Gs Bs area Vm Va baseKV zone Vmax Vmin' % indent) 142 if ncols >= MU_VMIN + 1: ## opf SOLVED, save with lambda's & mu's 143 fd.write('lam_P lam_Q mu_Vmax mu_Vmin') 144 fd.write("\n%s%s['bus'] = array([\n" % (indent, prefix)) 145 if ncols < MU_VMIN + 1: ## opf NOT SOLVED, save without lambda's & mu's 146 for i in range(bus.shape[0]): 147 fd.write('%s[%d, %d, %g, %g, %g, %g, %d, %.8g, %.8g, %g, %d, %g, %g],\n' % ((indent2,) + tuple(bus[i, :VMIN + 1]))) 148 else: ## opf SOLVED, save with lambda's & mu's 149 for i in range(bus.shape[0]): 150 fd.write('%s[%d, %d, %g, %g, %g, %g, %d, %.8g, %.8g, %g, %d, %g, %g, %.4f, %.4f, %.4f, %.4f],\n' % ((indent2,) + tuple(bus[:, :MU_VMIN + 1]))) 151 fd.write('%s])\n' % indent) 152 153 ## generator data 154 ncols = gen.shape[1] 155 fd.write('\n%s## generator data\n' % indent) 156 fd.write('%s# bus Pg Qg Qmax Qmin Vg mBase status Pmax Pmin' % indent) 157 if ppc_ver != "1": 158 fd.write(' Pc1 Pc2 Qc1min Qc1max Qc2min Qc2max ramp_agc ramp_10 ramp_30 ramp_q apf') 159 if ncols >= MU_QMIN + 1: # opf SOLVED, save with mu's 160 fd.write(' mu_Pmax mu_Pmin mu_Qmax mu_Qmin') 161 fd.write("\n%s%s['gen'] = array([\n" % (indent, prefix)) 162 if ncols < MU_QMIN + 1: ## opf NOT SOLVED, save without mu's 163 if ppc_ver == "1": 164 for i in range(gen.shape[0]): 165 fd.write('%s[%d, %g, %g, %g, %g, %.8g, %g, %d, %g, %g],\n' % ((indent2,) + tuple(gen[i, :PMIN + 1]))) 166 else: 167 for i in range(gen.shape[0]): 168 fd.write('%s[%d, %g, %g, %g, %g, %.8g, %g, %d, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g],\n' % ((indent2,) + tuple(gen[i, :APF + 1]))) 169 else: 170 if ppc_ver == "1": 171 for i in range(gen.shape[0]): 172 fd.write('%s[%d, %g, %g, %g, %g, %.8g, %g, %d, %g, %g, %.4f, %.4f, %.4f, %.4f],\n' % ((indent2,) + tuple(gen[i, :MU_QMIN + 1]))) 173 else: 174 for i in range(gen.shape[0]): 175 fd.write('%s[%d, %g, %g, %g, %g, %.8g, %g, %d, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %.4f, %.4f, %.4f, %.4f],\n' % ((indent2,) + tuple(gen[i, :MU_QMIN + 1]))) 176 fd.write('%s])\n' % indent) 177 178 ## branch data 179 ncols = branch.shape[1] 180 fd.write('\n%s## branch data\n' % indent) 181 fd.write('%s# fbus tbus r x b rateA rateB rateC ratio angle status' % indent) 182 if ppc_ver != "1": 183 fd.write(' angmin angmax') 184 if ncols >= QT + 1: ## power flow SOLVED, save with line flows 185 fd.write(' Pf Qf Pt Qt') 186 if ncols >= MU_ST + 1: ## opf SOLVED, save with mu's 187 fd.write(' mu_Sf mu_St') 188 if ppc_ver != "1": 189 fd.write(' mu_angmin mu_angmax') 190 fd.write('\n%s%s[\'branch\'] = array([\n' % (indent, prefix)) 191 if ncols < QT + 1: ## power flow NOT SOLVED, save without line flows or mu's 192 if ppc_ver == "1": 193 for i in range(branch.shape[0]): 194 fd.write('%s[%d, %d, %g, %g, %g, %g, %g, %g, %g, %g, %d],\n' % ((indent2,) + tuple(branch[i, :BR_STATUS + 1]))) 195 else: 196 for i in range(branch.shape[0]): 197 fd.write('%s[%d, %d, %g, %g, %g, %g, %g, %g, %g, %g, %d, %g, %g],\n' % ((indent2,) + tuple(branch[i, :ANGMAX + 1]))) 198 elif ncols < MU_ST + 1: ## power flow SOLVED, save with line flows but without mu's 199 if ppc_ver == "1": 200 for i in range(branch.shape[0]): 201 fd.write('%s[%d, %d, %g, %g, %g, %g, %g, %g, %g, %g, %d, %.4f, %.4f, %.4f, %.4f],\n' % ((indent2,) + tuple(branch[i, :QT + 1]))) 202 else: 203 for i in range(branch.shape[0]): 204 fd.write('%s[%d, %d, %g, %g, %g, %g, %g, %g, %g, %g, %d, %g, %g, %.4f, %.4f, %.4f, %.4f],\n' % ((indent2,) + tuple(branch[i, :QT + 1]))) 205 else: ## opf SOLVED, save with lineflows & mu's 206 if ppc_ver == "1": 207 for i in range(branch.shape[0]): 208 fd.write('%s[%d, %d, %g, %g, %g, %g, %g, %g, %g, %g, %d, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f],\n' % ((indent2,) + tuple(branch[i, :MU_ST + 1]))) 209 else: 210 for i in range(branch.shape[0]): 211 fd.write('%s[%d, %d, %g, %g, %g, %g, %g, %g, %g, %g, %d, %g, %g, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f, %.4f],\n' % ((indent2,) + tuple(branch[i, :MU_ANGMAX + 1]))) 212 fd.write('%s])\n' % indent) 213 214 ## OPF data 215 if (areas != None) and (len(areas) > 0) or (gencost != None) and (len(gencost) > 0): 216 fd.write('\n%s##----- OPF Data -----##' % indent) 217 if (areas != None) and (len(areas) > 0): 218 ## area data 219 fd.write('\n%s## area data\n' % indent) 220 fd.write('%s# area refbus\n' % indent) 221 fd.write("%s%s['areas'] = array([\n" % (indent, prefix)) 222 if len(areas) > 0: 223 for i in range(areas.shape[0]): 224 fd.write('%s[%d, %d],\n' % ((indent2,) + tuple(areas[i, :PRICE_REF_BUS + 1]))) 225 fd.write('%s])\n' % indent) 226 if gencost != None and len(gencost) > 0: 227 ## generator cost data 228 fd.write('\n%s## generator cost data\n' % indent) 229 fd.write('%s# 1 startup shutdown n x1 y1 ... xn yn\n' % indent) 230 fd.write('%s# 2 startup shutdown n c(n-1) ... c0\n' % indent) 231 fd.write('%s%s[\'gencost\'] = array([\n' % (indent, prefix)) 232 if len(gencost > 0): 233 if any(gencost[:, MODEL] == PW_LINEAR): 234 n1 = 2 * max(gencost[gencost[:, MODEL] == PW_LINEAR, NCOST]) 235 else: 236 n1 = 0 237 if any(gencost[:, MODEL] == POLYNOMIAL): 238 n2 = max(gencost[gencost[:, MODEL] == POLYNOMIAL, NCOST]) 239 else: 240 n2 = 0 241 n = int( max([n1, n2]) ) 242 if gencost.shape[1] < n + 4: 243 stderr.write('savecase: gencost data claims it has more columns than it does\n') 244 template = '%s[%d, %g, %g, %d' 245 for i in range(n): 246 template = template + ', %g' 247 template = template + '],\n' 248 for i in range(gencost.shape[0]): 249 fd.write(template % ((indent2,) + tuple(gencost[i]))) 250 fd.write('%s])\n' % indent) 251 252 ## generalized OPF user data 253 if ("A" in ppc) and (len(ppc["A"]) > 0) or ("N" in ppc) and (len(ppc["N"]) > 0): 254 fd.write('\n%s##----- Generalized OPF User Data -----##' % indent) 255 256 ## user constraints 257 if ("A" in ppc) and (len(ppc["A"]) > 0): 258 ## A 259 fd.write('\n%s## user constraints\n' % indent) 260 print_sparse(fd, prefix + "['A']", ppc["A"]) 261 if ("l" in ppc) and (len(ppc["l"]) > 0) and ("u" in ppc) and (len(ppc["u"]) > 0): 262 fd.write('%slu = array([\n' % indent) 263 for i in range(len(l)): 264 fd.write('%s[%g, %g],\n' % (indent2, ppc["l"][i], ppc["u"][i])) 265 fd.write('%s])\n' % indent) 266 fd.write("%s%s['l'] = lu[:, 0]\n" % (indent, prefix)) 267 fd.write("%s%s['u'] = lu[:, 1]\n\n" % (indent, prefix)) 268 elif ("l" in ppc) and (len(ppc["l"]) > 0): 269 fd.write("%s%s['l'] = array([\n" % (indent, prefix)) 270 for i in range(len(l)): 271 fd.write('%s[%g],\n' % (indent2, ppc["l"][i])) 272 fd.write('%s])\n\n' % indent) 273 elif ("u" in ppc) and (len(ppc["u"]) > 0): 274 fd.write("%s%s['u'] = array([\n" % (indent, prefix)) 275 for i in range(len(l)): 276 fd.write('%s[%g],\n' % (indent2, ppc["u"][i])) 277 fd.write('%s])\n\n' % indent) 278 279 ## user costs 280 if ("N" in ppc) and (len(ppc["N"]) > 0): 281 fd.write('\n%s## user costs\n' % indent) 282 print_sparse(fd, prefix + "['N']", ppc["N"]) 283 if ("H" in ppc) and (len(ppc["H"]) > 0): 284 print_sparse(fd, prefix + "['H']", ppc["H"]) 285 if ("fparm" in ppc) and (len(ppc["fparm"]) > 0): 286 fd.write("%sCw_fparm = array([\n" % indent) 287 for i in range(ppc["Cw"]): 288 fd.write('%s[%g, %d, %g, %g, %g],\n' % ((indent2,) + tuple(ppc["Cw"][i]) + tuple(ppc["fparm"][i, :]))) 289 fd.write('%s])\n' % indent) 290 fd.write('%s%s[\'Cw\'] = Cw_fparm[:, 0]\n' % (indent, prefix)) 291 fd.write("%s%s['fparm'] = Cw_fparm[:, 1:5]\n" % (indent, prefix)) 292 else: 293 fd.write("%s%s['Cw'] = array([\n" % (indent, prefix)) 294 for i in range(len(ppc["Cw"])): 295 fd.write('%s[%g],\n' % (indent2, ppc["Cw"][i])) 296 fd.write('%s])\n' % indent) 297 298 ## user vars 299 if ('z0' in ppc) or ('zl' in ppc) or ('zu' in ppc): 300 fd.write('\n%s## user vars\n' % indent) 301 if ('z0' in ppc) and (len(ppc['z0']) > 0): 302 fd.write('%s%s["z0"] = array([\n' % (indent, prefix)) 303 for i in range(len(ppc['z0'])): 304 fd.write('%s[%g],\n' % (indent2, ppc["z0"])) 305 fd.write('%s])\n' % indent) 306 if ('zl' in ppc) and (len(ppc['zl']) > 0): 307 fd.write('%s%s["zl"] = array([\n' % (indent2, prefix)) 308 for i in range(len(ppc['zl'])): 309 fd.write('%s[%g],\n' % (indent2, ppc["zl"])) 310 fd.write('%s])\n' % indent) 311 if ('zu' in ppc) and (len(ppc['zu']) > 0): 312 fd.write('%s%s["zu"] = array([\n' % (indent, prefix)) 313 for i in range(len(ppc['zu'])): 314 fd.write('%s[%g],\n' % (indent2, ppc["zu"])) 315 fd.write('%s])\n' % indent) 316 317 ## execute userfcn callbacks for 'savecase' stage 318 if 'userfcn' in ppc: 319 run_userfcn(ppc["userfcn"], 'savecase', ppc, fd, prefix) 320 321 fd.write('\n%sreturn ppc\n' % indent) 322 323 ## close file 324 fd.close() 325 326 return fname
327 328 343