0001 function [results, success, raw] = fmincopf_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
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
0070 VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
0071 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
0072 MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
0073 QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
0074 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0075 TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
0076 ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
0077
0078
0079 verbose = mpopt(31);
0080
0081
0082 mpc = get_mpc(om);
0083 [baseMVA, bus, gen, branch] = ...
0084 deal(mpc.baseMVA, mpc.bus, mpc.gen, mpc.branch);
0085 [vv, ll, nn] = get_idx(om);
0086
0087
0088 nb = size(bus, 1);
0089 nl = size(branch, 1);
0090 ny = getN(om, 'var', 'y');
0091
0092
0093 [x0, LB, UB] = getv(om);
0094
0095
0096 [A, l, u] = linear_constraints(om);
0097
0098
0099
0100 ieq = find( abs(u-l) <= eps );
0101 igt = find( u >= 1e10 & l > -1e10 );
0102 ilt = find( l <= -1e10 & u < 1e10 );
0103 ibx = find( (abs(u-l) > eps) & (u < 1e10) & (l > -1e10) );
0104 Af = [ A(ilt, :); -A(igt, :); A(ibx, :); -A(ibx, :) ];
0105 bf = [ u(ilt); -l(igt); u(ibx); -l(ibx)];
0106 Afeq = A(ieq, :);
0107 bfeq = u(ieq);
0108
0109
0110 [Ybus, Yf, Yt] = makeYbus(baseMVA, bus, branch);
0111
0112
0113 il = find(branch(:, RATE_A) ~= 0 & branch(:, RATE_A) < 1e10);
0114 nl2 = length(il);
0115
0116
0117 fmoptions = optimset('GradObj', 'on', 'GradConstr', 'on', ...
0118 'TolCon', mpopt(16), 'TolX', mpopt(17), 'TolFun', mpopt(18) );
0119 if mpopt(19) ~= 0
0120 fmoptions = optimset(fmoptions, 'MaxIter', mpopt(19), ...
0121 'MaxFunEvals', 4 * mpopt(19));
0122 end
0123
0124 if verbose == 0,
0125 fmoptions.Display = 'off';
0126 elseif verbose == 1
0127 fmoptions.Display = 'iter';
0128 else
0129 fmoptions.Display = 'testing';
0130 end
0131
0132
0133 otver = ver('optim');
0134 if str2double(otver.Version(1)) < 4
0135 fmoptions = optimset(fmoptions, 'LargeScale', 'off');
0136 Af = full(Af);
0137 Afeq = full(Afeq);
0138 else
0139 if mpopt(55) == 1
0140 fmoptions = optimset(fmoptions, 'Algorithm', 'active-set');
0141 Af = full(Af);
0142 Afeq = full(Afeq);
0143 elseif mpopt(55) == 2
0144 fmoptions = optimset(fmoptions, 'Algorithm', 'interior-point');
0145 elseif mpopt(55) == 3
0146 fmoptions = optimset(fmoptions, 'Algorithm', 'interior-point', 'Hessian','lbfgs');
0147 elseif mpopt(55) == 4
0148 fmc_hessian = @(x, lambda)opf_hessfcn(x, lambda, 1, om, Ybus, Yf(il,:), Yt(il,:), mpopt, il);
0149 fmoptions = optimset(fmoptions, 'Algorithm', 'interior-point', ...
0150 'Hessian', 'user-supplied', 'HessFcn', fmc_hessian);
0151 elseif mpopt(55) == 5
0152 fmoptions = optimset(fmoptions, 'Algorithm', 'interior-point', 'Hessian','fin-diff-grads', 'SubProblem', 'cg');
0153 else
0154 error('fmincopf_solver: unknown algorithm specified in FMC_ALG option');
0155 end
0156 end
0157
0158
0159
0160
0161 if str2double(otver.Version(1)) >= 4 && strcmp(optimget(fmoptions, 'Algorithm'), 'interior-point')
0162 x0 = zeros(getN(om, 'var'), 1);
0163 x0(vv.i1.Va:vv.iN.Va) = 0;
0164 x0(vv.i1.Vm:vv.iN.Vm) = 1;
0165 x0(vv.i1.Pg:vv.iN.Pg) = (gen(:, PMIN) + gen(:, PMAX)) / 2 / baseMVA;
0166 x0(vv.i1.Qg:vv.iN.Qg) = (gen(:, QMIN) + gen(:, QMAX)) / 2 / baseMVA;
0167 end
0168
0169
0170 f_fcn = @(x)opf_costfcn(x, om);
0171 gh_fcn = @(x)opf_consfcn(x, om, Ybus, Yf(il,:), Yt(il,:), mpopt, il);
0172 [x, f, info, Output, Lambda] = ...
0173 fmincon(f_fcn, x0, Af, bf, Afeq, bfeq, LB, UB, gh_fcn, fmoptions);
0174 success = (info > 0);
0175
0176
0177 Va = x(vv.i1.Va:vv.iN.Va);
0178 Vm = x(vv.i1.Vm:vv.iN.Vm);
0179 Pg = x(vv.i1.Pg:vv.iN.Pg);
0180 Qg = x(vv.i1.Qg:vv.iN.Qg);
0181 V = Vm .* exp(1j*Va);
0182
0183
0184
0185 bus(:, VA) = Va * 180/pi;
0186 bus(:, VM) = Vm;
0187 gen(:, PG) = Pg * baseMVA;
0188 gen(:, QG) = Qg * baseMVA;
0189 gen(:, VG) = Vm(gen(:, GEN_BUS));
0190
0191
0192 Sf = V(branch(:, F_BUS)) .* conj(Yf * V);
0193 St = V(branch(:, T_BUS)) .* conj(Yt * V);
0194 branch(:, PF) = real(Sf) * baseMVA;
0195 branch(:, QF) = imag(Sf) * baseMVA;
0196 branch(:, PT) = real(St) * baseMVA;
0197 branch(:, QT) = imag(St) * baseMVA;
0198
0199
0200
0201 muSf = zeros(nl, 1);
0202 muSt = zeros(nl, 1);
0203 if ~isempty(il)
0204 muSf(il) = 2 * Lambda.ineqnonlin(1:nl2) .* branch(il, RATE_A) / baseMVA;
0205 muSt(il) = 2 * Lambda.ineqnonlin((1:nl2)+nl2) .* branch(il, RATE_A) / baseMVA;
0206 end
0207
0208
0209 bus(:, MU_VMAX) = Lambda.upper(vv.i1.Vm:vv.iN.Vm);
0210 bus(:, MU_VMIN) = Lambda.lower(vv.i1.Vm:vv.iN.Vm);
0211 gen(:, MU_PMAX) = Lambda.upper(vv.i1.Pg:vv.iN.Pg) / baseMVA;
0212 gen(:, MU_PMIN) = Lambda.lower(vv.i1.Pg:vv.iN.Pg) / baseMVA;
0213 gen(:, MU_QMAX) = Lambda.upper(vv.i1.Qg:vv.iN.Qg) / baseMVA;
0214 gen(:, MU_QMIN) = Lambda.lower(vv.i1.Qg:vv.iN.Qg) / baseMVA;
0215 bus(:, LAM_P) = Lambda.eqnonlin(nn.i1.Pmis:nn.iN.Pmis) / baseMVA;
0216 bus(:, LAM_Q) = Lambda.eqnonlin(nn.i1.Qmis:nn.iN.Qmis) / baseMVA;
0217 branch(:, MU_SF) = muSf / baseMVA;
0218 branch(:, MU_ST) = muSt / baseMVA;
0219
0220
0221 nlnN = getN(om, 'nln');
0222 nlt = length(ilt);
0223 ngt = length(igt);
0224 nbx = length(ibx);
0225
0226
0227 kl = find(Lambda.eqnonlin < 0);
0228 ku = find(Lambda.eqnonlin > 0);
0229 nl_mu_l = zeros(nlnN, 1);
0230 nl_mu_u = [zeros(2*nb, 1); muSf; muSt];
0231 nl_mu_l(kl) = -Lambda.eqnonlin(kl);
0232 nl_mu_u(ku) = Lambda.eqnonlin(ku);
0233
0234
0235 kl = find(Lambda.eqlin < 0);
0236 ku = find(Lambda.eqlin > 0);
0237
0238 mu_l = zeros(size(u));
0239 mu_l(ieq(kl)) = -Lambda.eqlin(kl);
0240 mu_l(igt) = Lambda.ineqlin(nlt+(1:ngt));
0241 mu_l(ibx) = Lambda.ineqlin(nlt+ngt+nbx+(1:nbx));
0242
0243 mu_u = zeros(size(u));
0244 mu_u(ieq(ku)) = Lambda.eqlin(ku);
0245 mu_u(ilt) = Lambda.ineqlin(1:nlt);
0246 mu_u(ibx) = Lambda.ineqlin(nlt+ngt+(1:nbx));
0247
0248 mu = struct( ...
0249 'var', struct('l', Lambda.lower, 'u', Lambda.upper), ...
0250 'nln', struct('l', nl_mu_l, 'u', nl_mu_u), ...
0251 'lin', struct('l', mu_l, 'u', mu_u) );
0252
0253 results = mpc;
0254 [results.bus, results.branch, results.gen, ...
0255 results.om, results.x, results.mu, results.f] = ...
0256 deal(bus, branch, gen, om, x, mu, f);
0257
0258 pimul = [ ...
0259 results.mu.nln.l - results.mu.nln.u;
0260 results.mu.lin.l - results.mu.lin.u;
0261 -ones(ny>0, 1);
0262 results.mu.var.l - results.mu.var.u;
0263 ];
0264 raw = struct('xr', x, 'pimul', pimul, 'info', info, 'output', Output);