landlab.core.component_utils

iter_adaptive_time_steps(duration, *, calc_dt, max_steps=None, rtol=1e-12)[source]

Yield adaptive time steps that advance up to a requested duration.

Repeatedly call calc_dt to obtain the next stable time-step size, capping each step so that the total does not exceed duration. Note that iteration may stop within the tolerance specified by rtol.

Parameters:
  • duration (float) – Total amount of time to advance.

  • calc_dt (callable) – Called with no arguments before each substep to obtain the current stable time-step size. A return value of None signals that iteration should be stopped before duration is reached. A return value of inf advances to duration.

  • max_steps (int, optional) – Maximum number of substeps to yield before raising a RuntimeError.

  • rtol (float, optional) – Stop once the remaining time is no greater than rtol * duration. Consequently, the yielded time steps may sum to slightly less than duration.

Yields:

float – The next time-step size.

Raises:
  • ValueError – If duration or rtol are out of range.

  • RuntimeError – If max_steps is exceeded, or if a returned step is either invalid or is too small, relative to the elapsed time, to make further progress.

Return type:

Iterator[float]

Examples

>>> from landlab.core.component_utils import iter_adaptive_time_steps
>>> steps = iter([2.0, 2.0, 2.0, 1.0])
>>> list(iter_adaptive_time_steps(7.0, calc_dt=lambda: next(steps)))
[2.0, 2.0, 2.0, 1.0]

Return None from calc_dt to stop before duration is reached.

>>> steps = iter([2.0, 2.0, None])
>>> list(iter_adaptive_time_steps(10.0, calc_dt=lambda: next(steps)))
[2.0, 2.0]
>>> list(iter_adaptive_time_steps(10.0, calc_dt=lambda: 3.0))
[3.0, 3.0, 3.0, 1.0]
iter_time_steps(duration, *, dt=None)[source]

Yield fixed-size time steps that evenly span a requested duration.

Split duration into equally-sized substeps, so that no substeps are longer that dt.

Parameters:
  • duration (float) – Total amount of time to advance.

  • dt (float, optional) – Maximum time-step size. If not given, use duration as a single time step.

Yields:

float – The next time-step size.

Raises:

ValueError – If duration is negative, or if dt is not finite and positive.

Return type:

Iterator[float]

Examples

>>> from landlab.core.component_utils import iter_time_steps
>>> list(iter_time_steps(10.0, dt=2.5))
[2.5, 2.5, 2.5, 2.5]

A duration that doesn’t divide evenly is split into equal substeps, each no longer than dt, rather than leaving a short final step.

>>> list(iter_time_steps(10.0, dt=3.0))
[2.5, 2.5, 2.5, 2.5]

If dt isn’t given, duration is used as a single time step.

>>> list(iter_time_steps(5.0))
[5.0]