So here is one of the toughest errors to debug in Dymola:
When a model fails to translate with “Failed to reduce the DAE index” it is usually the start of a very frustrating day. The problem, in this case, is that Dymola needs to differentiate a specific equation but can’t.
Dymola has some fairly powerful symbolic math manipulation built in to turn a model into a system of differential equations that can be integrated through time. As part of that process, equations in the equation section of a model may need to be differentiated. Normally, Dymola handles this seamlessly. Functions, by way of having an algorithm section with procedural code, however, present an obstacle to this automatic differentiation. This is because the result of following a series of steps in an algorithm is not obviously differentiable.
Below is the model which gave the translation error at the start of this post. Its purpose is to simulate, in one dimension, a particle moving sinusoidally with respect to time. The model is very simple, having only 2 variables and 2 equations. The position of the particle is set by a function, and a velocity is calculated outside in the model. To get the velocity, however, Dymola must take a derivative of the ParticlePosition function, and it is in taking that derivative that Dymola trips. This is all valid Modelica syntax, and it checks with no errors or warnings, but it cannot be translated in its current state.
So how do we fix this error? Let me start by saying, the simple solution would be to move the particle path calculation into a block with an equation section. Another solution is to take the two line body of the function, and move it into one line, like so:
In this case, Dymola realizes our algorithm is really a simple equation in disguise and uses a process called function inlining to treat it as such.
When inlining is not an option, Dymola may still be able to symbolically differentiate a function, but it needs assurance that the function is differentiable over all possible input values. In these cases (and the model in Figure 2. is one of them), the smoothOrder annotation may be all that is needed to make the model translate.
There are still situations where a function cannot be symbolically differentiated (such as when running external C code). For arguments sake, let’s pretend this is one of those cases and find a solution.
The Derivative Annotation
To make this model work, we need to tell Dymola that our function is differentiable and that we know what the derivative is. We do this by placing an annotation at the end of our function that gives Dymola the name of a separate function (ParticleVelocity in this case) that Dymola can use as a time derivative.
Here is the implementation of ParticleVelocity:
To satisfy the annotation, the ParticleVelocity function must have the inputs in the same order as the ParticlePosition function, with the derivatives of any real inputs added on the end. In other words, the derivative of
must have these parameters in this order:
derFunction(realParam1, realParam2,… der_realParam1, der_realParam2…)
The ParticleVelocity function was computed with pen and paper using the chain rule and multiplication rule (you remember those, right?). Note that we did not take the easy way out by assuming t is time or amplitude is constant, as that would not be robust if a future developer used the function in a different way.
With these changes, Dymola will happily simulate our model.
A Word of Caution
It is easy to get into trouble when manually specifying derivatives. If the derivative specified is wrong, no warning or error will be issued. Rather, the simulation will just behave in unexpected ways.
Below is the block diagram for a simulation using the Modelica.Mechanics.Translational.Sources.Move block. The move block takes a vector of position, velocity, and acceleration as an input, and moves the translational flange accordingly. Internally, the move block uses functions and derivative annotations to manually specify derivatives, just as we did in the model above. In this model, I have piped three arbitrary signals into a move block, and then put some sensors on a mass attached to the move block’s output flange.
Here are the results of running this model:
The sensors show that the mass is moving linearly, its velocity is zero, and the only force on it is varying sinusoidally. This doesn’t make any physical sense, but it does correspond exactly with the three signals fed into the move block.
There are cases where decoupling derivatives like this is useful. Setting a position, while feeding zero for velocity and acceleration, can be a useful performance optimization in compliance joints, for example. Of course, such an approximation is only valid if the relative velocity and relative acceleration in the joint can be assumed negligible.
Derivative annotations are a way to let Dymola differentiate functions it cannot otherwise differentiate. While it is almost always better to let Dymola differentiate equations symbolically, derivative annotations are occasionally the only way to make a model depending on a function translate successfully. In these cases, they are a necessity and powerful feature of the Modelica language.
Written by: Joseph Henning – Software Engineer