模型从管道流出

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() 是否会触发。