Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding HVDC Line Implementation #111

Merged
merged 25 commits into from
Jul 29, 2017
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
53a74b6
Write out DC line data to dict
hakanergun Jun 27, 2017
33140e7
Bug fix DCLine data input from Matpower
hakanergun Jul 19, 2017
20e6681
Adding file for AC DC Power flow model
hakanergun Jul 19, 2017
a13a1ca
Add DC arcs and buspairs to base.jl
hakanergun Jul 20, 2017
733fb66
Consitent pmin, pmax fromulation
hakanergun Jul 20, 2017
8b83583
First draft of Matpower compatible DC line extension
hakanergun Jul 20, 2017
792b179
Merge branch lanl version to our branch
hakanergun Jul 24, 2017
804e3e9
Validating DC Line implementation
hakanergun Jul 24, 2017
3a71103
Bugfix after removal of dedicated acdc formulation
Jul 24, 2017
2de5c83
Further improve support for DC lines
Jul 24, 2017
8471dca
Add distflow based models
Jul 24, 2017
e3a5600
Removal of Distflow, will become separate project
Jul 25, 2017
a036afe
Fix OTS and TNEP tests
Jul 25, 2017
db51ca1
Bugfix/rewrite for negative PMIN values in a matpower case
Jul 25, 2017
32c08f3
Finalized testing of DC Line implementation
hakanergun Jul 26, 2017
9dd4c3c
Case 3 fix
Jul 26, 2017
589023b
Data warnings about dc lines
Jul 27, 2017
dc4fce0
Consistent formulation of DC line bounds
hakanergun Jul 27, 2017
b562caa
Merge branch 'master' of https://github.com/hakanergun/PowerModels.jl
hakanergun Jul 27, 2017
acd9729
Update of documentation
Jul 27, 2017
8d24a95
update of dc line warnings
Jul 27, 2017
4900714
Escape chars in case3.m
Jul 27, 2017
f3c3677
Suggested changes by Carleton
hakanergun Jul 28, 2017
db8892d
Updated description of keys in pm.ref
Jul 28, 2017
ec90a9a
Updated documentation
Jul 29, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
PowerModels.jl Change Log
PowerModels.jl Change Log
=================

### Staged
Expand All @@ -7,16 +7,17 @@ PowerModels.jl Change Log
- Fixed bug in constants for w-space phase angle difference constraints
- Fixed bug when no refrence bus was specified
- Fixed dcline parsing bug
- Support for DC Line formulation compatible with matpower

### v0.3.3
- Added JuMP v0.17 compatibility
- Reorganized documentation into Manual, Library, Developer, and Experimental Results
- Reorganized documentation into Manual, Library, Developer, and Experimental Results

### v0.3.2
- Updated type declarations to Julia v0.6 syntax
- Moved documentation to Documenter.jl (thanks to @yeesian)
- Added basic OPF results to Documentation
- Extended pm.ref include all fields from pm.data
- Extended pm.ref include all fields from pm.data

### v0.3.1
- Added JuMP v0.16 and Julia v0.6 compatibility
Expand Down Expand Up @@ -46,7 +47,7 @@ PowerModels.jl Change Log
- Added support Matlab cell arrays
- Added support for Matpower bus_names
- Added ability for reading non-standard Matpower data elements
- Added JuMP version v0.14 upper bound
- Added JuMP version v0.14 upper bound

### v0.2.2
- Added Transmission Network Expansion Planning (tnep) problem.
Expand Down
2 changes: 2 additions & 0 deletions docs/src/network-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ The data exchange via JSON files is ideal for building algorithms, however it is

In addition to parsing the standard Matpower parameters, PowerModels also supports extending the standard Matpower format in a number of ways as illustrated by the following examples. In these examples JSON document fragments are used to indicate the structure of the PowerModel dictionary.

Note that for DC lines, the flow results are returned using the same convention as for the AC lines, i.e. positive values for `p_from`/`q_from `and `p_to`/`q_to` indicating power flow from the 'to' node or 'from' node into the line. This means that w.r.t matpower the sign is identical for `p_from`, but opposite for `q_from`/`p_to`/`q_to`.

### Single Values
Single values are added to the root of the dictionary as follows,

Expand Down
24 changes: 21 additions & 3 deletions docs/src/specifications.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ variable_voltage(pm)
variable_active_generation(pm)
variable_reactive_generation(pm)
variable_line_flow(pm)
variable_line_flow_dc(pm)
```

### Constraints
Expand All @@ -31,6 +32,9 @@ for (i,branch) in pm.ref[:branch]
constraint_thermal_limit_from(pm, branch)
constraint_thermal_limit_to(pm, branch)
end
for (i,dcline) in pm.ref[:dcline]
constraint_dc_line(pm, dcline)
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here is an example

```

