1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 """Constructs an OPF model object from a PYPOWER case dict.
18 """
19
20 from sys import stdout, stderr
21
22 from numpy import array, any, delete, unique, arange, nonzero, pi, \
23 r_, ones, Inf
24 from numpy import flatnonzero as find
25
26 from scipy.sparse import hstack, csr_matrix as sparse
27
28 from pypower.pqcost import pqcost
29 from pypower.opf_args import opf_args
30 from pypower.makeBdc import makeBdc
31 from pypower.makeAvl import makeAvl
32 from pypower.makeApq import makeApq
33 from pypower.makeAang import makeAang
34 from pypower.makeAy import makeAy
35 from pypower.opf_model import opf_model
36 from pypower.run_userfcn import run_userfcn
37
38 from pypower.idx_cost import MODEL, NCOST, PW_LINEAR, COST, POLYNOMIAL
39 from pypower.idx_bus import BUS_TYPE, REF, VA, VM, PD, GS, VMAX, VMIN
40 from pypower.idx_gen import GEN_BUS, VG, PG, QG, PMAX, PMIN, QMAX, QMIN
41 from pypower.idx_brch import RATE_A
42
43
45 """Constructs an OPF model object from a PYPOWER case dict.
46
47 Assumes that ppc is a PYPOWER case dict with internal indexing,
48 all equipment in-service, etc.
49
50 @see: L{opf}, L{ext2int}, L{opf_execute}
51
52 @author: Ray Zimmerman (PSERC Cornell)
53 @author: Carlos E. Murillo-Sanchez (PSERC Cornell & Universidad
54 Autonoma de Manizales)
55 @author: Richard Lincoln
56 """
57
58 dc = ppopt['PF_DC']
59 alg = ppopt['OPF_ALG']
60 verbose = ppopt['VERBOSE']
61
62
63 nb = ppc['bus'].shape[0]
64 nl = ppc['branch'].shape[0]
65 ng = ppc['gen'].shape[0]
66 if 'A' in ppc:
67 nusr = ppc['A'].shape[0]
68 else:
69 nusr = 0
70
71 if 'N' in ppc:
72 nw = ppc['N'].shape[0]
73 else:
74 nw = 0
75
76 if dc:
77
78 ppc['gencost'], _ = pqcost(ppc['gencost'], ng)
79
80
81 if nusr or nw:
82 acc = r_[nb + arange(nb), 2 * nb + ng + arange(ng)]
83
84 if nusr and (ppc['A'].shape[1] >= 2*nb + 2*ng):
85
86 if ppc['A'][:, acc].nnz > 0:
87 stderr.write('opf_setup: attempting to solve DC OPF with user constraints on Vm or Qg\n')
88
89
90 bcc = delete(arange(ppc['A'].shape[1]), acc)
91 ppc['A'] = ppc['A'].tolil()[:, bcc].tocsr()
92
93 if nw and (ppc['N'].shape[1] >= 2*nb + 2*ng):
94
95 if ppc['N'][:, acc].nnz > 0:
96 ii, _ = nonzero(ppc['N'][:, acc])
97 _, ii = unique(ii, return_index=True)
98 if any(ppc['Cw'][ii]) | ( ('H' in ppc) & (len(ppc['H']) > 0) &
99 any(any(ppc['H'][:, ii])) ):
100 stderr.write('opf_setup: attempting to solve DC OPF with user costs on Vm or Qg\n')
101
102
103 bcc = delete(arange(ppc['N'].shape[1]), acc)
104 ppc['N'] = ppc['N'].tolil()[:, bcc].tocsr()
105
106
107 pwl1 = find((ppc['gencost'][:, MODEL] == PW_LINEAR) & (ppc['gencost'][:, NCOST] == 2))
108
109 if len(pwl1) > 0:
110 x0 = ppc['gencost'][pwl1, COST]
111 y0 = ppc['gencost'][pwl1, COST + 1]
112 x1 = ppc['gencost'][pwl1, COST + 2]
113 y1 = ppc['gencost'][pwl1, COST + 3]
114 m = (y1 - y0) / (x1 - x0)
115 b = y0 - m * x0
116 ppc['gencost'][pwl1, MODEL] = POLYNOMIAL
117 ppc['gencost'][pwl1, NCOST] = 2
118 ppc['gencost'][pwl1, COST:COST + 2] = r_[m, b]
119
120
121 baseMVA, bus, gen, branch, gencost, _, lbu, ubu, ppopt, \
122 _, fparm, H, Cw, z0, zl, zu, userfcn, _ = opf_args(ppc, ppopt)
123
124
125 refs = find(bus[:, BUS_TYPE] == REF)
126 if len(refs) > 1 and verbose > 0:
127 errstr = '\nopf_setup: Warning: Multiple reference buses.\n' + \
128 ' For a system with islands, a reference bus in each island\n' + \
129 ' may help convergence, but in a fully connected system such\n' + \
130 ' a situation is probably not reasonable.\n\n'
131 stdout.write(errstr)
132
133
134 gbus = gen[:, GEN_BUS].astype(int)
135 Va = bus[:, VA] * (pi / 180.0)
136 Vm = bus[:, VM].copy()
137 Vm[gbus] = gen[:, VG]
138 Pg = gen[:, PG] / baseMVA
139 Qg = gen[:, QG] / baseMVA
140 Pmin = gen[:, PMIN] / baseMVA
141 Pmax = gen[:, PMAX] / baseMVA
142 Qmin = gen[:, QMIN] / baseMVA
143 Qmax = gen[:, QMAX] / baseMVA
144
145 if dc:
146
147 nv = 0
148 nq = 0
149 q1 = array([])
150
151
152 B, Bf, Pbusinj, Pfinj = makeBdc(baseMVA, bus, branch)
153 neg_Cg = sparse((-ones(ng), (gen[:, GEN_BUS], arange(ng))), (nb, ng))
154 Amis = hstack([B, neg_Cg], 'csr')
155 bmis = -(bus[:, PD] + bus[:, GS]) / baseMVA - Pbusinj
156
157
158 il = find((branch[:, RATE_A] != 0) & (branch[:, RATE_A] < 1e10))
159 nl2 = len(il)
160 lpf = -Inf * ones(nl2)
161 upf = branch[il, RATE_A] / baseMVA - Pfinj[il]
162 upt = branch[il, RATE_A] / baseMVA + Pfinj[il]
163
164 user_vars = ['Va', 'Pg']
165 ycon_vars = ['Pg', 'y']
166 else:
167
168 nv = nb
169 nq = ng
170 q1 = ng
171
172
173 Avl, lvl, uvl, _ = makeAvl(baseMVA, gen)
174
175
176 Apqh, ubpqh, Apql, ubpql, Apqdata = makeApq(baseMVA, gen)
177
178 user_vars = ['Va', 'Vm', 'Pg', 'Qg']
179 ycon_vars = ['Pg', 'Qg', 'y']
180
181
182 Vau = Inf * ones(nb)
183 Val = -Vau
184 Vau[refs] = Va[refs]
185 Val[refs] = Va[refs]
186
187
188 Aang, lang, uang, iang = makeAang(baseMVA, branch, nb, ppopt)
189
190
191 if alg == 545 or alg == 550:
192 ny = 0
193 Ay = None
194 by = array([])
195 else:
196 ipwl = find(gencost[:, MODEL] == PW_LINEAR)
197 ny = ipwl.shape[0]
198 Ay, by = makeAy(baseMVA, ng, gencost, 1, q1, 1+ng+nq)
199
200 if any((gencost[:, MODEL] != POLYNOMIAL) & (gencost[:, MODEL] != PW_LINEAR)):
201 stderr.write('opf_setup: some generator cost rows have invalid MODEL value\n')
202
203
204 nx = nb+nv + ng+nq;
205 if nusr:
206 nz = ppc['A'].shape[1] - nx
207 if nz < 0:
208 stderr.write('opf_setup: user supplied A matrix must have at least %d columns.\n' % nx)
209 else:
210 nz = 0
211 if nw:
212 if ppc['N'].shape[1] != nx:
213 stderr.write('opf_setup: user supplied N matrix must have %d columns.\n' % nx)
214
215
216 om = opf_model(ppc)
217 if len(pwl1) > 0:
218 om.userdata('pwl1', pwl1)
219
220 if dc:
221 om.userdata('Bf', Bf)
222 om.userdata('Pfinj', Pfinj)
223 om.userdata('iang', iang)
224 om.add_vars('Va', nb, Va, Val, Vau)
225 om.add_vars('Pg', ng, Pg, Pmin, Pmax)
226 om.add_constraints('Pmis', Amis, bmis, bmis, ['Va', 'Pg'])
227 om.add_constraints('Pf', Bf[il, :], lpf, upf, ['Va'])
228 om.add_constraints('Pt', -Bf[il, :], lpf, upt, ['Va'])
229 om.add_constraints('ang', Aang, lang, uang, ['Va'])
230 else:
231 om.userdata('Apqdata', Apqdata)
232 om.userdata('iang', iang)
233 om.add_vars('Va', nb, Va, Val, Vau)
234 om.add_vars('Vm', nb, Vm, bus[:, VMIN], bus[:, VMAX])
235 om.add_vars('Pg', ng, Pg, Pmin, Pmax)
236 om.add_vars('Qg', ng, Qg, Qmin, Qmax)
237 om.add_constraints('Pmis', nb, 'nonlinear')
238 om.add_constraints('Qmis', nb, 'nonlinear')
239 om.add_constraints('Sf', nl, 'nonlinear')
240 om.add_constraints('St', nl, 'nonlinear')
241 om.add_constraints('PQh', Apqh, array([]), ubpqh, ['Pg', 'Qg'])
242 om.add_constraints('PQl', Apql, array([]), ubpql, ['Pg', 'Qg'])
243 om.add_constraints('vl', Avl, lvl, uvl, ['Pg', 'Qg'])
244 om.add_constraints('ang', Aang, lang, uang, ['Va'])
245
246
247 if ny > 0:
248 om.add_vars('y', ny)
249 om.add_constraints('ycon', Ay, array([]), by, ycon_vars)
250
251
252 if nz > 0:
253 om.add_vars('z', nz, z0, zl, zu)
254 user_vars.append('z')
255
256 if nusr:
257 om.add_constraints('usr', ppc['A'], lbu, ubu, user_vars)
258
259 if nw:
260 user_cost = {}
261 user_cost['N'] = ppc['N']
262 user_cost['Cw'] = Cw
263 if len(fparm) > 0:
264 user_cost['dd'] = fparm[:, 0]
265 user_cost['rh'] = fparm[:, 1]
266 user_cost['kk'] = fparm[:, 2]
267 user_cost['mm'] = fparm[:, 3]
268
269
270 user_cost['H'] = H
271
272 om.add_costs('usr', user_cost, user_vars)
273
274
275 run_userfcn(userfcn, 'formulation', om)
276
277 return om
278