Reputation: 23
It is a simple idea that I Want to solve the same equations in a finite volume when the variable x of next volume is computed smaller than 0. Because the characteristic of the modelica language, it is really hard for me to realise the loop. I hope someone can help me with this. Thanks!
model Model
parameter Real L = 10;
parameter Real r = 5;
parameter Integer N = 20;
Real x[N](each start = 0);
equation
if noEvent(x[1] >= 0 and x[1] < L) then
der(x[1]) = r;
else
der(x[1]) = 0;
end if;
for i in 2:N loop
if noEvent(x[i - 1] >= L and x[i] >= 0 and x[i] < L) then
der(x[i]) = r - 1 * time;
elseif noEvent(x[i] < 0) then
der(x[i - 1]) = r - x[i - 1];
else
der(x[i]) = 0;
end if;
end for;
end model;
The code just can not dostep when time > 8s. And the Mworks show the message:
...
Error: Failed to solve linear system at Time = 7.99999989157494
Error: Failed to solve linear system at Time = 7.99999989157489
Error: Failed to solve linear system at Time = 7.99999989157489
Upvotes: 1
Views: 91
Reputation: 6645
I have no Mworks, but Dymola. If we simulate your code in Dymola, we get the following error message:
Error: The following error was detected at time: 7.99999999711724
Error: Singular inconsistent scalar system for
der(x[2]) = ( -(if x[1] >= 10 and x[2] >= 0 and x[2] < 10 then 1*time-5 else (if x[2] < 0 then der(x[1])+x[1]-5 else 0.0)))/((if x[1] >= 10 and x[2] >= 0 and x[2] < 10 then 1.0 else (if x[2] < 0 then 0.0 else 1.0))) = -5/0
Looking in detail at the equation for x[2]
, we see that for x[2] < 0
we have
der(x[2]) = - (der(x[1])+x[1]-5) / 0
This originates from the elseif in your for loop, where you write:
elseif noEvent(x[i] < 0) then
der(x[i - 1]) = r - x[i - 1];
Here you only use the derivative of the previous vector element, while you are using der(x[i])
in the other if branches.
The modelica tool needs valid equations in all if branches.
My guess is, that it adds 0 * der(x[i])
to be able to create a solvable equation set.
So your equation in the elseif branch is extended by the tool to
0 * der(x[i]) + der(x[i - 1]) = r - x[i - 1]
And after causalization of the equations we get:
der(x[i]) := - (der(x[i - 1]) - r + x[i - 1]) / 0
To avoid the division by zero, you have to rewrite your for loop such that you are using der(x[i])
in every branch of the if statement. Here is an example how this could look like:
model Model2
parameter Real L = 10;
parameter Real r = 5;
parameter Integer N = 20;
Real x[N](each start = 0);
equation
if x[1] >= 0 and x[1] < L then
der(x[1]) = r;
else
der(x[1]) = 0;
end if;
for i in 2:N-1 loop
if x[i - 1] >= L and x[i] >= 0 and x[i] < L then
der(x[i]) = r - 1 * time;
elseif x[i+1] < 0 then
der(x[i]) = r - x[i];
else
der(x[i]) = 0;
end if;
end for;
if x[N - 1] >= L and x[N] >= 0 and x[N] < L then
der(x[N]) = r - 1 * time;
else
der(x[N]) = 0;
end if;
end Model2;
The elseif branch now looks ahead at the next element. This requries that the the last element of x
is handled in seperate equations, like you already do with the first one.
This code now simulates beyond 8s, but there seem to be some troubles with your equations. Nothing is happening after 8s, because x[2]
never reaches L
. I guess you have to rethink the equation der(x[i]) = r - 1 * time
(or the complete model) to solve that.
Note that I also removed all the noEvent()
operators, because I expect your model to run better with state events.
Upvotes: 2