Skip to content

Commit 80f2b19

Browse files
committed
Add conservative kwarg in structural_transformation
`conservative=true` limits tearing to only solve for trivial linear systems where the coefficient has the absolute value of 1. This is useful for debugging numerical stability issues after tearing. By default, we set `conservative=false`.
1 parent 0cc954d commit 80f2b19

File tree

6 files changed

+21
-11
lines changed

6 files changed

+21
-11
lines changed

src/structural_transformation/pantelides.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ end
123123
124124
Perform Pantelides algorithm.
125125
"""
126-
function pantelides!(state::TransformationState; finalize = true, maxiters = 8000)
126+
function pantelides!(
127+
state::TransformationState; finalize = true, maxiters = 8000, kwargs...)
127128
@unpack graph, solvable_graph, var_to_diff, eq_to_diff = state.structure
128129
neqs = nsrcs(graph)
129130
nvars = nv(var_to_diff)
@@ -181,7 +182,7 @@ function pantelides!(state::TransformationState; finalize = true, maxiters = 800
181182
ecolor[eq] || continue
182183
# introduce a new equation
183184
neqs += 1
184-
eq_derivative!(state, eq)
185+
eq_derivative!(state, eq; kwargs...)
185186
end
186187

187188
for var in eachindex(vcolor)

src/structural_transformation/partial_state_selection.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ function dummy_derivative_graph!(state::TransformationState, jac = nothing;
173173
state_priority = nothing, log = Val(false), kwargs...)
174174
state.structure.solvable_graph === nothing && find_solvables!(state; kwargs...)
175175
complete!(state.structure)
176-
var_eq_matching = complete(pantelides!(state))
176+
var_eq_matching = complete(pantelides!(state; kwargs...))
177177
dummy_derivative_graph!(state.structure, var_eq_matching, jac, state_priority, log)
178178
end
179179

src/structural_transformation/symbolics_tearing.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ function eq_derivative_graph!(s::SystemStructure, eq::Int)
5656
return eq_diff
5757
end
5858

59-
function eq_derivative!(ts::TearingState{ODESystem}, ieq::Int)
59+
function eq_derivative!(ts::TearingState{ODESystem}, ieq::Int; kwargs...)
6060
s = ts.structure
6161

6262
eq_diff = eq_derivative_graph!(s, ieq)
@@ -75,7 +75,8 @@ function eq_derivative!(ts::TearingState{ODESystem}, ieq::Int)
7575
add_edge!(s.graph, eq_diff, s.var_to_diff[var])
7676
end
7777
s.solvable_graph === nothing ||
78-
find_eq_solvables!(ts, eq_diff; may_be_zero = true, allow_symbolic = false)
78+
find_eq_solvables!(
79+
ts, eq_diff; may_be_zero = true, allow_symbolic = false, kwargs...)
7980

8081
return eq_diff
8182
end

src/structural_transformation/utils.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,9 @@ end
181181

182182
function find_eq_solvables!(state::TearingState, ieq, to_rm = Int[], coeffs = nothing;
183183
may_be_zero = false,
184-
allow_symbolic = false, allow_parameter = true, kwargs...)
184+
allow_symbolic = false, allow_parameter = true,
185+
conservative = false,
186+
kwargs...)
185187
fullvars = state.fullvars
186188
@unpack graph, solvable_graph = state.structure
187189
eq = equations(state)[ieq]
@@ -220,6 +222,7 @@ function find_eq_solvables!(state::TearingState, ieq, to_rm = Int[], coeffs = no
220222
coeffs === nothing || push!(coeffs, convert(Int, a))
221223
else
222224
all_int_vars = false
225+
conservative && continue
223226
end
224227
if a != 0
225228
add_edge!(solvable_graph, ieq, j)

src/systems/systems.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ $(SIGNATURES)
99
Structurally simplify algebraic equations in a system and compute the
1010
topological sort of the observed equations. When `simplify=true`, the `simplify`
1111
function will be applied during the tearing process. It also takes kwargs
12-
`allow_symbolic=false` and `allow_parameter=true` which limits the coefficient
13-
types during tearing.
12+
`allow_symbolic=false`, `allow_parameter=true`, and `conservative=false` which
13+
limits the coefficient types during tearing. In particular, `conservative=true`
14+
limits tearing to only solve for trivial linear systems where the coefficient
15+
has the absolute value of ``1``.
1416
1517
The optional argument `io` may take a tuple `(inputs, outputs)`.
1618
This will convert all `inputs` to parameters and allow them to be unconnected, i.e.,

src/systems/systemstructure.jl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -691,15 +691,18 @@ function _structural_simplify!(state::TearingState, io; simplify = false,
691691
ModelingToolkit.check_consistency(state, orig_inputs)
692692
end
693693
if fully_determined && dummy_derivative
694-
sys = ModelingToolkit.dummy_derivative(sys, state; simplify, mm, check_consistency)
694+
sys = ModelingToolkit.dummy_derivative(
695+
sys, state; simplify, mm, check_consistency, kwargs...)
695696
elseif fully_determined
696697
var_eq_matching = pantelides!(state; finalize = false, kwargs...)
697698
sys = pantelides_reassemble(state, var_eq_matching)
698699
state = TearingState(sys)
699700
sys, mm = ModelingToolkit.alias_elimination!(state; kwargs...)
700-
sys = ModelingToolkit.dummy_derivative(sys, state; simplify, mm, check_consistency)
701+
sys = ModelingToolkit.dummy_derivative(
702+
sys, state; simplify, mm, check_consistency, kwargs...)
701703
else
702-
sys = ModelingToolkit.tearing(sys, state; simplify, mm, check_consistency)
704+
sys = ModelingToolkit.tearing(
705+
sys, state; simplify, mm, check_consistency, kwargs...)
703706
end
704707
fullunknowns = [map(eq -> eq.lhs, observed(sys)); unknowns(sys)]
705708
@set! sys.observed = ModelingToolkit.topsort_equations(observed(sys), fullunknowns)

0 commit comments

Comments
 (0)