刚开始使用Modelica并且无法理解它是如何工作的.
在模型的下面'方法'中,qInflow和qOutflow在第二行中用于评估der(h),但它们还没有收到值!(它们没有在方法的"数据"中定义)?代码的执行顺序是什么.
equation
assert(minV >= 0, "minV must be greater or equal to zero");
der(h)=(qInflow - qOutflow)/area;
qInflow=if time > 150 then 3*flowLevel else flowLevel;
qOutflow=Functions.LimitValue(minV, maxV, -flowGain*outCtr);
error=ref - h;
der(x)=error/T;
outCtr=K*(error + x);
end FlatTank;
Run Code Online (Sandbox Code Playgroud)
来自http://www.mathcore.com/resources/documents/ie_tank_system.pdf
当来自使用命令式语义的语言和系统时,这是一个可以理解的混淆点.但Modelica并不像那样工作.
使用Modelica时,重要的是要理解一个equation部分包含方程式,而不是赋值.考虑一下,如果我给你以下方程式:
x + y = 3;
x + 2*y = 5;
Run Code Online (Sandbox Code Playgroud)
如果您了解这是一个数学上下文,则可以确定x必须具有值1并且y必须具有值2.换句话说,您必须求解联立方程组.你会注意到这些方程的左边不是变量(通常),它们是表达式.方程只是一个关系,它将左侧的一个表达式与右侧的另一个表达式相等.此外,这种关系总是正确的,所以秩序是无关紧要的.
这与具有命令性语义的命令式编程语言完全不同.但它也非常强大,因为你可以陈述这些关系(线性方程组,非线性方程组,隐式方程等),编译器将找出最有效的方法来解决它们.
回到您的示例,当您查看问题中的代码时,您将这些方程解释为赋值语句.这个概念得到了加强,因为它们碰巧在左侧有变量.但他们确实是方程式.在基于方程式的系统中,您不必担心先前是否已将指定变量分配给该系统.相反,要求仅仅是对于每个变量,存在(某处)方程,并且没有额外的方程.换句话说,您应该拥有与未知数相同数量的变量,并且方程组具有唯一解.这就是Modelica所需要的.
现在,Modelica支持您习惯的命令式语义.但它们仅用于特殊情况,因为它们限制了对数学行为的解释,从而干扰了允许Modelica编译器生成真正快速代码的符号操作.所以这不仅仅是一种风格问题.如果可能的话,你应该使用方程式,Modelica中的算法应该只作为最后的手段使用.
最后一点.有些人可能会疑惑"你是否告诉我这些方程式将被放入一些巨大的方程组中并通过矩阵求逆或Newton-Raphson或其他方法解决?为什么它显然会变得如此复杂,显然可以用更简单的方式解决!" 但它不会被解决为一个巨大的方程组.如果它可以作为一组简单的分配来解决它.这是将应用的不同符号操纵技术中的一种(在众多中).事实上,这是关于Modelica的一个关键点......您不需要担心优化解决方案方法,该工具将会解决这个问题.更重要的是,如果以一种同时出现系统的方式连接组件,您也不必担心这一点.Modelica工具可以为您处理这样的"代数循环",他们将对其进行优化以找到计算效率最高的公式,并且不依赖于您为这些情况重新制定模型.
这有帮助吗?