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()
运算符,因为我希望您的模型 运行 更好地处理状态事件。
当下一个体积的变量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()
运算符,因为我希望您的模型 运行 更好地处理状态事件。