Modelica 在“方程式”部分处理if案例

Modelica 在“方程式”部分处理if案例,modelica,dymola,openmodelica,Modelica,Dymola,Openmodelica,我想知道在Modelica中如何实现以下功能: suppose variables a,b Timetable object c equation if a>c.y then b = f(a) // with f a mathematical function else b = g(a) // with g a mathematical function end if; der(a) = h(a,b) //with h a

我想知道在Modelica中如何实现以下功能:

suppose variables a,b
Timetable object c

    equation
    if a>c.y then
      b = f(a) // with f a mathematical function
    else
      b = g(a) // with g a mathematical function
    end if;

    der(a) = h(a,b) //with h a mathematical function

Modelica如何确定if语句的哪种情况为真?如果没有if语句中确定的“b”值,它就无法计算“a”的值。

首先,请注意
a
是状态(至少基于您所示的方程式)。这意味着在当前时间将知道
a
。根据您的描述,
c
也是已知的(显然,它是时间的函数)。所以在任何时候,我们都知道将采用
if
语句的哪个分支

因此,对于任何给定的时间,我们都可以计算
b
,因此
der(a)
。真正的问题是
if
语句中的条件在什么时候发生变化

答案是(由Modelica编译器)建立了一个“monitor”函数,当该monitor函数超过零时,Modelica运行时将在该点停止集成,然后重新启动集成(使用另一个分支)。这是因为
if
语句中的条件表达式隐式生成事件

考虑这一点的另一种方式是,存在一个“隐藏”布尔变量,它指示我们是采用分支还是其他分支。首先,这听起来很疯狂,因为您假设Modelica运行时将根据是否
a>c.y
执行分支,但事实并非如此。它所做的是在模拟开始时根据
a>c.y
的值确定布尔值的初始值,然后尝试找出它实际发生变化的时间。它实际上并不总是计算
a>c.y
。这会导致奇怪的情况,即执行一个分支,即使它不应该执行。这将在Modelica中发生,并与生成的候选解决方案相关,而Modelica运行时试图确定事件发生的位置

我知道这听起来很混乱,但是如果你接受这个“隐藏的布尔变量”的概念,并且理解它在Modelica运行时能够确定应该发生更改的点(基于某个候选解决方案轨迹)之前是不会更改的,那么这一切都是有意义的


我希望这能有所帮助。

我想我明白你的意思了。您还说,有时一个分支被执行,而它不应该被执行。这表明我的程序效率不高。你知道一个更好的方法来实现它吗?我觉得“不应该”这个词太重了。在您确定需要在哪一点切换分支之前,不能争论是否应该执行分支。我认为这并不一定意味着任何事情都是低效的。您可以使用
noEvent
操作符使
if
语句按预期工作。但这不是默认行为的原因是,如果您这样做,它可能会给积分器带来更多的混乱。在您确定它是低效的之前,对它进行基准测试。