0001 function [results, success, raw] = copf_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
0070
0071 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
0072 VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
0073 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
0074 MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
0075 QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
0076 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0077 TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
0078 ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
0079
0080
0081 verbose = mpopt(31);
0082
0083
0084 mpc = get_mpc(om);
0085 [baseMVA, bus, gen, branch] = ...
0086 deal(mpc.baseMVA, mpc.bus, mpc.gen, mpc.branch);
0087 vv = get_idx(om);
0088
0089
0090 nb = size(bus, 1);
0091 nl = size(branch, 1);
0092 ny = getN(om, 'var', 'y');
0093
0094
0095 [x0, LB, UB] = getv(om);
0096
0097
0098
0099 nxyz = length(x0);
0100 om2 = om;
0101 om2 = add_constraints(om2, 'varlims', speye(nxyz, nxyz), LB, UB);
0102 [vv, ll, nn] = get_idx(om2);
0103 [A, l, u] = linear_constraints(om2);
0104
0105
0106 if all(bus(:, LAM_P) == 0)
0107 bus(:, LAM_P) = (10)*ones(nb, 1);
0108 end
0109
0110
0111
0112 ieq = find( abs(u-l) <= eps );
0113 igt = find( u >= 1e10 & l > -1e10 );
0114 ilt = find( l <= -1e10 & u < 1e10 );
0115 ibx = find( (abs(u-l) > eps) & (u < 1e10) & (l > -1e10) );
0116 Af = [ A(ilt, :); -A(igt, :); A(ibx, :); -A(ibx, :) ];
0117 bf = [ u(ilt); -l(igt); u(ibx); -l(ibx)];
0118 Afeq = A(ieq, :);
0119 bfeq = u(ieq);
0120
0121
0122 [Ybus, Yf, Yt] = makeYbus(baseMVA, bus, branch);
0123
0124
0125 il = find(branch(:, RATE_A) ~= 0 & branch(:, RATE_A) < 1e10);
0126 nl2 = length(il);
0127
0128
0129 mpopt(15) = 2 * nb + length(bfeq);
0130 if mpopt(19) == 0
0131 mpopt(19) = 150 + 2*nb;
0132 end
0133
0134
0135 otopt = foptions;
0136 otopt(1) = (verbose > 0);
0137
0138 otopt(2) = mpopt(17);
0139 otopt(3) = mpopt(18);
0140 otopt(4) = mpopt(16);
0141 otopt(13) = mpopt(15);
0142 otopt(14) = mpopt(19);
0143
0144
0145 [x, otopt, lambda] = constr('fun_copf', x0, otopt, [], [], 'grad_copf', ...
0146 om2, Ybus, Yf(il,:), Yt(il,:), Afeq, bfeq, Af, bf, mpopt, il);
0147
0148 [f, g] = feval('fun_copf', x, om2, Ybus, Yf(il,:), Yt(il,:), Afeq, bfeq, Af, bf, mpopt, il);
0149
0150
0151 if otopt(10) >= otopt(14) || max(abs(g(1:otopt(13)))) > otopt(4) ...
0152 || max(g((otopt(13)+1):length(g))) > otopt(4)
0153 success = 0;
0154 else
0155 success = 1;
0156 end
0157 info = success;
0158
0159
0160 Va = x(vv.i1.Va:vv.iN.Va);
0161 Vm = x(vv.i1.Vm:vv.iN.Vm);
0162 Pg = x(vv.i1.Pg:vv.iN.Pg);
0163 Qg = x(vv.i1.Qg:vv.iN.Qg);
0164 V = Vm .* exp(1j*Va);
0165
0166
0167
0168 bus(:, VA) = Va * 180/pi;
0169 bus(:, VM) = Vm;
0170 gen(:, PG) = Pg * baseMVA;
0171 gen(:, QG) = Qg * baseMVA;
0172 gen(:, VG) = Vm(gen(:, GEN_BUS));
0173
0174
0175 Sf = V(branch(:, F_BUS)) .* conj(Yf * V);
0176 St = V(branch(:, T_BUS)) .* conj(Yt * V);
0177 branch(:, PF) = real(Sf) * baseMVA;
0178 branch(:, QF) = imag(Sf) * baseMVA;
0179 branch(:, PT) = real(St) * baseMVA;
0180 branch(:, QT) = imag(St) * baseMVA;
0181
0182
0183 nA = length(u);
0184 neq = length(ieq);
0185 nlt = length(ilt);
0186 ngt = length(igt);
0187 nbx = length(ibx);
0188
0189
0190
0191 inln = [(1:2*nb), (1:2*nl2) + 2*nb+neq];
0192 kl = find(lambda(inln) < 0);
0193 ku = find(lambda(inln) > 0);
0194 nl_mu_l = zeros(2*(nb+nl2), 1);
0195 nl_mu_u = zeros(2*(nb+nl2), 1);
0196 nl_mu_l(kl) = -lambda(inln(kl));
0197 nl_mu_u(ku) = lambda(inln(ku));
0198
0199
0200 ilin = [(1:neq)+2*nb, (1:(nlt+ngt+2*nbx)) + 2*nb+neq+2*nl2];
0201 kl = find(lambda(ilin(1:neq)) < 0);
0202 ku = find(lambda(ilin(1:neq)) > 0);
0203
0204 mu_l = zeros(nA, 1);
0205 mu_l(ieq) = -lambda(ilin(1:neq));
0206 mu_l(ieq(ku)) = 0;
0207 mu_l(igt) = lambda(ilin(neq+nlt+(1:ngt)));
0208 mu_l(ibx) = lambda(ilin(neq+nlt+ngt+nbx+(1:nbx)));
0209
0210 mu_u = zeros(nA, 1);
0211 mu_u(ieq) = lambda(ilin(1:neq));
0212 mu_u(ieq(kl)) = 0;
0213 mu_u(ilt) = lambda(ilin(neq+(1:nlt)));
0214 mu_u(ibx) = lambda(ilin(neq+nlt+ngt+(1:nbx)));
0215
0216
0217 muLB = mu_l(ll.i1.varlims:ll.iN.varlims);
0218 muUB = mu_u(ll.i1.varlims:ll.iN.varlims);
0219 mu_l(ll.i1.varlims:ll.iN.varlims) = [];
0220 mu_u(ll.i1.varlims:ll.iN.varlims) = [];
0221
0222
0223
0224 muSf = zeros(nl, 1);
0225 muSt = zeros(nl, 1);
0226 muSf(il) = 2 * nl_mu_u((1:nl2)+2*nb ) .* branch(il, RATE_A) / baseMVA;
0227 muSt(il) = 2 * nl_mu_u((1:nl2)+2*nb+nl2) .* branch(il, RATE_A) / baseMVA;
0228
0229
0230 nl_mu_l = [nl_mu_l(1:2*nb); zeros(2*nl, 1)];
0231 nl_mu_u = [nl_mu_u(1:2*nb); muSf; muSt];
0232
0233
0234 bus(:, MU_VMAX) = muUB(vv.i1.Vm:vv.iN.Vm);
0235 bus(:, MU_VMIN) = muLB(vv.i1.Vm:vv.iN.Vm);
0236 gen(:, MU_PMAX) = muUB(vv.i1.Pg:vv.iN.Pg) / baseMVA;
0237 gen(:, MU_PMIN) = muLB(vv.i1.Pg:vv.iN.Pg) / baseMVA;
0238 gen(:, MU_QMAX) = muUB(vv.i1.Qg:vv.iN.Qg) / baseMVA;
0239 gen(:, MU_QMIN) = muLB(vv.i1.Qg:vv.iN.Qg) / baseMVA;
0240 bus(:, LAM_P) = (nl_mu_u(nn.i1.Pmis:nn.iN.Pmis) - nl_mu_l(nn.i1.Pmis:nn.iN.Pmis)) / baseMVA;
0241 bus(:, LAM_Q) = (nl_mu_u(nn.i1.Qmis:nn.iN.Qmis) - nl_mu_l(nn.i1.Qmis:nn.iN.Qmis)) / baseMVA;
0242 branch(:, MU_SF) = muSf / baseMVA;
0243 branch(:, MU_ST) = muSt / baseMVA;
0244
0245 mu = struct( ...
0246 'var', struct('l', muLB, 'u', muUB), ...
0247 'nln', struct('l', nl_mu_l, 'u', nl_mu_u), ...
0248 'lin', struct('l', mu_l, 'u', mu_u) );
0249
0250 results = mpc;
0251 [results.bus, results.branch, results.gen, ...
0252 results.om, results.x, results.mu, results.f] = ...
0253 deal(bus, branch, gen, om, x, mu, f);
0254
0255 pimul = [ ...
0256 results.mu.nln.l - results.mu.nln.u;
0257 results.mu.lin.l - results.mu.lin.u;
0258 -ones(ny>0, 1);
0259 results.mu.var.l - results.mu.var.u;
0260 ];
0261 raw = struct('xr', x, 'pimul', pimul, 'info', info);