Formulate my own objective function using PowerModels.jl variables

Hello,

I want to use PowerModels.jl flow variables to formulate a different objective function.
I try to see the format of variable_branch_flow and call it with PowerModels.variable_branch_flow(pm). However, when I try to see the output, it always says nothing. Is there anyway I can print out the variable_branch_flow before solving the optimization problem? Or I have to use the code in variable_branch_flow to check the format?

Thank you!

Hi Faoh,

I think the simplest solution is to pass in a JuMP model that you can view. Here are some examples,

https://lanl-ansi.github.io/PowerModels.jl/stable/quickguide/#Building-PowerModels-from-Network-Data-Dictionaries-1

using JuMP
using PowerModels

m = Model()
result = run_ac_opf("case.m", with_optimizer(Ipopt.Optimizer), jump_model=m)
println(m)

Hi Coffrin,

I am wondering can I get load data from the build model?
pm = build_model("~/PowerModels.jl-master/test/data/matpower/case5_tnep.m", DCPPowerModel, PowerModels.post_tnep, ref_extensions=[ref_add_on_off_va_bounds!,ref_add_ne_branch!])
Is there any dict that I can find load information from the pm?

Thank you!

Hi Coffrin,

I have another question when I try to access the branch flow.
I use the a part of code from ‘variable_active_branch_flow’ to get the branch flow information.

p = var(pm, nw, cnd)[:p] = JuMP.@variable(pm.model,
[(l,i,j) in ref(pm, nw, :arcs)], base_name="(nw)_(cnd)_p",
start = comp_start_value(ref(pm, nw, :branch, l), “p_start”, cnd)
)
When I printout the p, it shows
1-dimensional DenseAxisArray{VariableRef,1,…} with index sets:
Dimension 1, Tuple{Int64,Int64,Int64}[(4, 4, 5), (2, 2, 3), (3, 3, 4), (1, 1, 5), (4, 5, 4), (2, 3, 2), (3, 4, 3), (1, 5, 1)]
And data, a 8-element Array{VariableRef,1}:
0_1_p[(4, 4, 5)]
0_1_p[(2, 2, 3)]
0_1_p[(3, 3, 4)]
0_1_p[(1, 1, 5)]
0_1_p[(4, 5, 4)]
0_1_p[(2, 3, 2)]
0_1_p[(3, 4, 3)]
0_1_p[(1, 5, 1)].
When I access, say p[(4, 4, 5)], it only shows the 0_1_p[(4, 4, 5)] not the flow value of branch (4,4,5).
Can I access the branch flow value during the optimization?

Thank you

Hi Faoh,

For your first question, have you tried data = PowerModels.parse_file("~/PowerModels.jl-master/test/data/matpower/case5_tnep.m")?

For your second question, to see the value of a variable you need something like JuMP.value(p[(4, 4, 5)]), see the JuMP docs for more detials.

I hope that helps!

Thanks for your response!
Actually, for the first question, the parse_file code works in the outside of the optimization problem.
I try something like this to parse the network data within the optimization, but it throws me some error.

function run_tnep(file, model_constructor, optimizer; kwargs…)
data = PowerModels.parse_file(file)

return run_model(file, model_constructor, optimizer, post_tnep; ref_extensions=[ref_add_on_off_va_bounds!,ref_add_ne_branch!], solution_builder = solution_tnep!, kwargs…)
end

“the general form of the tnep optimization model”
function post_tnep(pm::GenericPowerModel)
data = PowerModels.parse_file(file)

I think the file is the file path to “~/PowerModels.jl-master/test/data/matpower/case5_tnep.m”.

I also try to add file in function like this post_tnep(file, pm::GenericPowerModel). It doesn’t work either.

What else I can try to parse the network data during the optimization process?

Thank you!

Hi Coffrin,

In your original constraint and objective code, does your code get the variable’s value?
Like this one
function constraint_thermal_limit_to(pm::GenericPowerModel, n::Int, c::Int, t_idx, rate_a)
p_to = var(pm, n, c, :p, t_idx)
q_to = var(pm, n, c, :q, t_idx)
JuMP.@constraint(pm.model, p_to^2 + q_to^2 <= rate_a^2)
end.
Since you are comparing the flow with the limitation, what value are p_to and q_to? I think it should be the implicit variable (flow) during the optimization and you didn’t add other function to get the value. Correct me if I misunderstand.

As the objective,
“Cost of building branches”
function objective_tnep_cost(pm::GenericPowerModel)
return JuMP.@objective(pm.model, Min,
sum(
sum(
sum( branch[“construction_cost”]*var(pm, n, c, :branch_ne, i) for (i,branch) in nw_ref[:ne_branch] )
for c in conductor_ids(pm, n))
for (n, nw_ref) in nws(pm))
)
end
I think it also considers the variable in [:branch_ne].
Is there any other function/rules in powermodels that can allow me to check the value of implicit variables?

Thank you!

These variables are often called “decision variables” in mathematical programming. They do not have a state until after an optimization solver is executed on the algorithm. After the solver is executed the JuMP.value is used to retrieve the variables’ value.

I see. In that case, can I create another decision variable that is consisted of your current variables?

Thank you!

Yes. JuMP lets you add new variables. Have a look at PowerModelsAnnex for some examples.

Hi Coffrin,

I notice that in the constraints, there is a function to get the power flow variables:
function constraint_thermal_limit_from(pm::GenericPowerModel, n::Int, c::Int, f_idx, rate_a)
p_fr = var(pm, n, c, :p, f_idx)
end
I know the f_idx = (i, f_bus, t_bus), but what is n and c? From the definition, n is the network id and c is the conductor id. When I assign the corresponding number, it shows key not found. Do I need to specify something else for n, and c.
I want to get the flow variables individually, like this:
p1=var(pm, nw, cnd,:p,(1,1,5)) #p[(1,1,5)]
p2=var(pm, nw, cnd,:p,(2,2,3)) #p[(2,2,3)]
p3=var(pm, nw, cnd,:p,(3,3,4)) #p[(3,3,4)]
p4=var(pm, nw, cnd,:p,(4,4,5)) #p[(4,4,5)]

pne1=var(pm, nw, cnd,:p_ne,(1,1,2)) #p_ne[(1,1,2)]
pne2=var(pm, nw, cnd,:p_ne,(2,1,4)) #p_ne[(2,1,4)]
pne3=var(pm, nw, cnd,:p_ne,(3,2,4)) #p_ne[(3,2,4)]

and put them into my nonlinear objective equation, which is very messy.

Thanks