Home > matpower4.0 > toggle_iflims.m

toggle_iflims

PURPOSE ^

TOGGLE_IFLIMS Enable or disable set of interface flow constraints.

SYNOPSIS ^

function mpc = toggle_iflims(mpc, on_off)

DESCRIPTION ^

TOGGLE_IFLIMS Enable or disable set of interface flow constraints.
   MPC = TOGGLE_IFLIMS(MPC, 'on')
   MPC = TOGGLE_IFLIMS(MPC, 'off')

   Enables or disables 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 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 or disable set of interface flow constraints.
0003 %   MPC = TOGGLE_IFLIMS(MPC, 'on')
0004 %   MPC = TOGGLE_IFLIMS(MPC, 'off')
0005 %
0006 %   Enables or disables a set of OPF userfcn callbacks to implement
0007 %   interface flow limits based on a DC flow model.
0008 %
0009 %   These callbacks expect to find an 'if' field in the input MPC, where
0010 %   MPC.if is a struct with the following fields:
0011 %       map     n x 2, defines each interface in terms of a set of
0012 %               branch indices and directions. Interface I is defined
0013 %               by the set of rows whose 1st col is equal to I. The
0014 %               2nd column is a branch index multiplied by 1 or -1
0015 %               respectively for lines whose orientation is the same
0016 %               as or opposite to that of the interface.
0017 %       lims    nif x 3, defines the DC model flow limits in MW
0018 %               for specified interfaces. The 2nd and 3rd columns specify
0019 %               the lower and upper limits on the (DC model) flow
0020 %               across the interface, respectively. Normally, the lower
0021 %               limit is negative, indicating a flow in the opposite
0022 %               direction.
0023 %
0024 %   The 'int2ext' callback also packages up results and stores them in
0025 %   the following output fields of results.if:
0026 %       P       - nif x 1, actual flow across each interface in MW
0027 %       mu.l    - nif x 1, shadow price on lower flow limit, ($/MW)
0028 %       mu.u    - nif x 1, shadow price on upper flow limit, ($/MW)
0029 %
0030 %   See also ADD_USERFCN, REMOVE_USERFCN, RUN_USERFCN, T_CASE30_USERFCNS.
0031 
0032 %   MATPOWER
0033 %   $Id: toggle_iflims.m,v 1.12 2010/04/26 19:45:25 ray Exp $
0034 %   by Ray Zimmerman, PSERC Cornell
0035 %   Copyright (c) 2009-2010 by Power System Engineering Research Center (PSERC)
0036 %
0037 %   This file is part of MATPOWER.
0038 %   See http://www.pserc.cornell.edu/matpower/ for more info.
0039 %
0040 %   MATPOWER is free software: you can redistribute it and/or modify
0041 %   it under the terms of the GNU General Public License as published
0042 %   by the Free Software Foundation, either version 3 of the License,
0043 %   or (at your option) any later version.
0044 %
0045 %   MATPOWER is distributed in the hope that it will be useful,
0046 %   but WITHOUT ANY WARRANTY; without even the implied warranty of
0047 %   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0048 %   GNU General Public License for more details.
0049 %
0050 %   You should have received a copy of the GNU General Public License
0051 %   along with MATPOWER. If not, see <http://www.gnu.org/licenses/>.
0052 %
0053 %   Additional permission under GNU GPL version 3 section 7
0054 %
0055 %   If you modify MATPOWER, or any covered work, to interface with
0056 %   other modules (such as MATLAB code and MEX-files) available in a
0057 %   MATLAB(R) or comparable environment containing parts covered
0058 %   under other licensing terms, the licensors of MATPOWER grant
0059 %   you additional permission to convey the resulting work.
0060 
0061 if strcmp(on_off, 'on')
0062     %% check for proper reserve inputs
0063     if ~isfield(mpc, 'if') || ~isstruct(mpc.if) || ...
0064             ~isfield(mpc.if, 'map') || ...
0065             ~isfield(mpc.if, 'lims')
0066         error('toggle_iflims: case must contain an ''if'' field, a struct defining ''map'' and ''lims''');
0067     end
0068     
0069     %% add callback functions
0070     %% note: assumes all necessary data included in 1st arg (mpc, om, results)
0071     %%       so, no additional explicit args are needed
0072     mpc = add_userfcn(mpc, 'ext2int', @userfcn_iflims_ext2int);
0073     mpc = add_userfcn(mpc, 'formulation', @userfcn_iflims_formulation);
0074     mpc = add_userfcn(mpc, 'int2ext', @userfcn_iflims_int2ext);
0075     mpc = add_userfcn(mpc, 'printpf', @userfcn_iflims_printpf);
0076     mpc = add_userfcn(mpc, 'savecase', @userfcn_iflims_savecase);
0077 elseif strcmp(on_off, 'off')
0078     mpc = remove_userfcn(mpc, 'savecase', @userfcn_iflims_savecase);
0079     mpc = remove_userfcn(mpc, 'printpf', @userfcn_iflims_printpf);
0080     mpc = remove_userfcn(mpc, 'int2ext', @userfcn_iflims_int2ext);
0081     mpc = remove_userfcn(mpc, 'formulation', @userfcn_iflims_formulation);
0082     mpc = remove_userfcn(mpc, 'ext2int', @userfcn_iflims_ext2int);
0083 else
0084     error('toggle_iflims: 2nd argument must be either ''on'' or ''off''');
0085 end
0086 
0087 
0088 %%-----  ext2int  ------------------------------------------------------
0089 function mpc = userfcn_iflims_ext2int(mpc, args)
0090 %
0091 %   mpc = userfcn_iflims_ext2int(mpc, args)
0092 %
0093 %   This is the 'ext2int' stage userfcn callback that prepares the input
0094 %   data for the formulation stage. It expects to find an 'if' field in
0095 %   mpc as described above. The optional args are not currently used.
0096 
0097 %% initialize some things
0098 ifmap = mpc.if.map;
0099 o = mpc.order;
0100 nl0 = size(o.ext.branch, 1);    %% original number of branches
0101 nl = size(mpc.branch, 1);       %% number of on-line branches
0102 
0103 %% save if.map for external indexing
0104 mpc.order.ext.ifmap = ifmap;
0105 
0106 %%-----  convert stuff to internal indexing  -----
0107 e2i = zeros(nl0, 1);
0108 e2i(o.branch.status.on) = (1:nl)';  %% ext->int branch index mapping
0109 d = sign(ifmap(:, 2));
0110 br = abs(ifmap(:, 2));
0111 ifmap(:, 2) = d .* e2i(br);
0112 ifmap(ifmap(:, 2) == 0, :) = [];    %% delete branches that are out
0113 
0114 mpc.if.map = ifmap;
0115 
0116 
0117 %%-----  formulation  --------------------------------------------------
0118 function om = userfcn_iflims_formulation(om, args)
0119 %
0120 %   om = userfcn_iflims_formulation(om, args)
0121 %
0122 %   This is the 'formulation' stage userfcn callback that defines the
0123 %   user costs and constraints for interface flow limits. It expects to
0124 %   find an 'if' field in the mpc stored in om, as described above. The
0125 %   optional args are not currently used.
0126 
0127 %% define named indices into data matrices
0128 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0129     TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
0130     ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
0131 
0132 %% initialize some things
0133 mpc = get_mpc(om);
0134 [baseMVA, bus, branch] = deal(mpc.baseMVA, mpc.bus, mpc.branch);
0135 ifmap = mpc.if.map;
0136 iflims = mpc.if.lims;
0137 
0138 %% form B matrices for DC model
0139 [B, Bf, Pbusinj, Pfinj] = makeBdc(baseMVA, bus, branch);
0140 n = size(Bf, 2);                    %% dim of theta
0141 
0142 %% form constraints
0143 ifidx = unique(iflims(:, 1));   %% interface number list
0144 nifs = length(ifidx);           %% number of interfaces
0145 Aif = sparse(nifs, n);
0146 lif = zeros(nifs, 1);
0147 uif = zeros(nifs, 1);
0148 for k = 1:nifs
0149     %% extract branch indices
0150     br = ifmap(ifmap(:, 1) == ifidx(k), 2);
0151     if isempty(br)
0152         error('userfcn_iflims_formulation: interface %d has no in-service branches', k);
0153     end
0154     d = sign(br);
0155     br = abs(br);
0156     Ak = sparse(1, n);              %% Ak = sum( d(i) * Bf(i, :) )
0157     bk = 0;                         %% bk = sum( d(i) * Pfinj(i) )
0158     for i = 1:length(br)
0159         Ak = Ak + d(i) * Bf(br(i), :);
0160         bk = bk + d(i) * Pfinj(br(i));
0161     end
0162     Aif(k, :) = Ak;
0163     lif(k) = iflims(k, 2) / baseMVA - bk;
0164     uif(k) = iflims(k, 3) / baseMVA - bk;
0165 end
0166 
0167 %% add interface constraint
0168 om = add_constraints(om, 'iflims',  Aif, lif, uif, {'Va'});      %% nifs
0169 
0170 
0171 %%-----  int2ext  ------------------------------------------------------
0172 function results = userfcn_iflims_int2ext(results, args)
0173 %
0174 %   results = userfcn_iflims_int2ext(results, args)
0175 %
0176 %   This is the 'int2ext' stage userfcn callback that converts everything
0177 %   back to external indexing and packages up the results. It expects to
0178 %   find an 'if' field in the results struct as described for mpc above.
0179 %   It also expects the results to contain solved branch flows and linear
0180 %   constraints named 'iflims' which are used to populate output fields
0181 %   in results.if. The optional args are not currently used.
0182 
0183 %% define named indices into data matrices
0184 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0185     TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
0186     ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
0187 
0188 %% get internal ifmap
0189 ifmap = results.if.map;
0190 iflims = results.if.lims;
0191 
0192 %%-----  convert stuff back to external indexing  -----
0193 results.if.map = results.order.ext.ifmap;
0194 
0195 %%-----  results post-processing  -----
0196 ifidx = unique(iflims(:, 1));   %% interface number list
0197 nifs = length(ifidx);           %% number of interfaces
0198 results.if.P = zeros(nifs, 1);
0199 for k = 1:nifs
0200     %% extract branch indices
0201     br = ifmap(ifmap(:, 1) ==  ifidx(k), 2);
0202     d = sign(br);
0203     br = abs(br);
0204     results.if.P(k) = sum( d .* results.branch(br, PF) );
0205 end
0206 results.if.mu.l = results.lin.mu.l.iflims;
0207 results.if.mu.u = results.lin.mu.u.iflims;
0208 
0209 
0210 %%-----  printpf  ------------------------------------------------------
0211 function results = userfcn_iflims_printpf(results, fd, mpopt, args)
0212 %
0213 %   results = userfcn_iflims_printpf(results, fd, mpopt, args)
0214 %
0215 %   This is the 'printpf' stage userfcn callback that pretty-prints the
0216 %   results. It expects a results struct, a file descriptor and a MATPOWER
0217 %   options vector. The optional args are not currently used.
0218 
0219 %% define named indices into data matrices
0220 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0221     TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
0222     ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
0223 
0224 %%-----  print results  -----
0225 OUT_ALL = mpopt(32);
0226 % ctol = mpopt(16);   %% constraint violation tolerance
0227 ptol = 1e-6;        %% tolerance for displaying shadow prices
0228 
0229 if OUT_ALL ~= 0
0230     iflims = results.if.lims;
0231     fprintf(fd, '\n================================================================================');
0232     fprintf(fd, '\n|     Interface Flow Limits                                                    |');
0233     fprintf(fd, '\n================================================================================');
0234     fprintf(fd, '\n Interface  Shadow Prc  Lower Lim      Flow      Upper Lim   Shadow Prc');
0235     fprintf(fd, '\n     #        ($/MW)       (MW)        (MW)        (MW)       ($/MW)   ');
0236     fprintf(fd, '\n----------  ----------  ----------  ----------  ----------  -----------');
0237     ifidx = unique(iflims(:, 1));   %% interface number list
0238     nifs = length(ifidx);           %% number of interfaces
0239     for k = 1:nifs
0240         fprintf(fd, '\n%6d ', iflims(k, 1));
0241         if results.if.mu.l(k) > ptol
0242             fprintf(fd, '%14.3f', results.if.mu.l(k));
0243         else
0244             fprintf(fd, '          -   ');
0245         end
0246         fprintf(fd, '%12.2f%12.2f%12.2f', iflims(k, 2), results.if.P(k), iflims(k, 3));
0247         if results.if.mu.u(k) > ptol
0248             fprintf(fd, '%13.3f', results.if.mu.u(k));
0249         else
0250             fprintf(fd, '         -     ');
0251         end
0252     end
0253     fprintf(fd, '\n');
0254 end
0255 
0256 
0257 %%-----  savecase  -----------------------------------------------------
0258 function mpc = userfcn_iflims_savecase(mpc, fd, prefix, args)
0259 %
0260 %   mpc = userfcn_iflims_savecase(mpc, fd, mpopt, args)
0261 %
0262 %   This is the 'savecase' stage userfcn callback that prints the M-file
0263 %   code to save the 'if' field in the case file. It expects a
0264 %   MATPOWER case struct (mpc), a file descriptor and variable prefix
0265 %   (usually 'mpc.'). The optional args are not currently used.
0266 
0267 ifmap = mpc.if.map;
0268 iflims = mpc.if.lims;
0269 
0270 fprintf(fd, '\n%%%%-----  Interface Flow Limit Data  -----%%%%\n');
0271 fprintf(fd, '%%%% interface<->branch map data\n');
0272 fprintf(fd, '%%\tifnum\tbranchidx (negative defines opposite direction)\n');
0273 fprintf(fd, '%sif.map = [\n', prefix);
0274 fprintf(fd, '\t%d\t%d;\n', ifmap');
0275 fprintf(fd, '];\n');
0276 
0277 fprintf(fd, '\n%%%% interface flow limit data (based on DC model)\n');
0278 fprintf(fd, '%%%% (lower limit should be negative for opposite direction)\n');
0279 fprintf(fd, '%%\tifnum\tlower\tupper\n');
0280 fprintf(fd, '%sif.lims = [\n', prefix);
0281 fprintf(fd, '\t%d\t%g\t%g;\n', iflims');
0282 fprintf(fd, '];\n');
0283 
0284 %% save output fields for solved case
0285 if isfield(mpc.if, 'P')
0286     if exist('serialize', 'file') == 2
0287         fprintf(fd, '\n%%%% solved values\n');
0288         fprintf(fd, '%sif.P = %s\n', prefix, serialize(mpc.if.P));
0289         fprintf(fd, '%sif.mu.l = %s\n', prefix, serialize(mpc.if.mu.l));
0290         fprintf(fd, '%sif.mu.u = %s\n', prefix, serialize(mpc.if.mu.u));
0291     else
0292         url = 'http://www.mathworks.com/matlabcentral/fileexchange/12063';
0293         warning('MATPOWER:serialize', ...
0294             '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);
0295     end
0296 end

Generated on Mon 26-Jan-2015 14:56:45 by m2html © 2005