0001 function [results, success, raw] = opf_execute(om, mpopt)
0002
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 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
0041 VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
0042 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
0043 MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
0044 QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
0045 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0046 TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
0047 ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
0048
0049
0050
0051 dc = mpopt(10);
0052 alg = mpopt(11);
0053 verbose = mpopt(31);
0054
0055
0056 om = build_cost_params(om);
0057
0058
0059 [vv, ll, nn] = get_idx(om);
0060
0061 if verbose > 0
0062 v = mpver('all');
0063 fprintf('\nMATPOWER Version %s, %s', v.Version, v.Date);
0064 end
0065
0066
0067 if dc
0068 if verbose > 0
0069 fprintf(' -- DC Optimal Power Flow\n');
0070 end
0071 [results, success, raw] = dcopf_solver(om, mpopt);
0072 else
0073
0074 if verbose > 0
0075 fprintf(' -- AC Optimal Power Flow\n');
0076 end
0077
0078
0079 if alg == 0
0080 if have_fcn('pdipmopf')
0081 alg = 540;
0082 else
0083 alg = 560;
0084 end
0085 end
0086
0087
0088 if alg == 100 || alg == 200
0089 alg = 300;
0090 elseif alg == 120 || alg == 220
0091 alg = 320;
0092 elseif alg == 140 || alg == 240
0093 alg = 340;
0094 elseif alg == 160 || alg == 260
0095 alg = 360;
0096 end
0097 mpopt(11) = alg;
0098
0099
0100 if alg == 560 || alg == 565
0101 if have_fcn('anon_fcns')
0102 solver = @mipsopf_solver;
0103 else
0104 solver = @mips6opf_solver;
0105 end
0106 [results, success, raw] = feval(solver, om, mpopt);
0107 elseif alg == 580
0108 if ~have_fcn('ipopt')
0109 error('opf_execute: OPF_ALG %d requires IPOPT (see https://projects.coin-or.org/Ipopt/)', alg);
0110 end
0111 [results, success, raw] = ipoptopf_solver(om, mpopt);
0112 elseif alg == 540 || alg == 545 || alg == 550
0113 if alg == 540
0114 if ~have_fcn('pdipmopf')
0115 error('opf_execute: OPF_ALG %d requires PDIPMOPF (see http://www.pserc.cornell.edu/tspopf/)', alg);
0116 end
0117 elseif alg == 545
0118 if ~have_fcn('scpdipmopf')
0119 error('opf_execute: OPF_ALG %d requires SCPDIPMOPF (see http://www.pserc.cornell.edu/tspopf/)', alg);
0120 end
0121 elseif alg == 550
0122 if ~have_fcn('tralmopf')
0123 error('opf_execute: OPF_ALG %d requires TRALM (see http://www.pserc.cornell.edu/tspopf/)', alg);
0124 end
0125 end
0126 [results, success, raw] = tspopf_solver(om, mpopt);
0127 elseif alg == 500
0128 if ~have_fcn('minopf')
0129 error('opf_execute: OPF_ALG %d requires MINOPF (see http://www.pserc.cornell.edu/minopf/)', alg);
0130 end
0131 [results, success, raw] = mopf_solver(om, mpopt);
0132 elseif alg == 520
0133 if ~have_fcn('fmincon')
0134 error('opf_execute: OPF_ALG %d requires FMINCON (Optimization Toolbox 2.x or later)', alg);
0135 end
0136 if have_fcn('anon_fcns')
0137 solver = @fmincopf_solver;
0138 else
0139 solver = @fmincopf6_solver;
0140 end
0141 [results, success, raw] = feval(solver, om, mpopt);
0142 elseif alg == 300
0143 if ~have_fcn('constr')
0144 error('opf_execute: OPF_ALG %d requires CONSTR (Optimization Toolbox 1.x)', alg);
0145 end
0146 [results, success, raw] = copf_solver(om, mpopt);
0147 elseif alg == 320 || alg == 340 || alg == 360
0148 [results, success, raw] = lpopf_solver(om, mpopt);
0149 else
0150 error('opf_execute: OPF_ALG %d is not a valid algorithm code', alg);
0151 end
0152 end
0153 if ~isfield(raw, 'output') || ~isfield(raw.output, 'alg') || isempty(raw.output.alg)
0154 raw.output.alg = alg;
0155 end
0156
0157 if success
0158 if ~dc
0159
0160 results.gen(:, VG) = results.bus(results.gen(:, GEN_BUS), VM);
0161
0162
0163 if ll.N.PQh > 0 || ll.N.PQl > 0
0164 mu_PQh = results.mu.lin.l(ll.i1.PQh:ll.iN.PQh) - results.mu.lin.u(ll.i1.PQh:ll.iN.PQh);
0165 mu_PQl = results.mu.lin.l(ll.i1.PQl:ll.iN.PQl) - results.mu.lin.u(ll.i1.PQl:ll.iN.PQl);
0166 Apqdata = userdata(om, 'Apqdata');
0167 results.gen = update_mupq(results.baseMVA, results.gen, mu_PQh, mu_PQl, Apqdata);
0168 end
0169
0170
0171 if mpopt(52)
0172
0173 if isfield(results, 'dg')
0174 raw.dg = results.dg;
0175 raw.g = results.g;
0176 end
0177
0178 if ~isfield(raw, 'dg')
0179 mpc = get_mpc(om);
0180 [Ybus, Yf, Yt] = makeYbus(mpc.baseMVA, mpc.bus, mpc.branch);
0181 [g, geq, dg, dgeq] = opf_consfcn(results.x, om, Ybus, Yf, Yt, mpopt);
0182 raw.g = [ geq; g];
0183 raw.dg = [ dgeq'; dg'];
0184 end
0185
0186 [f, df, d2f] = opf_costfcn(results.x, om);
0187 raw.df = df;
0188 raw.d2f = d2f;
0189 end
0190 end
0191
0192
0193 if isfield(results, 'dg')
0194 rmfield(results, 'dg');
0195 rmfield(results, 'g');
0196 end
0197
0198
0199 if ll.N.ang > 0
0200 iang = userdata(om, 'iang');
0201 results.branch(iang, MU_ANGMIN) = results.mu.lin.l(ll.i1.ang:ll.iN.ang) * pi/180;
0202 results.branch(iang, MU_ANGMAX) = results.mu.lin.u(ll.i1.ang:ll.iN.ang) * pi/180;
0203 end
0204 else
0205
0206 if ~dc && mpopt(52)
0207 raw.dg = [];
0208 raw.g = [];
0209 raw.df = [];
0210 raw.d2f = [];
0211 end
0212 end
0213
0214
0215 om_var_order = get(om, 'var', 'order');
0216 for k = 1:length(om_var_order)
0217 name = om_var_order{k};
0218 if getN(om, 'var', name)
0219 idx = vv.i1.(name):vv.iN.(name);
0220 results.var.val.(name) = results.x(idx);
0221 results.var.mu.l.(name) = results.mu.var.l(idx);
0222 results.var.mu.u.(name) = results.mu.var.u(idx);
0223 end
0224 end
0225
0226
0227 om_lin_order = get(om, 'lin', 'order');
0228 for k = 1:length(om_lin_order)
0229 name = om_lin_order{k};
0230 if getN(om, 'lin', name)
0231 idx = ll.i1.(name):ll.iN.(name);
0232 results.lin.mu.l.(name) = results.mu.lin.l(idx);
0233 results.lin.mu.u.(name) = results.mu.lin.u(idx);
0234 end
0235 end
0236
0237
0238 if ~dc
0239 om_nln_order = get(om, 'nln', 'order');
0240 for k = 1:length(om_nln_order)
0241 name = om_nln_order{k};
0242 if getN(om, 'nln', name)
0243 idx = nn.i1.(name):nn.iN.(name);
0244 results.nln.mu.l.(name) = results.mu.nln.l(idx);
0245 results.nln.mu.u.(name) = results.mu.nln.u(idx);
0246 end
0247 end
0248 end
0249
0250
0251 om_cost_order = get(om, 'cost', 'order');
0252 for k = 1:length(om_cost_order)
0253 name = om_cost_order{k};
0254 if getN(om, 'cost', name)
0255 results.cost.(name) = compute_cost(om, results.x, name);
0256 end
0257 end
0258
0259
0260
0261
0262 pwl1 = userdata(om, 'pwl1');
0263 if ~isempty(pwl1) && alg ~= 545 && alg ~= 550
0264
0265 vv = get_idx(om);
0266 if dc
0267 nx = vv.iN.Pg;
0268 else
0269 nx = vv.iN.Qg;
0270 end
0271 y = zeros(length(pwl1), 1);
0272 raw.xr = [ raw.xr(1:nx); y; raw.xr(nx+1:end)];
0273 results.x = [ results.x(1:nx); y; results.x(nx+1:end)];
0274 end
0275