Home > matpower5.0 > extract_islands.m

extract_islands

PURPOSE ^

function mpck = extract_islands(mpc, groups, k, custom)

SYNOPSIS ^

function mpck = extract_islands(mpc, varargin)

DESCRIPTION ^

function mpck = extract_islands(mpc, groups, k, custom)
EXTRACT_ISLANDS Extracts each island in a network with islands
   MPC_ARRAY = EXTRACT_ISLANDS(MPC)
   MPC_ARRAY = EXTRACT_ISLANDS(MPC, GROUPS)
   MPC_K = EXTRACT_ISLANDS(MPC, K)
   MPC_K = EXTRACT_ISLANDS(MPC, GROUPS, K)
   MPC_K = EXTRACT_ISLANDS(MPC, K, CUSTOM)
   MPC_K = EXTRACT_ISLANDS(MPC, GROUPS, K, CUSTOM)

   Returns a cell array of MATPOWER case structs for each island in
   the input case struct. If the optional second argument is a cell
   array GROUPS it is assumed to be a cell array of vectors of bus
   indices for each island (as returned by FIND_ISLANDS). Providing
   the GROUPS avoids the need for another traversal of the network
   connectivity and can save a significant amount of time on very
   large systems. If an additional argument K is included, it indicates
   which island(s) to return and the return value is a single case
   struct, rather than a cell array. If K is a scalar or vector, it
   it specifies the index(indices) of the island(s) to include in
   the resulting case file. K can also be the string 'all' which
   will include all islands. This is the same as simply eliminating
   all isolated buses.

   A final optional argument CUSTOM is a struct that can be used to
   indicate custom fields of MPC from which to extract data
   corresponding to buses generators, branches or DC lines. It has
   the following structure:

       CUSTOM.<ORDERING>{DIM} = FIELDS

   <ORDERING> is either 'bus', 'gen', 'branch' or 'dcline' and
   indicates that dimension DIM of FIELDS has dimensions
   corresponding to this <ORDERING> and should have the appropriate
   dimension extracted as well. FIELDS is a cell array, where
   each element is either a single string (field name of MPC) or
   a cell array of strings (nested fields of MPC).

   Examples:
       Extract each island into it's own case struct:
           mpc_list = extract_islands(mpc);

       Extract the 2nd (that is, 2nd largest) island:
           mpc2 = extract_islands(mpc, 2);

       Extract the first and 3rd islands without a re-traverals of the
       network:
           groups = find_islands(mpc);
           mpc1 = extract_islands(mpc, groups, 1);
           mpc3 = extract_islands(mpc, groups, 3);

       Extract the 2nd island, including custom fields, where
       mpc.bus_name{b} contains the name of bus b, and mpc.genfuel{g},
       mpc.emissions.rate(g, :), and mpc.genloc(:, g) contain,
       respectively, the generator's fuel type, emission rates and
       location coordinates:
           custom.bus{1} = {'bus_name'};
           custom.gen{1} = {'genfuel', {'emissions', 'rate'}};
           custom.gen{2} = {'genloc'};
           mpc = extract_islands(mpc, 1, custom);

   See also FIND_ISLANDS, CASE_INFO, CONNECTED_COMPONENTS.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function mpck = extract_islands(mpc, varargin)
