HASPQCAP Checks for P-Q capability curve constraints. TORF = HASPQCAP(GEN, HILO) returns a column vector of 1's and 0's. The 1's correspond to rows of the GEN matrix which correspond to generators which have defined a capability curve (with sloped upper and/or lower bound on Q) and require that additional linear constraints be added to the OPF. The GEN matrix in version 2 of the MATPOWER case format includes columns for specifying a P-Q capability curve for a generator defined as the intersection of two half-planes and the box constraints on P and Q. The two half planes are defined respectively as the area below the line connecting (Pc1, Qc1max) and (Pc2, Qc2max) and the area above the line connecting (Pc1, Qc1min) and (Pc2, Qc2min). If the optional 2nd argument is 'U' this function returns true only for rows corresponding to generators that require the upper constraint on Q. If it is 'L', only for those requiring the lower constraint. If the 2nd argument is not specified or has any other value it returns true for rows corresponding to gens that require either or both of the constraints. It is smart enough to return true only if the corresponding linear constraint is not redundant w.r.t the box constraints.
0001 function TorF = hasPQcap(gen, hilo) 0002 %HASPQCAP Checks for P-Q capability curve constraints. 0003 % TORF = HASPQCAP(GEN, HILO) returns a column vector of 1's and 0's. The 1's 0004 % correspond to rows of the GEN matrix which correspond to generators which 0005 % have defined a capability curve (with sloped upper and/or lower bound on 0006 % Q) and require that additional linear constraints be added to the OPF. 0007 % 0008 % The GEN matrix in version 2 of the MATPOWER case format includes columns 0009 % for specifying a P-Q capability curve for a generator defined as the 0010 % intersection of two half-planes and the box constraints on P and Q. The 0011 % two half planes are defined respectively as the area below the line 0012 % connecting (Pc1, Qc1max) and (Pc2, Qc2max) and the area above the line 0013 % connecting (Pc1, Qc1min) and (Pc2, Qc2min). 0014 % 0015 % If the optional 2nd argument is 'U' this function returns true only for 0016 % rows corresponding to generators that require the upper constraint on Q. 0017 % If it is 'L', only for those requiring the lower constraint. If the 2nd 0018 % argument is not specified or has any other value it returns true for rows 0019 % corresponding to gens that require either or both of the constraints. 0020 % 0021 % It is smart enough to return true only if the corresponding linear 0022 % constraint is not redundant w.r.t the box constraints. 0023 0024 % MATPOWER 0025 % Copyright (c) 2005-2016, Power Systems Engineering Research Center (PSERC) 0026 % by Ray Zimmerman, PSERC Cornell 0027 % 0028 % This file is part of MATPOWER. 0029 % Covered by the 3-clause BSD License (see LICENSE file for details). 0030 % See https://matpower.org for more info. 0031 0032 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ... 0033 MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ... 0034 QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen; 0035 0036 %% default value 0037 if nargin < 2 0038 hilo = 'B'; %% look at both top and bottom by default 0039 end 0040 0041 %% for which gens is it specified 0042 k = find( gen(:, PC1) | gen(:, PC2) ); 0043 ng = size(gen, 1); 0044 0045 if isempty(k) 0046 TorF = zeros(ng, 1); 0047 else 0048 %% eliminate cases where QMIN = QMAX = QC 0049 kk = find( gen(k, QMIN) == gen(k, QMAX) & ... 0050 gen(k, QMIN) == gen(k, QC1MAX) & ... 0051 gen(k, QMIN) == gen(k, QC1MIN) & ... 0052 gen(k, QMIN) == gen(k, QC2MAX) & ... 0053 gen(k, QMIN) == gen(k, QC2MIN) ); 0054 k(kk) = []; 0055 0056 %% check for errors in capability curve data 0057 if any( gen(k, PC1) >= gen(k, PC2) ) 0058 error('hasPQcap: must have Pc1 < Pc2'); 0059 end 0060 if any( gen(k, QC2MAX) <= gen(k, QC2MIN) & gen(k, QC1MAX) <= gen(k, QC1MIN) ) 0061 error('hasPQcap: capability curve defines an empty set'); 0062 end 0063 0064 %% for which gens is it specified 0065 k = find( gen(:, PC1) ~= gen(:, PC2) ); 0066 L = zeros(ng, 1); 0067 U = zeros(ng, 1); 0068 dPc = gen(k, PC2) - gen(k, PC1); 0069 0070 if ~strcmp(hilo, 'U') %% include lower constraint 0071 dQc = gen(k, QC2MIN) - gen(k, QC1MIN); 0072 Qmin_at_Pmin = gen(k, QC1MIN) + (gen(k, PMIN) - gen(k, PC1)) .* ... 0073 dQc ./ dPc; 0074 Qmin_at_Pmax = gen(k, QC1MIN) + (gen(k, PMAX) - gen(k, PC1)) .* ... 0075 dQc ./ dPc; 0076 L(k) = Qmin_at_Pmin > gen(k, QMIN) | Qmin_at_Pmax > gen(k, QMIN); 0077 end 0078 0079 if ~strcmp(hilo, 'L') %% include upper constraint 0080 dQc = gen(k, QC2MAX) - gen(k, QC1MAX); 0081 Qmax_at_Pmin = gen(k, QC1MAX) + (gen(k, PMIN) - gen(k, PC1)) .* ... 0082 dQc ./ dPc; 0083 Qmax_at_Pmax = gen(k, QC1MAX) + (gen(k, PMAX) - gen(k, PC1)) .* ... 0084 dQc ./ dPc; 0085 U(k) = Qmax_at_Pmin < gen(k, QMAX) | Qmax_at_Pmax < gen(k, QMAX); 0086 end 0087 0088 TorF = L | U; 0089 end