📄 fmincopf.m
字号:
function [busout, genout, branchout, f, success, info, et, g, jac] = ... fmincopf(baseMVA, bus, gen, branch, areas, gencost, Au, lbu, ubu, mpopt, ... N, fparm, H, Cw)%FMINCOPF Solves an AC optimal power flow using FMINCON (Opt Tbx 2.x & later).%% [bus, gen, branch, f, success] = fmincopf(casefile, mpopt)%% [bus, gen, branch, f, success] = fmincopf(casefile, A, l, u, mpopt)%% [bus, gen, branch, f, success] = fmincopf(baseMVA, bus, gen, branch, ...% areas, gencost, mpopt)%% [bus, gen, branch, f, success] = fmincopf(baseMVA, bus, gen, branch, ...% areas, gencost, A, l, u, mpopt)%% [bus, gen, branch, f, success] = fmincopf(baseMVA, bus, gen, branch, ...% areas, gencost, A, l, u, mpopt, ...% N, fparm, H, Cw)%% [bus, gen, branch, f, success, info, et, g, jac] = fmincopf(casefile)%% The data for the problem can be specified in one of 3 ways: (1) the name of% a case file which defines the data matrices baseMVA, bus, gen, branch,% areas and gencost, (2) a struct containing the data matrices as fields, or% (3) the data matrices themselves.%% When specified, A, l, u represent additional linear constraints on the% optimization variables, l <= A*[x; z] <= u. For an explanation of the% formulation used and instructions for forming the A matrix, type% 'help genform'.%% 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 or type 'help generalcost'). If the% resulting vector is now 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. Type 'help mpoption'% for details and default values.%% The solved case is returned in the 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) and the% Jacobian matrix (jac).%% Rules for A matrix: 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.%% NOTE: The shadow prices (lambda's and mu's) produced by fmincon appear to% be slightly inaccurate.% MATPOWER% $Id: fmincopf.m,v 1.14 2006/07/28 20:41:24 ray Exp $% by Carlos E. Murillo-Sanchez, PSERC Cornell & Universidad Autonoma de Manizales% Copyright (c) 2000-2006 by Power System Engineering Research Center (PSERC)% See http://www.pserc.cornell.edu/matpower/ for more info.% Sort out input argumentst1 = clock;if isstr(baseMVA) | isstruct(baseMVA) % passing filename or struct % 14 fmincopf(baseMVA, bus, gen, branch, areas, gencost, Au, lbu, ubu, mpopt, N, fparm, H, Cw) % 9 fmincopf(casefile, Au, lbu, ubu, mpopt, N, fparm, H, Cw) % 5 fmincopf(casefile, Au, lbu, ubu, mpopt) % 4 fmincopf(casefile, Au, lbu, ubu) % 2 fmincopf(casefile, mpopt) % 1 fmincopf(casefile) if any(nargin == [1, 2, 4, 5, 9]) casefile = baseMVA; if nargin == 9 N = gencost; fparm = Au; H = lbu; Cw = ubu; else N = []; fparm = []; H = []; Cw = []; end if nargin < 4 Au = sparse(0,0); lbu = []; ubu = []; else Au = bus; lbu = gen; ubu = branch; end if nargin == 9 | nargin == 5 mpopt = areas; elseif nargin == 2 mpopt = bus; else mpopt = []; end else error('fmincopf.m: Incorrect input parameter order, number or type'); end [baseMVA, bus, gen, branch, areas, gencost] = loadcase(casefile);else % passing individual data matrices % 14 fmincopf(baseMVA, bus, gen, branch, areas, gencost, Au, lbu, ubu, mpopt, N, fparm, H, Cw) % 10 fmincopf(baseMVA, bus, gen, branch, areas, gencost, Au, lbu, ubu, mpopt) % 9 fmincopf(baseMVA, bus, gen, branch, areas, gencost, Au, lbu, ubu) % 7 fmincopf(baseMVA, bus, gen, branch, areas, gencost, mpopt) % 6 fmincopf(baseMVA, bus, gen, branch, areas, gencost) if any(nargin == [6, 7, 9, 10, 14]) if nargin ~= 14 N = []; fparm = []; H = []; Cw = []; end if nargin == 7 mpopt = Au; elseif nargin == 6 | nargin == 9 mpopt = []; end if nargin < 9 Au = sparse(0,0); lbu = []; ubu = []; end else error('fmincopf.m: Incorrect input parameter order, number or type'); endendif size(N, 1) > 0 if size(N, 1) ~= size(fparm, 1) | size(N, 1) ~= size(H, 1) | ... size(N, 1) ~= size(H, 2) | size(N, 1) ~= length(Cw) error('fmincopf.m: wrong dimensions in generalized cost parameters'); end if size(Au, 1) > 0 & size(N, 2) ~= size(Au, 2) error('fmincopf.m: A and N must have the same number of columns'); endendif isempty(mpopt) mpopt = mpoption;end% Load column indexes for case tables.[PQ, PV, REF, NONE, BUS_I, BUS_TYPE, PD, QD, GS, BS, BUS_AREA, VM, ... VA, BASE_KV, ZONE, VMAX, VMIN, LAM_P, LAM_Q, MU_VMAX, MU_VMIN] = idx_bus;[GEN_BUS, PG, QG, QMAX, QMIN, VG, MBASE, GEN_STATUS, PMAX, PMIN, ... MU_PMAX, MU_PMIN, MU_QMAX, MU_QMIN, PC1, PC2, QC1MIN, QC1MAX, ... QC2MIN, QC2MAX, RAMP_AGC, RAMP_10, RAMP_30, RAMP_Q, APF] = idx_gen;[F_BUS, T_BUS, BR_R, BR_X, BR_B, RATE_A, RATE_B, RATE_C, ... TAP, SHIFT, BR_STATUS, PF, QF, PT, QT, MU_SF, MU_ST, ... ANGMIN, ANGMAX, MU_ANGMIN, MU_ANGMAX] = idx_brch;[PW_LINEAR, POLYNOMIAL, MODEL, STARTUP, SHUTDOWN, NCOST, COST] = idx_cost;% If tables do not have multiplier/extra columns, append zero cols.% Update whenever the data format changes!if size(bus,2) < MU_VMIN bus = [bus zeros(size(bus,1),MU_VMIN-size(bus,2)) ];endif size(gen,2) < MU_QMIN gen = [ gen zeros(size(gen,1),MU_QMIN-size(gen,2)) ];endif size(branch,2) < MU_ANGMAX branch = [ branch zeros(size(branch,1),MU_ANGMAX-size(branch,2)) ];end% Filter out inactive generators and branches; save original bus & branchcomgen = find(gen(:,GEN_STATUS) > 0);offgen = find(gen(:,GEN_STATUS) <= 0);onbranch = find(branch(:,BR_STATUS) ~= 0);offbranch = find(branch(:,BR_STATUS) == 0);genorg = gen;branchorg = branch;ng = size(gen,1); % original size(gen), at least temporallygen = gen(comgen, :);branch = branch(onbranch, :);if size(gencost,1) == ng gencost = gencost(comgen, :);else gencost = gencost( [comgen; comgen+ng], :);end% Renumber buses consecutively[i2e, bus, gen, branch, areas] = ext2int(bus, gen, branch, areas);[ref, pv, pq] = bustypes(bus, gen);% Sort generators in order of increasing bus number;ng = size(gen,1);[tmp, igen] = sort(gen(:, GEN_BUS));[tmp, inv_gen_ord] = sort(igen); % save for inverse reordering at the endgen = gen(igen, :);if ng == size(gencost,1) gencost = gencost(igen, :);else gencost = gencost( [igen; igen+ng], :);end% Print a warning if there is more than one reference busif size(find(bus(:, BUS_TYPE) == REF), 1) > 1 errstr = ['\nfmincopf: Warning: more than one reference bus detected in bus table data.\n', ... ' For a system with islands, a reference bus in each island\n', ... ' might help convergence but in a fully connected system such\n', ... ' a situation is probably not reasonable.\n\n' ]; fprintf(errstr);end% Find out if any of these "generators" are actually dispatchable loads.% (see 'help isload' for details on what constitutes a dispatchable load)% Dispatchable loads are modeled as generators with an added constant% power factor constraint. The power factor is derived from the original% value of Pmin and either Qmin (for inductive loads) or Qmax (for capacitive% loads). If both Qmin and Qmax are zero, this implies a unity power factor% without the need for an additional constraint.vload = find( isload(gen) & (gen(:, QMIN) ~= 0 | gen(:, QMAX) ~= 0) );% At least one of the Q limits must be zero (corresponding to Pmax == 0)if any( gen(vload, QMIN) ~= 0 & gen(vload, QMAX) ~= 0 ) error('fmincopf.m: Either Qmin or Qmax must be equal to zero for each dispatchable load.');end% Initial values of PG and QG must be consistent with specified power factor% This is to prevent a user from unknowingly using a case file which would% have defined a different power factor constraint under a previous version% which used PG and QG to define the power factor.Qlim = (gen(vload, QMIN) == 0) .* gen(vload, QMAX) + ... (gen(vload, QMAX) == 0) .* gen(vload, QMIN);if any( abs( gen(vload, QG) - gen(vload, PG) .* Qlim ./ gen(vload, PMIN) ) > 1e-4 ) errstr = sprintf('%s\n', ... 'For a dispatchable load, PG and QG must be consistent', ... 'with the power factor defined by PMIN and the Q limits.' ); error(errstr);end% Find out which generators require additional linear constraints% (as opposed to simple box constraints) on (Pg,Qg) to correctly% model their PQ capability curvesipqh = find( hasPQcap(gen, 'U') );ipql = find( hasPQcap(gen, 'L') );% Find out problem dimensionsnb = size(bus, 1); % busesng = size(gen, 1); % variable injectionsnl = size(branch, 1); % branchesiycost = find(gencost(:, MODEL) == PW_LINEAR); % y variables for pwl costny = size(iycost, 1);neqc = 2 * nb; % nonlinear equalitiesnusr = size(Au, 1); % # linear user constraintsnx = 2*nb + 2*ng; % control variablesnvl = size(vload, 1); % dispatchable loadsnpqh = size(ipqh, 1); % general pq capability curvesnpql = size(ipql, 1);if isempty(Au) nz = 0; Au = sparse(0,nx); if ~isempty(N) % still need to check number of columns of N if size(N,2) ~= nx; error(sprintf('fmincopf.m: user supplied N matrix must have %d columns.', nx)); end endelse nz = size(Au,2) - nx; % additional linear variables if nz < 0 error(sprintf('fmincopf.m: user supplied A matrix must have at least %d columns.', nx)); endendnxyz = nx+ny+nz; % total # of vars of all types% Definition of indexes into optimization variable vector and constraint% vector.thbas = 1; thend = thbas+nb-1;vbas = thend+1; vend = vbas+nb-1;pgbas = vend+1; pgend = pgbas+ng-1;qgbas = pgend+1; qgend = qgbas+ng-1;ybas = qgend + 1; yend = ybas + ny - 1;zbas = yend + 1; zend = zbas + nz - 1;pmsmbas = 1; pmsmend = pmsmbas+nb-1;qmsmbas = pmsmend+1; qmsmend = qmsmbas+nb-1;sfbas = qmsmend+1; sfend = sfbas+nl-1;stbas = sfend+1; stend = stbas+nl-1;usrbas = stend+1; usrend = usrbas+nusr-1; % warning: nusr could be 0pqhbas = usrend+1; pqhend = pqhbas+npqh-1; % warning: npqh could be 0pqlbas = pqhend+1; pqlend = pqlbas+npql-1; % warning: npql could be 0vlbas = pqlend+1; vlend = vlbas+nvl-1; % not done yet, need # of % Ay constraints.% Let makeAy deal with any y-variable for piecewise-linear convex costs.% note that if there are z variables then Ay doesn't have the columns% that would span the z variables, so we append them.if ny > 0 [Ay, by] = makeAy(baseMVA, ng, gencost, pgbas, qgbas, ybas); if nz > 0 Ay = [ Ay sparse(size(Ay,1), nz) ]; endelse Ay = []; by =[];endncony = size(Ay,1);yconbas = vlend+1; yconend = yconbas+ncony-1; % finally done with % constraint indexing% Make Avl, lvl, uvl in case there is a need for dispatchable loadsif nvl > 0 xx = gen(vload, PMIN); yy = Qlim; pftheta = atan2(yy, xx); pc = sin(pftheta); qc = -cos(pftheta); ii = [ (1:nvl)'; (1:nvl)' ]; jj = [ pgbas+vload-1; qgbas+vload-1 ]; Avl = sparse(ii, jj, [pc; qc], nvl, nxyz); lvl = zeros(nvl, 1); uvl = lvl;else Avl =[]; lvl =[]; uvl =[];end% Make Apqh if there is a need to add general PQ capability curves;% use normalized coefficient rows so multipliers have right scaling% in $$/puif npqh > 0 Apqhdata = [gen(ipqh,QC1MAX)-gen(ipqh,QC2MAX), gen(ipqh,PC2)-gen(ipqh,PC1)]; ubpqh = (gen(ipqh,QC1MAX)-gen(ipqh,QC2MAX)) .* gen(ipqh,PC1) ... + (gen(ipqh,PC2)-gen(ipqh,PC1)) .* gen(ipqh,QC1MAX); for i=1:npqh, tmp = norm(Apqhdata(i,:)); Apqhdata(i,:) = Apqhdata(i, :) / tmp; ubpqh(i) = ubpqh(i) / tmp; end Apqh = sparse([1:npqh, 1:npqh]', [(pgbas-1)+ipqh;(qgbas-1)+ipqh], ... Apqhdata(:), npqh, nxyz);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -