Decomposing Problems

Methods to decompose and solve the SinglePhase Branch Flow Model are provided based on the work in [2]. These methods are most advantageous when solving the non-linear (unrelaxed) power flow equations and are only valid(?) in radial networks.

CommonOPF.split_networkFunction
split_network(net::Network, bus::String)::Tuple{Network, Network}

Split net into one Network for everything above bus and one Network for everything below bus.

source
split_network(net::Network, bus::String, out_busses::Vector{String})::Tuple{Network, Network}

Split net into net_above and net_below where net_below has only out_busses and net_above has union( [bus], setdiff(busses(net), out_busses) ). We want to keep bus in both networks because there can be multiple branches out of bus that are not in out_busses.

Note that out_busses must contain bus

source
CommonOPF.init_split_networks!Function
init_split_networks!(nets::Vector{Network{SinglePhase}}; init_vs::Dict = Dict())

Set the loads on the upstream leaf nodes equal to the sum of all the loads in the downstream nodes. It is important that the order of nets is from leaf branches to trunk branches so that the sums of loads take into account all downstream sub-trees.

if init_vs is provided, the net.v0 is set for the Input with its net.substation_bus equal to the key in init_vs

init_vs = Dict(
    "sub_bus_1" => 0.98
)

for net in nets
    if net.substation_bus in keys(init_vs)
        net.v0 = init_vs[net.substation_bus]
    end
end
source
init_split_networks!(mg::MetaGraphsNext.MetaGraph; init_vs::Dict = Dict())

Use the :load_sum_order in mg to init_split_networks! in the correct order, i.e. set the loads at the leaf - substation connections as sums of all the loads (and the voltages at substations)

source
CommonOPF.splitting_bussesFunction
splitting_busses(net::Network, source::String; threshold::Int64=10)

Determine the busses to split a tree graph on by searching upward from the deepest leafs first and gathering the nearest busses until threshold is met for each subgraph.

Returns a Vector{String} for the bus names to split on and Vector{Vector{String}} for the corresponding busses within each sub-graph.

Note

It is not enough to have only the splitting busses to obey the max_busses limit because one must also know which sub branches to take from each splitting bus. In other words, we also need all the busses within each subgraph to split properly. For example, if a splitting bus has two sub branches then obeying the max_busses limit can require only including one sub branch out of the splitting bus. To know which branch to take we can use the other busses in the sub graph (which is why this method also returns the bussed in each subgraph).

source
CommonOPF.split_at_bussesFunction
split_at_busses(net::Network, at_busses::Vector{String})

Split net.graph using the at_busses

returns directed MetaGraph with vertices containing Network for the sub-graphs using integer vertex labels. For example mg[2] is the Network at the second vertex of the graph created by splitting the network via the at_busses.

source
split_at_busses(net::Network, at_busses::Vector{String}, with_busses::Vector{Vector{String}})

Split up p using the at_busses as each new substation_bus and containing the corresponding with_busses. The at_busses and with_busses can be determined using splitting_busses.

NOTE: this variation of spltatbusses allows for more than two splits at the same bus; whereas the other implementation of splitatbusses only splits the network into two parts for everything above and everything below a splitting bus.

source

[2]

Sadnan, Rabayet, and Anamika Dubey. "Distributed optimization using reduced network equivalents for radial power distribution systems." IEEE Transactions on Power Systems 36.4 (2021): 3645-3656.