PowerModelsGraph

The PowerModels data dictionary is useful for storing and accessing data about a grid, but a graph structure can be useful to analyse metrics like node degree or eigenvector centrality. It is used in this pacakge to create Layouts for plotting networks.

mutable struct PowerModelsGraph
    graph::Graphs.SimpleDiGraph
    node_comp_map::Dict{Int,Tuple{String, String}}
    edge_comp_map::Dict{Tuple{Int,Int},Tuple{String, String}}
    edge_connector_map::Dict{Tuple{Int,Int},Tuple{String, String}}

The PowerModelsGraph type stores a directed graph of the network, and mapping between the nodes and edges and the components that they refer to.

The node_comp_map is a Dictionary where the keys are the graph nodes and the values are a tuple of the component type and id, e.g.

node_comp_map = Dict(
    1 => ("bus","2"),
    2 => ("gen","4")
)

The edge_comp_map is a similar mapping for components that form the edges of the network. Here, the keys are the endpoints of the directed edge.

edge_comp_map = Dict(
    (1,2) => ("branch","1"),
    (2,3) => ("dcline","4")
)

Connectors are additional lines that connect non-bus nodes to a bus, for example generators. The mapping is similar to the edge_comp_map.

edge_connector_map = Dict(
    (1,4) => ("gen","1"),
    (1,5) => ("gen","2")
)

To create a PowerModelsGraph, the component types for nodes and edges must be specified.

PowerModelsGraph(data::Dict{String,<:Any},
                node_types::Vector{String},
                edge_types::Vector{String}
)

There is also a convinient function with default node and edge types as keyword arguments.

PowerModelsGraph(data::Dict{String,<:Any};
                node_types=["bus","gen","storage"]::Array{String,1},
                edge_types=["branch","dcline","switch"]::Array{String,1}
)

PowerModelsGraph Example

using PowerModels
using PowerPlots
case = parse_file("case14.m")

# Specify node and edge types
case_PMG = PowerModelsGraph(case, ["bus","gen"], ["branch","dcline"])

# Use default node and edge types
case_PMG = PowerModelsGraph(case)
PowerModelsGraph(Graphs.SimpleGraphs.SimpleGraph{Int64}(36, [[7, 10, 15], [3, 14, 28], [2, 11, 29], [5, 11, 30], [4, 6, 11, 21], [5, 14, 22], [1, 8, 9, 10, 16, 20], [7, 9, 17, 23], [7, 8, 10, 12, 14, 24], [1, 7, 9, 11, 25]  …  [5], [6], [8], [9], [10], [11], [14], [2], [3], [4]]), Dict(5 => ("bus", "13"), 16 => ("gen", "2"), 20 => ("load", "1"), 12 => ("bus", "7"), 24 => ("load", "3"), 28 => ("load", "7"), 8 => ("bus", "3"), 17 => ("gen", "3"), 30 => ("load", "9"), 1 => ("bus", "1")…), Dict((4, 5) => ("branch", "19"), (11, 5) => ("branch", "13"), (12, 13) => ("branch", "14"), (12, 14) => ("branch", "15"), (9, 10) => ("branch", "7"), (10, 11) => ("branch", "10"), (11, 3) => ("branch", "11"), (7, 9) => ("branch", "4"), (14, 2) => ("branch", "16"), (9, 12) => ("branch", "8")…), Dict((11, 18) => ("gen", "4"), (2, 28) => ("load", "7"), (3, 29) => ("load", "8"), (1, 15) => ("gen", "1"), (4, 30) => ("load", "9"), (7, 20) => ("load", "1"), (14, 27) => ("load", "6"), (7, 16) => ("gen", "2"), (9, 24) => ("load", "3"), (8, 23) => ("load", "2")…))

Using PowerModelsGraph

using PowerModels
using PowerPlots
using Graphs
case = parse_file("case14.m")

# Create a graph where buses are nodes and branches are edges
case_PMG = PowerModelsGraph(case, ["bus"], ["branch"]);
PowerModelsGraph(Graphs.SimpleGraphs.SimpleGraph{Int64}(20, [[7, 10], [3, 14], [2, 11], [5, 11], [4, 6, 11], [5, 14], [1, 8, 9, 10], [7, 9], [7, 8, 10, 12, 14], [1, 7, 9, 11], [3, 4, 5, 10], [9, 13, 14], [12], [2, 6, 9, 12]]), Dict(5 => ("bus", "13"), 7 => ("bus", "2"), 12 => ("bus", "7"), 8 => ("bus", "3"), 1 => ("bus", "1"), 4 => ("bus", "12"), 6 => ("bus", "14"), 13 => ("bus", "8"), 2 => ("bus", "10"), 10 => ("bus", "5")…), Dict((4, 5) => ("branch", "19"), (11, 5) => ("branch", "13"), (12, 13) => ("branch", "14"), (12, 14) => ("branch", "15"), (9, 10) => ("branch", "7"), (10, 11) => ("branch", "10"), (11, 3) => ("branch", "11"), (7, 9) => ("branch", "4"), (14, 2) => ("branch", "16"), (9, 12) => ("branch", "8")…), Dict{Tuple{Int64, Int64}, Tuple{String, String}}())
g = Graphs.SimpleGraph(case_PMG.graph) # Does the graph contain cycles?
is_cyclic(g)
true
# Get the adjacency matrix
adjacency_matrix(case_PMG.graph)
14×14 SparseArrays.SparseMatrixCSC{Int64, Int64} with 40 stored entries:
 ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  1  ⋅  ⋅  1  ⋅  ⋅  ⋅  ⋅
 ⋅  ⋅  1  ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  1
 ⋅  1  ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  1  ⋅  ⋅  ⋅
 ⋅  ⋅  ⋅  ⋅  1  ⋅  ⋅  ⋅  ⋅  ⋅  1  ⋅  ⋅  ⋅
 ⋅  ⋅  ⋅  1  ⋅  1  ⋅  ⋅  ⋅  ⋅  1  ⋅  ⋅  ⋅
 ⋅  ⋅  ⋅  ⋅  1  ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  1
 1  ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  1  1  1  ⋅  ⋅  ⋅  ⋅
 ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  1  ⋅  1  ⋅  ⋅  ⋅  ⋅  ⋅
 ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  1  1  ⋅  1  ⋅  1  ⋅  1
 1  ⋅  ⋅  ⋅  ⋅  ⋅  1  ⋅  1  ⋅  1  ⋅  ⋅  ⋅
 ⋅  ⋅  1  1  1  ⋅  ⋅  ⋅  ⋅  1  ⋅  ⋅  ⋅  ⋅
 ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  1  ⋅  ⋅  ⋅  1  1
 ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  ⋅  1  ⋅  ⋅
 ⋅  1  ⋅  ⋅  ⋅  1  ⋅  ⋅  1  ⋅  ⋅  1  ⋅  ⋅