0001 function [results, success, raw] = dcopf_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 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
0067 VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
0068 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
0069 MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
0070 QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
0071 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0072 TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
0073 ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
0074 [PW_LINEAR, POLYNOMIAL, MODEL, STARTUP, SHUTDOWN, NCOST, COST] = idx_cost;
0075
0076
0077 verbose = mpopt(31);
0078 alg = mpopt(26);
0079
0080
0081 if alg == 0
0082 if have_fcn('mosek')
0083 alg = 600;
0084 elseif have_fcn('bpmpd')
0085 alg = 100;
0086 elseif have_fcn('cplex')
0087 alg = 500;
0088 else
0089 alg = 200;
0090 end
0091 end
0092
0093
0094 mpc = get_mpc(om);
0095 [baseMVA, bus, gen, branch, gencost] = ...
0096 deal(mpc.baseMVA, mpc.bus, mpc.gen, mpc.branch, mpc.gencost);
0097 cp = get_cost_params(om);
0098 [N, H, Cw] = deal(cp.N, cp.H, cp.Cw);
0099 fparm = [cp.dd cp.rh cp.kk cp.mm];
0100 Bf = userdata(om, 'Bf');
0101 Pfinj = userdata(om, 'Pfinj');
0102 [vv, ll] = get_idx(om);
0103
0104
0105 ipol = find(gencost(:, MODEL) == POLYNOMIAL);
0106 ipwl = find(gencost(:, MODEL) == PW_LINEAR);
0107 nb = size(bus, 1);
0108 nl = size(branch, 1);
0109 nw = size(N, 1);
0110 ny = getN(om, 'var', 'y');
0111 nxyz = getN(om, 'var');
0112
0113
0114 [A, l, u] = linear_constraints(om);
0115 [x0, xmin, xmax] = getv(om);
0116
0117
0118
0119
0120
0121
0122
0123 any_pwl = (ny > 0);
0124 if any_pwl
0125 Npwl = sparse(ones(ny,1), vv.i1.y:vv.iN.y, 1, 1, nxyz);
0126 Hpwl = 0;
0127 Cpwl = 1;
0128 fparm_pwl = [1 0 0 1];
0129 else
0130 Npwl = sparse(0, nxyz);
0131 Hpwl = [];
0132 Cpwl = [];
0133 fparm_pwl = [];
0134 end
0135
0136
0137 npol = length(ipol);
0138 if any(find(gencost(ipol, NCOST) > 3))
0139 error('DC opf cannot handle polynomial costs with higher than quadratic order.');
0140 end
0141 iqdr = find(gencost(ipol, NCOST) == 3);
0142 ilin = find(gencost(ipol, NCOST) == 2);
0143 polycf = zeros(npol, 3);
0144 if ~isempty(iqdr)
0145 polycf(iqdr, :) = gencost(ipol(iqdr), COST:COST+2);
0146 end
0147 polycf(ilin, 2:3) = gencost(ipol(ilin), COST:COST+1);
0148 polycf = polycf * diag([ baseMVA^2 baseMVA 1]);
0149 Npol = sparse(1:npol, vv.i1.Pg-1+ipol, 1, npol, nxyz);
0150 Hpol = sparse(1:npol, 1:npol, 2*polycf(:, 1), npol, npol);
0151 Cpol = polycf(:, 2);
0152 fparm_pol = ones(npol,1) * [ 1 0 0 1 ];
0153
0154
0155 NN = [ Npwl; Npol; N ];
0156 HHw = [ Hpwl, sparse(any_pwl, npol+nw);
0157 sparse(npol, any_pwl), Hpol, sparse(npol, nw);
0158 sparse(nw, any_pwl+npol), H ];
0159 CCw = [Cpwl; Cpol; Cw];
0160 ffparm = [ fparm_pwl; fparm_pol; fparm ];
0161
0162
0163 nnw = any_pwl+npol+nw;
0164 M = sparse(1:nnw, 1:nnw, ffparm(:, 4), nnw, nnw);
0165 MR = M * ffparm(:, 2);
0166 HMR = HHw * MR;
0167 MN = M * NN;
0168 HH = MN' * HHw * MN;
0169 CC = full(MN' * (CCw - HMR));
0170 C0 = 1/2 * MR' * HMR + sum(polycf(:, 3));
0171
0172
0173 opt = struct('alg', alg, 'verbose', verbose);
0174 switch alg
0175 case {200, 250}
0176
0177 Varefs = bus(bus(:, BUS_TYPE) == REF, VA) * (pi/180);
0178
0179 lb = xmin; ub = xmax;
0180 lb(xmin == -Inf) = -1e10;
0181 ub(xmax == Inf) = 1e10;
0182 x0 = (lb + ub) / 2;
0183 x0(vv.i1.Va:vv.iN.Va) = Varefs(1);
0184 if ny > 0
0185 ipwl = find(gencost(:, MODEL) == PW_LINEAR);
0186 c = gencost(sub2ind(size(gencost), ipwl, NCOST+2*gencost(ipwl, NCOST)));
0187 x0(vv.i1.y:vv.iN.y) = max(c) + 0.1 * abs(max(c));
0188 end
0189
0190
0191 feastol = mpopt(81);
0192 gradtol = mpopt(82);
0193 comptol = mpopt(83);
0194 costtol = mpopt(84);
0195 max_it = mpopt(85);
0196 max_red = mpopt(86);
0197 if feastol == 0
0198 feastol = mpopt(16);
0199 end
0200 opt.mips_opt = struct( 'feastol', feastol, ...
0201 'gradtol', gradtol, ...
0202 'comptol', comptol, ...
0203 'costtol', costtol, ...
0204 'max_it', max_it, ...
0205 'max_red', max_red, ...
0206 'cost_mult', 1 );
0207 case 400
0208 opt.ipopt_opt = ipopt_options([], mpopt);
0209 case 500
0210 opt.cplex_opt = cplex_options([], mpopt);
0211 case 600
0212 opt.mosek_opt = mosek_options([], mpopt);
0213 end
0214
0215
0216 [x, f, info, output, lambda] = qps_matpower(HH, CC, A, l, u, xmin, xmax, x0, opt);
0217 success = (info == 1);
0218
0219
0220 if ~any(isnan(x))
0221
0222 Va = x(vv.i1.Va:vv.iN.Va);
0223 Pg = x(vv.i1.Pg:vv.iN.Pg);
0224 f = f + C0;
0225
0226
0227 bus(:, VA) = Va * 180/pi;
0228 gen(:, PG) = Pg * baseMVA;
0229
0230
0231 branch(:, [QF, QT]) = zeros(nl, 2);
0232 branch(:, PF) = (Bf * Va + Pfinj) * baseMVA;
0233 branch(:, PT) = -branch(:, PF);
0234 end
0235
0236
0237 mu_l = lambda.mu_l;
0238 mu_u = lambda.mu_u;
0239 muLB = lambda.lower;
0240 muUB = lambda.upper;
0241
0242
0243 il = find(branch(:, RATE_A) ~= 0 & branch(:, RATE_A) < 1e10);
0244 bus(:, [LAM_P, LAM_Q, MU_VMIN, MU_VMAX]) = zeros(nb, 4);
0245 gen(:, [MU_PMIN, MU_PMAX, MU_QMIN, MU_QMAX]) = zeros(size(gen, 1), 4);
0246 branch(:, [MU_SF, MU_ST]) = zeros(nl, 2);
0247 bus(:, LAM_P) = (mu_u(ll.i1.Pmis:ll.iN.Pmis) - mu_l(ll.i1.Pmis:ll.iN.Pmis)) / baseMVA;
0248 branch(il, MU_SF) = mu_u(ll.i1.Pf:ll.iN.Pf) / baseMVA;
0249 branch(il, MU_ST) = mu_u(ll.i1.Pt:ll.iN.Pt) / baseMVA;
0250 gen(:, MU_PMIN) = muLB(vv.i1.Pg:vv.iN.Pg) / baseMVA;
0251 gen(:, MU_PMAX) = muUB(vv.i1.Pg:vv.iN.Pg) / baseMVA;
0252 pimul = [
0253 mu_l - mu_u;
0254 -ones(ny>0, 1);
0255 muLB - muUB
0256 ];
0257
0258 mu = struct( ...
0259 'var', struct('l', muLB, 'u', muUB), ...
0260 'lin', struct('l', mu_l, 'u', mu_u) );
0261
0262 results = mpc;
0263 [results.bus, results.branch, results.gen, ...
0264 results.om, results.x, results.mu, results.f] = ...
0265 deal(bus, branch, gen, om, x, mu, f);
0266
0267 raw = struct('xr', x, 'pimul', pimul, 'info', info, 'output', output);