Skip to content

Commit

Permalink
Add layout weights (#105)
Browse files Browse the repository at this point in the history
  • Loading branch information
noahrhodes authored Jul 11, 2022
1 parent 2915d26 commit 6a7d8d6
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 7 deletions.
5 changes: 4 additions & 1 deletion docs/src/data_transformations/layouts.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,7 @@ The layout algorithm arguments can be also passed in directly through `powerplot
powerplot(case; layout_algorithm=Spring, iterations=50)
```

When using `fixed=true`, a variation of the `SFDP` algorithm is sued that does not update corrdinates with prior coordinates set. The same arguments arguments as the `SFDP` algorithm can be used to modify the layout.
When using `fixed=true`, a variation of the `SFDP` algorithm is used that does not update corrdinates with prior coordinates set. The same arguments arguments as the `SFDP` algorithm can be used to modify the layout.


The default weights for edge-type components (branches, dc lines, etc.) are `1.0`. The default weight for connectors (links from e.g. generators to buses) is 0.5. They can be modified by passing the argument `edge_weight` or `connector_weight` to the layout function. If a component has a `weight` entry in its data dictionary, such as `data["branch"]["1"]["weight"]`, this weight will be used instead.
2 changes: 1 addition & 1 deletion src/core/data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ function offset_parallel_edges!(data,offset)

dx = xcoord_2 - xcoord_1
dy = ycoord_2 - ycoord_1
normal_direction = (-dy, dx)
normal_direction = (-dy, dx)./(sqrt(dx^2+dy^2))

offset_range = range(-offset, offset, length=n_edges)

Expand Down
32 changes: 31 additions & 1 deletion src/layouts/common.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,40 @@ function layout_network(case::Dict{String,<:Any};
layout_algorithm = kamada_kawai,
node_types::Array{String,1}=["bus","gen","storage","load"],
edge_types::Array{String,1}=["switch","branch","dcline","transformer"],
connector_weight=0.5,
edge_weight=1.0,
kwargs...
)

data = deepcopy(case)
PMG = PowerModelsGraph(data,node_types,edge_types)

# calculate weights
weights = zeros(size(PMG.graph))
for ((s,d),(comp_type,comp_id)) in PMG.edge_comp_map

if haskey(case[comp_type][comp_id],"weight")
w = compcase[comp_type][comp_id]["weight"]
else
w=edge_weight
end
if w>weights[s,d]
weights[s,d]= w
weights[d,s]= w
end
end
for ((s,d),(comp_type,comp_id)) in PMG.edge_connector_map
if haskey(case[comp_type][comp_id],"weight")
w = compcase[comp_type][comp_id]["weight"]
else
w=connector_weight
end
if w>weights[s,d]
weights[s,d]= w
weights[d,s]= w
end
end

if fixed==true # use fixed-position SFDP layout
rng = MersenneTwister(1)

Expand All @@ -60,17 +88,19 @@ function layout_network(case::Dict{String,<:Any};

# Create SFDP layout with fixed nodes
a = Graphs.adjacency_matrix(PMG.graph)
a = a.*weights
pos = convert(Array,RecursiveArrayTools.VectorOfArray(SFDP_fixed(; fixed = fixed_pos, initialpos=initialpos, kwargs...)(a)))
positions = [[pos[1,i],pos[2,i]] for i in 1:size(pos,2)]

elseif layout_algorithm [Shell, SFDP, Buchheim, Spring, Stress, SquareGrid, Spectral] # Create layout from NetworkLayouts algorithms
a = Graphs.adjacency_matrix(PMG.graph)
a = a.*weights
pos = convert(Array,RecursiveArrayTools.VectorOfArray(layout_algorithm(;kwargs...)(a)))
positions = [[pos[1,i],pos[2,i]] for i in 1:size(pos,2)]

elseif layout_algorithm==kamada_kawai
# create layout using Kamada Kawai algorithm
positions = layout_algorithm(PMG; kwargs...)
positions = layout_algorithm(PMG; weights=weights, kwargs...)
else
Memento.error(_LOGGER, "layout_algorithm `$(layout_algorithm)` not supported.")
end
Expand Down
4 changes: 2 additions & 2 deletions src/layouts/kamada_kawaii_layout.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
`
calculate node positions use Kamada Kawai layout algorithm
"""
function kamada_kawai(G::PowerModelsGraph, dist::Union{Nothing,AbstractMatrix{<:Real}}=nothing, pos::Union{Nothing,AbstractMatrix{<:Real}}=nothing, weight="weight", scale=1, center=nothing, dim=2; kwargs...)
function kamada_kawai(G::PowerModelsGraph; dist::Union{Nothing,AbstractMatrix{<:Real}}=nothing, pos::Union{Nothing,AbstractMatrix{<:Real}}=nothing, weights=nothing, scale=1, center=nothing, dim=2, kwargs...)
graph = G.graph # convert to undirected graph
nNodes = Graphs.nv(graph)
if nNodes == 0
Expand All @@ -22,7 +22,7 @@ function kamada_kawai(G::PowerModelsGraph, dist::Union{Nothing,AbstractMatrix{<:
if dist===nothing
dist=Dict()
for i in 1:nNodes
dist[i]=Graphs.dijkstra_shortest_paths(graph, i).dists
dist[i]=Graphs.dijkstra_shortest_paths(graph, i, weights).dists
end
end
dist_mtx = 1e6 * ones(nNodes, nNodes)
Expand Down
6 changes: 4 additions & 2 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,10 @@ data = PowerModels.parse_file("$(joinpath(dirname(pathof(PowerModels)), ".."))/t
@test data["dcline"]["1"]["xcoord_2"] == data["branch"]["1"]["xcoord_2"]

offset_parallel_edges!(data,0.05) # offset, ensures coordinates values are different
@test isapprox(data["dcline"]["1"]["xcoord_1"] - data["branch"]["1"]["xcoord_1"], .03, atol=1e-1)
@test isapprox(data["dcline"]["1"]["xcoord_2"] - data["branch"]["1"]["xcoord_2"], .03, atol=1e-1)
dist = sqrt((data["dcline"]["1"]["xcoord_1"] - data["branch"]["1"]["xcoord_1"])^2+
(data["dcline"]["1"]["ycoord_1"] - data["branch"]["1"]["ycoord_1"])^2
)
@test isapprox(dist, 0.05*2; atol=1e-8)
end
end

Expand Down

0 comments on commit 6a7d8d6

Please sign in to comment.