-
function [MVAbase, bus, gen, gencost, branch, f, success, et] =
... runopf(casedata, mpopt, fname, solvedcase) %RUNOPF Runs an
optimal power flow. % [RESULTS, SUCCESS] = RUNOPF(CASEDATA, MPOPT,
FNAME, SOLVEDCASE) % % Runs an optimal power flow (AC OPF by
default), optionally returning % a RESULTS struct and SUCCESS flag.
% % Inputs (all are optional): % CASEDATA : either a MATPOWER case
struct or a string containing % the name of the file with the case
data (default is 'case9') % (see also CASEFORMAT and LOADCASE) %
MPOPT : MATPOWER options struct to override default options % can
be used to specify the solution algorithm, output options %
termination tolerances, and more (see also MPOPTION). % FNAME :
name of a file to which the pretty-printed output will % be
appended % SOLVEDCASE : name of file to which the solved case will
be saved % in MATPOWER case format (M-file will be assumed unless
the % specified name ends with '.mat') % % Outputs (all are
optional): % RESULTS : results struct, with the following fields: %
(all fields from the input MATPOWER case, i.e. bus, branch, % gen,
etc., but with solved voltages, power flows, etc.) % order - info
used in external internal data conversion % et - elapsed time in
seconds % success - success flag, 1 = succeeded, 0 = failed %
(additional OPF fields, see OPF for details) % SUCCESS : the
success flag can additionally be returned as % a second output
argument % % Calling syntax options: % results = runopf; % results
= runopf(casedata); % results = runopf(casedata, mpopt); % results
= runopf(casedata, mpopt, fname); % results = runopf(casedata,
mpopt, fname, solvedcase); % [results, success] = runopf(...); % %
Alternatively, for compatibility with previous versions of
MATPOWER, % some of the results can be returned as individual
output arguments: % % [baseMVA, bus, gen, gencost, branch, f,
success, et] = runopf(...); % % Example: % results =
runopf('case30'); % % See also RUNDCOPF, RUNUOPF.
% MATPOWER % $Id: runopf.m 2411 2014-11-04 20:13:56Z ray $ % by
Ray Zimmerman, PSERC Cornell % Copyright (c) 1996-2010 by Power
System Engineering Research Center
(PSERC) % % This file is part of MATPOWER.
-
% See http://www.pserc.cornell.edu/matpower/ for more info. % %
MATPOWER is free software: you can redistribute it and/or modify %
it under the terms of the GNU General Public License as published %
by the Free Software Foundation, either version 3 of the License, %
or (at your option) any later version. % % MATPOWER is distributed
in the hope that it will be useful, % but WITHOUT ANY WARRANTY;
without even the implied warranty of % MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the % GNU General Public License for
more details. % % You should have received a copy of the GNU
General Public License % along with MATPOWER. If not, see . % %
Additional permission under GNU GPL version 3 section 7 % % If you
modify MATPOWER, or any covered work, to interface with % other
modules (such as MATLAB code and MEX-files) available in a %
MATLAB(R) or comparable environment containing parts covered %
under other licensing terms, the licensors of MATPOWER grant % you
additional permission to convey the resulting work.
%%----- initialize ----- %% default arguments if nargin < 4
solvedcase = ''; %% don't save solved case if nargin < 3 fname =
''; %% don't print results to a file if nargin < 2 mpopt =
mpoption; %% use default options if nargin < 1 casedata =
'case9'; %% default data file is 'case9.m' end end end end
%%----- run the optimal power flow ----- [r, success] =
opf(casedata, mpopt);
%%----- output results ----- if fname [fd, msg] = fopen(fname,
'at'); if fd == -1 error(msg); else if mpopt.out.all == 0
printpf(r, fd, mpoption(mpopt, 'out.all', -1)); else printpf(r, fd,
mpopt); end fclose(fd); end end printpf(r, 1, mpopt);
-
%% save solved case if solvedcase savecase(solvedcase, r);
end
if nargout == 1 || nargout == 2 MVAbase = r; bus = success;
elseif nargout > 2 [MVAbase, bus, gen, gencost, branch, f, et] =
... deal(r.baseMVA, r.bus, r.gen, r.gencost, r.branch, r.f, r.et);
% else %% don't define MVAbase, so it doesn't print anything
end
-
function [busout, genout, branchout, f, success, info, et, g,
jac, xr, pimul]
= ... opf(varargin) %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
-
% 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) % .nln (AC only) % .mu shadow
prices on nonlinear constraints, by named block % .l lower bounds %
.Pmis real power mismatch equations % .Qmis reactive power mismatch
equations % .Sf flow limits at "from" end of branches % .St flow
limits at "to" end of branches % .u upper bounds % .Pmis, Qmis, Sf,
St % .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.
% MATPOWER % $Id: opf.m 2229 2013-12-11 01:28:09Z ray $ % by Ray
Zimmerman, PSERC Cornell % and Carlos E. Murillo-Sanchez, PSERC
Cornell & Universidad Autonoma de
Manizales % Copyright (c) 1996-2010 by Power System Engineering
Research Center
(PSERC) % % This file is part of MATPOWER. % See
http://www.pserc.cornell.edu/matpower/ for more info. % % MATPOWER
is free software: you can redistribute it and/or modify
-
% it under the terms of the GNU General Public License as
published % by the Free Software Foundation, either version 3 of
the License, % or (at your option) any later version. % % MATPOWER
is distributed in the hope that it will be useful, % but WITHOUT
ANY WARRANTY; without even the implied warranty of %
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU
General Public License for more details. % % You should have
received a copy of the GNU General Public License % along with
MATPOWER. If not, see . % % Additional permission under GNU GPL
version 3 section 7 % % If you modify MATPOWER, or any covered
work, to interface with % other modules (such as MATLAB code and
MEX-files) available in a % MATLAB(R) or comparable environment
containing parts covered % under other licensing terms, the
licensors of MATPOWER grant % you additional permission to convey
the resulting work.
%%----- initialization ----- t0 = clock; %% start timer
%% define named indices into data matrices [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;
%% process input arguments [mpc, mpopt] =
opf_args(varargin{:});
%% add zero columns to bus, gen, branch for multipliers, etc if
needed nb = size(mpc.bus, 1); %% number of buses nl =
size(mpc.branch, 1); %% number of branches ng = size(mpc.gen, 1);
%% number of dispatchable injections if size(mpc.bus,2) <
MU_VMIN mpc.bus = [mpc.bus zeros(nb, MU_VMIN-size(mpc.bus,2)) ];
end if size(mpc.gen,2) < MU_QMIN mpc.gen = [ mpc.gen zeros(ng,
MU_QMIN-size(mpc.gen,2)) ]; end if size(mpc.branch,2) <
MU_ANGMAX mpc.branch = [ mpc.branch zeros(nl,
MU_ANGMAX-size(mpc.branch,2)) ]; end
%%----- convert to internal numbering, remove out-of-service
stuff ----- mpc = ext2int(mpc);
%%----- construct OPF model object ----- om = opf_setup(mpc,
mpopt);
-
%%----- execute the OPF ----- if nargout > 7
mpopt.opf.return_raw_der = 1; end [results, success, raw] =
opf_execute(om, mpopt);
%%----- revert to original ordering, including out-of-service
stuff ----- results = int2ext(results);
%% zero out result fields of out-of-service gens & branches
if ~isempty(results.order.gen.status.off)
results.gen(results.order.gen.status.off, [PG QG MU_PMAX MU_PMIN])
= 0; end if ~isempty(results.order.branch.status.off)
results.branch(results.order.branch.status.off, [PF QF PT QT MU_SF
MU_ST
MU_ANGMIN MU_ANGMAX]) = 0; end
%%----- finish preparing output ----- et = etime(clock, t0); %%
compute elapsed time if nargout > 0 if nargout
- function [baseMVA, bus, gen, branch, gencost, Au, lbu, ubu, ...
mpopt, N, fparm, H, Cw, z0, zl, zu, userfcn] = ...
opf_args(baseMVA, bus, gen, branch, areas, gencost, Au, lbu, ubu,
... mpopt, N, fparm, H, Cw, z0, zl, zu) %OPF_ARGS Parses and
initializes OPF input arguments. % [MPC, MPOPT] = OPF_ARGS( ... ) %
[BASEMVA, BUS, GEN, BRANCH, GENCOST, A, L, U, MPOPT, ... % N,
FPARM, H, CW, Z0, ZL, ZU, USERFCN] = OPF_ARGS( ... ) % Returns the
full set of initialized OPF input arguments, filling in % default
values for missing arguments. See Examples below for the % possible
calling syntax options. % % Examples: % Output argument options: %
% [mpc, mpopt] = opf_args( ... ) % [baseMVA, bus, gen, branch,
gencost, A, l, u, mpopt, ... % N, fparm, H, Cw, z0, zl, zu,
userfcn] = opf_args( ... ) % % Input arguments options: % %
opf_args(mpc) % opf_args(mpc, mpopt) % opf_args(mpc, userfcn,
mpopt) % opf_args(mpc, A, l, u) % opf_args(mpc, A, l, u, mpopt) %
opf_args(mpc, A, l, u, mpopt, N, fparm, H, Cw) % opf_args(mpc, A,
l, u, mpopt, N, fparm, H, Cw, z0, zl, zu) % % opf_args(baseMVA,
bus, gen, branch, areas, gencost) % opf_args(baseMVA, bus, gen,
branch, areas, gencost, mpopt) % opf_args(baseMVA, bus, gen,
branch, areas, gencost, userfcn, mpopt) % opf_args(baseMVA, bus,
gen, branch, areas, gencost, A, l, u) % opf_args(baseMVA, bus, gen,
branch, areas, gencost, A, l, u, mpopt) % opf_args(baseMVA, bus,
gen, branch, areas, gencost, A, l, u, ... % mpopt, N, fparm, H, Cw)
% opf_args(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 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. See MPOPTION %
for details and default values.
% MATPOWER % $Id: opf_args.m 2409 2014-10-22 20:59:54Z ray $ %
by Ray Zimmerman, PSERC Cornell % and Carlos E. Murillo-Sanchez,
PSERC Cornell & Universidad Autonoma de
Manizales % Copyright (c) 1996-2010 by Power System Engineering
Research Center
(PSERC) % % This file is part of MATPOWER. % See
http://www.pserc.cornell.edu/matpower/ for more info. % % MATPOWER
is free software: you can redistribute it and/or modify % it under
the terms of the GNU General Public License as published % by the
Free Software Foundation, either version 3 of the License, % or (at
your option) any later version. % % MATPOWER is distributed in the
hope that it will be useful, % but WITHOUT ANY WARRANTY; without
even the implied warranty of % MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the % GNU General Public License for more
details. % % You should have received a copy of the GNU General
Public License % along with MATPOWER. If not, see . % % Additional
permission under GNU GPL version 3 section 7 % % If you modify
MATPOWER, or any covered work, to interface with % other modules
(such as MATLAB code and MEX-files) available in a % MATLAB(R) or
comparable environment containing parts covered % under other
licensing terms, the licensors of MATPOWER grant % you additional
permission to convey the resulting work.
if nargout == 2 want_mpc = 1; else want_mpc = 0; end userfcn =
[]; if ischar(baseMVA) || isstruct(baseMVA) %% passing filename or
struct %---- opf(baseMVA, bus, gen, branch, areas, gencost, Au,
lbu, ubu,
mpopt, N, fparm, H, Cw, z0, zl, zu) % 12 opf(casefile, Au, lbu,
ubu, mpopt, N, fparm, H, Cw,
z0, zl, zu)
-
% 9 opf(casefile, Au, lbu, ubu, mpopt, N, fparm, H, Cw) % 5
opf(casefile, Au, lbu, ubu, mpopt) % 4 opf(casefile, Au, lbu, ubu)
% 3 opf(casefile, userfcn, mpopt) % 2 opf(casefile, mpopt) % 1
opf(casefile) if any(nargin == [1, 2, 3, 4, 5, 9, 12]) casefile =
baseMVA; if nargin == 12 zu = fparm; zl = N; z0 = mpopt; Cw = ubu;
H = lbu; fparm = Au; N = gencost; mpopt = areas; ubu = branch; lbu
= gen; Au = bus; elseif nargin == 9 zu = []; zl = []; z0 = []; Cw =
ubu; H = lbu; fparm = Au; N = gencost; mpopt = areas; ubu = branch;
lbu = gen; Au = bus; elseif nargin == 5 zu = []; zl = []; z0 = [];
Cw = []; H = sparse(0,0); fparm = []; N = sparse(0,0); mpopt =
areas; ubu = branch; lbu = gen; Au = bus; elseif nargin == 4 zu =
[]; zl = []; z0 = []; Cw = []; H = sparse(0,0); fparm = []; N =
sparse(0,0); mpopt = mpoption; ubu = branch; lbu = gen; Au = bus;
elseif nargin == 3
-
userfcn = bus; zu = []; zl = []; z0 = []; Cw = []; H =
sparse(0,0); fparm = []; N = sparse(0,0); mpopt = gen; ubu = [];
lbu = []; Au = sparse(0,0); elseif nargin == 2 zu = []; zl = []; z0
= []; Cw = []; H = sparse(0,0); fparm = []; N = sparse(0,0); mpopt
= bus; ubu = []; lbu = []; Au = sparse(0,0); elseif nargin == 1 zu
= []; zl = []; z0 = []; Cw = []; H = sparse(0,0); fparm = []; N =
sparse(0,0); mpopt = mpoption; ubu = []; lbu = []; Au =
sparse(0,0); end else error('opf_args.m: Incorrect input parameter
order, number or type'); end mpc = loadcase(casefile); [baseMVA,
bus, gen, branch, gencost] = ... deal(mpc.baseMVA, mpc.bus,
mpc.gen, mpc.branch, mpc.gencost); if isfield(mpc, 'areas') areas =
mpc.areas; else areas = []; end if isempty(Au) &&
isfield(mpc, 'A') [Au, lbu, ubu] = deal(mpc.A, mpc.l, mpc.u); end
if isempty(N) && isfield(mpc, 'N') %% these two must go
together [N, Cw] = deal(mpc.N, mpc.Cw); end if isempty(H)
&& isfield(mpc, 'H') %% will default to zeros H =
mpc.H;
-
end if isempty(fparm) && isfield(mpc, 'fparm') %% will
default to [1 0 0 1] fparm = mpc.fparm; end if isempty(z0)
&& isfield(mpc, 'z0') z0 = mpc.z0; end if isempty(zl)
&& isfield(mpc, 'zl') zl = mpc.zl; end if isempty(zu)
&& isfield(mpc, 'zu') zu = mpc.zu; end if isempty(userfcn)
&& isfield(mpc, 'userfcn') userfcn = mpc.userfcn; end else
%% passing individual data matrices %---- opf(baseMVA, bus, gen,
branch, areas, gencost, Au, lbu, ubu,
mpopt, N, fparm, H, Cw, z0, zl, zu) % 17 opf(baseMVA, bus, gen,
branch, areas, gencost, Au, lbu, ubu,
mpopt, N, fparm, H, Cw, z0, zl, zu) % 14 opf(baseMVA, bus, gen,
branch, areas, gencost, Au, lbu, ubu,
mpopt, N, fparm, H, Cw) % 10 opf(baseMVA, bus, gen, branch,
areas, gencost, Au, lbu, ubu,
mpopt) % 9 opf(baseMVA, bus, gen, branch, areas, gencost, Au,
lbu, ubu) % 8 opf(baseMVA, bus, gen, branch, areas, gencost,
userfcn, mpopt) % 7 opf(baseMVA, bus, gen, branch, areas, gencost,
mpopt) % 6 opf(baseMVA, bus, gen, branch, areas, gencost) if
any(nargin == [6, 7, 8, 9, 10, 14, 17]) if nargin == 14 zu = []; zl
= []; z0 = []; elseif nargin == 10 zu = []; zl = []; z0 = []; Cw =
[]; H = sparse(0,0); fparm = []; N = sparse(0,0); elseif nargin ==
9 zu = []; zl = []; z0 = []; Cw = []; H = sparse(0,0); fparm = [];
N = sparse(0,0); mpopt = mpoption; elseif nargin == 8 userfcn = Au;
zu = []; zl = []; z0 = []; Cw = [];
-
H = sparse(0,0); fparm = []; N = sparse(0,0); mpopt = lbu; ubu =
[]; lbu = []; Au = sparse(0,0); elseif nargin == 7 zu = []; zl =
[]; z0 = []; Cw = []; H = sparse(0,0); fparm = []; N = sparse(0,0);
mpopt = Au; ubu = []; lbu = []; Au = sparse(0,0); elseif nargin ==
6 zu = []; zl = []; z0 = []; Cw = []; H = sparse(0,0); fparm = [];
N = sparse(0,0); mpopt = mpoption; ubu = []; lbu = []; Au =
sparse(0,0); end else error('opf_args.m: Incorrect input parameter
order, number or type'); end if want_mpc mpc = struct( ...
'baseMVA', baseMVA, ... 'bus', bus, ... 'gen', gen, ... 'branch',
branch, ... 'gencost', gencost ... ); end end nw = size(N, 1); if
nw if size(Cw, 1) ~= nw error('opf_args.m: dimension mismatch
between N and Cw in generalized
cost parameters'); end if ~isempty(fparm) && size(fparm,
1) ~= nw error('opf_args.m: dimension mismatch between N and fparm
in generalized
cost parameters'); end if ~isempty(H) && (size(H, 1) ~=
nw || size(H, 2) ~= nw)
-
error('opf_args.m: dimension mismatch between N and H in
generalized cost
parameters'); end if size(Au, 1) > 0 && size(N, 2) ~=
size(Au, 2) error('opf_args.m: A and N must have the same number of
columns'); end %% make sure N and H are sparse if ~issparse(N)
error('opf_args.m: N must be sparse in generalized cost
parameters'); end if ~issparse(H) error('opf_args.m: H must be
sparse in generalized cost parameters'); end end if ~issparse(Au)
error('opf_args.m: Au must be sparse'); end if isempty(mpopt) mpopt
= mpoption; end if want_mpc if ~isempty(areas) mpc.areas = areas;
end if ~isempty(Au) [mpc.A, mpc.l, mpc.u] = deal(Au, lbu, ubu); end
if ~isempty(N) [mpc.N, mpc.Cw ] = deal(N, Cw); if ~isempty(fparm)
mpc.fparm = fparm; end if ~isempty(H) mpc.H = H; end end if
~isempty(z0) mpc.z0 = z0; end if ~isempty(zl) mpc.zl = zl; end if
~isempty(zu) mpc.zu = zu; end if ~isempty(userfcn) mpc.userfcn =
userfcn; end baseMVA = mpc; bus = mpopt; end
-
function om = opf_setup(mpc, mpopt) %OPF Constructs an OPF model
object from a MATPOWER case struct. % OM = OPF_SETUP(MPC, MPOPT) %
% Assumes that MPC is a MATPOWER case struct with internal
indexing, % all equipment in-service, etc. % % See also OPF,
EXT2INT, OPF_EXECUTE.
% MATPOWER % $Id: opf_setup.m 2435 2014-12-03 20:55:02Z ray $ %
by Ray Zimmerman, PSERC Cornell % and Carlos E. Murillo-Sanchez,
PSERC Cornell & Universidad Autonoma de
Manizales % Copyright (c) 1996-2010 by Power System Engineering
Research Center
(PSERC) % % This file is part of MATPOWER. % See
http://www.pserc.cornell.edu/matpower/ for more info. % % MATPOWER
is free software: you can redistribute it and/or modify % it under
the terms of the GNU General Public License as published % by the
Free Software Foundation, either version 3 of the License, % or (at
your option) any later version. % % MATPOWER is distributed in the
hope that it will be useful, % but WITHOUT ANY WARRANTY; without
even the implied warranty of % MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the % GNU General Public License for more
details. % % You should have received a copy of the GNU General
Public License % along with MATPOWER. If not, see . % % Additional
permission under GNU GPL version 3 section 7 % % If you modify
MATPOWER, or any covered work, to interface with % other modules
(such as MATLAB code and MEX-files) available in a % MATLAB(R) or
comparable environment containing parts covered % under other
licensing terms, the licensors of MATPOWER grant % you additional
permission to convey the resulting work.
%% options dc = strcmp(upper(mpopt.model), 'DC'); alg =
upper(mpopt.opf.ac.solver);
%% define named indices into data matrices [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;
-
%% data dimensions nb = size(mpc.bus, 1); %% number of buses nl
= size(mpc.branch, 1); %% number of branches ng = size(mpc.gen, 1);
%% number of dispatchable injections if isfield(mpc, 'A') nusr =
size(mpc.A, 1); %% number of linear user constraints else nusr = 0;
end if isfield(mpc, 'N') nw = size(mpc.N, 1); %% number of general
cost vars, w else nw = 0; end
if dc %% ignore reactive costs for DC mpc.gencost =
pqcost(mpc.gencost, ng);
%% reduce A and/or N from AC dimensions to DC dimensions, if
needed if nusr || nw acc = [nb+(1:nb) 2*nb+ng+(1:ng)]; %% Vm and Qg
columns if nusr && size(mpc.A, 2) >= 2*nb + 2*ng %% make
sure there aren't any constraints on Vm or Qg if any(any(mpc.A(:,
acc))) error('opf_setup: attempting to solve DC OPF with user
constraints on
Vm or Qg'); end mpc.A(:, acc) = []; %% delete Vm and Qg columns
end if nw && size(mpc.N, 2) >= 2*nb + 2*ng %% make sure
there aren't any costs on Vm or Qg if any(any(mpc.N(:, acc))) [ii,
jj] = find(mpc.N(:, acc)); ii = unique(ii); %% indices of w with
potential non-zero cost
terms from Vm or Qg if any(mpc.Cw(ii)) || (isfield(mpc, 'H')
&& ~isempty(mpc.H) && ... any(any(mpc.H(:, ii))))
error('opf_setup: attempting to solve DC OPF with user costs on
Vm
or Qg'); end end mpc.N(:, acc) = []; %% delete Vm and Qg columns
end end end
%% convert single-block piecewise-linear costs into linear
polynomial cost pwl1 = find(mpc.gencost(:, MODEL) == PW_LINEAR
& mpc.gencost(:, NCOST) == 2); % p1 = []; if ~isempty(pwl1) x0
= mpc.gencost(pwl1, COST); y0 = mpc.gencost(pwl1, COST+1); x1 =
mpc.gencost(pwl1, COST+2); y1 = mpc.gencost(pwl1, COST+3); m = (y1
- y0) ./ (x1 - x0);
-
b = y0 - m .* x0; mpc.gencost(pwl1, MODEL) = POLYNOMIAL;
mpc.gencost(pwl1, NCOST) = 2; mpc.gencost(pwl1, COST:COST+1) = [m
b]; end
%% create (read-only) copies of individual fields for
convenience [baseMVA, bus, gen, branch, gencost, Au, lbu, ubu,
mpopt, ... N, fparm, H, Cw, z0, zl, zu, userfcn] = opf_args(mpc,
mpopt);
%% warn if there is more than one reference bus refs =
find(bus(:, BUS_TYPE) == REF); if length(refs) > 1 &&
mpopt.verbose > 0 errstr = ['\nopf_setup: Warning: Multiple
reference buses.\n', ... ' For a system with islands, a reference
bus in each
island\n', ... ' may help convergence, but in a fully
connected
system such\n', ... ' a situation is probably not
reasonable.\n\n' ]; fprintf(errstr); end
%% set up initial variables and bounds Va = bus(:, VA) *
(pi/180); Vm = bus(:, VM); Pg = gen(:, PG) / baseMVA; Qg = gen(:,
QG) / baseMVA; Pmin = gen(:, PMIN) / baseMVA; Pmax = gen(:, PMAX) /
baseMVA; Qmin = gen(:, QMIN) / baseMVA; Qmax = gen(:, QMAX) /
baseMVA;
if dc %% DC model %% more problem dimensions nv = 0; %% number
of voltage magnitude vars nq = 0; %% number of Qg vars q1 = []; %%
index of 1st Qg column in Ay
%% power mismatch constraints [B, Bf, Pbusinj, Pfinj] =
makeBdc(baseMVA, bus, branch); neg_Cg = sparse(gen(:, GEN_BUS),
1:ng, -1, nb, ng); %% Pbus w.r.t. Pg Amis = [B neg_Cg]; bmis =
-(bus(:, PD) + bus(:, GS)) / baseMVA - Pbusinj;
%% branch flow constraints il = find(branch(:, RATE_A) ~= 0
& branch(:, RATE_A) < 1e10); nl2 = length(il); %% number of
constrained lines if nl2 upf = branch(il, RATE_A) / baseMVA -
Pfinj(il); upt = branch(il, RATE_A) / baseMVA + Pfinj(il); else upf
= []; upt = []; end
-
user_vars = {'Va', 'Pg'}; ycon_vars = {'Pg', 'y'}; else %% AC
model %% more problem dimensions nv = nb; %% number of voltage
magnitude vars nq = ng; %% number of Qg vars q1 = 1+ng; %% index of
1st Qg column in Ay
%% dispatchable load, constant power factor constraints [Avl,
lvl, uvl] = makeAvl(baseMVA, gen);
%% generator PQ capability curve constraints [Apqh, ubpqh, Apql,
ubpql, Apqdata] = makeApq(baseMVA, gen);
user_vars = {'Va', 'Vm', 'Pg', 'Qg'}; ycon_vars = {'Pg', 'Qg',
'y'}; end
%% voltage angle reference constraints Vau = Inf * ones(nb, 1);
Val = -Vau; Vau(refs) = Va(refs); Val(refs) = Va(refs);
%% branch voltage angle difference limits [Aang, lang, uang,
iang] = makeAang(baseMVA, branch, nb, mpopt);
%% basin constraints for piece-wise linear gen cost variables if
(strcmp(alg, 'PDIPM') && mpopt.pdipm.step_control) ||
strcmp(alg, 'TRALM') %% SC-PDIPM or TRALM, no CCV cost vars ny = 0;
Ay = sparse(0, ng+nq); by =[]; else ipwl = find(gencost(:, MODEL)
== PW_LINEAR); %% piece-wise linear costs ny = size(ipwl, 1); %%
number of piece-wise linear cost vars [Ay, by] = makeAy(baseMVA,
ng, gencost, 1, q1, 1+ng+nq); end if any(gencost(:, MODEL) ~=
POLYNOMIAL & gencost(:, MODEL) ~= PW_LINEAR) error('opf_setup:
some generator cost rows have invalid MODEL value'); end
%% more problem dimensions nx = nb+nv + ng+nq; %% number of
standard OPF control variables if nusr nz = size(mpc.A, 2) - nx; %%
number of user z variables if nz < 0 error('opf_setup: user
supplied A matrix must have at least %d columns.',
nx); end else nz = 0; %% number of user z variables if nw %%
still need to check number of columns of N if size(mpc.N, 2) ~=
nx;
-
error('opf_setup: user supplied N matrix must have %d columns.',
nx); end end end
%% construct OPF model object om = opf_model(mpc); if
~isempty(pwl1) om = userdata(om, 'pwl1', pwl1); end if dc om =
userdata(om, 'Bf', Bf); om = userdata(om, 'Pfinj', Pfinj); om =
userdata(om, 'iang', iang); om = add_vars(om, 'Va', nb, Va, Val,
Vau); om = add_vars(om, 'Pg', ng, Pg, Pmin, Pmax); om =
add_constraints(om, 'Pmis', Amis, bmis, bmis, {'Va', 'Pg'}); %% nb
om = add_constraints(om, 'Pf', Bf(il,:), -upt, upf, {'Va'}); %% nl2
om = add_constraints(om, 'ang', Aang, lang, uang, {'Va'}); %% nang
else om = userdata(om, 'Apqdata', Apqdata); om = userdata(om,
'iang', iang); om = add_vars(om, 'Va', nb, Va, Val, Vau); om =
add_vars(om, 'Vm', nb, Vm, bus(:, VMIN), bus(:, VMAX)); om =
add_vars(om, 'Pg', ng, Pg, Pmin, Pmax); om = add_vars(om, 'Qg', ng,
Qg, Qmin, Qmax); om = add_constraints(om, 'Pmis', nb, 'nonlinear');
om = add_constraints(om, 'Qmis', nb, 'nonlinear'); om =
add_constraints(om, 'Sf', nl, 'nonlinear'); om =
add_constraints(om, 'St', nl, 'nonlinear'); om =
add_constraints(om, 'PQh', Apqh, [], ubpqh, {'Pg', 'Qg'}); %% npqh
om = add_constraints(om, 'PQl', Apql, [], ubpql, {'Pg', 'Qg'}); %%
npql om = add_constraints(om, 'vl', Avl, lvl, uvl, {'Pg', 'Qg'});
%% nvl om = add_constraints(om, 'ang', Aang, lang, uang, {'Va'});
%% nang end
%% y vars, constraints for piece-wise linear gen costs if ny
> 0 om = add_vars(om, 'y', ny); om = add_constraints(om, 'ycon',
Ay, [], by, ycon_vars); %% ncony end
%% add user vars, constraints and costs (as specified via A,
..., N, ...) if nz > 0 om = add_vars(om, 'z', nz, z0, zl, zu);
user_vars{end+1} = 'z'; end if nusr om = add_constraints(om, 'usr',
mpc.A, lbu, ubu, user_vars); %% nusr end if nw user_cost.N = mpc.N;
user_cost.Cw = Cw; if ~isempty(fparm) user_cost.dd = fparm(:, 1);
user_cost.rh = fparm(:, 2);
-
user_cost.kk = fparm(:, 3); user_cost.mm = fparm(:, 4); end if
~isempty(H) user_cost.H = H; end om = add_costs(om, 'usr',
user_cost, user_vars); end
%% execute userfcn callbacks for 'formulation' stage om =
run_userfcn(userfcn, 'formulation', om);
-
function [results, success, raw] = opf_execute(om, mpopt)
%OPF_EXECUTE Executes the OPF specified by an OPF model object. %
[RESULTS, SUCCESS, RAW] = OPF_EXECUTE(OM, MPOPT) % % RESULTS are
returned with internal indexing, all equipment % in-service, etc. %
% See also OPF, OPF_SETUP.
% MATPOWER % $Id: opf_execute.m 2375 2014-09-08 18:26:13Z ray $
% by Ray Zimmerman, PSERC Cornell % Copyright (c) 2009-2010 by
Power System Engineering Research Center
(PSERC) % % This file is part of MATPOWER. % See
http://www.pserc.cornell.edu/matpower/ for more info. % % MATPOWER
is free software: you can redistribute it and/or modify % it under
the terms of the GNU General Public License as published % by the
Free Software Foundation, either version 3 of the License, % or (at
your option) any later version. % % MATPOWER is distributed in the
hope that it will be useful, % but WITHOUT ANY WARRANTY; without
even the implied warranty of % MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the % GNU General Public License for more
details. % % You should have received a copy of the GNU General
Public License % along with MATPOWER. If not, see . % % Additional
permission under GNU GPL version 3 section 7 % % If you modify
MATPOWER, or any covered work, to interface with % other modules
(such as MATLAB code and MEX-files) available in a % MATLAB(R) or
comparable environment containing parts covered % under other
licensing terms, the licensors of MATPOWER grant % you additional
permission to convey the resulting work.
%% define named indices into data matrices [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;
%%----- setup ----- %% options dc = strcmp(upper(mpopt.model),
'DC'); alg = upper(mpopt.opf.ac.solver); sdp = strcmp(alg,
'SDPOPF');
%% build user-defined costs
-
om = build_cost_params(om);
%% get indexing [vv, ll, nn] = get_idx(om);
if mpopt.verbose > 0 v = mpver('all'); fprintf('\nMATPOWER
Version %s, %s', v.Version, v.Date); end
%%----- run DC OPF solver ----- if dc if mpopt.verbose > 0
fprintf(' -- DC Optimal Power Flow\n'); end [results, success, raw]
= dcopf_solver(om, mpopt); else %%----- run AC OPF solver ----- if
mpopt.verbose > 0 fprintf(' -- AC Optimal Power Flow\n');
end
%% if opf.ac.solver not set, choose best available option if
strcmp(alg, 'DEFAULT') if have_fcn('pdipmopf') alg = 'PDIPM'; %%
PDIPM else alg = 'MIPS'; %% MIPS end mpopt = mpoption(mpopt,
'opf.ac.solver', alg); end
%% Algorithm alg = 'FMINCON'; %% tambahan dari pak rony
%% run specific AC OPF solver switch alg case 'MIPS' [results,
success, raw] = mipsopf_solver(om, mpopt); case 'IPOPT' if
~have_fcn('ipopt') error('opf_execute: MPOPT.opf.ac.solver = ''%s''
requires IPOPT (see
https://projects.coin-or.org/Ipopt/)', alg); end [results,
success, raw] = ipoptopf_solver(om, mpopt); case 'PDIPM' if
mpopt.pdipm.step_control if ~have_fcn('scpdipmopf')
error('opf_execute: MPOPT.opf.ac.solver = ''%s'' requires
SCPDIPMOPF (see http://www.pserc.cornell.edu/tspopf/)', alg);
end else if ~have_fcn('pdipmopf')
-
error('opf_execute: MPOPT.opf.ac.solver = ''%s'' requires
PDIPMOPF
(see http://www.pserc.cornell.edu/tspopf/)', alg); end end
[results, success, raw] = tspopf_solver(om, mpopt); case 'TRALM' if
~have_fcn('tralmopf') error('opf_execute: MPOPT.opf.ac.solver =
''%s'' requires TRALM (see
http://www.pserc.cornell.edu/tspopf/)', alg); end [results,
success, raw] = tspopf_solver(om, mpopt); case 'MINOPF' if
~have_fcn('minopf') error('opf_execute: MPOPT.opf.ac.solver =
''%s'' requires MINOPF (see
http://www.pserc.cornell.edu/minopf/)', alg); end [results,
success, raw] = mopf_solver(om, mpopt); case 'FMINCON' if
~have_fcn('fmincon') error('opf_execute: MPOPT.opf.ac.solver =
''%s'' requires FMINCON
(Optimization Toolbox 2.x or later)', alg); end [results,
success, raw] = fmincopf_solver(om, mpopt); case 'KNITRO' if
~have_fcn('knitro') error('opf_execute: MPOPT.opf.ac.solver =
''%s'' requires KNITRO (see
http://www.ziena.com/)', alg); end [results, success, raw] =
ktropf_solver(om, mpopt); case 'SDPOPF' if ~have_fcn('yalmip')
error('opf_execute: MPOPT.opf.ac.solver = ''%s'' requires YALMIP
(see
http://users.isy.liu.se/johanl/yalmip/)', alg); end [results,
success, raw] = sdpopf_solver(om, mpopt); otherwise
error('opf_execute: MPOPT.opf.ac.solver = ''%s'' is not a valid AC
OPF
solver selection', alg); end end if ~isfield(raw, 'output') ||
~isfield(raw.output, 'alg') ||
isempty(raw.output.alg) raw.output.alg = alg; end
if success if ~dc && ~sdp %% copy bus voltages back to
gen matrix results.gen(:, VG) = results.bus(results.gen(:,
GEN_BUS), VM);
%% gen PQ capability curve multipliers if ll.N.PQh > 0 ||
ll.N.PQl > 0 mu_PQh = results.mu.lin.l(ll.i1.PQh:ll.iN.PQh)
-
results.mu.lin.u(ll.i1.PQh:ll.iN.PQh); mu_PQl =
results.mu.lin.l(ll.i1.PQl:ll.iN.PQl) -
results.mu.lin.u(ll.i1.PQl:ll.iN.PQl);
-
Apqdata = userdata(om, 'Apqdata'); results.gen =
update_mupq(results.baseMVA, results.gen, mu_PQh, mu_PQl,
Apqdata); end
%% compute g, dg, f, df, d2f if requested by opf.return_raw_der
= 1 if mpopt.opf.return_raw_der %% move from results to raw if
using v4.0 of MINOPF or TSPOPF if isfield(results, 'dg') raw.dg =
results.dg; raw.g = results.g; end %% compute g, dg, unless already
done by post-v4.0 MINOPF or TSPOPF if ~isfield(raw, 'dg') mpc =
get_mpc(om); [Ybus, Yf, Yt] = makeYbus(mpc.baseMVA, mpc.bus,
mpc.branch); [g, geq, dg, dgeq] = opf_consfcn(results.x, om, Ybus,
Yf, Yt, mpopt); raw.g = [ geq; g]; raw.dg = [ dgeq'; dg']; %% true
Jacobian organization end %% compute df, d2f [f, df, d2f] =
opf_costfcn(results.x, om); raw.df = df; raw.d2f = d2f; end end
%% delete g and dg fieldsfrom results if using v4.0 of MINOPF or
TSPOPF if isfield(results, 'dg') rmfield(results, 'dg');
rmfield(results, 'g'); end
%% angle limit constraint multipliers if ~sdp &&
ll.N.ang > 0 iang = userdata(om, 'iang'); results.branch(iang,
MU_ANGMIN) = results.mu.lin.l(ll.i1.ang:ll.iN.ang) *
pi/180; results.branch(iang, MU_ANGMAX) =
results.mu.lin.u(ll.i1.ang:ll.iN.ang) *
pi/180; end else %% assign empty g, dg, f, df, d2f if requested
by opf.return_raw_der = 1 if ~dc &&
mpopt.opf.return_raw_der raw.dg = []; raw.g = []; raw.df = [];
raw.d2f = []; end end
if ~sdp %% assign values and limit shadow prices for variables
om_var_order = get(om, 'var', 'order'); for k =
1:length(om_var_order) name = om_var_order(k).name;
-
if getN(om, 'var', name) idx = vv.i1.(name):vv.iN.(name);
results.var.val.(name) = results.x(idx); results.var.mu.l.(name) =
results.mu.var.l(idx); results.var.mu.u.(name) =
results.mu.var.u(idx); end end
%% assign shadow prices for linear constraints om_lin_order =
get(om, 'lin', 'order'); for k = 1:length(om_lin_order) name =
om_lin_order(k).name; if getN(om, 'lin', name) idx =
ll.i1.(name):ll.iN.(name); results.lin.mu.l.(name) =
results.mu.lin.l(idx); results.lin.mu.u.(name) =
results.mu.lin.u(idx); end end
%% assign shadow prices for nonlinear constraints if ~dc
om_nln_order = get(om, 'nln', 'order'); for k =
1:length(om_nln_order) name = om_nln_order(k).name; if getN(om,
'nln', name) idx = nn.i1.(name):nn.iN.(name);
results.nln.mu.l.(name) = results.mu.nln.l(idx);
results.nln.mu.u.(name) = results.mu.nln.u(idx); end end end
%% assign values for components of user cost om_cost_order =
get(om, 'cost', 'order'); for k = 1:length(om_cost_order) name =
om_cost_order(k).name; if getN(om, 'cost', name)
results.cost.(name) = compute_cost(om, results.x, name); end
end
%% if single-block PWL costs were converted to POLY, insert
dummy y into x %% Note: The "y" portion of x will be nonsense, but
everything should at %% least be in the expected locations. pwl1 =
userdata(om, 'pwl1'); if ~isempty(pwl1) && ~strcmp(alg,
'TRALM') && ~(strcmp(alg, 'PDIPM') &&
mpopt.pdipm.step_control) %% get indexing vv = get_idx(om); if
dc nx = vv.iN.Pg; else nx = vv.iN.Qg; end y = zeros(length(pwl1),
1); raw.xr = [ raw.xr(1:nx); y; raw.xr(nx+1:end)];
-
results.x = [ results.x(1:nx); y; results.x(nx+1:end)]; end
end
-
function [h, g, dh, dg] = opf_consfcn(x, om, Ybus, Yf, Yt,
mpopt, il,
varargin) %OPF_CONSFCN Evaluates nonlinear constraints and their
Jacobian for OPF. % [H, G, DH, DG] = OPF_CONSFCN(X, OM, YBUS, YF,
YT, MPOPT, IL) % % Constraint evaluation function for AC optimal
power flow, suitable % for use with MIPS or FMINCON. Computes
constraint vectors and their % gradients. % % Inputs: % X :
optimization vector % OM : OPF model object % YBUS : bus admittance
matrix % YF : admittance matrix for "from" end of constrained
branches % YT : admittance matrix for "to" end of constrained
branches % MPOPT : MATPOWER options struct % IL : (optional) vector
of branch indices corresponding to % branches with flow limits (all
others are assumed to be % unconstrained). The default is [1:nl]
(all branches). % YF and YT contain only the rows corresponding to
IL. % % Outputs: % H : vector of inequality constraint values (flow
limits) % limit^2 - flow^2, where the flow can be apparent power %
real power or current, depending on value of % opf.flow_lim in
MPOPT (only for constrained lines) % G : vector of equality
constraint values (power balances) % DH : (optional) inequality
constraint gradients, column j is % gradient of H(j) % DG :
(optional) equality constraint gradients % % Examples: % [h, g] =
opf_consfcn(x, om, Ybus, Yf, Yt, mpopt); % [h, g, dh, dg] =
opf_consfcn(x, om, Ybus, Yf, Yt, mpopt); % [h, g, dh, dg] =
opf_consfcn(x, om, Ybus, Yf, Yt, mpopt, il); % % See also
OPF_COSTFCN, OPF_HESSFCN.
% MATPOWER % $Id: opf_consfcn.m 2266 2014-01-16 18:12:59Z ray $
% by Carlos E. Murillo-Sanchez, PSERC Cornell & Universidad
Autonoma de
Manizales % and Ray Zimmerman, PSERC Cornell % Copyright (c)
1996-2010 by Power System Engineering Research Center
(PSERC) % % This file is part of MATPOWER. % See
http://www.pserc.cornell.edu/matpower/ for more info. % % MATPOWER
is free software: you can redistribute it and/or modify % it under
the terms of the GNU General Public License as published % by the
Free Software Foundation, either version 3 of the License, % or (at
your option) any later version. % % MATPOWER is distributed in the
hope that it will be useful, % but WITHOUT ANY WARRANTY; without
even the implied warranty of % MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the
-
% GNU General Public License for more details. % % You should
have received a copy of the GNU General Public License % along with
MATPOWER. If not, see . % % Additional permission under GNU GPL
version 3 section 7 % % If you modify MATPOWER, or any covered
work, to interface with % other modules (such as MATLAB code and
MEX-files) available in a % MATLAB(R) or comparable environment
containing parts covered % under other licensing terms, the
licensors of MATPOWER grant % you additional permission to convey
the resulting work.
%%----- initialize ----- %% define named indices into data
matrices [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, ~, 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;
% xd = x; x = x(1:26, 1); %% tambahan dari pak rony %sizex =
size(full(x)) %% unpack data mpc = get_mpc(om); [baseMVA, bus, gen,
branch] = deal(mpc.baseMVA, mpc.bus, mpc.gen,
mpc.branch); vv = get_idx(om);
%% problem dimensions ibeban = find(bus(:, PD) > 0); %%
mencari bus generator nb = size(bus, 1); %% number of buses nl =
size(branch, 1); %% number of branches ng = size(gen, 1); %% number
of dispatchable injections nxyz = length(x); %% total number of
control vars of all types % k = [45 46 47 48];% untuk case 9 % w =
[49 50 51 52];% untuk case 9 %% set default constrained lines if
nargin < 7 il = (1:nl); %% all lines have limits by default end
nl2 = length(il); %% number of constrained lines
%% grab Pg & Qg x Pg = x(vv.i1.Pg:vv.iN.Pg); %% active
generation in p.u. Qg = x(vv.i1.Qg:vv.iN.Qg); %% reactive
generation in p.u. % %% grab Pg & Qg untuk kondisi 2 % Pg2 =
x(k); %% active generation in p.u. % Qg2 = x(w); %% reactive
generation in p.u. % %% put Pg & Qg back in gen gen(:, PG) = Pg
* baseMVA; %% active generation in MW
-
gen(:, QG) = Qg * baseMVA; %% reactive generation in MVAr %
gen(:, PG) = Pg2 * baseMVA; %% active generation in MW % gen(:, QG)
= Qg2 * baseMVA; %% reactive generation in MVAr
%% rebuild Sbus untuk kondisi 1 dan 2 Sbus = makeSbus(baseMVA,
bus, gen); %% net injected power in p.u. Sbus2 = makeSbus2(baseMVA,
bus, gen); %% net injected power in p.u. % Sbus = [Sbus; Sbus2]; %%
----- evaluate constraints ----- %% reconstruct V Va =
x(vv.i1.Va:vv.iN.Va) Vm = x(vv.i1.Vm:vv.iN.Vm) V = Vm .* exp(1j *
Va); % V = [V; V]; % Va2 = x(vv.i1.Va:vv.iN.Va); % Vm2 =
x(vv.i1.Vm:vv.iN.Vm); % V2 = Vm2 .* exp(1j * Va2);
%% evaluate power flow equations % Ybus2 = [Ybus; Ybus]; mis = V
.* conj(Ybus * V) - Sbus; mis2 = V .* conj(Ybus * V) - Sbus2;
%%----- evaluate constraint function values ----- %% first, the
equality constraints (power flow) untuk kondisi 1 g = [ real(mis);
%% active power mismatch for all buses imag(mis) ]; %% reactive
power mismatch for all buses %% first, the equality constraints
(power flow) untuk kondisi 2 g2 = [ real(mis2); %% active power
mismatch for all buses imag(mis2) ]; %% reactive power mismatch for
all buses % sizeg = size(full(g)); %% then, the inequality
constraints (branch flow limits) untuk kondisi 1 if nl2 > 0
flow_max = (branch(il, RATE_A)/baseMVA).^2; flow_max(flow_max == 0)
= Inf; if upper(mpopt.opf.flow_lim(1)) == 'I' %% current magnitude
limit, |I| If = Yf * V; It = Yt * V; h = [ If .* conj(If) -
flow_max; %% branch current limits (from bus) It .* conj(It) -
flow_max ]; %% branch current limits (to bus) else %% compute
branch power flows Sf = V(branch(il, F_BUS)) .* conj(Yf * V); %%
complex power injected at
"from" bus (p.u.) St = V(branch(il, T_BUS)) .* conj(Yt * V); %%
complex power injected at
"to" bus (p.u.) if upper(mpopt.opf.flow_lim(1)) == 'P' %% active
power limit, P (Pan
Wei) h = [ real(Sf).^2 - flow_max; %% branch real power limits
(from
bus) real(St).^2 - flow_max ]; %% branch real power limits
(to
bus) else %% apparent power limit, |S| h = [ Sf .* conj(Sf) -
flow_max; %% branch apparent power limits
(from bus)
-
St .* conj(St) - flow_max ]; %% branch apparent power limits
(to bus) end end else h = zeros(0,1); end %% then, the
inequality constraints (branch flow limits)untuk kondisi 2 if nl2
> 0 flow_max = (branch(il, RATE_A)/baseMVA).^2;
flow_max(flow_max == 0) = Inf; if upper(mpopt.opf.flow_lim(1)) ==
'I' %% current magnitude limit, |I| If2 = Yf * V; It2 = Yt * V; h2
= [ If2 .* conj(If2) - flow_max; %% branch current limits (from
bus) It2 .* conj(It2) - flow_max ]; %% branch current limits (to
bus) else %% compute branch power flows Sf2 = V(branch(il, F_BUS))
.* conj(Yf * V); %% complex power injected at
"from" bus (p.u.) St2 = V(branch(il, T_BUS)) .* conj(Yt * V); %%
complex power injected at
"to" bus (p.u.) if upper(mpopt.opf.flow_lim(1)) == 'P' %% active
power limit, P (Pan
Wei) h2 = [ real(Sf2).^2 - flow_max; %% branch real power
limits
(from bus) real(St2).^2 - flow_max ]; %% branch real power
limits (to
bus) else %% apparent power limit, |S| h2 = [ Sf2 .* conj(Sf2) -
flow_max; %% branch apparent power
limits (from bus) St2 .* conj(St2) - flow_max ]; %% branch
apparent power limits
(to bus) end end else h2 = zeros(0,1); end %%----- evaluate
partials of constraints ----- if nargout > 2 %% index ranges iVa
= vv.i1.Va:vv.iN.Va; iVm = vv.i1.Vm:vv.iN.Vm; iPg =
vv.i1.Pg:vv.iN.Pg; iQg = vv.i1.Qg:vv.iN.Qg;
%% compute partials of injected bus powers untuk kondisi 1
[dSbus_dVm, dSbus_dVa] = dSbus_dV(Ybus, V); %% w.r.t. V neg_Cg =
sparse(gen(:, GEN_BUS), 1:ng, -1, nb, ng); %% Pbus w.r.t. Pg %%
Qbus w.r.t. Qg %% construct Jacobian of equality (power flow)
constraints and transpose it
untuk kondisi 1 dg = sparse(2*nb, nxyz); sizedg =
size(full(dg)); dg(:, [iVa iVm iPg iQg]) = [
-
real([dSbus_dVa dSbus_dVm]) neg_Cg sparse(nb, ng); %% P mismatch
w.r.t
Va, Vm, Pg, Qg imag([dSbus_dVa dSbus_dVm]) sparse(nb, ng)
neg_Cg; %% Q mismatch w.r.t
Va, Vm, Pg, Qg ]; dg = dg';
%% compute partials of injected bus powers untuk kondisi 2
[dSbus2_dVm, dSbus2_dVa] = dSbus2_dV(Ybus, V); %% w.r.t. V neg_Cg =
sparse(gen(:, GEN_BUS), 1:ng, -1, nb, ng); %% Pbus w.r.t. Pg %%
Qbus w.r.t. Qg %% construct Jacobian of equality (power flow)
constraints and transpose it
untuk kondisi 2 dg2 = sparse(2*nb, nxyz); dg2(:, [iVa iVm iPg
iQg]) = [ real([dSbus2_dVa dSbus2_dVm]) neg_Cg sparse(nb, ng); %% P
mismatch w.r.t
Va, Vm, Pg, Qg imag([dSbus2_dVa dSbus2_dVm]) sparse(nb, ng)
neg_Cg; %% Q mismatch w.r.t
Va, Vm, Pg, Qg ]; dg2 = dg2'; if nl2 > 0 %% compute partials
of Flows w.r.t. V untuk kondisi 1 if upper(mpopt.opf.flow_lim(1))
== 'I' %% current [dFf_dVa, dFf_dVm, dFt_dVa, dFt_dVm, Ff, Ft] =
dIbr_dV(branch(il,:),
Yf, Yt, V); else %% power [dFf_dVa, dFf_dVm, dFt_dVa, dFt_dVm,
Ff, Ft] = dSbr_dV(branch(il,:),
Yf, Yt, V); end if upper(mpopt.opf.flow_lim(1)) == 'P' %% real
part of flow (active
power) dFf_dVa = real(dFf_dVa); dFf_dVm = real(dFf_dVm); dFt_dVa
= real(dFt_dVa); dFt_dVm = real(dFt_dVm); Ff = real(Ff); Ft =
real(Ft); end
%% squared magnitude of flow (of complex power or current, or
real power)
untuk kondisi 1 [df_dVa, df_dVm, dt_dVa, dt_dVm] = ...
dAbr_dV(dFf_dVa, dFf_dVm, dFt_dVa, dFt_dVm, Ff, Ft);
%% construct Jacobian of inequality (branch flow) constraints
& transpose
untuk kondisi 1 dh = sparse(2*nl2, nxyz); dh(:, [iVa iVm]) = [
df_dVa, df_dVm; %% "from" flow limit dt_dVa, dt_dVm; %% "to" flow
limit ]; dh = dh'; else dh = sparse(nxyz, 0); end
-
if nl2 > 0 %% compute partials of Flows w.r.t. V untuk
kondisi 2 if upper(mpopt.opf.flow_lim(1)) == 'I' %% current
[dFf2_dVa, dFf2_dVm, dFt2_dVa, dFt2_dVm, Ff2, Ft2] =
dIbr2_dV(branch(il,:), Yf, Yt, V); else %% power [dFf2_dVa,
dFf2_dVm, dFt2_dVa, dFt2_dVm, Ff2, Ft2] =
dSbr2_dV(branch(il,:), Yf, Yt, V); end if
upper(mpopt.opf.flow_lim(1)) == 'P' %% real part of flow
(active
power) dFf2_dVa = real(dFf2_dVa); dFf2_dVm = real(dFf2_dVm);
dFt2_dVa = real(dFt2_dVa); dFt2_dVm = real(dFt2_dVm); Ff2 =
real(Ff2); Ft2 = real(Ft2); end
%% squared magnitude of flow (of complex power or current, or
real power)
untuk kondisi 2 [df2_dVa, df2_dVm, dt2_dVa, dt2_dVm] = ...
dAbr2_dV(dFf2_dVa, dFf2_dVm, dFt2_dVa, dFt2_dVm, Ff2, Ft2);
%% construct Jacobian of inequality (branch flow) constraints
& transpose
untuk kondisi 2 dh2 = sparse(2*nl2, nxyz); dh2(:, [iVa iVm]) = [
df2_dVa, df2_dVm; %% "from" flow limit dt2_dVa, dt2_dVm; %% "to"
flow limit ]; dh2 = dh2'; else dh2 = sparse(nxyz, 0); end % h = h2
% dh = dh2 % g % g2 % dg = dg2 %% multiplier factor for loads %
fkali = [1 1.03 1.03 1.035 1.06 1.065 1.065 1.07 1.08 1.095 1.09
1.09 1.125
1.13 1.14 1.25 1.35 1.5 1.6 1.7 1.8 1.9 2 2.1];%coba ramp rate 1
(-2) (1
case14) alhamdulillah berhasil % fkali = [1 1.05 1.1 1.15 1.2
1.25 1.3 1.35 1.4 1.45 1.5 1.55 1.6 1.65 1.7
1.75 1.8 1.85 1.9 1.95 2 2.1 2.15 2.2];%fkali1 alhamdulillah
berhasil % % fkali = [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1]; % always 1 % fkali = [1 1.03 1.03 1.03 1.06 1.06 1.06 1.1 1.2
1.3 1.3 1.3 1.2 1.2 1.3
1.3 1.3 1.4 1.5 1.5 1.5 1.5 1.4 1.3];%coba ramp rate dari pak
roni(-2) % fkali = [1 1.03 1.03 1.05 1.06 1.08 1.09 1.1 1.2 1.3 1.3
1.3 1.2 1.2 1.3
1.3 1.3 1.4 1.5 1.5 1.5 1.5 1.4 1.3];%coba ramp rate (-2) %
fkali = [1 1 1 0.9 0.95 0.88 0.85 0.8 0.8 0.78 0.78 0.7 0.6 0.6
0.65 0.65
0.8 0.8 0.9 0.9 0.9 1.0 1.0 1.1];%coba ramp rate 3 (-2) % fkali
= [1 1.05 1.08 1.09 1.1 1.1 1.16 1.2 1.2 1.24 1.3 1.3 1.4 1.45
1.45
1.5 1.8 1.5 1.5 1.1 1.1 1 1 1];%coba ramp rate 4 (2)
-
% fkali = [1 1.1 1.1 1.1 1.1 1.2 1.2 1.2 1.2 1.3 1.3 1.3 1.3 1.4
1.4 1.4 1.4
1.5 1.5 1.5 1.5 1.6 1.6 1];%coba ramp rate 5 (-2) % fkali = [1
1.01 1.02 1.03 1.04 1.05 1.06 1.07 1.08 1.09 1.1 1.11 1.12 1.13
1.14 1.15 1.16 1.17 1.18 1.19 1.2 1.21 1.22 1.23];%coba ramp
rate 6 (-2) % fkali = [1 1.025 1.025 1.025 1.045 1.045 1.045 1.095
1.15 1.215 1.315 1.315
1.315 1.11 1.15 1.15 1.35 1.35 1.45 1.485 1.55 1.55 1.45
1.35];%coba ramp
rate 7 (-2) % fkali = [1 1.015 1.025 1.035 1.045 1.055 1.065
1.075 1.085 1.095 1.15 1.115
1.125 1.135 1.145 1.15 1.165 1.175 1.185 1.195 1.25 1.215 1.225
1.235];%coba
ramp rate 8 (-2) % fkali = [1 1.015 1.025 1.035 1.045 1.055
1.065 1.075 1.085 1.095 1.15 1.115
1.15 1.095 1.085 1.075 1.065 1.055 1.045 1.035 1.025 1.015 1.0
1.0];%coba
ramp rate 9 (1) (0) % fkali = [0.6 0.6 0.65 0.65 0.8 0.8 0.9 0.9
0.9 1.0 1.0 1.1 1.1 1.0 1.0 1.0
0.9 0.95 0.88 0.85 0.8 0.8 0.78 0.7];%coba ramp rate 9 (-2) %
fkali = [1 1.01 1.02 1.03 1.04 1.05 1.06 1.07 1.08 1.09 1.1 1.1
1.12 1.13
1.14 1.15 1.16 1.2 1.2 1.2 1.19 1.18 1.17 1.1];%coba ramp rate
10 (-2) % fkali = [1 1.01 1.02 1.03 1.04 1.05 1.06 1.07 1.08 1.09
1.1 1.1 1.12 1.13
1.14 1.15 1.16 1.2 1.2 1.2 1.1 1.1 1.1 1.0];%coba ramp rate 11
(0) % fkali = [1 1.01 1.02 1.03 1.04 1.05 1.06 1.07 1.08 1.09 1.1
1.1 1.12 1.13
1.14 1.15 1.16 1.25 1.25 1.2 1.1 1.1 1.1 1.0];%coba ramp rate 12
(0) % fkali = [1 1.01 1.01 1.01 1.01 1.02 1.03 1.03 1.03 1.03 1.1
1.1 1.12 1.13
1.14 1.15 1.16 1.25 1.25 1.2 1.1 1.1 1.1 1.0];%coba ramp rate 12
(0) % fkali = [0.5 0.5 0.55 0.55 0.55 0.55 0.6 0.6 0.7 0.75 0.8
0.85 0.9 0.9 0.9
1.0 1.0 1.0 1.0 1.0 1.0 1.0 0.8 0.5];%coba ramp rate 13 (-2) %
fkali = [0.35 0.35 0.35 0.35 0.4 0.4 0.4 0.45 0.45 0.5 0.5 0.5 0.6
0.6 0.65
0.65 0.8 0.8 0.9 0.5 0.5 4.0 0.3 0.3];%coba ramp rate 14 (-2) %
fkali = [1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2]; %fkali2 % fkali
= [1 1.6]; %fkali3 %% To expand matrixes due to additional
considered time T = 2; %%time interval for i=1:T-1; dh =
blkdiag(dh, dh2); h = [h; h2]; % fkali(i+1)*BB(igen); % dg(igen)=
fkali(i+1)*BB(igen) dg = blkdiag(dg, dg2); % fkali(i+1)*B(ibeban);
% g(ibeban)= fkali(i+1)*B(ibeban); g = [g; g2]; end sizeh =
size(h); sizedh = size(full(dh)); sizeg = size(g); sizedg =
size(full(dg)); h = (h); dh = (full(dh)); g = (g); dg =
(full(dg));
end end
-
function [f, df, d2f] = opf_costfcn(x, om, varargin)
%OPF_COSTFCN Evaluates objective function, gradient and Hessian for
OPF. % [F, DF, D2F] = OPF_COSTFCN(X, OM) % % Objective function
evaluation routine for AC optimal power flow, % suitable for use
with MIPS or FMINCON. Computes objective function value, % gradient
and Hessian. % % Inputs: % X : optimization vector % OM : OPF model
object % % Outputs: % F : value of objective function % DF :
(optional) gradient of objective function (column vector) % D2F :
(optional) Hessian of objective function (sparse matrix) % %
Examples: % f = opf_costfcn(x, om); % [f, df] = opf_costfcn(x, om);
% [f, df, d2f] = opf_costfcn(x, om); % % See also OPF_CONSFCN,
OPF_HESSFCN.
% MATPOWER % $Id: opf_costfcn.m 1635 2010-04-26 19:45:26Z ray $
% by Carlos E. Murillo-Sanchez, PSERC Cornell & Universidad
Autonoma de
Manizales % and Ray Zimmerman, PSERC Cornell % Copyright (c)
1996-2010 by Power System Engineering Research Center
(PSERC) % % This file is part of MATPOWER. % See
http://www.pserc.cornell.edu/matpower/ for more info. % % MATPOWER
is free software: you can redistribute it and/or modify % it under
the terms of the GNU General Public License as published % by the
Free Software Foundation, either version 3 of the License, % or (at
your option) any later version. % % MATPOWER is distributed in the
hope that it will be useful, % but WITHOUT ANY WARRANTY; without
even the implied warranty of % MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the % GNU General Public License for more
details. % % You should have received a copy of the GNU General
Public License % along with MATPOWER. If not, see . % % Additional
permission under GNU GPL version 3 section 7 % % If you modify
MATPOWER, or any covered work, to interface with % other modules
(such as MATLAB code and MEX-files) available in a % MATLAB(R) or
comparable environment containing parts covered % under other
licensing terms, the licensors of MATPOWER grant % you additional
permission to convey the resulting work.
-
%%----- initialize ----- %% define named indices into data
matrices [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;
x = x(1:52, 1); %% tambahan dari pak rony
%% unpack data mpc = get_mpc(om); [baseMVA, gen, gencost] =
deal(mpc.baseMVA, mpc.gen, mpc.gencost); cp = get_cost_params(om);
[N, Cw, H, dd, rh, kk, mm] = deal(cp.N, cp.Cw, cp.H, cp.dd, ...
cp.rh, cp.kk, cp.mm); vv = get_idx(om);
%% problem dimensions ng = size(gen, 1); %% number of
dispatchable injections ny = getN(om, 'var', 'y'); %% number of
piece-wise linear costs nxyz = length(x); %% total number of
control vars of all types k = [45 46 47 48];% untuk case 9 w = [49
50 51 52];% untuk case 9 % k = [133 134 135 136 137 138];% untuk
case 30 % w = [139 140 141 142 143 144];% untuk case 30 %% grab Pg
& Qg Pg = x(vv.i1.Pg:vv.iN.Pg); %% active generation in p.u. Qg
= x(vv.i1.Qg:vv.iN.Qg); %% reactive generation in p.u. Pg2 = x(k);
%% active generation in p.u. Qg2 = x(w); %% reactive generation in
p.u. %%----- evaluate objective function ----- %% polynomial cost
of P and Q % use totcost only on polynomial cost; in the
minimization problem % formulation, pwl cost is the sum of the y
variables. ipol = find(gencost(:, MODEL) == POLYNOMIAL); %% poly MW
and MVAr costs xx = [ Pg; Qg ] * baseMVA; xx2 = [ Pg2; Qg2 ] *
baseMVA; if ~isempty(ipol) f = sum( totcost(gencost(ipol, :),
xx(ipol)) ); %% cost of poly P or Q f2 = sum( totcost(gencost(ipol,
:), xx2(ipol)) ) %% cost of poly P or Q else f = 0; end
%% piecewise linear cost of P and Q if ny > 0 ccost =
full(sparse(ones(1,ny), vv.i1.y:vv.iN.y, ones(1,ny), 1, nxyz)); f =
f + ccost * x; else ccost = zeros(1, nxyz); end
%% generalized cost term
-
if ~isempty(N) nw = size(N, 1); r = N * x - rh; %% Nx - rhat iLT
= find(r < -kk); %% below dead zone iEQ = find(r == 0 & kk
== 0); %% dead zone doesn't exist iGT = find(r > kk); %% above
dead zone iND = [iLT; iEQ; iGT]; %% rows that are Not in the Dead
region iL = find(dd == 1); %% rows using linear function iQ =
find(dd == 2); %% rows using quadratic function LL = sparse(iL, iL,
1, nw, nw); QQ = sparse(iQ, iQ, 1, nw, nw); kbar = sparse(iND, iND,
[ ones(length(iLT), 1); zeros(length(iEQ), 1); -ones(length(iGT),
1)], nw, nw) * kk; rr = r + kbar; %% apply non-dead zone shift M =
sparse(iND, iND, mm(iND), nw, nw); %% dead zone or scale diagrr =
sparse(1:nw, 1:nw, rr, nw, nw);
%% linear rows multiplied by rr(i), quadratic rows by rr(i)^2 w
= M * (LL + QQ * diagrr) * rr;
f = f + (w' * H * w) / 2 + Cw' * w; end
%%----- evaluate cost gradient ----- if nargout > 1 %% index
ranges iPg = vv.i1.Pg:vv.iN.Pg; iQg = vv.i1.Qg:vv.iN.Qg;
%% polynomial cost of P and Q df_dPgQg = zeros(2*ng, 1); %%
w.r.t p.u. Pg and Qg df_dPgQg(ipol) = baseMVA *
polycost(gencost(ipol, :), xx(ipol), 1); df = zeros(nxyz, 1);
df(iPg) = df_dPgQg(1:ng); df(iQg) = df_dPgQg((1:ng) + ng);
%% piecewise linear cost of P and Q df = df + ccost'; % As in
MINOS, the linear cost row is additive wrt % any nonlinear
cost.
%% generalized cost term if ~isempty(N) HwC = H * w + Cw; AA =
N' * M * (LL + 2 * QQ * diagrr); df = df + AA * HwC;
%% numerical check if 0 %% 1 to check, 0 to skip check ddff =
zeros(size(df)); step = 1e-7; tol = 1e-3; for k = 1:length(x) xx =
x; xx(k) = xx(k) + step;
-
ddff(k) = (opf_costfcn(xx, om) - f) / step; end if max(abs(ddff
- df)) > tol idx = find(abs(ddff - df) == max(abs(ddff - df)));
fprintf('\nMismatch in gradient\n'); fprintf('idx df(num) df
diff\n'); fprintf('%4d%16g%16g%16g\n', [ 1:length(df); ddff'; df';
abs(ddff -
df)' ]); fprintf('MAX\n'); fprintf('%4d%16g%16g%16g\n', [ idx';
ddff(idx)'; df(idx)';
abs(ddff(idx) - df(idx))' ]); fprintf('\n'); end end %% numeric
check end
%% ---- evaluate cost Hessian ----- if nargout > 2 pcost =
gencost(1:ng, :); if size(gencost, 1) > ng qcost =
gencost(ng+1:2*ng, :); else qcost = []; end
%% polynomial generator costs d2f_dPg2 = sparse(ng, 1); %%
w.r.t. p.u. Pg d2f_dQg2 = sparse(ng, 1); %% w.r.t. p.u. Qg ipolp =
find(pcost(:, MODEL) == POLYNOMIAL); d2f_dPg2(ipolp) = baseMVA^2 *
polycost(pcost(ipolp, :),
Pg(ipolp)*baseMVA, 2); if ~isempty(qcost) %% Qg is not free
ipolq = find(qcost(:, MODEL) == POLYNOMIAL); d2f_dQg2(ipolq) =
baseMVA^2 * polycost(qcost(ipolq, :),
Qg(ipolq)*baseMVA, 2); end i = [iPg iQg]'; d2f = sparse(i, i,
[d2f_dPg2; d2f_dQg2], nxyz, nxyz);
%% generalized cost if ~isempty(N) d2f = d2f + AA * H * AA' + 2
* N' * M * QQ * sparse(1:nw, 1:nw, HwC,
nw, nw) * N; end end % D = f; % DD = df; % size(f); % size(df);
% % fkali = [1 1.6]; %fkali3 % T = 2; %% time interval % for
i=1:T-1; % % f = D*fkali(i+1); % f = f+D; % df = [DD; df]; %
end
-
sizef = size(f); sizedf = size(df); f = (f); df = (df); end
end
-
function Lxx = opf_hessfcn(x, lambda, cost_mult, om, Ybus, Yf,
Yt, mpopt, il) %OPF_HESSFCN Evaluates Hessian of Lagrangian for AC
OPF. % LXX = OPF_HESSFCN(X, LAMBDA, COST_MULT, OM, YBUS, YF, YT,
MPOPT, IL) % % Hessian evaluation function for AC optimal power
flow, suitable % for use with MIPS or FMINCON's interior-point
algorithm. % % Inputs: % X : optimization vector % LAMBDA (struct)
% .eqnonlin : Lagrange multipliers on power balance equations %
.ineqnonlin : Kuhn-Tucker multipliers on constrained branch flows %
COST_MULT : (optional) Scale factor to be applied to the cost %
(default = 1). % OM : OPF model object % YBUS : bus admittance
matrix % YF : admittance matrix for "from" end of constrained
branches % YT : admittance matrix for "to" end of constrained
branches % MPOPT : MATPOWER options struct % IL : (optional) vector
of branch indices corresponding to % branches with flow limits (all
others are assumed to be % unconstrained). The default is [1:nl]
(all branches). % YF and YT contain only the rows corresponding to
IL. % % Outputs: % LXX : Hessian of the Lagrangian. % % Examples: %
Lxx = opf_hessfcn(x, lambda, cost_mult, om, Ybus, Yf, Yt, mpopt); %
Lxx = opf_hessfcn(x, lambda, cost_mult, om, Ybus, Yf, Yt, mpopt,
il); % % See also OPF_COSTFCN, OPF_CONSFCN.
% MATPOWER % $Id: opf_hessfcn.m 2328 2014-05-23 18:43:00Z ray $
% by Ray Zimmerman, PSERC Cornell % and Carlos E. Murillo-Sanchez,
PSERC Cornell & Universidad Autonoma de
Manizales % Copyright (c) 1996-2010 by Power System Engineering
Research Center
(PSERC) % % This file is part of MATPOWER. % See
http://www.pserc.cornell.edu/matpower/ for more info. % % MATPOWER
is free software: you can redistribute it and/or modify % it under
the terms of the GNU General Public License as published % by the
Free Software Foundation, either version 3 of the License, % or (at
your option) any later version. % % MATPOWER is distributed in the
hope that it will be useful, % but WITHOUT ANY WARRANTY; without
even the implied warranty of % MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the % GNU General Public License for more
details. % % You should have received a copy of the GNU General
Public License % along with MATPOWER. If not, see . %
-
% Additional permission under GNU GPL version 3 section 7 % % If
you modify MATPOWER, or any covered work, to interface with % other
modules (such as MATLAB code and MEX-files) available in a %
MATLAB(R) or comparable environment containing parts covered %
under other licensing terms, the licensors of MATPOWER grant % you
additional permission to convey the resulting work.
%%----- initialize ----- %% define named indices into data
matrices [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;
%% default args if isempty(cost_mult) cost_mult = 1; end
%% unpack data mpc = get_mpc(om); [baseMVA, bus, gen, branch,
gencost] = ... deal(mpc.baseMVA, mpc.bus, mpc.gen, mpc.branch,
mpc.gencost); cp = get_cost_params(om); [N, Cw, H, dd, rh, kk, mm]
= deal(cp.N, cp.Cw, cp.H, cp.dd, ... cp.rh, cp.kk, cp.mm); vv =
get_idx(om);
%% unpack needed parameters nb = size(bus, 1); %% number of
buses nl = size(branch, 1); %% number of branches ng = size(gen,
1); %% number of dispatchable injections nxyz = length(x); %% total
number of control vars of all types
%% set default constrained lines if nargin < 8 il = (1:nl);
%% all lines have limits by default end nl2 = length(il); %% number
of constrained lines
%% grab Pg & Qg Pg = x(vv.i1.Pg:vv.iN.Pg); %% active
generation in p.u. Qg = x(vv.i1.Qg:vv.iN.Qg); %% reactive
generation in p.u.
%% put Pg & Qg back in gen gen(:, PG) = Pg * baseMVA; %%
active generation in MW gen(:, QG) = Qg * baseMVA; %% reactive
generation in MVAr
%% reconstruct V Va = zeros(nb, 1); Va =
x(vv.i1.Va:vv.iN.Va);
-
Vm = x(vv.i1.Vm:vv.iN.Vm); V = Vm .* exp(1j * Va); nxtra = nxyz
- 2*nb; pcost = gencost(1:ng, :); if size(gencost, 1) > ng qcost
= gencost(ng+1:2*ng, :); else qcost = []; end
%% ----- evaluate d2f ----- d2f_dPg2 = sparse(ng, 1); %% w.r.t.
p.u. Pg d2f_dQg2 = sparse(ng, 1); %% w.r.t. p.u. Qg ipolp =
find(pcost(:, MODEL) == POLYNOMIAL); d2f_dPg2(ipolp) = baseMVA^2 *
polycost(pcost(ipolp, :), Pg(ipolp)*baseMVA,
2); if ~isempty(qcost) %% Qg is not free ipolq = find(qcost(:,
MODEL) == POLYNOMIAL); d2f_dQg2(ipolq) = baseMVA^2 *
polycost(qcost(ipolq, :),
Qg(ipolq)*baseMVA, 2); end i = [vv.i1.Pg:vv.iN.Pg
vv.i1.Qg:vv.iN.Qg]'; d2f = sparse(i, i, [d2f_dPg2; d2f_dQg2], nxyz,
nxyz);
%% generalized cost if ~isempty(N) nw = size(N, 1); r = N * x -
rh; %% Nx - rhat iLT = find(r < -kk); %% below dead zone iEQ =
find(r == 0 & kk == 0); %% dead zone doesn't exist iGT = find(r
> kk); %% above dead zone iND = [iLT; iEQ; iGT]; %% rows that
are Not in the Dead region iL = find(dd == 1); %% rows using linear
function iQ = find(dd == 2); %% rows using quadratic function LL =
sparse(iL, iL, 1, nw, nw); QQ = sparse(iQ, iQ, 1, nw, nw); kbar =
sparse(iND, iND, [ ones(length(iLT), 1); zeros(length(iEQ), 1);
-ones(length(iGT), 1)], nw, nw) * kk; rr = r + kbar; %% apply
non-dead zone shift M = sparse(iND, iND, mm(iND), nw, nw); %% dead
zone or scale diagrr = sparse(1:nw, 1:nw, rr, nw, nw);
%% linear rows multiplied by rr(i), quadratic rows by rr(i)^2 w
= M * (LL + QQ * diagrr) * rr; HwC = H * w + Cw; AA = N' * M * (LL
+ 2 * QQ * diagrr); d2f = d2f + AA * H * AA' + 2 * N' * M * QQ *
sparse(1:nw, 1:nw, HwC, nw,
nw) * N; end d2f = d2f * cost_mult;
%%----- evaluate Hessian of power balance constraints ----- nlam
= length(lambda.eqnonlin) / 2; lamP = lambda.eqnonlin(1:nlam); lamQ
= lambda.eqnonlin((1:nlam)+nlam);
-
[Gpaa, Gpav, Gpva, Gpvv] = d2Sbus_dV2(Ybus, V, lamP); [Gqaa,
Gqav, Gqva, Gqvv] = d2Sbus_dV2(Ybus, V, lamQ); d2G = [ real([Gpaa
Gpav; Gpva Gpvv]) + imag([Gqaa Gqav; Gqva Gqvv]) sparse(2*nb,
nxtra); sparse(nxtra, 2*nb + nxtra) ];
%%----- evaluate Hessian of flow constraints ----- nmu =
length(lambda.ineqnonlin) / 2; if nmu muF =
lambda.ineqnonlin(1:nmu); muT = lambda.ineqnonlin((1:nmu)+nmu);
else %% keep dimensions of empty matrices/vectors compatible muF =
zeros(0,1); %% (required to avoid problems when using Knitro muT =
zeros(0,1); %% on cases with all lines unconstrained) end if
upper(mpopt.opf.flow_lim(1)) == 'I' %% current [dIf_dVa, dIf_dVm,
dIt_dVa, dIt_dVm, If, It] = dIbr_dV(branch(il,:), Yf,
Yt, V); [Hfaa, Hfav, Hfva, Hfvv] = d2AIbr_dV2(dIf_dVa, dIf_dVm,
If, Yf, V, muF); [Htaa, Htav, Htva, Htvv] = d2AIbr_dV2(dIt_dVa,
dIt_dVm, It, Yt, V, muT); else f = branch(il, F_BUS); %% list of
"from" buses t = branch(il, T_BUS); %% list of "to" buses Cf =
sparse(1:nl2, f, ones(nl2, 1), nl2, nb); %% connection matrix
for
line & from buses Ct = sparse(1:nl2, t, ones(nl2, 1), nl2,
nb); %% connection matrix for
line & to buses [dSf_dVa, dSf_dVm, dSt_dVa, dSt_dVm, Sf, St]
= dSbr_dV(branch(il,:), Yf,
Yt, V); if upper(mpopt.opf.flow_lim(1)) == 'P' %% real power
[Hfaa, Hfav, Hfva, Hfvv] = d2ASbr_dV2(real(dSf_dVa),
real(dSf_dVm),
real(Sf), Cf, Yf, V, muF); [Htaa, Htav, Htva, Htvv] =
d2ASbr_dV2(real(dSt_dVa), real(dSt_dVm),
real(St), Ct, Yt, V, muT); else %% apparent power [Hfaa, Hfav,
Hfva, Hfvv] = d2ASbr_dV2(dSf_dVa, dSf_dVm, Sf, Cf, Yf, V,
muF); [Htaa, Htav, Htva, Htvv] = d2ASbr_dV2(dSt_dVa, dSt_dVm,
St, Ct, Yt, V,
muT); end end d2H = [ [Hfaa Hfav; Hfva Hfvv] + [Htaa Htav; Htva
Htvv] sparse(2*nb, nxtra); sparse(nxtra, 2*nb + nxtra) ];
%%----- do numerical check using (central) finite differences
----- if 0 nx = length(x); step = 1e-5; num_d2f = sparse(nx, nx);
num_d2G = sparse(nx, nx); num_d2H = sparse(nx, nx); for i =
1:nx
-
xp = x; xm = x; xp(i) = x(i) + step/2; xm(i) = x(i) - step/2; %
evaluate cost & gradients [fp, dfp] = opf_costfcn(xp, om); [fm,
dfm] = opf_costfcn(xm, om); % evaluate constraints & gradients
[Hp, Gp, dHp, dGp] = opf_consfcn(xp, om, Ybus, Yf, Yt, mpopt, il);
[Hm, Gm, dHm, dGm] = opf_consfcn(xm, om, Ybus, Yf, Yt, mpopt, il);
num_d2f(:, i) = cost_mult * (dfp - dfm) / step; num_d2G(:, i) =
(dGp - dGm) * lambda.eqnonlin / step; num_d2H(:, i) = (dHp - dHm) *
lambda.ineqnonlin / step; end d2f_err = full(max(max(abs(d2f -
num_d2f)))); d2G_err = full(max(max(abs(d2G - num_d2G)))); d2H_err
= full(max(max(abs(d2H - num_d2H)))); if d2f_err > 1e-6
fprintf('Max difference in d2f: %g\n', d2f_err); end if d2G_err
> 1e-5 fprintf('Max difference in d2G: %g\n', d2G_err); end if
d2H_err > 1e-6 fprintf('Max difference in d2H: %g\n', d2H_err);
end end
Lxx = d2f + d2G + d2H;