Home > matpower7.1 > lib > apply_changes.m

apply_changes

PURPOSE ^

APPLY_CHANGES Applies a set of changes to a MATPOWER case

SYNOPSIS ^

function mpc = apply_changes(label, mpc, chgtab)

DESCRIPTION ^

APPLY_CHANGES  Applies a set of changes to a MATPOWER case
   mpc_modified = apply_changes(label, mpc_original, chgtab)

   Applies the set of changes identified by LABEL to the case in MPC, where
   the change sets are specified in CHGTAB.

   LABEL is an integer which identifies the set of changes of interest

   MPC is a MATPOWER case struct with at least fields bus, gen and branch

   CHGTAB is the table of changes that lists the individual changes required
   by each change set, one "change" per row (multiple rows or changes
   allowed for each change set). Type "help idx_ct" for more complete
   information about the format.
   1st column: change set label, integer > 0
   2nd column: change set probability
   3rd column: table to be modified (1:bus, 2:gen, 3:branch) or
               4: bus area changes, apply to all gens/buses/branches in
               a given area; 5: gen table area changes apply to all
               generators in a given area; or 6: branch area changes apply
               to all branches connected to buses in a given area.
   4th column: row of table to be modified (if 3rd col is 1-3),
               or area number for overall changes (if 3rd column is 4-6).
   5th column: column of table to be modified. It is best to use the
               named column index defined in the corresponding idx_bus,
               idx_gen, idx_branch or idx_cost M-files in MATPOWER.
   6th column: type of change: 1: absolute (replace)
                               2: relative (multiply by factor)
                               3: additive (add to value)
   7th column: new value or multiplicative or additive factor

   Examples:

   chgtab = [ ...
       1   0.1   CT_TGEN       2  GEN_STATUS     CT_REP  0;
       2   0.05  CT_TGEN       3  PMAX           CT_REP  100;
       3   0.2   CT_TBRCH      2  BR_STATUS      CT_REP  0;
       4   0.1   CT_TAREALOAD  2  CT_LOAD_ALL_P  CT_REL  1.1;
    ];

   Description of each change set:
   1. Turn off generator 2, 10% probability.
   2. Set generator 3's max output to 100 MW, 5% probability.
   3. Take branch 2 out of service, 20% probability.
   4. Scale all loads in area 2 (real & reactive, fixed and dispatchable)
      by a factor of 1.1, 10% probability.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function mpc = apply_changes(label, mpc, chgtab)
