Clock
Causal is a clocked simulation environment. That is, model components are evolved in different time intervals, called the sampling interval. During the simulation, model components are triggered by these generated time pulses. A Clock instance is used to to generate those time pulses. The simulation time settings–the simulation start time, stop time, sampling interval–are configured through the Clock.
Construction of Clock
Construction of Clock is done by specifying its start time and final time and the simulation sampling period.
julia> using Causal # hide
julia> Clock(0., 1, 10.)
Clock(gen:0.0:1.0:10.0, paused:false)
julia> Clock{Int}(1, 1, 10)
ERROR: MethodError: no method matching Clock{Int64,CB} where CB(::Int64, ::Int64, ::Int64)Basic Usage of Clocks
A Clock has a Callback list so that a Callback can be constructed to trigger specific events configured with the time settings. See the following case study.
Let us consider a Clock with initial time of 0, sampling interval of 1 and final time of 10.
julia> using Causal # hide
julia> clk = Clock(0., 1., 10.)
Clock(gen:0.0:1.0:10.0, paused:false)Notice that clk is not running, since it is not set. Now, let us set it
julia> set!(clk)
ERROR: UndefVarError: set! not definedclk is ready to run, i.e., to be iterated. The following commands generated clock ticks and shows it on the console.
julia> for t in clk
@show t
end
t = 0.0
t = 1.0
t = 2.0
t = 3.0
t = 4.0
t = 5.0
t = 6.0
t = 7.0
t = 8.0
t = 9.0
t = 10.0At this point, clk is out of time. The current time of clk does not advance any more.
julia> take!(clk)
ERROR: MethodError: no method matching take!(::Clock{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Nothing})
Closest candidates are:
take!(!Matched::Distributed.WorkerPool) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.5/Distributed/src/workerpool.jl:136
take!(!Matched::IOStream) at iostream.jl:419
take!(!Matched::Base.GenericIOBuffer{Array{UInt8,1}}) at iobuffer.jl:385
...But, clk can be reset again.
julia> set!(clk, 0., 1., 10.)
ERROR: UndefVarError: set! not definedConsider that we want to configure an alarm. For this, let us consider that when the time of clk is greater than 5 an alarm message is printed on the console. To this end, we need to construct a Callback and add it to the callbacks of clk. (When constructed callback list of clk is empty.)
julia> condition(clk) = clk.t > 5
condition (generic function with 1 method)
julia> action(clk) = println("Clock time = ", clk.t)
action (generic function with 1 method)
julia> clk = Clock(0., 1., 10., callbacks=Callback(condition=condition, action=action))
Clock(gen:0.0:1.0:10.0, paused:false)
julia> set!(clk)
ERROR: UndefVarError: set! not definedNow, let us run clk by iterating it.
julia> for t in clk
@show t
end
ERROR: type Clock has no field tNote that we, constructed a simple callback. It is of course possible to construct more complex callbacks.
Usage of Clocks with ProgressMeter
It also possible to iterate the Clocks by using a progress meter. See ProgressMeter for further information for progress meter.
using Causal
using ProgressMeter
clk = Clock(0., 0.01, 1.)
set!(clk)
@showprogress for t in clk
end Note that clk is just iterated.
Full API
Causal.Clock — Typemutable struct Clock{T, CB}Clock generates time instants to sample the systems. A Clock is an iterable
Fields
generator::AnyInternal generator. Can be any iterable
paused::BoolIf true, clock iteration is halted
callbacks::AnyCallback set. See
Callbackname::SymbolName of clock
uuid::Base.UUIDIdentiy number of clock
Example
julia> clk = Clock(0 : 2)
Clock(gen:0:2, paused:false)
julia> for t in clk
@show t
end
t = 0
t = 1
t = 2Causal.pause! — Methodpause!(clk)
Pauses clk. When paused, the iteration of clock is halted.
Example
julia> clk = Clock(0 : 5)
Clock(gen:0:5, paused:false)
julia> iterate(clk)
(0, 0)
julia> iterate(clk, 1)
(2, 2)
julia> pause!(clk)
Clock(gen:0:5, paused:true)
julia> iterate(clk, 1)
┌ Warning: Clock is paused
└ @ Causal ~/.julia/dev/Causal/src/components/sources/clock.jl:41