Constraints in a loop in the PowerModels

I want to enforce linear envelopes on the cosine function in PowerModelsAnnex. I implement the following code for doing that.

for (bp, buspair) in ref[:buspairs]
for k=1:length(linear_envelopes1)
@constraint(model, cs[bp]>= linear_envelopes1 [k]*td[bp]+ linear_envelopes2 [k])
end
end

I get the following error. Can you please let me know how I can fix this. Thanks in advance!

ERROR: LoadError: The operators <=, >=, and == can only be used to specify scalar constraints. If you are trying to add a vectorized constraint, use the element-wise dot comparison operators (.<=, .>=, or .==) instead

Some, or all of your components are vectors. Try the .>= as the error message suggests.

Thanks for the response! I have already tried that but I got the following error. I think it is better to define a dictionary for the linear envelope’s coefficient and then used the vectorized constraints.

ERROR: LoadError: MethodError: no method matching addVectorizedConstraint(::JuMP.Model, ::JuMP.GenericRangeConstraint{JuMP.GenericAffExpr{Float64,JuMP.Variable}})
Closest candidates are:
addVectorizedConstraint(::JuMP.Model, ::Array{JuMP.GenericRangeConstraint{JuMP.GenericAffExpr{Float64,JuMP.Variable}},N} where N) at C:\Users\Rasoul.julia\v0.6\JuMP\src\affexpr.jl:221
addVectorizedConstraint(::JuMP.Model, ::Array{JuMP.GenericQuadConstraint{JuMP.GenericQuadExpr{Float64,JuMP.Variable}},N} where N) at C:\Users\Rasoul.julia\v0.6\JuMP\src\quadexpr.jl:172

You should read the first post of PSA: make it easier to help you. It’s easier to help if you can provide a minimal working example. What are cs[bp], linear_envelopes1[k], td[pb], and linear_envelopes2[k]?

However, it looks like you are using an old and outdated version of Julia/JuMP. You should update to Julia 1.0 and JuMP 0.21.

At first glance it looks like this code should work. So it should be mostly a debugging exercise along the lines @odow has suggested.

Concerning this code,

One thing that stood out to me was that linear_envelopes1 is not indexed first by bp. I would have exepected something like,

for (bp, buspair) in ref[:buspairs]
  for k=1:length(linear_envelopes1[bp])
    @constraint(model, cs[bp]>= linear_envelopes1[bp][k]*td[bp] + linear_envelopes2[bp][k])
  end
end

As I would expect each buspair to have its own envelope. You might be considering a case where there is only one envelope shared across all buspairs. In that case, what you originally proposed was along the right lines.

Thanks for the instructive response. In my code each buspair has its own linear envelopes. I have two options to implement the code, I can define a dictionary or I can define a two-dimensional array. Which one do you think is better in terms of execution time?

The set of bus pairs is very sparse, so I would recommend Dict(bp => Array[line1, line2, ... n]). The PWL cost function implementation gives an example of this. For example see, https://github.com/lanl-ansi/PowerModels.jl/blob/v0.15.5/src/core/objective.jl#L392

Thank you so much for the instructive response. It was really helpful!

1 Like