Skip to content

Commit 148dba7

Browse files
authored
Merge pull request #3710 from CliMA/gb/non_zero_t_start
Add option to restart from a non zero t and bump to 0.29.1
2 parents f8cdc63 + 3fc23da commit 148dba7

File tree

8 files changed

+46
-31
lines changed

8 files changed

+46
-31
lines changed

NEWS.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@ ClimaAtmos.jl Release Notes
44
main
55
-------
66

7+
v0.29.1
8+
-------
9+
10+
### Add support for non-zero `t_start`
11+
12+
Passing a non zero `t_start` is useful in conditions where one wants to have a
13+
specific `start_date`, but start the simulation from a different point. This is
14+
used by `ClimaCoupler` to restart simulations.
15+
716
v0.29.0
817
-------
918

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "ClimaAtmos"
22
uuid = "b2c96348-7fb7-4fe0-8da9-78d88439e717"
33
authors = ["Climate Modeling Alliance"]
4-
version = "0.29.0"
4+
version = "0.29.1"
55

66
[deps]
77
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"

config/default_configs/default_config.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ FLOAT_TYPE:
123123
dt:
124124
help: "Simulation time step. Examples: [`10secs`, `1hours`]"
125125
value: "600secs"
126+
t_start:
127+
help: "Simulation start time. This is typically useful in the context of manually restarting a simulation (e.g., but reinitializing the initial state). It is overwritten when the simulation is restarted with the checkpointing system. Examples: [`0secs`, `40secs`]"
128+
value: "0secs"
126129
t_end:
127130
help: "Simulation end time. Examples: [`1200days`, `40secs`]"
128131
value: "10days"

docs/src/restarts.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ is started.
4747
If is also possible to manually specify a restart file. In this case, this will
4848
override any file automatically detected.
4949

50+
`ClimaAtmos` also comes with a configuration,` t_start`, to change the initial
51+
time of the simulation without changing the start date. This option can be
52+
useful manually restarting a simulation (e.g., by overwriting the initial
53+
conditions). When a simulation is restarted from a checkpoint, this option
54+
becomes redundant.
55+
5056
### Accumulated Diagnostics
5157

5258
At the moment, `ClimaAtmos` does not support working with accumulated

src/callbacks/callbacks.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ NVTX.@annotate function rrtmgp_model_callback!(integrator)
290290

291291
set_surface_albedo!(Y, p, t, p.atmos.surface_albedo)
292292

293-
RRTMGPI.update_fluxes!(rrtmgp_model, UInt32(t / integrator.p.dt))
293+
RRTMGPI.update_fluxes!(rrtmgp_model, UInt32(floor(t / integrator.p.dt)))
294294
Fields.field2array(ᶠradiation_flux) .= rrtmgp_model.face_flux
295295
return nothing
296296
end

src/callbacks/get_callbacks.jl

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,6 @@
1-
function get_diagnostics(
2-
parsed_args,
3-
atmos_model,
4-
Y,
5-
p,
6-
sim_info,
7-
t_start,
8-
output_dir,
9-
)
10-
11-
(; dt, start_date) = sim_info
1+
function get_diagnostics(parsed_args, atmos_model, Y, p, sim_info, output_dir)
2+
3+
(; dt, t_start, start_date) = sim_info
124

135
FT = Spaces.undertype(axes(Y.c))
146
context = ClimaComms.context(axes(Y.c))
@@ -249,16 +241,16 @@ function checkpoint_frequency_from_parsed_args(dt_save_state_to_disk::String)
249241
end
250242

251243

252-
function get_callbacks(config, sim_info, atmos, params, Y, p, t_start)
244+
function get_callbacks(config, sim_info, atmos, params, Y, p)
253245
(; parsed_args, comms_ctx) = config
254246
FT = eltype(params)
255-
(; dt, output_dir, start_date) = sim_info
247+
(; dt, output_dir, start_date, t_start, t_end) = sim_info
256248

257249
callbacks = ()
258250
if parsed_args["log_progress"]
259251
@info "Progress logging enabled"
260252
walltime_info = WallTimeInfo()
261-
tot_steps = ceil(Int, (sim_info.t_end - t_start) / dt)
253+
tot_steps = ceil(Int, (t_end - t_start) / dt)
262254
five_percent_steps = ceil(Int, 0.05 * tot_steps)
263255
cond = let schedule = CappedGeometricSeriesSchedule(five_percent_steps)
264256
(u, t, integrator) -> schedule(integrator)
@@ -340,7 +332,7 @@ function get_callbacks(config, sim_info, atmos, params, Y, p, t_start)
340332
dt isa ITime ?
341333
ITime(time_to_seconds(parsed_args["dt_cloud_fraction"])) :
342334
FT(time_to_seconds(parsed_args["dt_cloud_fraction"]))
343-
dt_cf, _, _, _ = promote(dt_cf, t_start, dt, sim_info.t_end)
335+
dt_cf, _, _, _ = promote(dt_cf, t_start, dt, t_end)
344336
callbacks =
345337
(callbacks..., call_every_dt(cloud_fraction_model_callback!, dt_cf))
346338
end
@@ -349,7 +341,7 @@ function get_callbacks(config, sim_info, atmos, params, Y, p, t_start)
349341
dt_rad =
350342
dt isa ITime ? ITime(time_to_seconds(parsed_args["dt_rad"])) :
351343
FT(time_to_seconds(parsed_args["dt_rad"]))
352-
dt_rad, _, _, _ = promote(dt_rad, t_start, dt, sim_info.t_end)
344+
dt_rad, _, _, _ = promote(dt_rad, t_start, dt, t_end)
353345
# We use Millisecond to support fractional seconds, eg. 0.1
354346
dt_rad_ms = Dates.Millisecond(1_000 * float(dt_rad))
355347
if parsed_args["dt_save_state_to_disk"] != "Inf" &&

