-
Notifications
You must be signed in to change notification settings - Fork 24
/
clock.jl
68 lines (57 loc) · 2.06 KB
/
clock.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
const DEFAULT_DATE = DateTime(2000, 1, 1)
"""
Clock struct keeps track of the model time, how many days to integrate for
and how many time steps this takes
$(TYPEDFIELDS)."""
Base.@kwdef mutable struct Clock
"current model time"
time::DateTime = DEFAULT_DATE
"start time of simulation"
start::DateTime = DEFAULT_DATE
"period to integrate for, set in set_period!(::Clock, ::Dates.Period)"
period::Second = Second(0)
"Counting all time steps during simulation"
timestep_counter::Int = 0
"number of time steps to integrate for, set in initialize!(::Clock, ::AbstractTimeStepper)"
n_timesteps::Int = 0
end
function timestep!(clock::Clock, Δt; increase_counter::Bool=true)
clock.time += Δt
# the first timestep is a half-step and doesn't count
clock.timestep_counter += increase_counter
end
# pretty printing
function Base.show(io::IO, C::Clock)
println(io, "$(typeof(C))")
keys = propertynames(C)
print_fields(io, C, keys)
end
"""
$(TYPEDSIGNATURES)
Initialize the clock with the time step `Δt` in the `time_stepping`."""
function initialize!(clock::Clock, time_stepping::AbstractTimeStepper)
clock.n_timesteps = ceil(Int, clock.period.value/time_stepping.Δt_sec)
clock.start = clock.time # store the start time
clock.timestep_counter = 0 # reset counter
return clock
end
"""
$(TYPEDSIGNATURES)
Set the `period` of the clock to a new value. Converts any `Dates.Period` input to `Second`."""
function set_period!(clock::Clock, period::Period)
clock.period = Second(period)
end
"""
$(TYPEDSIGNATURES)
Set the `period` of the clock to a new value. Converts any `::Real` input to `Day`."""
function set_period!(clock::Clock, period::Real)
@info "Input $period assumed to have units of days. Use Week($period), Hour($period), Minute($period) otherwise."
clock.period = Day(period)
end
"""
$(TYPEDSIGNATURES)
Create and initialize a clock from `time_stepping`"""
function Clock(time_stepping::AbstractTimeStepper; kwargs...)
clock = Clock(; kwargs...)
initialize!(clock, time_stepping)
end