Skip to content

System Dynamics

The behavior of a model is defined by system dynamics, which can be one or more functions, Model instances, or combinations thereof. The main purpose of dynamics is to define how the state of a model changes over time, based on the current time, state, inputs and parameters. Not all dynamics need to calculate state changes; dynamics can also calculate intermediate values or other outputs.

A dynamics function has the following signature, where time is the current time as a float, state is a dictionary mapping state component labels to their current values, inputs is a dictionary mapping input labels to their current values, and parameters is a dictionary mapping parameter names to their values. Any of the arguments can be omitted if they are not necessary. No other arguments should be included.

def dynamics_function(time, state, inputs, parameters):
    ...

The return value is a dictionary mapping name of the derivatives of the state components to their calculated values.

Example: forced oscillator

An example of dynamics that calculates the acceleration of a forced oscillator is shown below. The model is mathematically described as:

\[\frac{d^2x}{dt^2} = \frac{1}{m} \cdot \left[ -kx -b\frac{dx}{dt} + F_0 \sin\left(\omega t\right) \right]\]
    def update_forced_oscillator(state, inputs, parameters):
        acceleration = (
            -parameters["k"] * state["position"]
            - parameters["b"] * state["velocity"]
            + inputs["force"]
        ) / parameters["m"]
        return {
            "acceleration": acceleration,
            "velocity": state["velocity"],
        }

This model's state has two components: the current position (\(x\)), and the current velocity (\(\frac{dx}{dt}\)). The model has a single input: the external force \(F_0 \sin \left( \omega t \right)\). Three parameters describe the rest of the model: the restoring constant \(k\), the damping coefficient \(b\), and the mass \(m\). The acceleration is calculated from the state, input and parameters.

The full example can be found here

Example: constant rate of change

As an extreme example, minimalist dynamics that just returns a constant rate of change for a state could be defined without any arguments:

def constant_rate_of_change():
    return {"position_change": 5.0}  # constant rate of change of 5 units per time unit