1

I have been trying to model flow through a pipe that can be partially full, or totally full in modelica and running it in OpenModelica. I have finally reduced the example to essentially just use the area of a circle, and to have no outflow until it is full, then complete outflow. But, I am still getting errors. I have tried it a few different ways. The first way gives an error about solving a nonlinear system once the pipe becomes "filled up". Instead I want it to switch over:

   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;

This version seems to give results that are closer to what I want, but it still doesn't work. In this case, the problem is that phi is supposed to be limited to 2*pi. Instead it keeps increasing. Meanwhile, I don't actually see flowmode change. I do see the outflow go negative for a single cycle, then it jumps back to zero. I don't understand what is changing the flowmode back from channel to full, since there is no corresponding "when" to change it back.

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.
I am using the newest beta of OpenModelica. My complete model will have other feature that are not included in either of these examples. But, hopefully if I can get this simple version working, I can expand from there.

4

1 回答 1

2

您的代码以 phi 的非线性方程结束(在 level_limit 和一个 flow_out 从模型中删除之后)。

0 = 0.5 * R ^ 2.0 * (phi - sin(phi)) - mass

OM 在不为变量 phi 添加约束的情况下解决了这个问题。而是在找到解决方案后检查断言。如果您在 OpenModelica 中使用 non-linear solver=kinsol,则会将约束添加到非线性方程中,但在这种情况下无济于事。我也有点不确定是否when noEvent()会触发。

于 2016-02-12T06:50:53.327 回答