Matpowerincludes three OPF extensions implementing via callbacks, respectively, the
co-optimization of energy and reserves, interface ﬂow limits and dispatchable DC
7.6.1 Fixed Zonal Reserves
This extension is a more complete version of the example of ﬁxed zonal reserve
requirements used for illustration above in Sections 7.3 and 7.4. The details of the
extensions to the standard OPF problem are given in equations (7.2)–(7.5) and a
description of the relevant input and output data structures is summarized in Tables 7-5
and 7-6, respectively.
Table 7-5:Input Data Structures for Fixed Zonal Reserves
additional ﬁeld in mpc containing input parameters for zonal reserves in thefollowing sub-ﬁelds:
reserve price in $/MW, computed for unitas the sum of the shadow pricesof constraintsin(7.5)in which unitparticipates ()
‡All zonal reserve result sub-ﬁelds arevectors, where the values are set to zero for units not participating inthe provision of reserves.
The code for implementing the callbacks can be found in toggle_reserves. A wrapper
around runopf that turns on this extension before running the OPF is provided in
runopf_w_res, allowing you to run a case with an appropriate reserves ﬁeld, such as
t_case30_userfcns, as follows.
results = runopf_w_res('t_case30_userfcns');
See help runopf_w_res and help toggle_reserves for more information. Examples of
using this extension and a case ﬁle deﬁning the necessary input data can be found in
t_opf_userfcns and t_case30_userfcns, respectively. Additional tests for runopf_w_res
are included in t_runopf_w_res.
7.6.2 Interface Flow Limits
This extension adds interface ﬂow limits based on ﬂows computed from a DC network
model. It is implemented in toggle_iflims. A ﬂow interface is deﬁned as a set of
branch indices and a direction for each branch. If represents the real power ﬂow
(“from” bus “to” bus) in branch and is equal to 1 or to indicate the
then the interface ﬂow for interface is deﬁned as
where each branch ﬂow is an approximation calculated as a linear function of the bus
voltage angles based on the DC power ﬂow model from equation (3.29).
This extension adds to the OPF problem a set of doubly-bounded constraints on
where and are the speciﬁed lower and upper bounds on the interface ﬂow,
and is a the set indices of interfaces whose ﬂow limits are to be enforced.
The data for the problem is speciﬁed in an additional if ﬁeld in the Matpowercase
struct mpc. This ﬁeld is itself a struct with two sub-ﬁelds, map and lims, used for input
data, and two others, P and mu, used for output data. The format of this data is described
in detail in Tables 7-7 and 7-8.
Table 7-7:Input Data Structures for Interface Flow Limits
additional ﬁeld in mpc containing input parameters for interface ﬂow limitsin the following sub-ﬁelds:
matrix deﬁning the interfaces, whereis the numberbranches that belong to interface. Thebranches of interfaceare deﬁned byrows in the matrix, where the ﬁrst column in each isequal toand the second is equal to the corresponding branch indexmultiplied byto indicate the direction.
matrix of interface limits, whereis the number of interfacelimits to be enforced. The ﬁrst column is the indexof the interface, andthe second and third columns areand, the lower and upperlimits respectively, on the DC model ﬂow limits (in MW) for the interface.
Table 7-8:Output Data Structures for Interface Flow Limits
OPF results struct, superset of mpc with additional ﬁelds for output data
additional ﬁeld in results containing output parameters for interface ﬂowlimits in the following sub-ﬁelds:
vector of actual ﬂow in MW across the corresponding interface(as measured at the “from” end of associated branches)
vector of shadow prices on lower ﬂow limits (/MW)†
vector of shadow prices on upper ﬂow limits (/MW)†
†Here we assume the objective function has units.
See help toggle_iflims for more information. Examples of using this extension and a
case ﬁle deﬁning the necessary input data for it can be found in t_opf_userfcns and
t_case30_userfcns, respectively. Note that, while this extension can be used for AC
OPF problems, the actual AC interface ﬂows will not necessarily be limited to
the speciﬁed values, since it is a DC ﬂow approximation that is used for the
Running a case that includes the interface ﬂow limits is as simple as loading the case,
turning on the extension and running it. Unlike with the reserves extension, Matpower
does not currently have a wrapper function to automate this.
Beginning with version 4.1, Matpoweralso includes a simple model for dispatchable DC
transmission lines. While the implementation is based on the extensible OPF architecture
described above, it can be used for simple power ﬂow problems as well, in which the case
the (OPF only) formulation callback is skipped.
A DC line in Matpoweris modeled as two linked “dummy” generators, as shown in
Figures 7-2 and 7-3, one with negative capacity extracting real power from the network at
the “from” end of the line and another with positive capacity injecting power into the
network at the “to” end. These dummy generators are added by the ext2int callback and
removed by the int2ext callback. The real power ﬂow on the DC line at the “from”
end is deﬁned to be equal to the negative of the injection of corresponding dummy
generator. The ﬂow at the “to” end is deﬁned to be equal to the injection of the
Matpowerlinks the values of and using the following relationship, which
includes a linear approximation of the real power loss in the line.
Here the linear coeﬃcient is assumed to be a small () positive number.
Obviously, this is not applicable for bi-directional lines, where the ﬂow could go either
direction, resulting in decreasing losses for increasing ﬂow in the “to” “from”
direction. There are currently two options for handling bi-directional lines. The ﬁrst is to
use a constant loss model by setting . The second option is to create two separate
but identical lines oriented in opposite directions. In this case, it is important
that the lower limit on the ﬂow and the constant term of the loss model
be set to zero to ensure that only one of the two lines has non-zero ﬂow at a
Upper and lower bounds on the value of the ﬂow can be speciﬁed for each DC line,
along with an optional operating cost. It is also assumed that the terminals of the line
have a range of reactive power capability that can be used to maintain a voltage setpoint.
Just as with a normal generator, the voltage setpoint is only used for simple power ﬂow;
the OPF dispatches the voltage anywhere between the lower and upper bounds speciﬁed
for the bus. Similarly, in a simple power ﬂow the input value for and the
corresponding value for , computed from (7.8), are used to specify the ﬂow in the
Most of the data for DC lines is stored in a dcline ﬁeld in the Matpowercase struct
mpc. This ﬁeld is a matrix similar to the branch matrix, where each row corresponds to a
particular DC line. The columns of the matrix are deﬁned in Table B-5 and include
connection bus indices, line status, ﬂows, terminal reactive injections, voltage setpoints,
limits on power ﬂow and VAr injections, and loss parameters. Also, similar to the
branch or gen matrices, some of the columns are used for input values, some for
results, and some, such as PF can be either input or output, depending on whether
the problem is a simple power ﬂow or an optimal power ﬂow. The idx_dcline
function deﬁnes a set of constants for use as named column indices for the dcline
An optional dclinecost matrix, in the same form as gencost, can be used to specify a
cost to be applied to in the OPF. If the dclinecost ﬁeld is not present, the cost is
assumed to be zero.
Matpower’s DC line handling is implemented in toggle_dcline and examples of
using it can be found in t_dcline. The case ﬁle t_case9_dcline includes some example
DC line data. See help toggle_dcline for more information.
Running a case that includes DC lines is as simple as loading the case, turning on the
extension and running it. Unlike with the reserves extension, Matpowerdoes not
currently have a wrapper function to automate this.
Matpowerincludes an extension that replaces limits (such as branch ﬂow limits, voltage
magnitude bounds, generator limits, etc.) in an optimal power ﬂow with soft limits, that
is, limits that can be violated with some linear penalty cost. This can be useful
in identifying the cause of infeasibility in some optimal power ﬂow problems.
The extension is implemented in toggle_softlims. A limited version for branch
ﬂow constraints in a DC model only, was introduced in Matpower 5.0, with a
generalization to all of the standard OPF limits added in Matpower 7.0. The soft AC
branch ﬂow limit implemention provides an example of user-deﬁned nonlinear
In general, replacing a hard constraint of the form
with a soft limit involves introducing a new non-negative variable to represent the
violation of the original constraint. The original hard constraint (7.9) is replaced by one in
which this violation variable is used to “relax” the constraint by adding it to the
Finally, a penalty cost on violations is implemented via a linear cost coeﬃcient, ,
applied to each violation variable , so that the additional user deﬁned cost term from
(6.47) for the set of soft limits looks like
Take, as an example, branch ﬂow limits. The ﬂow constraints in (6.9) and
(6.10) are rewritten by replacing the right hand side with a ﬂow violation variable
In the case of AC ﬂow constraints, the ﬂow functions and are nonlinear and
can be either apparent power, active power, or current as shown in (6.11). In the case of
DC ﬂow constraints, where there are no losses, these ﬂows can be implemented in terms of
the ﬂow at the from end of the line and its negative, both linear functions of the bus
voltage angles, based on (6.30) and (6.31).
The feasible area for the DC case is illustrated in Figure 7-4.
Matpowerimplements soft limits for each of the types of constraints listed in
Table 7-9, where the formulation for each constraint type is shown.
Table 7-9:Soft Limit Formulation
†Only applicable for the AC OPF.‡Example of a user-deﬁned nonlinear constraint in the AC version.
The parameters for the problem are speciﬁed in an additional softlims ﬁeld in the
Matpowercase struct mpc. This ﬁeld is itself a struct where each sub-ﬁeld corresponds to
the name of one of the limits listed in Table 7-9. For each of the limits, the input
parameters are speciﬁed in the ﬁelds detailed in Table 7-10, with defaults summarized in
Table 7-10:Input Data Structures for OPF Soft Limits
additional ﬁeld in mpc containing OPF soft limit input parameters for thepossible limits, each of which is optional.*
<LIM> refers to the name of the limit, i.e. one of the following: ANGMIN, ANGMAX,RATE_A, PMIN, PMAX, QMIN, QMAX, VMIN, VMAX. Each of these is a struct with inputparameters deﬁning the soft limits for this type of constraint in the followingoptional ﬁelds (see Table7-11for defaults):
vector of row indices for bus, branch or gen matrix, depending on<LIM>, specifying the elements for which corresponding soft limits are to beapplied†
vector of external bus numbers specifying the buses to which soft limitsare to be applied†
scalar orvectorof linear cost coeﬃcients for limit violation costs
string indicating type of modiﬁcation to original hard limit:
do not add soft limit, no change to original hard limit
add soft limit, relax hard limit by removing it completely
add soft limit, relax hard limit by replacing original with valuespeciﬁed in hl_val
add soft limit, relax hard limit by scaling original by valuespeciﬁed in hl_val
add soft limit, relax hard limit by shifting original by valuespeciﬁed in hl_val
scalar orvector value used to modify hard limit according to hl_mod.Ignored for 'none' and 'remove', required for 'replace', and optional, withthe following defaults, for 'scale' and 'shift':
2 for positive upper limits or negative lower limits, 0.5 otherwise
0.25 for VMAX and VMIN, 10 otherwise
*For ﬁelds not present, the value of the 'opf.softlims.defaults' option determines whether the corresponding limitis unchanged (= 0) or converted (= 1, default) to a soft limit using default values from Table7-11.†For bus constraints, idx overrides busnum if both are provided.‡Only applicable for bus constraints, i.e. <LIM> is VMIN or VMAX.§Any new, relaxed hard limits are implemented via bounds on the violation variables. See Table7-12for details.
Table 7-11:Default Soft Limit Values
voltage magnitude lower bound
voltage magnitude upper bound
branch ﬂow limit
all on-line branches with bounded ﬂow limits
$1000/MVA, $1000/MW, or $1000/(kA† where the unitsdepend on 'opf.flow_lim'
generator active power lower bound
all on-line generators, excluding dispatchable loads
PMAX, QMIN, QMAX
generator active power upper bound, reactive power lower/upper bounds
all on-line generators, excluding dispatchable loads
$1000/MW or $1000/MVAr†
branch angle diﬀerence lower/upper bounds
all on-line branches with angle diﬀerence limits,, where
†Unless the maximum marginal cost atacross all online generators, which we call, exceeds $1000/MWh,in which case the numerical value of the default cost isinstead of 1000 (orinstead of 100,000, forVMIN or VMAX).
Depending on whether the original constraint in (7.10) is an upper bound or a lower
bound, it can be written as one of the following
where is the actual value of the hard limit. When introducing a soft limit, this
original hard limit can be removed completely or modiﬁed to have a new value.
Matpowerprovides a several ways of modifying the original hard limit based on ﬁelds
hl_mod (“hard limit modiﬁcation”) and hl_val (“hard limit value”) in the respective
limit structures. This new hard limit is implemented via an upper bound on the
corresponding violation variable . Table 7-12 summarizes the new hard limits and the
corresponding bounds on the violation variable as functions of the values of hl_mod and
Table 7-12:Possible Hard-Limit Modiﬁcations
new hard limit
upper bound on violation variable
†Plus sign for upper bounds and minus sign for lower bounds.
Unspeciﬁed limits in the mpc.softlims input parameters are handled diﬀerently,
depending on the value of the Matpoweroption 'opf.softlims.default' (see
If the opf.softlims.default option is 1 (default), each limit not explicitly
speciﬁed, whether missing in mpc.softlims or present but empty, will be
initialized as in Table 7-11.
If the opf.softlims.default option is 0, limits that are missing in mpc.softlims
are treated as though speciﬁed with hl_mod = 'none', that is, they are not
converted to soft limits at all. On the other hand, the default soft limits
of Table 7-11 are still applied to any limit that is present in mpc.softlims
but empty. For example, mpc.softlims.RATE_A = struct() would result in the
default soft branch limits being applied.
Soft limit outputs, summarized in Table 7-13, include the amount and cost of any
overloads, that is, violations of the original hard limits. These can be found as additional
ﬁelds, overload and ov_cost, under each limit in results.softlims. The Kuhn-Tucker
multipliers on the soft limit constraints are also included in the usual columns of the
corresponding matrix in the results, e.g. bus(:, MU_VMAX), branch(:, MU_SF), etc. When
there are no violations, these shadow prices are the same as if hard limits were
imposed. When there is a violation, they are equal to the cost associated with
the violation variable, except in the case where a modiﬁed hard limit is also
binding, in which case it also reﬂects the shadow price on this modiﬁed hard
Table 7-13:Output Data Structures for OPF Soft Limits
additional ﬁeld in results containing OPF soft limit outputs foreach limit type
<LIM> refers to the name of the limit, i.e. one of the following:ANGMIN, ANGMAX, RATE_A, PMIN, PMAX, QMIN, QMAX, VMIN, VMAX. Eachof these is a struct with the following output ﬁelds:
vector of overload quantities for this limit (amount oforiginal hard limit violation)
vector of overload penalty costs for this limit
Kuhn-Tucker multipliers on angle diﬀerence lower bounds‡
Kuhn-Tucker multipliers on angle diﬀerence upper bounds‡
Kuhn-Tucker multipliers on branch ﬂow limits (from end)‡
Kuhn-Tucker multipliers on branch ﬂow limits (to end)‡
Kuhn-Tucker multipliers on active gen lower bounds‡
Kuhn-Tucker multipliers on active gen upper bounds‡
Kuhn-Tucker multipliers on reactive gen lower bounds‡
Kuhn-Tucker multipliers on reactive gen upper bounds‡
Kuhn-Tucker multipliers on voltage magnitude lower bounds‡
Kuhn-Tucker multipliers on voltage magnitude upper bounds‡
†The dimensions of overload and ov_cost correspond to all buses, branches or generators (depending on <LIM>), not justthose whose limits were converted to soft limits. Entries corresponding to those not included (implicitly or explicitly)in idx are set to zero.†For limits that have been converted to soft limits, these are the shadow prices on the soft limit constraints. When thereis no violation of the soft limit, this shadow price is the same as it would be for the original hard limit. When there isa violation, it is equal to the corresponding user-supplied violation cost, unless an updated hard constraint is alsobinding.
See help toggle_softlims for more information on this extension. Examples of using
this extension can be found in t_opf_softlims. Running a case that includes the default
soft limits is as simple as loading the case, turning on the extension and running it. Unlike
with the reserves extension, Matpowerdoes not currently have a wrapper function to