lanl-ansi / powermodelsannex.jl Goto Github PK
View Code? Open in Web Editor NEWA PowerModels.jl Extension Package for Exploratory Work
License: Other
A PowerModels.jl Extension Package for Exploratory Work
License: Other
@JuliaRegistrator register()
Can a new version of PowerModelsAnnex be released to get access to the frontend again?
This issue is used to trigger TagBot; feel free to unsubscribe.
If you haven't already, you should update your TagBot.yml
to include issue comment triggers.
Please see this post on Discourse for instructions and more details.
If you'd like for me to do this for you, comment TagBot fix
on this issue.
I'll open a PR within a few hours, please be patient!
Hello, I was attempting to run the code in ac-opf.jl and received an error when I run the following command:
ref = PowerModels.build_ref(pm_dict)[:nw][0]
The error I get is: ERROR: cannot assign a value to variable InfrastructureModels.ref from module Main
Not sure whether one of the variables is out of scope? Any assistance would be greatly appreciated.
Many thanks
For both OPF and PF.
Just using the Project.toml should be good enough as the Manifest.toml is recreated locally for everyone from the Project.toml
should increase average coverage significantly.
Is it possible to runt the OBBT code with post_qc_opf model in PowerModelsAnnex as a model constructor? Please let me know how I can do that if it is possible. Thanks in advance!
Add multinetwork support to objective_min_fuel_cost{T <: SOCWROAForm}
.
I want to run the OBBT code for a QC relaxation in PowerModelsAnnex. I set the model_constructor in OBBT code to “QCWRTriNoLinkPowerModel” and run the following command but got an error.
run_obbt_opf(case,IpoptSolver())
ERROR: UndefVarError: QCWRTriNoLinkPowerModel not defined
Can you please let me know how I can run the OBBT code for a model_constructor in PowerModelAnnex.
I also want to add several new constraints to the code. Where is the best location to add the constraints? Should I add them to the model_constructor or post_qc_opf in opf.jl script? I will appreciate any help. Thanks in advance!
Right now, passing a network of type ::Network
into network2pmc function would create a PowerModels dictionary that does not have the key shunt
if there is no shunt element in the original network. However, PowerModels.jl checks for that key every time it wants to run a form of powerflow/optimal power flow and fails as it couldn't find the key. If there is no shunt element, network2pmc should still create a key-empty value pair "shunt" => Dict{String,Any}().
The frontend unit provides a build_pmc!
functionality that converts the data contained in the dataframes into the dictionary that then PowerModels can handle to construct the model for the optimization. There seems to be some instability in the conversions between dataframes and dictionary that lead to incorrect behavior.
Here is an attempt at a minimal presentation of the problem:
# - initial definitions and imports
using PowerModels, PowerModelsAnnex, Ipopt, Missings
PM = PowerModels; PMA = PowerModelsAnnex;
solver = IpoptSolver(print_level=0)
# Load a grid, extract the data used for constructing the PowerModel
net = PMA.Network("<your path to the case>/case5.m")
original = PMA.pmc(net)
# Run the opf, successfully
opf1 = PM.run_dc_opf(original, solver)
# Now, rebuild the pmc inside the net
net2 = deepcopy(net)
PMA.build_pmc!(net2)
rebuilt = PMA.pmc(net2)
opf2 = PM.run_dc_opf(rebuilt, solver)
While the first opf works, the second fails:
julia> opf2 = PM.run_dc_opf(rebuilt, solver)
ERROR: Only cost models of types 1 and 2 are supported at this time, given cost model type of nothing
Stacktrace:
[1] objective_min_fuel_cost(::PowerModels.GenericPowerModel{PowerModels.DCPlosslessForm}) at /path/to/packages/packages/v0.6/PowerModels/src/core/objective.jl:57
[2] post_opf(::PowerModels.GenericPowerModel{PowerModels.DCPlosslessForm}) at /path/to/packages/packages/v0.6/PowerModels/src/prob/opf.jl:25
[3] #build_generic_model#149(::Bool, ::Bool, ::Array{Any,1}, ::Function, ::Dict{String,Any}, ::Type{T} where T, ::PowerModels.#post_opf) at /path/to/packages/packages/v0.6/PowerModels/src/core/base.jl:241
[4] #run_generic_model#147(::Function, ::Array{Any,1}, ::Function, ::Dict{String,Any}, ::Type{T} where T, ::Ipopt.IpoptSolver, ::Function) at /path/to/packages/packages/v0.6/PowerModels/src/core/base.jl:211
[5] #run_opf#583 at /path/to/packages/packages/v0.6/PowerModels/src/prob/opf.jl:15 [inlined]
[6] run_opf(::Dict{String,Any}, ::Type{T} where T, ::Ipopt.IpoptSolver) at /path/to/packages/packages/v0.6/PowerModels/src/prob/opf.jl:15
[7] #run_dc_opf#582 at /path/to/packages/packages/v0.6/PowerModels/src/prob/opf.jl:10 [inlined]
[8] run_dc_opf(::Dict{String,Any}, ::Ipopt.IpoptSolver) at /path/to/packages/packages/v0.6/PowerModels/src/prob/opf.jl:10
Inspecting the dictionaries that are created, original
and rebuilt
there seem to be a number of differences. Among the others, the ones that trigger this particular error are:
julia> # Among the differences:
println("Original number of cost coefficients (bus 4): ", original["gen"]["4"]["ncost"])
Original number of cost coefficients (bus 4): 3
julia> println("New number of cost coefficients (bus 4): ", rebuilt["gen"]["4"]["ncost"])
New number of cost coefficients (bus 4): 0
julia> println("Original cost type (bus 1):", original["gen"]["1"]["model"])
Original cost type (bus 1):2
julia> println("New cost type (bus1):", rebuilt["gen"]["1"]["model"])
New cost type (bus1):-1
(The generators are chosen for illustrative purposes, I get these problems for all of them)
There are also other differences, that impact the construction of the OPF model (in particular, assumptions about the keys of some dictionaries being strings vs integers), but in general it seems that we need to make this build_pmc!
function (and the construction of the Network
) a little bit more consistent.
Setup (which I don't think is important for this particular problem): julia 0.6.4
julia> Pkg.status("PowerModels")
- PowerModels 0.8.8
julia> Pkg.status("PowerModelsAnnex")
- PowerModelsAnnex 0.1.7+ master
I find the dc-opf
example to be a very useful self contained example of how the DC OPF algorithm can be implemented.
I would like to make a feature request for a similar example for a two stage scenario based security constrained DC OPF example. My goal is to find the least cost dispatch such that if any predefined contingency occurs, the flows on the elements of the post contingency system are less than the emergency ratings.
I am keen to attempt to implement this but I am not sure where to start. Can anyone suggest code samples or papers to read that might help?
Thanks
Add variants of the SOCWR Model that support Conic and MIQCQP OTS formulations.
The transformer line data in the frontend does not parse the tap
and angle
of the transformers. Accordingly, the network2pmc
function does map these two sets of data to a pmc
format.
Add a model
directory with functions that build standard formulations of PF and OPF from scratch and return a JuMP model.
These changes can be made,
PowerModelsAnnex.run_api_opf =>run_api_opf
PowerModelsAnnex.run_sad_opf => run_sad_opf
PowerModelsAnnex.APIACPPowerModel => APIACPPowerModel
once PowerModels does not export such functions (version after v0.4.0).
@eperim, I am working on migrating this code to work on v0.6/v0.7/v1.0. Currently I am stuck with a segmentation fault that occurs during compilation on Julia v0.7 while in frontend/units.jl
. The issue seems to be in this call, Unitful.register(current_module())
.
Can you have a look and see if you can suggest a fix?
Full trace,
using PowerModelsAnnex
...
┌ Warning: `current_module()` is deprecated, use `@__MODULE__` instead.
│ caller = top-level scope at none:0
└ @ Core none:0
WARNING: eval from module Unitful to PowerModelsAnnex:
Expr(:call, :/, Unitful.FreeUnits{(Unitful.Unit{:WattHour, Unitful.Dimensions{(Unitful.Dimension{:Length}(power=Base.Rational{Int64}(num=2, den=1)), Unitful.Dimension{:Mass}(power=Base.Rational{Int64}(num=1, den=1)), Unitful.Dimension{:Time}(power=Base.Rational{Int64}(num=-2, den=1)))}}(tens=6, power=Base.Rational{Int64}(num=1, den=1)),), Unitful.Dimensions{(Unitful.Dimension{:Length}(power=Base.Rational{Int64}(num=2, den=1)), Unitful.Dimension{:Mass}(power=Base.Rational{Int64}(num=1, den=1)), Unitful.Dimension{:Time}(power=Base.Rational{Int64}(num=-2, den=1)))}}(), Unitful.FreeUnits{(Unitful.Unit{:Minute, Unitful.Dimensions{(Unitful.Dimension{:Time}(power=Base.Rational{Int64}(num=1, den=1)),)}}(tens=0, power=Base.Rational{Int64}(num=1, den=1)),), Unitful.Dimensions{(Unitful.Dimension{:Time}(power=Base.Rational{Int64}(num=1, den=1)),)}}())
** incremental compilation may be broken for this module **
WARNING: eval from module Unitful to PowerModelsAnnex:
Expr(:call, :*, Unitful.FreeUnits{(Unitful.Unit{:Watt, Unitful.Dimensions{(Unitful.Dimension{:Length}(power=Base.Rational{Int64}(num=2, den=1)), Unitful.Dimension{:Mass}(power=Base.Rational{Int64}(num=1, den=1)), Unitful.Dimension{:Time}(power=Base.Rational{Int64}(num=-3, den=1)))}}(tens=6, power=Base.Rational{Int64}(num=1, den=1)),), Unitful.Dimensions{(Unitful.Dimension{:Length}(power=Base.Rational{Int64}(num=2, den=1)), Unitful.Dimension{:Mass}(power=Base.Rational{Int64}(num=1, den=1)), Unitful.Dimension{:Time}(power=Base.Rational{Int64}(num=-3, den=1)))}}(), Unitful.FreeUnits{(Unitful.Unit{:Hour, Unitful.Dimensions{(Unitful.Dimension{:Time}(power=Base.Rational{Int64}(num=1, den=1)),)}}(tens=0, power=Base.Rational{Int64}(num=1, den=1)),), Unitful.Dimensions{(Unitful.Dimension{:Time}(power=Base.Rational{Int64}(num=1, den=1)),)}}())
** incremental compilation may be broken for this module **
signal (11): Segmentation fault: 11
in expression starting at no file:0
jl_gc_pool_alloc at /Users/osx/buildbot/slave/package_osx64/build/src/gc.c:963
jl_gc_alloc at /Users/osx/buildbot/slave/package_osx64/build/src/./julia_internal.h:274
_new_array_ at /Users/osx/buildbot/slave/package_osx64/build/src/array.c:99
...
There seems to be an issue with the FrontEnd?
See: https://travis-ci.org/lanl-ansi/PowerModelsAnnex.jl/builds/475814466
It seems that the stance towards default values for missing data is to use missing
s. While this is certainly appropriate in some cases, it might be good to have a more flexible approach and allow for other possibilities.
For example, in this case, it might be appropriate to use zero as default, rather than missing
. In other cases, one might want to simply set the missing value to a predetermined default value which might be, for instance, a certain industry standard.
While the default option might still be to use missing
s, a different solution might involve the introduction of a dictionary of defaults that can be manipulated by the user:
const DEFAULTS = Dict{Symbol, Any}(
:load_p => 0.0,
:load_q => 0.0,
:name => missing,
:coordinate => missing,
:rate_a => missing,
...
)
build_solution
, otherwise JuMP.value() can fail (see PowerModels fix, lanl-ansi/PowerModels.jl@b80f4fe)JuMP.optimize!
, and merge code into optimize_model!
optimize_model!
make optimizer
an optional kwarg (see, lanl-ansi/PowerModels.jl@8a8c9c0)build_model
-> instantiate_model
; build_solution
-> build_result
post_*
functions to build_*
post_(mn_)<prob name>(_<variant>)*
The objective functions in PowerModelsAnnex loop over the generators and their cost coefficients. However, when there is a generator with zero cost coefficients, it seems like this data is taken out of the reference and the code throws an error at the objective function.
Example:
If generator 3 has zero cost coefficients, ref[:gen][3]["cost"] = []
In this case, the code throws an out-of-bounds error because the objective tries to access
ref[:gen][3]["cost"][1], ref[:gen][3]["cost"][2] and ref[:gen][3]["cost"][3]
@objective(model, Min,
sum(gen["cost"][1]*pg[i]^2 + gen["cost"][2]*pg[i] + gen["cost"][3] for (i,gen) in ref[:gen]) +
sum(dcline["cost"][1]*p_dc[from_idx[i]]^2 + dcline["cost"][2]*p_dc[from_idx[i]] + dcline["cost"][3] for (i,dcline) in ref[:dcline])
)
I assume this is due to some update in the way the reference is constructed, and maybe already fixed in PowerModels? Is there a good place to see an example for how to write the objective in this case?
pglib model sketch,
""
function post_api_opf(pm::GenericPowerModel)
variable_voltage(pm)
bounds_tighten_voltage(pm)
variable_generation(pm, bounded = false)
upperbound_negative_active_generation(pm)
variable_line_flow(pm)
variable_dcline_flow(pm)
variable_load_factor(pm)
objective_max_loading(pm)
#objective_max_loading_voltage_norm(pm)
#objective_max_loading_gen_output(pm)
constraint_voltage(pm)
for i in ids(pm, :ref_buses)
constraint_theta_ref(pm, i)
end
for (i,gen) in ref(pm, :gen)
pg = var(pm,:pg,i)
@constraint(pm.model, pg >= gen["pmin"])
end
for i in ids(pm, :bus)
constraint_kcl_shunt_scaled(pm, i)
end
for i in ids(pm, :branch)
constraint_ohms_yt_from(pm, i)
constraint_ohms_yt_to(pm, i)
constraint_voltage_angle_difference(pm, i)
constraint_thermal_limit_from(pm, i; scale = 0.999)
constraint_thermal_limit_to(pm, i; scale = 0.999)
end
for i in ids(pm, :dcline)
constraint_dcline(pm, i)
end
end
""
function get_solution(pm::APIACPPowerModel, sol::Dict{String,Any})
add_bus_voltage_setpoint(sol, pm)
add_generator_power_setpoint(sol, pm)
add_branch_flow_setpoint(sol, pm)
add_bus_demand_setpoint(sol, pm)
end
""
function add_bus_demand_setpoint(sol, pm::APIACPPowerModel)
mva_base = pm.data["baseMVA"]
add_setpoint(sol, pm, "bus", "pd", :load_factor; default_value = (item) -> item["pd"], scale = (x,item) -> item["pd"] > 0 && item["qd"] > 0 ? x*item["pd"] : item["pd"], extract_var = (var,idx,item) -> var)
add_setpoint(sol, pm, "bus", "qd", :load_factor; default_value = (item) -> item["qd"], scale = (x,item) -> item["qd"], extract_var = (var,idx,item) -> var)
end
""
function run_sad_opf(file, model_constructor, solver; kwargs...)
return run_generic_model(file, model_constructor, solver, post_sad_opf; kwargs...)
end
""
function post_sad_opf{T <: AbstractPForms}(pm::GenericPowerModel{T})
variable_voltage(pm)
variable_generation(pm)
variable_line_flow(pm)
variable_dcline_flow(pm, bounded = false)
@variable(pm.model, theta_delta_bound >= 0.0, start = 0.523598776)
@objective(pm.model, Min, theta_delta_bound)
constraint_voltage(pm)
for i in ids(pm, :ref_buses)
constraint_theta_ref(pm, i)
end
for i in ids(pm, :bus)
constraint_kcl_shunt(pm, i)
end
for (i,branch) in ref(pm, :branch)
constraint_ohms_yt_from(pm, i)
constraint_ohms_yt_to(pm, i)
constraint_voltage_angle_difference(pm, i)
theta_fr = var(pm, :va, branch["f_bus"])
theta_to = var(pm, :va, branch["t_bus"])
@constraint(pm.model, theta_fr - theta_to <= theta_delta_bound)
@constraint(pm.model, theta_fr - theta_to >= -theta_delta_bound)
constraint_thermal_limit_from(pm, i; scale = 0.999)
constraint_thermal_limit_to(pm, i; scale = 0.999)
end
for i in ids(pm, :dcline)
constraint_dcline(pm, i)
end
end
@JuliaRegistrator register()
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.