模型从管道流出
Model flow from a pipe
我一直在尝试模拟通过管道的流量,该管道在 Modelica 中可以部分充满,也可以完全充满,在 OpenModelica 中 运行。我最终将示例简化为基本上只使用圆的面积,并且在它充满之前没有流出,然后完全流出。但是,我仍然遇到错误。我尝试了几种不同的方法。一旦管道变为 "filled up",第一种方法给出了求解非线性系统的错误。相反,我希望它切换:
model SimplePipe1
Modelica.SIunits.Area A;
Modelica.SIunits.Mass mass;
Modelica.SIunits.Height level(start = 0.5, fixed = true, min = 0.0, max = 2 * R) "Liquid level (m)";
parameter Modelica.SIunits.Radius R = 1.0 "pipe inner radius (m)";
parameter Real flow_in = 1.0;
Real flow_out;
Modelica.SIunits.Angle phi(start = 3.1, min = 0.0, max = 7.2832) "Angle from center to surface level";
Modelica.SIunits.Area A;
Modelica.SIunits.Mass mass;
Modelica.SIunits.Height level(start = 0.5, fixed = true, min = 0.0, max = 2 * R) "Liquid level (m)";
parameter Modelica.SIunits.Radius R = 1.0 "pipe inner radius (m)";
parameter Real flow_in = 1.0;
Real flow_out;
Modelica.SIunits.Angle phi(start = 3.1, min = 0.0, max = 7.2832) "Angle from center to surface level";
equation
mass = A;
//Assume unit length pipe and unit density
flow_in + flow_out = der(mass);
A = 0.5 * R ^ 2 * (phi - sin(phi));
// phi = if noEvent(level <= 0) then 0 elseif noEvent(level >= 2 * R) then 2 * Modelica.Constants.pi else 2 * acos((R - level) / R);
if noEvent(level <= 0) then
phi = 0;
flow_out = 0;
elseif noEvent(level >= 2 * R) then
phi = 2 * Modelica.Constants.pi;
flow_out = -flow_in;
else
flow_out = 0;
//Partially full pipe has no out outflow
phi = 2 * acos((R - level) / R);
end if;
annotation(Icon, Diagram, experiment(StartTime = 0, StopTime = 10, Tolerance = 1e-06, Interval = 0.02));
end SimplePipe1;
这个版本似乎给出了更接近我想要的结果,但还是不行。在这种情况下,问题是 phi 应该限制为 2*pi。反而不断增加。同时,我实际上并没有看到 flowmode 发生变化。我确实看到流出在一个周期内变为负值,然后跳回零。我不明白是什么将流模式从通道改回完整,因为没有相应的 "when" 将其改回。
model SimplePipe2
type modetype = enumeration(empty, full, channel);
modetype flowmode(start = modetype.channel);
Modelica.SIunits.Area A;
Modelica.SIunits.Mass mass;
Modelica.SIunits.Height level(start = 0.5, fixed = true, min = 0.0, max = 2 * R) "Liquid level (m)";
Modelica.SIunits.Height level_limit;
parameter Modelica.SIunits.Radius R = 1.0 "pipe inner radius (m)";
parameter Real flow_in = 1.0;
Real flow_out;
Modelica.SIunits.Angle phi(start = 3.1, min = 0.0, max = 7.2832) "Angle from center to surface level";
Real flow_out;
initial equation
flowmode = modetype.channel;
equation
mass = A;
//Assume unit length pipe and unit density
flow_in + flow_out = der(mass);
A = 0.5 * R ^ 2 * (phi - sin(phi));
cos(phi / 2) = (R - level) / R;
if flowmode == modetype.empty then
flow_out = 0;
elseif flowmode == modetype.full then
flow_out = -flow_in;
else
flow_out = 0;
//Partially full pipe has no out outflow
end if;
when noEvent(phi >= 2 * Modelica.Constants.pi) then
reinit(flow_out, -flow_in);
reinit(level, 2 * R);
flowmode = modetype.full;
end when;
annotation(Icon, Diagram, experiment(StartTime = 0, StopTime = 10, Tolerance = 1e-06, Interval = 0.02));
end SimplePipe2;
This question that I asked is related to solving the same problem, but doesn't have the issue of a circle/cylinder. And, my second example above is based somewhat on this question.
我正在使用 OpenModelica 的最新测试版。我的完整模型将具有这些示例中未包含的其他功能。但是,希望如果我能让这个简单的版本工作,我可以从那里扩展。
您的代码以 phi 的非线性方程结束(在 level_limit 和一个 flow_out 从模型中删除之后)。
0 = 0.5 * R ^ 2.0 * (phi - sin(phi)) - mass
OM 在不为变量 phi 添加约束的情况下解决了这个问题。而是在找到解决方案后检查断言。如果您在 OpenModelica 中使用 non-linear solver=kinsol,约束将添加到非线性方程中,但在这种情况下无济于事。我也有点不确定 when noEvent()
是否会触发。
我一直在尝试模拟通过管道的流量,该管道在 Modelica 中可以部分充满,也可以完全充满,在 OpenModelica 中 运行。我最终将示例简化为基本上只使用圆的面积,并且在它充满之前没有流出,然后完全流出。但是,我仍然遇到错误。我尝试了几种不同的方法。一旦管道变为 "filled up",第一种方法给出了求解非线性系统的错误。相反,我希望它切换:
model SimplePipe1
Modelica.SIunits.Area A;
Modelica.SIunits.Mass mass;
Modelica.SIunits.Height level(start = 0.5, fixed = true, min = 0.0, max = 2 * R) "Liquid level (m)";
parameter Modelica.SIunits.Radius R = 1.0 "pipe inner radius (m)";
parameter Real flow_in = 1.0;
Real flow_out;
Modelica.SIunits.Angle phi(start = 3.1, min = 0.0, max = 7.2832) "Angle from center to surface level";
Modelica.SIunits.Area A;
Modelica.SIunits.Mass mass;
Modelica.SIunits.Height level(start = 0.5, fixed = true, min = 0.0, max = 2 * R) "Liquid level (m)";
parameter Modelica.SIunits.Radius R = 1.0 "pipe inner radius (m)";
parameter Real flow_in = 1.0;
Real flow_out;
Modelica.SIunits.Angle phi(start = 3.1, min = 0.0, max = 7.2832) "Angle from center to surface level";
equation
mass = A;
//Assume unit length pipe and unit density
flow_in + flow_out = der(mass);
A = 0.5 * R ^ 2 * (phi - sin(phi));
// phi = if noEvent(level <= 0) then 0 elseif noEvent(level >= 2 * R) then 2 * Modelica.Constants.pi else 2 * acos((R - level) / R);
if noEvent(level <= 0) then
phi = 0;
flow_out = 0;
elseif noEvent(level >= 2 * R) then
phi = 2 * Modelica.Constants.pi;
flow_out = -flow_in;
else
flow_out = 0;
//Partially full pipe has no out outflow
phi = 2 * acos((R - level) / R);
end if;
annotation(Icon, Diagram, experiment(StartTime = 0, StopTime = 10, Tolerance = 1e-06, Interval = 0.02));
end SimplePipe1;
这个版本似乎给出了更接近我想要的结果,但还是不行。在这种情况下,问题是 phi 应该限制为 2*pi。反而不断增加。同时,我实际上并没有看到 flowmode 发生变化。我确实看到流出在一个周期内变为负值,然后跳回零。我不明白是什么将流模式从通道改回完整,因为没有相应的 "when" 将其改回。
model SimplePipe2
type modetype = enumeration(empty, full, channel);
modetype flowmode(start = modetype.channel);
Modelica.SIunits.Area A;
Modelica.SIunits.Mass mass;
Modelica.SIunits.Height level(start = 0.5, fixed = true, min = 0.0, max = 2 * R) "Liquid level (m)";
Modelica.SIunits.Height level_limit;
parameter Modelica.SIunits.Radius R = 1.0 "pipe inner radius (m)";
parameter Real flow_in = 1.0;
Real flow_out;
Modelica.SIunits.Angle phi(start = 3.1, min = 0.0, max = 7.2832) "Angle from center to surface level";
Real flow_out;
initial equation
flowmode = modetype.channel;
equation
mass = A;
//Assume unit length pipe and unit density
flow_in + flow_out = der(mass);
A = 0.5 * R ^ 2 * (phi - sin(phi));
cos(phi / 2) = (R - level) / R;
if flowmode == modetype.empty then
flow_out = 0;
elseif flowmode == modetype.full then
flow_out = -flow_in;
else
flow_out = 0;
//Partially full pipe has no out outflow
end if;
when noEvent(phi >= 2 * Modelica.Constants.pi) then
reinit(flow_out, -flow_in);
reinit(level, 2 * R);
flowmode = modetype.full;
end when;
annotation(Icon, Diagram, experiment(StartTime = 0, StopTime = 10, Tolerance = 1e-06, Interval = 0.02));
end SimplePipe2;
This question that I asked is related to solving the same problem, but doesn't have the issue of a circle/cylinder. And, my second example above is based somewhat on this question.
我正在使用 OpenModelica 的最新测试版。我的完整模型将具有这些示例中未包含的其他功能。但是,希望如果我能让这个简单的版本工作,我可以从那里扩展。
您的代码以 phi 的非线性方程结束(在 level_limit 和一个 flow_out 从模型中删除之后)。
0 = 0.5 * R ^ 2.0 * (phi - sin(phi)) - mass
OM 在不为变量 phi 添加约束的情况下解决了这个问题。而是在找到解决方案后检查断言。如果您在 OpenModelica 中使用 non-linear solver=kinsol,约束将添加到非线性方程中,但在这种情况下无济于事。我也有点不确定 when noEvent()
是否会触发。