Simulation Module

Define methods to setup a simulation and run it.

Time

Defines a Time object, and a manager to hold the simulation time.

class Time(value: float)

Extend Quantity class to define simulation time.

Whenever the time is updated, it recomputes the difference between the new and the current value and its inverse (accessibles trough the dt and inv_dt properties)

property dt: float

Get the difference between the new and the current value of the time.

Returns:

the delta time value

Return type:

float

property inv_dt: float

Get the inverse of dt.

Returns:

the delta time inverse

Return type:

float

update(new: Any) None

Update the new value of the time and recomputes dt and inv_dt.

Note

If dt is 0.0, inv_dt is set to 0.0.

Parameters:

new (float) – the new value to set

initialize(value: Any) None

Initialize the new and current value.

Note

It set both dt and inv_dt to 0.

Parameters:

value – the value to set

class TimeManager(start: float = 0.0, duration: float = 0.001, step_size: float = 0.001, min_step: float = 6.25e-05)

Updates the time value during the simulation.

Parameters:
  • start (float) – start value for the simulation time.

  • end (float) – end value for the simulation time. The time new and current value can not exceed it.

  • time_step (float) – time increment when update time is called.

  • min_step – minimum allowed value of the time increment.

Raises:

ValueError – ValueError is raised when : * the start parameter is superior to the end parameter. * the time_step parameter is negative.

start: float

The starting time of the time manager.

property min_step: float

Get the minimum time step size allowed.

Returns:

the minimum time step size.

Return type:

float

property end: float

Get the current end time.

Returns:

the end time

Return type:

float

property duration: float

Get the duration.

Returns:

the duration

Return type:

float

property step_size: float

Get the standard step size

Returns:

the standard step size

Return type:

float

property current_step_size: float

Get the current time step size.

Returns:

the time step

Return type:

float

property time: Time

Get the current Time quantity

Returns:

the time quantity

Return type:

Time

property ended: bool

Get if the time has reached the end time.

Returns:

True if the new time value has reached the end time, False otherwise.

Return type:

bool

update_time() None

Set the current time value to the new time value and update the new time value with the defined time step increment.

If the end value is reached, the new time value is set to the end value.

initialize() None

Initialize the time with the start value.

State

Define the State that holds simulation variables.

class State

The State holds the variables names, quantities and indexes during the simulation.

Variables quantity values can be accessed individually with their names or index, or altogether throught the State Vector.

property size: int

Get the total size of the state.

Returns:

the size of the state

Return type:

int

property variables: dict[str, Quantity[Any]]

Get a mapping of variables names and quantities.

Returns:

the variables names and quantities.

Return type:

dict[str, Quantity]

property state_vector: ndarray[tuple[int, ...], dtype[float64]]

Get the vector of the new values of the state variable quantities.

Returns:

the state vector

Return type:

NDArray[np.float64]

get(key: str) Quantity[Any] | None

Get the variable quantity with the given key, or None if it is not registered.

Parameters:

key (str) – the variable key

Returns:

the variable or None

Return type:

Quantity | None

update(mapping: Mapping[str, Any]) None

Update the state variable quantities with the values provided in the mapping.

Note

New variables in the mapping are added to the state while existing variables quantities are initialised to the given value.

Parameters:

mapping (str) – the values to update the state.

property indexes: dict[str, int]

Get a mapping of the variables indexes with their names.

Returns:

the variables indexes ordered by variables ids

Return type:

dict[str, int]

get_variable_index(variable_id: str) int

Get the index of the variable with the given name

Parameters:

variable_id – the variable id

Return type:

str

Returns:

the variable index

Return type:

int

get_variable_size(var_id: str) int

Get the size of the variable with the given name.

Parameters:

var_id – the variable id

Return type:

str

Returns:

the size of the variable

Return type:

int

get_variable_id(var_index: int) str

Get the variable name with the given index.

Parameters:

var_index – the variable index

Return type:

int

Returns:

the variable id

Return type:

str

update_state_vector(x: ndarray[tuple[int, ...], dtype[float64]]) None

Update the new values of the state vector quantities, with the given vector.

Parameters:

x (NDArray[np.float64]) – the vector to set.

Raises:

ValueError – Raise a ValueError when x and the state vector sizes don’t match.

reset_state_vector() None

Set the new values to the current value of the state vector quantities.

set_state_vector(x: ndarray[tuple[int, ...], dtype[float64]]) None

Set the new and current values of the state vector quantities with the given vector.

Parameters:

x (NDArray[np.float64]) – the vector to set.

Raises:

ValueError – Raise a ValueError when x and the state vector sizes don’t match.

add_variable(var_id: str, var_value: Any) None

