Skip to content

Commit

Permalink
Merge pull request #420 from SpeedyWeather/mg/sim-clock-period-kwarg
Browse files Browse the repository at this point in the history
  • Loading branch information
milankl authored Dec 5, 2023
2 parents c11508e + 11ce352 commit 047adec
Show file tree
Hide file tree
Showing 13 changed files with 92 additions and 49 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ With v0.6 the interface to SpeedyWeather.jl consist of 4 steps: define the grid,
spectral_grid = SpectralGrid(trunc=31, Grid=OctahedralGaussianGrid, nlev=8)
model = PrimitiveDryModel(;spectral_grid, orography = EarthOrography(spectral_grid))
simulation = initialize!(model)
run!(simulation,n_days=10,output=true)
run!(simulation,period=Day(10),output=true)
```
and you will see

Expand Down
4 changes: 2 additions & 2 deletions docs/src/how_to_run_speedy.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ just ignore those. But the `Leapfrog` time stepper comes with `Δt_at_T31` which
is the parameter used to scale the time step automatically. This means at a spectral
resolution of T31 it would use 30min steps, at T63 it would be ~half that, 15min, etc.
Meaning that if you want to have a shorter or longer time step you can create a new
`Leapfrog` time stepper. But remember that every model component depends on a
`Leapfrog` time stepper. All time inputs are supposed to be given with the help of `Dates` (e.g. `Minute()`, `Hour()`, ...). But remember that every model component depends on a
`SpectralGrid` as first argument.
```@example howto
spectral_grid = SpectralGrid(trunc=63,nlev=1)
Expand Down Expand Up @@ -206,7 +206,7 @@ By default this runs for 10 days without output. These are the options left
to change, so with
```@example howto
model.output.id = "test" # hide
run!(simulation,n_days=5,output=true)
run!(simulation,period=Day(5),output=true)
```
You would continue this simulation (the previous `run!` call already integrated
10 days!) for another 5 days and storing default [NetCDF output](@ref).
4 changes: 2 additions & 2 deletions docs/src/output.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ The time axis of the NetCDF output will now look like
```@example netcdf
using NCDatasets
model.feedback.verbose = false # hide
run!(simulation,n_days=1,output=true)
run!(simulation,period=Day(1),output=true)
id = model.output.id
ds = NCDataset("run_$id/output.nc")
ds["time"][:]
Expand All @@ -79,7 +79,7 @@ time_stepping = Leapfrog(spectral_grid,adjust_with_output=true)
output = OutputWriter(spectral_grid, ShallowWater, output_dt=Hour(1))
model = ShallowWaterModel(;spectral_grid, time_stepping, output)
simulation = initialize!(model)
run!(simulation,n_days=1,output=true)
run!(simulation,period=Day(1),output=true)
id = model.output.id
ds = NCDataset("run_$id/output.nc")
ds["time"][:]
Expand Down
22 changes: 11 additions & 11 deletions docs/src/setups.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ complicated setups.
initial_conditions = StartWithRandomVorticity()
model = BarotropicModel(;spectral_grid, initial_conditions, planet=still_earth)
simulation = initialize!(model)
run!(simulation,n_days=20)
run!(simulation,period=Day(20))
```

We want to use the barotropic model to simulate some free-decaying 2D turbulence
Expand Down Expand Up @@ -53,11 +53,11 @@ plotted for surface relative vorticity with a unicode plot. The resolution of th
is not necessarily representative but it lets us have a quick look at the result
```@example barotropic_setup
simulation = initialize!(model)
run!(simulation,n_days=20)
run!(simulation,period=Day(20))
```

Woohoo! Something is moving! You could pick up where this simulation stopped by simply
doing `run!(simulation,n_days=50)` again. We didn't store any output, which
doing `run!(simulation,period=Day(50))` again. We didn't store any output, which
you can do by `run!(simulation,output=true)`, which will switch on NetCDF output
with default settings. More options on output in [NetCDF output](@ref).

