PowerModelsAnnex.jl obtaining duals

I have downloaded the PowerModelsAnnex.jl files. I am using the build_qc_opf functions, and wish to obtain dual prices from the solution. The specific dual prices I wish to obtain are the duals of the power balance or KCL constraints formed in the function build_qc_opf(). A sample of what I am trying to do is below.

  1. Do i need to name the constraints? and if so, how would i name constraints that are called within a for loop within a function. For example, there would be one constraint per bus, so just including a name within the @constraint call would mean that I replace the name at each iteration.
  2. In any case not sure whether just calling the resultdual or getdual functions would work outside of the function, where the model is defined within the function? when i have tried getdual(constraintname) it has not recognised the variable.
  3. is there a constraint dictionary I can access somehow?

model = Model()
pm = build_qc_opf(data,model)
set_optimizer(model,Ipopt.Optimizer)
result = optimize!(model)
vars = all_variables(model)
has_duals(model) [this returns a true]
dual_price = dual(model)

Thoughts greatly appreciated @ccoffrin

This is more of a JuMP question than a PowerModels question. You will need to modify build_qc_opf to return some pointers to the power balance constraints and then call the dual function on those constraints after the optimize! call.

At the JuMP level something along these lines should work,

using JuMP

m = Model(Some.Optimizer)
@variable(m, x)
@objective(m, Min, 2.0*x^2)
c = @constraint(m, x == 1.23)
optimize!(m)
value(x)
dual(c)

Thank you @ccoffrin

My follow up is probably a more JuMP question then… For constraints that are defined within a for loop, we would need a multi-dimensional pointer, and the pointer would need to be initialised. How would one intialise the pointer? i.e. would you have to declare the type, and what would that type be?

I have seen solutions that modify incorporate multi-dimensionality into @constraint. However that would not be suitable if one is manipulating data and expressions earlier in the for loop prior to creating the constraint.

You can store constraint in a vector, for example.

model = Model()
@variable(model, x)
cons = []
for a = 1:4
    c = @constraint(model, x <= a)
    push!(cons, c)
end

You can use any Julia data structures you like. You aren’t restricted to the JuMP provided ones.

many thanks!