Escolar Documentos
Profissional Documentos
Cultura Documentos
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%%----- 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);
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 <= A*[x; z] <= u. If the user specifies an A
%
matrix that has more columns than the number of "x" (OPF) variables,
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
.l
.u
.nln
.lin
.l
.u
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
only)
%
only)
%
only)
%
%
%
%
%
%
%
See
.dg
.df
.d2f
.var
.val
.u
.cost
.PQl
.vl
.ycon
basin constraints for CCV for pwl costs
(other) any user defined constraint blocks
upper bounds
.Pmis, Pf, Pt, PQh, PQl, vl, ycon, (other)
user defined cost values, by named block
%
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
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
%
-----
-----
-----
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*[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
%
%
%
%
%
%
%
%
%
%
%
%
%
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 <http://www.gnu.org/licenses/>.
%
%
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,
% 5
opf(casefile, Au,
lbu, ubu,
% 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
mpopt, N,
mpopt)
fparm, H,
Cw)
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)
%% data dimensions
nb
= size(mpc.bus, 1);
nl
= size(mpc.branch, 1);
ng
= size(mpc.gen, 1);
if isfield(mpc, 'A')
nusr = size(mpc.A, 1);
else
nusr = 0;
end
if isfield(mpc, 'N')
nw = size(mpc.N, 1);
else
nw = 0;
end
%% number of buses
%% number of branches
%% number of dispatchable injections
%% number of linear user constraints
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
Va
=
Vm
=
Pg
=
Qg
=
Pmin =
Pmax =
Qmin =
Qmax =
if dc
%% more
nv
=
nq
=
q1
=
%% DC model
problem dimensions
0;
%% number of voltage magnitude vars
0;
%% number of Qg vars
[];
%% index of 1st Qg column in Ay
%% nb
%% nl2
%% nang
%%
%%
%%
%%
npqh
npql
nvl
nang
%% ncony
%% 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);
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';
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
%
%
%
%
%
%
%
%
%
%
%
%
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]) = [
%% P mismatch w.r.t
%% Q mismatch w.r.t
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
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;
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 <http://www.gnu.org/licenses/>.
%
%
%
%
%
%
%
%
%%
%%
%%
%%
number of buses
number of branches
number of dispatchable injections
total number of control vars of all types
%% active generation in MW
%% 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
w = M * (LL + QQ * diagrr) *
HwC = H * w + Cw;
AA = N' * M * (LL + 2 * QQ *
d2f = d2f + AA * H * AA' + 2
nw) * N;
end
d2f = d2f * cost_mult;
-----
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
d2G_err = full(max(max(abs(d2G
d2H_err = full(max(max(abs(d2H
if d2f_err > 1e-6
fprintf('Max difference in
end
if d2G_err > 1e-5
fprintf('Max difference in
end
if d2H_err > 1e-6
fprintf('Max difference in
end
end
Lxx = d2f + d2G + d2H;
- num_d2f))));
- num_d2G))));
- num_d2H))));
d2f: %g\n', d2f_err);
d2G: %g\n', d2G_err);
d2H: %g\n', d2H_err);