Expand All @@ -71,7 +71,7 @@ with default settings. More options on output in [NetCDF output](@ref).
initial_conditions = ZonalJet()
model = ShallowWaterModel(;spectral_grid, orography, initial_conditions)
simulation = initialize!(model)
run!(simulation,n_days=6)
run!(simulation,period=Day(6))
```

As a second example, let's investigate the Galewsky et al.[^G04] test case for the shallow
Expand All @@ -97,12 +97,12 @@ Now we construct a model, but this time a `ShallowWaterModel`
```@example galewsky_setup
model = ShallowWaterModel(;spectral_grid, orography, initial_conditions)
simulation = initialize!(model)
run!(simulation,n_days=6)
run!(simulation,period=Day(6))
```
Oh yeah. That looks like the wobbly jet in their paper. Let's run it again for another 6 days
but this time also store [NetCDF output](@ref).
```@example galewsky_setup
run!(simulation,n_days=6,output=true)
run!(simulation,period=Day(6),output=true)
```
The progress bar tells us that the simulation run got the identification "0001"
(which just counts up, so yours might be higher), meaning that
Expand Down Expand Up @@ -164,7 +164,7 @@ compare with the last plot
```@example galewsky_setup
model = ShallowWaterModel(;spectral_grid, orography, initial_conditions)
simulation = initialize!(model)
run!(simulation,n_days=12,output=true)
run!(simulation,period=Day(12),output=true)
```

This time the run got a new run id, which you see in the progress bar, but can again always check
Expand Down Expand Up @@ -207,8 +207,8 @@ output = OutputWriter(spectral_grid,ShallowWater,output_dt=Hour(6),output_vars=[
model = ShallowWaterModel(;spectral_grid,output,drag,forcing)
simulation = initialize!(model)
model.feedback.verbose = false # hide
run!(simulation,n_days=20) # discard first 20 days
run!(simulation,n_days=20,output=true)
run!(simulation,period=Day(20)) # discard first 20 days
run!(simulation,period=Day(20),output=true)
nothing # hide
```

Expand Down Expand Up @@ -260,7 +260,7 @@ output = OutputWriter(spectral_grid,ShallowWater,output_dt=Hour(12),output_vars=
model = ShallowWaterModel(;spectral_grid,orography,output,initial_conditions,implicit,time_stepping)
simulation = initialize!(model)
model.feedback.verbose = false # hide
run!(simulation,n_days=2,output=true)
run!(simulation,period=Day(2),output=true)
nothing # hide
```

Expand Down Expand Up @@ -324,7 +324,7 @@ initial_conditions = ZonalWind()
model = PrimitiveDryModel(;spectral_grid,orography,initial_conditions,physics=false)
simulation = initialize!(model)
model.feedback.verbose = false # hide
run!(simulation,n_days=9,output=true)
run!(simulation,period=Day(9),output=true)
nothing # hide
```

Expand Down
2 changes: 1 addition & 1 deletion docs/src/speedytransforms.md
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ drag = QuadraticDrag(spectral_grid)
model = ShallowWaterModel(;spectral_grid,forcing,drag)
model.feedback.verbose = false # hide
simulation = initialize!(model);
run!(simulation,n_days=30)
run!(simulation,period=Day(30))
nothing # hide
```

Expand Down
2 changes: 1 addition & 1 deletion src/SpeedyWeather.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import Adapt: Adapt, adapt, adapt_structure

# INPUT OUTPUT
import TOML
import Dates: Dates, DateTime, Millisecond, Second, Minute, Hour, Day
import Dates: Dates, DateTime, Period, Millisecond, Second, Minute, Hour, Day
import Printf: Printf, @sprintf
import NCDatasets: NCDatasets, NCDataset, defDim, defVar
import JLD2: jldopen
Expand Down
21 changes: 18 additions & 3 deletions src/dynamics/prognostic_variables.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ Base.@kwdef mutable struct Clock
"current model time"
time::DateTime = DEFAULT_DATE

"number of days to integrate for, set in run!(::Simulation)"
n_days::Float64 = 0
"period to integrate for, set in set_period!(::Clock, ::Dates.Period)"
period::Second = Second(0)

"number of time steps to integrate for, set in initialize!(::Clock,::TimeStepper)"
n_timesteps::Int = 0
Expand All @@ -28,10 +28,25 @@ end
$(TYPEDSIGNATURES)
Initialize the clock with the time step `Δt` in the `time_stepping`."""
function initialize!(clock::Clock,time_stepping::TimeStepper)
clock.n_timesteps = ceil(Int,3600*24*clock.n_days/time_stepping.Δt_sec)
clock.n_timesteps = ceil(Int,clock.period.value/time_stepping.Δt_sec)
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`"""
Expand Down
5 changes: 3 additions & 2 deletions src/output/feedback.jl
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,16 @@ function initialize!(feedback::Feedback,clock::Clock,model::ModelSetup)
(; run_path, id) = feedback
SG = model.spectral_grid
L = model.time_stepping

days = clock.period.value/(3600*24)

# create progress.txt file in run_????/
progress_txt = open(joinpath(run_path,"progress.txt"),"w")
s = "Starting SpeedyWeather.jl run $id on "*
Dates.format(Dates.now(),Dates.RFC1123Format)
write(progress_txt,s*"\n")
write(progress_txt,"Integrating:\n")
write(progress_txt,"$SG\n")
write(progress_txt,"Time: $(clock.n_days) days at Δt = $(L.Δt_sec)s\n")
write(progress_txt,"Time: $days days at Δt = $(L.Δt_sec)s\n")
write(progress_txt,"\nAll data will be stored in $run_path\n")
feedback.progress_txt = progress_txt
end
Expand Down
14 changes: 10 additions & 4 deletions src/run_speedy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,24 @@
$(TYPEDSIGNATURES)
Run a SpeedyWeather.jl `simulation`. The `simulation.model` is assumed to be initialized."""
function run!( simulation::Simulation;
n_days::Real = 10,
output::Bool = false)
period = Day(10),
output::Bool = false,
n_days::Union{Nothing, Real}=nothing)

