我想问一个关于何时函数的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;
答案 0 :(得分:4)
我在这段代码中看到了两个问题。主要问题在于这就是所谓的“可变指数”问题。我会解决这个问题。但首先,我想指出您的if
和when
条款没有正确同步。我的意思是,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;
现在,if
和when
子句都绑定到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运行此模型(尽管我对您的问题或预期结果了解不足以真正验证结果)。
我希望有所帮助。