Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/itzi_core/simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -564,11 +564,13 @@ def reconcile_hotstart_resume(self, hotstart_config: SimulationConfig) -> Self:
if not self.drainage_model:
self.schedule.set_deadline("drainage", self.end_time)

# Accumulators begin at the last archived report boundary, independently
# of the cadence selected for the resumed run.
self.report.last_step = self.schedule.deadline("record") - hotstart_config.record_step
if self.report.dt != hotstart_config.record_step:
self.schedule.set_deadline(
"record", min(self.end_time, self.sim_time + self.report.dt)
)
self.report.last_step = copy.copy(self.sim_time)

if self.hydrology_model.dt != timedelta(seconds=hotstart_config.dtinf):
self.schedule.set_deadline(
Expand Down
17 changes: 16 additions & 1 deletion tests/test_hotstart_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def create_sim_config(
),
output_map_names=helpers.make_output_map_names(
"out_hotstart",
["water_depth", "qx", "qy", "created_volume"],
["water_depth", "qx", "qy", "created_volume", "mean_rainfall"],
),
surface_flow_parameters=SurfaceFlowParameters(hmin=0.0001, dtmax=0.3, cfl=0.2),
infiltration_model=InfiltrationModelType.GREEN_AMPT,
Expand Down Expand Up @@ -351,6 +351,15 @@ def test_roundtrip_state_restoration_and_match(
# Calling initialize() would overwrite restored state (old_domain_volume, accum arrays, etc.)
run_simulation_to_end(sim_b, skip_initialize=True)

resumed_output = sim_b.report.raster_provider
assert isinstance(resumed_output, MemoryRasterOutputProvider)
_, mean_rainfall = resumed_output.output_maps_dict["mean_rainfall"][0]
np.testing.assert_allclose(
mean_rainfall,
domain_5by5.arr_rain * 3_600_000,
rtol=1e-5,
)

# Step 4: Verify final results match uninterrupted reference
# Use qe/qs (internal flow arrays) instead of qx/qy (output arrays computed on-the-fly)
assert_final_state_matches(sim_b, uninterrupted_simulation)
Expand Down Expand Up @@ -472,6 +481,12 @@ def test_resume_applies_new_record_step_cadence(
]

assert resumed_record_times[: len(expected_record_times)] == expected_record_times
_, mean_rainfall = resumed_output.output_maps_dict["mean_rainfall"][0]
np.testing.assert_allclose(
mean_rainfall,
domain_5by5.arr_rain * 3_600_000,
rtol=1e-5,
)

assert_state_differs(sim_b, record_step_hotstart_run["simulation"])

Expand Down
Loading