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

afc/radial_branches_matrices #67

Merged
merged 39 commits into from
Jan 11, 2024
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
384221e
afc/updated test for radial branches, stated changes on BA
alefcastelli Dec 14, 2023
8461498
afc/updated BA matrix with radial lines
alefcastelli Dec 14, 2023
f8ba721
afc/new methods for a, ba and aba with radial branches
alefcastelli Dec 14, 2023
ec9efc7
afc/finished incidence matrix with tests
alefcastelli Dec 20, 2023
00485fb
afc/ fixed ba matrix with radial lines and test
alefcastelli Dec 20, 2023
3aa6143
afc/missing part...
alefcastelli Dec 20, 2023
dee3bfb
afc/updated ABA and tests
alefcastelli Dec 20, 2023
3b64e89
afc/fixes
alefcastelli Dec 20, 2023
37fa497
afc/found arror in testing for ABA
alefcastelli Dec 20, 2023
d58bb86
afc/ptdf chagnese - to be continued
alefcastelli Dec 21, 2023
a928840
afc/radial features for PTDF matirx, tests passed
alefcastelli Dec 22, 2023
08dfda2
afc/fixed tests and docstring for PTDF, completed VirtualPTDF (radial…
alefcastelli Dec 22, 2023
128d890
afc/radial branches for LODF, tests passed
alefcastelli Dec 22, 2023
7546d80
afc/formatter
alefcastelli Dec 22, 2023
b1012f3
afc/virtual lodf with radial branches, tests passed
alefcastelli Dec 22, 2023
5b8624b
afc/formatter
alefcastelli Dec 22, 2023
c63f66b
afc/minor bug
alefcastelli Dec 22, 2023
89b14de
fixes to radial branches
jd-lara Dec 28, 2023
d4ea703
fix bus aggregation
jd-lara Dec 28, 2023
2b6f15d
add subnetworks back
jd-lara Dec 28, 2023
f58c137
add new fields and updtes to radial branhces
jd-lara Jan 2, 2024
44c2e85
undo changes to IncidenceMatrix
jd-lara Jan 2, 2024
e3d95e7
remove unnecessarty test
jd-lara Jan 2, 2024
1bf7548
change conditional fix
jd-lara Jan 3, 2024
841a380
add docstrings and bug fixes
jd-lara Jan 3, 2024
63c6b7e
formatter
jd-lara Jan 3, 2024
762353d
add new methods for incidence matrix
jd-lara Jan 3, 2024
407670b
fixes to LODF and PTDF calculations
jd-lara Jan 3, 2024
6ff7891
fix tests
jd-lara Jan 3, 2024
130ad34
afc/fixed todos, fixed lodf, added tests
alefcastelli Jan 9, 2024
7dfccc9
afc/ found bug in VirtualLODF and some typos
alefcastelli Jan 10, 2024
71e5c73
afc/fixed PTDF and test
alefcastelli Jan 10, 2024
8c208d2
formatter
jd-lara Jan 10, 2024
ec03f4e
afc/bug found, "reduce_A_matrix" still to be checked
alefcastelli Jan 10, 2024
dc0443e
Merge branch 'afc/radial_branches_matrices' of https://github.com/NRE…
alefcastelli Jan 10, 2024
cb45fe4
afc/formatter
alefcastelli Jan 10, 2024
d1c5e36
afc/updated reduce_A_matrix
alefcastelli Jan 11, 2024
c00703d
afc/ changed function output
alefcastelli Jan 11, 2024
f590cb1
afc/minor change
alefcastelli Jan 11, 2024
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
54 changes: 43 additions & 11 deletions src/BA_ABA_matrices.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Structure containing the BA matrix and other relevant data.

# Arguments
- `data::SparseArrays.SparseMatrixCSC{Float64, Int}`:
the transposed BA matrix coming from the product between the Incidence
the transposed BA matrix coming from the product between the Incidence
Matrix A and the Matrix of Susceptance B
- `axes<:NTuple{2, Dict}`:
Tuple containing two vectors, the first one contains the names of each
Expand All @@ -14,30 +14,46 @@ Structure containing the BA matrix and other relevant data.
Tuple containing 2 Dictionaries mapping the number of rows and columns
with the names of buses and branches
- `ref_bus_positions::Set{Int}`:
Vector containing the indexes of the columns of the BA matrix corresponding
Set containing the indexes of the columns of the BA matrix corresponding
to the refence buses
- `radial_branches::RadialBranches`:
Structure containing the radial branches and leaf buses that were removed
while evaluating the matrix
"""
struct BA_Matrix{Ax, L <: NTuple{2, Dict}} <: PowerNetworkMatrix{Float64}
data::SparseArrays.SparseMatrixCSC{Float64, Int}
axes::Ax
lookup::L
ref_bus_positions::Set{Int}
radial_branches::RadialBranches
end

"""
Build the BA matrix from a given System

# Arguments
- `sys::PSY.System`:
PSY system for which the matrix is constructed
- `reduce_radial_branches::Bool`:
if True the matrix is build considering radial branches removed from
the system
"""
function BA_Matrix(sys::PSY.System)
branches = get_ac_branches(sys)
buses = get_buses(sys)
function BA_Matrix(sys::PSY.System; reduce_radial_branches::Bool = false)
if reduce_radial_branches
rb = RadialBranches(IncidenceMatrix(sys))
else
rb = RadialBranches()
end
branches = get_ac_branches(sys, rb.radial_branches)
buses = get_buses(sys, rb.bus_reduction_map)
ref_bus_positions = find_slack_positions(buses)
bus_lookup = make_ax_ref(buses)
line_ax = [PSY.get_name(branch) for branch in branches]
bus_ax = [PSY.get_number(bus) for bus in setdiff(buses, ref_bus_positions)]
axes = (bus_ax, line_ax)
lookup = (make_ax_ref(bus_ax), make_ax_ref(line_ax))
data = calculate_BA_matrix(branches, bus_lookup)
return BA_Matrix(data, axes, lookup, ref_bus_positions)
return BA_Matrix(data, axes, lookup, ref_bus_positions, rb)
end

"""
Expand All @@ -48,7 +64,7 @@ Structure containing the ABA matrix and other relevant data.
the ABA matrix coming from the product between the Incidence Matrix A and
the Matrix BA.
- `axes<:NTuple{2, Dict}`:
Tuple containing two identical vectors, both containing the number of
Tuple containing two identical vectors, both containing the number of
each bus of the network (each one related to a row/column of the Matrix
in "data"), excluding the slack buses.
- `lookup<:NTuple{2, Dict}`:
Expand All @@ -59,6 +75,9 @@ Structure containing the ABA matrix and other relevant data.
to the refence buses
- `K<:Union{Nothing, KLU.KLUFactorization{Float64, Int}}`:
either nothing or a container for KLU factorization matrices (LU factorization)
- `radial_branches::RadialBranches`:
Structure containing the radial branches and leaf buses that were removed
while evaluating the matrix
"""
struct ABA_Matrix{
Ax,
Expand All @@ -70,6 +89,7 @@ struct ABA_Matrix{
lookup::L
ref_bus_positions::Set{Int}
K::F
radial_branches::RadialBranches
end

"""
Expand All @@ -82,9 +102,19 @@ Builds the ABA matrix from a System
# Keyword arguments
- `factorize`: if true populates ABA_Matrix.K with KLU factorization matrices
"""
function ABA_Matrix(sys::PSY.System; factorize = false)
branches = get_ac_branches(sys)
buses = get_buses(sys)
function ABA_Matrix(
sys::PSY.System;
factorize = false,
reduce_radial_branches::Bool = false,
)
if reduce_radial_branches
rb = RadialBranches(IncidenceMatrix(sys))
else
rb = RadialBranches()
end

branches = get_ac_branches(sys, rb.radial_branches)
buses = get_buses(sys, rb.bus_reduction_map)
bus_lookup = make_ax_ref(buses)

A, ref_bus_positions = calculate_A_matrix(branches, buses)
Expand All @@ -107,6 +137,7 @@ function ABA_Matrix(sys::PSY.System; factorize = false)
lookup,
ref_bus_positions,
K,
rb,
)
end

Expand All @@ -124,6 +155,7 @@ function factorize(ABA::ABA_Matrix{Ax, L, Nothing}) where {Ax, L <: NTuple{2, Di
deepcopy(ABA.lookup),
deepcopy(ABA.ref_bus_positions),
klu(ABA.data),
deepcopy(ABA.radial_branches),
)
return ABA_lu
end
Expand All @@ -149,7 +181,7 @@ function Base.getindex(
return A.data[bus_number, line_number]
end

# get_index functions: ABA_Matrix stores a square matrix whose number of rows
# get_index functions: ABA_Matrix stores a square matrix whose number of rows
# and column is equal to the number of the system's buses minus the slack ones,
# NOTE: bus_1, bus_2 are bus numbers not row and column indices!
function Base.getindex(A::ABA_Matrix, bus_1, bus_2)
Expand Down
4 changes: 2 additions & 2 deletions src/PowerNetworkMatrices.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ import Pardiso

# network calculations
include("PowerNetworkMatrix.jl")
include("BA_ABA_matrices.jl")
include("incedence_matrix.jl")
include("adjacency_matrix.jl")
include("common.jl")
include("radial_braches.jl")
include("common.jl")
include("BA_ABA_matrices.jl")
include("definitions.jl")
include("ptdf_calculations.jl")
include("ybus_calculations.jl")
Expand Down
68 changes: 50 additions & 18 deletions src/common.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ end
"""
Gets the AC branches from a given Systems.
"""
function get_ac_branches(sys::PSY.System)
function get_ac_branches(
sys::PSY.System,
radial_branches::Set{String} = Set{String}(),
)::Vector{PSY.ACBranch}
collection = Vector{PSY.ACBranch}()
for br in PSY.get_components(PSY.get_available, PSY.ACBranch, sys)
arc = PSY.get_arc(br)
Expand All @@ -31,7 +34,9 @@ function get_ac_branches(sys::PSY.System)
),
)
end
_add_to_collection!(collection, br)
if PSY.get_name(br) ∉ radial_branches
_add_to_collection!(collection, br)
end
end
return sort!(collection;
by = x -> (PSY.get_number(PSY.get_arc(x).from), PSY.get_number(PSY.get_arc(x).to)),
Expand All @@ -41,18 +46,35 @@ end
"""
Gets the non-isolated buses from a given System
"""
function get_buses(sys::PSY.System)::Vector{PSY.ACBus}
return sort!(
collect(
PSY.get_components(
x -> PSY.get_bustype(x) != ACBusTypes.ISOLATED,
PSY.ACBus,
sys,
),
);
by = x -> PSY.get_number(x),
)
function get_buses(
sys::PSY.System,
bus_reduction_map::Dict{Int64, Set{Int64}} = Dict{Int64, Set{Int64}}(),
)::Vector{PSY.ACBus}
leaf_buses = Set{PSY.Int64}()
if !isempty(bus_reduction_map)
for vals in values(bus_reduction_map)
union!(leaf_buses, vals)
end
end

count_i = 1
all_buses = PSY.get_components(PSY.ACBus, sys)
buses = Vector{PSY.ACBus}(undef, length(all_buses))
for b in all_buses
if PSY.get_bustype(b) == ACBusTypes.ISOLATED
continue
end

if PSY.get_number(b) ∈ leaf_buses
continue
end
buses[count_i] = b
count_i += 1
end

return sort!(deleteat!(buses, count_i:length(buses)); by = x -> PSY.get_number(x))
end

"""
Gets the indices of the reference (slack) buses.
NOTE:
Expand Down Expand Up @@ -157,11 +179,17 @@ function calculate_adjacency(
a = SparseArrays.spzeros(Int8, buscount, buscount)

for b in branches
(fr_b, to_b) = get_bus_indices(b, bus_lookup)
fr_b, to_b = get_bus_indices(b, bus_lookup)
a[fr_b, to_b] = 1
a[to_b, fr_b] = -1
a[fr_b, fr_b] = 1
a[to_b, to_b] = 1
end

# If a line is disconnected needs to check for the buses correctly
for i in 1:buscount
if PSY.get_bustype(buses[i]) == ACBusTypes.ISOLATED
continue
end
a[i, i] = 1
end

# Return both for type stability
Expand Down Expand Up @@ -191,6 +219,10 @@ function calculate_BA_matrix(
(fr_b, to_b) = get_bus_indices(b, bus_lookup)
b_val = PSY.get_series_susceptance(b)

if !isfinite(b_val)
error("Invalid value for branch $(PSY.summary(b)), $b_val")
end

push!(BA_I, fr_b)
push!(BA_J, ix)
push!(BA_V, b_val)
Expand Down Expand Up @@ -275,7 +307,7 @@ end
"""
!!! MISSING DOCUMENTATION !!!
"""
function assing_reference_buses(
function assign_reference_buses(
subnetworks::Dict{Int, Set{Int}},
ref_bus_positions::Set{Int},
)
Expand Down Expand Up @@ -320,7 +352,7 @@ function find_subnetworks(M::SparseArrays.SparseMatrixCSC, bus_numbers::Vector{I
subnetworks = Dict{Int, Set{Int}}()
for (ix, bus_number) in enumerate(bus_numbers)
neighbors = SparseArrays.nzrange(M, ix)
if length(neighbors) < 1
if length(neighbors) <= 1
@warn "Bus $bus_number is islanded"
subnetworks[bus_number] = Set{Int}(bus_number)
continue
Expand Down
49 changes: 45 additions & 4 deletions src/incedence_matrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ Incidence matrix: shows connection between buses, defining lines
Tuple containing two dictionaries, the first mapping the branches
and buses with their enumerated indexes.
- `ref_bus_positions::Set{Int}`:
vector containing the indices of the reference slack buses.
Vector containing the indices of the reference slack buses.
- `radial_branches::RadialBranches`:
Structure containing the radial branches and leaf buses that were removed
while evaluating the matrix
"""
struct IncidenceMatrix{Ax, L <: NTuple{2, Dict}} <: PowerNetworkMatrix{Int8}
data::SparseArrays.SparseMatrixCSC{Int8, Int}
Expand All @@ -26,16 +29,54 @@ get_lookup(A::IncidenceMatrix) = A.lookup
get_slack_position(A::IncidenceMatrix) = A.ref_bus_positions

"""
Builds the Incidence matrix by evaluating the actual matrix and other relevant
Builds the Incidence matrix of the system by evaluating the actual matrix and other relevant
values.

# Arguments
- `sys::PSY.System`:
the PowerSystem system to consider
- `reduce_radial_branches::Bool`:
if True the matrix will be evaluated discarding
all the radial branches and leaf buses (optional, default value is false)
"""
function IncidenceMatrix(sys::PSY.System)
function IncidenceMatrix(
sys::PSY.System,
)
data, axes, lookup, ref_bus_positions = evaluate_A_matrix_values(sys)
return IncidenceMatrix(data, axes, lookup, ref_bus_positions)
end

"""
Builds the Incidence matrix of the system by evaluating the actual matrix and other relevant
values.

# Arguments
- `sys::PSY.System`: the PowerSystem system to consider
- `radial_branches::RadialBranches`:
Structure containing the radial branches and leaf buses that were removed
while evaluating the matrix
"""
function evaluate_A_matrix_values(
sys::PSY.System,
)
branches = get_ac_branches(sys)
buses = get_buses(sys)
line_ax = [PSY.get_name(branch) for branch in branches]
bus_ax = [PSY.get_number(bus) for bus in buses]
data, ref_bus_positions = calculate_A_matrix(branches, buses)
axes = (line_ax, bus_ax)
lookup = (make_ax_ref(line_ax), make_ax_ref(bus_ax))
return IncidenceMatrix(data, axes, lookup, ref_bus_positions)
return data, axes, lookup, ref_bus_positions
end

function reduce_A_matrix(
A::IncidenceMatrix,
bus_reduction_map::Dict{Int, Set{Int}},
meshed_branches::Set{String},
)
branch_ixs = sort!([A.lookup[1][k] for k in meshed_branches])
bus_ixs = sort!([A.lookup[2][k] for k in keys(bus_reduction_map)])
ref_buses = [k for (k, v) in A.lookup[2] if v in A.ref_bus_positions]
ref_bus_positions = Set{Int}(i for i in bus_ixs if i in ref_buses)
return A.data[branch_ixs, bus_ixs], ref_bus_positions
end
Loading
Loading