Add a variable to the state.

Parameters:
  • var_id (str) – the name of the variable

  • value – the initial value of the variable.

remove_variable(var_id: str) None

Remove a variable from the state

Parameters:

var_id (str) – the name of the variable to remove.

Solvers

Declare a generic Solver class and solver implementations

class Solution(x: NDArray[np.float64], converged: bool)

Represent the solution return by a solver.

x: NDArray[np.float64]

the actual solution

converged: bool

get if the solver converged.

exception ConvergenceError

Error raised when the solver did not converged.

class AbstractSolver(tolerance: float = 1e-09, iteration_max: int = 10)

Base class for solvers.

tolerance: float

the solver tolerance

iteration_max: int

the solver maximum allowed number of iterations

abstract solve(state: State, system: EqSystem, magnitudes: dict[str, float] | None = None) Solution

Child classes have to override this method

Returns:

the solution of the solver

Return type:

_Array

class NewtonSolver(tolerance: float = 1e-09, iteration_max: int = 10)

Implementation of the AbstractSolver class using a Newton method.

solve(state: State, system: EqSystem, magnitudes: dict[str, float] | None = None) Solution

Solve the equation system using the Newton method.

Returns:

the solution

Return type:

Solution

Saved Quantities

Define a register to hold SavedQuantities during the simulation.

class SavedQuantities

Register holding saved quantities.

update() None

Update all saved quantities using their Expression object.

register(quantity_id: str, expression: Expression, model: ModelComponent, size: int, index: int) None

Register a Saved Quantity with its expression and model.

Parameters:
  • quantity_id (str) – the global saved quantity name

  • expression (Expression) – the expression to use for the quantity

  • model (ModelComponent) – the model declaring the expression

unregister(quantity_id: str) None

Unregister a saved quantity

Parameters:

quantity_id (str) – the quantity global name to unregister

Functions

Declare base functions to write functions used during the simulation.

class AbstractFunction

Base class for functions that update quantities during the simulation.

abstract eval(*args: Any, **kwargs: Any) Any

Child Functions have to overwrite this method to compute the function result.

is_time_function(tested_function: AbstractFunction) bool

Test if the simulation function needs simulation time parameter.

Parameters:

tested_function (AbstractFunction) – the function

Returns:

True if the function needs time, False otherwise

Return type:

bool

is_state_function(tested_function: AbstractFunction) bool

Test if the simulation function needs the state.

Parameters:

function (AbstractFunction) – the simulation function

Returns:

True if the function needs the state, False otherwise

Return type:

bool

Setup

Defines functions to setup the simulation

SystemExpressions

Type Alias matching a set of Expression objects with their model instance and their line in the residual.

create_models(model_id: str, description: ModelComponentDescription, parameters: dict[str, Quantity[Any]]) dict[str, ModelComponent]

Create a model component instance and its submodels from the given parameters.

Parameters:

parameters (dict[str, Quantity]) – the available quantities

Returns:

a dict containing the created model and all its submodels recursively.

Return type:

dict[str, ModelComponent].

build_state(net: Net) State

Build the state of the simulation from the net description.

Parameters:

net (Net) – the net description

Returns:

the initial state

Return type:

State

build_parameters(net: Net, state: State) dict[str, Quantity[Any]]

Build the initial parameter register from the net description and the initial state.

Parameters:
  • net (State) – the net description

  • net – the state

Returns:

the initial parameter register

Return type:

Parameters

build_eq_system(expressions: SystemExpressions, state: State) EqSystem

Build an EqSystem instance from set of Expression objects.

Parameters:
  • expressions (Expressions) – The expressions representing the system

  • state – the state for the system

Tupe size:

State

Returns:

an equation system initialized with the given expressions

Return type:

EqSystem

build_blocks(net: Net, quantities: dict[str, Quantity[Any]]) dict[str, ModelComponent]

Build all the blocks and their submodels holding the quantities from the net.

Parameters:
  • net (Net) – the net

  • quantities (dict[str, Quantity]) – the simulation quantities

build_saved_quantities(net: Net, models: dict[str, ModelComponent]) SavedQuantities

Create the saved quantities register for the simulation.

Parameters:
  • net (Net) – the simulation net

  • models (dict[str, ModelComponent]) – the models in the simulations

Returns:

the simulation saved quantities

Return type:

SavedQuantities

class SimulationFactory(simulation_type: type[AbstractSimulation], solver: AbstractSolver | None = None, net: Net | None = None, simulation_options: dict[str, Any] | None = None)

Factory for Simulation objects

