0001 function mpc = toggle_dcline(mpc, on_off)
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 if strcmp(on_off, 'on')
0060
0061 c = idx_dcline;
0062
0063
0064 if ~isfield(mpc, 'dcline') || size(mpc.dcline, 2) < c.LOSS1
0065 error('toggle_dcline: case must contain a ''dcline'' field, an ndc x %d matrix.', c.LOSS1);
0066 end
0067 if isfield(mpc, 'dclinecost') && size(mpc.dcline, 1) ~= size(mpc.dclinecost, 1)
0068 error('toggle_dcline: number of rows in ''dcline'' field (%d) and ''dclinecost'' field (%d) do not match.', ...
0069 size(mpc.dcline, 1), size(mpc.dclinecost, 1));
0070 end
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080 mpc = add_userfcn(mpc, 'ext2int', @userfcn_dcline_ext2int);
0081 mpc = add_userfcn(mpc, 'formulation', @userfcn_dcline_formulation);
0082 mpc = add_userfcn(mpc, 'int2ext', @userfcn_dcline_int2ext);
0083 mpc = add_userfcn(mpc, 'printpf', @userfcn_dcline_printpf);
0084 mpc = add_userfcn(mpc, 'savecase', @userfcn_dcline_savecase);
0085 elseif strcmp(on_off, 'off')
0086 mpc = remove_userfcn(mpc, 'savecase', @userfcn_dcline_savecase);
0087 mpc = remove_userfcn(mpc, 'printpf', @userfcn_dcline_printpf);
0088 mpc = remove_userfcn(mpc, 'int2ext', @userfcn_dcline_int2ext);
0089 mpc = remove_userfcn(mpc, 'formulation', @userfcn_dcline_formulation);
0090 mpc = remove_userfcn(mpc, 'ext2int', @userfcn_dcline_ext2int);
0091 else
0092 error('toggle_dcline: 2nd argument must be either ''on'' or ''off''');
0093 end
0094
0095
0096
0097 function mpc = userfcn_dcline_ext2int(mpc, args)
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
0110 VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
0111 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
0112 MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
0113 QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
0114 [PW_LINEAR, POLYNOMIAL, MODEL, STARTUP, SHUTDOWN, NCOST, COST] = idx_cost;
0115 c = idx_dcline;
0116
0117
0118 if isfield(mpc, 'dclinecost')
0119 havecost = 1;
0120 else
0121 havecost = 0;
0122 end
0123
0124
0125 mpc.order.ext.dcline = mpc.dcline;
0126 if havecost
0127 mpc.order.ext.dclinecost = mpc.dclinecost;
0128 end
0129
0130
0131 mpc.order.dcline.status.on = find(mpc.dcline(:, c.BR_STATUS) > 0);
0132 mpc.order.dcline.status.off = find(mpc.dcline(:, c.BR_STATUS) <= 0);
0133
0134
0135 dc = mpc.dcline(mpc.order.dcline.status.on, :);
0136 if havecost
0137 dcc = mpc.dclinecost(mpc.order.dcline.status.on, :);
0138 mpc.dclinecost = dcc;
0139 end
0140 ndc = size(dc, 1);
0141 o = mpc.order;
0142
0143
0144 dc(:, c.F_BUS) = o.bus.e2i(dc(:, c.F_BUS));
0145 dc(:, c.T_BUS) = o.bus.e2i(dc(:, c.T_BUS));
0146 mpc.dcline = dc;
0147
0148
0149
0150
0151 dc(:, c.PT) = dc(:, c.PF) - (dc(:, c.LOSS0) + dc(:, c.LOSS1) .* dc(:, c.PF));
0152
0153
0154 fg = zeros(ndc, size(mpc.gen, 2));
0155 fg(:, MBASE) = 100;
0156 fg(:, GEN_STATUS) = dc(:, c.BR_STATUS);
0157 fg(:, PMIN) = -Inf;
0158 fg(:, PMAX) = Inf;
0159 tg = fg;
0160 fg(:, GEN_BUS) = dc(:, c.F_BUS);
0161 tg(:, GEN_BUS) = dc(:, c.T_BUS);
0162 fg(:, PG) = -dc(:, c.PF);
0163 tg(:, PG) = dc(:, c.PT);
0164 fg(:, QG) = dc(:, c.QF);
0165 tg(:, QG) = dc(:, c.QT);
0166 fg(:, VG) = dc(:, c.VF);
0167 tg(:, VG) = dc(:, c.VT);
0168 k = find(dc(:, c.PMIN) >= 0);
0169 if ~isempty(k)
0170 fg(k, PMAX) = -dc(k, c.PMIN);
0171 end
0172 k = find(dc(:, c.PMAX) >= 0);
0173 if ~isempty(k)
0174 fg(k, PMIN) = -dc(k, c.PMAX);
0175 end
0176 k = find(dc(:, c.PMIN) < 0);
0177 if ~isempty(k)
0178 tg(k, PMIN) = dc(k, c.PMIN);
0179 end
0180 k = find(dc(:, c.PMAX) < 0);
0181 if ~isempty(k)
0182 tg(k, PMAX) = dc(k, c.PMAX);
0183 end
0184 fg(:, QMIN) = dc(:, c.QMINF);
0185 fg(:, QMAX) = dc(:, c.QMAXF);
0186 tg(:, QMIN) = dc(:, c.QMINT);
0187 tg(:, QMAX) = dc(:, c.QMAXT);
0188
0189
0190
0191 fg(isload(fg), PMAX) = -1e-6;
0192 tg(isload(tg), PMAX) = -1e-6;
0193
0194
0195 refbus = find(mpc.bus(:, BUS_TYPE) == REF);
0196 mpc.bus(dc(:, c.F_BUS), BUS_TYPE) = PV;
0197 mpc.bus(dc(:, c.T_BUS), BUS_TYPE) = PV;
0198 mpc.bus(refbus, BUS_TYPE) = REF;
0199
0200
0201 mpc.gen = [mpc.gen; fg; tg];
0202
0203
0204 if isfield(mpc, 'gencost') && ~isempty(mpc.gencost)
0205 [ngcr, ngcc] = size(mpc.gencost);
0206 if havecost
0207 ndccc = size(dcc, 2);
0208 ccc = max([ngcc; ndccc]);
0209 if ccc > ngcc
0210 mpc.gencost = [mpc.gencost zeros(ngcr, ccc-ngcc)];
0211 end
0212
0213
0214
0215 for k = 1:ndc
0216 if dcc(k, MODEL) == POLYNOMIAL
0217 nc = dcc(k, NCOST);
0218 temp = dcc(k, NCOST+(1:nc));
0219
0220
0221
0222 temp((nc-1):-2:1) = -temp((nc-1):-2:1);
0223 else
0224 nc = dcc(k, NCOST);
0225 temp = dcc(k, NCOST+(1:2*nc));
0226
0227 xx = -temp(1:2:2*nc);
0228 yy = temp(2:2:2*nc);
0229 temp(1:2:2*nc) = xx(end:-1:1);
0230 temp(2:2:2*nc) = yy(end:-1:1);
0231 end
0232 padding = zeros(1, ccc-NCOST-length(temp));
0233 gck = [dcc(k, 1:NCOST) temp padding];
0234
0235
0236 mpc.gencost = [mpc.gencost; gck];
0237 end
0238
0239 tgc = ones(ndc, 1) * [2 0 0 2 zeros(1, ccc-4)];
0240 mpc.gencost = [mpc.gencost; tgc];
0241 else
0242
0243 dcgc = ones(2*ndc, 1) * [2 0 0 2 zeros(1, ngcc-4)];
0244 mpc.gencost = [mpc.gencost; dcgc];
0245 end
0246 end
0247
0248
0249
0250 function om = userfcn_dcline_formulation(om, args)
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276 c = idx_dcline;
0277
0278
0279 mpc = get_mpc(om);
0280 dc = mpc.dcline;
0281 ndc = size(dc, 1);
0282 ng = size(mpc.gen, 1) - 2*ndc;
0283
0284
0285 nL0 = -dc(:, c.LOSS0) / mpc.baseMVA;
0286 L1 = dc(:, c.LOSS1);
0287 Adc = [sparse(ndc, ng) spdiags(1-L1, 0, ndc, ndc) speye(ndc, ndc)];
0288
0289
0290 om = add_constraints(om, 'dcline', Adc, nL0, nL0, {'Pg'});
0291
0292
0293
0294 function results = userfcn_dcline_int2ext(results, args)
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
0310 MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
0311 QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
0312 c = idx_dcline;
0313
0314
0315 o = results.order;
0316 k = find(o.ext.dcline(:, c.BR_STATUS));
0317 ndc = length(k);
0318 ng = size(results.gen, 1) - 2*ndc;
0319
0320
0321 fg = results.gen(ng +(1:ndc), :);
0322 tg = results.gen(ng+ndc+(1:ndc), :);
0323
0324
0325 results.gen = results.gen(1:ng, :);
0326 results.gencost = results.gencost(1:ng, :);
0327
0328
0329 results.dcline(:, c.PF) = -fg(:, PG);
0330 results.dcline(:, c.PT) = tg(:, PG);
0331 results.dcline(:, c.QF) = fg(:, QG);
0332 results.dcline(:, c.QT) = tg(:, QG);
0333 results.dcline(:, c.VF) = fg(:, VG);
0334 results.dcline(:, c.VT) = tg(:, VG);
0335 if size(fg, 2) >= MU_QMIN
0336 results.dcline(:, c.MU_PMIN ) = fg(:, MU_PMAX) + tg(:, MU_PMIN);
0337 results.dcline(:, c.MU_PMAX ) = fg(:, MU_PMIN) + tg(:, MU_PMAX);
0338 results.dcline(:, c.MU_QMINF) = fg(:, MU_QMIN);
0339 results.dcline(:, c.MU_QMAXF) = fg(:, MU_QMAX);
0340 results.dcline(:, c.MU_QMINT) = tg(:, MU_QMIN);
0341 results.dcline(:, c.MU_QMAXT) = tg(:, MU_QMAX);
0342 end
0343
0344
0345 results.order.int.dcline = results.dcline;
0346
0347 o.ext.dcline(k, c.PF:c.VT) = results.dcline(:, c.PF:c.VT);
0348 if size(results.dcline, 2) == c.MU_QMAXT
0349 o.ext.dcline(k, c.MU_PMIN:c.MU_QMAXT) = results.dcline(:, c.MU_PMIN:c.MU_QMAXT);
0350 end
0351 results.dcline = o.ext.dcline;
0352
0353
0354
0355 function results = userfcn_dcline_printpf(results, fd, mpopt, args)
0356
0357
0358
0359
0360
0361
0362
0363
0364 c = idx_dcline;
0365
0366
0367 OUT_ALL = mpopt(32);
0368 OUT_BRANCH = OUT_ALL == 1 || (OUT_ALL == -1 && mpopt(36));
0369 if OUT_ALL == -1
0370 OUT_ALL_LIM = mpopt(38);
0371 elseif OUT_ALL == 1
0372 OUT_ALL_LIM = 2;
0373 else
0374 OUT_ALL_LIM = 0;
0375 end
0376 if OUT_ALL_LIM == -1
0377 OUT_LINE_LIM = mpopt(40);
0378 else
0379 OUT_LINE_LIM = OUT_ALL_LIM;
0380 end
0381 ctol = mpopt(16);
0382 ptol = 1e-4;
0383
0384
0385 dc = results.dcline;
0386 ndc = size(dc, 1);
0387 kk = find(dc(:, c.BR_STATUS) ~= 0);
0388 if OUT_BRANCH
0389 fprintf(fd, '\n================================================================================');
0390 fprintf(fd, '\n| DC Line Data |');
0391 fprintf(fd, '\n================================================================================');
0392 fprintf(fd, '\n Line From To Power Flow Loss Reactive Inj (MVAr)');
0393 fprintf(fd, '\n # Bus Bus From (MW) To (MW) (MW) From To ');
0394 fprintf(fd, '\n------ ------ ------ --------- --------- --------- --------- ---------');
0395 loss = 0;
0396 for k = 1:ndc
0397 if dc(k, c.BR_STATUS)
0398 fprintf(fd, '\n%5d%8d%8d%11.2f%11.2f%11.2f%11.2f%11.2f', ...
0399 k, dc(k, c.F_BUS:c.T_BUS), dc(k, c.PF:c.PT), ...
0400 dc(k, c.PF) - dc(k, c.PT), dc(k, c.QF:c.QT) );
0401 loss = loss + dc(k, c.PF) - dc(k, c.PT);
0402 else
0403 fprintf(fd, '\n%5d%8d%8d%11s%11s%11s%11s%11s', ...
0404 k, dc(k, c.F_BUS:c.T_BUS), '- ', '- ', '- ', '- ', '- ');
0405 end
0406 end
0407 fprintf(fd, '\n ---------');
0408 fprintf(fd, '\n Total:%11.2f\n', loss);
0409 end
0410
0411 if OUT_LINE_LIM == 2 || (OUT_LINE_LIM == 1 && ...
0412 (any(dc(kk, c.PF) > dc(kk, c.PMAX) - ctol) || ...
0413 any(dc(kk, c.MU_PMIN) > ptol) || ...
0414 any(dc(kk, c.MU_PMAX) > ptol)))
0415 fprintf(fd, '\n================================================================================');
0416 fprintf(fd, '\n| DC Line Constraints |');
0417 fprintf(fd, '\n================================================================================');
0418 fprintf(fd, '\n Line From To Minimum Actual Flow Maximum');
0419 fprintf(fd, '\n # Bus Bus Pmin mu Pmin (MW) Pmax Pmax mu ');
0420 fprintf(fd, '\n------ ------ ------ --------- --------- --------- --------- ---------');
0421 for k = 1:ndc
0422 if OUT_LINE_LIM == 2 || (OUT_LINE_LIM == 1 && ...
0423 (dc(k, c.PF) > dc(k, c.PMAX) - ctol || ...
0424 dc(k, c.MU_PMIN) > ptol || ...
0425 dc(k, c.MU_PMAX) > ptol))
0426 if dc(k, c.BR_STATUS)
0427 fprintf(fd, '\n%5d%8d%8d', k, dc(k, c.F_BUS:c.T_BUS) );
0428 if dc(k, c.MU_PMIN) > ptol
0429 fprintf(fd, '%11.3f', dc(k, c.MU_PMIN) );
0430 else
0431 fprintf(fd, '%11s', '- ' );
0432 end
0433 fprintf(fd, '%11.2f%11.2f%11.2f', ...
0434 dc(k, c.PMIN), dc(k, c.PF), dc(k, c.PMAX) );
0435 if dc(k, c.MU_PMAX) > ptol
0436 fprintf(fd, '%11.3f', dc(k, c.MU_PMAX) );
0437 else
0438 fprintf(fd, '%11s', '- ' );
0439 end
0440 else
0441 fprintf(fd, '\n%5d%8d%8d%11s%11s%11s%11s%11s', ...
0442 k, dc(k, c.F_BUS:c.T_BUS), '- ', '- ', '- ', '- ', '- ');
0443 end
0444 end
0445 end
0446 fprintf(fd, '\n');
0447 end
0448
0449
0450
0451 function mpc = userfcn_dcline_savecase(mpc, fd, prefix, args)
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461 c = idx_dcline;
0462
0463
0464 ncols = size(mpc.dcline, 2);
0465 fprintf(fd, '\n%%%%----- DC Line Data -----%%%%\n');
0466 if ncols < c.MU_QMAXT
0467 fprintf(fd, '%%\tfbus\ttbus\tstatus\tPf\tPt\tQf\tQt\tVf\tVt\tPmin\tPmax\tQminF\tQmaxF\tQminT\tQmaxT\tloss0\tloss1\n');
0468 else
0469 fprintf(fd, '%%\tfbus\ttbus\tstatus\tPf\tPt\tQf\tQt\tVf\tVt\tPmin\tPmax\tQminF\tQmaxF\tQminT\tQmaxT\tloss0\tloss1\tmuPmin\tmuPmax\tmuQminF\tmuQmaxF\tmuQminT\tmuQmaxT\n');
0470 end
0471 template = '\t%d\t%d\t%d\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g\t%.9g';
0472 if ncols == c.MU_QMAXT
0473 template = [template, '\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f\t%.4f'];
0474 end
0475 template = [template, ';\n'];
0476 fprintf(fd, '%sdcline = [\n', prefix);
0477 fprintf(fd, template, mpc.dcline.');
0478 fprintf(fd, '];\n');