def test_update_flow_field_time1_iteration1(self, tmp_path): """ Check that the flow in domain is set as expected when no flow (qx & qy==0) """ # create a delta with default settings p = utilities.yaml_from_dict(tmp_path, 'input.yaml') delta = DeltaModel(input_file=p) delta.log_info = mock.MagicMock() # conditions are zero already, but... delta._time_iter = 1 iteration = 1 # run the method qx0 = np.copy(delta.qx) delta.update_flow_field(iteration) # assertions # not sure what to check here other than that something changed assert np.any(delta.qx != qx0) # check inlet boundary conditon assert np.all(delta.qx[0, delta.inlet] == delta.qw0) assert np.all(delta.qy[0, delta.inlet] == 0) assert np.all(delta.qw[0, delta.inlet] == delta.qw0) assert delta.log_info.call_count == 1
def test_route_sand_parcels(self, tmp_path): # create a delta with default settings p = utilities.yaml_from_dict(tmp_path, 'input.yaml', { 'Np_sed': 1000, 'f_bedload': 0.6 }) _delta = DeltaModel(input_file=p) # mock top-level methods / objects _delta.log_info = mock.MagicMock() _delta._sr = mock.MagicMock() # mock the shared tools start indices def _patched_starts(inlet, inlet_weights, num_starts): return np.random.randint(0, 5, size=(num_starts, )) patcher = mock.patch('pyDeltaRCM.shared_tools.get_start_indices', new=_patched_starts) patcher.start() # run the method _delta.route_all_sand_parcels() # methods called assert (_delta._sr.run.call_count == 1) assert (_delta.log_info.call_count == 3) # stop the patch patcher.stop()
def test_save_metadata_no_grids(self, tmp_path): p = utilities.yaml_from_dict(tmp_path, 'input.yaml', { 'save_dt': 1, 'save_metadata': True }) _delta = DeltaModel(input_file=p) # mock the log_info _delta.log_info = mock.MagicMock() # mock the actual output routines _delta.make_figure = mock.MagicMock() _delta.save_figure = mock.MagicMock() _delta.save_grids = mock.MagicMock() exp_path_nc = os.path.join(tmp_path / 'out_dir', 'pyDeltaRCM_output.nc') assert os.path.isfile(exp_path_nc) for _t in range(0, 3): _delta.save_grids_and_figs() _delta._save_iter += 1 # close the file and connect _delta.output_netcdf.close() ds = netCDF4.Dataset(exp_path_nc, "r", format="NETCDF4") # assertions assert not ('eta' in ds.variables) assert ds['meta']['H_SL'].shape[0] == 4 # init + 3 assert ds['meta']['L0'][:] == 3
def test_save_no_figs_no_grids(self, tmp_path): p = utilities.yaml_from_dict(tmp_path, 'input.yaml', {'save_dt': 1}) _delta = DeltaModel(input_file=p) # mock the log_info _delta.log_info = mock.MagicMock() # mock the actual output routines _delta.make_figure = mock.MagicMock() _delta.save_figure = mock.MagicMock() _delta.save_grids = mock.MagicMock() # check nothing created at the start _delta.make_figure.call_count == 0 _delta.save_figure.call_count == 0 _delta.save_grids.call_count == 0 # update the delta a few times for _t in range(0, 4): _delta._time = (_t * _delta._dt) _delta.save_grids_and_figs() # check nothing after a number of iterations, greater than dt assert _delta._time > _delta.save_dt _delta.make_figure.call_count == 0 _delta.save_figure.call_count == 0 _delta.save_grids.call_count == 0
def test_update_flow_field_time0_iteration0(self, tmp_path): """ Check that the flow at the inlet is set as expected """ # create a delta with default settings p = utilities.yaml_from_dict(tmp_path, 'input.yaml') delta = DeltaModel(input_file=p) # mock the log delta.log_info = mock.MagicMock() # conditions are zero already, but... delta._time_iter = 0 iteration = 0 # run the method delta.update_flow_field(iteration) # assertions assert np.all(delta.qx[1:, :] == delta.qxn[1:, :]) assert np.all(delta.qy[1:, :] == delta.qyn[1:, :]) # check inlet boundary conditon assert np.all(delta.qx[0, delta.inlet] == delta.qw0) assert np.all(delta.qy[0, delta.inlet] == 0) assert np.all(delta.qw[0, delta.inlet] == delta.qw0) assert delta.log_info.call_count == 1
def test_solve_water_and_sediment_timestep_itermax_10(self, tmp_path): # create a delta with different itermax p = utilities.yaml_from_dict(tmp_path, 'input.yaml', {'itermax': 10}) delta = DeltaModel(input_file=p) # mock top-level methods, verify call was made to each delta.log_info = mock.MagicMock() delta.init_water_iteration = mock.MagicMock() delta.run_water_iteration = mock.MagicMock() delta.compute_free_surface = mock.MagicMock() delta.finalize_water_iteration = mock.MagicMock() delta.route_sediment = mock.MagicMock() # run the timestep delta.solve_water_and_sediment_timestep() # assert that methods are called assert delta.init_water_iteration.called is True assert delta.run_water_iteration.called is True assert delta.compute_free_surface.called is True assert delta.finalize_water_iteration.called is True _calls = [mock.call(i) for i in range(10)] delta.finalize_water_iteration.assert_has_calls(_calls, any_order=False) assert delta.finalize_water_iteration.call_count == 10 assert (delta.route_sediment.called is True) assert (delta._is_finalized is False)
def test_save_sedflux_grids(self, tmp_path): p = utilities.yaml_from_dict(tmp_path, 'input.yaml', { 'save_dt': 1, 'save_sedflux_grids': True }) _delta = DeltaModel(input_file=p) # mock the log_info _delta.log_info = mock.MagicMock() exp_path_nc = os.path.join(tmp_path / 'out_dir', 'pyDeltaRCM_output.nc') assert os.path.isfile(exp_path_nc) for _t in range(0, 6): _delta.save_grids('sedflux', _delta.qs, _delta._save_iter) _delta._save_iter += 1 # close the file and connect _delta.output_netcdf.close() ds = netCDF4.Dataset(exp_path_nc, "r", format="NETCDF4") # assertions assert (_delta.log_info.call_count == 6) _arr = ds.variables['sedflux'] assert _arr.shape[1] == _delta.qs.shape[0] assert _arr.shape[2] == _delta.qs.shape[1] assert ('meta' in ds.groups) # if any grids, save meta too
def test_load_already_open_netcdf_error(self, patched, tmp_path): """ Test that a checkpoint can be loaded when the load expects there to be a netcdf file. This will create a new netcdf file and raise a warning. """ # define a yaml with an output, and checkpoint p = utilities.yaml_from_dict(tmp_path, 'input.yaml', { 'save_checkpoint': True, 'save_eta_grids': True }) _delta = DeltaModel(input_file=p) # make mocks _delta.log_info = mock.MagicMock() _delta.logger = mock.MagicMock() _delta.init_output_file = mock.MagicMock() # close the file so can be safely opened in load _delta.output_netcdf.close() # check that files exist, and then open the nc back up assert os.path.isfile( os.path.join(_delta.prefix, 'pyDeltaRCM_output.nc')) assert os.path.isfile(os.path.join(_delta.prefix, 'checkpoint.npz')) _ = Dataset(os.path.join(_delta.prefix, 'pyDeltaRCM_output.nc')) # now try to resume a model and should throw error with pytest.raises(RuntimeError): _delta.load_checkpoint()
def test_save_one_fig_no_grids(self, tmp_path): p = utilities.yaml_from_dict(tmp_path, 'input.yaml', { 'save_dt': 1, 'save_eta_figs': True }) _delta = DeltaModel(input_file=p) # mock the log_info _delta.log_info = mock.MagicMock() # mock the actual output routines _delta.make_figure = mock.MagicMock() _delta.save_figure = mock.MagicMock() _delta.save_grids = mock.MagicMock() # check nothing created at the start _delta.make_figure.call_count == 0 _delta.save_figure.call_count == 0 _delta.save_grids.call_count == 0 assert (len(_delta._save_fig_list) > 0) assert (_delta._save_eta_figs is True) # update the delta a few times for _t in range(0, 5): _delta.save_grids_and_figs() _delta._save_iter += 1 _delta.make_figure.call_count == 5 _delta.save_figure.call_count == 5 _delta.save_grids.call_count == 0
def test_save_one_fig_one_grid(self, tmp_path): p = utilities.yaml_from_dict(tmp_path, 'input.yaml', { 'save_dt': 1, 'save_eta_grids': True, 'save_discharge_figs': True }) _delta = DeltaModel(input_file=p) # mock the log_info _delta.log_info = mock.MagicMock() # mock the actual output routines _delta.make_figure = mock.MagicMock() _delta.save_figure = mock.MagicMock() _delta.save_grids = mock.MagicMock() assert (_delta._save_eta_grids is True) assert (_delta._save_metadata is True) # check for the netcdf file exp_path_nc = os.path.join(tmp_path / 'out_dir', 'pyDeltaRCM_output.nc') assert os.path.isfile(exp_path_nc) nc_size_before = os.path.getsize(exp_path_nc) assert nc_size_before > 0 # saved once already / inited # update a couple times, should increase on each save for _t in range(0, 5): _delta.save_grids_and_figs() _delta._save_iter += 1 _delta.make_figure.call_count == 5 _delta.save_figure.call_count == 5 _delta.save_grids.call_count == 5
def test_finalize_updated(self, tmp_path): p = utilities.yaml_from_dict(tmp_path, 'input.yaml') _delta = DeltaModel(input_file=p) # mock the top-level _delta.log_info = mock.MagicMock() _delta.output_data = mock.MagicMock() _delta.output_checkpoint = mock.MagicMock() # modify the save interval _t = 5 _delta._save_dt = _t * _delta._dt _delta._checkpoint_dt = _t * _delta._dt # run a mock update / save _delta._time = _t * _delta._dt _delta._save_iter += int(1) _delta._save_time_since_data = 0 _delta._save_time_since_checkpoint = 0 # run finalize _delta.finalize() # assert calls # should only hit top-levels assert _delta.log_info.call_count == 2 assert _delta.output_data.call_count == 0 assert _delta.output_checkpoint.call_count == 0 assert _delta._is_finalized is True
def test_save_a_checkpoint_checkpoint_False(self, tmp_path): # create a delta with subsidence parameters p = utilities.yaml_from_dict(tmp_path, 'input.yaml', {'save_checkpoint': False}) _delta = DeltaModel(input_file=p) # mock the actual save checkpoint function to see if it was called _delta.save_the_checkpoint = mock.MagicMock() _delta.log_info = mock.MagicMock() _delta.output_checkpoint() # assertions assert (_delta.save_the_checkpoint.called is False) assert (_delta.log_info.called is False)
def test_load_wo_netcdf_expected(self, patched, tmp_path): """ Test that a checkpoint can be loaded when the load expects there to be a netcdf file. This will create a new netcdf file and raise a warning. """ # define a yaml with NO outputs, but checkpoint p = utilities.yaml_from_dict(tmp_path, 'input.yaml', { 'save_checkpoint': True, 'save_eta_grids': True }) _delta = DeltaModel(input_file=p) # make mocks _delta.log_info = mock.MagicMock() _delta.logger = mock.MagicMock() _delta.init_output_file = mock.MagicMock() # close the file so can be safely opened in load _delta.output_netcdf.close() # check that files exist, and then delete nc assert os.path.isfile( os.path.join(_delta.prefix, 'pyDeltaRCM_output.nc')) assert os.path.isfile(os.path.join(_delta.prefix, 'checkpoint.npz')) os.remove(os.path.join(_delta.prefix, 'pyDeltaRCM_output.nc')) # now mess up a field _eta0 = np.copy(_delta.eta) _rand_field = np.random.uniform(0, 1, size=_delta.eta.shape) _delta.eta = _rand_field assert np.all(_delta.eta == _rand_field) # now resume from the checkpoint to restore the field with pytest.warns(UserWarning, match=r'NetCDF4 output *.'): _delta.load_checkpoint() # check that fields match assert np.all(_delta.eta == _eta0) assert _delta._save_iter == 0 # assertions on function calls _delta.log_info.assert_called() _delta.logger.warning.assert_called() _delta.init_output_file.assert_called() patched.assert_called()
def test_finalize_timestep(self, tmp_path): # create a delta with default settings p = utilities.yaml_from_dict(tmp_path, 'input.yaml', {'SLR': 0.001}) delta = DeltaModel(input_file=p) # mock the flooding correction and log delta.log_info = mock.MagicMock() delta.flooding_correction = mock.MagicMock() # run the step delta.finalize_timestep() # assert submethod called once delta.flooding_correction.call_count == 1 # check that sea level rose as expected assert delta.H_SL == 25
def test_save_grids_exception(self, tmp_path): p = utilities.yaml_from_dict(tmp_path, 'input.yaml', {'save_dt': 1}) _delta = DeltaModel(input_file=p) # mock the log_info _delta.log_info = mock.MagicMock() # no netcdf will be created exp_path_nc = os.path.join(tmp_path / 'out_dir', 'pyDeltaRCM_output.nc') assert os.path.isfile(exp_path_nc) is False # trying to save a grid will raise an exception with pytest.raises(Exception, match=r"DeltaModel' object .*"): _delta.save_grids('sedflux', _delta.qs, _delta._save_iter) # assert log was called when exception was raised assert (_delta.log_info.call_count == 1)
def test_save_a_checkpoint_checkpoint_true(self, tmp_path): # create a delta with subsidence parameters p = utilities.yaml_from_dict(tmp_path, 'input.yaml', {'save_checkpoint': True}) _delta = DeltaModel(input_file=p) # force the time to be greater than the checkpoint interval _delta._save_time_since_checkpoint = 2 * _delta._checkpoint_dt # mock the actual save checkpoint function to see if it was called _delta.save_the_checkpoint = mock.MagicMock() _delta.log_info = mock.MagicMock() # run the output checkpoint func _delta.output_checkpoint() # assertions assert (_delta.save_the_checkpoint.call_count == 1) assert (_delta.log_info.call_count == 1)
def test_save_all_figures_no_grids(self, tmp_path): p = utilities.yaml_from_dict( tmp_path, 'input.yaml', { 'save_dt': 1, 'save_eta_figs': True, 'save_discharge_figs': True, 'save_velocity_figs': True, 'save_stage_figs': True, 'save_depth_figs': True, 'save_sedflux_figs': True }) _delta = DeltaModel(input_file=p) # mock the log_info _delta.log_info = mock.MagicMock() # mock the actual output routines _delta.make_figure = mock.MagicMock() _delta.save_figure = mock.MagicMock() _delta.save_grids = mock.MagicMock() exp_path_nc = os.path.join(tmp_path / 'out_dir', 'pyDeltaRCM_output.nc') assert not os.path.isfile(exp_path_nc) for _t in range(0, 5): _delta.save_grids_and_figs() _delta._save_iter += 1 _delta._time += _delta._dt # assertions _delta.make_figure.assert_any_call('eta', 0) _delta.make_figure.assert_any_call('stage', 0) _delta.make_figure.assert_any_call('depth', 0) _delta.make_figure.assert_any_call('qw', 0) _delta.make_figure.assert_any_call('uw', 0) _delta.make_figure.assert_any_call('qs', 0) for _i in range(1, 5): _delta.make_figure.assert_any_call('eta', _delta._dt * _i) _delta.make_figure.call_count == 5 * 6 _delta.save_figure.call_count == 5 * 6 _delta.save_grids.call_count == 0
def test_fields_updated(self, tmp_path): # create a delta with default settings p = utilities.yaml_from_dict(tmp_path, 'input.yaml') delta = DeltaModel(input_file=p) delta.log_info = mock.MagicMock() # run the method delta.init_water_iteration() # assertions assert np.all(delta.qxn == 0) assert np.all(delta.qyn == 0) assert np.all(delta.qwn == 0) assert np.all(delta.free_surf_flag == 1) # all parcels begin as valid assert np.all(delta.free_surf_walk_inds == 0) assert np.all(delta.sfc_visit == 0) assert np.all(delta.sfc_sum == 0) assert delta.log_info.call_count == 1
def test_load_standard_grid(self, patched, tmp_path): """Test that a run can be resumed when there are outputs. """ # create one delta, just to have a checkpoint file p = utilities.yaml_from_dict(tmp_path, 'input.yaml', { 'save_checkpoint': True, 'save_eta_grids': True }) _delta = DeltaModel(input_file=p) # make mocks _delta.log_info = mock.MagicMock() _delta.logger = mock.MagicMock() _delta.init_output_file = mock.MagicMock() # close the file so can be safely opened in load _delta.output_netcdf.close() # check checkpoint exists assert os.path.isfile(os.path.join(_delta.prefix, 'checkpoint.npz')) assert os.path.isfile( os.path.join(_delta.prefix, 'pyDeltaRCM_output.nc')) # now mess up a field _eta0 = np.copy(_delta.eta) _rand_field = np.random.uniform(0, 1, size=_delta.eta.shape) _delta.eta = _rand_field assert np.all(_delta.eta == _rand_field) # now resume from the checkpoint to restore the field _delta.load_checkpoint() # check that fields match assert np.all(_delta.eta == _eta0) # assertions on function calls _call = [mock.call('Renaming old NetCDF4 output file', verbosity=2)] _delta.log_info.assert_has_calls(_call, any_order=True) _delta.logger.assert_not_called() _delta.init_output_file.assert_not_called() patched.assert_called()
def test_update_velocity_field(self, tmp_path): """ Check that flow velocity field is updated as expected """ # create a delta with default settings p = utilities.yaml_from_dict(tmp_path, 'input.yaml') delta = DeltaModel(input_file=p) delta.log_info = mock.MagicMock() # run the method delta.update_velocity_field() # make a mask, which is less restictive that the actual mask dmask = delta.depth > 0 # assertions assert np.all(delta.ux[dmask] != 0) assert np.all(delta.uw[dmask] != 0) assert delta.log_info.call_count == 1
def test_finalize_not_updated(self, tmp_path): p = utilities.yaml_from_dict(tmp_path, 'input.yaml') _delta = DeltaModel(input_file=p) _delta.log_info = mock.MagicMock() _delta.output_data = mock.MagicMock() _delta.output_checkpoint = mock.MagicMock() # run finalize _delta.finalize() # assert calls # should hit all options since no saves assert _delta.log_info.call_count == 2 # these were originally included in `finalize`, but no longer. # the checks for no call are here to ensure we don't revert assert _delta.output_data.call_count == 0 assert _delta.output_checkpoint.call_count == 0 assert _delta._is_finalized is True
def test_route_sediment(self, tmp_path): # create a delta with default settings p = utilities.yaml_from_dict(tmp_path, 'input.yaml') _delta = DeltaModel(input_file=p) # mock top-level methods _delta.log_info = mock.MagicMock() _delta.init_sediment_iteration = mock.MagicMock() _delta.route_all_sand_parcels = mock.MagicMock() _delta.topo_diffusion = mock.MagicMock() _delta.route_all_mud_parcels = mock.MagicMock() # run the method _delta.route_sediment() # methods called assert (_delta.log_info.call_count == 4) assert (_delta.init_sediment_iteration.called is True) assert (_delta.route_all_sand_parcels.called is True) assert (_delta.topo_diffusion.called is True) assert (_delta.route_all_mud_parcels.called is True)
def test_route_water(self, tmp_path): # create a delta with default settings p = utilities.yaml_from_dict(tmp_path, 'input.yaml') _delta = DeltaModel(input_file=p) # mock top-level methods _delta.log_info = mock.MagicMock() _delta.init_water_iteration = mock.MagicMock() _delta.run_water_iteration = mock.MagicMock() _delta.compute_free_surface = mock.MagicMock() _delta.finalize_water_iteration = mock.MagicMock() # run the method _delta.route_water() # methods called assert (_delta.log_info.called is True) assert (_delta.init_water_iteration.call_count == _delta._itermax) assert (_delta.run_water_iteration.call_count == _delta._itermax) assert (_delta.compute_free_surface.call_count == _delta._itermax) assert (_delta.finalize_water_iteration.call_count == _delta._itermax)
def test_save_one_grid_metadata_by_default(self, tmp_path): p = utilities.yaml_from_dict( tmp_path, 'input.yaml', { 'save_dt': 1, 'save_metadata': False, 'save_eta_grids': True, 'C0_percent': 0.2 }) _delta = DeltaModel(input_file=p) # mock the log_info _delta.log_info = mock.MagicMock() # mock the actual output routines _delta.make_figure = mock.MagicMock() _delta.save_figure = mock.MagicMock() _delta.save_grids = mock.MagicMock() exp_path_nc = os.path.join(tmp_path / 'out_dir', 'pyDeltaRCM_output.nc') assert os.path.isfile(exp_path_nc) for _t in range(0, 6): _delta.save_grids_and_figs() _delta._save_iter += 1 # close the file and connect _delta.output_netcdf.close() ds = netCDF4.Dataset(exp_path_nc, "r", format="NETCDF4") # assertions _arr = ds.variables['eta'] assert _arr.shape[1] == _delta.eta.shape[0] assert _arr.shape[2] == _delta.eta.shape[1] assert ('meta' in ds.groups) # if any grids, save meta too assert ds.groups['meta']['H_SL'].shape[0] == _arr.shape[0] assert np.all(ds.groups['meta']['C0_percent'][:] == 0.2) assert np.all(ds.groups['meta']['f_bedload'][:] == 0.5)
def test_load_wo_netcdf_not_expected(self, patched, tmp_path): """ Test that a checkpoint can be loaded when the load does not expect there to be any netcdf file. """ # create one delta, just to have a checkpoint file p = utilities.yaml_from_dict(tmp_path, 'input.yaml', {'save_checkpoint': True}) _delta = DeltaModel(input_file=p) # make mocks _delta.log_info = mock.MagicMock() _delta.logger = mock.MagicMock() _delta.init_output_file = mock.MagicMock() assert os.path.isfile(os.path.join(_delta.prefix, 'checkpoint.npz')) assert not os.path.isfile( os.path.join(_delta.prefix, 'pyDeltaRCM_output.nc')) # now mess up a field _eta0 = np.copy(_delta.eta) _rand_field = np.random.uniform(0, 1, size=_delta.eta.shape) _delta.eta = _rand_field assert np.all(_delta.eta == _rand_field) # now resume from the checkpoint to restore the field _delta.load_checkpoint() # check that fields match assert np.all(_delta.eta == _eta0) # assertions on function calls _delta.log_info.assert_called() _delta.logger.assert_not_called() _delta.init_output_file.assert_not_called() patched.assert_called()
def test_update_make_record(self, tmp_path): # create a delta with default settings p = utilities.yaml_from_dict(tmp_path, 'input.yaml', {'save_checkpoint': True}) _delta = DeltaModel(input_file=p) # modify the save interval to be twice dt _delta._save_dt = 2 * _delta._dt _delta._checkpoint_dt = 2 * _delta._dt # mock top-level methods, verify call was made to each _delta.solve_water_and_sediment_timestep = mock.MagicMock() _delta.apply_subsidence = mock.MagicMock() _delta.finalize_timestep = mock.MagicMock() _delta.log_info = mock.MagicMock() _delta.log_model_time = mock.MagicMock() _delta.save_the_checkpoint = mock.MagicMock() # DO NOT mock output_data our output_checkpoint # mock the calls inside output_data _delta.save_stratigraphy = mock.MagicMock() _delta.save_grids_and_figs = mock.MagicMock() # run the timestep: t=0 # * should call core, but nothing else after init _delta.update() # assert calls assert _delta.solve_water_and_sediment_timestep.call_count == 1 assert _delta.apply_subsidence.call_count == 1 assert _delta.finalize_timestep.call_count == 1 assert _delta.log_model_time.call_count == 1 # assert times / counters assert _delta.time_iter == int(1) assert _delta.time == _delta.dt assert _delta.save_time_since_data == _delta._dt assert _delta.save_iter == int(1) assert _delta._save_time_since_checkpoint == _delta._dt # run another step # * should call core steps and outputs _delta.update() # assert calls assert _delta.solve_water_and_sediment_timestep.call_count == 2 assert _delta.apply_subsidence.call_count == 2 assert _delta.finalize_timestep.call_count == 2 assert _delta.log_model_time.call_count == 2 # assert times / counters assert _delta.time_iter == int(2) assert _delta.time == 2 * _delta.dt assert _delta.save_time_since_data == 0 assert _delta.save_iter == int(2) assert _delta._save_time_since_checkpoint == 0 # run another step # should call core, but nothing else _delta.update() # assert calls assert _delta.solve_water_and_sediment_timestep.call_count == 3 assert _delta.apply_subsidence.call_count == 3 assert _delta.finalize_timestep.call_count == 3 assert _delta.log_model_time.call_count == 3 # assert times / counters assert _delta.time_iter == int(3) assert _delta.time == 3 * _delta.dt assert _delta.save_time_since_data == _delta._dt assert _delta.save_iter == int(2) assert _delta._save_time_since_checkpoint == _delta._dt