0001 function hh = plot_gen(md, idx, varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
0050 MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
0051 QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
0052
0053
0054 my_xlabel = 'Period';
0055 nt = md.idx.nt;
0056 ng = size(md.mpc.gen, 1);
0057 nj_max = max(md.idx.nj);
0058 nc_max = max(max(md.idx.nc));
0059
0060
0061 if nargin < 2
0062 idx = [];
0063 end
0064 if isempty(idx)
0065 idx = (1:ng)';
0066 end
0067 nidx = length(idx);
0068 if nidx > 1 && size(idx, 1) == 1
0069 idx = idx';
0070 end
0071 b = md.mpc.gen(idx, GEN_BUS);
0072
0073
0074 opt = struct( ...
0075 'saveit', false, ...
0076 'saveall', false, ...
0077 'savepath', '', ...
0078 'savename', 'gen-%s.pdf', ...
0079 'tol', 1e-3, ...
0080 'size_factor', 1, ...
0081 'show_grid', true, ...
0082 'show_Pc', true, ...
0083 'show_variable_Pmax', 1, ...
0084 'show_limits', 1, ...
0085 'show_contingencies', 1, ...
0086 'show_reserves', 0 );
0087
0088
0089 if mod(length(varargin), 2)
0090 if ~isstruct(varargin{1})
0091 error('plot_gen: Single OPT argument must be a struct');
0092 end
0093 myopt = varargin{1};
0094 k = 2;
0095 else
0096 myopt = struct;
0097 k = 1;
0098 end
0099 while k < length(varargin)
0100 opt_name = varargin{k};
0101 opt_val = varargin{k+1};
0102 if ~isfield(opt, opt_name)
0103 error('plot_gen: ''%s'' is not a valid option name', opt_name);
0104 end
0105 myopt.(opt_name) = opt_val;
0106 k = k + 2;
0107 end
0108 fields = fieldnames(myopt);
0109 for f = 1:length(fields)
0110 opt.(fields{f}) = myopt.(fields{f});
0111 end
0112
0113
0114 if opt.saveall && nidx > 1
0115 if isempty(strfind(opt.savename, '%s'))
0116 error('plot_gen: ''savename'' must include a ''%s'' placeholder when ''saveall'' option is true.');
0117 end
0118 for i = 1:nidx
0119 plot_gen(md, idx(i), opt, 'saveit', true);
0120 end
0121 end
0122
0123
0124 if isfield(md.mpc, 'genfuel')
0125 gf = md.mpc.genfuel{idx};
0126 else
0127 gf = '';
0128 end
0129 p = (1:nt)';
0130 Pg = zeros(nt, nj_max);
0131 Pgk = NaN(nt, nj_max, nc_max);
0132 maxPmax = -Inf(nt, 1);
0133 minPmin = Inf(nt, 1);
0134 Pmax = NaN(nt, nj_max);
0135 ncPmax = NaN(nt, nj_max);
0136 ncPg = NaN(nt, nj_max);
0137
0138
0139 constantPmax = 1;
0140 constantPmin = 1;
0141 for t = 1:nt
0142 maxPmax(t) = sum(md.flow(t,1,1).mpc.gen(idx, PMAX), 1);
0143 minPmin(t) = sum(md.flow(t,1,1).mpc.gen(idx, PMIN), 1);
0144 for j = 1:md.idx.nj(t)
0145 if sum(md.flow(t,j,1).mpc.gen(idx, PMAX), 1) ~= maxPmax(t)
0146 constantPmax = 0;
0147 if maxPmax(t) < sum(md.flow(t,j,1).mpc.gen(idx, PMAX), 1);
0148 maxPmax(t) = sum(md.flow(t,j,1).mpc.gen(idx, PMAX), 1);
0149 end
0150 end
0151 if sum(md.flow(t,j,1).mpc.gen(idx, PMIN), 1) ~= minPmin(t)
0152 constantPmin = 0;
0153 if minPmin(t) > sum(md.flow(t,j,1).mpc.gen(idx, PMIN), 1);
0154 minPmin(t) = sum(md.flow(t,j,1).mpc.gen(idx, PMIN), 1);
0155 end
0156 end
0157 Pg(t,j) = sum(md.flow(t,j,1).mpc.gen(idx, PG), 1);
0158 for k = 1:md.idx.nc(t,j)
0159 Pgk(t,j,k) = sum(md.flow(t,j,k+1).mpc.gen(idx, PG), 1);
0160 end
0161 Pmax(t,j) = sum(md.flow(t,j,1).mpc.gen(idx, PMAX), 1);
0162 if abs(Pmax(t,j) - Pg(t,j)) > opt.tol
0163 ncPmax(t,j) = Pmax(t,j);
0164 ncPg(t,j) = Pg(t,j);
0165 end
0166 end
0167 end
0168 ePg = sum(md.results.ExpectedDispatch(idx, :), 1);
0169 Pc = sum(md.results.Pc(idx, :), 1)';
0170 Rpp = sum(md.results.Rpp(idx, :), 1)';
0171 Rpm = sum(md.results.Rpm(idx, :), 1)';
0172 Rrp = sum(md.results.Rrp(idx, :), 1)';
0173 Rrm = sum(md.results.Rrm(idx, :), 1)';
0174 Gmax = Pc + Rpp;
0175 Gmin = Pc - Rpm;
0176
0177
0178
0179 plot(p, maxPmax+0.001, 'LineStyle', 'none')
0180 hold on
0181 plot(p, minPmin-0.001, 'LineStyle', 'none')
0182
0183
0184 maxPg = max(Pg, [], 2)+0.001;
0185 minPg = min(Pg, [], 2)-0.001;
0186 patch([p;p(end:-1:1); p(1)], [minPg; maxPg(end:-1:1); minPg(1)], 0.95*[1 1 1], 'LineStyle', 'none')
0187
0188
0189 v = axis;
0190 if v(3) > 0
0191 v(3) = 0;
0192 elseif v(4) < 0
0193 v(4) = 0;
0194 end
0195 if opt.show_reserves
0196 if v(4) < max([max(Rpp), max(Rpm), max(Rrp), max(Rrm)])
0197 v(4) = max([max(Rpp), max(Rpm), max(Rrp), max(Rrm)]) + 0.001;
0198 end
0199 end
0200
0201
0202 if opt.show_grid
0203 m = v(3) - 100*(v(4) - v(3));
0204 M = v(4) + 100*(v(4) - v(3));
0205 for k = 0:nt
0206 line([k; k], [m; M], 'LineWidth', 0.25, 'Color', 0.9*[1 1 1]);
0207 end
0208 end
0209 axis(v);
0210
0211
0212 if opt.show_reserves
0213 plot(p, Rpp, '-.', 'Color', 0.8*[0 1 0], 'LineWidth', 1);
0214 plot(p, Rpm, '-.', 'Color', 0.9*[1 0 0], 'LineWidth', 1);
0215 plot(p, [NaN; Rrp], ':', 'Color', 0.8*[0 1 0], 'LineWidth', 1);
0216 plot(p, [NaN; Rrm], ':', 'Color', 0.9*[1 0 0], 'LineWidth', 1);
0217 end
0218 plot(p, Pg, '-', 'Color', 0.8*[1 1 1], 'LineWidth', 1);
0219 if opt.show_Pc
0220 plot(p, Pc, '--', 'Color', 0.5*[1 1 1], 'LineWidth', 2);
0221 end
0222 plot(p, Gmax, '--', 'Color', 0.8*[0 1 0], 'LineWidth', 1);
0223 plot(p, Gmin, '--', 'Color', 0.9*[1 0 0], 'LineWidth', 1);
0224 plot(p, ePg', 'Color', [0 0 1], 'LineWidth', 2);
0225 if nc_max && opt.show_contingencies
0226 plot(p, reshape(Pgk, nt, nj_max*nc_max), 'x');
0227 end
0228 plot(p, Pg, 'o', 'MarkerSize', 6*opt.size_factor);
0229
0230
0231 if opt.show_limits
0232 plot(p, maxPmax, ':k', 'LineWidth', 1);
0233 plot(p, minPmin, ':k', 'LineWidth', 1);
0234 end
0235 if ~constantPmax && opt.show_variable_Pmax
0236
0237 plot(p, Pmax, 'v', 'MarkerSize', 6*opt.size_factor);
0238
0239
0240 end
0241
0242 hold off;
0243
0244 if nidx == 1
0245 if ~isempty(md.Storage.UnitIdx)
0246 s = find(idx == md.Storage.UnitIdx);
0247 else
0248 s = 0;
0249 end
0250 if s
0251 title(sprintf('Real Power Output for Storage Unit %d (Gen %d) @ Bus %d', s, idx, b), 'FontSize', 18*opt.size_factor);
0252 else
0253 tt = sprintf('Real Power Output for Gen %d @ Bus %d', idx, b);
0254 if ~isempty(gf)
0255 tt = sprintf('%s (%s)', tt, gf);
0256 end
0257 title(tt, 'FontSize', 18*opt.size_factor);
0258 end
0259 else
0260 if nidx == ng && all(idx == (1:ng)')
0261 txt = 'All';
0262 else
0263 txt = 'Selected';
0264 end
0265 title(sprintf('Real Power Output for %s Generators', txt), 'FontSize', 18*opt.size_factor);
0266 end
0267 ylabel('Real Power, MW', 'FontSize', 16*opt.size_factor);
0268 xlabel(my_xlabel, 'FontSize', 16*opt.size_factor);
0269
0270 set(gca, 'FontSize', 12*opt.size_factor);
0271 h = gcf;
0272 set(h, 'PaperOrientation', 'landscape');
0273
0274 set(h, 'PaperPosition', [0 0 11 8.5]);
0275 if opt.saveit || opt.saveall
0276 if nidx == 1
0277 txt = sprintf('%d', idx);
0278 elseif nidx == ng && all(idx == (1:ng)')
0279 txt = 'all';
0280 else
0281 txt = 'selected';
0282 end
0283 if isempty(strfind(opt.savename, '%s'))
0284 pdf_name = opt.savename;
0285 else
0286 pdf_name = sprintf(opt.savename, txt);
0287 end
0288 print('-dpdf', fullfile(opt.savepath, pdf_name));
0289 end
0290 if nargout
0291 hh = h;
0292 end