参数化 Modelica 库和“延迟”结构参数设置的可能性 - 第 3 部分

Parametrised Modelica library and possibility to “delay” setting of structural parameter - part 3

我正在寻找一种将代码分为两部分的好方法:通用库和应用程序代码, 我使用的示例通常包含液体,我想让通用库独立于液体中的成分数量。这个想法是应用程序代码设置使用的液体介质,然后从通用库中导入设备,并使这些设备适应实际介质。

下面的示例是一个非常简洁的示例,说明了执行此代码划分的一种方法。在这里,我在部分包 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;

在具有相同代码结构的稍大示例中,我遇到了一些问题:

该消息对我来说没有意义,因为 nc 在编译时已知,在 EquipmentLib 被适配的级别。这个问题实际上可以通过给 MediumBase 中的 nc 赋予 Medium Base 中的“虚拟”值 nc=1 来解决,然后在编译期间将 nc 更改为调整 EquipmentLib 时提供的值。

所以我的问题是:

  1. 对我来说,保持 nc 未定义然后确保在编译期间设置值看起来更好,而在编译期间更改常量看起来有问题,但也许(仍然)在 Modelica 中允许。在 Modelica 语言规范中,我可以在附录 A 中看到常量的要求是(仅)它在模拟期间是常量,即不是在编译期间。在附录 E8.2 中,我看到也许应该完成 nc 的初始分配,但不确定。不过,希望对此发表一些评论。
  2. JModelica 和 OpenModelica 的较大示例编译器怎么会分别给出警告和错误?
  3. Modelica 规范对这里的内容有何看法?

如果需要,我可以提供更大的示例,但我认为这里可能是一个更笼统的答案。

1) 理论上我明白你的意思,但是 modelica 语言标准要求每个模型(除了连接器和部分模型)都必须自己有效。这似乎与您的情况无关,因为您定义了一个部分包,这里的问题是您在结构上依赖于此变量的同一范围内定义了一个数组。因此我强烈建议提供一个可以检查的默认值。

2) 我实际上无法重现该问题。使用 OpenModelica,即使 nc=10000 一切都运行良好。缓慢但有效(我们正在努力使 array/vector 的东西在未来变得更快)。我正在使用夜间构建 (OpenModelica 1.16.0~dev-102-g5c1a023)。

3) 参见 1)。 一般来说,我可以补充说你应该在每个组件上单独使用检查模型(绿色圆圈顶部中间的单个复选标记)来检查你所做的一切是否符合 modelica 语言。您还可以使用它旁边的实例化按钮来查看将从您的代码生成的平面模型。

此外,我建议使用编译标志 -d=newInst(前提是您使用的是较新的版本之一)。这使用了对 modelica 规范更严格且效率更高的新实例化。

我现在已经确认我发布的代码确实是正确的,并且对于部分包(或模型),您可以定义没有值的变量或具有未确定大小的向量,前提是它们在编译时被完全定义。导致我提到的问题的具有相似结构的更复杂的代码现在也已解决。该代码适用于 JModelica 2.14 和 OpenModelica 1.16 每晚构建 ...b48。有趣的是,该代码不适用于 1.15 或更早版本。感谢我在 Modelon 的联系人 Markus Olsson!