【问题标题】:OpenModelica: "Warning: maximal number of iteration reached but no root found" with conditional equationOpenModelica:“警告:达到最大迭代次数但未找到根”,带有条件方程
【发布时间】:2019-10-07 08:40:27
【问题描述】:

我是一名 OpenModelica 初学者,试图对具有恒定电压和电流限制的 DC/DC 转换器进行建模。基本上,输出应该提供恒定电压,直到达到最大电流,然后通过降低电压来保持该电流。

到目前为止,这是我代码的方程式部分:

model DC_DC "Voltage source with current limiting"

  import SI = Modelica.SIunits;

  parameter SI.Voltage Vnom(start=1) "Value of nominal output voltage";
  parameter SI.Current Inom(start=1) "Value for maximum continous output current";
  parameter SI.Current Imax(start=1) "Value for maximum output current";

  Modelica.Electrical.Analog.Interfaces.PositivePin p 
    annotation (Placement(transformation(extent={{-110, -10},{-90,10}})));
  Modelica.Electrical.Analog.Interfaces.NegativePin n 
    annotation (Placement(transformation(extent={{110, -10},{90,10}})));

  SI.Voltage v;

equation 

  v = p.v - n.v;

  if n.i > Imax and v <= Vnom then
    n.i = Imax;
    0 = p.i + n.i;
  else
    Vnom = p.v - n.v;
    0 = p.i + n.i;
  end if;

end DC_DC;

每当我进行模拟时,电压和电流的结果看起来就像我预期的那样,因此计算似乎是正确的。但是,我收到警告

已达到最大迭代次数,但未找到根。

谁能给我解释一下?谢谢!

【问题讨论】:

  • 您能分享一个最小的工作示例吗?我可以想象n.i 是一个状态,并且您想将 when-equation 与 reinit-operator 一起使用。
  • 我添加了最小工作模型。在这种情况下,您将如何应用 reinit 运算符?

标签: simulation modelica openmodelica dymola


【解决方案1】:

但是,我收到了警告

maximum number of iteration reached, but no root found.

谁能给我解释一下?谢谢!

原因是积分器无法求解您制定的方程组。
根本问题是,您试图更改连续状态(此处为n.i)而不告诉积分器。


如果您想在某个事件中更改状态变量的值,您需要使用 reinit-operator,它只允许在 when 等式中使用。

您可以执行类似于以下模型的操作:

package minExample
  model DC_DC "Voltage source with current limiting"
    import SI = Modelica.SIunits;

    parameter SI.Voltage Vnom(start=1) "Value of nominal output voltage";
    parameter SI.Current Inom(start=1) "Value for maximum continous output current";
    parameter SI.Current Imax(start=1) "Value for maximum output current";

    Modelica.Electrical.Analog.Interfaces.PositivePin p "Positive electrical pin";
    Modelica.Electrical.Analog.Interfaces.NegativePin n "Negative electrical pin";
    SI.Voltage v "Voltage drop of the two pins (= p.v - n.v)";
  equation
    when n.i > Imax then
      reinit(n.i,Imax);
    end when;

    if n.i > Imax then
      v = 0;
    else
      Vnom = p.v - n.v;
    end if;

    // Connect equations
    0 = p.i + n.i;
    v = p.v - n.v;
  end DC_DC;

  model test
    Modelica.Electrical.Analog.Basic.Ground ground1;
    Modelica.Electrical.Analog.Basic.Inductor inductor1(L = 0.5);
    DC_DC dc_dc1;
  equation
    connect(inductor1.n, ground1.p);
    connect(dc_dc1.n, ground1.p);
    connect(inductor1.p, dc_dc1.p);
  end test;
end minExample;

【讨论】:

  • 感谢您的帮助。在额外的 when 指令中执行 reinit 对我来说似乎是一个好方法。但它仍然不起作用。如果 n.i>Imax,为什么要设置 v=0?在我看来,那一行应该是 n.i = Imax。
  • 我完全没有电气工程方面的经验,所以我不应该多说。但是你说你想模拟一个电压源,所以我认为它应该控制电压而不是电流。但这或多或少只是一个猜测。
  • 只需阅读 reinit(x,exp) 的文档:看来需要将 der 运算符应用于 x 以使 reinit() 有所作为(build.openmodelica.org/Documentation/…)所以这并不似乎可以做到这一点......
  • 然后编辑您的示例,使其实际重现您的错误并发布整个错误。也许还有其他问题。但在大多数情况下n.i 应该成为一个状态,就像我在test 模型中强制使用电感器(其中基本上有der(n.i))。
  • 使用 when ... reinit 只会更改一次状态,并且不会将其保持在该值 - 所以它不能解决这个问题。 (但 reinit 不应该要求应用 der。)
【解决方案2】:

不幸的是,您必须了解 s 参数化才能解决此问题,如在 e.g. Modelica.Electrical.Analog.Ideal.IdealDiode。

除了单元检查,您应该执行以下操作:

 Real s;
equation 

  v = p.v - n.v;

  if s<0 then
    s=v-Vnom;
    n.i=Imax;
  else
    Vnom = v;
    s=Imax-n.i;
  end if;
  0 = p.i + n.i;

我相信这个的原始参考是https://ieeexplore.ieee.org/document/808640

这个模型也可以通过添加一个新变量并重写 if 方程来改写这种风格

  Boolean saturatedCurrent=s<0;
equation
  v-vNom=if saturatedCurrent then s else 0;
  Imax-n.i=if saturatedCurrent then 0 else s; 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-12
    • 2018-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多