KKT condition not satisfied in DCOPF

I wanted to evaluate whether the KKT condition \lambda_i - \lambda_j = \mu^{+}_{ij} - \mu^{-}_{ij} holds for standard DC-OPF. I made a small test on the 5-bus case.

using PowerModels
using GLPK

result = PowerModels.solve_dc_opf("pglib_opf_case5_pjm.m", GLPK.Optimizer, setting = Dict("output" => Dict("duals" => true)))
lmps = Dict()
mus_fr = Dict()
mus_to = Dict()
for (b, bus) in result["solution"]["bus"]
    push!(lmps, parse(Int64,b) => bus["lam_kcl_r"])
end
for (b, branch) in result["solution"]["branch"]
    push!(mus_fr, parse(Int64,b) => branch["mu_sm_fr"])
    push!(mus_to, parse(Int64,b) => branch["mu_sm_to"])
end
lmps[5] - lmps[4] - (mus_fr[6] - mus_to[6])# = 0

Line (6,4,5) is congested as can be seen by dual multipliers \mu.

Dict{Any, Any} with 6 entries:
  5 => 0.0
  4 => 0.0
  6 => 6232.2
  2 => 0.0
  3 => 0.0
  1 => 0.0

lmps[4] = -3994
lmps[5] = -1000
mus_fr[6] = 6232
mus_fr[5] = 0

Without congestion, it is easy to see and verify that the difference in lmps is 0 and lagrangian multipliers \mu as well.

With congestion, however, as far as I understand, lmps[5] - lmps[4] - (mus_fr[6] - mus_to[6])# = 0 should be 0, but it is not. I tried for multiple solvers and test cases.

Am I missing something fundamental?

Thanks in advance.

DCopf is simple, why don’t you directly write an LP yourself (e.g. with JuMP), with the raw data (in PowerModels)?

I actually did for a small synthetic 3bus test case but made the same observation. With PowersModels, at least, i can exclude any mistake with regard to DCOPF implementation on my end as its tried and tested.

I forgot a dual multiplier related to the power flow. Adding it, solves the issue. There is no direct way to access it through PowerModels, however.

1 Like

Hi @simoni0 welcome to the forum :smile:

Im pleased you got it sorted. I’d strongly encourage you to use HiGHS.jl instead of GLPK.jl. its generally faster and more robust

1 Like