Skip to content

refactor: allow new clocks to be defined in downstream packages #995

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 45 additions & 4 deletions src/clock.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
@data Clocks begin
abstract type AbstractClock end

@data Clocks<:AbstractClock begin
ContinuousClock
struct PeriodicClock
dt::Union{Nothing, Float64, Rational{Int}}
Expand Down Expand Up @@ -63,6 +65,7 @@ issolverstepclock(::Any) = false
iscontinuous(::Any) = false
is_discrete_time_domain(::Any) = false

# public
function first_clock_tick_time(c, t0)
@match c begin
PeriodicClock(dt) => ceil(t0 / dt) * dt
Expand All @@ -71,13 +74,51 @@ function first_clock_tick_time(c, t0)
end
end

struct IndexedClock{I}
clock::TimeDomain
# public
"""
$(TYPEDEF)

A struct representing the operation of indexing a clock to obtain a subset of the time
points at which it ticked. The actual list of time points depends on the tick instances
on which the clock was ticking, and can be obtained via `canonicalize_indexed_clock`
by providing a timeseries solution object.

For example, `IndexedClock(PeriodicClock(0.1), 3)` refers to the third time that
`PeriodicClock(0.1)` ticked. If the simulation started at `t = 0`, then this would be
`t = 0.2`. Similarly, `IndexedClock(PeriodicClock(0.1), [1, 5])` refers to `t = 0.0`
and `t = 0.4` in this context.

# Fields

$(TYPEDFIELDS)
"""
struct IndexedClock{C <: AbstractClock, I}
"""
The clock being indexed. A subtype of `SciMLBase.AbstractClock`
"""
clock::C
"""
The subset of indexes being referred to. This can be an integer, an array of integers,
a range or `Colon()` to refer to all the points that the clock ticked.
"""
idx::I
end

Base.getindex(c::TimeDomain, idx) = IndexedClock(c, idx)
# public
"""
$(TYPEDSIGNATURES)

Return a `SciMLBase.IndexedClock` representing the subset of the time points that the clock
ticked indicated by `idx`.
"""
Base.getindex(c::AbstractClock, idx) = IndexedClock(c, idx)

# public
"""
$(TYPEDSIGNATURES)

Return the time points in the interval
"""
function canonicalize_indexed_clock(ic::IndexedClock, sol::AbstractTimeseriesSolution)
c = ic.clock

Expand Down
Loading