From e243e5b44ea0c4570ae427bdce1d68dc29594f24 Mon Sep 17 00:00:00 2001 From: Jago Strong-Wright Date: Thu, 21 Mar 2024 08:59:53 -0400 Subject: [PATCH] =?UTF-8?q?Adds=20`last=5F=CE=94t`=20to=20`Clock`=20(#3508?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * added `Δt` to `Clock` * fixed clock to work for DateTime * changed name to `last_Δt` * fixed Clock adapt * updated docstring * Update src/TimeSteppers/clock.jl Co-authored-by: Gregory L. Wagner * fixed constructor * updated `reset!` * fixed formatting * Apply suggestions from code review Co-authored-by: Gregory L. Wagner * Update src/TimeSteppers/clock.jl Co-authored-by: Navid C. Constantinou * increase size_threshold=1MiB * fix doctest * fix doctest * Update pipeline.yml * fix size_threshold --------- Co-authored-by: Gregory L. Wagner Co-authored-by: Navid C. Constantinou --- .buildkite/distributed/pipeline.yml | 2 +- docs/make.jl | 2 +- docs/src/model_setup/background_fields.md | 4 +-- docs/src/model_setup/clock.md | 6 ++-- .../hydrostatic_free_surface_model.jl | 4 +-- .../nonhydrostatic_model.jl | 4 +-- .../ShallowWaterModels/shallow_water_model.jl | 4 +-- src/Simulations/simulation.jl | 3 +- src/TimeSteppers/clock.jl | 35 +++++++++++++------ 9 files changed, 39 insertions(+), 25 deletions(-) diff --git a/.buildkite/distributed/pipeline.yml b/.buildkite/distributed/pipeline.yml index bc6dd5c456..2d2b59eea0 100644 --- a/.buildkite/distributed/pipeline.yml +++ b/.buildkite/distributed/pipeline.yml @@ -1,7 +1,7 @@ agents: queue: new-central slurm_mem: 8G - modules: climacommon/2024_02_27 + modules: climacommon/2024_03_18 env: diff --git a/docs/make.jl b/docs/make.jl index 568ffe94ec..452b1a226f 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -174,7 +174,7 @@ format = Documenter.HTML(collapselevel = 1, prettyurls = get(ENV, "CI", nothing) == "true", canonical = "https://clima.github.io/OceananigansDocumentation/stable/", mathengine = MathJax3(), - size_threshold = 819200, + size_threshold = 2^20, assets = String["assets/citations.css"]) makedocs(sitename = "Oceananigans.jl", diff --git a/docs/src/model_setup/background_fields.md b/docs/src/model_setup/background_fields.md index 44bec466e3..fd4a526866 100644 --- a/docs/src/model_setup/background_fields.md +++ b/docs/src/model_setup/background_fields.md @@ -56,7 +56,7 @@ model.background_fields.velocities.u FunctionField located at (Face, Center, Center) ├── func: U (generic function with 1 method) ├── grid: 1×1×1 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 3×3×3 halo -├── clock: Clock(time=0 seconds, iteration=0) +├── clock: Clock(time=0 seconds, iteration=0, last_Δt=Inf days) └── parameters: nothing ``` @@ -99,6 +99,6 @@ model.background_fields.tracers.b FunctionField located at (Center, Center, Center) ├── func: B (generic function with 1 method) ├── grid: 1×1×1 RectilinearGrid{Float64, Periodic, Periodic, Bounded} on CPU with 3×3×3 halo -├── clock: Clock(time=0 seconds, iteration=0) +├── clock: Clock(time=0 seconds, iteration=0, last_Δt=Inf days) └── parameters: (α = 3.14, N = 1.0, f = 0.1) ``` diff --git a/docs/src/model_setup/clock.md b/docs/src/model_setup/clock.md index 50128ff0bb..c2d2a2eb2b 100644 --- a/docs/src/model_setup/clock.md +++ b/docs/src/model_setup/clock.md @@ -14,7 +14,7 @@ end ```jldoctest julia> clock = Clock(time=0.0) -Clock{Float64}: time = 0 seconds, iteration = 0, stage = 1 +Clock{Float64, Float64}: time = 0 seconds, last_Δt = Inf days, iteration = 0, stage = 1 ``` but can be modified to start the model clock at some other time. @@ -22,7 +22,7 @@ For example, passing ```jldoctest julia> clock = Clock(time=3600.0) -Clock{Float64}: time = 1 hour, iteration = 0, stage = 1 +Clock{Float64, Float64}: time = 1 hour, last_Δt = Inf days, iteration = 0, stage = 1 ``` to the constructor for `NonhydrostaticModel` causes the simulation @@ -37,7 +37,7 @@ for example, pass julia> using TimesDates julia> clock = Clock(time=TimeDate(2020)) -Clock{TimesDates.TimeDate}: time = 2020-01-01T00:00:00, iteration = 0, stage = 1 +Clock{TimesDates.TimeDate, Float64}: time = 2020-01-01T00:00:00, last_Δt = Inf days, iteration = 0, stage = 1 ``` to `NonhydrostaticModel`. `TimesDates.TimeDate` supports nanosecond resolution and is thus recommended diff --git a/src/Models/HydrostaticFreeSurfaceModels/hydrostatic_free_surface_model.jl b/src/Models/HydrostaticFreeSurfaceModels/hydrostatic_free_surface_model.jl index e090d20ea4..02928201c3 100644 --- a/src/Models/HydrostaticFreeSurfaceModels/hydrostatic_free_surface_model.jl +++ b/src/Models/HydrostaticFreeSurfaceModels/hydrostatic_free_surface_model.jl @@ -55,7 +55,7 @@ default_free_surface(grid; gravitational_acceleration=g_Earth) = """ HydrostaticFreeSurfaceModel(; grid, - clock = Clock{eltype(grid)}(0, 0, 1), + clock = Clock{eltype(grid)}(time = 0), momentum_advection = CenteredSecondOrder(), tracer_advection = CenteredSecondOrder(), buoyancy = SeawaterBuoyancy(eltype(grid)), @@ -103,7 +103,7 @@ Keyword arguments - `auxiliary_fields`: `NamedTuple` of auxiliary fields. Default: `nothing`. """ function HydrostaticFreeSurfaceModel(; grid, - clock = Clock{eltype(grid)}(0, 0, 1), + clock = Clock{eltype(grid)}(time = 0), momentum_advection = CenteredSecondOrder(), tracer_advection = CenteredSecondOrder(), buoyancy = SeawaterBuoyancy(eltype(grid)), diff --git a/src/Models/NonhydrostaticModels/nonhydrostatic_model.jl b/src/Models/NonhydrostaticModels/nonhydrostatic_model.jl index a5ea3e5197..07e0141c1d 100644 --- a/src/Models/NonhydrostaticModels/nonhydrostatic_model.jl +++ b/src/Models/NonhydrostaticModels/nonhydrostatic_model.jl @@ -52,7 +52,7 @@ end """ NonhydrostaticModel(; grid, - clock = Clock{eltype(grid)}(0, 0, 1), + clock = Clock{eltype(grid)}(time = 0), advection = CenteredSecondOrder(), buoyancy = nothing, coriolis = nothing, @@ -105,7 +105,7 @@ Keyword arguments - `auxiliary_fields`: `NamedTuple` of auxiliary fields. Default: `nothing` """ function NonhydrostaticModel(; grid, - clock = Clock{eltype(grid)}(0, 0, 1), + clock = Clock{eltype(grid)}(time = 0), advection = CenteredSecondOrder(), buoyancy = nothing, coriolis = nothing, diff --git a/src/Models/ShallowWaterModels/shallow_water_model.jl b/src/Models/ShallowWaterModels/shallow_water_model.jl index d18e8eb086..bd46367ba9 100644 --- a/src/Models/ShallowWaterModels/shallow_water_model.jl +++ b/src/Models/ShallowWaterModels/shallow_water_model.jl @@ -61,7 +61,7 @@ struct VectorInvariantFormulation end """ ShallowWaterModel(; grid, gravitational_acceleration, - clock = Clock{eltype(grid)}(0, 0, 1), + clock = Clock{eltype(grid)}(time = 0), momentum_advection = UpwindBiasedFifthOrder(), tracer_advection = WENO(), mass_advection = WENO(), @@ -112,7 +112,7 @@ Keyword arguments function ShallowWaterModel(; grid, gravitational_acceleration, - clock = Clock{eltype(grid)}(0, 0, 1), + clock = Clock{eltype(grid), eltype(grid)}(0, Inf, 0, 1), momentum_advection = UpwindBiasedFifthOrder(), tracer_advection = WENO(), mass_advection = WENO(), diff --git a/src/Simulations/simulation.jl b/src/Simulations/simulation.jl index 22ccb2ae3d..fc90daf99b 100644 --- a/src/Simulations/simulation.jl +++ b/src/Simulations/simulation.jl @@ -161,7 +161,8 @@ run_wall_time(sim::Simulation) = prettytime(sim.run_wall_time) Reset `sim`ulation, `model.clock`, and `model.timestepper` to their initial state. """ function reset!(sim::Simulation) - sim.model.clock.time = 0.0 + sim.model.clock.time = 0 + sim.model.clock.last_Δt = Inf sim.model.clock.iteration = 0 sim.model.clock.stage = 1 sim.stop_iteration = Inf diff --git a/src/TimeSteppers/clock.jl b/src/TimeSteppers/clock.jl index 24b219a603..b1b8da173b 100644 --- a/src/TimeSteppers/clock.jl +++ b/src/TimeSteppers/clock.jl @@ -6,30 +6,39 @@ import Base: show import Oceananigans.Units: Time """ - mutable struct Clock{T<:Number} + mutable struct Clock{T, FT} -Keeps track of the current `time`, `iteration` number, and time-stepping `stage`. +Keeps track of the current `time`, `last_Δt`, `iteration` number, and time-stepping `stage`. The `stage` is updated only for multi-stage time-stepping methods. The `time::T` is either a number or a `DateTime` object. """ -mutable struct Clock{T} - time :: T +mutable struct Clock{TT, DT} + time :: TT + last_Δt :: DT iteration :: Int stage :: Int end """ - Clock(; time, iteration=0, stage=1) + Clock(; time, last_Δt = Inf, iteration=0, stage=1) Returns a `Clock` object. By default, `Clock` is initialized to the zeroth `iteration` -and first time step `stage`. +and first time step `stage` with `last_Δt`. """ -Clock(; time::T, iteration=0, stage=1) where T = Clock{T}(time, iteration, stage) +Clock(; time::TT, last_Δt::DT=Inf, iteration=0, stage=1) where {TT, DT} = Clock{TT, DT}(time, last_Δt, iteration, stage) +# TODO: when supporting DateTime, this function will have to be extended +time_step_type(TT) = TT + +function Clock{TT}(; time, last_Δt=Inf, iteration=0, stage=1) where TT + DT = time_step_type(TT) + last_Δt = convert(DT, last_Δt) + return Clock{TT, DT}(time, last_Δt, iteration, stage) +end -Base.summary(clock::Clock) = string("Clock(time=$(prettytime(clock.time)), iteration=$(clock.iteration))") +Base.summary(clock::Clock) = string("Clock(time=$(prettytime(clock.time)), iteration=$(clock.iteration), last_Δt=$(prettytime(clock.last_Δt)))") -Base.show(io::IO, c::Clock{T}) where T = - println(io, "Clock{$T}: time = $(prettytime(c.time)), iteration = $(c.iteration), stage = $(c.stage)") +Base.show(io::IO, c::Clock{TT, DT}) where {TT, DT} = + println(io, "Clock{$TT, $DT}: time = $(prettytime(c.time)), last_Δt = $(prettytime(c.last_Δt)), iteration = $(c.iteration), stage = $(c.stage)") next_time(clock, Δt) = clock.time + Δt next_time(clock::Clock{<:AbstractTime}, Δt) = clock.time + Nanosecond(round(Int, 1e9 * Δt)) @@ -52,6 +61,8 @@ function tick!(clock, Δt; stage=false) tick_time!(clock, Δt) + clock.last_Δt = Δt + if stage # tick a stage update clock.stage += 1 else # tick an iteration and reset stage @@ -63,4 +74,6 @@ function tick!(clock, Δt; stage=false) end "Adapt `Clock` to work on the GPU via CUDAnative and CUDAdrv." -Adapt.adapt_structure(to, clock::Clock) = (time=clock.time, iteration=clock.iteration, stage=clock.stage) +Adapt.adapt_structure(to, clock::Clock) = + (time=clock.time, last_Δt=clock.last_Δt, iteration=clock.iteration, stage=clock.stage) +