Home > matpower5.1 > toggle_iflims.m

toggle_iflims

PURPOSE ^

TOGGLE_IFLIMS Enable, disable or check status of set of interface flow limits.

SYNOPSIS ^

function mpc = toggle_iflims(mpc, on_off)

DESCRIPTION ^

TOGGLE_IFLIMS Enable, disable or check status of set of interface flow limits.
   MPC = TOGGLE_IFLIMS(MPC, 'on')
   MPC = TOGGLE_IFLIMS(MPC, 'off')
   T_F = TOGGLE_IFLIMS(MPC, 'status')

   Enables, disables or checks the status of a set of OPF userfcn
   callbacks to implement interface flow limits based on a DC flow model.

   These callbacks expect to find an 'if' field in the input MPC, where
   MPC.if is a struct with the following fields:
       map     n x 2, defines each interface in terms of a set of 
               branch indices and directions. Interface I is defined
               by the set of rows whose 1st col is equal to I. The
               2nd column is a branch index multiplied by 1 or -1
               respectively for lines whose orientation is the same
               as or opposite to that of the interface.
       lims    nif x 3, defines the DC model flow limits in MW
               for specified interfaces. The first column is the index
               of the interface, the 2nd and 3rd columns specify
               the lower and upper limits on the (DC model) flow
               across the interface, respectively. Normally, the lower
               limit is negative, indicating a flow in the opposite
               direction.

   The 'int2ext' callback also packages up results and stores them in
   the following output fields of results.if:
       P       - nif x 1, actual flow across each interface in MW
       mu.l    - nif x 1, shadow price on lower flow limit, ($/MW)
       mu.u    - nif x 1, shadow price on upper flow limit, ($/MW)

   See also ADD_USERFCN, REMOVE_USERFCN, RUN_USERFCN, T_CASE30_USERFCNS.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function mpc = toggle_iflims(mpc, on_off)
