Skip to content

Commit ca74c6f

Browse files
frederikgethccoffrin
authored andcommitted
Discrepancy BIM vs BFM (#286)
* found for discrepancy SOC BFM vs BIM * Documentation fix * Looser bounds on square current magnitude variable
1 parent f4abaf1 commit ca74c6f

File tree

4 files changed

+55
-22
lines changed

4 files changed

+55
-22
lines changed

docs/src/quickguide.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -86,15 +86,15 @@ This network data can be modified in the same way as the previous Matpower `.m`
8686
## Inspecting AC and DC branch flow results
8787
The flow AC and DC branch results are not written to the result by default. To inspect the flow results, pass a settings Dict
8888
```julia
89-
result = run_opf("case3_dc.m", ACPPowerModel, IpoptSolver(), setting = Dict("output" => Dict("line_flows" => true)))
89+
result = run_opf("case3_dc.m", ACPPowerModel, IpoptSolver(), setting = Dict("output" => Dict("branch_flows" => true)))
9090
result["solution"]["dcline"]["1"]
9191
result["solution"]["branch"]["2"]
9292
```
9393

94-
The losses of a AC or DC branch can be derived:
94+
The losses of an AC or DC branch can be derived:
9595
```julia
96-
loss_ac = Dict(name => data["p_to"]+data["p_from"] for (name, data) in result["solution"]["branch"])
97-
loss_dc = Dict(name => data["p_to"]+data["p_from"] for (name, data) in result["solution"]["dcline"])
96+
loss_ac = Dict(name => data["pt"]+data["pf"] for (name, data) in result["solution"]["branch"])
97+
loss_dc = Dict(name => data["pt"]+data["pf"] for (name, data) in result["solution"]["dcline"])
9898
```
9999

100100

src/core/data.jl

+37-10
Original file line numberDiff line numberDiff line change
@@ -44,30 +44,57 @@ function calc_series_current_magnitude_bound(branches, buses)
4444
g_sh_to = branch["g_to"]
4545
b_sh_fr = branch["b_fr"]
4646
b_sh_to = branch["b_to"]
47-
zmag_fr = abs(g_sh_fr + im*b_sh_fr)
48-
zmag_to = abs(g_sh_to + im*b_sh_to)
47+
r_s = branch["br_r"]
48+
x_s = branch["br_x"]
4949

5050
vmax_fr = bus_fr["vmax"]
5151
vmax_to = bus_fr["vmax"]
52-
vmin_fr = bus_fr["vmin"]
53-
vmin_to = bus_fr["vmin"]
5452

5553
tap_fr = branch["tap"]
5654
tap_to = 1 # no transformer on to side, keeps expressions symmetric.
5755
smax = branch["rate_a"]
5856

59-
cmax_tot_fr = smax*tap_fr/vmin_fr
60-
cmax_tot_to = smax*tap_to/vmin_to
57+
cmax_p = (2*smax + abs(g_sh_fr)*vmax_fr^2 + abs(g_sh_to)*vmax_to^2)/(abs(r_s))
58+
cmax_q = (2*smax + abs(b_sh_fr)*vmax_fr^2 + abs(b_sh_to)*vmax_to^2)/(abs(x_s))
6159

62-
cmax_sh_fr = zmag_fr * vmax_fr
63-
cmax_sh_to = zmag_to * vmax_to
64-
65-
cmax[key] = max(cmax_tot_fr + cmax_sh_fr, cmax_tot_to + cmax_sh_to)
60+
cmax[key] = min(cmax_p, cmax_q)
6661
end
6762
return cmax
6863
end
6964

7065

66+
""
67+
function calc_series_active_power_bound(branches, buses)
68+
pmax = Dict([(key, 0.0) for key in keys(branches)])
69+
for (key, branch) in branches
70+
bus_fr = buses[branch["f_bus"]]
71+
g_sh_fr = branch["g_fr"]
72+
vmax_fr = bus_fr["vmax"]
73+
tap_fr = branch["tap"]
74+
smax = branch["rate_a"]
75+
76+
pmax[key] = smax + abs(g_sh_fr) * (vmax_fr/tap_fr)^2
77+
end
78+
return pmax
79+
end
80+
81+
82+
""
83+
function calc_series_reactive_power_bound(branches, buses)
84+
qmax = Dict([(key, 0.0) for key in keys(branches)])
85+
for (key, branch) in branches
86+
bus_fr = buses[branch["f_bus"]]
87+
b_sh_fr = branch["g_fr"]
88+
vmax_fr = bus_fr["vmax"]
89+
tap_fr = branch["tap"]
90+
smax = branch["rate_a"]
91+
92+
qmax[key] = smax + abs(b_sh_fr) * (vmax_fr/tap_fr)^2
93+
end
94+
return qmax
95+
end
96+
97+
7198
""
7299
function calc_theta_delta_bounds(data::Dict{String,Any})
73100
bus_count = length(data["bus"])

src/form/df.jl

+13-7
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,14 @@ end
2525

2626

2727
function variable_active_branch_series_flow(pm::GenericPowerModel, n::Int=pm.cnw; bounded = true)
28+
branches = pm.ref[:nw][n][:branch]
29+
buses = pm.ref[:nw][n][:bus]
30+
pmax = calc_series_active_power_bound(branches, buses)
2831
if bounded
2932
pm.var[:nw][n][:p_s] = @variable(pm.model,
3033
[(l,i,j) in pm.ref[:nw][n][:arcs_from]], basename="$(n)_p_s",
31-
lowerbound = -pm.ref[:nw][n][:branch][l]["rate_a"],
32-
upperbound = pm.ref[:nw][n][:branch][l]["rate_a"],
34+
lowerbound = -pmax[l],
35+
upperbound = pmax[l],
3336
start = getstart(pm.ref[:nw][n][:branch], l, "p_start")
3437
)
3538
else
@@ -42,11 +45,14 @@ end
4245

4346

4447
function variable_reactive_branch_series_flow(pm::GenericPowerModel, n::Int=pm.cnw; bounded = true)
48+
branches = pm.ref[:nw][n][:branch]
49+
buses = pm.ref[:nw][n][:bus]
50+
qmax = calc_series_reactive_power_bound(branches, buses)
4551
if bounded
4652
pm.var[:nw][n][:q_s] = @variable(pm.model,
4753
[(l,i,j) in pm.ref[:nw][n][:arcs_from]], basename="$(n)_q_s",
48-
lowerbound = -pm.ref[:nw][n][:branch][l]["rate_a"],
49-
upperbound = pm.ref[:nw][n][:branch][l]["rate_a"],
54+
lowerbound = -qmax[l],
55+
upperbound = qmax[l],
5056
start = getstart(pm.ref[:nw][n][:branch], l, "q_start")
5157
)
5258
else
@@ -96,11 +102,11 @@ function constraint_voltage_magnitude_difference(pm::GenericPowerModel{T}, n::In
96102
ccm = pm.var[:nw][n][:ccm][i]
97103

98104
#define series flow expressions to simplify Ohm's law
99-
p_fr_s = p_fr - g_sh_fr*(w_fr/tm^2)
100-
q_fr_s = q_fr + b_sh_fr*(w_fr/tm^2)
105+
p_s_fr = p_fr - g_sh_fr*(w_fr/tm^2)
106+
q_s_fr = q_fr + b_sh_fr*(w_fr/tm^2)
101107

102108
#KVL over the line:
103-
@constraint(pm.model, w_to == (w_fr/tm^2) - 2*(r*p_fr_s + x*q_fr_s) + (r^2 + x^2)*ccm)
109+
@constraint(pm.model, w_to == (w_fr/tm^2) - 2*(r*p_s_fr + x*q_s_fr) + (r^2 + x^2)*ccm)
104110

105111
end
106112

test/opf.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ end
294294
result = run_opf_bf("../test/data/matpower/case5_gap.m", SOCDFPowerModel, ipopt_solver)
295295

296296
@test result["status"] == :LocalOptimal
297-
@test isapprox(result["objective"], -27660.4; atol = 1e0)
297+
@test isapprox(result["objective"], -28238.0; atol = 1e0)
298298
end
299299
@testset "5-bus with pwl costs" begin
300300
result = run_opf_bf("../test/data/matpower/case5_pwlc.m", SOCDFPowerModel, ipopt_solver)

0 commit comments

Comments
 (0)