0001 function mpc = toggle_iflims(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 if strcmp(upper(on_off), 'ON')
0045
0046 if ~isfield(mpc, 'if') || ~isstruct(mpc.if) || ...
0047 ~isfield(mpc.if, 'map') || ...
0048 ~isfield(mpc.if, 'lims')
0049 error('toggle_iflims: case must contain an ''if'' field, a struct defining ''map'' and ''lims''');
0050 end
0051
0052
0053
0054
0055 mpc = add_userfcn(mpc, 'ext2int', @userfcn_iflims_ext2int);
0056 mpc = add_userfcn(mpc, 'formulation', @userfcn_iflims_formulation);
0057 mpc = add_userfcn(mpc, 'int2ext', @userfcn_iflims_int2ext);
0058 mpc = add_userfcn(mpc, 'printpf', @userfcn_iflims_printpf);
0059 mpc = add_userfcn(mpc, 'savecase', @userfcn_iflims_savecase);
0060 mpc.userfcn.status.iflims = 1;
0061 elseif strcmp(upper(on_off), 'OFF')
0062 mpc = remove_userfcn(mpc, 'savecase', @userfcn_iflims_savecase);
0063 mpc = remove_userfcn(mpc, 'printpf', @userfcn_iflims_printpf);
0064 mpc = remove_userfcn(mpc, 'int2ext', @userfcn_iflims_int2ext);
0065 mpc = remove_userfcn(mpc, 'formulation', @userfcn_iflims_formulation);
0066 mpc = remove_userfcn(mpc, 'ext2int', @userfcn_iflims_ext2int);
0067 mpc.userfcn.status.iflims = 0;
0068 elseif strcmp(upper(on_off), 'STATUS')
0069 if isfield(mpc, 'userfcn') && isfield(mpc.userfcn, 'status') && ...
0070 isfield(mpc.userfcn.status, 'iflims')
0071 mpc = mpc.userfcn.status.iflims;
0072 else
0073 mpc = 0;
0074 end
0075 else
0076 error('toggle_iflims: 2nd argument must be ''on'', ''off'' or ''status''');
0077 end
0078
0079
0080
0081 function mpc = userfcn_iflims_ext2int(mpc, args)
0082
0083
0084
0085
0086
0087
0088
0089
0090 ifmap = mpc.if.map;
0091 o = mpc.order;
0092 nl0 = size(o.ext.branch, 1);
0093 nl = size(mpc.branch, 1);
0094
0095
0096 mpc.order.ext.ifmap = ifmap;
0097
0098
0099 e2i = zeros(nl0, 1);
0100 e2i(o.branch.status.on) = (1:nl)';
0101 d = sign(ifmap(:, 2));
0102 br = abs(ifmap(:, 2));
0103 ifmap(:, 2) = d .* e2i(br);
0104 ifmap(ifmap(:, 2) == 0, :) = [];
0105
0106 mpc.if.map = ifmap;
0107
0108
0109
0110 function om = userfcn_iflims_formulation(om, args)
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0121 TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
0122 ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
0123
0124
0125 mpc = get_mpc(om);
0126 [baseMVA, bus, branch] = deal(mpc.baseMVA, mpc.bus, mpc.branch);
0127 ifmap = mpc.if.map;
0128 iflims = mpc.if.lims;
0129
0130
0131 [B, Bf, Pbusinj, Pfinj] = makeBdc(baseMVA, bus, branch);
0132 n = size(Bf, 2);
0133
0134
0135 ifidx = unique(iflims(:, 1));
0136 nifs = length(ifidx);
0137 Aif = sparse(nifs, n);
0138 lif = zeros(nifs, 1);
0139 uif = zeros(nifs, 1);
0140 for k = 1:nifs
0141
0142 br = ifmap(ifmap(:, 1) == ifidx(k), 2);
0143 if isempty(br)
0144 error('userfcn_iflims_formulation: interface %d has no in-service branches', k);
0145 end
0146 d = sign(br);
0147 br = abs(br);
0148 Ak = sparse(1, n);
0149 bk = 0;
0150 for i = 1:length(br)
0151 Ak = Ak + d(i) * Bf(br(i), :);
0152 bk = bk + d(i) * Pfinj(br(i));
0153 end
0154 Aif(k, :) = Ak;
0155 lif(k) = iflims(k, 2) / baseMVA - bk;
0156 uif(k) = iflims(k, 3) / baseMVA - bk;
0157 end
0158
0159
0160 om = add_constraints(om, 'iflims', Aif, lif, uif, {'Va'});
0161
0162
0163
0164 function results = userfcn_iflims_int2ext(results, args)
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0177 TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
0178 ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
0179
0180
0181 ifmap = results.if.map;
0182 iflims = results.if.lims;
0183
0184
0185 results.if.map = results.order.ext.ifmap;
0186
0187
0188 ifidx = unique(iflims(:, 1));
0189 nifs = length(ifidx);
0190 results.if.P = zeros(nifs, 1);
0191 for k = 1:nifs
0192
0193 br = ifmap(ifmap(:, 1) == ifidx(k), 2);
0194 d = sign(br);
0195 br = abs(br);
0196 results.if.P(k) = sum( d .* results.branch(br, PF) );
0197 end
0198 results.if.mu.l = results.lin.mu.l.iflims / results.baseMVA;
0199 results.if.mu.u = results.lin.mu.u.iflims / results.baseMVA;
0200
0201
0202
0203 function results = userfcn_iflims_printpf(results, fd, mpopt, args)
0204
0205
0206
0207
0208
0209
0210
0211
0212 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0213 TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
0214 ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
0215
0216
0217 ptol = 1e-6;
0218 isOPF = isfield(results, 'f') && ~isempty(results.f);
0219 SUPPRESS = mpopt.out.suppress_detail;
0220 if SUPPRESS == -1
0221 if size(results.bus, 1) > 500
0222 SUPPRESS = 1;
0223 else
0224 SUPPRESS = 0;
0225 end
0226 end
0227 OUT_ALL = mpopt.out.all;
0228 OUT_FORCE = mpopt.out.force;
0229 OUT_BRANCH = OUT_ALL == 1 || (OUT_ALL == -1 && ~SUPPRESS && mpopt.out.branch);
0230
0231 if isOPF && OUT_BRANCH && (results.success || OUT_FORCE)
0232 iflims = results.if.lims;
0233 fprintf(fd, '\n================================================================================');
0234 fprintf(fd, '\n| Interface Flow Limits |');
0235 fprintf(fd, '\n================================================================================');
0236 fprintf(fd, '\n Interface Shadow Prc Lower Lim Flow Upper Lim Shadow Prc');
0237 fprintf(fd, '\n # ($/MW) (MW) (MW) (MW) ($/MW) ');
0238 fprintf(fd, '\n---------- ---------- ---------- ---------- ---------- -----------');
0239 ifidx = unique(iflims(:, 1));
0240 nifs = length(ifidx);
0241 for k = 1:nifs
0242 fprintf(fd, '\n%6d ', iflims(k, 1));
0243 if results.if.mu.l(k) > ptol
0244 fprintf(fd, '%14.3f', results.if.mu.l(k));
0245 else
0246 fprintf(fd, ' - ');
0247 end
0248 fprintf(fd, '%12.2f%12.2f%12.2f', iflims(k, 2), results.if.P(k), iflims(k, 3));
0249 if results.if.mu.u(k) > ptol
0250 fprintf(fd, '%13.3f', results.if.mu.u(k));
0251 else
0252 fprintf(fd, ' - ');
0253 end
0254 end
0255 fprintf(fd, '\n');
0256 end
0257
0258
0259
0260 function mpc = userfcn_iflims_savecase(mpc, fd, prefix, args)
0261
0262
0263
0264
0265
0266
0267
0268
0269 ifmap = mpc.if.map;
0270 iflims = mpc.if.lims;
0271
0272 fprintf(fd, '\n%%%%----- Interface Flow Limit Data -----%%%%\n');
0273 fprintf(fd, '%%%% interface<->branch map data\n');
0274 fprintf(fd, '%%\tifnum\tbranchidx (negative defines opposite direction)\n');
0275 fprintf(fd, '%sif.map = [\n', prefix);
0276 fprintf(fd, '\t%d\t%d;\n', ifmap');
0277 fprintf(fd, '];\n');
0278
0279 fprintf(fd, '\n%%%% interface flow limit data (based on DC model)\n');
0280 fprintf(fd, '%%%% (lower limit should be negative for opposite direction)\n');
0281 fprintf(fd, '%%\tifnum\tlower\tupper\n');
0282 fprintf(fd, '%sif.lims = [\n', prefix);
0283 fprintf(fd, '\t%d\t%g\t%g;\n', iflims');
0284 fprintf(fd, '];\n');
0285
0286
0287 if isfield(mpc.if, 'P')
0288 if exist('serialize', 'file') == 2
0289 fprintf(fd, '\n%%%% solved values\n');
0290 fprintf(fd, '%sif.P = %s\n', prefix, serialize(mpc.if.P));
0291 fprintf(fd, '%sif.mu.l = %s\n', prefix, serialize(mpc.if.mu.l));
0292 fprintf(fd, '%sif.mu.u = %s\n', prefix, serialize(mpc.if.mu.u));
0293 else
0294 url = 'http://www.mathworks.com/matlabcentral/fileexchange/12063';
0295 warning('MATPOWER:serialize', ...
0296 'userfcn_iflims_savecase: Cannot save the ''iflims'' output fields without the ''serialize'' function, which is available as a free download from:\n<%s>\n\n', url);
0297 end
0298 end