0001 function [results, success, raw] = mipsopf_solver(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
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
0051 VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
0052 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
0053 MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
0054 QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
0055 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0056 TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
0057 ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
0058 [PW_LINEAR, POLYNOMIAL, MODEL, STARTUP, SHUTDOWN, NCOST, COST] = idx_cost;
0059
0060
0061 opt = mpopt.mips;
0062 opt.verbose = mpopt.verbose;
0063 if opt.feastol == 0
0064 opt.feastol = mpopt.opf.violation;
0065 end
0066 if ~isfield(opt, 'cost_mult') || isempty(opt.cost_mult)
0067 opt.cost_mult = 1e-4;
0068 end
0069
0070
0071 mpc = om.get_mpc();
0072 [baseMVA, bus, gen, branch, gencost] = ...
0073 deal(mpc.baseMVA, mpc.bus, mpc.gen, mpc.branch, mpc.gencost);
0074 [vv, ll, nne, nni] = om.get_idx();
0075
0076
0077 nb = size(bus, 1);
0078 nl = size(branch, 1);
0079 ny = om.getN('var', 'y');
0080
0081
0082 [A, l, u] = om.params_lin_constraint();
0083
0084
0085 [x0, xmin, xmax] = om.params_var();
0086
0087
0088 [Ybus, Yf, Yt] = makeYbus(baseMVA, bus, branch);
0089
0090
0091 if mpopt.opf.start < 2
0092 s = 1;
0093 lb = xmin; ub = xmax;
0094 lb(xmin == -Inf) = -1e10;
0095 ub(xmax == Inf) = 1e10;
0096 x0 = (lb + ub) / 2;
0097 k = find(xmin == -Inf & xmax < Inf);
0098 x0(k) = xmax(k) - s;
0099 k = find(xmin > -Inf & xmax == Inf);
0100 x0(k) = xmin(k) + s;
0101 Varefs = bus(bus(:, BUS_TYPE) == REF, VA) * (pi/180);
0102 Vmax = min(bus(:, VMAX), 1.5);
0103 Vmin = max(bus(:, VMIN), 0.5);
0104 Vm = (Vmax + Vmin) / 2;
0105 if mpopt.opf.v_cartesian
0106 V = Vm * exp(1j*Varefs(1));
0107 x0(vv.i1.Vr:vv.iN.Vr) = real(V);
0108 x0(vv.i1.Vi:vv.iN.Vi) = imag(V);
0109 else
0110 x0(vv.i1.Va:vv.iN.Va) = Varefs(1);
0111 x0(vv.i1.Vm:vv.iN.Vm) = Vm;
0112 if ny > 0
0113 ipwl = find(gencost(:, MODEL) == PW_LINEAR);
0114 c = gencost(sub2ind(size(gencost), ipwl, NCOST+2*gencost(ipwl, NCOST)));
0115 x0(vv.i1.y:vv.iN.y) = max(c) + 0.1 * abs(max(c));
0116 end
0117 end
0118 end
0119
0120
0121 il = find(branch(:, RATE_A) ~= 0 & branch(:, RATE_A) < 1e10);
0122 nl2 = length(il);
0123
0124
0125 f_fcn = @(x)opf_costfcn(x, om);
0126 gh_fcn = @(x)opf_consfcn(x, om, Ybus, Yf(il,:), Yt(il,:), mpopt, il);
0127 hess_fcn = @(x, lambda, cost_mult)opf_hessfcn(x, lambda, cost_mult, om, Ybus, Yf(il,:), Yt(il,:), mpopt, il);
0128 [x, f, info, Output, Lambda] = ...
0129 mips(f_fcn, x0, A, l, u, xmin, xmax, gh_fcn, hess_fcn, opt);
0130 success = (info > 0);
0131
0132
0133 if mpopt.opf.v_cartesian
0134 Vi = x(vv.i1.Vi:vv.iN.Vi);
0135 Vr = x(vv.i1.Vr:vv.iN.Vr);
0136 V = Vr + 1j*Vi;
0137 Va = angle(V);
0138 Vm = abs(V);
0139 else
0140 Va = x(vv.i1.Va:vv.iN.Va);
0141 Vm = x(vv.i1.Vm:vv.iN.Vm);
0142 V = Vm .* exp(1j*Va);
0143 end
0144 Pg = x(vv.i1.Pg:vv.iN.Pg);
0145 Qg = x(vv.i1.Qg:vv.iN.Qg);
0146
0147
0148
0149 bus(:, VA) = Va * 180/pi;
0150 bus(:, VM) = Vm;
0151 gen(:, PG) = Pg * baseMVA;
0152 gen(:, QG) = Qg * baseMVA;
0153 gen(:, VG) = Vm(gen(:, GEN_BUS));
0154
0155
0156 Sf = V(branch(:, F_BUS)) .* conj(Yf * V);
0157 St = V(branch(:, T_BUS)) .* conj(Yt * V);
0158 branch(:, PF) = real(Sf) * baseMVA;
0159 branch(:, QF) = imag(Sf) * baseMVA;
0160 branch(:, PT) = real(St) * baseMVA;
0161 branch(:, QT) = imag(St) * baseMVA;
0162
0163
0164
0165 muSf = zeros(nl, 1);
0166 muSt = zeros(nl, 1);
0167 if ~isempty(il)
0168 if upper(mpopt.opf.flow_lim(1)) == 'P'
0169 muSf(il) = Lambda.ineqnonlin(nni.i1.Sf:nni.iN.Sf);
0170 muSt(il) = Lambda.ineqnonlin(nni.i1.St:nni.iN.St);
0171 else
0172 muSf(il) = 2 * Lambda.ineqnonlin(nni.i1.Sf:nni.iN.Sf) .* branch(il, RATE_A) / baseMVA;
0173 muSt(il) = 2 * Lambda.ineqnonlin(nni.i1.St:nni.iN.St) .* branch(il, RATE_A) / baseMVA;
0174 end
0175 end
0176
0177
0178 if mpopt.opf.v_cartesian
0179 if om.userdata.veq
0180 lam = Lambda.eqnonlin(nne.i1.Veq:nne.iN.Veq);
0181 mu_Vmax = zeros(size(lam));
0182 mu_Vmin = zeros(size(lam));
0183 mu_Vmax(lam > 0) = lam(lam > 0);
0184 mu_Vmin(lam < 0) = -lam(lam < 0);
0185 bus(om.userdata.veq, MU_VMAX) = mu_Vmax;
0186 bus(om.userdata.veq, MU_VMIN) = mu_Vmin;
0187 end
0188 bus(om.userdata.viq, MU_VMAX) = Lambda.ineqnonlin(nni.i1.Vmax:nni.iN.Vmax);
0189 bus(om.userdata.viq, MU_VMIN) = Lambda.ineqnonlin(nni.i1.Vmin:nni.iN.Vmin);
0190 else
0191 bus(:, MU_VMAX) = Lambda.upper(vv.i1.Vm:vv.iN.Vm);
0192 bus(:, MU_VMIN) = Lambda.lower(vv.i1.Vm:vv.iN.Vm);
0193 end
0194 gen(:, MU_PMAX) = Lambda.upper(vv.i1.Pg:vv.iN.Pg) / baseMVA;
0195 gen(:, MU_PMIN) = Lambda.lower(vv.i1.Pg:vv.iN.Pg) / baseMVA;
0196 gen(:, MU_QMAX) = Lambda.upper(vv.i1.Qg:vv.iN.Qg) / baseMVA;
0197 gen(:, MU_QMIN) = Lambda.lower(vv.i1.Qg:vv.iN.Qg) / baseMVA;
0198 if mpopt.opf.current_balance
0199
0200
0201
0202
0203
0204
0205 VV = V ./ (V .* conj(V));
0206 VVr = real(VV);
0207 VVi = imag(VV);
0208 lamM = Lambda.eqnonlin(nne.i1.rImis:nne.iN.rImis);
0209 lamN = Lambda.eqnonlin(nne.i1.iImis:nne.iN.iImis);
0210 bus(:, LAM_P) = (VVr.*lamM + VVi.*lamN) / baseMVA;
0211 bus(:, LAM_Q) = (VVi.*lamM - VVr.*lamN) / baseMVA;
0212 else
0213 bus(:, LAM_P) = Lambda.eqnonlin(nne.i1.Pmis:nne.iN.Pmis) / baseMVA;
0214 bus(:, LAM_Q) = Lambda.eqnonlin(nne.i1.Qmis:nne.iN.Qmis) / baseMVA;
0215 end
0216 branch(:, MU_SF) = muSf / baseMVA;
0217 branch(:, MU_ST) = muSt / baseMVA;
0218
0219
0220 nlnN = 2*nb + 2*nl;
0221
0222
0223 kl = find(Lambda.eqnonlin < 0);
0224 ku = find(Lambda.eqnonlin > 0);
0225 nl_mu_l = zeros(nlnN, 1);
0226 nl_mu_u = [zeros(2*nb, 1); muSf; muSt];
0227 nl_mu_l(kl) = -Lambda.eqnonlin(kl);
0228 nl_mu_u(ku) = Lambda.eqnonlin(ku);
0229
0230 if isfield(Lambda, 'ineqnonlin')
0231 lam_nli = Lambda.ineqnonlin;
0232 else
0233 lam_nli = [];
0234 end
0235
0236 mu = struct( ...
0237 'var', struct('l', Lambda.lower, 'u', Lambda.upper), ...
0238 'nln', struct('l', nl_mu_l, 'u', nl_mu_u), ...
0239 'nle', Lambda.eqnonlin, ...
0240 'nli', lam_nli, ...
0241 'lin', struct('l', Lambda.mu_l, 'u', Lambda.mu_u) );
0242
0243 results = mpc;
0244 [results.bus, results.branch, results.gen, ...
0245 results.om, results.x, results.mu, results.f] = ...
0246 deal(bus, branch, gen, om, x, mu, f);
0247
0248 pimul = [ ...
0249 results.mu.nln.l - results.mu.nln.u;
0250 results.mu.lin.l - results.mu.lin.u;
0251 -ones(ny>0, 1);
0252 results.mu.var.l - results.mu.var.u;
0253 ];
0254 raw = struct('xr', x, 'pimul', pimul, 'info', info, 'output', Output);