Home > matpower7.1 > lib > uopf.m

uopf

PURPOSE ^

UOPF Solves combined unit decommitment / optimal power flow.

SYNOPSIS ^

function [bus, gen, branch, f, success, info, et, g, jac, xr, pimul] =uopf(varargin)

DESCRIPTION ^

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 MPOPT.verbose (see MPOPTION) is true, it prints progress
   info, if it is > 1 it prints the output of each individual opf.

   See also OPF, RUNUOPF.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

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 MPOPT.verbose (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 %   Copyright (c) 1996-2016, Power Systems Engineering Research Center (PSERC)
0056 %   by Ray Zimmerman, PSERC Cornell
0057 %
0058 %   This file is part of MATPOWER.
0059 %   Covered by the 3-clause BSD License (see LICENSE file for details).
0060 %   See https://matpower.org for more info.
0061 
0062 %%----- initialization -----
0063 t0 = tic;       %% start timer
0064 
0065 %% process input arguments
0066 [mpc, mpopt] = opf_args(varargin{:});
0067 
0068 %% options
0069 if mpopt.verbose    %% turn down verbosity one level for calls to opf
0070     mpopt = mpoption(mpopt, 'verbose', mpopt.verbose-1);
0071 end
0072 
0073 %% define named indices into bus, gen, branch matrices
0074 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ...
0075     VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;
0076 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ...
0077     MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ...
0078     QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;
0079 
0080 %%-----  do combined unit commitment/optimal power flow  -----
0081 
0082 %% check for sum(Pmin) > total load, decommit as necessary
0083 on   = find( mpc.gen(:, GEN_STATUS) > 0 & ~isload(mpc.gen) );   %% gens in service
0084 onld = find( mpc.gen(:, GEN_STATUS) > 0 &  isload(mpc.gen) );   %% disp loads in serv
0085 load_capacity = sum(mpc.bus(:, PD)) - sum(mpc.gen(onld, PMIN)); %% total load capacity
0086 Pmin = mpc.gen(on, PMIN);
0087 while sum(Pmin) > load_capacity
0088     %% shut down most expensive unit
0089     avgPmincost = totcost(mpc.gencost(on, :), Pmin) ./ Pmin;
0090     [junk, i] = fairmax(avgPmincost);   %% pick one with max avg cost at Pmin
0091     i = on(i);                          %% convert to generator index
0092 
0093     if mpopt.verbose
0094         fprintf('Shutting down generator %d so all Pmin limits can be satisfied.\n', i);
0095     end
0096 
0097     %% set generation to zero
0098     mpc.gen(i, [ PG QG GEN_STATUS ]) = 0;
0099     
0100     %% update minimum gen capacity
0101     on  = find( mpc.gen(:, GEN_STATUS) > 0 & ~isload(mpc.gen) );   %% gens in service
0102     Pmin = mpc.gen(on, PMIN);
0103 end
0104 if ~any(mpc.gen(:, GEN_STATUS) > 0)     %% don't bother to run anything if
0105     success = 0;                        %% everything has been shut down
0106     results0 = mpc;
0107     results0.success = success;
0108     results0.f = NaN;
0109     results0.et = 0;
0110     if mpopt.verbose
0111         fprintf('Infeasible problem, Pmin limits cannot be satisfied without shutting down all generators.\n');
0112     end
0113 else
0114     %% run initial opf
0115     [results, success] = opf(mpc, mpopt);
0116 
0117     %% best case so far
0118     results1 = results;
0119 
0120     %% best case for this stage (ie. with n gens shut down, n=0,1,2 ...)
0121     results0 = results1;
0122     mpc.bus = results0.bus;     %% use these V as starting point for OPF
0123 
0124     while 1
0125         %% get candidates for shutdown
0126         candidates = find(results0.gen(:, MU_PMIN) > 0 & results0.gen(:, PMIN) > 0);
0127         if isempty(candidates)
0128             break;
0129         end
0130         done = 1;   %% do not check for further decommitment unless we
0131                     %%  see something better during this stage
0132         for i = 1:length(candidates)
0133             k = candidates(i);
0134             %% start with best for this stage
0135             mpc.gen = results0.gen;
0136         
0137             %% shut down gen k
0138             mpc.gen(k, [ PG QG GEN_STATUS ]) = 0;
0139         
0140             %% run opf
0141             if any(mpc.gen(:, GEN_STATUS) > 0)
0142                 [results, success] = opf(mpc, mpopt);
0143             else
0144                 success = 0;
0145             end
0146         
0147             %% something better?
0148             if success && results.f < results1.f
0149                 results1 = results;
0150                 k1 = k;
0151                 done = 0;   %% make sure we check for further decommitment
0152             end
0153         end
0154 
0155         if done
0156             %% decommits at this stage did not help, so let's quit
0157             break;
0158         else
0159             %% shutting something else down helps, so let's keep going
0160             if mpopt.verbose
0161                 fprintf('Shutting down generator %d.\n', k1);
0162             end
0163         
0164             results0 = results1;
0165             mpc.bus = results0.bus;     %% use these V as starting point for OPF
0166         end 
0167     end
0168 end
0169 
0170 %% compute elapsed time
0171 et = toc(t0);
0172 
0173 %% finish preparing output
0174 if nargout > 0
0175   success = results0.success;
0176   if nargout <= 2
0177     results0.et = et;
0178     bus = results0;
0179     gen = success;
0180   else
0181     [bus, gen, branch, f, info, xr, pimul] = deal(results0.bus, results0.gen, ...
0182                     results0.branch, results0.f, results0.raw.info, ...
0183                     results0.raw.xr, results0.raw.pimul);
0184     if isfield(results0, 'g')
0185       g = results0.g;
0186     end
0187     if isfield(results0, 'dg')
0188       jac = results0.dg;
0189     end
0190   end
0191 elseif results0.success
0192   results0.et = et;
0193   printpf(results0, 1, mpopt);
0194 end
0195 
0196 
0197 function [val, idx] = fairmax(x)
0198 %FAIRMAX    Same as built-in MAX, except breaks ties randomly.
0199 %   [VAL, IDX] = FAIRMAX(X) takes a vector as an argument and returns
0200 %   the same output as the built-in function MAX with two output
0201 %   parameters, except that where the maximum value occurs at more
0202 %   than one position in the  vector, the index is chosen randomly
0203 %   from these positions as opposed to just choosing the first occurance.
0204 %
0205 %   See also MAX.
0206 
0207 val = max(x);               %% find max value
0208 i   = find(x == val);       %% find all positions where this occurs
0209 n   = length(i);            %% number of occurences
0210 idx = i( fix(n*rand)+1 );   %% select index randomly among occurances

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