我看到这段代码有两个问题。主要问题与这就是所谓的“变量索引”问题有关。我会解决的。但首先,我想指出您的if
andwhen
子句没有正确同步。我的意思是,您的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
andwhen
子句都与trigger
变量相关联。if
现在我们可以解决您的主要问题,即在您的陈述的一方面,您有:
der(x_calc) = time * 5;
...另一方面,您有:
x_calc = 0;
在实践中,这意味着对于模拟的一部分,您x_calc
使用微分方程求解,而在模拟的另一部分,您x_calc
使用代数方程求解。这会导致“变量索引”问题,因为 DAE 的“索引”会根据 的值trigger
是真还是假而变化。
一种方法是稍微修改方程。我们不使用方程,而是指定forx_calc = 0
的初始条件,然后执行一个表示 的值不变的微分方程,即。换句话说,通过将代数方程设置删除为常数并用我们将初始值设置为所需值的方程替换它来获得相同的行为,然后添加一个微分方程,实际上,它只是表示值of不变。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 运行(尽管我对您的问题或预期结果知之甚少,无法真正验证结果)。
我希望这会有所帮助。