modelica:计算连续变量的最小值/最大值

时间:2015-06-09 13:01:10

标签: max minimum modelica openmodelica

如上所述:我希望计算连续变量随时间的最小值(和/或最大值)。这是一个演示的最小例子:

model MinMaxTest
  Real u;
  Real u_min(start = 10);
  Real u_max(start = -10);
equation
  u = sin(time / 180 * Modelica.Constants.pi);
  u_min = min(u, u_min);
  u_max = max(u, u_max);
  annotation(experiment(StartTime = 0, StopTime = 360, Tolerance = 1e-06, Interval = 1));
end MinMaxTest;

u是任意连续变量(出于演示目的,是一个简单的正弦波)。 u_min / u_max是随时间变化的最小值/最大值。

显然,预期结果为u_min=-1u_max=1。不幸的是,模拟以“Matrix奇异!”崩溃了。错误。任何人都可以指导我如何避免这种情况吗?

编辑1

我正在使用OpenModelica 1.15(原为1.9.2)

编辑2

由于我对Modelica很陌生,我很难理解以下方法之间的差异:

  1. u_min = if noEvent(u < u_min) then u else pre(u_min);
  2. if noEvent(u < u_min) then u_min = u; else u_min = pre(u_min); end if;
  3. u_min = if noEvent(u < u_min) then u else u_min;
  4. u_min = if u < u_min then u else pre(u_min);
  5. u_min = if u < u_min then u else u_min;
  6. when u < u_min then u_min = u; end when;
  7. u_min + T*der(u_min) = if u <= u_min then u else u_min;
  8. 1和2是等效的,并导致预期的行为。

    3产生了所需的结果,但给出了关于“代数循环”的“翻译通知”,为什么?

    到目前为止,

    4失败,结果u_min曲线与u相同?!为什么呢?

    5结合了3和4。

    6无法使用Sorry - Support for Discrete Equation Systems is not yet implemented

    进行编译

    7我不清楚这背后的想法是什么,但如果T具有建议的大小,它就有效。

    如果我正确理解了Modelica文档,那么1-5的共同点就是一直有一个方程式处于活动状态。 noEvent禁止在指定的过零点处生成事件。我的印象是这主要是提高效率。为什么要将它排除导致4失败? pre指的是变量的前一个值,所以我想如果我们想保持一个变量不变是有意义的,但是为什么7没有呢?我对when的理解是,它的等式仅在该精确事件中有效,否则保留先前的值,这就是为什么我尝试在6中使用它。它似乎工作如果我比较常数值(对于这个特定问题没有用)。

    EDIT3

    1. u_min = smooth(0, if u < u_min then u else pre(u_min));
    2. 有趣的是,这也有效。

3 个答案:

答案 0 :(得分:3)

我用Dymola 2016测试了你的模型并且它有效,但是你可以尝试使用另一种方法。在Modelica中,你必须考虑方程而不是分配。

u_min = min(u, u_min);

如果将代码作为一系列指令执行,您将会怎么做。在引擎盖下,Modelica工具转换了这个等式 进入非线性系统,随着模拟的进行而解决。

这些是模拟模型时得到的统计数据

Statistics

Original Model
Number of components: 1
Variables: 3
Unknowns: 3 (3 scalars)
Equations: 3
Nontrivial: 3

Translated Model
Time-varying variables: 3 scalars
Number of mixed real/discrete systems of equations: 0
Sizes of linear systems of equations: { }
Sizes after manipulation of the linear systems: { }
Sizes of nonlinear systems of equations: {1, 1}
Sizes after manipulation of the nonlinear systems: {1, 1}
Number of numerical Jacobians: 0

如您所见,有两个非线性系统,一个用于u_min,另一个用于u_max

您遇到的另一种解决方案是

model Test
  Real x;
  Real y;
  Real u_min;
  Real u_max;
  parameter Real T = 1e-4;
equation 
  x = sin(time) + 0.1*time;
  y = sin(time) - 0.1*time;
  u_min + T*der(u_min) = if y <= u_min then y else u_min;
  u_max + T*der(u_max) = if x >= u_max then x else u_max;

end Test;

在这种情况下,u_minu_max是两个状态变量,它们会跟随 变量x和y,取决于它们的值。例如,当x低于u_max时,u_max会“卡住”达到该时间点达到的最大值。

很抱歉,但由于这是我的第一个回复,因此无法发布模型的运行图像。

答案 1 :(得分:2)

这里的主要问题是你得到一个单数的方程,因为你试图解决方程 u_min = min(u,u_min)。如果u_min取决于u和u_min,并且u_min的{​​{1>}的每个值小于u都适合等式,那么工具也可能会尝试为此使用非线性求解器。 另一个解决方案可能是延迟算子:

  u_min = min(u, delay(u_min,0));
  u_max = max(u, delay(u_max,0));

关于不同方法的一些注释:

  1. u_min = if noEvent(u < u_min) then u else pre(u_min);
  2. if noEvent(u < u_min) then u_min = u; else u_min = pre(u_min); end if;
  3. 这两者在语义上是相同的,因此结果应该是相同的。此外,pre运算符的使用解决了这个问题,因为此处u_min取决于upre(u_min),因此不需要非线性求解器。

    1. u_min = if noEvent(u < u_min) then u else u_min;
    2. 如上所述min()使用u_minu的解决方案取决于u_minnoEvent(),这导致非线性解决方案。

      1. u_min =如果你&lt; u_min然后你预先(u_min);
      2. u < u_min运算符的语义在字面上使用了if-expression,在这种情况下,触发事件u_min = u并且始终使用表达式u_min = if u < u_min then u else u_min;。 / p>

        1. when u < u_min the u_min = u; end when;
        2. 是的,它结合了3和4的问题。

          1. u_min
          2. 此处u_min的解决方案再次取决于uu_min + T*der(u_min) = if u <= u_min then u else u_min;

            1. activity starter
            2. 这里u_min是一个状态,因此u_min的计算由积分器完成,此方程现在求解为der(u_min),然后影响u_min。

答案 2 :(得分:1)

对于您的初步问题,OpenModelica中似乎正常工作的是:

u_min = min(u, pre(u_min));
u_max = max(u, pre(u_max));

对我来说,编译,模拟并给出预​​期的结果,但也会说“Matrix singular!”。另一方面,如果我将u_max的初始声明更改为:

Real u_max(start = 0);

然后,“矩阵奇异!”走开了。
我不知道为什么,但这似乎确实起到了作用,我建议比你列出的其他选项更直接。