UOPF Solves combined unit decommitment / optimal power flow. [RESULTS, SUCCESS] = UOPF(MPC, MPOPT) Returns either a RESULTS struct and an optional SUCCESS flag, or individual data matrices, the objective function value and a SUCCESS flag. In the latter case, there are additional optional return values. See Examples below for the possible calling syntax options. Examples: Output argument options: results = uopf(...) [results, success] = uopf(...) [bus, gen, branch, f, success] = uopf(...) [bus, gen, branch, f, success, info, et, g, jac, xr, pimul] = uopf(...) Input arguments options: uopf(mpc) uopf(mpc, mpopt) uopf(mpc, userfcn, mpopt) uopf(mpc, A, l, u) uopf(mpc, A, l, u, mpopt) uopf(mpc, A, l, u, mpopt, N, fparm, H, Cw) uopf(mpc, A, l, u, mpopt, N, fparm, H, Cw, z0, zl, zu) uopf(baseMVA, bus, gen, branch, areas, gencost) uopf(baseMVA, bus, gen, branch, areas, gencost, mpopt) uopf(baseMVA, bus, gen, branch, areas, gencost, userfcn, mpopt) uopf(baseMVA, bus, gen, branch, areas, gencost, A, l, u) uopf(baseMVA, bus, gen, branch, areas, gencost, A, l, u, mpopt) uopf(baseMVA, bus, gen, branch, areas, gencost, A, l, u, ... mpopt, N, fparm, H, Cw) uopf(baseMVA, bus, gen, branch, areas, gencost, A, l, u, ... mpopt, N, fparm, H, Cw, z0, zl, zu) See OPF for more information on input and output arguments. Solves a combined unit decommitment and optimal power flow for a single time period. Uses an algorithm similar to dynamic programming. It proceeds through a sequence of stages, where stage N has N generators shut down, starting with N=0. In each stage, it forms a list of candidates (gens at their Pmin limits) and computes the cost with each one of them shut down. It selects the least cost case as the starting point for the next stage, continuing until there are no more candidates to be shut down or no more improvement can be gained by shutting something down. If VERBOSE in mpopt (see MPOPTION) is true, it prints progress info, if it is > 1 it prints the output of each individual opf. See also OPF, RUNUOPF.
0001 function [bus, gen, branch, f, success, info, et, g, jac, xr, pimul] = ... 0002 uopf(varargin) 0003 %UOPF Solves combined unit decommitment / optimal power flow. 0004 % [RESULTS, SUCCESS] = UOPF(MPC, MPOPT) 0005 % 0006 % Returns either a RESULTS struct and an optional SUCCESS flag, or individual 0007 % data matrices, the objective function value and a SUCCESS flag. In the 0008 % latter case, there are additional optional return values. See Examples 0009 % below for the possible calling syntax options. 0010 % 0011 % Examples: 0012 % Output argument options: 0013 % 0014 % results = uopf(...) 0015 % [results, success] = uopf(...) 0016 % [bus, gen, branch, f, success] = uopf(...) 0017 % [bus, gen, branch, f, success, info, et, g, jac, xr, pimul] = uopf(...) 0018 % 0019 % Input arguments options: 0020 % 0021 % uopf(mpc) 0022 % uopf(mpc, mpopt) 0023 % uopf(mpc, userfcn, mpopt) 0024 % uopf(mpc, A, l, u) 0025 % uopf(mpc, A, l, u, mpopt) 0026 % uopf(mpc, A, l, u, mpopt, N, fparm, H, Cw) 0027 % uopf(mpc, A, l, u, mpopt, N, fparm, H, Cw, z0, zl, zu) 0028 % 0029 % uopf(baseMVA, bus, gen, branch, areas, gencost) 0030 % uopf(baseMVA, bus, gen, branch, areas, gencost, mpopt) 0031 % uopf(baseMVA, bus, gen, branch, areas, gencost, userfcn, mpopt) 0032 % uopf(baseMVA, bus, gen, branch, areas, gencost, A, l, u) 0033 % uopf(baseMVA, bus, gen, branch, areas, gencost, A, l, u, mpopt) 0034 % uopf(baseMVA, bus, gen, branch, areas, gencost, A, l, u, ... 0035 % mpopt, N, fparm, H, Cw) 0036 % uopf(baseMVA, bus, gen, branch, areas, gencost, A, l, u, ... 0037 % mpopt, N, fparm, H, Cw, z0, zl, zu) 0038 % 0039 % See OPF for more information on input and output arguments. 0040 % 0041 % Solves a combined unit decommitment and optimal power flow for a single 0042 % time period. Uses an algorithm similar to dynamic programming. It proceeds 0043 % through a sequence of stages, where stage N has N generators shut down, 0044 % starting with N=0. In each stage, it forms a list of candidates (gens at 0045 % their Pmin limits) and computes the cost with each one of them shut down. 0046 % It selects the least cost case as the starting point for the next stage, 0047 % continuing until there are no more candidates to be shut down or no 0048 % more improvement can be gained by shutting something down. 0049 % If VERBOSE in mpopt (see MPOPTION) is true, it prints progress 0050 % info, if it is > 1 it prints the output of each individual opf. 0051 % 0052 % See also OPF, RUNUOPF. 0053 0054 % MATPOWER 0055 % $Id: uopf.m,v 1.24 2010/06/29 19:24:35 ray Exp $ 0056 % by Ray Zimmerman, PSERC Cornell 0057 % Copyright (c) 1996-2010 by Power System Engineering Research Center (PSERC) 0058 % 0059 % This file is part of MATPOWER. 0060 % See http://www.pserc.cornell.edu/matpower/ for more info. 0061 % 0062 % MATPOWER is free software: you can redistribute it and/or modify 0063 % it under the terms of the GNU General Public License as published 0064 % by the Free Software Foundation, either version 3 of the License, 0065 % or (at your option) any later version. 0066 % 0067 % MATPOWER is distributed in the hope that it will be useful, 0068 % but WITHOUT ANY WARRANTY; without even the implied warranty of 0069 % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0070 % GNU General Public License for more details. 0071 % 0072 % You should have received a copy of the GNU General Public License 0073 % along with MATPOWER. If not, see <http://www.gnu.org/licenses/>. 0074 % 0075 % Additional permission under GNU GPL version 3 section 7 0076 % 0077 % If you modify MATPOWER, or any covered work, to interface with 0078 % other modules (such as MATLAB code and MEX-files) available in a 0079 % MATLAB(R) or comparable environment containing parts covered 0080 % under other licensing terms, the licensors of MATPOWER grant 0081 % you additional permission to convey the resulting work. 0082 0083 %%----- initialization ----- 0084 t0 = clock; %% start timer 0085 0086 %% process input arguments 0087 [mpc, mpopt] = opf_args(varargin{:}); 0088 0089 %% options 0090 verbose = mpopt(31); %% VERBOSE 0091 if verbose %% turn down verbosity one level for calls to opf 0092 mpopt = mpoption(mpopt, 'VERBOSE', verbose-1); 0093 end 0094 0095 %% define named indices into bus, gen, branch matrices 0096 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ... 0097 VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus; 0098 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ... 0099 MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ... 0100 QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen; 0101 0102 %%----- do combined unit commitment/optimal power flow ----- 0103 0104 %% check for sum(Pmin) > total load, decommit as necessary 0105 on = find( mpc.gen(:, GEN_STATUS) > 0 & ~isload(mpc.gen) ); %% gens in service 0106 onld = find( mpc.gen(:, GEN_STATUS) > 0 & isload(mpc.gen) ); %% disp loads in serv 0107 load_capacity = sum(mpc.bus(:, PD)) - sum(mpc.gen(onld, PMIN)); %% total load capacity 0108 Pmin = mpc.gen(on, PMIN); 0109 while sum(Pmin) > load_capacity 0110 %% shut down most expensive unit 0111 avgPmincost = totcost(mpc.gencost(on, :), Pmin) ./ Pmin; 0112 [junk, i] = fairmax(avgPmincost); %% pick one with max avg cost at Pmin 0113 i = on(i); %% convert to generator index 0114 0115 if verbose 0116 fprintf('Shutting down generator %d so all Pmin limits can be satisfied.\n', i); 0117 end 0118 0119 %% set generation to zero 0120 mpc.gen(i, [ PG QG GEN_STATUS ]) = 0; 0121 0122 %% update minimum gen capacity 0123 on = find( mpc.gen(:, GEN_STATUS) > 0 & ~isload(mpc.gen) ); %% gens in service 0124 Pmin = mpc.gen(on, PMIN); 0125 end 0126 0127 %% run initial opf 0128 [results, success] = opf(mpc, mpopt); 0129 0130 %% best case so far 0131 results1 = results; 0132 0133 %% best case for this stage (ie. with n gens shut down, n=0,1,2 ...) 0134 results0 = results1; 0135 mpc.bus = results0.bus; %% use these V as starting point for OPF 0136 0137 while 1 0138 %% get candidates for shutdown 0139 candidates = find(results0.gen(:, MU_PMIN) > 0 & results0.gen(:, PMIN) > 0); 0140 if isempty(candidates) 0141 break; 0142 end 0143 done = 1; %% do not check for further decommitment unless we 0144 %% see something better during this stage 0145 for i = 1:length(candidates) 0146 k = candidates(i); 0147 %% start with best for this stage 0148 mpc.gen = results0.gen; 0149 0150 %% shut down gen k 0151 mpc.gen(k, [ PG QG GEN_STATUS ]) = 0; 0152 0153 %% run opf 0154 [results, success] = opf(mpc, mpopt); 0155 0156 %% something better? 0157 if success && results.f < results1.f 0158 results1 = results; 0159 k1 = k; 0160 done = 0; %% make sure we check for further decommitment 0161 end 0162 end 0163 0164 if done 0165 %% decommits at this stage did not help, so let's quit 0166 break; 0167 else 0168 %% shutting something else down helps, so let's keep going 0169 if verbose 0170 fprintf('Shutting down generator %d.\n', k1); 0171 end 0172 0173 results0 = results1; 0174 mpc.bus = results0.bus; %% use these V as starting point for OPF 0175 end 0176 end 0177 0178 %% compute elapsed time 0179 et = etime(clock, t0); 0180 0181 %% finish preparing output 0182 if nargout > 0 0183 success = results0.success; 0184 if nargout <= 2 0185 results0.et = et; 0186 bus = results0; 0187 gen = success; 0188 else 0189 [bus, gen, branch, f, info, xr, pimul] = deal(results0.bus, results0.gen, ... 0190 results0.branch, results0.f, results0.raw.info, ... 0191 results0.raw.xr, results0.raw.pimul); 0192 if isfield(results0, 'g') 0193 g = results0.g; 0194 end 0195 if isfield(results0, 'dg') 0196 jac = results0.dg; 0197 end 0198 end 0199 elseif results0.success 0200 results0.et = et; 0201 printpf(results0, 1, mpopt); 0202 end