modelica语言如何实现上一卷回流?

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

当下一个体积的变量x计算小于0时,我想在有限体积中求解相同的方程是一个简单的想法。由于modelica语言的特性,我真的很难实现循环。我希望有人可以帮助我。谢谢!

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;

当时间 > 8s 时,代码无法执行。 Mworks 显示消息:

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

我没有Mworks,只有Dymola。如果我们在 Dymola 中模拟您的代码,我们会收到以下错误消息:

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

仔细查看 x[2] 的等式,我们发现 x[2] < 0

der(x[2]) = - (der(x[1])+x[1]-5) / 0

这源于您的 for 循环中的 elseif,您在其中写入:

elseif noEvent(x[i] < 0) then 
  der(x[i - 1]) = r - x[i - 1];

这里你只使用前一个向量元素的导数,而你在另一个if分支中使用der(x[i])。 modelica 工具需要所有 if 分支中的有效方程。 我的猜测是,它添加了 0 * der(x[i]) 以便能够创建可解方程组。

所以你在 elseif 分支中的等式被工具扩展为

0 * der(x[i]) + der(x[i - 1]) = r - x[i - 1]

方程因果化后我们得到:

der(x[i]) := - (der(x[i - 1]) - r + x[i - 1]) / 0

为了避免被零除,您必须重写 for 循环,以便在 if 语句的每个分支中使用 der(x[i])。这是一个示例:

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;

elseif 分支现在向前看下一个元素。这要求 x 的最后一个元素在单独的方程式中处理,就像您已经对第一个元素所做的那样。

此代码现在可以模拟 8 秒以上,但您的方程似乎有一些问题。 8 秒后什么也没有发生,因为 x[2] 永远不会达到 L。我猜你必须重新考虑方程 der(x[i]) = r - 1 * time(或完整模型)来解决这个问题。

请注意,我还删除了所有 noEvent() 运算符,因为我希望您的模型 运行 更好地处理状态事件。