Skip to content

Commit 49b5c3f

Browse files
committed
Throw an error if structural simplification is applied twice
1 parent e9617e5 commit 49b5c3f

File tree

10 files changed

+47
-13
lines changed

10 files changed

+47
-13
lines changed

src/structural_transformation/StructuralTransformations.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ using ModelingToolkit: ODESystem, AbstractSystem, var_from_nested_derivative, Di
2424
invalidate_cache!, Substitutions, get_or_construct_tearing_state,
2525
filter_kwargs, lower_varname, setio, SparseMatrixCLIL,
2626
get_fullvars, has_equations, observed,
27-
Schedule
27+
Schedule, schedule
2828

2929
using ModelingToolkit.BipartiteGraphs
3030
import .BipartiteGraphs: invview, complete

src/structural_transformation/symbolics_tearing.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,7 @@ function tearing_reassemble(state::TearingState, var_eq_matching,
615615
if sys isa ODESystem
616616
@set! sys.schedule = Schedule(var_eq_matching, dummy_sub)
617617
end
618+
sys = schedule(sys)
618619
@set! state.sys = sys
619620
@set! sys.tearing_state = state
620621
return invalidate_cache!(sys)

src/systems/abstractsystem.jl

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,19 @@ end
846846

847847
iscomplete(sys::AbstractSystem) = isdefined(sys, :complete) && getfield(sys, :complete)
848848

849+
function schedule(sys::AbstractSystem)
850+
has_schedule(sys) ? sys : (@set! sys.isscheduled = true)
851+
end
852+
function isscheduled(sys::AbstractSystem)
853+
if has_schedule(sys)
854+
get_schedule(sys) !== nothing
855+
elseif has_isscheduled(sys)
856+
get_isscheduled(sys)
857+
else
858+
false
859+
end
860+
end
861+
849862
"""
850863
$(TYPEDSIGNATURES)
851864
@@ -907,7 +920,8 @@ for prop in [:eqs
907920
:split_idxs
908921
:parent
909922
:index_cache
910-
:is_scalar_noise]
923+
:is_scalar_noise
924+
:isscheduled]
911925
fname_get = Symbol(:get_, prop)
912926
fname_has = Symbol(:has_, prop)
913927
@eval begin

src/systems/diffeqs/sdesystem.jl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,13 +133,15 @@ struct SDESystem <: AbstractODESystem
133133
be `true` when `noiseeqs isa Vector`.
134134
"""
135135
is_scalar_noise::Bool
136+
isscheduled::Bool
136137

137138
function SDESystem(tag, deqs, neqs, iv, dvs, ps, tspan, var_to_name, ctrls, observed,
138139
tgrad,
139140
jac,
140141
ctrl_jac, Wfact, Wfact_t, name, systems, defaults, connector_type,
141142
cevents, devents, parameter_dependencies, metadata = nothing, gui_metadata = nothing,
142-
complete = false, index_cache = nothing, parent = nothing, is_scalar_noise = false;
143+
complete = false, index_cache = nothing, parent = nothing, is_scalar_noise = false,
144+
isscheduled = false;
143145
checks::Union{Bool, Int} = true)
144146
if checks == true || (checks & CheckComponents) > 0
145147
check_independent_variables([iv])
@@ -162,7 +164,8 @@ struct SDESystem <: AbstractODESystem
162164
new(tag, deqs, neqs, iv, dvs, ps, tspan, var_to_name, ctrls, observed, tgrad, jac,
163165
ctrl_jac,
164166
Wfact, Wfact_t, name, systems, defaults, connector_type, cevents, devents,
165-
parameter_dependencies, metadata, gui_metadata, complete, index_cache, parent, is_scalar_noise)
167+
parameter_dependencies, metadata, gui_metadata, complete, index_cache, parent, is_scalar_noise,
168+
isscheduled)
166169
end
167170
end
168171

src/systems/discrete_system/discrete_system.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,16 @@ struct DiscreteSystem <: AbstractTimeDependentSystem
9191
The hierarchical parent system before simplification.
9292
"""
9393
parent::Any
94+
isscheduled::Bool
9495

9596
function DiscreteSystem(tag, discreteEqs, iv, dvs, ps, tspan, var_to_name,
9697
observed,
9798
name,
9899
systems, defaults, preface, connector_type, parameter_dependencies = Equation[],
99100
metadata = nothing, gui_metadata = nothing,
100101
tearing_state = nothing, substitutions = nothing,
101-
complete = false, index_cache = nothing, parent = nothing;
102+
complete = false, index_cache = nothing, parent = nothing,
103+
isscheduled = false;
102104
checks::Union{Bool, Int} = true)
103105
if checks == true || (checks & CheckComponents) > 0
104106
check_independent_variables([iv])
@@ -113,7 +115,7 @@ struct DiscreteSystem <: AbstractTimeDependentSystem
113115
systems,
114116
defaults,
115117
preface, connector_type, parameter_dependencies, metadata, gui_metadata,
116-
tearing_state, substitutions, complete, index_cache, parent)
118+
tearing_state, substitutions, complete, index_cache, parent, isscheduled)
117119
end
118120
end
119121

src/systems/jumps/jumpsystem.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,13 @@ struct JumpSystem{U <: ArrayPartition} <: AbstractTimeDependentSystem
114114
Cached data for fast symbolic indexing.
115115
"""
116116
index_cache::Union{Nothing, IndexCache}
117+
isscheduled::Bool
117118

