Skip to content

Events and operating protocols

Events interrupt a solve, either stopping it before the end of the interval or rewriting its state and continuing. See events.

diff_soup.Event

A condition that stops a solve, or rewrites its state and continues, when it fires.

Pass it, or an EventSet, as event= to pdesolve. Without a root_finder the condition is read as a boolean at the end of each accepted step, and with one its sign change is located inside the step.

Parameters:

Name Type Description Default
cond_fn Callable

cond_fn(t, y, args, *, control=None), returning a boolean, or a real scalar for a continuous event.

required
affect Optional[Callable]

affect(t, y, args, control) returning (y_new, control_new), or None to stop the solve at the event.

None
root_finder Optional[Any]

Root finder that locates a continuous crossing, for example Bisection().

None
direction Literal['up', 'down', 'any']

Crossing that fires a continuous event, "up" (negative to positive), "down", or "any".

'any'
state_policy Any

A DenseOutputPolicy whose "projected" mode projects mid-step states onto the algebraic constraints, and needs a root_finder.

None

diff_soup.timestepping.EventSet

Several events checked together in one solve.

When several fire in one step the earliest wins, and declaration order breaks ties.

Parameters:

Name Type Description Default
events tuple[Event, ...]

Tuple of Event objects.

required

diff_soup.timestepping.EventObservable

A scalar function of the state that builds event conditions.

crosses gives a condition for a continuous event, and below and above give boolean ones.

Attributes:

Name Type Description
fn Callable

The scalar function fn(t, y, args).

crosses

crosses(level: float) -> Callable

Return the real-valued condition fn(t, y, args) - level for a continuous event.

Parameters:

Name Type Description Default
level float

Level whose crossing fires the event.

required

Returns:

Type Description
Callable

A condition for Event(cond_fn=...), which needs a root_finder.

below

below(level: float) -> Callable

Return a boolean condition, true while fn(t, y, args) < level.

Parameters:

Name Type Description Default
level float

Threshold.

required

Returns:

Type Description
Callable

A condition for a discrete Event.

above

above(level: float) -> Callable

Return a boolean condition, true while fn(t, y, args) > level.

Parameters:

Name Type Description Default
level float

Threshold.

required

Returns:

Type Description
Callable

A condition for a discrete Event.

soc classmethod

soc(fn: Callable) -> 'EventObservable'

Wrap a state-of-charge function, the same as EventObservable(fn=fn).

Parameters:

Name Type Description Default
fn Callable

The function fn(t, y, args).

required

Returns:

Type Description
'EventObservable'

An EventObservable.

voltage classmethod

voltage(fn: Callable) -> 'EventObservable'

Wrap a voltage function, the same as EventObservable(fn=fn).

Parameters:

Name Type Description Default
fn Callable

The function fn(t, y, args).

required

Returns:

Type Description
'EventObservable'

An EventObservable.

diff_soup.timestepping.terminate_steady_state

terminate_steady_state(rtol: float, atol: float, norm: Optional[Callable] = None) -> Event

Return a terminating event that fires once norm(f) < atol + rtol * norm(y).

The condition reads f from a residual_fn keyword, or else from args, as a function args(t, y), a sequence starting with one, or the vector itself.

Parameters:

Name Type Description Default
rtol float

Relative tolerance.

required
atol float

Absolute tolerance.

required
norm Optional[Callable]

Norm of a vector, the root mean square when None.

None

Returns:

Type Description
Event

A discrete Event with no affect.

diff_soup.timestepping.Bisection

Root finder that locates an event crossing by bisection on the step's interval.

It runs a fixed number of halvings, set by rtol and capped by max_iters_cap, so it works under jit and vmap.

Parameters:

Name Type Description Default
rtol

Tolerance relative to the bracket width, which sets the number of halvings.

required
atol

Absolute time tolerance that JNDF, JBDF, and JIDA use to match the crossing against other crossings and save times.

required
max_iters_cap

Upper bound on the number of halvings.

required

Operating protocols

A Schedule of Segments runs an experiment through rows of the operating table in turn, and ControlState carries the controls through a solve (controls).

diff_soup.Schedule dataclass

An operating protocol, a sequence of segments run one after another.

Each segment starts where the one before it ended. Pass the schedule as schedule= on ds.inference.Experiment.

Parameters:

Name Type Description Default
segments Any

Sequence of at least one Segment.

required
carry_step Optional[bool]

Whether each segment keeps the step size and history of the one before, with None keeping them only when the mode is unchanged.

None

diff_soup.Segment dataclass

One step of a Schedule, holding one row of the operating table at a target for a duration.

Pass exactly one of current, voltage, or power. A tuple target is a polynomial in the time since the segment started, constant term first. All values are concrete numbers, built outside jax.jit.

Parameters:

Name Type Description Default
current Any

Target of the current row.

None
voltage Any

Target of the voltage row.

None
power Any

Target of the power row.

None
duration Any

Positive length of the segment.

required

diff_soup.ControlState

The control values a solve carries, with an epoch that counts their changes.

Pass one as control_state0= to a solve. On a problem with an operating table, ControlState.operating builds it, and an affect event returns its update.

Attributes:

Name Type Description
values Any

Control mapping, or None.

epoch Array

Number of control changes so far, an int32 scalar starting at zero.

mode Optional[Array]

Index of the active row of the operating table, or None.

target Optional[Array]

Value the active row drives to, or None outside an operating protocol.

values instance-attribute

values: Any

epoch instance-attribute

epoch: Array

mode class-attribute instance-attribute

mode: Optional[Array] = None

target class-attribute instance-attribute

target: Optional[Array] = None

is_operating property

is_operating: bool

Whether this state carries an operating mode and target.

operating classmethod

operating(*, mode: Union[int, str, Array], target: Any, current_seed: Any = None, values: Any = None, target_terms: Any = None, target_origin: Any = None) -> 'ControlState'

Build the state of an operating protocol, an active row and its target, at epoch zero.

Parameters:

Name Type Description Default
mode Union[int, str, Array]

Index of the active row in the operating table, or its name.

required
target Any

Float scalar the active row drives to.

required
current_seed Any

Float scalar starting value of the current unknown, or None.

None
values Any

Control mapping carried alongside, or None.

None
target_terms Any

Coefficients of tau, tau**2, and so on, added to target, with tau the time since target_origin.

None
target_origin Any

Time that tau counts from, given together with target_terms.

None

Returns:

Type Description
'ControlState'

A ControlState with epoch zero.

target_at

target_at(t: Any) -> jax.Array

Return the target at time t, with the polynomial terms added when present.

Parameters:

Name Type Description Default
t Any

Time.

required

Returns:

Type Description
Array

The target as a scalar array.

bump

bump() -> 'ControlState'

Return a copy with the epoch advanced by one.

with_values

with_values(values: Any) -> 'ControlState'

Return a copy with new control values and the epoch advanced by one.

Parameters:

Name Type Description Default
values Any

The new control mapping.

required

Returns:

Type Description
'ControlState'

The updated ControlState.

with_operating

with_operating(*, mode: Optional[Union[int, Array]] = None, target: Any = None, current_seed: Any = None) -> 'ControlState'

Return a copy with a new mode or target, advancing the epoch only when either changes.

Use it in an affect event to switch rows mid-solve. It needs an operating state whose mode is an integer index.

Parameters:

Name Type Description Default
mode Optional[Union[int, Array]]

New row index, or None to keep the mode.

None
target Any

New float target, or None to keep it.

None
current_seed Any

New starting value of the current unknown, or None to keep it.

None

Returns:

Type Description
'ControlState'

The updated ControlState.