Skip to content

Commit ea15f34

Browse files
committed
Add option to eliminate constants during structural_simplify.
1 parent 25436f8 commit ea15f34

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

src/systems/abstractsystem.jl

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -952,16 +952,20 @@ $(SIGNATURES)
952952
953953
Structurally simplify algebraic equations in a system and compute the
954954
topological sort of the observed equations. When `simplify=true`, the `simplify`
955-
function will be applied during the tearing process. It also takes kwargs
955+
function will be applied during the tearing process. When `simplify_constants=true`
956+
`eliminate_constants` will be applied prior to tearing. It also takes kwargs
956957
`allow_symbolic=false` and `allow_parameter=true` which limits the coefficient
957958
types during tearing.
958959
959960
The optional argument `io` may take a tuple `(inputs, outputs)`.
960961
This will convert all `inputs` to parameters and allow them to be unconnected, i.e.,
961962
simplification will allow models where `n_states = n_equations - n_inputs`.
962963
"""
963-
function structural_simplify(sys::AbstractSystem, io = nothing; simplify = false, kwargs...)
964+
function structural_simplify(sys::AbstractSystem, io = nothing; simplify = false, simplify_constants = true, kwargs...)
964965
sys = expand_connections(sys)
966+
if simplify_constants
967+
sys = eliminate_constants(sys)
968+
end
965969
state = TearingState(sys)
966970
has_io = io !== nothing
967971
has_io && markio!(state, io...)
@@ -979,6 +983,20 @@ function structural_simplify(sys::AbstractSystem, io = nothing; simplify = false
979983
return has_io ? (sys, input_idxs) : sys
980984
end
981985

986+
987+
""" Replace constants in dynamical equations with their literal values."""
988+
function eliminate_constants(sys::AbstractSystem)
989+
if has_eqs(sys)
990+
eqs = get_eqs(sys)
991+
eq_cs = collect_constants(eqs)
992+
if !isempty(eq_cs)
993+
new_eqs = eliminate_constants(eqs, eq_cs)
994+
@set! sys.eqs = new_eqs
995+
end
996+
end
997+
return sys
998+
end
999+
9821000
function io_preprocessing(sys::AbstractSystem, inputs,
9831001
outputs; simplify = false, kwargs...)
9841002
sys, input_idxs = structural_simplify(sys, (inputs, outputs); simplify, kwargs...)

test/constants.jl

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,22 @@ eqs = [D(x) ~ a]
1212
prob = ODEProblem(sys, [0], [0.0, 1.0], [])
1313
sol = solve(prob, Tsit5())
1414

15+
newsys = eliminate_constants(sys)
16+
@test isequal(equations(newsys), [D(x) ~ 1])
17+
1518
# Test structural_simplify substitutions & observed values
1619
eqs = [D(x) ~ 1,
1720
w ~ a]
1821
@named sys = ODESystem(eqs)
19-
simp = structural_simplify(sys);
22+
simp = structural_simplify(sys, simplify_constants = false);
2023
@test isequal(simp.substitutions.subs[1], eqs[2])
2124
@test isequal(equations(simp)[1], eqs[1])
2225
prob = ODEProblem(simp, [0], [0.0, 1.0], [])
2326
sol = solve(prob, Tsit5())
2427
@test sol[w][1] == 1
28+
# Now eliminate the constants first
29+
simp = structural_simplify(sys, simplify_constants = true);
30+
@test isequal(simp.substitutions.subs[1], w ~ 1)
2531

2632
#Constant with units
2733
@constants β=1 [unit = u"m/s"]
@@ -31,3 +37,8 @@ MT.get_unit(β)
3137
D = Differential(t)
3238
eqs = [D(x) ~ β]
3339
sys = ODESystem(eqs, name = :sys)
40+
# Note that the equation won't unit-check now
41+
# b/c the literal value doesn't have units on it
42+
# Testing that units checking is bypassed in the constructors
43+
simp = structural_simplify(sys)
44+
@test_throws MT.ValidationError MT.check_units(simp.eqs...)

0 commit comments

Comments
 (0)