Skip to content

Commit 71331ab

Browse files
committed
merging update with master
2 parents 3ddfb08 + ef11351 commit 71331ab

16 files changed

+80
-144
lines changed

README.md

+13-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# PowerModels.jl
22

3+
Release: [![PowerModels](http://pkg.julialang.org/badges/PowerModels_0.4.svg)](http://pkg.julialang.org/?pkg=PowerModels), [![PowerModels](http://pkg.julialang.org/badges/PowerModels_0.5.svg)](http://pkg.julialang.org/?pkg=PowerModels)
4+
5+
Dev:
36
[![Build Status](https://travis-ci.org/lanl-ansi/PowerModels.jl.svg?branch=master)](https://travis-ci.org/lanl-ansi/PowerModels.jl)
47
[![codecov](https://codecov.io/gh/lanl-ansi/PowerModels.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/lanl-ansi/PowerModels.jl)
58

@@ -25,11 +28,15 @@ This enables the definition of a wide variety of power network formulations and
2528

2629
## Installation
2730

28-
For the moment, PowerModels.jl is not yet registered as a Julia package. Hence, "clone" should be used instead of "add" for package installation,
31+
The latest stable release of PowerModels can be installed using the Julia package manager with,
32+
33+
`Pkg.add("PowerModels")`
34+
35+
For the current development version, "clone" this repository directly with,
2936

3037
`Pkg.clone("[email protected]:lanl-ansi/PowerModels.jl.git")`
3138

32-
At least one solver is required for running PowerModels. Using the open-source solver Ipopt is recommended, as it is extremely fast, and can be used to solve a wide variety of the problems and network formulations provided in PowerModels. The Ipopt solver is installed via,
39+
At least one solver is required for running PowerModels. Using the open-source solver Ipopt is recommended, as it is extremely fast, and can be used to solve a wide variety of the problems and network formulations provided in PowerModels. The Ipopt solver can be installed via tha package manager with,
3340

3441
`Pkg.add("Ipopt")`
3542

@@ -41,23 +48,23 @@ Once PowerModels is installed, Ipopt is installed, and a network data file (e.g.
4148
using PowerModels
4249
using Ipopt
4350
44-
run_ac_opf("nesta\_case3\_lmbd.m", IpoptSolver())
51+
run_ac_opf("nesta_case3_lmbd.m", IpoptSolver())
4552
```
4653

4754
Similarly, a DC Optimal Power Flow can be executed with,
4855
```
49-
run_dc_opf("nesta\_case3\_lmbd.m", IpoptSolver())
56+
run_dc_opf("nesta_case3_lmbd.m", IpoptSolver())
5057
```
5158

5259
In fact, "run_ac_opf" and "run_dc_opf" are shorthands for a more general formulation-independent OPF execution, "run_opf". For example, "run_ac_opf" is,
5360
```
54-
run_opf("nesta\_case3\_lmbd.m", ACPPowerModel, IpoptSolver())
61+
run_opf("nesta_case3_lmbd.m", ACPPowerModel, IpoptSolver())
5562
```
5663

5764
Where "ACPPowerModel" indicates an AC formulation in polar coordinates. This more generic "run_opf" allows one to solve an OPF problem with any power network formulation implemented in PowerModels. For example, an SOC Optimal Power Flow can be run with,
5865

5966
```
60-
run_opf("nesta\_case3\_lmbd.m", SOCWRPowerModel, IpoptSolver())
67+
run_opf("nesta_case3_lmbd.m", SOCWRPowerModel, IpoptSolver())
6168
```
6269

6370
Extending PowerModels with new problems and formulations will be covered in a another tutorial, that is not yet available.

src/core/base.jl

+14-39
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
# stuff that is universal to all power models
22

3-
export
3+
export
44
GenericPowerModel,
55
setdata, setsolver, solve
66

7-
87
type PowerDataSets
98
ref_bus
109
buses
@@ -26,8 +25,6 @@ abstract AbstractPowerModel
2625
abstract AbstractPowerFormulation
2726
abstract AbstractConicPowerFormulation <: AbstractPowerFormulation
2827

29-
30-
3128
type GenericPowerModel{T<:AbstractPowerFormulation} <: AbstractPowerModel
3229
model::Model
3330
data::Dict{AbstractString,Any}
@@ -36,7 +33,6 @@ type GenericPowerModel{T<:AbstractPowerFormulation} <: AbstractPowerModel
3633
solution::Dict{AbstractString,Any}
3734
end
3835

39-
4036
# default generic constructor
4137
function GenericPowerModel{T}(data::Dict{AbstractString,Any}, vars::T; setting = Dict{AbstractString,Any}(), solver = JuMP.UnsetSolver())
4238
data, sets = process_raw_data(data)
@@ -52,7 +48,6 @@ function GenericPowerModel{T}(data::Dict{AbstractString,Any}, vars::T; setting =
5248
return pm
5349
end
5450

55-
5651
function process_raw_data(data::Dict{AbstractString,Any})
5752
make_per_unit(data)
5853
unify_transformer_taps(data)
@@ -64,8 +59,6 @@ function process_raw_data(data::Dict{AbstractString,Any})
6459
return data, sets
6560
end
6661

67-
68-
6962
#
7063
# Just seems too hard to maintain with the default constructor
7164
#
@@ -79,7 +72,6 @@ end
7972

8073
#end
8174

82-
8375
# TODO Ask Miles, why do we need to put JuMP. here? using at top level should bring it in
8476
function JuMP.setsolver(pm::GenericPowerModel, solver::MathProgBase.AbstractMathProgSolver)
8577
setsolver(pm.model, solver)
@@ -97,7 +89,6 @@ function JuMP.solve(pm::GenericPowerModel)
9789
return status, solve_time
9890
end
9991

100-
10192
function run_generic_model(file, model_constructor, solver, post_method; solution_builder = get_solution, kwargs...)
10293
data = PowerModels.parse_file(file)
10394

@@ -110,8 +101,7 @@ function run_generic_model(file, model_constructor, solver, post_method; solutio
110101
return build_solution(pm, status, solve_time; solution_builder = solution_builder)
111102
end
112103

113-
114-
function build_sets(data :: Dict{AbstractString,Any})
104+
function build_sets(data::Dict{AbstractString,Any})
115105
bus_lookup = [ Int(bus["index"]) => bus for bus in data["bus"] ]
116106
gen_lookup = [ Int(gen["index"]) => gen for gen in data["gen"] ]
117107
for gencost in data["gencost"]
@@ -120,15 +110,14 @@ function build_sets(data :: Dict{AbstractString,Any})
120110
end
121111
branch_lookup = [ Int(branch["index"]) => branch for branch in data["branch"] ]
122112

123-
# filter turned off stuff
113+
# filter turned off stuff
124114
bus_lookup = filter((i, bus) -> bus["bus_type"] != 4, bus_lookup)
125115
gen_lookup = filter((i, gen) -> gen["gen_status"] == 1 && gen["gen_bus"] in keys(bus_lookup), gen_lookup)
126116
branch_lookup = filter((i, branch) -> branch["br_status"] == 1 && branch["f_bus"] in keys(bus_lookup) && branch["t_bus"] in keys(bus_lookup), branch_lookup)
127117

128-
129118
arcs_from = [(i,branch["f_bus"],branch["t_bus"]) for (i,branch) in branch_lookup]
130119
arcs_to = [(i,branch["t_bus"],branch["f_bus"]) for (i,branch) in branch_lookup]
131-
arcs = [arcs_from; arcs_to]
120+
arcs = [arcs_from; arcs_to]
132121

133122
bus_gens = [i => [] for (i,bus) in bus_lookup]
134123
for (i,gen) in gen_lookup
@@ -156,16 +145,15 @@ function build_sets(data :: Dict{AbstractString,Any})
156145

157146

158147
buspair_indexes = collect(Set([(i,j) for (l,i,j) in arcs_from]))
159-
buspairs = buspair_parameters(buspair_indexes, branch_lookup, bus_lookup)
148+
buspairs = buspair_parameters(buspair_indexes, branch_lookup, bus_lookup)
160149

161150
return PowerDataSets(ref_bus, bus_lookup, bus_idxs, gen_lookup, gen_idxs, branch_lookup, branch_idxs, bus_gens, arcs_from, arcs_to, arcs, bus_branches, buspairs, buspair_indexes)
162151
end
163152

164-
165153
# compute bus pair level structures
166154
function buspair_parameters(buspair_indexes, branches, buses)
167-
bp_angmin = [bp => -Inf for bp in buspair_indexes]
168-
bp_angmax = [bp => Inf for bp in buspair_indexes]
155+
bp_angmin = [bp => -Inf for bp in buspair_indexes]
156+
bp_angmax = [bp => Inf for bp in buspair_indexes]
169157
bp_line = [bp => Inf for bp in buspair_indexes]
170158

171159
for (l,branch) in branches
@@ -178,8 +166,8 @@ function buspair_parameters(buspair_indexes, branches, buses)
178166
end
179167

180168
buspairs = [(i,j) => Dict(
181-
"line"=>bp_line[(i,j)],
182-
"angmin"=>bp_angmin[(i,j)],
169+
"line"=>bp_line[(i,j)],
170+
"angmin"=>bp_angmin[(i,j)],
183171
"angmax"=>bp_angmax[(i,j)],
184172
"rate_a"=>branches[bp_line[(i,j)]]["rate_a"],
185173
"tap"=>branches[bp_line[(i,j)]]["tap"],
@@ -191,9 +179,6 @@ function buspair_parameters(buspair_indexes, branches, buses)
191179
return buspairs
192180
end
193181

194-
195-
196-
197182
not_pu = Set(["rate_a","rate_b","rate_c","bs","gs","pd","qd","pg","qg","pmax","pmin","qmax","qmin"])
198183
not_rad = Set(["angmax","angmin","shift","va"])
199184

@@ -209,7 +194,7 @@ function make_per_unit(mva_base::Number, data::Dict{AbstractString,Any})
209194
if k == "gencost"
210195
for cost_model in data[k]
211196
if cost_model["model"] != 2
212-
println("WARNING: Skipping generator cost model of tpye other than 2")
197+
warn("Skipping generator cost model of type other than 2")
213198
continue
214199
end
215200
degree = length(cost_model["cost"])
@@ -255,10 +240,8 @@ function unify_transformer_taps(data::Dict{AbstractString,Any})
255240
end
256241
end
257242

258-
259-
260243
# NOTE, this function assumes all values are p.u. and angles are in radians
261-
function add_branch_parameters(data :: Dict{AbstractString,Any})
244+
function add_branch_parameters(data::Dict{AbstractString,Any})
262245
min_theta_delta = calc_min_phase_angle(data)
263246
max_theta_delta = calc_max_phase_angle(data)
264247

@@ -278,7 +261,7 @@ function add_branch_parameters(data :: Dict{AbstractString,Any})
278261
end
279262
end
280263

281-
function standardize_cost_order(data :: Dict{AbstractString,Any})
264+
function standardize_cost_order(data::Dict{AbstractString,Any})
282265
for gencost in data["gencost"]
283266
if gencost["model"] == 2 && length(gencost["cost"]) < 3
284267
println("std gen cost: ",gencost["cost"])
@@ -289,26 +272,18 @@ function standardize_cost_order(data :: Dict{AbstractString,Any})
289272
end
290273
end
291274

292-
293-
function calc_max_phase_angle(data :: Dict{AbstractString,Any})
275+
function calc_max_phase_angle(data::Dict{AbstractString,Any})
294276
bus_count = length(data["bus"])
295277
angle_max = [branch["angmax"] for branch in data["branch"]]
296278
sort!(angle_max, rev=true)
297279

298280
return sum(angle_max[1:bus_count-1])
299281
end
300282

301-
function calc_min_phase_angle(data :: Dict{AbstractString,Any})
283+
function calc_min_phase_angle(data::Dict{AbstractString,Any})
302284
bus_count = length(data["bus"])
303285
angle_min = [branch["angmin"] for branch in data["branch"]]
304286
sort!(angle_min)
305287

306288
return sum(angle_min[1:bus_count-1])
307289
end
308-
309-
310-
311-
312-
313-
314-

src/core/constraint.jl

+3-8
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
##########################################################################################################
2-
# The purpose of this file is to define commonly used and created constraints used in power flow models
1+
################################################################################
2+
# This file defines commonly used and created constraints for power flow models
33
# This will hopefully make everything more compositional
4-
##########################################################################################################
5-
4+
################################################################################
65

76
# Generic thermal limit constraint
87
function constraint_thermal_limit_from{T}(pm::GenericPowerModel{T}, branch; scale = 1.0)
@@ -86,7 +85,6 @@ function constraint_thermal_limit_to_on_off{T}(pm::GenericPowerModel{T}, branch;
8685
return Set([c])
8786
end
8887

89-
9088
function constraint_active_gen_setpoint{T}(pm::GenericPowerModel{T}, gen)
9189
i = gen["index"]
9290
pg = getvariable(pm.model, :pg)[gen["index"]]
@@ -102,7 +100,6 @@ function constraint_reactive_gen_setpoint{T}(pm::GenericPowerModel{T}, gen)
102100
return Set([c])
103101
end
104102

105-
106103
function constraint_active_loss_lb{T}(pm::GenericPowerModel{T}, branch)
107104
@assert branch["br_r"] >= 0
108105

@@ -137,5 +134,3 @@ function constraint_reactive_loss_lb{T}(pm::GenericPowerModel{T}, branch)
137134
c = @constraint(m, q_fr + q_to >= -branch["br_b"]/2*(v_fr^2/branch["tap"]^2 + v_to^2))
138135
return Set([c])
139136
end
140-
141-

src/core/objective.jl

+4-8
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,23 @@
1-
##########################################################################################################
2-
# The purpose of this file is to define commonly used and created constraints used in power flow models
1+
################################################################################
2+
# This file is to defines commonly used constraints for power flow models
33
# This will hopefully make everything more compositional
4-
##########################################################################################################
5-
4+
################################################################################
65

76
function objective_min_fuel_cost{T}(pm::GenericPowerModel{T})
87
pg = getvariable(pm.model, :pg)
98
cost = (i) -> pm.set.gens[i]["cost"]
109
return @objective(pm.model, Min, sum{ cost(i)[1]*pg[i]^2 + cost(i)[2]*pg[i] + cost(i)[3], i in pm.set.gen_indexes} )
1110
end
1211

13-
1412
function objective_min_fuel_cost{T <: AbstractConicPowerFormulation}(pm::GenericPowerModel{T})
1513
@variable(pm.model, pm.set.gens[i]["pmin"]^2 <= pg_sqr[i in pm.set.gen_indexes] <= pm.set.gens[i]["pmax"]^2)
1614

1715
pg = getvariable(pm.model, :pg)
1816

1917
for (i, gen) in pm.set.gens
20-
@constraint(pm.model, norm([2*pg[i], pg_sqr[i]-1]) <= pg_sqr[i]+1)
18+
@constraint(pm.model, norm([2*pg[i], pg_sqr[i]-1]) <= pg_sqr[i]+1)
2119
end
2220

2321
cost = (i) -> pm.set.gens[i]["cost"]
2422
return @objective(pm.model, Min, sum{ cost(i)[1]*pg_sqr[i] + cost(i)[2]*pg[i] + cost(i)[3], i in pm.set.gen_indexes} )
2523
end
26-
27-

src/core/relaxation_scheme.jl

+5-15
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
1-
2-
31
function relaxation_complex_product(m, a, b, c, d)
4-
# TODO add LNC cuts to this
2+
# TODO add LNC cuts to this
53
c = @constraint(m, c^2 + d^2 <= a*b)
64
return Set([c])
75
end
86

9-
107
function relaxation_complex_product_on_off(m, a, b, c, d, z)
11-
# TODO add LNC cuts to this
8+
# TODO add LNC cuts to this
129
@assert getlowerbound(c) <= 0 && getupperbound(c) >= 0
1310
@assert getlowerbound(d) <= 0 && getupperbound(d) >= 0
14-
# assume c and d are already linked to z in other constraints
11+
# assume c and d are already linked to z in other constraints
1512
# and will be forced to 0 when z is 0
1613

1714
a_ub = getupperbound(a)
@@ -24,7 +21,6 @@ function relaxation_complex_product_on_off(m, a, b, c, d, z)
2421
return Set([c1, c2, c3])
2522
end
2623

27-
2824
function relaxation_equality_on_off(m, x, y, z)
2925
# assumes 0 is in the domain of y when z is 0
3026

@@ -37,23 +33,21 @@ function relaxation_equality_on_off(m, x, y, z)
3733
return Set([c1, c2])
3834
end
3935

40-
4136
# general relaxation of a square term
4237
function relaxation_sqr(m, x, y)
4338
c1 = @constraint(m, y >= x^2)
4439
c2 = @constraint(m, y <= (getupperbound(x)+getlowerbound(x))*x - getupperbound(x)*getlowerbound(x))
4540
return Set([c1, c2])
4641
end
4742

48-
4943
# general relaxation of a sin term
5044
function relaxation_sin(m, x, y)
5145
ub = getupperbound(x)
5246
lb = getlowerbound(x)
5347
@assert lb >= -pi/2 && ub <= pi/2
5448

5549
max_ad = max(abs(lb),abs(ub))
56-
50+
5751
if lb < 0 && ub > 0
5852
c1 = @constraint(m, y <= cos(max_ad/2)*(x - max_ad/2) + sin(max_ad/2))
5953
c2 = @constraint(m, y >= cos(max_ad/2)*(x + max_ad/2) - sin(max_ad/2))
@@ -69,21 +63,19 @@ function relaxation_sin(m, x, y)
6963
return Set([c1, c2])
7064
end
7165

72-
7366
# general relaxation of a cosine term
7467
function relaxation_cos(m, x, y)
7568
ub = getupperbound(x)
7669
lb = getlowerbound(x)
7770
@assert lb >= -pi/2 && ub <= pi/2
7871

7972
max_ad = max(abs(lb),abs(ub))
80-
73+
8174
c1 = @constraint(m, y <= 1 - (1-cos(max_ad))/(max_ad*max_ad)*(x^2))
8275
c2 = @constraint(m, y >= (cos(lb) - cos(ub))/(lb-ub)*(x - lb) + cos(lb))
8376
return Set([c1, c2])
8477
end
8578

86-
8779
# general relaxation of binlinear term (McCormick)
8880
function relaxation_product(m, x, y, z)
8981
x_ub = getupperbound(x)
@@ -98,5 +90,3 @@ function relaxation_product(m, x, y, z)
9890

9991
return Set([c1, c2, c3, c4])
10092
end
101-
102-

0 commit comments

Comments
 (0)