Let's say I have a simple model with a control loop:
If the plant model is direct feedthrough, this will result in an algebraic loop. While Simulink can solve the algebraic loop most of the time, it usually slows down the simulation, and when the solve fails to converge it can lead to errors like this:
Breaking the loop with a Memory Block
To break the algebraic loop, you need to insert in the loop a nondirect feedthrough block. The first thing most users think about is a Unit Delay or Memory block.
If the blocks in the algebraic loop have a discrete sample time, inserting a Unit Delay is usually the best solution. Of course this will change the dynamic of the system, this is something you need to evaluate and see if this is acceptable for your application.
If the blocks in the loop have a continuous sample time, what many users try is inserting a Memory block. The Memory block is similar to the Unit Delay block in a sense that it delays its input by one time step, however it works with variable-step signals. Let's see what it does for our model.
At least, now the model simulates to completion and we can look at the results:
However when simulating the model, we quickly notice that it simulates very slowly. If I log data from the model, I can see that it takes more than 500,000 steps to simulate this model for two seconds!
If we plot the steps taken by the variable-step solver, we can see that after the step input, the solver begins to take steps of about 1e-6 seconds and gets stuck there.
Why is it happening? This is because the output of the Memory block is not continuous, and it is driving a block with continuous states, the State-Space block. Every time the output of the Memory block changes, the solver needs to reset, forcing the small step size that we observe. We know that this situation is problematic and we have a Model Advisor check for that: Check for non-continuous signals driving derivative ports
The Solution: Breaking the Loop using a Transfer Function block
As suggested by the Model Advisor, the recommended way to break this algebraic loop is to use a continuous block. The one I typically prefer is a first order Transfer Function. Like the Memory block, this will introduce a new dynamic in the system. The trick is to make the time constant of the Transfer Function small enough to not affect the dynamics of the system significantly. In this case, I used 1e-6.
With this change, the model gives similar results, but the simulation completes almost instantly, taking only 633 time steps:
Now it's your turn
If you have experiences or suggestions on how to handle algebraic loops, let us know by leaving a comment here.
*** Important Update ***
After publishing this post, a few users contacted me mentioning that some Simulink demos use a Memory block to break algebraic loops. I consequently decided to add this update to highlight the fact that breaking an algebraic loop with a Memory block is problematic only when the loop is continuous. Let's look at a few of those examples and explain why, because the loops are not continuous, it is ok to break them with a Memory block.
sldemo_clutch: In this model, the following pattern is used in the clutch logic:
You can notice that I enabled the port data type and sample time displays to highlight that this loop take a fixed-in-minor-steps sample time, and the data type of the signals involved is boolean. This subsystem implements a discrete combinatorial logic deciding if the clutch should be locked or not depending on two inputs and it's previous state. Since the loop is discrete, the Memory block is the way to go.
sldemo_bounce: In this model, we can see that an algebraic loop is broken by a Memory block:
At first look, this loop has a continuous sample time and is of data type double. So why am I not considering it continuous? Because of when the loop is actually active. Let's look at the logic here. First, we need to note that the Integrator is configured to reset dx/dt when x reaches saturation:
As soon as the Integrator enters the saturation, we want to apply a new velocity that is 80% of the velocity when it entered the saturation, but in opposite direction, to take it out of the saturation. This means that the output of the loop is not used continuously by the Integrator. It is used only for one time step, at a discontinuity, when entering the saturation triggers a zero-crossing event.
I hope those clarification makes it clearer that when I recommend breaking algebraic loops with transfer functions, I am talking about continuous algebraic loops, where (if a Memory block was used) the output of the Memory block would drive a derivative port as can be detected by the Model Advisor check mentioned above.
14 CommentsOldest to Newest
Whether this memory block will cause any issue if i use fixed step solver.
I also want ask the same question: Whether this memory block will cause any issue if i use fixed step solver?
Is it possible to get the model parameters (Controller gain, state-space parameters) of the first example?
Thanks for the interest in this post. I placed a ZIP-file with the models used in this post here:
About the fixed-step question. The impact of using a Memory or Unit Delay to break an algebraic loop that is originally made of continuous values and sample time is less significant for a fixed-step solver than a variable-step solver.
However I still recommend a Transfer Function. The reason is that continuous solvers take minor steps and expect the signals to be continuous during those minor steps. Using a discrete block like Memory or Unit Delay will introduce discontinuities in the minor steps, typically a stairs pattern. A Transfer Function will keep the entire loop continuous, making the results more accurate.
You can observe the data during the minor steps using my MATLAB Central submission here:
using an IC (initial condition) block from “Signal Attribute” library of simulink can easily help and solve the problem.
Thanks for the informative article. One thing I wanted to point out is that the transfer function fix is not always straightforward to implement. For example, if using a FixedStep solver at a rate that is just fast enough to capture the relevant dynamics of a system, then any transfer function used to resolve the algebraic loop will alter the true dynamic response of the system. In cases like this, I have implemented a simple algebraic-loop-solver using a while iterator block or a MATLAB Function block.
I’d be curious to hear thoughts on this approach. Any other ideas for resolving algebraic loop when transfer functions aren’t possible because of their effects on the system dynamics?
Thanks Matt. I agree with you. In many cases algebraic loops happen when a a component in the model is modeled in a too simplified way. For example not including the dynamic response of a sensor.
However in other cases the system needs to be modeled by differential algebraic equation (DAE). In this case you need to solve those algebraic constraints, and this has a cost.
Simulink includes an algebraic loop solver that can solve those constraints, so in general you do not need to implement your own solver. However, if for any reason you want to, it is possible using an Iterator Subsystem or the MATLAB Function block as you describe. Here is an example of how this can work:
For acausal systems intrinsically involving algebraic constraints, we recommend modeling using Simscape, which is especially designed to solve such problem.
I have used the memory block to break the algebraic loop in my application which contain a state chart. As you know to make a transistion between two modes, it’s mandatory to initialize the signal input of the chart after every transition from mode to another, because the value of transition condition can be attainable a once.
I encounter a problem.The application doesnt work as expected because the memory memorise the latest signal value. So the transition can’t be valid. How can I solve this problem or how can I break the loop in other way.
Thank you for your help in advance.
Thanks for this article, but you’ve just told me with the attached link what i should’nt do, but i’d like to know also, what I’ll must do in order to break correctly my algebraic loop, please I would appreciate your answer.
Hi guys, i’m changing the memory block for the tranfer fcn block in my model, but i have this error,
An error occurred while running the simulation and the simulation was terminated
Derivative of state ‘1’ in block ‘New_MEC2EA_PandO_paso_FIJO/Baterias24V 3MIL 25 S /Battery4/Model/Current filter’ at time 0.0 is not finite. The simulation will be stopped. There may be a singularity in the solution. If not, try reducing the step size (either by reducing the fixed step size or by tightening the error tolerances)
Can you help me to solve this?.
@Tony Castillo: My first guess is that you have a division by zero, causing a NaN or Inf to enter a the filter block, which has continuous states. I would recommend using the Simulink debugger and the “nanbreak” function to see where this originates.
There is also a diagnostic in the model configuration to trigger an error when a division by zero happens.
The computing performance Guy refers to is a minor issue IMO. A more significant issue is the incorrect results that are easily obtained. Do mind that the step size may be determined of other parts of the model and hence your model may create from time to time different results due to parameter changes somewhere else. Using a memory block for solving an algebraic loop is a disqualified technique. Basically an algebraic loop is a bug and you’d rather treat it as such. In the above example you will have to adjust the A, B, C and D matrices to obtain the correct results. More difficult ones may incur remodeling the entire system. For that reason a-causal languages are preferred for physical modeling mitigating the algebraic loop issue. However, using a transfer function in the feedback loop can be made physical plausible in some cases.
Does anyone have thoughts with regard to using the transport delay block as a sort of “memory” block for the continuous system? This also introduces dynamic differences, which can be negligible provided the delay time is significantly smaller than relevant dynamics, but it does not, in my investigations, appear to significantly increase solver time.
This is a good point. The Transport Delay is appropriate to break such loop. The main point is that a Transfer Function or a Transport Delay will introduce a delay that is not function of the solver step size.