if !isnothing(n_days)
@warn "run!: n_days keyword is deprecated, use period = Day(n_days) instead."
period = Day(n_days)
end

(;prognostic_variables, diagnostic_variables, model) = simulation
(;clock) = prognostic_variables

# set the clock's enddate
clock.n_days = n_days
set_period!(clock,period)
initialize!(clock,model.time_stepping)

model.output.output = output # enable/disable output

# run it, yeah!
time_stepping!(prognostic_variables,diagnostic_variables,model)
end
end
21 changes: 21 additions & 0 deletions test/dates.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,25 @@
L4 = Leapfrog(SG,Δt_at_T31=Minute(60),adjust_with_output=false)
L5 = Leapfrog(SG,Δt_at_T31=Hour(1),adjust_with_output=false)
@test L4.Δt == L5.Δt

# clock tests
c1 = SpeedyWeather.Clock()
SG2 = SpectralGrid(trunc=31, nlev=1)
L6 = Leapfrog(SG2,Δt_at_T31=Hour(1),adjust_with_output=false)

SpeedyWeather.set_period!(c1, Hour(10))
SpeedyWeather.initialize!(c1, L6)
@test c1.n_timesteps == 10

SpeedyWeather.set_period!(c1, 10) # assumed to be in days
SpeedyWeather.initialize!(c1, L6)
@test c1.n_timesteps == 24*10

SpeedyWeather.set_period!(c1, 10.0) # also assumed to be in days
SpeedyWeather.initialize!(c1, L6)
@test c1.n_timesteps == 24*10

SpeedyWeather.set_period!(c1, Day(2))
SpeedyWeather.initialize!(c1, L6)
@test c1.n_timesteps == 48
end
34 changes: 17 additions & 17 deletions test/netcdf_output.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,89 +2,89 @@ using NCDatasets, Dates

@testset "Output on various grids" begin
tmp_output_path = mktempdir(pwd(), prefix = "tmp_testruns_") # Cleaned up when the process exits
n_days = 1
period = Day(1)

# default grid, Float64, ShallowWater
spectral_grid = SpectralGrid(;NF=Float64,nlev=1)
output = OutputWriter(spectral_grid,ShallowWater,path=tmp_output_path)
model = ShallowWaterModel(;spectral_grid,output)
simulation = initialize!(model)
run!(simulation,output=true;n_days)
run!(simulation,output=true;period)
@test simulation.model.feedback.nars_detected == false

# default grid, Float32, ShallowWater
spectral_grid = SpectralGrid(;NF=Float32,nlev=1)
output = OutputWriter(spectral_grid,ShallowWater,path=tmp_output_path)
model = ShallowWaterModel(;spectral_grid,output)
simulation = initialize!(model)
run!(simulation,output=true;n_days)
run!(simulation,output=true;period)
@test simulation.model.feedback.nars_detected == false

# FullClenshawGrid, Float32, ShallowWater
spectral_grid = SpectralGrid(;NF=Float32,Grid=FullClenshawGrid,nlev=1)
output = OutputWriter(spectral_grid,ShallowWater,path=tmp_output_path)
model = ShallowWaterModel(;spectral_grid,output)
simulation = initialize!(model)
run!(simulation,output=true;n_days)
run!(simulation,output=true;period)
@test simulation.model.feedback.nars_detected == false

# OctahedralClenshawGrid, Float32, ShallowWater
spectral_grid = SpectralGrid(;NF=Float32,Grid=OctahedralClenshawGrid,nlev=1)
output = OutputWriter(spectral_grid,ShallowWater,path=tmp_output_path)
model = ShallowWaterModel(;spectral_grid,output)
simulation = initialize!(model)
run!(simulation,output=true;n_days)
run!(simulation,output=true;period)
@test simulation.model.feedback.nars_detected == false

# HEALPixGrid, Float32, ShallowWater
spectral_grid = SpectralGrid(;NF=Float32,Grid=HEALPixGrid,nlev=1)
output = OutputWriter(spectral_grid,ShallowWater,path=tmp_output_path)
model = ShallowWaterModel(;spectral_grid,output)
simulation = initialize!(model)
run!(simulation,output=true;n_days)
run!(simulation,output=true;period)
@test simulation.model.feedback.nars_detected == false