## Optimal Transmission Switching (OTS)
Expand All @@ -48,6 +52,7 @@ variable_voltage_on_off(pm)
variable_active_generation(pm)
variable_reactive_generation(pm)
variable_line_flow(pm)
variable_line_flow_dc(pm)
```

### Objective
Expand All @@ -73,6 +78,9 @@ for (i,branch) in pm.ref[:branch]
constraint_thermal_limit_from_on_off(pm, branch)
constraint_thermal_limit_to_on_off(pm, branch)
end
for (i,dcline) in pm.ref[:dcline]
constraint_dc_line(pm, dcline)
end
```

## Power Flow (PF)
Expand All @@ -85,6 +93,7 @@ variable_voltage(pm, bounded = false)
variable_active_generation(pm, bounded = false)
variable_reactive_generation(pm, bounded = false)
variable_line_flow(pm, bounded = false)
variable_line_flow_dc(pm, bounded = false)
```

### Constraints
Expand All @@ -93,6 +102,7 @@ constraint_theta_ref(pm)
constraint_voltage_magnitude_setpoint(pm, pm.ref[:bus][pm.ref[:ref_bus]])
constraint_voltage(pm)


for (i,bus) in pm.ref[:bus]
constraint_kcl_shunt(pm, bus)

Expand All @@ -113,6 +123,10 @@ for (i,branch) in pm.ref[:branch]
constraint_ohms_yt_from(pm, branch)
constraint_ohms_yt_to(pm, branch)
end
for (i,dcline) in pm.ref[:dcline]
constraint_active_dc_line_setpoint(pm, dcline)
constraint_dc_line_voltage(pm, dcline; epsilon = 0.00001)
end
```

## Transmission Network Expansion Planning (TNEP)
Expand All @@ -124,12 +138,13 @@ objective_tnep_cost(pm)

### Variables
```julia
variable_line_ne(pm)
variable_line_ne(pm)
variable_voltage(pm)
variable_voltage_ne(pm)
variable_active_generation(pm)
variable_reactive_generation(pm)
variable_line_flow(pm)
variable_line_flow_dc(pm)
variable_line_flow_ne(pm)
```

Expand All @@ -151,15 +166,18 @@ for (i,branch) in pm.ref[:branch]

constraint_thermal_limit_from(pm, branch)
constraint_thermal_limit_to(pm, branch)
end
end

for (i,branch) in pm.ref[:ne_branch]
constraint_ohms_yt_from_ne(pm, branch)
constraint_ohms_yt_to_ne(pm, branch)
constraint_ohms_yt_to_ne(pm, branch)

constraint_phase_angle_difference_ne(pm, branch)

constraint_thermal_limit_from_ne(pm, branch)
constraint_thermal_limit_to_ne(pm, branch)
end
for (i,dcline) in pm.ref[:dcline]
constraint_dc_line(pm, dcline)
end
```
57 changes: 56 additions & 1 deletion src/core/base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export
```
type GenericPowerModel{T<:AbstractPowerFormulation}
model::JuMP.Model
data::Dict{String,Any}
data::Dict{String,Any}
setting::Dict{String,Any}
solution::Dict{String,Any}
ref::Dict{Symbol,Any} # reference data
Expand Down Expand Up @@ -176,11 +176,16 @@ function build_ref(data::Dict{String,Any})
ref[:bus] = filter((i, bus) -> bus["bus_type"] != 4, ref[:bus])
ref[:gen] = filter((i, gen) -> gen["gen_status"] == 1 && gen["gen_bus"] in keys(ref[:bus]), ref[:gen])
ref[:branch] = filter((i, branch) -> branch["br_status"] == 1 && branch["f_bus"] in keys(ref[:bus]) && branch["t_bus"] in keys(ref[:bus]), ref[:branch])
ref[:dcline] = filter((i, dcline) -> dcline["br_status"] == 1 && dcline["f_bus"] in keys(ref[:bus]) && dcline["t_bus"] in keys(ref[:bus]), ref[:dcline])

ref[:arcs_from] = [(i,branch["f_bus"],branch["t_bus"]) for (i,branch) in ref[:branch]]
ref[:arcs_to] = [(i,branch["t_bus"],branch["f_bus"]) for (i,branch) in ref[:branch]]
ref[:arcs] = [ref[:arcs_from]; ref[:arcs_to]]

ref[:arcs_from_dc] = [(i,dcline["f_bus"],dcline["t_bus"]) for (i,dcline) in ref[:dcline]]
ref[:arcs_to_dc] = [(i,dcline["t_bus"],dcline["f_bus"]) for (i,dcline) in ref[:dcline]]
ref[:arcs_dc] = [ref[:arcs_from_dc]; ref[:arcs_to_dc]]

bus_gens = Dict([(i, []) for (i,bus) in ref[:bus]])
for (i,gen) in ref[:gen]
push!(bus_gens[gen["gen_bus"]], i)
Expand All @@ -193,6 +198,11 @@ function build_ref(data::Dict{String,Any})
end
ref[:bus_arcs] = bus_arcs

