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

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