避免在查找向量中最大值索引的块中颤动

时间:2018-07-14 12:07:01

标签: modelica openmodelica

Modelica Newbie试图构建一个块,以标识一组实数值(向量)中的最高数值。

我尝试了两种版本-一种只给我最高值的索引,另一种可以切换相应布尔向量的值。

均失败。对于某些高输入值,模型(几乎)可以正常工作,但是大多数时候我会收到一条错误消息:“在时间0.0277777777839..0.0277777778544周围检测到抖动(连续100个状态事件,总时间增量小于步长0.02) )。这可能是性能瓶颈。有关更多信息,请使用-lv LOG_EVENTS。零交叉点为:indexMaxBool1.temp> indexMaxBool1.tempMax“

我搜索了涉及震颤的错误消息,并找到了答案,并用WHEN替换了IF语句。我只是很害怕,后者不会按需要提高计算频率(只有一次?需要重置吗?)。

我希望能获得一些有关如何避免这种颤抖的提示。

到目前为止,这是我的模特:

阻止获取最高值的索引:

block IndexMax
  extends Modelica.Blocks.Icons.Block;
  parameter Integer nin=1 "Number of inputs";
  Modelica.Blocks.Interfaces.RealInput v[nin];
  Modelica.Blocks.Interfaces.IntegerOutput index;

    protected
      Real tempMax;
      Real temp;

algorithm
   if size(v,1)>1 then
     tempMax := v[1];
     index := 1;

     for i in 2:size(v,1) loop
       temp := v[i];
       if temp > tempMax then
        tempMax := temp;
        index := i;
       end if;
     end for;
  else
    index :=0;
  end if;

end IndexMax;

块获取一个布尔值向量,其中一个在最高输入的索引处打开:

block IndexMaxBool
  extends Modelica.Blocks.Icons.Block;
  parameter Integer nin = 1 "Number of inputs";
  Modelica.Blocks.Interfaces.RealInput v[nin];
  Modelica.Blocks.Interfaces.BooleanOutput bool[nin];
protected
  Real tempMax;
  Real temp;
  Integer index;
algorithm
  if size(v, 1) > 1 then
    for i in 1:size(v,1) loop
      bool[i] := false;
    end for;
    tempMax := v[1];
    index := 1;

    for i in 2:size(v, 1) loop
      temp := v[i];
      if temp > tempMax then
        tempMax := temp;
        index := i;
      end if;
    end for;
  else
    index := 0;
  end if;
  if index > 0 then
    bool[index]:=true;
  end if;
end IndexMaxBool;

测试模型:

model testMax2
    Modelica.Blocks.Sources.RealExpression realExpression1(y = 1);
    FlowsAndStreams.BDSCalc.IndexMaxBool indexMaxBool1(nin = 3);
    Modelica.Blocks.Interfaces.BooleanOutput y;
    Modelica.Blocks.Interfaces.BooleanOutput y1;
    Modelica.Blocks.Interfaces.BooleanOutput y2;
    Modelica.Blocks.Sources.Sine sine1(amplitude = 2, freqHz = 1, phase = 0.785398);
    Modelica.Blocks.Sources.Sine sine2(amplitude = 2, freqHz = 3);
    equation
      connect(sine1.y, indexMaxBool1.v[2]);
      connect(sine2.y, indexMaxBool1.v[3]);
      connect(indexMaxBool1.bool[3], y2);
      connect(indexMaxBool1.bool[1], y);
      connect(indexMaxBool1.bool[2], y1);
      connect(realExpression1.y, indexMaxBool1.v[1]);
end testMax2;

和:

model testMax
    FlowsAndStreams.BDSCalc.IndexMax indexMax1(nin = 3);
    Modelica.Blocks.Sources.RealExpression realExpression1(y = 1);
    Modelica.Blocks.Sources.RealExpression realExpression2(y = 10);
    Modelica.Blocks.Sources.RealExpression realExpression3(y = 3);
    Modelica.Blocks.Interfaces.IntegerOutput y;
    equation
      connect(realExpression3.y, indexMax1.v[3]) annotation(
        Line(points = {{-69, -40}, {-8, -40}, {-8, 0}}, color = {0, 0, 127}));
      connect(realExpression2.y, indexMax1.v[2]) annotation(
        Line(points = {{-69, 0}, {-8, 0}}, color = {0, 0, 127}));
      connect(realExpression1.y, indexMax1.v[1]) annotation(
        Line(points = {{-69, 30}, {-10, 30}, {-10, 0}, {-8, 0}}, color = {0, 0, 127}));
      connect(indexMax1.index, y) annotation(
        Line(points = {{10, 0}, {50, 0}}, color = {255, 127, 0}));
end testMax;

1 个答案:

答案 0 :(得分:1)

我找到了一个解决方案-但我不知道它为什么起作用。 我删除了中间变量temp,而是直接使用v值。瞧!

如果v [i]> maxTemp则...

我在这里留下这个问题,可能对某人有帮助。