OPF Solves an optimal power flow. [RESULTS, SUCCESS] = OPF(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 = opf(...) [results, success] = opf(...) [bus, gen, branch, f, success] = opf(...) [bus, gen, branch, f, success, info, et, g, jac, xr, pimul] = opf(...) Input arguments options: opf(mpc) opf(mpc, mpopt) opf(mpc, userfcn, mpopt) opf(mpc, A, l, u) opf(mpc, A, l, u, mpopt) opf(mpc, A, l, u, mpopt, N, fparm, H, Cw) opf(mpc, A, l, u, mpopt, N, fparm, H, Cw, z0, zl, zu) opf(baseMVA, bus, gen, branch, areas, gencost) opf(baseMVA, bus, gen, branch, areas, gencost, mpopt) opf(baseMVA, bus, gen, branch, areas, gencost, userfcn, mpopt) opf(baseMVA, bus, gen, branch, areas, gencost, A, l, u) opf(baseMVA, bus, gen, branch, areas, gencost, A, l, u, mpopt) opf(baseMVA, bus, gen, branch, areas, gencost, A, l, u, ... mpopt, N, fparm, H, Cw) opf(baseMVA, bus, gen, branch, areas, gencost, A, l, u, ... mpopt, N, fparm, H, Cw, z0, zl, zu) The data for the problem can be specified in one of three ways: (1) a string (mpc) containing the file name of a MATPOWER case which defines the data matrices baseMVA, bus, gen, branch, and gencost (areas is not used at all, it is only included for backward compatibility of the API). (2) a struct (mpc) containing the data matrices as fields. (3) the individual data matrices themselves. The optional user parameters for user constraints (A, l, u), user costs (N, fparm, H, Cw), user variable initializer (z0), and user variable limits (zl, zu) can also be specified as fields in a case struct, either passed in directly or defined in a case file referenced by name. When specified, A, l, u represent additional linear constraints on the optimization variables, l <= A*[x; z] <= u. If the user specifies an A matrix that has more columns than the number of "x" (OPF) variables, then there are extra linearly constrained "z" variables. For an explanation of the formulation used and instructions for forming the A matrix, see the manual. A generalized cost on all variables can be applied if input arguments N, fparm, H and Cw are specified. First, a linear transformation of the optimization variables is defined by means of r = N * [x; z]. Then, to each element of r a function is applied as encoded in the fparm matrix (see manual). If the resulting vector is named w, then H and Cw define a quadratic cost on w: (1/2)*w'*H*w + Cw * w . H and N should be sparse matrices and H should also be symmetric. The optional mpopt vector specifies MATPOWER options. If the OPF algorithm is not explicitly set in the options MATPOWER will use the default solver, based on a primal-dual interior point method. For the AC OPF this is opf.ac.solver = 'MIPS', unless the TSPOPF optional package is installed, in which case the default is 'PDIPM'. For the DC OPF, the default is opf.dc.solver = 'MIPS'. See MPOPTION for more details on the available OPF solvers and other OPF options and their default values. The solved case is returned either in a single results struct (described below) or in the individual data matrices, bus, gen and branch. Also returned are the final objective function value (f) and a flag which is true if the algorithm was successful in finding a solution (success). Additional optional return values are an algorithm specific return status (info), elapsed time in seconds (et), the constraint vector (g), the Jacobian matrix (jac), and the vector of variables (xr) as well as the constraint multipliers (pimul). The single results struct is a MATPOWER case struct (mpc) with the usual baseMVA, bus, branch, gen, gencost fields, along with the following additional fields: .order see 'help ext2int' for details of this field .et elapsed time in seconds for solving OPF .success 1 if solver converged successfully, 0 otherwise .om OPF model object, see 'help opf_model' .x final value of optimization variables (internal order) .f final objective function value .mu shadow prices on ... .var .l lower bounds on variables .u upper bounds on variables .nln .l lower bounds on nonlinear constraints .u upper bounds on nonlinear constraints .lin .l lower bounds on linear constraints .u upper bounds on linear constraints .raw raw solver output in form returned by MINOS, and more .xr final value of optimization variables .pimul constraint multipliers .info solver specific termination code .output solver specific output information .alg algorithm code of solver used .g (optional) constraint values .dg (optional) constraint 1st derivatives .df (optional) obj fun 1st derivatives (not yet implemented) .d2f (optional) obj fun 2nd derivatives (not yet implemented) .var .val optimization variable values, by named block .Va voltage angles .Vm voltage magnitudes (AC only) .Pg real power injections .Qg reactive power injections (AC only) .y constrained cost variable (only if have pwl costs) (other) any user defined variable blocks .mu variable bound shadow prices, by named block .l lower bound shadow prices .Va, Vm, Pg, Qg, y, (other) .u upper bound shadow prices .Va, Vm, Pg, Qg, y, (other) .nle (AC only) .lambda shadow prices on nonlinear equality constraints, by named block .Pmis real power mismatch equations .Qmis reactive power mismatch equations (other) use defined constraints .nli (AC only) .mu shadow prices on nonlinear inequality constraints, by named block .Sf flow limits at "from" end of branches .St flow limits at "to" end of branches (other) use defined constraints .lin .mu shadow prices on linear constraints, by named block .l lower bounds .Pmis real power mistmatch equations (DC only) .Pf flow limits at "from" end of branches (DC only) .Pt flow limits at "to" end of branches (DC only) .PQh upper portion of gen PQ-capability curve (AC only) .PQl lower portion of gen PQ-capability curve (AC only) .vl constant power factor constraint for loads (AC only) .ycon basin constraints for CCV for pwl costs (other) any user defined constraint blocks .u upper bounds .Pmis, Pf, Pt, PQh, PQl, vl, ycon, (other) .cost user defined cost values, by named block See also RUNOPF, DCOPF, UOPF, CASEFORMAT.
0001 function [busout, genout, branchout, f, success, info, et, g, jac, xr, pimul] = ... 0002 opf(varargin) 0003 %OPF Solves an optimal power flow. 0004 % [RESULTS, SUCCESS] = OPF(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 = opf(...) 0015 % [results, success] = opf(...) 0016 % [bus, gen, branch, f, success] = opf(...) 0017 % [bus, gen, branch, f, success, info, et, g, jac, xr, pimul] = opf(...) 0018 % 0019 % Input arguments options: 0020 % 0021 % opf(mpc) 0022 % opf(mpc, mpopt) 0023 % opf(mpc, userfcn, mpopt) 0024 % opf(mpc, A, l, u) 0025 % opf(mpc, A, l, u, mpopt) 0026 % opf(mpc, A, l, u, mpopt, N, fparm, H, Cw) 0027 % opf(mpc, A, l, u, mpopt, N, fparm, H, Cw, z0, zl, zu) 0028 % 0029 % opf(baseMVA, bus, gen, branch, areas, gencost) 0030 % opf(baseMVA, bus, gen, branch, areas, gencost, mpopt) 0031 % opf(baseMVA, bus, gen, branch, areas, gencost, userfcn, mpopt) 0032 % opf(baseMVA, bus, gen, branch, areas, gencost, A, l, u) 0033 % opf(baseMVA, bus, gen, branch, areas, gencost, A, l, u, mpopt) 0034 % opf(baseMVA, bus, gen, branch, areas, gencost, A, l, u, ... 0035 % mpopt, N, fparm, H, Cw) 0036 % opf(baseMVA, bus, gen, branch, areas, gencost, A, l, u, ... 0037 % mpopt, N, fparm, H, Cw, z0, zl, zu) 0038 % 0039 % The data for the problem can be specified in one of three ways: 0040 % (1) a string (mpc) containing the file name of a MATPOWER case 0041 % which defines the data matrices baseMVA, bus, gen, branch, and 0042 % gencost (areas is not used at all, it is only included for 0043 % backward compatibility of the API). 0044 % (2) a struct (mpc) containing the data matrices as fields. 0045 % (3) the individual data matrices themselves. 0046 % 0047 % The optional user parameters for user constraints (A, l, u), user costs 0048 % (N, fparm, H, Cw), user variable initializer (z0), and user variable 0049 % limits (zl, zu) can also be specified as fields in a case struct, 0050 % either passed in directly or defined in a case file referenced by name. 0051 % 0052 % When specified, A, l, u represent additional linear constraints on the 0053 % optimization variables, l <= A*[x; z] <= u. If the user specifies an A 0054 % matrix that has more columns than the number of "x" (OPF) variables, 0055 % then there are extra linearly constrained "z" variables. For an 0056 % explanation of the formulation used and instructions for forming the 0057 % A matrix, see the manual. 0058 % 0059 % A generalized cost on all variables can be applied if input arguments 0060 % N, fparm, H and Cw are specified. First, a linear transformation 0061 % of the optimization variables is defined by means of r = N * [x; z]. 0062 % Then, to each element of r a function is applied as encoded in the 0063 % fparm matrix (see manual). If the resulting vector is named w, 0064 % then H and Cw define a quadratic cost on w: (1/2)*w'*H*w + Cw * w . 0065 % H and N should be sparse matrices and H should also be symmetric. 0066 % 0067 % The optional mpopt vector specifies MATPOWER options. If the OPF 0068 % algorithm is not explicitly set in the options MATPOWER will use 0069 % the default solver, based on a primal-dual interior point method. 0070 % For the AC OPF this is opf.ac.solver = 'MIPS', unless the TSPOPF optional 0071 % package is installed, in which case the default is 'PDIPM'. For the 0072 % DC OPF, the default is opf.dc.solver = 'MIPS'. See MPOPTION for 0073 % more details on the available OPF solvers and other OPF options 0074 % and their default values. 0075 % 0076 % The solved case is returned either in a single results struct (described 0077 % below) or in the individual data matrices, bus, gen and branch. Also 0078 % returned are the final objective function value (f) and a flag which is 0079 % true if the algorithm was successful in finding a solution (success). 0080 % Additional optional return values are an algorithm specific return status 0081 % (info), elapsed time in seconds (et), the constraint vector (g), the 0082 % Jacobian matrix (jac), and the vector of variables (xr) as well 0083 % as the constraint multipliers (pimul). 0084 % 0085 % The single results struct is a MATPOWER case struct (mpc) with the 0086 % usual baseMVA, bus, branch, gen, gencost fields, along with the 0087 % following additional fields: 0088 % 0089 % .order see 'help ext2int' for details of this field 0090 % .et elapsed time in seconds for solving OPF 0091 % .success 1 if solver converged successfully, 0 otherwise 0092 % .om OPF model object, see 'help opf_model' 0093 % .x final value of optimization variables (internal order) 0094 % .f final objective function value 0095 % .mu shadow prices on ... 0096 % .var 0097 % .l lower bounds on variables 0098 % .u upper bounds on variables 0099 % .nln 0100 % .l lower bounds on nonlinear constraints 0101 % .u upper bounds on nonlinear constraints 0102 % .lin 0103 % .l lower bounds on linear constraints 0104 % .u upper bounds on linear constraints 0105 % .raw raw solver output in form returned by MINOS, and more 0106 % .xr final value of optimization variables 0107 % .pimul constraint multipliers 0108 % .info solver specific termination code 0109 % .output solver specific output information 0110 % .alg algorithm code of solver used 0111 % .g (optional) constraint values 0112 % .dg (optional) constraint 1st derivatives 0113 % .df (optional) obj fun 1st derivatives (not yet implemented) 0114 % .d2f (optional) obj fun 2nd derivatives (not yet implemented) 0115 % .var 0116 % .val optimization variable values, by named block 0117 % .Va voltage angles 0118 % .Vm voltage magnitudes (AC only) 0119 % .Pg real power injections 0120 % .Qg reactive power injections (AC only) 0121 % .y constrained cost variable (only if have pwl costs) 0122 % (other) any user defined variable blocks 0123 % .mu variable bound shadow prices, by named block 0124 % .l lower bound shadow prices 0125 % .Va, Vm, Pg, Qg, y, (other) 0126 % .u upper bound shadow prices 0127 % .Va, Vm, Pg, Qg, y, (other) 0128 % .nle (AC only) 0129 % .lambda shadow prices on nonlinear equality constraints, 0130 % by named block 0131 % .Pmis real power mismatch equations 0132 % .Qmis reactive power mismatch equations 0133 % (other) use defined constraints 0134 % .nli (AC only) 0135 % .mu shadow prices on nonlinear inequality constraints, 0136 % by named block 0137 % .Sf flow limits at "from" end of branches 0138 % .St flow limits at "to" end of branches 0139 % (other) use defined constraints 0140 % .lin 0141 % .mu shadow prices on linear constraints, by named block 0142 % .l lower bounds 0143 % .Pmis real power mistmatch equations (DC only) 0144 % .Pf flow limits at "from" end of branches (DC only) 0145 % .Pt flow limits at "to" end of branches (DC only) 0146 % .PQh upper portion of gen PQ-capability curve (AC only) 0147 % .PQl lower portion of gen PQ-capability curve (AC only) 0148 % .vl constant power factor constraint for loads (AC only) 0149 % .ycon basin constraints for CCV for pwl costs 0150 % (other) any user defined constraint blocks 0151 % .u upper bounds 0152 % .Pmis, Pf, Pt, PQh, PQl, vl, ycon, (other) 0153 % .cost user defined cost values, by named block 0154 % 0155 % See also RUNOPF, DCOPF, UOPF, CASEFORMAT. 0156 0157 % MATPOWER 0158 % Copyright (c) 1996-2016, Power Systems Engineering Research Center (PSERC) 0159 % by Ray Zimmerman, PSERC Cornell 0160 % and Carlos E. Murillo-Sanchez, PSERC Cornell & Universidad Nacional de Colombia 0161 % 0162 % This file is part of MATPOWER. 0163 % Covered by the 3-clause BSD License (see LICENSE file for details). 0164 % See https://matpower.org for more info. 0165 0166 %%----- initialization ----- 0167 t0 = tic; %% start timer 0168 0169 %% define named indices into data matrices 0170 [PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ... 0171 VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus; 0172 [GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ... 0173 MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ... 0174 QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen; 0175 [F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ... 0176 TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ... 0177 ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch; 0178 [PW_LINEAR, POLYNOMIAL, MODEL, STARTUP, SHUTDOWN, NCOST, COST] = idx_cost; 0179 0180 %% process input arguments 0181 [mpc, mpopt] = opf_args(varargin{:}); 0182 0183 %% if 'opf.ac.solver' not set, choose MIPS 0184 if strcmp(upper(mpopt.opf.ac.solver), 'DEFAULT') 0185 mpopt = mpoption(mpopt, 'opf.ac.solver', 'MIPS'); %% MIPS 0186 end 0187 0188 %% handle deprecated 'opf.init_from_mpc' option 0189 if mpopt.opf.start == 0 && mpopt.opf.init_from_mpc ~= -1 0190 %% init_from_mpc = 0 --> start = 1 don't use mpc 0191 %% init_from_mpc = 1 --> start = 2 do use mpc 0192 mpopt.opf.start = mpopt.opf.init_from_mpc + 1; 0193 end 0194 0195 %% initialize state with power flow solution, if requested 0196 if mpopt.opf.start == 3 0197 mpopt_pf = mpoption(mpopt, 'out.all', 0, 'verbose', max(0, mpopt.verbose-1)); 0198 if mpopt.verbose 0199 fprintf('Running power flow to initialize OPF.\n'); 0200 end 0201 rpf = runpf(mpc, mpopt_pf); 0202 if rpf.success 0203 mpc = rpf; %% or should I just copy Va, Vm, Pg, Qg? 0204 end 0205 end 0206 0207 %% add zero columns to bus, gen, branch for multipliers, etc if needed 0208 nb = size(mpc.bus, 1); %% number of buses 0209 nl = size(mpc.branch, 1); %% number of branches 0210 ng = size(mpc.gen, 1); %% number of dispatchable injections 0211 if size(mpc.bus,2) < MU_VMIN 0212 mpc.bus = [mpc.bus zeros(nb, MU_VMIN-size(mpc.bus,2)) ]; 0213 end 0214 if size(mpc.gen,2) < MU_QMIN 0215 mpc.gen = [ mpc.gen zeros(ng, MU_QMIN-size(mpc.gen,2)) ]; 0216 end 0217 if size(mpc.branch,2) < MU_ANGMAX 0218 mpc.branch = [ mpc.branch zeros(nl, MU_ANGMAX-size(mpc.branch,2)) ]; 0219 end 0220 0221 %%----- convert to internal numbering, remove out-of-service stuff ----- 0222 mpc = ext2int(mpc, mpopt); 0223 0224 %%----- construct OPF model object ----- 0225 om = opf_setup(mpc, mpopt); 0226 0227 %%----- execute the OPF ----- 0228 if nargout > 7 0229 mpopt.opf.return_raw_der = 1; 0230 end 0231 if ~isempty(mpc.bus) 0232 [results, success, raw] = opf_execute(om, mpopt); 0233 else 0234 results = mpc; 0235 success = 0; 0236 raw.output.message = 'MATPOWER case contains no connected buses'; 0237 if mpopt.verbose 0238 fprintf('OPF not valid : %s', raw.output.message); 0239 end 0240 end 0241 results.success = success; %% make success available to subsequent callbacks 0242 0243 %%----- revert to original ordering, including out-of-service stuff ----- 0244 results = int2ext(results); 0245 0246 %% zero out result fields of out-of-service gens & branches 0247 if ~isempty(results.order.gen.status.off) 0248 results.gen(results.order.gen.status.off, [PG QG MU_PMAX MU_PMIN]) = 0; 0249 end 0250 if ~isempty(results.order.branch.status.off) 0251 results.branch(results.order.branch.status.off, [PF QF PT QT MU_SF MU_ST MU_ANGMIN MU_ANGMAX]) = 0; 0252 end 0253 0254 %%----- finish preparing output ----- 0255 et = toc(t0); %% compute elapsed time 0256 if nargout > 0 0257 if nargout <= 2 0258 results.et = et; 0259 results.raw = raw; 0260 busout = results; 0261 genout = success; 0262 else 0263 [busout, genout, branchout, f, info, xr, pimul] = deal(results.bus, ... 0264 results.gen, results.branch, results.f, raw.info, raw.xr, raw.pimul); 0265 if isfield(results, 'g') 0266 g = results.g; 0267 end 0268 if isfield(results, 'dg') 0269 jac = results.dg; 0270 end 0271 end 0272 elseif success 0273 results.et = et; 0274 printpf(results, 1, mpopt); 0275 end