0002 %function mpck = extract_islands(mpc, groups, k, custom)
0003 %EXTRACT_ISLANDS Extracts each island in a network with islands
0004 %   MPC_ARRAY = EXTRACT_ISLANDS(MPC)
0005 %   MPC_ARRAY = EXTRACT_ISLANDS(MPC, GROUPS)
0006 %   MPC_K = EXTRACT_ISLANDS(MPC, K)
0007 %   MPC_K = EXTRACT_ISLANDS(MPC, GROUPS, K)
0008 %   MPC_K = EXTRACT_ISLANDS(MPC, K, CUSTOM)
0009 %   MPC_K = EXTRACT_ISLANDS(MPC, GROUPS, K, CUSTOM)
0010 %
0011 %   Returns a cell array of MATPOWER case structs for each island in
0012 %   the input case struct. If the optional second argument is a cell
0013 %   array GROUPS it is assumed to be a cell array of vectors of bus
0014 %   indices for each island (as returned by FIND_ISLANDS). Providing
0015 %   the GROUPS avoids the need for another traversal of the network
0016 %   connectivity and can save a significant amount of time on very
0017 %   large systems. If an additional argument K is included, it indicates
0018 %   which island(s) to return and the return value is a single case
0019 %   struct, rather than a cell array. If K is a scalar or vector, it
0020 %   it specifies the index(indices) of the island(s) to include in
0021 %   the resulting case file. K can also be the string 'all' which
0022 %   will include all islands. This is the same as simply eliminating
0023 %   all isolated buses.
0024 %
0025 %   A final optional argument CUSTOM is a struct that can be used to
0026 %   indicate custom fields of MPC from which to extract data
0027 %   corresponding to buses generators, branches or DC lines. It has
0028 %   the following structure:
0029 %
0030 %       CUSTOM.<ORDERING>{DIM} = FIELDS
0031 %
0032 %   <ORDERING> is either 'bus', 'gen', 'branch' or 'dcline' and
0033 %   indicates that dimension DIM of FIELDS has dimensions
0034 %   corresponding to this <ORDERING> and should have the appropriate
0035 %   dimension extracted as well. FIELDS is a cell array, where
0036 %   each element is either a single string (field name of MPC) or
0037 %   a cell array of strings (nested fields of MPC).
0038 %
0039 %   Examples:
0040 %       Extract each island into it's own case struct:
0041 %           mpc_list = extract_islands(mpc);
0042 %
0043 %       Extract the 2nd (that is, 2nd largest) island:
0044 %           mpc2 = extract_islands(mpc, 2);
0045 %
0046 %       Extract the first and 3rd islands without a re-traverals of the
0047 %       network:
0048 %           groups = find_islands(mpc);
0049 %           mpc1 = extract_islands(mpc, groups, 1);
0050 %           mpc3 = extract_islands(mpc, groups, 3);
0051 %
0052 %       Extract the 2nd island, including custom fields, where
0053 %       mpc.bus_name{b} contains the name of bus b, and mpc.genfuel{g},
0054 %       mpc.emissions.rate(g, :), and mpc.genloc(:, g) contain,
0055 %       respectively, the generator's fuel type, emission rates and
0056 %       location coordinates:
0057 %           custom.bus{1} = {'bus_name'};
0058 %           custom.gen{1} = {'genfuel', {'emissions', 'rate'}};
0059 %           custom.gen{2} = {'genloc'};
0060 %           mpc = extract_islands(mpc, 1, custom);
0061 %
0062 %   See also FIND_ISLANDS, CASE_INFO, CONNECTED_COMPONENTS.
0063 
0064 %   MATPOWER
0065 %   $Id: extract_islands.m 2373 2014-08-11 13:56:55Z ray $
0066 %   by Ray Zimmerman, PSERC Cornell
0067 %   Copyright (c) 2012, 2014 by Power System Engineering Research Center (PSERC)
0068 %
0069 %   This file is part of MATPOWER.
0070 %   See http://www.pserc.cornell.edu/matpower/ for more info.
0071 %
0072 %   MATPOWER is free software: you can redistribute it and/or modify
0073 %   it under the terms of the GNU General Public License as published
0074 %   by the Free Software Foundation, either version 3 of the License,
0075 %   or (at your option) any later version.
0076 %
0077 %   MATPOWER is distributed in the hope that it will be useful,
0078 %   but WITHOUT ANY WARRANTY; without even the implied warranty of
0079 %   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0080 %   GNU General Public License for more details.
0081 %
0082 %   You should have received a copy of the GNU General Public License
0083 %   along with MATPOWER. If not, see <http://www.gnu.org/licenses/>.
0084 %
0085 %   Additional permission under GNU GPL version 3 section 7
0086 %
0087 %   If you modify MATPOWER, or any covered work, to interface with
0088 %   other modules (such as MATLAB code and MEX-files) available in a
0089 %   MATLAB(R) or comparable environment containing parts covered
0090 %   under other licensing terms, the licensors of MATPOWER grant
0091 %   you additional permission to convey the resulting work.
0092 
0093 %% define named indices into data matrices
0094 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
0095     VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
0096 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
0097     MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
0098     QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
0099 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0100     TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
0101     ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
0102 c = idx_dcline;
0103 
0104 %% set up connectivity matrices
0105 nb  = size(mpc.bus, 1);     %% number of buses
0106 nl  = size(mpc.branch, 1);  %% number of branches
0107 if isfield(mpc, 'dcline')   %% number of DC lines
0108     ndc = size(mpc.dcline, 1);
0109 else
0110     ndc = 0;
0111 end
0112 ng  = size(mpc.gen, 1);     %% number of dispatchable injections
0113 
0114 e2i = sparse(mpc.bus(:, BUS_I), ones(nb, 1), 1:nb, max(mpc.bus(:, BUS_I)), 1);
0115 C_on = sparse(1:nl, e2i(mpc.branch(:, F_BUS)), -mpc.branch(:, BR_STATUS), nl, nb) + ...
0116     sparse(1:nl, e2i(mpc.branch(:, T_BUS)),  mpc.branch(:, BR_STATUS), nl, nb);
0117 C = sparse(1:nl, e2i(mpc.branch(:, F_BUS)), -1, nl, nb) + ...
0118     sparse(1:nl, e2i(mpc.branch(:, T_BUS)),  1, nl, nb);
0119 if ndc
0120     Cdc_on = sparse(1:ndc, e2i(mpc.dcline(:, c.F_BUS)), -mpc.dcline(:, c.BR_STATUS), ndc, nb) + ...
0121         sparse(1:ndc, e2i(mpc.dcline(:, c.T_BUS)),  mpc.dcline(:, c.BR_STATUS), ndc, nb);
0122     Cdc = sparse(1:ndc, e2i(mpc.dcline(:, c.F_BUS)), -1, ndc, nb) + ...
0123         sparse(1:ndc, e2i(mpc.dcline(:, c.T_BUS)),  1, ndc, nb);
0124 end
0125 Cg_on = sparse(1:ng, e2i(mpc.gen(:, GEN_BUS)), mpc.gen(:, GEN_STATUS), ng, nb);
0126 Cg = sparse(1:ng, e2i(mpc.gen(:, GEN_BUS)), 1, ng, nb);
0127 
0128 if nnz(C)
0129     n = length(varargin);
0130     if n >= 1 && iscell(varargin{1})
0131         groups = varargin{1};
0132         z = 1;
0133     else
0134         groups = {};
0135         z = 0;
0136     end
0137     if z+1 <= n
0138         k = varargin{z+1};
0139     else
0140         k = [];
0141     end
0142     if z+2 <= n
0143         custom = varargin{z+2};
0144     else
0145         custom = struct();
0146     end
0147     
0148     %% find islands, if not provided
0149     if isempty(groups)
0150         groups = connected_components(C_on);
0151     end
0152     
0153     %% check inputs
0154     if isempty(k)
0155         g1 = 1;
0156         gn = length(groups);
0157     else
0158         if ischar(k)
0159             if strcmp(upper(k), 'ALL')
0160                 k = (1:length(groups))';
0161             else
0162                 error('extract_islands: K = ''%s'' is not a valid input', k);
0163             end
0164         end
0165         if max(k) > length(groups)
0166             error('extract_islands: cannot extract island %d, network has only %d islands', ...
0167                     max(k), length(groups));
0168         end
0169         if length(k) > 1        %% extract multiple islands as one case
0170             tmpgroup = groups{k(1)};
0171             for j = 2:length(k)
0172                 tmpgroup = union(tmpgroup, groups{k(j)});
0173             end
0174             groups = { tmpgroup };
0175             g1 = 1;
0176             gn = 1;
0177         else                    %% extract single island
0178             g1 = k;
0179             gn = k;
0180         end
0181     end
0182     
0183     %% extract islands
0184     for i = g1:gn
0185         kk  = i-g1+1;
0186         b  = groups{i};                     %% buses in group i
0187         %% branches with both ends in group i
0188         ibr = find(sum(abs(C(:, b)), 2) & ~sum(C(:, b), 2));
0189         ig  = find(sum(Cg(:, b), 2));       %% gens in group i
0190         %% DC lines with both ends in group i
0191         if ndc
0192             idc = find(sum(abs(Cdc(:, b)), 2) & ~sum(Cdc(:, b), 2));
0193         else
0194             idc = [];
0195         end
0196     
0197         mpck{kk}        = mpc;
0198         mpck{kk}.bus    = mpc.bus(b, :);
0199         mpck{kk}.branch = mpc.branch(ibr, :);
0200         mpck{kk}.gen    = mpc.gen(ig, :);
0201         if isfield(mpck{kk}, 'gencost')
0202             if size(mpck{kk}.gencost, 1) == 2*ng
0203                 mpck{kk}.gencost = mpc.gencost([ig; ng+ig], :);
0204             else
0205                 mpck{kk}.gencost = mpc.gencost(ig, :);
0206             end
0207         end
0208         if ndc
0209             mpck{kk}.dcline = mpc.dcline(idc, :);
0210             if isfield(mpck{kk}, 'dclinecost')
0211                 mpck{kk}.dclinecost = mpc.dclinecost(idc, :);
0212             end
0213         end
0214 
0215         %% handle custom fields
0216         orderings = {'bus', 'gen', 'branch', 'dcline'};
0217         indexes = {b, ig, ibr, idc};
0218 
0219         for n = 1:length(orderings)
0220             ord = orderings{n};
0221             if isfield(custom, ord)
0222                 for dim = 1:length(custom.(ord))
0223                     for j = 1:length(custom.(ord){dim})
0224                         s = [];
0225                         field = custom.(ord){dim}{j};
0226                         if ischar(field)
0227                             field = { field };
0228                         end
0229 
0230                         tmp = mpck{kk}; %% check this for presence of sub-fields
0231                         skip = 0;
0232                         for i = 1:length(field)
0233                             s(i).type = '.';
0234                             s(i).subs = field{i};
0235                             if isfield(tmp, field{i}) && ~isempty(tmp.(field{i}))
0236                                 %% have sub-field, continue
0237                                 tmp = tmp.(field{i});
0238                             else
0239                                 %% sub-field doesn't exist, skip it
0240                                 skip = 1;
0241                                 break;
0242                             end
0243                         end
0244                         if ~skip
0245                             mpck{kk} = subsasgn(mpck{kk}, s, get_reorder(subsref(mpck{kk}, s), indexes{n}, dim));
0246                         end
0247                     end
0248                 end
0249             end
0250         end
0251     end
0252 
0253     %% convert from cell array to single MATPOWER case struct as appropriate
0254     if ~isempty(k)
0255         mpck = mpck{1};
0256     end
0257 else
0258     mpck = [];
0259 end

Generated on Mon 26-Jan-2015 15:21:31 by m2html © 2005