Skip to content

Commit 22fb377

Browse files
Merge pull request #2805 from SciML/myb/conservative
Add `conservative` kwarg in `structural_transformation`
2 parents 0cc954d + 898e592 commit 22fb377

File tree

7 files changed

+30
-11
lines changed

7 files changed

+30
-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)

test/nonlinearsystem.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,3 +274,12 @@ eqs = [u3 ~ u1 + u2, u4 ~ 2 * (u1 + u2), u3 + u4 ~ 3 * (u1 + u2)]
274274
@named ns = NonlinearSystem(eqs, [u1, u2], [u3, u4])
275275
sys = structural_simplify(ns; fully_determined = false)
276276
@test length(unknowns(sys)) == 1
277+
278+
# Conservative
279+
@variables X(t)
280+
alg_eqs = [1 ~ 2X]
281+
@named ns = NonlinearSystem(alg_eqs)
282+
sys = structural_simplify(ns)
283+
@test length(equations(sys)) == 0
284+
sys = structural_simplify(ns; conservative = true)
285+
@test length(equations(sys)) == 1

0 commit comments

Comments
 (0)