Home > matpower6.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 %   Copyright (c) 2012-2016, Power Systems Engineering Research Center (PSERC)
0066 %   by Ray Zimmerman, PSERC Cornell
0067 %
0068 %   This file is part of MATPOWER.
0069 %   Covered by the 3-clause BSD License (see LICENSE file for details).
0070 %   See http://www.pserc.cornell.edu/matpower/ for more info.
0071 
0072 %% define named indices into data matrices
0073 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
0074     VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
0075 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
0076     MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
0077     QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
0078 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0079     TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
0080     ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
0081 c = idx_dcline;
0082 
0083 %% set up connectivity matrices
0084 nb  = size(mpc.bus, 1);     %% number of buses
0085 nl  = size(mpc.branch, 1);  %% number of branches
0086 if isfield(mpc, 'dcline')   %% number of DC lines
0087     ndc = size(mpc.dcline, 1);
0088 else
0089     ndc = 0;
0090 end
0091 ng  = size(mpc.gen, 1);     %% number of dispatchable injections
0092 
0093 e2i = sparse(mpc.bus(:, BUS_I), ones(nb, 1), 1:nb, max(mpc.bus(:, BUS_I)), 1);
0094 C_on = sparse(1:nl, e2i(mpc.branch(:, F_BUS)), -mpc.branch(:, BR_STATUS), nl, nb) + ...
0095     sparse(1:nl, e2i(mpc.branch(:, T_BUS)),  mpc.branch(:, BR_STATUS), nl, nb);
0096 C = sparse(1:nl, e2i(mpc.branch(:, F_BUS)), -1, nl, nb) + ...
0097     sparse(1:nl, e2i(mpc.branch(:, T_BUS)),  1, nl, nb);
0098 if ndc
0099     Cdc_on = sparse(1:ndc, e2i(mpc.dcline(:, c.F_BUS)), -mpc.dcline(:, c.BR_STATUS), ndc, nb) + ...
0100         sparse(1:ndc, e2i(mpc.dcline(:, c.T_BUS)),  mpc.dcline(:, c.BR_STATUS), ndc, nb);
0101     Cdc = sparse(1:ndc, e2i(mpc.dcline(:, c.F_BUS)), -1, ndc, nb) + ...
0102         sparse(1:ndc, e2i(mpc.dcline(:, c.T_BUS)),  1, ndc, nb);
0103 end
0104 Cg_on = sparse(1:ng, e2i(mpc.gen(:, GEN_BUS)), mpc.gen(:, GEN_STATUS), ng, nb);
0105 Cg = sparse(1:ng, e2i(mpc.gen(:, GEN_BUS)), 1, ng, nb);
0106 
0107 if nnz(C)
0108     n = length(varargin);
0109     if n >= 1 && iscell(varargin{1})
0110         groups = varargin{1};
0111         z = 1;
0112     else
0113         groups = {};
0114         z = 0;
0115     end
0116     if z+1 <= n
0117         k = varargin{z+1};
0118     else
0119         k = [];
0120     end
0121     if z+2 <= n
0122         custom = varargin{z+2};
0123     else
0124         custom = struct();
0125     end
0126     
0127     %% find islands, if not provided
0128     if isempty(groups)
0129         groups = connected_components(C_on);
0130     end
0131     
0132     %% check inputs
0133     if isempty(k)
0134         g1 = 1;
0135         gn = length(groups);
0136     else
0137         if ischar(k)
0138             if strcmp(upper(k), 'ALL')
0139                 k = (1:length(groups))';
0140             else
0141                 error('extract_islands: K = ''%s'' is not a valid input', k);
0142             end
0143         end
0144         if max(k) > length(groups)
0145             error('extract_islands: cannot extract island %d, network has only %d islands', ...
0146                     max(k), length(groups));
0147         end
0148         if length(k) > 1        %% extract multiple islands as one case
0149             tmpgroup = groups{k(1)};
0150             for j = 2:length(k)
0151                 tmpgroup = union(tmpgroup, groups{k(j)});
0152             end
0153             groups = { tmpgroup };
0154             g1 = 1;
0155             gn = 1;
0156         else                    %% extract single island
0157             g1 = k;
0158             gn = k;
0159         end
0160     end
0161     
0162     %% extract islands
0163     for i = g1:gn
0164         kk  = i-g1+1;
0165         b  = groups{i};                     %% buses in group i
0166         %% branches with both ends in group i
0167         ibr = find(sum(abs(C(:, b)), 2) & ~sum(C(:, b), 2));
0168         ig  = find(sum(Cg(:, b), 2));       %% gens in group i
0169         %% DC lines with both ends in group i
0170         if ndc
0171             idc = find(sum(abs(Cdc(:, b)), 2) & ~sum(Cdc(:, b), 2));
0172         else
0173             idc = [];
0174         end
0175     
0176         mpck{kk}        = mpc;
0177         mpck{kk}.bus    = mpc.bus(b, :);
0178         mpck{kk}.branch = mpc.branch(ibr, :);
0179         mpck{kk}.gen    = mpc.gen(ig, :);
0180         if isfield(mpck{kk}, 'gencost')
0181             if size(mpck{kk}.gencost, 1) == 2*ng
0182                 mpck{kk}.gencost = mpc.gencost([ig; ng+ig], :);
0183             else
0184                 mpck{kk}.gencost = mpc.gencost(ig, :);
0185             end
0186         end
0187         if ndc
0188             mpck{kk}.dcline = mpc.dcline(idc, :);
0189             if isfield(mpck{kk}, 'dclinecost')
0190                 mpck{kk}.dclinecost = mpc.dclinecost(idc, :);
0191             end
0192         end
0193 
0194         %% handle custom fields
0195         orderings = {'bus', 'gen', 'branch', 'dcline'};
0196         indexes = {b, ig, ibr, idc};
0197 
0198         for n = 1:length(orderings)
0199             ord = orderings{n};
0200             if isfield(custom, ord)
0201                 for dim = 1:length(custom.(ord))
0202                     for j = 1:length(custom.(ord){dim})
0203                         s = [];
0204                         field = custom.(ord){dim}{j};
0205                         if ischar(field)
0206                             field = { field };
0207                         end
0208 
0209                         tmp = mpck{kk}; %% check this for presence of sub-fields
0210                         skip = 0;
0211                         for i = 1:length(field)
0212                             s(i).type = '.';
0213                             s(i).subs = field{i};
0214                             if isfield(tmp, field{i}) && ~isempty(tmp.(field{i}))
0215                                 %% have sub-field, continue
0216                                 tmp = tmp.(field{i});
0217                             else
0218                                 %% sub-field doesn't exist, skip it
0219                                 skip = 1;
0220                                 break;
0221                             end
0222                         end
0223                         if ~skip
0224                             mpck{kk} = subsasgn(mpck{kk}, s, get_reorder(subsref(mpck{kk}, s), indexes{n}, dim));
0225                         end
0226                     end
0227                 end
0228             end
0229         end
0230     end
0231 
0232     %% convert from cell array to single MATPOWER case struct as appropriate
0233     if ~isempty(k)
0234         mpck = mpck{1};
0235     end
0236 else
0237     mpck = [];
0238 end

Generated on Fri 16-Dec-2016 12:45:37 by m2html © 2005