0002 %APPLY_CHANGES  Applies a set of changes to a MATPOWER case
0003 %   mpc_modified = apply_changes(label, mpc_original, chgtab)
0004 %
0005 %   Applies the set of changes identified by LABEL to the case in MPC, where
0006 %   the change sets are specified in CHGTAB.
0007 %
0008 %   LABEL is an integer which identifies the set of changes of interest
0009 %
0010 %   MPC is a MATPOWER case struct with at least fields bus, gen and branch
0011 %
0012 %   CHGTAB is the table of changes that lists the individual changes required
0013 %   by each change set, one "change" per row (multiple rows or changes
0014 %   allowed for each change set). Type "help idx_ct" for more complete
0015 %   information about the format.
0016 %   1st column: change set label, integer > 0
0017 %   2nd column: change set probability
0018 %   3rd column: table to be modified (1:bus, 2:gen, 3:branch) or
0019 %               4: bus area changes, apply to all gens/buses/branches in
0020 %               a given area; 5: gen table area changes apply to all
0021 %               generators in a given area; or 6: branch area changes apply
0022 %               to all branches connected to buses in a given area.
0023 %   4th column: row of table to be modified (if 3rd col is 1-3),
0024 %               or area number for overall changes (if 3rd column is 4-6).
0025 %   5th column: column of table to be modified. It is best to use the
0026 %               named column index defined in the corresponding idx_bus,
0027 %               idx_gen, idx_branch or idx_cost M-files in MATPOWER.
0028 %   6th column: type of change: 1: absolute (replace)
0029 %                               2: relative (multiply by factor)
0030 %                               3: additive (add to value)
0031 %   7th column: new value or multiplicative or additive factor
0032 %
0033 %   Examples:
0034 %
0035 %   chgtab = [ ...
0036 %       1   0.1   CT_TGEN       2  GEN_STATUS     CT_REP  0;
0037 %       2   0.05  CT_TGEN       3  PMAX           CT_REP  100;
0038 %       3   0.2   CT_TBRCH      2  BR_STATUS      CT_REP  0;
0039 %       4   0.1   CT_TAREALOAD  2  CT_LOAD_ALL_P  CT_REL  1.1;
0040 %    ];
0041 %
0042 %   Description of each change set:
0043 %   1. Turn off generator 2, 10% probability.
0044 %   2. Set generator 3's max output to 100 MW, 5% probability.
0045 %   3. Take branch 2 out of service, 20% probability.
0046 %   4. Scale all loads in area 2 (real & reactive, fixed and dispatchable)
0047 %      by a factor of 1.1, 10% probability.
0048 
0049 %   To do:
0050 %       - check for valid row number
0051 
0052 %   MATPOWER
0053 %   Copyright (c) 2000-2016, Power Systems Engineering Research Center (PSERC)
0054 %   by Carlos E. Murillo-Sanchez, PSERC Cornell & Universidad Nacional de Colombia
0055 %   and Ray Zimmerman, PSERC Cornell
0056 %
0057 %   This file is part of MATPOWER.
0058 %   Covered by the 3-clause BSD License (see LICENSE file for details).
0059 %   See https://matpower.org for more info.
0060 
0061 %% define named indices into data matrices
0062 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
0063     VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
0064 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
0065     MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
0066     QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
0067 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ...
0068     TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ...
0069     ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;
0070 [PW_LINEAR, POLYNOMIAL, MODEL, STARTUP, SHUTDOWN, NCOST, COST] = idx_cost;
0071 [CT_LABEL, CT_PROB, CT_TABLE, CT_TBUS, CT_TGEN, CT_TBRCH, CT_TAREABUS, ...
0072     CT_TAREAGEN, CT_TAREABRCH, CT_ROW, CT_COL, CT_CHGTYPE, CT_REP, ...
0073     CT_REL, CT_ADD, CT_NEWVAL, CT_TLOAD, CT_TAREALOAD, CT_LOAD_ALL_PQ, ...
0074     CT_LOAD_FIX_PQ, CT_LOAD_DIS_PQ, CT_LOAD_ALL_P, CT_LOAD_FIX_P, ...
0075     CT_LOAD_DIS_P, CT_TGENCOST, CT_TAREAGENCOST, CT_MODCOST_F, ...
0076     CT_MODCOST_X] = idx_ct;
0077 
0078 %% find the change set to be applied
0079 kk = find(label == chgtab(:, CT_LABEL));
0080 if isempty(kk)
0081     error('apply_changes: LABEL %d not found in CHGTAB', label);
0082 end
0083 
0084 %% create map of external bus numbers to bus indices
0085 i2e = mpc.bus(:, BUS_I);
0086 e2i = sparse(max(i2e), 1);
0087 e2i(i2e) = (1:size(mpc.bus, 1))';
0088 
0089 for c = 1:length(kk)
0090     %% extract data for individual change to be applied
0091     %% (c-th change in specified change set)
0092     change = num2cell(chgtab(kk(c), :));
0093     [tbl, row, col, typ, val] = ...
0094         deal(change{[CT_TABLE, CT_ROW, CT_COL, CT_CHGTYPE, CT_NEWVAL]});
0095 
0096     %% apply the change
0097     if tbl == CT_TBUS                               %% modify bus table
0098       if ~any(col == [PD QD GS BS VMAX VMIN])
0099         error('apply_changes: modification to column %d of bus table not supported', col);
0100       end
0101       if row == 0                                       %% modify all rows
0102         if typ == CT_REP                                    %% replace
0103           mpc.bus(:, col) = val * ones(size(mpc.bus, 1), 1);
0104         elseif typ == CT_REL                                %% scale
0105           mpc.bus(:, col) = val * mpc.bus(:, col);
0106         elseif typ == CT_ADD                                %% shift
0107           mpc.bus(:, col) = val + mpc.bus(:, col);
0108         else
0109           error('apply_changes: unsupported modification type %d for bus table', typ);
0110         end
0111       else                                              %% modify single row
0112         if typ == CT_REP                                    %% replace
0113           mpc.bus(row, col) = val;
0114         elseif typ == CT_REL                                %% scale
0115           mpc.bus(row, col) = val * mpc.bus(row, col);
0116         elseif typ == CT_ADD                                %% shift
0117           mpc.bus(row, col) = val + mpc.bus(row, col);             
0118         else
0119           error('apply_changes: unsupported modification type %d for bus table', typ);
0120         end
0121       end
0122     elseif tbl == CT_TBRCH                          %% modify branch table
0123       if ~any(col == ...
0124             [BR_R BR_X BR_B RATE_A RATE_B RATE_C TAP SHIFT BR_STATUS ANGMIN ANGMAX])
0125         error('apply_changes: modification to column %d of branch table not supported', col);
0126       end
0127       if row == 0                                       %% modify all rows
0128         if typ == CT_REP                                    %% replace
0129           mpc.branch(:, col) = val * ones(size(mpc.branch, 1), 1);
0130         elseif typ == CT_REL                                %% scale
0131           mpc.branch(:, col) = val * mpc.branch(:, col);
0132         elseif typ == CT_ADD                                %% shift
0133           mpc.branch(:, col) = val + mpc.branch(:, col);
0134         else
0135           error('apply_changes: unsupported modification type %d for branch table', typ);
0136         end
0137       else                                              %% modify single row
0138         if typ == CT_REP                                    %% replace
0139           mpc.branch(row, col) = val;
0140         elseif typ == CT_REL                                %% scale
0141           mpc.branch(row, col) = val * mpc.branch(row, col);
0142         elseif typ == CT_ADD                                %% shift
0143           mpc.branch(row, col) = val + mpc.branch(row, col);
0144         else
0145           error('apply_changes: unsupported modification type %d for branch table', typ);
0146         end
0147       end
0148     elseif tbl == CT_TGEN                           %% modify gen table
0149       if ~any(col == ...
0150             [QMAX QMIN GEN_STATUS PMAX PMIN PC1 PC2 QC1MIN QC1MAX QC2MIN  QC2MAX ...
0151             RAMP_AGC RAMP_10 RAMP_30 RAMP_Q APF])
0152         error('apply_changes: modification to column %d of gen table not supported', col);
0153       end
0154       if row == 0                                       %% modify all rows
0155         if typ == CT_REP                                    %% replace
0156           mpc.gen(:, col) = val * ones(size(mpc.gen, 1), 1);
0157         elseif typ == CT_REL                                %% scale
0158           mpc.gen(:, col) = val * mpc.gen(:, col);
0159         elseif typ == CT_ADD                                %% shift
0160           mpc.gen(:, col) = val + mpc.gen(:, col);
0161         else
0162           error('apply_changes: unsupported modification type %d for gen table', typ);
0163         end
0164       else                                              %% modify single row
0165         if typ == CT_REP                                    %% replace
0166           mpc.gen(row, col) = val;
0167         elseif typ == CT_REL                                %% scale
0168           mpc.gen(row, col) = val * mpc.gen(row, col);
0169         elseif typ == CT_ADD                                %% shift
0170           mpc.gen(row, col) = val + mpc.gen(row, col);
0171         else
0172           error('apply_changes: unsupported modification type %d for gen table', typ);
0173         end
0174       end
0175     elseif tbl == CT_TGENCOST                       %% modify gencost table
0176       if col == CT_MODCOST_F || col == CT_MODCOST_X     %% use modcost to scale/shift cost
0177         if typ == CT_REL
0178           if col == CT_MODCOST_F
0179             modcost_type = 'SCALE_F';
0180           else  %% col == CT_MODCOST_X
0181             modcost_type = 'SCALE_X';
0182           end
0183         elseif typ == CT_ADD
0184           if col == CT_MODCOST_F
0185             modcost_type = 'SHIFT_F';
0186           else  %% col == CT_MODCOST_X
0187             modcost_type = 'SHIFT_X';
0188           end
0189         else
0190             error('apply_changes: unsupported modification type %d for gencost table CT_MODCOST_F/X modification', typ);
0191         end
0192         if row == 0
0193           mpc.gencost = modcost(mpc.gencost, val, modcost_type);
0194         else
0195           mpc.gencost(row, :) = modcost(mpc.gencost(row, :), val, modcost_type);
0196         end
0197       else                                              %% normal individual column mod
0198         if col < 1 || fix(col) ~= col   %% needs to be positive integer
0199           error('apply_changes: modification to column %d of gencost table not supported', col);
0200         end
0201         if row == 0                                       %% modify all rows
0202           if typ == CT_REP                                    %% replace
0203             mpc.gencost(:, col) = val * ones(size(mpc.gencost, 1), 1);
0204           elseif typ == CT_REL                                %% scale
0205             mpc.gencost(:, col) = val * mpc.gencost(:, col);
0206           elseif typ == CT_ADD                                %% shift
0207             mpc.gencost(:, col) = val + mpc.gencost(:, col);
0208           else
0209             error('apply_changes: unsupported modification type %d for gencost table', typ);
0210           end
0211         else                                              %% modify single row
0212           if typ == CT_REP                                    %% replace
0213             mpc.gencost(row, col) = val;
0214           elseif typ == CT_REL                                %% scale
0215             mpc.gencost(row, col) = val * mpc.gencost(row, col);
0216           elseif typ == CT_ADD                                %% shift
0217             mpc.gencost(row, col) = val + mpc.gencost(row, col);
0218           else
0219             error('apply_changes: unsupported modification type %d for gencost table', typ);
0220           end
0221         end
0222       end
0223     elseif tbl == CT_TAREABUS                   %% area-wide mod to bus table
0224       if ~any(col == [PD QD GS BS VMAX VMIN])
0225         error('apply_changes: area-wide modification to column %d of bus table not supported', col);
0226       end
0227       jj = find(mpc.bus(:, BUS_AREA) == row);
0228       if typ == CT_REP                                      %% replace
0229         mpc.bus(jj, col) = val * ones(size(jj));
0230       elseif typ == CT_REL                                  %% scale
0231         mpc.bus(jj, col) = val * mpc.bus(jj, col);
0232       elseif typ == CT_ADD                                  %% shift
0233         mpc.bus(jj, col) = val + mpc.bus(jj, col);
0234       else
0235         error('apply_changes: unsupported area-wide modification type %d for bus table', typ);
0236       end
0237     elseif tbl == CT_TAREABRCH                  %% area-wide mod to branch table
0238       if ~any(col == ...
0239             [BR_R BR_X BR_B RATE_A RATE_B RATE_C TAP SHIFT BR_STATUS ANGMIN ANGMAX])
0240         error('apply_changes: area-wide modification to column %d of branch table not supported', col);
0241       end
0242       jj = find((row == mpc.bus(e2i(mpc.branch(:, F_BUS)), BUS_AREA)) | ...
0243                 (row == mpc.bus(e2i(mpc.branch(:, T_BUS)), BUS_AREA)) );
0244       if typ == CT_REP                                      %% replace
0245         mpc.branch(jj, col) = val * ones(size(jj));
0246       elseif typ == CT_REL                                  %% scale
0247         mpc.branch(jj, col) = val * mpc.branch(jj, col);
0248       elseif typ == CT_ADD                                  %% shift
0249         mpc.branch(jj, col) = val + mpc.branch(jj, col);
0250       else
0251         error('apply_changes: unsupported area-wide modification type %d for branch table', typ);
0252       end
0253     elseif tbl == CT_TAREAGEN                   %% area-wide mod to gen table
0254       if ~any(col == ...
0255             [QMAX QMIN GEN_STATUS PMAX PMIN PC1 PC2 QC1MIN QC1MAX QC2MIN  QC2MAX ...
0256             RAMP_AGC RAMP_10 RAMP_30 RAMP_Q APF])
0257         error('apply_changes: area-wide modification to column %d of gen table not supported', col);
0258       end
0259       jj = find(row == mpc.bus(e2i(mpc.gen(:, GEN_BUS)), BUS_AREA));
0260       if typ == CT_REP                                      %% replace
0261         mpc.gen(jj, col) = val * ones(size(jj));
0262       elseif typ == CT_REL                                  %% scale
0263         mpc.gen(jj, col) = val * mpc.gen(jj, col);
0264       elseif typ == CT_ADD                                  %% shift
0265         mpc.gen(jj, col) = val + mpc.gen(jj, col);
0266       else
0267         error('apply_changes: unsupported area-wide modification type %d for gen table', typ);
0268       end
0269     elseif tbl == CT_TAREAGENCOST               %% area-wide mod to gencost table
0270       jj = find(row == mpc.bus(e2i(mpc.gen(:, GEN_BUS)), BUS_AREA));
0271       if col == CT_MODCOST_F || col == CT_MODCOST_X
0272         if typ == CT_REL
0273           if col == CT_MODCOST_F
0274             modcost_type = 'SCALE_F';
0275           else  %% col == CT_MODCOST_X
0276             modcost_type = 'SCALE_X';
0277           end
0278         elseif typ == CT_ADD
0279           if col == CT_MODCOST_F
0280             modcost_type = 'SHIFT_F';
0281           else  %% col == CT_MODCOST_X
0282             modcost_type = 'SHIFT_X';
0283           end
0284         else
0285             error('apply_changes: unsupported area-wide modification type %d for gencost table CT_MODCOST_F/X modification', typ);
0286         end
0287         mpc.gencost(jj, :) = modcost(mpc.gencost(jj, :), val, modcost_type);
0288       else
0289         if col < 1 || fix(col) ~= col   %% needs to be positive integer
0290           error('apply_changes: area-wide modification to column %d of gencost table not supported', col);
0291         end
0292         if typ == CT_REP                                      %% replace
0293           mpc.gencost(jj, col) = val * ones(size(jj));
0294         elseif typ == CT_REL                                  %% scale
0295           mpc.gencost(jj, col) = val * mpc.gencost(jj, col);
0296         elseif typ == CT_ADD                                  %% shift
0297           mpc.gencost(jj, col) = val + mpc.gencost(jj, col);
0298         else
0299           error('apply_changes: unsupported area-wide modification type %d for gencost table', typ);
0300         end
0301       end
0302     elseif tbl == CT_TLOAD || tbl == CT_TAREALOAD           %% modify loads
0303       if ~any(abs(col) == (CT_LOAD_ALL_PQ:CT_LOAD_DIS_P))
0304         error('apply_changes: column=%d for load modifications is not supported', col);
0305       end
0306       switch abs(col)
0307         case {CT_LOAD_ALL_PQ, CT_LOAD_FIX_PQ, CT_LOAD_DIS_PQ}
0308             opt.pq = 'PQ';
0309         case {CT_LOAD_ALL_P, CT_LOAD_FIX_P, CT_LOAD_DIS_P}
0310             opt.pq = 'P';
0311       end
0312       switch abs(col)
0313         case {CT_LOAD_ALL_PQ, CT_LOAD_ALL_P}
0314             opt.which = 'BOTH';
0315         case {CT_LOAD_FIX_PQ, CT_LOAD_FIX_P}
0316             opt.which = 'FIXED';
0317         case {CT_LOAD_DIS_PQ, CT_LOAD_DIS_P}
0318             opt.which = 'DISPATCHABLE';
0319       end
0320 
0321       %% define load_zone
0322       if tbl == CT_TLOAD
0323         nb = size(mpc.bus, 1);
0324         if row == 0                                     %% modify load at all buses
0325           load_zone = ones(nb, 1);
0326         else                                            %% modify load at single bus
0327           load_zone = zeros(nb, 1);
0328           load_zone(row) = 1;
0329         end
0330       elseif tbl == CT_TAREALOAD
0331         load_zone = double(mpc.bus(:, BUS_AREA) == row);  %% modify load in single area
0332       end
0333 
0334       switch typ
0335         case CT_REP                                     %% replace
0336             opt.scale = 'QUANTITY';
0337             dmd = val;
0338         case CT_REL                                     %% scale
0339             opt.scale = 'FACTOR';
0340             dmd = val;
0341         case CT_ADD                                     %% shift
0342             opt.scale = 'QUANTITY';
0343             old_val = total_load(mpc, load_zone);
0344             dmd = old_val + val;
0345         otherwise
0346           error('apply_changes: unsupported modification type %d for loads', typ);
0347       end
0348       %% scale the loads ...
0349       if col < 0    %% ... including dispatchable load costs
0350           [mpc.bus, mpc.gen, mpc.gencost] = scale_load(dmd, mpc.bus, mpc.gen, load_zone, opt, mpc.gencost);
0351       else          %% ... not including dispatchable load costs
0352           [mpc.bus, mpc.gen] = scale_load(dmd, mpc.bus, mpc.gen, load_zone, opt);
0353       end
0354     else
0355       error('apply_changes: CHGTAB attempts to modify unsupported table type')
0356     end
0357 end

Generated on Fri 09-Oct-2020 11:21:31 by m2html © 2005