src/solver/type_getters.jl

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -604,12 +604,19 @@ function get_sim_info(config::AtmosConfig)
604604
isnothing(restart_file) ||
605605
@info "Restarting simulation from file $restart_file"
606606
epoch = DateTime(parsed_args["start_date"], dateformat"yyyymmdd")
607+
t_start_int = time_to_seconds(parsed_args["t_start"])
608+
if !isnothing(restart_file) && t_start_int != 0
609+
@warn "Non zero `t_start` passed with a restarting simulation. The provided `t_start` will be ignored."
610+
end
607611
if parsed_args["use_itime"]
608612
dt = ITime(time_to_seconds(parsed_args["dt"]))
613+
t_start = ITime(time_to_seconds(parsed_args["t_start"]), epoch = epoch)
609614
t_end = ITime(time_to_seconds(parsed_args["t_end"]), epoch = epoch)
610-
(dt, t_end) = promote(dt, t_end)
615+
# ITime(0) is added for backward compatibility (since t_start used to always be 0)
616+
(dt, t_start, t_end, _) = promote(dt, t_start, t_end, ITime(0))
611617
else
612618
dt = FT(time_to_seconds(parsed_args["dt"]))
619+
t_start = FT(time_to_seconds(parsed_args["t_start"]))
613620
t_end = FT(time_to_seconds(parsed_args["t_end"]))
614621
end
615622
sim = (;
@@ -619,12 +626,14 @@ function get_sim_info(config::AtmosConfig)
619626
job_id,
620627
dt = dt,
621628
start_date = epoch,
629+
t_start = t_start,
622630
t_end = t_end,
623631
)
624-
n_steps = floor(Int, sim.t_end / sim.dt)
632+
n_steps = floor(Int, (sim.t_end - sim.t_start) / sim.dt)
625633
@info(
626634
"Time info:",
627635
dt = parsed_args["dt"],
636+
t_start = parsed_args["t_start"],
628637
t_end = parsed_args["t_end"],
629638
floor_n_steps = n_steps,
630639
)
@@ -734,6 +743,8 @@ function get_simulation(config::AtmosConfig)
734743
hash(atmos),
735744
)
736745
spaces = get_spaces_restart(Y)
746+
# Fix the t_start in sim_info with the one from the restart
747+
sim_info = merge(sim_info, (; t_start))
737748
end
738749
@info "Allocating Y: $s"
739750
else
@@ -749,14 +760,6 @@ function get_simulation(config::AtmosConfig)
749760
spaces.center_space,
750761
spaces.face_space,
751762
)
752-
if sim_info.dt isa ITime
753-
t_start = ITime(
754-
Spaces.undertype(axes(Y.c))(0);
755-
epoch = sim_info.start_date,
756-
)
757-
else
758-
t_start = Spaces.undertype(axes(Y.c))(0)
759-
end
760763
end
761764
@info "Allocating Y: $s"
762765

@@ -800,7 +803,7 @@ function get_simulation(config::AtmosConfig)
800803
@info "ode_configuration: $s"
801804

802805
s = @timed_str begin
803-
callback = get_callbacks(config, sim_info, atmos, params, Y, p, t_start)
806+
callback = get_callbacks(config, sim_info, atmos, params, Y, p)
804807
end
805808
@info "get_callbacks: $s"
806809

@@ -814,7 +817,6 @@ function get_simulation(config::AtmosConfig)
814817
Y,
815818
p,
816819
sim_info,
817-
t_start,
818820
output_dir,
819821
)
820822
end
@@ -853,7 +855,7 @@ function get_simulation(config::AtmosConfig)
853855
@info "n_steps_per_cycle_per_cb (non diagnostics): $steps_cycle_non_diag"
854856
@info "n_steps_per_cycle (non diagnostics): $steps_cycle"
855857

856-
tspan = (t_start, sim_info.t_end)
858+
tspan = (sim_info.t_start, sim_info.t_end)
857859
s = @timed_str begin
858860
integrator_args, integrator_kwargs = args_integrator(
859861
config.parsed_args,

test/coupler_compatibility.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ end
213213
# Verify that using PrescribedSurface does not break the initialization of
214214
# RRTMGP or diagnostic EDMF. We currently need a moisture model in order to
215215
# use diagnostic EDMF.
216+
#
217+
# Also verify we can start with a different t_start than 0
216218
config = CA.AtmosConfig(
217219
Dict(
218220
"surface_setup" => "PrescribedSurface",
@@ -225,6 +227,7 @@ end
225227
# remove the following line and check that the test runs in less than a few
226228
# minutes on GitHub
227229
"output_default_diagnostics" => false,
230+
"t_start" => "1secs",
228231
);
229232
job_id = "coupler_compatibility3",
230233
)

0 commit comments

Comments
 (0)