emulsim.simulation module

Provides a class representing the full simulation.

Simulation

Class defining the simulation state.

SimulationSolver

Solver for element/actor-based simulations.

class Simulation(state: State, actors: Sequence[tuple[str | tuple[str], ActorBase]] | None = None, *, check: str = 'log', profile: bool = False)[source]

Bases: object

Class defining the simulation state.

Parameters:
  • state (State) – The initial simulation state defining the elements in the simulation.

  • actors (sequence, optional) – The actors in the simulation. This should be an iterable returning an (element_names, actor) pair for each item, where element_names is a sequence of all elements this actor affects. All actors are added to the simulation by calling add_actor().

  • check (str) – A flag determining what to do when the chosen elements are not the ones expected by the actor class. Possible options are: ignore (skip checks), warn (using warnings module), log (warn using logging module), or raise (raise a RuntimeError).

  • profile (bool) – Flag indicating whether the simulation should be profiled. If True, the accumulated duration of each actor is recorded during a simulation. The result is available via the timing property of Simulation, which contains the runtime of all actors in seconds.

add_actor(elements: str | tuple[str], actor: ActorBase, *, check: str = 'log')[source]

Adds a new actor to the simulation.

Parameters:
  • elements (str or tuple of str) – The elements this actor acts upon. This needs to have the exact number of elements the actor expects. In the special case of autonomous actors, a single string can be given instead of a tuple with a single entry.

  • actor (ActorBase) – The instance describing the actor.

  • check (str) – A flag determining what to do when the chosen elements are not the ones expected by the actor class. Possible options are: ignore (skip checks), warn (using warnings module), log (warn using logging module), or raise (raise a RuntimeError).

copy(method: Literal['clean', 'shallow', 'data']) Simulation[source]

Returns a copy the entire simulation.

Parameters:

method (str) – Determines whether a clean, shallow, or data copy is performed. See copy() for details.

estimate_dt(state: State | None = None) float[source]

Get the optimal time step for the simulation.

Parameters:

state (State) – A state, which may influence the calculation of the time step

Returns:

the time step

Return type:

float

evolve(state: State, t: float, dt: float) None[source]

Evolve the state from time t to t + dt

Parameters:
  • state (State) – The state of the simulation

  • t (float) – The current time point

  • dt (float) – The time step

get_graph(with_data: bool = True)[source]

Return a graph representation of the simulation.

Parameters:

with_data (bool) – Flag determining whether the element and actor objects are added to the vertices.

Returns:

A graph where all elements and actors are represented as nodes.

Return type:

networkx.DiGraph

get_interacting_elements(with_data: bool = True)[source]

Return a graph representation the interacting elements of a simulation.

Parameters:

with_data (bool) – Flag determining whether the element and actor objects are added to the vertices and edges, respectively.

Returns:

A graph where all elements are represented as nodes and their interactions are represented as edges.

Return type:

networkx.DiGraph

property info: dict[str, Any]

information about the state

Type:

dict

make_evolver_numba(state: State | None = None) Callable[[tuple[ndarray, ...], float, float], None][source]

Return a function evolving the state from time t to t + dt

Parameters:

state (State) – A state defining the degrees of freedom of the simulation.

Returns:

A function with signature (state_data, t: float, dt: float), which evolves the state in time

Return type:

callable

plot_as_graph(layout: str | Callable = 'auto', **kwargs) None[source]

Represent the simulation in a graphical form.

Parameters:
  • layout (str) – Choose a method for determining the layout of the graph. Possible arguments include the names of all nx.*_layout functions.

  • **kwargs – All arguments are passed to networkx.draw()

plot_interacting_elements(layout: str | Callable = 'auto', *, label_edges: bool = True, **kwargs) None[source]

Plot all interacting elements as a graph.

Parameters:
  • layout (str) – Choose a method for determining the layout of the graph. Possible arguments include the names of all nx.*_layout functions or a callable function

  • label_edges (bool) – Flag determining whether the edges are labeled with the actors

  • **kwargs – All arguments are passed to networkx.draw()

run(t_range: TRangeType, dt: float | None = None, tracker: TrackerCollectionDataType = None, *, backend: str = 'auto', ret_info: bool = False, use_cache: bool = False, **kwargs) State | tuple[State, dict[str, Any]][source]

Run the simulation to advance the state in time.

Parameters:
  • t_range (float or tuple of floats) – Sets the time range for which the simulation is run. If only a single value t_end is given, the time range is assumed to be [0, t_end].

  • dt (float) – Time step of the explicit stepping. If None, the time step will be chosen automatically using the method estimate_dt().

  • tracker – Defines trackers that process the state of the simulation at specified times. A tracker is either an instance of TrackerBase or a string identifying a tracker (possible identifiers can be obtained by calling get_named_trackers()). Multiple trackers can be specified as a list. The default tracker simply displays a progress bar. More general trackers are defined in trackers and trackers, where all options are explained in detail. In particular, the time points where the tracker analyzes data can be chosen when creating a tracker object explicitly.

  • backend (str) – Determines how the function is created. Accepted values are ‘numpy` and ‘numba’. Alternatively, ‘auto’ lets the code decide for the most optimal backend.

  • ret_info (bool) – Flag determining whether diagnostic information about the solver process should be returned.

  • use_cache (bool) – Indicates whether a stepper from the cache can also be used. This is disabled by default since there is no check whether the simulation parameters changed. However, using the cache can accelerate a second run of the simulation when the stepper are identical.

  • **kwargs – All additional arguments are forwarded to SimulationSolver

Returns:

The state of the simulation at the last time point. In the case ret_info == True, a tuple with the final state and a dictionary with additional information is returned.

Return type:

SimulationState

class SimulationSolver(simulation: Simulation, *, backend: str = 'auto', adaptive: bool = False, tolerance: float = 0.0001, use_cache: bool = False)[source]

Bases: AdaptiveSolverBase

Solver for element/actor-based simulations.

Initialize the explicit solver for the actor-based simulation.

Parameters:
  • simulation (Simulation) – The simulation that will be run

  • backend (str) – Determines how the simulation is run. Accepted values are numpy and numba. Alternatively, ‘auto’ lets the code use the numba backend if possible and otherwise falls back to the numpy backend

  • adaptive (bool) – When enabled, the time step is adjusted during the simulation using the error tolerance set with tolerance.

  • tolerance (float) – The error tolerance used in adaptive time stepping. This is used in adaptive time stepping to choose a time step which is small enough so the truncation error of a single step is below tolerance.

  • use_cache (bool) – Indicates whether a stepper from the cache can also be used. This is disabled by default since there is no check whether the simulation parameters changed. However, using the cache can accelerate a second run of the simulation when the stepper are identical.

dt_default = 1.0

default time step used when no initial value was specified

Type:

float

dt_max: float = 10000000000.0

maximal time step that the adaptive solver will use

Type:

float

dt_min: float = 1e-10

minimal time step that the adaptive solver will use

Type:

float

make_stepper(state: State, dt: float | None = None) Callable[[State, float, float], float][source]

Return a stepper function using an explicit scheme.

Parameters:
  • state (FieldBase) – An example for the state from which element definitions are extracted.

  • dt (float) – Time step used (Uses SolverBase.dt_default if None). This sets the initial time step for adaptive solvers.

Returns:

Function that can be called to advance the state from time t_start to time t_end. The function call signature is (state: numpy.ndarray, t_start: float, t_end: float)