Network Model

CommonOPF.NetworkType
struct Network <: AbstractNetwork
    graph::MetaGraphsNext.AbstractGraph
    substation_bus::String
    Sbase::Real
    Vbase::Real
    Zbase::Real
    v0::Union{Real, AbstractVecOrMat{<:Number}}
    Ntimesteps::Int
    bounds::VariableBounds
    var_names::AbstractVector{Symbol}
end

The Network model is used to store all the inputs required to create power flow and optimal power flow models. Underlying the Network model is a MetaGraphsNext.MetaGraph that stores the edge and node data in the network.

We leverage the AbstractNetwork type to make an intuitive interface for the Network model. For example, edges(network) returns an iterator of edge tuples with bus name values; (but if we used Graphs.edges(MetaGraph) we would get an iterator of Graphs.SimpleGraphs.SimpleEdge with integer values).

A Network can be created directly, via a Dict, or a filepath. The minimum inputs must have a vector of Conductor specifications and a Network key containing at least the substation_bus. See Input Formats for more details.

var_names is empty be default. It is used in the results getters like opf_results.

source
CommonOPF.NetworkMethod
function Network(d::Dict; directed::Union{Bool,Missing}=missing)

Construct a Network from a dictionary that has at least keys for:

  1. :Conductor, a vector of dicts with Conductor specs
  2. :Network, a dict with at least :substation_bus

If directed is missing then the graph is directed only if the number of busses and edges imply a radial graph.

source

Edges

The edges of the Network model include all power transfer elements, i.e. the devices in the power system that move power from one place to another and therefore have two or more busses. Edges include:

Within the network model edges are indexed via two-tuples of bus names like so:

using CommonOPF
net = Network_IEEE13_SinglePhase()
net[("650", "632")]
CommonOPF.Conductor
  busses: Tuple{String, String}
  phases: Missing missing
  name: String "mtx601"
  template: Missing missing
  r0: Missing missing
  x0: Missing missing
  r1: Float64 0.185966659863092
  x1: Float64 0.596766656810831
  c1: Missing missing
  rmatrix: Missing missing
  xmatrix: Missing missing
  cmatrix: Missing missing
  length: Float64 0.3787878787878788
  amps_limit: Missing missing

Nodes

The abstract node in the graph model is really an electrical bus. In single phase models a bus and a node are synonymous. However, in multi-phase models we can think of each bus have multiple nodes, or terminals, where each phase-wire connects. Busses are implicitly specified in the busses of the edge specifications.

Nodes contain:

Within the network model busses are indexed via bus names like so:

using CommonOPF
net = Network_IEEE13_SinglePhase()
net["675"]
Dict{Symbol, Any} with 1 entry:
  :Load => Load("675", [281], [154], missing, missing, missing, missing, missin…

Network Reduction

A few convenience methods are provided in CommonOPF for reducing network complexity by removing intermediate busses and trimming branches that will not typically impact OPF results.

CommonOPF.remove_bus!Method
remove_bus!(j::String, net::Network{SinglePhase})

Remove bus j in the line i->j->k from the model by making an equivalent line from busses i->k

source
CommonOPF.reduce_tree!Method
reduce_tree!(net::Network{SinglePhase})

combine any line sets with intermediate busses that have indegree == outdegree == 1 and is not a load bus into a single line

See remove_bus! for how the two lines are combined.

source
CommonOPF.trim_tree!Function
trim_tree!(net::Network)

Trim any branches that have empty busses, i.e. remove the branches that have no loads or DER.

source
CommonOPF.trim_tree_once!Function
trim_tree_once!(net::Network)

A support function for trim_tree!, trim_tree_once! removes all the empty leaf busses. When trimming the tree sometimes new leafs are created. So trim_tree! loops over trim_tree_once!.

source