Modelica I/O 块与函数
Modelica I/O blocks vs. Functions
Modelica 中的块和函数有一些相同点和不同点。在块中,输出变量最有可能使用方程根据输入变量表示,而在函数中,输出变量使用赋值根据输入变量表示。给定一个关系 y = f(u) 可以用这两个概念来表达,我很想知道在哪种情况下你应该支持哪个概念?
就个人而言,
使用 input/output 连接器可以更好地将块集成到框图中
编译器最有可能更好地处理块中的方程,以进行符号操作、优化和评估 Jacobian 计算所需的分析导数。所以我猜想在某些边界情况下,块可能对数值错误不太敏感。对于函数,如果未明确提供导数,则很可能使用有限差分法对其进行评估。
另一方面,函数中的一组赋值很可能被视为单个方程。如果用块中更大的方程组表示相同的一组赋值,将导致模型更大,可能导致运行时性能下降
尽管带有算法部分的块在某种程度上等同于具有相同赋值集的函数,但函数调用的语法在某些情况下更受欢迎
可以建立块类型的层次结构并执行面向对象建模的所有操作。功能有点有限。不可能从包含算法部分的非抽象函数进行扩展。但是可以有(一个)抽象函数充当(一个)接口,从中可以建立已实现的功能等。
上面的一些论点取决于特定模拟环境处理块或函数的方式。这些可能是不一定知道的低级细节。
您可能对相反的事情感兴趣:像调用函数一样调用块:
https://github.com/modelica/ModelicaSpecification/issues/1512
使用函数语法的好处是不需要声明+连接组件:
Block b;
equation
connect(x, b.in1);
connect(y, b.in2);
connect(z, b.out1);
对
z = Block(x, y);
当然现在还不存在这种语法。你真的想尽可能地使用块。算法块也可能是函数,因为它们更短且更容易编写,并且会在结果文件中引入更少的轨迹(除非您想调试函数调用内部发生的事情,否则很好)。
您“问题”中的列表已经是一个很好的总结。还有一些其他的事情需要考虑:
关于函数的微分,开发者至少需要定义赋值可以微分的频率(这里有个不错的read on this), as e.g. Dymola will not do it automatically. Alternatively the differentiated function can be specified manually (here). By the way, a partial derivative can be defined as well, see Language Specification, Sec. 12.7.2.
当需要反转函数时,可能需要手动定义它。这在 Language Specification, Sec. 中有描述。 12.8.
此外,函数中的代码可以内联也很重要,这应该可以解决上面提到的一些问题,请参阅 Language Specification,第 1 节。 18.3.
一般来说,只要没有很强的功能理由,我就会去块。我想到的一些是程序执行的需要,或者 for
-循环。
这只是我的两分钱 - 欢迎更多意见...
Modelica 中的块和函数有一些相同点和不同点。在块中,输出变量最有可能使用方程根据输入变量表示,而在函数中,输出变量使用赋值根据输入变量表示。给定一个关系 y = f(u) 可以用这两个概念来表达,我很想知道在哪种情况下你应该支持哪个概念?
就个人而言,
使用 input/output 连接器可以更好地将块集成到框图中
编译器最有可能更好地处理块中的方程,以进行符号操作、优化和评估 Jacobian 计算所需的分析导数。所以我猜想在某些边界情况下,块可能对数值错误不太敏感。对于函数,如果未明确提供导数,则很可能使用有限差分法对其进行评估。
另一方面,函数中的一组赋值很可能被视为单个方程。如果用块中更大的方程组表示相同的一组赋值,将导致模型更大,可能导致运行时性能下降
尽管带有算法部分的块在某种程度上等同于具有相同赋值集的函数,但函数调用的语法在某些情况下更受欢迎
可以建立块类型的层次结构并执行面向对象建模的所有操作。功能有点有限。不可能从包含算法部分的非抽象函数进行扩展。但是可以有(一个)抽象函数充当(一个)接口,从中可以建立已实现的功能等。
上面的一些论点取决于特定模拟环境处理块或函数的方式。这些可能是不一定知道的低级细节。
您可能对相反的事情感兴趣:像调用函数一样调用块:
https://github.com/modelica/ModelicaSpecification/issues/1512
使用函数语法的好处是不需要声明+连接组件:
Block b;
equation
connect(x, b.in1);
connect(y, b.in2);
connect(z, b.out1);
对
z = Block(x, y);
当然现在还不存在这种语法。你真的想尽可能地使用块。算法块也可能是函数,因为它们更短且更容易编写,并且会在结果文件中引入更少的轨迹(除非您想调试函数调用内部发生的事情,否则很好)。
您“问题”中的列表已经是一个很好的总结。还有一些其他的事情需要考虑:
关于函数的微分,开发者至少需要定义赋值可以微分的频率(这里有个不错的read on this), as e.g. Dymola will not do it automatically. Alternatively the differentiated function can be specified manually (here). By the way, a partial derivative can be defined as well, see Language Specification, Sec. 12.7.2.
当需要反转函数时,可能需要手动定义它。这在 Language Specification, Sec. 中有描述。 12.8.
此外,函数中的代码可以内联也很重要,这应该可以解决上面提到的一些问题,请参阅 Language Specification,第 1 节。 18.3.
一般来说,只要没有很强的功能理由,我就会去块。我想到的一些是程序执行的需要,或者 for
-循环。
这只是我的两分钱 - 欢迎更多意见...