Today I will share a technique I often use when debugging Simulink models, and more especially Simscape models.
Algebraic Constraint Violated
Did you ever run into the following warning?
Based on my experience, if you get this warning as you are building your model, you better address it immediately. As your model grows larger, this kind of problem can become more difficult to debug, and is likely to return when your model gets more complex.
What does this warning mean?
In many cases, Simulink models are made of Ordinary Differential Equations (ODE). For those, the model computes the derivative of all states, and the solver, for example ode45, integrates each of them almost independently, ensuring they all respect the tolerances specified in the model configuration.
For some models, especially Simscape models, the equations are not a set of ODE, but a set of Differential Algebraic Equations (DAE).
What does this means? This means that in addition to respecting the tolerances specified in the model configuration, the states must also respect algebraic costraints linking them together.
An example DAE can be found in the MATLAB documentation, and looks like:
As you can see, we do not have an equation that computes the derivative of y3 as in a ODE. Instead, we have an equation that algebraically links y3 to y1 and y2.
If the algebraic constraints between the equations of the system are very complex and change very fast, it's possible that Simulink will fail to respect the constraint even when taking the smallest possible step size.
Finding the root cause
Here is what I do when that happens. To begin, launch the Simulink command-line Debugger:
Then I set a time breakpoint just before the warning and start the simulation until it reaches that point:
At this point, I want to enable the maximum level of solver tracing, set a breakpoint on solver errors, and continue:
When the breakpoint is hit, typically I see a large amount of failed steps with the comment "Newton iteration failed to converge". The number next to "Ix", is the index of the state failing to respect the algebraic constraint.
You can get its name using the states command:
The complex algebraic constraint is probably close to this state. In Hydraulic and Pneumatic domains, this is often caused by what we call a "dry node". For example, in the arrangement below, the flow going through the Check Valve and the Directional Valve is algebraically linked. The flow going through the Check Valve must also go through the Directional Valve, there is nowhere else to go. If the Check Valve cracks, or the Directional Valve command change quickly, this algebraic constraint changes over time.
To workaround this situation, you can reduce the solver tolerances to force it to take smaller steps and better capture the changes in the algebraic constraints. Another option is to break the algebraic constraint. In the Hydraulic domain, this is usually done by inserting a Constant Volume Chamber:
I know this method is manual, and not all people are comfortable with the command line debugger, but this has helped me a lot in the past, so I thought I should share. We are working on improving the process for debugging this kind of problem, and I look forward to sharing that with you in the future.
Try this approach and let me know what you think by leaving a comment here.