Modelica:步进函数的初始条件

时间:2014-07-16 01:05:17

标签: modelica dymola openmodelica

我想问一个关于何时函数的Modelica问题,以及以下源代码无法正常运行。变量Pstart_CONV是if语句中der(x_calc)的初始条件,当“when语句”变为true时,Pstart_CONV值由x给出。因为x是一个阶跃函数,我想为der(x_calc)分配一个初始条件,因此可以为整个域继续x。

非常感谢,

来源:

model Unnamed4
  Real  Pstart_CONV;

  Real P_crit_ratio;
  parameter Real P_crit_ratio_criteria = 2.00;

  Real x;
  Real x_calc(start=0);

equation 
  P_crit_ratio = 10-time;

  when P_crit_ratio <= P_crit_ratio_criteria then
    Pstart_CONV = x;
  end when;

  if P_crit_ratio >= P_crit_ratio_criteria then
    x = time^2;
    x_calc = 0;
  else
    der(x_calc) = time * 5;
    x = x_calc + Pstart_CONV;
  end if;   
end Unnamed4;

1 个答案:

答案 0 :(得分:4)

我在这段代码中看到了两个问题。主要问题在于这就是所谓的“可变指数”问题。我会解决这个问题。但首先,我想指出您的ifwhen条款没有正确同步。我的意思是,if语句表示的行为更改不一定会在when子句被激活的同一时刻发生。

要解决此问题,您可以轻松地将模型重构为如下所示:

model Model1
  Real Pstart_CONV;
  Real P_crit_ratio;
  parameter Real P_crit_ratio_criteria=2.00;
  Real x;
  Real x_calc(start=0);
  Boolean trigger(start=false);
equation 
  P_crit_ratio = 10-time;

  when P_crit_ratio <= P_crit_ratio_criteria then
    Pstart_CONV = x;
    trigger = true;
  end when;

  if trigger then
    der(x_calc) = time * 5;
    x = x_calc + Pstart_CONV;
  else
    x_calc = 0;
    x = time^2;
  end if;
end Model1;

现在,ifwhen子句都绑定到trigger变量。现在我们可以解决您的主要问题,即您if声明的一方:

der(x_calc) = time * 5;

......另一方面,你有:

x_calc = 0;

在实践中,这意味着对于部分模拟,您使用微分方程求解x_calc,而在模拟的其他部分,您使用代数方程求解x_calc。这会导致“变量索引”问题,因为DAE的“索引”会根据trigger的值是真还是假来改变。

一种方法是稍微修改方程式。我们不是使用公式x_calc = 0,而是为0指定x_calc的初始条件,然后执行一个微分方程,表明x_calc的值不会改变,即, der(x_calc) = 0。换句话说,通过将代数方程设置x_calc移除到常量并将其替换为我们将x_calc的初始值设置为所需值的等式,然后添加差值来获得相同的行为实际上,简单地说x_calc的值不会改变。

在您的案例中进行此类更改会产生以下模型:

model Model2
  Real Pstart_CONV;
  Real P_crit_ratio;
  parameter Real P_crit_ratio_criteria=2.0;
  Real x;
  Real x_calc(start=0);
  Boolean trigger(start=false);
initial equation
  x_calc = 0;
equation
  P_crit_ratio = 10-time;

  when P_crit_ratio <= P_crit_ratio_criteria then
    Pstart_CONV = x;
    trigger = true;
  end when;

  if trigger then
    der(x_calc) = time * 5;
    x = x_calc + Pstart_CONV;
  else
    der(x_calc) = 0;
    x = time^2;
  end if;
end Model2;

我对它进行了测试,并使用SystemModeler运行此模型(尽管我对您的问题或预期结果了解不足以真正验证结果)。

我希望有所帮助。