Modelica:不可能使用连接器进行参数传播
我正在开发一个用于模拟化学过程的(开放)Modelica 库。对于商业工具,一种常见的方法是为进料流定义一次混合物配置(例如涉及多少化学成分以及涉及哪些化学成分,如水、乙醇等),然后该信息通过流传播到所有后续的单元操作。
不幸的是,到目前为止我还没有设法使用强大的modelica语言来实现这个功能。理想的情况是对“流程”进行建模,如下所示:
package StreamTest
connector Stream_Port
parameter String componentlist[:];
Real T, p;
end Stream_Port;
model Feed_model
parameter String componentlist[:];
Stream_Port Out(componentlist = componentlist);
Real T, p;
equation
Out.T = T;
Out.p = p;
end Feed_model;
model Tank_model
parameter String componentlist[:];
Real T,p;
Stream_Port In(componentlist = componentlist);
equation
In.T = T;
In.p = p;
end Tank_model;
model Process
Feed_model Feed (componentlist = {"A", "B"});
Tank_model Tank;
equation
connect(Feed.Out, Tank.In);
Feed.Out.T = 200;
Feed.Out.p = 1;
end Process;
end StreamTest;
当然,这个示例被精简到最本质的部分,因为“组件列表”没有做任何事情。在下一步中,“componentlist”将用于计算每个模型中的物理属性,定义分子分数的数组大小等。
传播的想法如下:
- “componentlist”仅在 Feed_model 的实例中定义 一次。
- “组件列表”被设置为等于连接器Stream_Port的“组件列表”。
- 连接进料和罐,并将“成分列表”传输到罐的“输入”端口。
- 现在是关键点:Tank 从端口“In”获取“组件列表”并将其传播到 Tank 的组件列表。组件列表比在罐内用于物理属性和阵列大小,并且也可以通过罐的某些出口传播到下一个单元。
不幸的是,这不适用于 Openmodelica,尽管没有语法错误,而且我看不到这种方法不符合的语言定义中的任何点。错误消息是:
[StreamTest: 17:5-17:38]: Failed to deduce dimension 1 of componentlist due to missing binding equation.
当然,我可以在每个单元的模型“过程”级别上定义“组件列表”:
model Process
Feed_model Feed (componentlist = {"A", "B"});
Tank_model Tank (componentlist = {"A", "B"});
equation
connect(Feed.Out, Tank.In);
Feed.Out.T = 200;
Feed.Out.p = 1;
end Process;
但是我必须为“过程”中模型的每个实例冗余地执行此操作 -不像我想实现更大的流程模型那么优雅......
这种行为的原因:参数传播仅在模型的声明部分“向下”工作,其中所有模型都被实例化。当我们连接模型时,参数传播只能用于端口定义内的数组大小。它就被卡住了:信息没有传输到下一个连接的单元。
任何想法,如何解决这个问题?我错过了什么吗?虽然我对一些类似的商业工具很有经验,但我仍然处于 modelica 的学习曲线上......
I am working on a (Open)Modelica library for simulating chemical processes. With commercial tools it is a common approach that the mixture configuration (e.g. how many and which chemical components are involved like water, ethanol, ...) is defined once for the feed-stream and then this information is propagated via the streams to all the subsequent unit operations.
Unfortunately, so far I did not manage to use the powerful modelica language to achieve this functionality. The ideal situation would be to model a "Process" like this:
package StreamTest
connector Stream_Port
parameter String componentlist[:];
Real T, p;
end Stream_Port;
model Feed_model
parameter String componentlist[:];
Stream_Port Out(componentlist = componentlist);
Real T, p;
equation
Out.T = T;
Out.p = p;
end Feed_model;
model Tank_model
parameter String componentlist[:];
Real T,p;
Stream_Port In(componentlist = componentlist);
equation
In.T = T;
In.p = p;
end Tank_model;
model Process
Feed_model Feed (componentlist = {"A", "B"});
Tank_model Tank;
equation
connect(Feed.Out, Tank.In);
Feed.Out.T = 200;
Feed.Out.p = 1;
end Process;
end StreamTest;
Of course this example is stripped down to the essential since nothing is done with "componentlist". In the next step "componentlist" would be used for calculating physical properties in each model, to define array sizes of molefractions etc.
The idea of propagation is as follows:
- The "componentlist" is defined in the instance of the Feed_model only once.
- The "componentlist" is set equal to the "componentlist" of the connector Stream_Port.
- Feed and Tank are connected and the "componentlist" is transferred to the Port "In" of Tank.
- Now the crucial point: Tank takes the "componentlist" from the port "In" and propagates it to the componentlist of Tank. componentlist than is used inside the tank for physical properties and array sizes and may also be propagated via some outlet-port of tank to the next unit.
Unfortunately, this does not work with Openmodelica although there is no syntactical error and I cannot see any point in the language definition this approach is not complying with. The error message is:
[StreamTest: 17:5-17:38]: Failed to deduce dimension 1 of componentlist due to missing binding equation.
Of course, I can define the "componentlist" on the level of the model "process" for each unit:
model Process
Feed_model Feed (componentlist = {"A", "B"});
Tank_model Tank (componentlist = {"A", "B"});
equation
connect(Feed.Out, Tank.In);
Feed.Out.T = 200;
Feed.Out.p = 1;
end Process;
But then I have to do this redundantly for each and every instance of a model in "Process" -- not as elegant as I would like to implement larger process models...
Reasons for this behaviour: Parameter propagation only works "downwards" in the declaration part of a model where all the models are instantiated. When we connect models, parameter propagation can only be used for array sizes inside the port-definition. And there it is stuck: The information is not transported to the next connected unit.
Any idea, how to solve this problem? Did I miss something? Although I am quite experienced with some some similar commercial tools I am still on the learning curve of modelica...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
AFAIK,仅靠 (Open)Modelica 是不可能做到这一点的,但一些工具已经通过自动化功能进行了修改:
(https://build.openmodelica.org/Documentation/Modelica .Fluid.UsersGuide.ComponentDefinition.FluidConnectors.html)
Dymola 视频演示了这一点:https://www.modelon.com/propagating-replaceable-medium-automatically/
Modelica 规范问题,如果您希望将其包含在语言/重新开放讨论中:https://github.com/modelica/ModelicaSpecification/issues/240
AFAIK, this is not possible with (Open)Modelica alone, but some tools have been amended with an automation capability:
(https://build.openmodelica.org/Documentation/Modelica.Fluid.UsersGuide.ComponentDefinition.FluidConnectors.html)
Dymola video demonstrating this: https://www.modelon.com/propagating-replaceable-medium-automatically/
The Modelica Specification issue in case you would like to see this included in the language/reopen discussion: https://github.com/modelica/ModelicaSpecification/issues/240
在 Modelica 中,媒体模型不是通过连接传播的(我同意这是非常合乎逻辑的)。相反,它们是通过可替换包从上到下传播的。正如我所说,我知道通过连接器传播参数更加直观。但是连接的语言语义只处理值,而不处理类型,并且替换不同抽象媒体模型的能力非常重要,因为在大多数情况下,不同的媒体模型不仅仅是参数化(值变化),而是拓扑变化(类型变化)。这就是采用可替换包(类型)机制的原因。
In Modelica, media models are not propagated via connections (which I agree would be quite logical). Instead, they are propagated via replaceable packages from the top down. As I said, I understand that propagation of parameters via connectors is more intuitive. But the language semantics of connections only deal with values, not with types and the ability to substitute different abstract media models is pretty important because in most cases different media models are not simply parametric (value changes) but rather topology changes (type changes). This is why the replaceable package (types) mechanism is employed.
我认为问题在于编译时数组大小并未在各处定义。假设您想要避免多次指定组件数量,您还可以使用 内部/外部机制:
I think the problem is that the array size is not defined everywhere at compile time. Assuming what you want is to avoid specifying the number of components many times, you could also use the inner/outer mechanism:
我非常感兴趣地阅读了您的帖子和讨论,我自己也曾为类似的问题而苦苦挣扎。区分 Modelica 中可以表达的内容与 Modelica 标准库的常见用法和风格非常重要。
为了举例说明 Michael Tiller 所写的有关如何通过可替换包传播媒体模型的内容,我附上了下面的代码,其中显示了一个与您的示例有些相似的示例。此处,浓度矢量为 c 的液体流 F 从 FeedTank 流向 HarvestTank,通过具有驱动该流的压差的管道。还使用了流和流的概念。您可以在 如何构造Modelica 中的液体平衡连接器?。 (注意 DEMO_v46 与使用解决方案 DEMO_v42 更新的 DEMO_v40 相同)
我不想使用术语“传播”,而是说 EquipmentLib 是使用可替换媒体包“适应”的。
传播意味着一条路径,或许还有一系列的变化,而这里整个设备库都在一个语句中进行了调整。
EquipmentLib 包含储罐、管道、传感器、泵等组件,其中实际包“Medium”(包括物质数量)称为 EquipmentLib 的形式参数。通过更改库的“介质参数”,您可以获得适合您选择的介质的所有设备。这就像我眼中你们在实践中的工作方式。例如,如果您需要建立一个处理酸性溶液的工艺,那么您从一开始就选择专门用于处理该溶液的储罐、管道、泵等。
I read your post and discussion here with great interest and I have struggled with similar questions myself. Important to distinguish between what can be expressed in Modelica from what is common usage and style of Modelica Standard Library.
To exemplify what Michael Tiller wrote about how media models are propagated via replaceable package I enclose the code below that shows an example somewhat similar to yours. Here, a flow F of liquid with concentration vector c from FeedTank to HarvestTank through a pipe with a pressure difference that drives the flow. The concepts of flow and stream are also used. You can read more about a similar example at How to construct a balanced connector for liquids in Modelica?. (Note DEMO_v46 is the same as DEMO_v40 updated with the solution DEMO_v42)
I prefer not to use the term "propagate" and rather say that the EquipmentLib is "adapted" using a replaceable media package.
Propagate implies a path and perhaps a sequence of change, while here the whole EquipmentLib is adapted in one statement.
The EquipmentLib contains components like tanks, pipes, sensors, pumps etc where the actual package "Medium" (including number of substances) is called a formal parameter of the EquipmentLib. By changing the "medium-parameter" of the library you get all equipment adapted to the media of your choice. This resembles the way you work in practice in my eyes. For example if you need to build a process that should handle very acid solutions, then you choose tanks, pipes, pumps etc that are specified to handle that, up front from start.