0001 function [MVAbase, bus, gen, branch, success, et] = ...
0002 runpf(casedata, mpopt, fname, solvedcase)
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
0074 VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
0075 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0076 TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
0077 ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
0078 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
0079 MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
0080 QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
0081
0082
0083 if nargin < 4
0084 solvedcase = '';
0085 if nargin < 3
0086 fname = '';
0087 if nargin < 2
0088 mpopt = mpoption;
0089 if nargin < 1
0090 casedata = 'case9';
0091 end
0092 end
0093 end
0094 end
0095
0096
0097 qlim = mpopt.pf.enforce_q_lims;
0098 dc = strcmp(upper(mpopt.model), 'DC');
0099
0100
0101 mpc = loadcase(casedata);
0102
0103
0104 if size(mpc.branch,2) < QT
0105 mpc.branch = [ mpc.branch zeros(size(mpc.branch, 1), QT-size(mpc.branch,2)) ];
0106 end
0107
0108
0109 mpc = ext2int(mpc);
0110 [baseMVA, bus, gen, branch] = deal(mpc.baseMVA, mpc.bus, mpc.gen, mpc.branch);
0111
0112
0113 [ref, pv, pq] = bustypes(bus, gen);
0114
0115
0116 on = find(gen(:, GEN_STATUS) > 0);
0117 gbus = gen(on, GEN_BUS);
0118
0119
0120 t0 = clock;
0121 its = 0;
0122 if mpopt.verbose > 0
0123 v = mpver('all');
0124 fprintf('\nMATPOWER Version %s, %s', v.Version, v.Date);
0125 end
0126 if dc
0127 if mpopt.verbose > 0
0128 fprintf(' -- DC Power Flow\n');
0129 end
0130
0131 Va0 = bus(:, VA) * (pi/180);
0132
0133
0134 [B, Bf, Pbusinj, Pfinj] = makeBdc(baseMVA, bus, branch);
0135
0136
0137
0138 Pbus = real(makeSbus(baseMVA, bus, gen)) - Pbusinj - bus(:, GS) / baseMVA;
0139
0140
0141 [Va, success] = dcpf(B, Pbus, Va0, ref, pv, pq);
0142 its = 1;
0143
0144
0145 branch(:, [QF, QT]) = zeros(size(branch, 1), 2);
0146 branch(:, PF) = (Bf * Va + Pfinj) * baseMVA;
0147 branch(:, PT) = -branch(:, PF);
0148 bus(:, VM) = ones(size(bus, 1), 1);
0149 bus(:, VA) = Va * (180/pi);
0150
0151
0152
0153
0154 refgen = zeros(size(ref));
0155 for k = 1:length(ref)
0156 temp = find(gbus == ref(k));
0157 refgen(k) = on(temp(1));
0158 end
0159 gen(refgen, PG) = gen(refgen, PG) + (B(ref, :) * Va - Pbus(ref)) * baseMVA;
0160 else
0161 alg = upper(mpopt.pf.alg);
0162 if mpopt.verbose > 0
0163 switch alg
0164 case 'NR'
0165 solver = 'Newton';
0166 case 'FDXB'
0167 solver = 'fast-decoupled, XB';
0168 case 'FDBX'
0169 solver = 'fast-decoupled, BX';
0170 case 'GS'
0171 solver = 'Gauss-Seidel';
0172 otherwise
0173 solver = 'unknown';
0174 end
0175 fprintf(' -- AC Power Flow (%s)\n', solver);
0176 end
0177
0178
0179 V0 = bus(:, VM) .* exp(sqrt(-1) * pi/180 * bus(:, VA));
0180 vcb = ones(size(V0));
0181 vcb(pq) = 0;
0182 k = find(vcb(gbus));
0183 V0(gbus(k)) = gen(on(k), VG) ./ abs(V0(gbus(k))).* V0(gbus(k));
0184
0185 if qlim
0186 ref0 = ref;
0187 Varef0 = bus(ref0, VA);
0188 limited = [];
0189 fixedQg = zeros(size(gen, 1), 1);
0190 end
0191
0192
0193 [Ybus, Yf, Yt] = makeYbus(baseMVA, bus, branch);
0194
0195 repeat = 1;
0196 while (repeat)
0197
0198
0199 Sbus = @(Vm)makeSbus(baseMVA, bus, gen, mpopt, Vm);
0200
0201
0202 switch alg
0203 case 'NR'
0204 [V, success, iterations] = newtonpf(Ybus, Sbus, V0, ref, pv, pq, mpopt);
0205 case {'FDXB', 'FDBX'}
0206 [Bp, Bpp] = makeB(baseMVA, bus, branch, alg);
0207 [V, success, iterations] = fdpf(Ybus, Sbus, V0, Bp, Bpp, ref, pv, pq, mpopt);
0208 case 'GS'
0209 if (~isempty(mpopt.exp.sys_wide_zip_loads.pw) && ...
0210 any(mpopt.exp.sys_wide_zip_loads.pw(2:3))) || ...
0211 (~isempty(mpopt.exp.sys_wide_zip_loads.qw) && ...
0212 any(mpopt.exp.sys_wide_zip_loads.qw(2:3)))
0213 warning('runpf: Gauss-Seidel algorithm does not support ZIP load model. Converting to constant power loads.')
0214 mpopt = mpoption(mpopt, 'exp.sys_wide_zip_loads', ...
0215 struct('pw', [], 'qw', []));
0216 end
0217 [V, success, iterations] = gausspf(Ybus, Sbus([]), V0, ref, pv, pq, mpopt);
0218 otherwise
0219 error('runpf: Only Newton''s method, fast-decoupled, and Gauss-Seidel power flow algorithms currently implemented.');
0220 end
0221 its = its + iterations;
0222
0223
0224 [bus, gen, branch] = pfsoln(baseMVA, bus, gen, branch, Ybus, Yf, Yt, V, ref, pv, pq, mpopt);
0225
0226 if qlim
0227
0228 mx = find( gen(:, GEN_STATUS) > 0 ...
0229 & gen(:, QG) > gen(:, QMAX) + mpopt.opf.violation );
0230 mn = find( gen(:, GEN_STATUS) > 0 ...
0231 & gen(:, QG) < gen(:, QMIN) - mpopt.opf.violation );
0232
0233 if ~isempty(mx) || ~isempty(mn)
0234
0235 infeas = union(mx', mn')';
0236
0237 remaining = find( gen(:, GEN_STATUS) > 0 & ...
0238 ( bus(gen(:, GEN_BUS), BUS_TYPE) == PV | ...
0239 bus(gen(:, GEN_BUS), BUS_TYPE) == REF ));
0240 if length(infeas) == length(remaining) && all(infeas == remaining) && ...
0241 (isempty(mx) || isempty(mn))
0242
0243
0244 if mpopt.verbose
0245 fprintf('All %d remaining gens exceed their Q limits : INFEASIBLE PROBLEM\n', length(infeas));
0246 end
0247 success = 0;
0248 break;
0249 end
0250
0251
0252 if qlim == 2
0253 [junk, k] = max([gen(mx, QG) - gen(mx, QMAX);
0254 gen(mn, QMIN) - gen(mn, QG)]);
0255 if k > length(mx)
0256 mn = mn(k-length(mx));
0257 mx = [];
0258 else
0259 mx = mx(k);
0260 mn = [];
0261 end
0262 end
0263
0264 if mpopt.verbose && ~isempty(mx)
0265 fprintf('Gen %d at upper Q limit, converting to PQ bus\n', mx);
0266 end
0267 if mpopt.verbose && ~isempty(mn)
0268 fprintf('Gen %d at lower Q limit, converting to PQ bus\n', mn);
0269 end
0270
0271
0272 fixedQg(mx) = gen(mx, QMAX);
0273 fixedQg(mn) = gen(mn, QMIN);
0274 mx = [mx;mn];
0275
0276
0277 gen(mx, QG) = fixedQg(mx);
0278 gen(mx, GEN_STATUS) = 0;
0279 for i = 1:length(mx)
0280 bi = gen(mx(i), GEN_BUS);
0281 bus(bi, [PD,QD]) = ...
0282 bus(bi, [PD,QD]) - gen(mx(i), [PG,QG]);
0283 end
0284 if length(ref) > 1 && any(bus(gen(mx, GEN_BUS), BUS_TYPE) == REF)
0285 error('runpf: Sorry, MATPOWER cannot enforce Q limits for slack buses in systems with multiple slacks.');
0286 end
0287 bus(gen(mx, GEN_BUS), BUS_TYPE) = PQ;
0288
0289
0290 ref_temp = ref;
0291 [ref, pv, pq] = bustypes(bus, gen);
0292
0293
0294
0295 if ref ~= ref_temp
0296 bus(ref, BUS_TYPE) = REF;
0297 bus( pv, BUS_TYPE) = PV;
0298 if mpopt.verbose
0299 fprintf('Bus %d is new slack bus\n', ref);
0300 end
0301 end
0302 limited = [limited; mx];
0303 else
0304 repeat = 0;
0305 end
0306 else
0307 repeat = 0;
0308 end
0309 end
0310 if qlim && ~isempty(limited)
0311
0312 gen(limited, QG) = fixedQg(limited);
0313 for i = 1:length(limited)
0314 bi = gen(limited(i), GEN_BUS);
0315 bus(bi, [PD,QD]) = ...
0316 bus(bi, [PD,QD]) + gen(limited(i), [PG,QG]);
0317 end
0318 gen(limited, GEN_STATUS) = 1;
0319 if ref ~= ref0
0320
0321 bus(:, VA) = bus(:, VA) - bus(ref0, VA) + Varef0;
0322 end
0323 end
0324 end
0325 mpc.et = etime(clock, t0);
0326 mpc.success = success;
0327 mpc.iterations = its;
0328
0329
0330
0331 [mpc.bus, mpc.gen, mpc.branch] = deal(bus, gen, branch);
0332 results = int2ext(mpc);
0333
0334
0335 if ~isempty(results.order.gen.status.off)
0336 results.gen(results.order.gen.status.off, [PG QG]) = 0;
0337 end
0338 if ~isempty(results.order.branch.status.off)
0339 results.branch(results.order.branch.status.off, [PF QF PT QT]) = 0;
0340 end
0341
0342 if fname
0343 [fd, msg] = fopen(fname, 'at');
0344 if fd == -1
0345 error(msg);
0346 else
0347 if mpopt.out.all == 0
0348 printpf(results, fd, mpoption(mpopt, 'out.all', -1));
0349 else
0350 printpf(results, fd, mpopt);
0351 end
0352 fclose(fd);
0353 end
0354 end
0355 printpf(results, 1, mpopt);
0356
0357
0358 if solvedcase
0359 savecase(solvedcase, results);
0360 end
0361
0362 if nargout == 1 || nargout == 2
0363 MVAbase = results;
0364 bus = success;
0365 elseif nargout > 2
0366 [MVAbase, bus, gen, branch, et] = ...
0367 deal(results.baseMVA, results.bus, results.gen, results.branch, results.et);
0368
0369 end