Home > matpower4.1 > scale_load.m

scale_load

PURPOSE ^

SCALE_LOAD Scales fixed and/or dispatchable loads.

SYNOPSIS ^

function [bus, gen] = scale_load(load, bus, gen, load_zone, opt)

DESCRIPTION ^

SCALE_LOAD Scales fixed and/or dispatchable loads.
   BUS = SCALE_LOAD(LOAD, BUS);
   [BUS, GEN] = SCALE_LOAD(LOAD, BUS, GEN, LOAD_ZONE, OPT)

   Scales active (and optionally reactive) loads in each zone by a
   zone-specific ratio, i.e. R(k) for zone k. Inputs are ...

   LOAD - Each element specifies the amount of scaling for the
       corresponding load zone, either as a direct scale factor
       or as a target quantity. If there are nz load zones this
       vector has nz elements.

   BUS - standard BUS matrix with nb rows, where the fixed active
       and reactive loads available for scaling are specified in
       columns PD and QD

   GEN - (optional) standard GEN matrix with ng rows, where the
       dispatchable loads available for scaling are specified by
       columns PG, QG, PMIN, QMIN and QMAX (in rows for which
       ISLOAD(GEN) returns true). If GEN is empty, it assumes
       there are no dispatchable loads.

   LOAD_ZONE - (optional) nb element vector where the value of
       each element is either zero or the index of the load zone
       to which the corresponding bus belongs. If LOAD_ZONE(b) = k
       then the loads at bus b will be scaled according to the
       value of LOAD(k). If LOAD_ZONE(b) = 0, the loads at bus b
       will not be modified. If LOAD_ZONE is empty, the default is
       determined by the dimensions of the LOAD vector. If LOAD is
       a scalar, a single system-wide zone including all buses is
       used, i.e. LOAD_ZONE = ONES(nb, 1). If LOAD is a vector, the
       default LOAD_ZONE is defined as the areas specified in the
       BUS matrix, i.e. LOAD_ZONE = BUS(:, BUS_AREA), and LOAD
       should have dimension = MAX(BUS(:, BUS_AREA)).

   OPT - (optional) struct with three possible fields, 'scale',
       'pq' and 'which' that determine the behavior as follows:

     OPT.scale (default is 'FACTOR')
       'FACTOR'   : LOAD consists of direct scale factors, where
                    LOAD(k) = scale factor R(k) for zone k
       'QUANTITY' : LOAD consists of target quantities, where
                    LOAD(k) = desired total active load in MW for
                    zone k after scaling by an appropriate R(k)

     OPT.pq    (default is 'PQ')
       'PQ' : scale both active and reactive loads
       'P'  : scale only active loads

     OPT.which (default is 'BOTH' if GEN is provided, else 'FIXED')
       'FIXED'        : scale only fixed loads
       'DISPATCHABLE' : scale only dispatchable loads
       'BOTH'         : scale both fixed and dispatchable loads

   Examples:
       Scale all real and reactive fixed loads up by 10%.

       bus = scale_load(1.1, bus);

       Scale all active loads (fixed and dispatchable) at the first 10
       buses so their total equals 100 MW, and at next 10 buses so their
       total equals 50 MW.

       load_zone = zeros(nb, 1);
       load_zone(1:10) = 1;
       load_zone(11:20) = 2;
       opt = struct('pq', 'P', 'scale', 'QUANTITY');
       load = [100; 50];
       [bus, gen] = scale_load(load, bus, gen, load_zone, opt);

   See also TOTAL_LOAD.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [bus, gen] = scale_load(load, bus, gen, load_zone, opt)
