Quick Start Guide
Once PowerModelsDistribution is installed, Ipopt is installed, and a network data file (e.g., "case3_unbalanced.dss"
in the package folder under ./test/data
) has been acquired, an unbalanced AC Optimal Power Flow can be executed with,
using PowerModelsDistribution
using Ipopt
solve_mc_opf("case3_unbalanced.dss", ACPUPowerModel, Ipopt.Optimizer)
Parsing files
To parse an OpenDSS file into PowerModelsDistribution's default ENGINEERING
format, use the parse_file
command
eng = parse_file("case3_unbalanced.dss")
To examine the MATHEMATICAL
model it is possible to transform the data model using the transform_data_model
command, but this step is not necessary to run a problem.
math = transform_data_model(eng)
Getting Results
The run commands in PowerModelsDistribution return detailed results data in the form of a dictionary. This dictionary can be saved for further processing as follows,
result = solve_mc_opf(eng, ACPUPowerModel, Ipopt.Optimizer)
Alternatively, you can pass the file path string directly:
result = solve_mc_opf("case3_unbalanced.dss", ACPUPowerModel, Ipopt.Optimizer)
Accessing Different Formulations
ACPUPowerModel
indicates an unbalanced (i.e., multiconductor) AC formulation in polar coordinates. This more generic solve_mc_opf
allows one to solve an OPF problem with any power network formulation in PowerModelsDistribution. For example, the SDPUBFPowerModel
relaxation of unbalanced Optimal Power Flow (branch flow model) can be run with,
using SCS
solve_mc_opf(eng, SDPUBFPowerModel, with_optimizer(SCS.Optimizer))
Note that you have to use a SDP-capable solver, e.g., the open-source solver SCS, to solve SDP models.
Inspecting the Formulation
The following example demonstrates how to break a solve_mc_opf
call into separate model building and solving steps. This allows inspection of the JuMP model created by PowerModelsDistribution for the AC-OPF problem. Note that the MATHEMATICAL
model must be passed to instantiate_mc_model
, so the data model must either be transformed with transform_data_model
or parsed directly to a MATHEMATICAL
model using the data_model
keyword argument:
math = parse_file("case3_unbalanced.dss"; data_model=MATHEMATICAL)
pm = instantiate_model(math, ACPUPowerModel, build_mc_opf; ref_extensions=[ref_add_arcs_trans!])
print(pm.model)
optimize_model!(pm, optimizer=Ipopt.Optimizer)
Providing a Warm Start
To reduce the number of solver iterations, it might be useful to provide a (good) initial value to some or all optimization variables. To do so, it is sufficient to assign a value or vector (depending on the dimensions of the variable) in the data dictionary, under the key $(variablename)_start
. The example below shows how to do it for the vm
and va
variables.
math = parse_file("case3_unbalanced.dss"; data_model=MATHEMATICAL)
math["bus"]["2"]["vm_start"] = [0.9959, 0.9959, 0.9959]
math["bus"]["2"]["va_start"] = [0.00, -2.0944, 2.0944]
Providing a bad initial value might result in the opposite effect: longer calculation times or convergence issues, so the start value assignment should be done attentively. If no initial value is provided, a flat start is assigned by default. The default initial value of each variable is indicated in the function where the variable is defined, as the last argument of the comp_start_value
function. In the case of vm
, this is 1.0, as shown below:
vm = var(pm, nw)[:vm] = Dict(i => JuMP.@variable(pm.model,
[c in 1:ncnds], base_name="$(nw)_vm_$(i)",
start = comp_start_value(ref(pm, nw, :bus, i), "vm_start", c, 1.0)
) for i in ids(pm, nw, :bus)
)
Finally, it should be noted that if va_start
and vm_start
are present in a data dictionary which is passed to the ACR or IVR formulation, these are converted to their rectangular equivalents and used as vr_start
and vi_start
.
Examples
More examples of working with the engineering data model can be found in the /examples
folder of the PowerModelsDistribution.jl repository. These are Pluto Notebooks; instructions for running them can be found in the Pluto documentation.