我正在寻找一种将代码分为两部分的好方法:通用库和应用程序代码,我使用的示例通常包含液体,我想让通用库独立于液体中的组件数量。这个想法是应用程序代码设置使用的液体介质,然后从通用库中导入设备,并使这些设备适应实际介质。
下面的示例是一个非常简洁的示例,它说明了进行这种代码划分的一种方法。在这里,我在部分包 MediumBase 中未定义组件数量的值 nc。稍后,当 EquipmentLib 适应实际的 Medium 时, nc 会得到一个值。这就是我所说的结构参数的“延迟”设置。该代码在 JModelica 和 OpenModelica 中运行良好。
package DEMO_v30
// Author: Jan Peter Axelsson
// ---------------------------------------------------------------------------------------------
// Interfaces
// ---------------------------------------------------------------------------------------------
import Modelica.Blocks.Interfaces.RealInput;
import Modelica.Blocks.Interfaces.RealOutput;
partial package MediumBase
constant Integer nc "Number of components";
replaceable type Concentration = Real[nc] "Component conc";
end MediumBase;
package Medium3
extends MediumBase (nc=3);
end Medium3;
// ---------------------------------------------------------------------------------------------
// Equipment dependent on the medium
// ---------------------------------------------------------------------------------------------
package EquipmentLib
replaceable package Medium = MediumBase // formal parameter - EquipmentLib
constrainedby MediumBase;
model ReactorType
parameter Medium.Concentration c_0 = ones(Medium.nc) "Initial component conc";
Medium.Concentration c (start=c_0, each fixed=true) "Component conc";
equation
for i in 1:Medium.nc loop
der(c[i]) = -c[i];
end for;
end ReactorType;
end EquipmentLib;
// ---------------------------------------------------------------------------------------------
// Adaptation of package Equipment to Medium3
// ---------------------------------------------------------------------------------------------
package Equipment
import DEMO_v30.EquipmentLib;
extends EquipmentLib(redeclare package Medium=Medium3);
end Equipment;
// ---------------------------------------------------------------------------------------------
// Examples of systems
// ---------------------------------------------------------------------------------------------
model Test
Equipment.ReactorType reactor;
end Test;
end DEMO_v30;
在具有相同代码结构的稍大示例中,我遇到了一些问题:
- 在 JModelica 中,我收到“常量 nc 没有绑定表达式”的警告
- 在 OpenModelica 中,我收到一个错误“无法评估结构参数(或常数).. nc,它给出了数组 c[MediumBase.nc] 的维度。数组维度必须在编译时知道'
该消息对我来说没有意义,因为 nc 在编译时已知,在 EquipmentLib 适应的级别。这个问题实际上可以通过在 MediumBase 中为 nc 赋予 Medium Base 中的“虚拟”值 nc=1 来解决,然后在编译期间将 nc 更改为适配 EquipmentLib 时提供的值。
所以我的问题是:
- 对我来说,最好保持 nc 未定义,然后确保在编译期间设置值,而在编译期间更改常量看起来有问题,但在 Modelica 中可能(仍然)允许。在 Modelica 语言规范中,我可以在附录 A 中看到,对常量的要求是(仅)它在模拟期间是常量,即在编译期间不是。在附录 E8.2 中,我看到也许应该对 nc 进行初始分配,但不确定。不过,希望对此发表一些评论。
- JModelica 和 OpenModelica 的示例编译器怎么会分别给出警告和错误?
- Modelica 规范对这里的内容有什么看法?
如果需要,我可以提供更大的示例,但我认为这可能是一个更普遍的答案。