# OctaHEALPixGrid, Float32, ShallowWater
spectral_grid = SpectralGrid(;NF=Float32,Grid=OctaHEALPixGrid,nlev=1)
output = OutputWriter(spectral_grid,ShallowWater,path=tmp_output_path)
model = ShallowWaterModel(;spectral_grid,output)
simulation = initialize!(model)
run!(simulation,output=true;n_days)
run!(simulation,output=true;period)
@test simulation.model.feedback.nars_detected == false

# OctahedralClenshawGrid, as matrix, Float32, ShallowWater
spectral_grid = SpectralGrid(;NF=Float32,Grid=OctahedralClenshawGrid,nlev=1)
output = OutputWriter(spectral_grid,ShallowWater,path=tmp_output_path,as_matrix=true)
model = ShallowWaterModel(;spectral_grid,output)
simulation = initialize!(model)
run!(simulation,output=true;n_days)
run!(simulation,output=true;period)
@test simulation.model.feedback.nars_detected == false

# OctaHEALPixGrid, as matrix, Float32, PrimitiveDry
spectral_grid = SpectralGrid(;NF=Float32,Grid=OctaHEALPixGrid)
output = OutputWriter(spectral_grid,PrimitiveDry,path=tmp_output_path,as_matrix=true)
model = PrimitiveDryModel(;spectral_grid,output)
simulation = initialize!(model)
run!(simulation,output=true;n_days)
run!(simulation,output=true;period)
@test simulation.model.feedback.nars_detected == false

# OctaHEALPixGrid, as matrix, Float32, but output Float64 PrimitiveDry
spectral_grid = SpectralGrid(;NF=Float32,Grid=OctaHEALPixGrid)
output = OutputWriter(spectral_grid,PrimitiveDry,path=tmp_output_path,as_matrix=true,NF=Float64)
model = PrimitiveDryModel(;spectral_grid,output)
simulation = initialize!(model)
run!(simulation,output=true;n_days)
run!(simulation,output=true;period)
@test simulation.model.feedback.nars_detected == false
end

@testset "Restart from output file" begin
tmp_output_path = mktempdir(pwd(), prefix = "tmp_testruns_") # Cleaned up when the process exits

spectral_grid = SpectralGrid()
output = OutputWriter(spectral_grid,PrimitiveDry,path=tmp_output_path,id="restart-test")
model = PrimitiveDryModel(;spectral_grid,output)
simulation = initialize!(model)
run!(simulation,output=true,n_days=1)
run!(simulation,output=true;period=Day(1))

initial_conditions = StartFromFile(path=tmp_output_path,id="restart-test")
model2 = PrimitiveDryModel(;spectral_grid,initial_conditions)
Expand Down Expand Up @@ -119,7 +119,7 @@ end
output = OutputWriter(spectral_grid,PrimitiveDry,path=tmp_output_path,id="dense-output-test",output_dt=Hour(0))
model = PrimitiveDryModel(;spectral_grid,output)
simulation = initialize!(model)
run!(simulation,output=true,n_days=1)
run!(simulation,output=true;period=Day(1))

progn = simulation.prognostic_variables
tmp_read_path = joinpath(model.output.run_path,model.output.filename)
Expand All @@ -131,7 +131,7 @@ end
time_stepping = Leapfrog(spectral_grid, adjust_with_output=true)
model = PrimitiveDryModel(;spectral_grid,output,time_stepping)
simulation = initialize!(model)
run!(simulation,output=true,n_days=1)
run!(simulation,output=true;period=Day(1))
t = SpeedyWeather.load_trajectory("time", model)
@test all(y->y==diff(t)[1], diff(t)) # all elements equal
@test diff(t)[1] == Minute(70)
Expand All @@ -141,11 +141,11 @@ end
# at the moment, no error
# 1kyrs simulation
spectral_grid = SpectralGrid()
time_stepping = Leapfrog(spectral_grid,Δt_at_T31=Minute(60*24*365*10))
output = OutputWriter(spectral_grid,PrimitiveDry,path=tmp_output_path,id="long-output-test",output_dt=Hour(24*365*10))
time_stepping = Leapfrog(spectral_grid,Δt_at_T31=Day(3650))
output = OutputWriter(spectral_grid,PrimitiveDry,path=tmp_output_path,id="long-output-test",output_dt=Day(3650))
model = PrimitiveDryModel(;spectral_grid,output,time_stepping)
simulation = initialize!(model)
run!(simulation,output=true,n_days=365000)
run!(simulation,output=true,period=Day(365000))

progn = simulation.prognostic_variables
tmp_read_path = joinpath(model.output.run_path,model.output.filename)
Expand Down
Loading

0 comments on commit 047adec

Please sign in to comment.