gordon
gordon

Reputation: 23

How to realise the backflow from one volume to the upper volume by modelica language?

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

Answers (1)

marco
marco

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 xis 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

Related Questions