Skip to content

Commit e1c5914

Browse files
rb004fccoffrin
authored andcommitted
Adding network expansion planning (#33)
Basic implementation of transmission network expansion planning. This code should be revisited when #34 is closed and should be considered in the context of #35
1 parent fd82229 commit e1c5914

File tree

9 files changed

+1416
-29
lines changed

9 files changed

+1416
-29
lines changed

src/PowerModels.jl

+1
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,6 @@ include("prob/pf.jl")
2727
include("prob/opf.jl")
2828
include("prob/ots.jl")
2929
include("prob/misc.jl")
30+
include("prob/tnep.jl")
3031

3132
end

src/core/base.jl

+32-20
Original file line numberDiff line numberDiff line change
@@ -31,32 +31,44 @@ type GenericPowerModel{T<:AbstractPowerFormulation} <: AbstractPowerModel
3131
set::PowerDataSets
3232
setting::Dict{AbstractString,Any}
3333
solution::Dict{AbstractString,Any}
34+
35+
# Extension dictionary
36+
# Extensions should define a type to hold information particular to
37+
# their functionality, and store an instance of the type in this
38+
# dictionary keyed on an extension-specific symbol
39+
ext::Dict{Symbol,Any}
3440
end
3541

3642
# default generic constructor
37-
function GenericPowerModel{T}(data::Dict{AbstractString,Any}, vars::T; setting = Dict{AbstractString,Any}(), solver = JuMP.UnsetSolver())
38-
data, sets = process_raw_data(data)
39-
43+
function GenericPowerModel{T}(data::Dict{AbstractString,Any}, vars::T; setting = Dict{AbstractString,Any}(), solver = JuMP.UnsetSolver(), data_processor = process_raw_mp_data)
44+
data, sets, ext = data_processor(data)
4045
pm = GenericPowerModel{T}(
4146
Model(solver = solver), # model
4247
data, # data
4348
sets, # sets
4449
setting, # setting
4550
Dict{AbstractString,Any}(), # solution
51+
ext # ext
4652
)
4753

4854
return pm
4955
end
5056

51-
function process_raw_data(data::Dict{AbstractString,Any})
57+
function process_raw_mp_data(data::Dict{AbstractString,Any})
5258
make_per_unit(data)
53-
unify_transformer_taps(data)
54-
add_branch_parameters(data)
55-
standardize_cost_order(data)
5659

60+
min_theta_delta = calc_min_phase_angle(data)
61+
max_theta_delta = calc_max_phase_angle(data)
62+
63+
unify_transformer_taps(data["branch"])
64+
add_branch_parameters(data["branch"], min_theta_delta, max_theta_delta)
65+
66+
standardize_cost_order(data)
5767
sets = build_sets(data)
5868

59-
return data, sets
69+
ext = Dict{Symbol,Any}()
70+
71+
return data, sets, ext
6072
end
6173

6274
#
@@ -143,7 +155,6 @@ function build_sets(data::Dict{AbstractString,Any})
143155
gen_idxs = collect(keys(gen_lookup))
144156
branch_idxs = collect(keys(branch_lookup))
145157

146-
147158
buspair_indexes = collect(Set([(i,j) for (l,i,j) in arcs_from]))
148159
buspairs = buspair_parameters(buspair_indexes, branch_lookup, bus_lookup)
149160

@@ -232,20 +243,17 @@ function make_per_unit(mva_base::Number, data::Number)
232243
#println("$(parent) $(data)")
233244
end
234245

235-
function unify_transformer_taps(data::Dict{AbstractString,Any})
236-
for branch in data["branch"]
246+
function unify_transformer_taps(branches)
247+
for branch in branches
237248
if branch["tap"] == 0.0
238249
branch["tap"] = 1.0
239250
end
240251
end
241252
end
242253

243254
# NOTE, this function assumes all values are p.u. and angles are in radians
244-
function add_branch_parameters(data::Dict{AbstractString,Any})
245-
min_theta_delta = calc_min_phase_angle(data)
246-
max_theta_delta = calc_max_phase_angle(data)
247-
248-
for branch in data["branch"]
255+
function add_branch_parameters(branches, min_theta_delta, max_theta_delta)
256+
for branch in branches
249257
r = branch["br_r"]
250258
x = branch["br_x"]
251259
tap_ratio = branch["tap"]
@@ -276,14 +284,18 @@ function calc_max_phase_angle(data::Dict{AbstractString,Any})
276284
bus_count = length(data["bus"])
277285
angle_max = [branch["angmax"] for branch in data["branch"]]
278286
sort!(angle_max, rev=true)
279-
280-
return sum(angle_max[1:bus_count-1])
287+
if length(angle_max) > 1
288+
return sum(angle_max[1:bus_count-1])
289+
end
290+
return angle_max[1]
281291
end
282292

283293
function calc_min_phase_angle(data::Dict{AbstractString,Any})
284294
bus_count = length(data["bus"])
285295
angle_min = [branch["angmin"] for branch in data["branch"]]
286296
sort!(angle_min)
287-
288-
return sum(angle_min[1:bus_count-1])
297+
if length(angle_min) > 1
298+
return sum(angle_min[1:bus_count-1])
299+
end
300+
return angle_min[1]
289301
end

src/core/variable.jl

+5-8
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,7 @@ function variable_reactive_line_flow{T}(pm::GenericPowerModel{T}; bounded = true
8989
return q
9090
end
9191

92-
function compute_voltage_product_bounds{T}(pm::GenericPowerModel{T})
93-
buspairs = pm.set.buspairs
94-
buspair_indexes = pm.set.buspair_indexes
95-
92+
function compute_voltage_product_bounds(buspairs, buspair_indexes)
9693
wr_min = Dict([(bp, -Inf) for bp in buspair_indexes])
9794
wr_max = Dict([(bp, Inf) for bp in buspair_indexes])
9895
wi_min = Dict([(bp, -Inf) for bp in buspair_indexes])
@@ -126,7 +123,7 @@ end
126123

127124
function variable_complex_voltage_product{T}(pm::GenericPowerModel{T}; bounded = true)
128125
if bounded
129-
wr_min, wr_max, wi_min, wi_max = compute_voltage_product_bounds(pm)
126+
wr_min, wr_max, wi_min, wi_max = compute_voltage_product_bounds(pm.set.buspairs, pm.set.buspair_indexes)
130127

131128
@variable(pm.model, wr_min[bp] <= wr[bp in pm.set.buspair_indexes] <= wr_max[bp], start = getstart(pm.set.buspairs, bp, "wr_start", 1.0))
132129
@variable(pm.model, wi_min[bp] <= wi[bp in pm.set.buspair_indexes] <= wi_max[bp], start = getstart(pm.set.buspairs, bp, "wi_start"))
@@ -138,18 +135,18 @@ function variable_complex_voltage_product{T}(pm::GenericPowerModel{T}; bounded =
138135
end
139136

140137
function variable_complex_voltage_product_on_off{T}(pm::GenericPowerModel{T})
141-
wr_min, wr_max, wi_min, wi_max = compute_voltage_product_bounds(pm)
138+
wr_min, wr_max, wi_min, wi_max = compute_voltage_product_bounds(pm.set.buspairs, pm.set.buspair_indexes)
142139

143140
bi_bp = Dict([(i, (b["f_bus"], b["t_bus"])) for (i,b) in pm.set.branches])
144141

145142
@variable(pm.model, min(0, wr_min[bi_bp[b]]) <= wr[b in pm.set.branch_indexes] <= max(0, wr_max[bi_bp[b]]), start = getstart(pm.set.buspairs, bi_bp[b], "wr_start", 1.0))
146-
@variable(pm.model, min(0, wi_min[bi_bp[b]]) <= wi[b in pm.set.branch_indexes] <= max(0, wi_max[bi_bp[b]]), start = getstart(pm.set.buspairs, bi_bp[b], "wr_start"))
143+
@variable(pm.model, min(0, wi_min[bi_bp[b]]) <= wi[b in pm.set.branch_indexes] <= max(0, wi_max[bi_bp[b]]), start = getstart(pm.set.buspairs, bi_bp[b], "wi_start"))
147144

148145
return wr, wi
149146
end
150147

151148
function variable_complex_voltage_product_matrix{T}(pm::GenericPowerModel{T})
152-
wr_min, wr_max, wi_min, wi_max = compute_voltage_product_bounds(pm)
149+
wr_min, wr_max, wi_min, wi_max = compute_voltage_product_bounds(pm.set.buspairs, pm.set.buspair_indexes)
153150

154151
w_index = 1:length(pm.set.bus_indexes)
155152
lookup_w_index = Dict([(bi, i) for (i,bi) in enumerate(pm.set.bus_indexes)])

src/form/wr.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ function constraint_voltage_magnitude_sqr_to_on_off{T}(pm::GenericPowerModel{T})
224224
end
225225

226226
function constraint_complex_voltage_product_on_off{T}(pm::GenericPowerModel{T})
227-
wr_min, wr_max, wi_min, wi_max = compute_voltage_product_bounds(pm)
227+
wr_min, wr_max, wi_min, wi_max = compute_voltage_product_bounds(pm.set.buspairs, pm.set.buspair_indexes)
228228

229229
bi_bp = Dict([(i, (b["f_bus"], b["t_bus"])) for (i,b) in pm.set.branches])
230230

0 commit comments

Comments
 (0)