118119
function JumpSystem{U}(tag, ap::U, iv, unknowns, ps, var_to_name, observed, name,
119120
systems,
120121
defaults, connector_type, devents, parameter_dependencies,
121122
metadata = nothing, gui_metadata = nothing,
122-
complete = false, index_cache = nothing;
123+
complete = false, index_cache = nothing, isscheduled = false;
123124
checks::Union{Bool, Int} = true) where {U <: ArrayPartition}
124125
if checks == true || (checks & CheckComponents) > 0
125126
check_independent_variables([iv])
@@ -132,7 +133,7 @@ struct JumpSystem{U <: ArrayPartition} <: AbstractTimeDependentSystem
132133
end
133134
new{U}(tag, ap, iv, unknowns, ps, var_to_name, observed, name, systems, defaults,
134135
connector_type, devents, parameter_dependencies, metadata, gui_metadata,
135-
complete, index_cache)
136+
complete, index_cache, isscheduled)
136137
end
137138
end
138139
function JumpSystem(tag, ap, iv, states, ps, var_to_name, args...; kwargs...)

src/systems/nonlinear/nonlinearsystem.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,21 +89,22 @@ struct NonlinearSystem <: AbstractTimeIndependentSystem
8989
The hierarchical parent system before simplification.
9090
"""
9191
parent::Any
92+
isscheduled::Bool
9293

9394
function NonlinearSystem(tag, eqs, unknowns, ps, var_to_name, observed, jac, name,
9495
systems,
9596
defaults, connector_type, parameter_dependencies = Equation[], metadata = nothing,
9697
gui_metadata = nothing,
9798
tearing_state = nothing, substitutions = nothing,
98-
complete = false, index_cache = nothing, parent = nothing; checks::Union{
99-
Bool, Int} = true)
99+
complete = false, index_cache = nothing, parent = nothing,
100+
isscheduled = false; checks::Union{Bool, Int} = true)
100101
if checks == true || (checks & CheckUnits) > 0
101102
u = __get_unit_type(unknowns, ps)
102103
check_units(u, eqs)
103104
end
104105
new(tag, eqs, unknowns, ps, var_to_name, observed, jac, name, systems, defaults,
105106
connector_type, parameter_dependencies, metadata, gui_metadata, tearing_state,
106-
substitutions, complete, index_cache, parent)
107+
substitutions, complete, index_cache, parent, isscheduled)
107108
end
108109
end
109110

src/systems/optimization/optimizationsystem.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,12 @@ struct OptimizationSystem <: AbstractOptimizationSystem
6464
The hierarchical parent system before simplification.
6565
"""
6666
parent::Any
67+
isscheduled::Bool
6768

6869
function OptimizationSystem(tag, op, unknowns, ps, var_to_name, observed,
6970
constraints, name, systems, defaults, metadata = nothing,
70-
gui_metadata = nothing, complete = false, index_cache = nothing, parent = nothing;
71+
gui_metadata = nothing, complete = false, index_cache = nothing, parent = nothing,
72+
isscheduled = false;
7173
checks::Union{Bool, Int} = true)
7274
if checks == true || (checks & CheckUnits) > 0
7375
u = __get_unit_type(unknowns, ps)
@@ -77,7 +79,7 @@ struct OptimizationSystem <: AbstractOptimizationSystem
7779
end
7880
new(tag, op, unknowns, ps, var_to_name, observed,
7981
constraints, name, systems, defaults, metadata, gui_metadata, complete,
80-
index_cache, parent)
82+
index_cache, parent, isscheduled)
8183
end
8284
end
8385

src/systems/systems.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@ function System(eqs::AbstractVector{<:Equation}, iv, args...; name = nothing,
33
ODESystem(eqs, iv, args...; name, kw..., checks = false)
44
end
55

6+
const REPEATED_SIMPLIFICATION_MESSAGE = "Structural simplification cannot be applied to a completed system. Double simplification is not allowed."
7+
8+
struct RepeatedStructuralSimplificationError <: Exception end
9+
10+
function Base.showerror(io::IO, e::RepeatedStructuralSimplificationError)
11+
print(io, REPEATED_SIMPLIFICATION_MESSAGE)
12+
end
13+
614
"""
715
$(SIGNATURES)
816
@@ -21,6 +29,7 @@ function structural_simplify(
2129
sys::AbstractSystem, io = nothing; simplify = false, split = true,
2230
allow_symbolic = false, allow_parameter = true, conservative = false, fully_determined = true,
2331
kwargs...)
32+
isscheduled(sys) && throw(RepeatedStructuralSimplificationError())
2433
newsys′ = __structural_simplify(sys, io; simplify,
2534
allow_symbolic, allow_parameter, conservative, fully_determined,
2635
kwargs...)

test/components.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ completed_rc_model = complete(rc_model)
4444
@test ModelingToolkit.n_extra_equations(capacitor) == 2
4545
@test length(equations(structural_simplify(rc_model, allow_parameter = false))) == 2
4646
sys = structural_simplify(rc_model)
47+
@test_throws ModelingToolkit.RepeatedStructuralSimplificationError structural_simplify(sys)
4748
@test length(equations(sys)) == 1
4849
check_contract(sys)
4950
@test !isempty(ModelingToolkit.defaults(sys))

0 commit comments

Comments
 (0)