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