0002 %SCALE_LOAD Scales fixed and/or dispatchable loads.
0003 %   BUS = SCALE_LOAD(LOAD, BUS);
0004 %   [BUS, GEN] = SCALE_LOAD(LOAD, BUS, GEN, LOAD_ZONE, OPT)
0005 %
0006 %   Scales active (and optionally reactive) loads in each zone by a
0007 %   zone-specific ratio, i.e. R(k) for zone k. Inputs are ...
0008 %
0009 %   LOAD - Each element specifies the amount of scaling for the
0010 %       corresponding load zone, either as a direct scale factor
0011 %       or as a target quantity. If there are nz load zones this
0012 %       vector has nz elements.
0013 %
0014 %   BUS - standard BUS matrix with nb rows, where the fixed active
0015 %       and reactive loads available for scaling are specified in
0016 %       columns PD and QD
0017 %
0018 %   GEN - (optional) standard GEN matrix with ng rows, where the
0019 %       dispatchable loads available for scaling are specified by
0020 %       columns PG, QG, PMIN, QMIN and QMAX (in rows for which
0021 %       ISLOAD(GEN) returns true). If GEN is empty, it assumes
0022 %       there are no dispatchable loads.
0023 %
0024 %   LOAD_ZONE - (optional) nb element vector where the value of
0025 %       each element is either zero or the index of the load zone
0026 %       to which the corresponding bus belongs. If LOAD_ZONE(b) = k
0027 %       then the loads at bus b will be scaled according to the
0028 %       value of LOAD(k). If LOAD_ZONE(b) = 0, the loads at bus b
0029 %       will not be modified. If LOAD_ZONE is empty, the default is
0030 %       determined by the dimensions of the LOAD vector. If LOAD is
0031 %       a scalar, a single system-wide zone including all buses is
0032 %       used, i.e. LOAD_ZONE = ONES(nb, 1). If LOAD is a vector, the
0033 %       default LOAD_ZONE is defined as the areas specified in the
0034 %       BUS matrix, i.e. LOAD_ZONE = BUS(:, BUS_AREA), and LOAD
0035 %       should have dimension = MAX(BUS(:, BUS_AREA)).
0036 %
0037 %   OPT - (optional) struct with three possible fields, 'scale',
0038 %       'pq' and 'which' that determine the behavior as follows:
0039 %
0040 %     OPT.scale (default is 'FACTOR')
0041 %       'FACTOR'   : LOAD consists of direct scale factors, where
0042 %                    LOAD(k) = scale factor R(k) for zone k
0043 %       'QUANTITY' : LOAD consists of target quantities, where
0044 %                    LOAD(k) = desired total active load in MW for
0045 %                    zone k after scaling by an appropriate R(k)
0046 %
0047 %     OPT.pq    (default is 'PQ')
0048 %       'PQ' : scale both active and reactive loads
0049 %       'P'  : scale only active loads
0050 %
0051 %     OPT.which (default is 'BOTH' if GEN is provided, else 'FIXED')
0052 %       'FIXED'        : scale only fixed loads
0053 %       'DISPATCHABLE' : scale only dispatchable loads
0054 %       'BOTH'         : scale both fixed and dispatchable loads
0055 %
0056 %   Examples:
0057 %       Scale all real and reactive fixed loads up by 10%.
0058 %
0059 %       bus = scale_load(1.1, bus);
0060 %
0061 %       Scale all active loads (fixed and dispatchable) at the first 10
0062 %       buses so their total equals 100 MW, and at next 10 buses so their
0063 %       total equals 50 MW.
0064 %
0065 %       load_zone = zeros(nb, 1);
0066 %       load_zone(1:10) = 1;
0067 %       load_zone(11:20) = 2;
0068 %       opt = struct('pq', 'P', 'scale', 'QUANTITY');
0069 %       load = [100; 50];
0070 %       [bus, gen] = scale_load(load, bus, gen, load_zone, opt);
0071 %
0072 %   See also TOTAL_LOAD.
0073 
0074 %   MATPOWER
0075 %   $Id: scale_load.m,v 1.15 2011/07/08 20:37:01 cvs Exp $
0076 %   by Ray Zimmerman, PSERC Cornell
0077 %   Copyright (c) 2004-2010 by Power System Engineering Research Center (PSERC)
0078 %
0079 %   This file is part of MATPOWER.
0080 %   See http://www.pserc.cornell.edu/matpower/ for more info.
0081 %
0082 %   MATPOWER is free software: you can redistribute it and/or modify
0083 %   it under the terms of the GNU General Public License as published
0084 %   by the Free Software Foundation, either version 3 of the License,
0085 %   or (at your option) any later version.
0086 %
0087 %   MATPOWER is distributed in the hope that it will be useful,
0088 %   but WITHOUT ANY WARRANTY; without even the implied warranty of
0089 %   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0090 %   GNU General Public License for more details.
0091 %
0092 %   You should have received a copy of the GNU General Public License
0093 %   along with MATPOWER. If not, see <http://www.gnu.org/licenses/>.
0094 %
0095 %   Additional permission under GNU GPL version 3 section 7
0096 %
0097 %   If you modify MATPOWER, or any covered work, to interface with
0098 %   other modules (such as MATLAB code and MEX-files) available in a
0099 %   MATLAB(R) or comparable environment containing parts covered
0100 %   under other licensing terms, the licensors of MATPOWER grant
0101 %   you additional permission to convey the resulting work.
0102 
0103 %% define constants
0104 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
0105     VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
0106 %% purposely being backward compatible with older MATPOWER
0107 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, ...
0108     PMAX, PMIN, MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN] = idx_gen;
0109 
0110 nb = size(bus, 1);          %% number of buses
0111 
0112 %%-----  process inputs  -----
0113 if nargin < 5
0114     opt = struct;
0115     if nargin < 4
0116         load_zone = [];
0117         if nargin < 3
0118             gen = [];
0119         end
0120     end
0121 end
0122 
0123 %% fill out and check opt
0124 if isempty(gen)
0125     opt.which = 'FIXED';
0126 end
0127 if ~isfield(opt, 'pq')
0128     opt.pq = 'PQ';          %% 'PQ' or 'P'
0129 end
0130 if ~isfield(opt, 'which')
0131     opt.which = 'BOTH';     %% 'FIXED', 'DISPATCHABLE' or 'BOTH'
0132 end
0133 if ~isfield(opt, 'scale')
0134     opt.scale = 'FACTOR';   %% 'FACTOR' or 'QUANTITY'
0135 end
0136 if ~strcmp(opt.pq, 'P') && ~strcmp(opt.pq, 'PQ')
0137     error('scale_load: opt.pq must equal ''PQ'' or ''P''');
0138 end
0139 if opt.which(1) ~= 'F' && opt.which(1) ~= 'D' && opt.which(1) ~= 'B'
0140     error('scale_load: opt.which should be ''FIXED'', ''DISPATCHABLE'' or ''BOTH''');
0141 end
0142 if opt.scale(1) ~= 'F' && opt.scale(1) ~= 'Q'
0143     error('scale_load: opt.scale should be ''FACTOR'' or ''QUANTITY''');
0144 end
0145 if isempty(gen) && opt.which(1) ~= 'F'
0146     error('scale_load: need gen matrix to scale dispatchable loads');
0147 end
0148 
0149 %% create dispatchable load connection matrix
0150 if ~isempty(gen)
0151     ng = size(gen, 1);
0152     is_ld = isload(gen) & gen(:, GEN_STATUS) > 0;
0153     ld = find(is_ld);
0154 
0155     %% create map of external bus numbers to bus indices
0156     i2e = bus(:, BUS_I);
0157     e2i = sparse(max(i2e), 1);
0158     e2i(i2e) = (1:nb)';
0159 
0160     Cld = sparse(e2i(gen(:, GEN_BUS)), (1:ng)', is_ld, nb, ng);
0161 else
0162     ng = [];
0163     ld = [];
0164 end
0165 
0166 if isempty(load_zone)
0167     if length(load) == 1        %% make a single zone of all load buses
0168         load_zone = zeros(nb, 1);                           %% initialize
0169         load_zone(bus(:, PD) ~= 0 | bus(:, QD) ~= 0) = 1;   %% FIXED loads
0170         if ~isempty(gen)
0171             load_zone(e2i(gen(ld, GEN_BUS))) = 1;   %% DISPATCHABLE loads
0172         end
0173     else                        %% use areas defined in bus data as zones
0174         load_zone = bus(:, BUS_AREA);
0175     end
0176 end
0177 
0178 %% check load_zone to make sure it's consistent with size of load vector
0179 if max(load_zone) > length(load)
0180     error('scale_load: load vector must have a value for each load zone specified');
0181 end
0182 
0183 %%-----  compute scale factors for each zone  -----
0184 scale = load;
0185 Pdd = zeros(nb, 1);     %% dispatchable P at each bus
0186 if opt.scale(1) == 'Q'  %% 'QUANTITY'
0187     %% find load capacity from dispatchable loads
0188     if ~isempty(gen)
0189         Pdd = -Cld * gen(:, PMIN);
0190     end
0191 
0192     %% compute scale factors
0193     for k = 1:length(load)
0194         idx = find( load_zone == k );
0195         fixed = sum(bus(idx, PD));
0196         dispatchable = sum(Pdd(idx));
0197         total = fixed + dispatchable;
0198         if opt.which(1) == 'B'      %% 'BOTH'
0199             if total ~= 0
0200                 scale(k) = load(k) / total;
0201             elseif load(k) == total
0202                 scale(k) = 1;
0203             else
0204                 error('scale_load: impossible to make zone %d load equal %g by scaling non-existent loads', k, load(k));
0205             end
0206         elseif opt.which(1) == 'F'  %% 'FIXED'
0207             if fixed ~= 0
0208                 scale(k) = (load(k) - dispatchable) / fixed;
0209             elseif load(k) == dispatchable
0210                 scale(k) = 1;
0211             else
0212                 error('scale_load: impossible to make zone %d load equal %g by scaling non-existent fixed load', k, load(k));
0213             end
0214         elseif opt.which(1) == 'D'  %% 'DISPATCHABLE'
0215             if dispatchable ~= 0
0216                 scale(k) = (load(k) - fixed) / dispatchable;
0217             elseif load(k) == fixed
0218                 scale(k) = 1;
0219             else
0220                 error('scale_load: impossible to make zone %d load equal %g by scaling non-existent dispatchable load', k, load(k));
0221             end
0222         end
0223     end
0224 end
0225 
0226 %%-----  do the scaling  -----
0227 %% fixed loads
0228 if opt.which(1) ~= 'D'      %% includes 'FIXED', not 'DISPATCHABLE' only
0229     for k = 1:length(scale)
0230         idx = find( load_zone == k );
0231         bus(idx, PD) = bus(idx, PD) * scale(k);
0232         if strcmp(opt.pq, 'PQ')
0233             bus(idx, QD) = bus(idx, QD) * scale(k);
0234         end
0235     end
0236 end
0237 
0238 %% dispatchable loads
0239 if opt.which(1) ~= 'F'      %% includes 'DISPATCHABLE', not 'FIXED' only
0240     for k = 1:length(scale)
0241         idx = find( load_zone == k );
0242         [junk, i, junk2] = intersect(e2i(gen(ld, GEN_BUS)), idx);
0243         ig = ld(i);
0244 
0245         gen(ig, [PG PMIN]) = gen(ig, [PG PMIN]) * scale(k);
0246         if strcmp(opt.pq, 'PQ')
0247             gen(ig, [QG QMIN QMAX]) = gen(ig, [QG QMIN QMAX]) * scale(k);
0248         end
0249     end
0250 end

Generated on Mon 26-Jan-2015 15:00:13 by m2html © 2005