我看到这段代码有两个问题。主要问题与这就是所谓的“变量索引”问题有关。我会解决的。但首先,我想指出您的 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,而是为x_calc 指定初始条件0,然后执行一个微分方程,表明x_calc 的值不会改变,即, @ 987654339@。换句话说,通过将代数方程设置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 运行(尽管我对您的问题或预期结果知之甚少,无法真正验证结果)。
希望对你有帮助。