Home > matpower7.0 > extras > misc > checklimits.m

checklimits

PURPOSE ^

CHECKLIMITS Checks a solved power flow case for limit violations.

SYNOPSIS ^

function [Fv, Pv, Qv, Vv] = checklimits(mpc, ac, quiet)

DESCRIPTION ^

CHECKLIMITS   Checks a solved power flow case for limit violations.

   [FV, PV] = CHECKLIMITS(MPC)
   [FV, PV, QV, VV] = CHECKLIMITS(MPC, AC)
   [FV, PV, QV, VV] = CHECKLIMITS(MPC, AC, QUIET)

   Inputs:
       MPC : MATPOWER case struct
       AC :  0 = check DC limits, real power flows, Pg limits
             1 = check AC limits (includes |V|, Qg lims, MVA flows)
       QUIET : 1 doesn't print anything, 0 prints results

   Work-in-progress:   Currently only flow and real power generation limit
                       checks are implemented.
                       At this point, the code *is* the documentation.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [Fv, Pv, Qv, Vv] = checklimits(mpc, ac, quiet)
0002 %CHECKLIMITS   Checks a solved power flow case for limit violations.
0003 %
0004 %   [FV, PV] = CHECKLIMITS(MPC)
0005 %   [FV, PV, QV, VV] = CHECKLIMITS(MPC, AC)
0006 %   [FV, PV, QV, VV] = CHECKLIMITS(MPC, AC, QUIET)
0007 %
0008 %   Inputs:
0009 %       MPC : MATPOWER case struct
0010 %       AC :  0 = check DC limits, real power flows, Pg limits
0011 %             1 = check AC limits (includes |V|, Qg lims, MVA flows)
0012 %       QUIET : 1 doesn't print anything, 0 prints results
0013 %
0014 %   Work-in-progress:   Currently only flow and real power generation limit
0015 %                       checks are implemented.
0016 %                       At this point, the code *is* the documentation.
0017 
0018 %   MATPOWER
0019 %   Copyright (c) 2014-2016, Power Systems Engineering Research Center (PSERC)
0020 %   by Ray Zimmerman, PSERC Cornell
0021 %
0022 %   This file is part of MATPOWER Extras.
0023 %   Covered by the 3-clause BSD License (see LICENSE file for details).
0024 %   See https://github.com/MATPOWER/matpower-extras for more info.
0025 
0026 define_constants;
0027 tol = 0.001;
0028 
0029 %% input args
0030 if nargin < 3
0031     quiet = 0;
0032     if nargin < 2
0033         ac = [];
0034     end
0035 end
0036 
0037 %% set default
0038 if isempty(ac)
0039     if any(mpc.bus(:, VM) ~= 1)
0040         ac = 1;
0041     else
0042         ac = 0;
0043     end
0044 end
0045 
0046 %%-----  branch flows  -----
0047 %% get flows
0048 if ac
0049     Ff = sqrt(mpc.branch(:, PF).^2 + mpc.branch(:, QF).^2);
0050     Ft = sqrt(mpc.branch(:, PT).^2 + mpc.branch(:, QT).^2);
0051     F = max(Ff, Ft);
0052 else
0053     F = abs(mpc.branch(:, PF));
0054 end
0055 %% find branch flow violations
0056 Fv.i  = find(F > mpc.branch(:, RATE_A) + tol & mpc.branch(:, RATE_A) > 0);
0057 Fv.ib = find(F > mpc.branch(:, RATE_B) + tol & mpc.branch(:, RATE_B) > 0);
0058 Fv.ic = find(F > mpc.branch(:, RATE_C) + tol & mpc.branch(:, RATE_C) > 0);
0059 %% absolute flow violations
0060 Fv.v  = F(Fv.i)  - mpc.branch(Fv.i, RATE_A);
0061 Fv.vb = F(Fv.ib) - mpc.branch(Fv.ib, RATE_B);
0062 Fv.vc = F(Fv.ic) - mpc.branch(Fv.ic, RATE_C);
0063 %% percentage flow violations
0064 Fv.p  = 100 * Fv.v  ./ mpc.branch(Fv.i, RATE_A);
0065 Fv.pb = 100 * Fv.vb ./ mpc.branch(Fv.ib, RATE_B);
0066 Fv.pc = 100 * Fv.vc ./ mpc.branch(Fv.ic, RATE_C);
0067 %% sort by percentage violation
0068 [Fv.p,  k]  = sort(Fv.p,  'descend');
0069 [Fv.pb, kb] = sort(Fv.pb, 'descend');
0070 [Fv.pc, kc] = sort(Fv.pc, 'descend');
0071 %% reorder indices, absolute violations
0072 Fv.i  = Fv.i(k);
0073 Fv.ib = Fv.ib(kb);
0074 Fv.ic = Fv.ic(kc);
0075 Fv.v  = Fv.v(k);
0076 Fv.vb = Fv.vb(kb);
0077 Fv.vc = Fv.vc(kc);
0078 
0079 %%-----  generator real power  -----
0080 Pg = mpc.gen(:, PG);
0081 %% find Pmin and Pmax violations
0082 Pv.i = find(Pg < mpc.gen(:, PMIN) - tol & mpc.gen(:, GEN_STATUS) > 0);
0083 Pv.I = find(Pg > mpc.gen(:, PMAX) + tol & mpc.gen(:, GEN_STATUS) > 0);
0084 %% absolute gen limit violations
0085 Pv.v = mpc.gen(Pv.i, PMIN) - Pg(Pv.i);
0086 Pv.V = Pg(Pv.I) - mpc.gen(Pv.I, PMAX);
0087 %% percentage gen limit violations
0088 Pv.p = 100 * Pv.v ./ max(abs(mpc.gen(Pv.i, PMIN)), abs(mpc.gen(Pv.i, PMAX)));
0089 Pv.P = 100 * Pv.V ./ max(abs(mpc.gen(Pv.I, PMIN)), abs(mpc.gen(Pv.I, PMAX)));
0090 %% sort by percentage violation
0091 [Pv.p, k] = sort(Pv.p, 'descend');
0092 [Pv.P, K] = sort(Pv.P, 'descend');
0093 %% reorder indices, absolute violations
0094 Pv.i  = Pv.i(k);
0095 Pv.I  = Pv.I(K);
0096 Pv.v  = Pv.v(k);
0097 Pv.V  = Pv.V(K);
0098 
0099 %%-----  generator reactive power  -----
0100 Qg = mpc.gen(:, QG);
0101 %% find Qmin and Qmax violations
0102 Qv.i = find(Qg < mpc.gen(:, QMIN) - tol & mpc.gen(:, GEN_STATUS) > 0);
0103 Qv.I = find(Qg > mpc.gen(:, QMAX) + tol & mpc.gen(:, GEN_STATUS) > 0);
0104 %% absolute gen limit violations
0105 Qv.v = mpc.gen(Qv.i, QMIN) - Qg(Qv.i);
0106 Qv.V = Qg(Qv.I) - mpc.gen(Qv.I, QMAX);
0107 %% percentage gen limit violations
0108 Qv.p = 100 * Qv.v ./ max(abs(mpc.gen(Qv.i, QMIN)), abs(mpc.gen(Qv.i, QMAX)));
0109 Qv.P = 100 * Qv.V ./ max(abs(mpc.gen(Qv.I, QMIN)), abs(mpc.gen(Qv.I, QMAX)));
0110 %% sort by percentage violation
0111 [Qv.p, k] = sort(Qv.p, 'descend');
0112 [Qv.P, K] = sort(Qv.P, 'descend');
0113 %% reorder indices, absolute violations
0114 Qv.i  = Qv.i(k);
0115 Qv.I  = Qv.I(K);
0116 Qv.v  = Qv.v(k);
0117 Qv.V  = Qv.V(K);
0118 
0119 %%-----  bus voltage magnitudes  -----
0120 Vm = mpc.bus(:, VM);
0121 %% find Vmin and Vmax violations
0122 Vv.i = find(Vm < mpc.bus(:, VMIN) - tol);
0123 Vv.I = find(Vm > mpc.bus(:, VMAX) + tol);
0124 %% absolute voltage limit violations
0125 Vv.v = mpc.bus(Vv.i, VMIN) - Vm(Vv.i);
0126 Vv.V = Vm(Vv.I) - mpc.bus(Vv.I, VMAX);
0127 %% percentage voltage limit violations
0128 Vv.p = 100 * Vv.v ./ max(abs(mpc.bus(Vv.i, VMIN)), abs(mpc.bus(Vv.i, VMAX)));
0129 Vv.P = 100 * Vv.V ./ max(abs(mpc.bus(Vv.I, VMIN)), abs(mpc.bus(Vv.I, VMAX)));
0130 %% sort by percentage violation
0131 [Vv.p, k] = sort(Vv.p, 'descend');
0132 [Vv.P, K] = sort(Vv.P, 'descend');
0133 %% reorder indices, absolute violations
0134 Vv.i  = Vv.i(k);
0135 Vv.I  = Vv.I(K);
0136 Vv.v  = Vv.v(k);
0137 Vv.V  = Vv.V(K);
0138 
0139 if ~quiet
0140     fprintf('\n');
0141     if isempty(Fv.ic)
0142         fprintf('No Branch Flow Emergency Rating Violations\n');
0143     else
0144         fprintf('Branch Flow Emergency Rating Violations\n');
0145         fprintf(' branch     from       to        flow        limit     violation  %% violation\n');
0146         fprintf('--------  --------  --------  ----------  ----------  ----------  ----------\n');
0147         for k = 1:length(Fv.ic);
0148             fprintf('%7d  %8d  %8d  %10.1f  %10.1f  %10.2f  %10.1f\n', Fv.ic(k), ...
0149                 mpc.branch(Fv.ic(k), F_BUS), ...
0150                 mpc.branch(Fv.ic(k), T_BUS), ...
0151                 F(Fv.ic(k)), ...
0152                 mpc.branch(Fv.ic(k), RATE_C), ...
0153                 Fv.vc(k), ...
0154                 Fv.pc(k) ...
0155             );
0156         end
0157     end
0158     if isempty(Fv.ib)
0159         fprintf('No Branch Flow Short Term Rating Violations\n');
0160     else
0161         fprintf('Branch Flow Short Term Rating Violations\n');
0162         fprintf(' branch     from       to        flow        limit     violation  %% violation\n');
0163         fprintf('--------  --------  --------  ----------  ----------  ----------  ----------\n');
0164         for k = 1:length(Fv.ib);
0165             fprintf('%7d  %8d  %8d  %10.1f  %10.1f  %10.2f  %10.1f\n', Fv.ib(k), ...
0166                 mpc.branch(Fv.ib(k), F_BUS), ...
0167                 mpc.branch(Fv.ib(k), T_BUS), ...
0168                 F(Fv.ib(k)), ...
0169                 mpc.branch(Fv.ib(k), RATE_B), ...
0170                 Fv.vb(k), ...
0171                 Fv.pb(k) ...
0172             );
0173         end
0174     end
0175     if isempty(Fv.i)
0176         fprintf('No Branch Flow Normal Rating Violations\n');
0177     else
0178         fprintf('Branch Flow Normal Rating Violations\n');
0179         fprintf(' branch     from       to        flow        limit     violation  %% violation\n');
0180         fprintf('--------  --------  --------  ----------  ----------  ----------  ----------\n');
0181         for k = 1:length(Fv.i);
0182             fprintf('%7d  %8d  %8d  %10.1f  %10.1f  %10.2f  %10.1f\n', Fv.i(k), ...
0183                 mpc.branch(Fv.i(k), F_BUS), ...
0184                 mpc.branch(Fv.i(k), T_BUS), ...
0185                 F(Fv.i(k)), ...
0186                 mpc.branch(Fv.i(k), RATE_A), ...
0187                 Fv.v(k), ...
0188                 Fv.p(k) ...
0189             );
0190         end
0191     end
0192 
0193     fprintf('\n');
0194     fprintf('Generator Active Limit Violations\n');
0195     if isempty(Pv.i)
0196         fprintf('No Pmin Violations\n');
0197     else
0198         fprintf('Pmin Violations\n');
0199         fprintf('  gen       bus        Pmin         Pg         Pmax     violation  %% violation\n');
0200         fprintf('--------  --------  ----------  ----------  ----------  ----------  ----------\n');
0201         for k = 1:length(Pv.i);
0202             fprintf('%7d  %8d  %10.1f  %10.1f  %10.1f  %10.2f  %10.1f\n', Pv.i(k), ...
0203                 mpc.gen(Pv.i(k), GEN_BUS), ...
0204                 mpc.gen(Pv.i(k), PMIN), ...
0205                 Pg(Pv.i(k)), ...
0206                 mpc.gen(Pv.i(k), PMAX), ...
0207                 Pv.v(k), ...
0208                 Pv.p(k) ...
0209             );
0210         end
0211     end
0212     if isempty(Pv.I)
0213         fprintf('No Pmax Violations\n');
0214     else
0215         fprintf('Pmax Violations\n');
0216         fprintf('  gen       bus        Pmin         Pg         Pmax     violation  %% violation\n');
0217         fprintf('--------  --------  ----------  ----------  ----------  ----------  ----------\n');
0218         for k = 1:length(Pv.I);
0219             fprintf('%7d  %8d  %10.1f  %10.1f  %10.1f  %10.2f  %10.1f\n', Pv.I(k), ...
0220                 mpc.gen(Pv.I(k), GEN_BUS), ...
0221                 mpc.gen(Pv.I(k), PMIN), ...
0222                 Pg(Pv.I(k)), ...
0223                 mpc.gen(Pv.I(k), PMAX), ...
0224                 Pv.V(k), ...
0225                 Pv.P(k) ...
0226             );
0227         end
0228     end
0229 
0230     fprintf('\n');
0231     fprintf('Generator Reactive Limit Violations\n');
0232     if isempty(Qv.i)
0233         fprintf('No Qmin Violations\n');
0234     else
0235         fprintf('Qmin Violations\n');
0236         fprintf('  gen       bus        Qmin         Qg         Qmax     violation  %% violation\n');
0237         fprintf('--------  --------  ----------  ----------  ----------  ----------  ----------\n');
0238         for k = 1:length(Qv.i);
0239             fprintf('%7d  %8d  %10.1f  %10.1f  %10.1f  %10.2f  %10.1f\n', Qv.i(k), ...
0240                 mpc.gen(Qv.i(k), GEN_BUS), ...
0241                 mpc.gen(Qv.i(k), QMIN), ...
0242                 Qg(Qv.i(k)), ...
0243                 mpc.gen(Qv.i(k), QMAX), ...
0244                 Qv.v(k), ...
0245                 Qv.p(k) ...
0246             );
0247         end
0248     end
0249     if isempty(Qv.I)
0250         fprintf('No Qmax Violations\n');
0251     else
0252         fprintf('Qmax Violations\n');
0253         fprintf('  gen       bus        Qmin         Qg         Qmax     violation  %% violation\n');
0254         fprintf('--------  --------  ----------  ----------  ----------  ----------  ----------\n');
0255         for k = 1:length(Qv.I);
0256             fprintf('%7d  %8d  %10.1f  %10.1f  %10.1f  %10.2f  %10.1f\n', Qv.I(k), ...
0257                 mpc.gen(Qv.I(k), GEN_BUS), ...
0258                 mpc.gen(Qv.I(k), QMIN), ...
0259                 Qg(Qv.I(k)), ...
0260                 mpc.gen(Qv.I(k), QMAX), ...
0261                 Qv.V(k), ...
0262                 Qv.P(k) ...
0263             );
0264         end
0265     end
0266 
0267     fprintf('\n');
0268     fprintf('Bus Voltage Limit Violations\n');
0269     if isempty(Vv.i)
0270         fprintf('No Vmin Violations\n');
0271     else
0272         fprintf('Vmin Violations\n');
0273         fprintf('   bus        Vmin         Vm         Vmax     violation  %% violation\n');
0274         fprintf(' --------  ----------  ----------  ----------  ----------  ----------\n');
0275         for k = 1:length(Vv.i);
0276             fprintf('%8d  %10.2f  %10.2f  %10.2f  %10.2f  %10.2f\n', Vv.i(k), ...
0277                 mpc.bus(Vv.i(k), VMIN), ...
0278                 Vm(Vv.i(k)), ...
0279                 mpc.bus(Vv.i(k), VMAX), ...
0280                 Vv.v(k), ...
0281                 Vv.p(k) ...
0282             );
0283         end
0284     end
0285     if isempty(Vv.I)
0286         fprintf('No Vmax Violations\n');
0287     else
0288         fprintf('Vmax Violations\n');
0289         fprintf('   bus        Vmin         Vm         Vmax     violation  %% violation\n');
0290         fprintf(' --------  ----------  ----------  ----------  ----------  ----------\n');
0291         for k = 1:length(Vv.I);
0292             fprintf('%8d  %10.2f  %10.2f  %10.2f  %10.2f  %10.2f\n', Vv.I(k), ...
0293                 mpc.bus(Vv.I(k), VMIN), ...
0294                 Vm(Vv.I(k)), ...
0295                 mpc.bus(Vv.I(k), VMAX), ...
0296                 Vv.V(k), ...
0297                 Vv.P(k) ...
0298             );
0299         end
0300     end
0301 end

Generated on Mon 24-Jun-2019 15:58:45 by m2html © 2005