Defining a system of ODEs
The primary goal of the DiffSL language is to define a system of ODEs in the following form:
$$ \begin{align*} M(t) \frac{\mathrm{d}\mathbf{u}}{\mathrm{d}t} &= F(\mathbf{u}, t) \\ \mathbf{u}(0) &= \mathbf{u}_0 \end{align*} $$
where \( \mathbf{u} \) is the vector of state variables, \( \mathbf{u}_0 \) is the initial condition, \( F \) is the RHS function, and \( M \) is the mass matrix. The DSL allows the user to specify the state vector \( \mathbf{u} \) and the RHS function \( F \).
Optionally, the user can also define the derivative of the state vector \( \mathrm{d}\mathbf{u}/\mathrm{d}t \) and the mass matrix \( M \) as a function of \( \mathrm{d}\mathbf{u}/\mathrm{d}t \) (note that this function should be linear!). The user is also free to define an arbitrary number of intermediate tensors that are required to calculate \( F \) and \( M \).
Defining state variables
To define the state variables \(\mathbf{u} \), we create a special
vector variable u_i
. Note the particular name u
is used to indicate that this
is the state vector.
The values that we use for u_i
are the initial values of the state variables
at \( t=0 \), so an initial condition \( \mathbf{u}(t=0) = [x(0), y(0), z(0)] = [1, 0, 0] \) is defined as:
u_i {
x = 1,
y = 0,
z = 0,
}
Since we will often use the individual elements of the state vector in the RHS function, it is useful to define them as separate variables as well.
We can optionally define the time derivatives of the state variables, \( \mathbf{\dot{u}} \) as well:
dudt_i {
dxdt = 1,
dydt = 0,
dzdt = 0,
}
Here the initial values of the time derivatives are given. In many cases any values can be given here as the time derivatives of the state variables are calculated from the RHS. However, if there are any algebraic variables in the equations then these values can be used used as a starting point to calculate a set of consistent initial values for the state variables.
Note that there is no need to define dudt
if you do not define a mass matrix \( M \).
Defining the ODE system equations
We now define the right-hand-side function \( F \) that we want to solve, using the
variables that we have defined earlier. We do this by defining a vector variable
F_i
that corresponds to the RHS of the equations.
For example, to define a simple system of ODEs:
$$ \begin{align*} \frac{dx}{dt} &= y \\ \frac{dy}{dt} &= -x \\ x(0) &= 1 \\ y(0) &= 0 \\ \end{align*} $$
We write:
u_i { x = 1, y = 0 }
F_i { y, -x }
Defining the mass matrix
We can also define a mass matrix \( M \) by defining a vector variable M_i
which is the product of the mass matrix with the time derivative of the state vector \( M \mathbf{\dot{u}} \).
This is optional, and if not defined, the mass matrix is assumed to be the identity
matrix.
Notice that we are defining a vector variable M_i
, which is the LHS of the ODE equations \( M \mathbf{\dot{u}} \), and not the mass matrix itself.
For example, lets define a simple DAE system using a singular mass matrix with a zero on the diagonal:
$$ \begin{align*} \frac{\mathrm{d}x}{\mathrm{d}t} &= x \\ 0 &= y-x \\ x(0) &= 1 \\ y(0) &= 0 \\ \end{align*} $$
We write:
u_i {
x = 1,
y = 0,
}
dudt_i {
dxdt = 0,
dydt = 1,
}
M_i {
dxdt,
0,
}
F_i {
x,
y-x,
}