Parameters:
  • simulation_type (type[AbstractSimulation]) – The simulation type to create

  • net (Net) – the net to initialize the simulation parameters

  • solver (AbstractSolver) – the solver the simulation will use

  • simulation_options (dict[str, Any]) – additional simulation options depending on the simulation type

create_simulation() AbstractSimulation

Create a Simulation instance.

Returns:

a simulation instance.

Return type:

AbstractSimulation

Runtime

Defines the Simulation classes that define how the simulations runs

Parameters

Type alias for quantities collection

Result

Type alias for a single result line

Results

Type alias for all the results of the simulation

class AbstractSimulation(factory: Any, time_manager: TimeManager, state: State, parameters: dict[str, Quantity[Any]], saved_quantities: SavedQuantities, models: dict[str, ModelComponent], solver: AbstractSolver, eq_system: EqSystem, magnitudes: dict[str, float] | None = None)

Base class for Simulations

Note

Use a SimulationFactory instance to instanciate simulations.

Parameters:
  • factory (SimulationFactory) – the factory that created the simulation instance.

  • time_manager (TimeManager) – the simulation time manager

  • solver (AbstractSolver) – the solver to use for simulation steps

  • state (State) – the simulation state

  • parameters (Parameters) – the simulations quantities for parameters.

  • saved_quantities (SavedQuantities) – the Saved Quantities register

  • models (ModelComponent) – the mapping of used models with their names

  • eq_system (EqSystem) – the equation system to solve at each time step

  • magnitudes (dict[str, float]) – magnitude of the state variables

property update_functions: dict[str, AbstractFunction]

Get all functions to update at each time step with their matching quantity global name.

Returns:

the update functions

Return type:

dict[str, AbstractFunction]

property outputs_functions: dict[str, AbstractFunction]

Get all functions that compute the additional output after a time step with their matching output global names.

Returns:

the output functions

Return type:

dict[str, AbstractFunction]

property quantities: dict[str, Quantity[Any]]

Get all the quantities in the simulation from the parameters, the state and the time manager.

Returns:

a dictionary containing all the simulation quantities

Return type:

dict[str, Quantity]

register_timed_parameter_update(parameter_id: str, update_function: AbstractFunction) None

Register a simulation function to update the parameters with the given global name at each time step.

Parameters:
  • parameter_id (str) – the global name of the parameter to update

  • update_function (AbstractFunction) – the function to call to evaluate the parameter value

unregister_timed_parameter_update(parameter_id: str) None

Unegister a simulation function from the timed updates.

Parameters:

parameter_id (str) – the global name of the parameter to unregister.

register_output_function(output_id: str, update_function: AbstractFunction) None

Register a function that is called to compute an additional output.

Parameters:
  • output_id (AbstractFunction) – the global name of the output in the results

  • update_function – the function to compute the output

Raises:

ValueError – Raises a value error when the output id is already defined in the results

unregister_output_function(output_id: str) None

Unregister a function from the outputs updates.

Parameters:

output_id (str) – the global name of the output.

abstract run() list[dict[str, float64 | ndarray[tuple[int, ...], dtype[float64]]]]

Run the simulation, this method should be implemented in child classes.

Returns:

the list of solution for each time step

Return type:

list[NDArray[float64]]

class ForwardSimulation(factory: Any, time_manager: TimeManager, state: State, parameters: dict[str, Quantity[Any]], saved_quantities: SavedQuantities, models: dict[str, ModelComponent], solver: AbstractSolver, eq_system: EqSystem, magnitudes: dict[str, float] | None = None)

Extend AbstractSimulation class to define a Forward Simulation.

The forward simulation solve the Equation System at each time step using the simulation Solver.

If the solver did not converge at a given time step, it breaks the current time step into smaller steps and try again. If it still do not converge, it recursivly breaks the current time steps again and stops if the time step is under the minimum time step allowed by the time manager.

When finding a solution for a reduced time step, the simulation then tries to solve for the remaining time interval in the current time step.

Note

When breaking a simulation step, the forward simulation still only provide a result for the time step interval given to the time manager.

run() list[dict[str, float64 | ndarray[tuple[int, ...], dtype[float64]]]]

Solve the system for each time steps.

Returns:

the list of solution for each time step

Return type:

list[NDArray[float64]]

Raises:

SimulationError – raise a Simulation Error holding the current results if the simulation stops before reaching the end time.

exception SimulationError(message: str, intermediate_results: list[dict[str, float64 | ndarray[tuple[int, ...], dtype[float64]]]], *args: Any, **kwargs: Any)

Error raised when the simulation encounter a problem.

intermediate_results: list[dict[str, float64 | ndarray[tuple[int, ...], dtype[float64]]]]

Results obtained before the simulation error occured