0002 %TOGGLE_IFLIMS Enable, disable or check status of set of interface flow limits.
0003 %   MPC = TOGGLE_IFLIMS(MPC, 'on')
0004 %   MPC = TOGGLE_IFLIMS(MPC, 'off')
0005 %   T_F = TOGGLE_IFLIMS(MPC, 'status')
0006 %
0007 %   Enables, disables or checks the status of a set of OPF userfcn
0008 %   callbacks to implement interface flow limits based on a DC flow model.
0009 %
0010 %   These callbacks expect to find an 'if' field in the input MPC, where
0011 %   MPC.if is a struct with the following fields:
0012 %       map     n x 2, defines each interface in terms of a set of
0013 %               branch indices and directions. Interface I is defined
0014 %               by the set of rows whose 1st col is equal to I. The
0015 %               2nd column is a branch index multiplied by 1 or -1
0016 %               respectively for lines whose orientation is the same
0017 %               as or opposite to that of the interface.
0018 %       lims    nif x 3, defines the DC model flow limits in MW
0019 %               for specified interfaces. The first column is the index
0020 %               of the interface, the 2nd and 3rd columns specify
0021 %               the lower and upper limits on the (DC model) flow
0022 %               across the interface, respectively. Normally, the lower
0023 %               limit is negative, indicating a flow in the opposite
0024 %               direction.
0025 %
0026 %   The 'int2ext' callback also packages up results and stores them in
0027 %   the following output fields of results.if:
0028 %       P       - nif x 1, actual flow across each interface in MW
0029 %       mu.l    - nif x 1, shadow price on lower flow limit, ($/MW)
0030 %       mu.u    - nif x 1, shadow price on upper flow limit, ($/MW)
0031 %
0032 %   See also ADD_USERFCN, REMOVE_USERFCN, RUN_USERFCN, T_CASE30_USERFCNS.
0033 
0034 %   MATPOWER
0035 %   Copyright (c) 2009-2015 by Power System Engineering Research Center (PSERC)
0036 %   by Ray Zimmerman, PSERC Cornell
0037 %
0038 %   $Id: toggle_iflims.m 2644 2015-03-11 19:34:22Z ray $
0039 %
0040 %   This file is part of MATPOWER.
0041 %   Covered by the 3-clause BSD License (see LICENSE file for details).
0042 %   See http://www.pserc.cornell.edu/matpower/ for more info.
0043 
0044 if strcmp(upper(on_off), 'ON')
0045     %% check for proper reserve inputs
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     %% add callback functions
0053     %% note: assumes all necessary data included in 1st arg (mpc, om, results)
0054     %%       so, no additional explicit args are needed
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 %%-----  ext2int  ------------------------------------------------------
0081 function mpc = userfcn_iflims_ext2int(mpc, args)
0082 %
0083 %   mpc = userfcn_iflims_ext2int(mpc, args)
0084 %
0085 %   This is the 'ext2int' stage userfcn callback that prepares the input
0086 %   data for the formulation stage. It expects to find an 'if' field in
0087 %   mpc as described above. The optional args are not currently used.
0088 
0089 %% initialize some things
0090 ifmap = mpc.if.map;
0091 o = mpc.order;
0092 nl0 = size(o.ext.branch, 1);    %% original number of branches
0093 nl = size(mpc.branch, 1);       %% number of on-line branches
0094 
0095 %% save if.map for external indexing
0096 mpc.order.ext.ifmap = ifmap;
0097 
0098 %%-----  convert stuff to internal indexing  -----
0099 e2i = zeros(nl0, 1);
0100 e2i(o.branch.status.on) = (1:nl)';  %% ext->int branch index mapping
0101 d = sign(ifmap(:, 2));
0102 br = abs(ifmap(:, 2));
0103 ifmap(:, 2) = d .* e2i(br);
0104 ifmap(ifmap(:, 2) == 0, :) = [];    %% delete branches that are out
0105 
0106 mpc.if.map = ifmap;
0107 
0108 
0109 %%-----  formulation  --------------------------------------------------
0110 function om = userfcn_iflims_formulation(om, args)
0111 %
0112 %   om = userfcn_iflims_formulation(om, args)
0113 %
0114 %   This is the 'formulation' stage userfcn callback that defines the
0115 %   user costs and constraints for interface flow limits. It expects to
0116 %   find an 'if' field in the mpc stored in om, as described above. The
0117 %   optional args are not currently used.
0118 
0119 %% define named indices into data matrices
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 %% initialize some things
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 %% form B matrices for DC model
0131 [B, Bf, Pbusinj, Pfinj] = makeBdc(baseMVA, bus, branch);
0132 n = size(Bf, 2);                    %% dim of theta
0133 
0134 %% form constraints
0135 ifidx = unique(iflims(:, 1));   %% interface number list
0136 nifs = length(ifidx);           %% number of interfaces
0137 Aif = sparse(nifs, n);
0138 lif = zeros(nifs, 1);
0139 uif = zeros(nifs, 1);
0140 for k = 1:nifs
0141     %% extract branch indices
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);              %% Ak = sum( d(i) * Bf(i, :) )
0149     bk = 0;                         %% bk = sum( d(i) * Pfinj(i) )
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 %% add interface constraint
0160 om = add_constraints(om, 'iflims',  Aif, lif, uif, {'Va'});      %% nifs
0161 
0162 
0163 %%-----  int2ext  ------------------------------------------------------
0164 function results = userfcn_iflims_int2ext(results, args)
0165 %
0166 %   results = userfcn_iflims_int2ext(results, args)
0167 %
0168 %   This is the 'int2ext' stage userfcn callback that converts everything
0169 %   back to external indexing and packages up the results. It expects to
0170 %   find an 'if' field in the results struct as described for mpc above.
0171 %   It also expects the results to contain solved branch flows and linear
0172 %   constraints named 'iflims' which are used to populate output fields
0173 %   in results.if. The optional args are not currently used.
0174 
0175 %% define named indices into data matrices
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 %% get internal ifmap
0181 ifmap = results.if.map;
0182 iflims = results.if.lims;
0183 
0184 %%-----  convert stuff back to external indexing  -----
0185 results.if.map = results.order.ext.ifmap;
0186 
0187 %%-----  results post-processing  -----
0188 ifidx = unique(iflims(:, 1));   %% interface number list
0189 nifs = length(ifidx);           %% number of interfaces
0190 results.if.P = zeros(nifs, 1);
0191 for k = 1:nifs
0192     %% extract branch indices
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 %%-----  printpf  ------------------------------------------------------
0203 function results = userfcn_iflims_printpf(results, fd, mpopt, args)
0204 %
0205 %   results = userfcn_iflims_printpf(results, fd, mpopt, args)
0206 %
0207 %   This is the 'printpf' stage userfcn callback that pretty-prints the
0208 %   results. It expects a results struct, a file descriptor and a MATPOWER
0209 %   options struct. The optional args are not currently used.
0210 
0211 %% define named indices into data matrices
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 %%-----  print results  -----
0217 ptol = 1e-6;        %% tolerance for displaying shadow prices
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));   %% interface number list
0240     nifs = length(ifidx);           %% number of interfaces
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 %%-----  savecase  -----------------------------------------------------
0260 function mpc = userfcn_iflims_savecase(mpc, fd, prefix, args)
0261 %
0262 %   mpc = userfcn_iflims_savecase(mpc, fd, mpopt, args)
0263 %
0264 %   This is the 'savecase' stage userfcn callback that prints the M-file
0265 %   code to save the 'if' field in the case file. It expects a
0266 %   MATPOWER case struct (mpc), a file descriptor and variable prefix
0267 %   (usually 'mpc.'). The optional args are not currently used.
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 %% save output fields for solved case
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

Generated on Fri 20-Mar-2015 18:23:34 by m2html © 2005