Skip to content

Commit ea02561

Browse files
Add symbolic tspan field to System struct
This commit addresses issue #847 by adding a symbolic time span (tspan) field to the System struct for time-dependent systems. The tspan field allows users to specify the time interval for simulations directly in the system definition, which can be either numeric values or symbolic expressions involving parameters. Changes: - Added tspan field to System struct with type Union{Nothing, Tuple{Any, Any}} - Updated System constructors to accept tspan parameter with default value nothing - Added documentation for the new tspan field - Added comprehensive tests for tspan functionality including numeric, symbolic, and nil cases - Tests verify that tspan is preserved through system completion The tspan field is automatically accessible via get_tspan() and has_tspan() getter methods through the existing SYS_PROPS metaprogramming framework. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent b0907ec commit ea02561

File tree

2 files changed

+37
-4
lines changed

2 files changed

+37
-4
lines changed

src/systems/system.jl

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,11 @@ struct System <: IntermediateDeprecationSystem
190190
"""
191191
tstops::Vector{Any}
192192
"""
193+
The time span for time-dependent systems. This is a tuple of the start and end
194+
time for the system, which can be symbolic expressions involving parameters.
195+
"""
196+
tspan::Union{Nothing, Tuple{Any, Any}}
197+
"""
193198
The `TearingState` of the system post-simplification with `mtkcompile`.
194199
"""
195200
tearing_state::Any
@@ -256,7 +261,7 @@ struct System <: IntermediateDeprecationSystem
256261
defaults, guesses, systems, initialization_eqs, continuous_events, discrete_events,
257262
connector_type, assertions = Dict{BasicSymbolic, String}(),
258263
metadata = MetadataT(), gui_metadata = nothing,
259-
is_dde = false, tstops = [], tearing_state = nothing, namespacing = true,
264+
is_dde = false, tstops = [], tspan = nothing, tearing_state = nothing, namespacing = true,
260265
complete = false, index_cache = nothing, ignored_connections = nothing,
261266
preface = nothing, parent = nothing, initializesystem = nothing,
262267
is_initializesystem = false, is_discrete = false, isscheduled = false,
@@ -296,7 +301,7 @@ struct System <: IntermediateDeprecationSystem
296301
observed, parameter_dependencies, var_to_name, name, description, defaults,
297302
guesses, systems, initialization_eqs, continuous_events, discrete_events,
298303
connector_type, assertions, metadata, gui_metadata, is_dde,
299-
tstops, tearing_state, namespacing, complete, index_cache, ignored_connections,
304+
tstops, tspan, tearing_state, namespacing, complete, index_cache, ignored_connections,
300305
preface, parent, initializesystem, is_initializesystem, is_discrete,
301306
isscheduled, schedule)
302307
end
@@ -332,7 +337,7 @@ function System(eqs::Vector{Equation}, iv, dvs, ps, brownians = [];
332337
continuous_events = SymbolicContinuousCallback[], discrete_events = SymbolicDiscreteCallback[],
333338
connector_type = nothing, assertions = Dict{BasicSymbolic, String}(),
334339
metadata = MetadataT(), gui_metadata = nothing,
335-
is_dde = nothing, tstops = [], tearing_state = nothing,
340+
is_dde = nothing, tstops = [], tspan = nothing, tearing_state = nothing,
336341
ignored_connections = nothing, parent = nothing,
337342
description = "", name = nothing, discover_from_metadata = true,
338343
initializesystem = nothing, is_initializesystem = false, is_discrete = false,
@@ -417,7 +422,7 @@ function System(eqs::Vector{Equation}, iv, dvs, ps, brownians = [];
417422
costs, consolidate, dvs, ps, brownians, iv, observed, Equation[],
418423
var_to_name, name, description, defaults, guesses, systems, initialization_eqs,
419424
continuous_events, discrete_events, connector_type, assertions, metadata, gui_metadata, is_dde,
420-
tstops, tearing_state, true, false, nothing, ignored_connections, preface, parent,
425+
tstops, tspan, tearing_state, true, false, nothing, ignored_connections, preface, parent,
421426
initializesystem, is_initializesystem, is_discrete; checks)
422427
end
423428

test/odesystem.jl

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,3 +1614,31 @@ end
16141614
@test_nowarn push!(arr, sys)
16151615
@test_nowarn TestWrapper(sys)
16161616
end
1617+
1618+
@testset "Symbolic tspan" begin
1619+
@variables x(t) y(t)
1620+
@parameters σ ρ β
1621+
1622+
# Test creating a system with tspan
1623+
eqs = [D(x) ~ σ * (y - x),
1624+
D(y) ~ x *- x) - y]
1625+
1626+
# Test with numeric tspan
1627+
@named sys1 = System(eqs, t, [x, y], [σ, ρ, β]; tspan = (0.0, 10.0))
1628+
@test ModelingToolkit.get_tspan(sys1) == (0.0, 10.0)
1629+
@test ModelingToolkit.has_tspan(sys1) == true
1630+
1631+
# Test with symbolic tspan
1632+
@parameters t0 tf
1633+
@named sys2 = System(eqs, t, [x, y], [σ, ρ, β]; tspan = (t0, tf))
1634+
@test isequal(ModelingToolkit.get_tspan(sys2), (t0, tf))
1635+
1636+
# Test without tspan
1637+
@named sys3 = System(eqs, t, [x, y], [σ, ρ, β])
1638+
@test ModelingToolkit.get_tspan(sys3) === nothing
1639+
@test ModelingToolkit.has_tspan(sys3) == true # Field exists but is nothing
1640+
1641+
# Test that tspan is preserved through system completion
1642+
sys1_complete = complete(sys1)
1643+
@test ModelingToolkit.get_tspan(sys1_complete) == (0.0, 10.0)
1644+
end

0 commit comments

Comments
 (0)