Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
47 changes: 47 additions & 0 deletions src/carpanzano_tearing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,52 @@ $TYPEDFIELDS
eqfilter::F3 = (_ -> true)
end

"""
$TYPEDSIGNATURES

In `full_var_eq_matching`, for a fully determined system, we expect every valid variable
to be matched to a valid equation. `var_eq_matching` will have some `unassigned`. Update
`full_var_eq_matching` to match `var_eq_matching`, and fill in the `unassigned` as best as
possible.
"""
function update_full_var_eq_matching!(
graph, full_var_eq_matching, var_eq_matching, vars::Vector{Int},
eqs::OrderedSet{Int}; varfilter
)
# In `full_var_eq_matching`, for a fully determined system, we expect every valid
# variable to be matched to a valid equation. `var_eq_matching` will have some
# `unassigned`. Update `full_var_eq_matching` to match `var_eq_matching`, and
# fill in the `unassigned` as best as possible.
for var in vars
if varfilter(var)
eq = full_var_eq_matching[var] = var_eq_matching[var]
eq isa Int && delete!(eqs, eq)
end
end

for var in vars
isempty(eqs) && break
varfilter(var) || continue
_eq = full_var_eq_matching[var]
_eq isa Int && continue
found = false
for eq in eqs
Graphs.has_edge(graph, BipartiteGraphs.BipartiteEdge(eq, var)) || continue
found = true
full_var_eq_matching[var] = eq
delete!(eqs, eq)
break
end
found && continue
eq = full_var_eq_matching[var] = first(eqs)
delete!(eqs, eq)
end
end

function (alg::CarpanzanoTearing)(structure::SystemStructure)
(; isder, varfilter, eqfilter) = alg
(; graph, solvable_graph) = structure

var_eq_matching = maximal_matching(
graph, Unassigned;
srcfilter = eqfilter,
Expand All @@ -54,9 +97,11 @@ function (alg::CarpanzanoTearing)(structure::SystemStructure)

active_vars = OrderedSet{Int}()
active_eqs = OrderedSet{Int}()
remaining_eqs = OrderedSet{Int}()
for vars in var_sccs
empty!(active_vars)
empty!(active_eqs)
empty!(remaining_eqs)
for var in vars
# Identify variables and equations in this SCC
if varfilter(var)
Expand All @@ -65,12 +110,14 @@ function (alg::CarpanzanoTearing)(structure::SystemStructure)
# pass the filter.
if var_eq_matching[var] isa Int
push!(active_eqs, var_eq_matching[var])
push!(remaining_eqs, var_eq_matching[var])
end
end
# Tearing will now determine the matching
var_eq_matching[var] = unassigned
end
carpanzano_tear_scc!(alg, structure, var_eq_matching, active_vars, active_eqs)
update_full_var_eq_matching!(graph, full_var_eq_matching, var_eq_matching, vars, remaining_eqs; varfilter)
end

return TearingResult(var_eq_matching, full_var_eq_matching, var_sccs), (;)
Expand Down
4 changes: 4 additions & 0 deletions src/modia_tearing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -109,19 +109,22 @@ function tear_graph_modia(structure::SystemStructure, isder::F = nothing,
filtered_vars = BitSet()
free_eqs = free_equations(graph, var_sccs, var_eq_matching, varfilter)
is_overdetemined = !isempty(free_eqs)
remaining_eqs = OrderedSet{Int}()
for vars in var_sccs
for var in vars
if varfilter(var)
push!(filtered_vars, var)
if var_eq_matching[var] !== unassigned
push!(ieqs, var_eq_matching[var])
push!(remaining_eqs, var_eq_matching[var])
end
end
var_eq_matching[var] = unassigned
end
tear_graph_block_modia!(var_eq_matching, ict, solvable_graph, ieqs,
filtered_vars,
isder)
update_full_var_eq_matching!(graph, full_var_eq_matching, var_eq_matching, vars, remaining_eqs; varfilter)

# If the systems is overdetemined, we cannot assume the free equations
# will not form algebraic loops with equations in the sccs.
Expand All @@ -134,6 +137,7 @@ function tear_graph_modia(structure::SystemStructure, isder::F = nothing,
end
empty!(ieqs)
empty!(filtered_vars)
empty!(remaining_eqs)
end
return var_eq_matching, full_var_eq_matching, var_sccs
end
Loading