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