bus_arcs_dc = Dict([(i, []) for (i,bus) in ref[:bus]])
for (l,i,j) in ref[:arcs_dc]
push!(bus_arcs_dc[i], (l,i,j))
end
ref[:bus_arcs_dc] = bus_arcs_dc

# a set of buses to support multiple connected components
ref_buses = Dict()
Expand All @@ -217,6 +227,11 @@ function build_ref(data::Dict{String,Any})


ref[:buspairs] = buspair_parameters(ref[:arcs_from], ref[:branch], ref[:bus])
############################ DC LINES##########################################
if haskey(ref, :dcline)
ref[:buspairs_dc] = buspair_parameters_dc(ref[:arcs_from_dc], ref[:dcline], ref[:bus])
end
###############################################################################

if haskey(ref, :ne_branch)
ref[:ne_branch] = filter((i, branch) -> branch["br_status"] == 1 && branch["f_bus"] in keys(ref[:bus]) && branch["t_bus"] in keys(ref[:bus]), ref[:ne_branch])
Expand Down Expand Up @@ -284,3 +299,43 @@ function buspair_parameters(arcs_from, branches, buses)

return buspairs
end

"compute bus pair level structures for DC"
function buspair_parameters_dc(arcs_from_dc, dclines, buses)
buspair_indexes = collect(Set([(i,j) for (l,i,j) in arcs_from_dc]))

bp_angmin = Dict([(bp, -Inf) for bp in buspair_indexes])
bp_angmax = Dict([(bp, Inf) for bp in buspair_indexes])
bp_line = Dict([(bp, Inf) for bp in buspair_indexes])
pmint = Dict([(bp, Inf) for bp in buspair_indexes])
pminf = Dict([(bp, Inf) for bp in buspair_indexes])
pmaxt = Dict([(bp, Inf) for bp in buspair_indexes])
pmaxf = Dict([(bp, Inf) for bp in buspair_indexes])

for (l,dcline) in dclines
i = dcline["f_bus"]
j = dcline["t_bus"]

bp_line[(i,j)] = min(bp_line[(i,j)], l)
end

buspairs_dc = Dict([((i,j), Dict(
"line"=>bp_line[(i,j)],
"pminf"=>dclines[bp_line[(i,j)]]["pminf"],
"pmaxf"=>dclines[bp_line[(i,j)]]["pmaxf"],
"pmint"=>dclines[bp_line[(i,j)]]["pmint"],
"pmaxt"=>dclines[bp_line[(i,j)]]["pmaxt"],
"qminf"=>dclines[bp_line[(i,j)]]["qminf"],
"qmaxf"=>dclines[bp_line[(i,j)]]["qmaxf"],
"qmint"=>dclines[bp_line[(i,j)]]["qmint"],
"qmaxt"=>dclines[bp_line[(i,j)]]["qmaxt"],
"pf"=>dclines[bp_line[(i,j)]]["pf"],
"pt"=>dclines[bp_line[(i,j)]]["pt"],
"qf"=>dclines[bp_line[(i,j)]]["qf"],
"qt"=>dclines[bp_line[(i,j)]]["qt"],
"vf"=>dclines[bp_line[(i,j)]]["vf"],
"vt"=>dclines[bp_line[(i,j)]]["vt"]
)) for (i,j) in buspair_indexes])

return buspairs_dc
end
21 changes: 20 additions & 1 deletion src/core/constraint.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
###############################################################################
# This file defines commonly used constraints for power flow models
# These constraints generally assume that the model contains p and q values
# These constraints generally assume that the model contains p and q values
# for branches line flows and bus flow conservation
###############################################################################

Expand Down Expand Up @@ -88,3 +88,22 @@ function constraint_reactive_gen_setpoint(pm::GenericPowerModel, i, qg)
c = @constraint(pm.model, qg_var == qg)
return Set([c])
end

"`pf[i] == pf, pt[i] == pt`"
function constraint_active_dc_line_setpoint(pm::GenericPowerModel, i, f_idx, t_idx, pf, pt, epsilon)
p_fr = getindex(pm.model, :p_dc)[f_idx]
p_to = getindex(pm.model, :p_dc)[t_idx]

if epsilon == 0.0
c1 = @constraint(pm.model, p_fr == pf)
c2 = @constraint(pm.model, p_to == pt)
return Set([c1,c2])
else
c1 = @constraint(pm.model, p_fr >= pf - epsilon)
c2 = @constraint(pm.model, p_to >= pt - epsilon)
c3 = @constraint(pm.model, p_fr <= pf + epsilon)
c4 = @constraint(pm.model, p_to <= pt + epsilon)
return Set([c1,c2,c3,c4])
end

end
Loading