参数化Modelica库和#x201C;延迟”;结构参数的设置.第3部分

参数化Modelica库和#x201C;延迟”;结构参数的设置.第3部分,modelica,openmodelica,jmodelica,Modelica,Openmodelica,Jmodelica,我正在寻找一种将代码分为两部分的好方法:通用库和应用程序代码, 我使用的示例通常包含液体,我希望使通用库独立于液体中的组件数量。其思想是,应用程序代码设置所使用的液体介质,然后从通用库导入设备,并使这些设备适应实际介质 下面的示例是一个非常简洁的示例,说明了进行代码划分的一种方法。在这里,我让组件数量的值nc在部分包MediumBase中未定义。稍后,当设备库适应实际介质时,nc将获得一个值。这就是我对结构参数“延迟”设置的意思。代码在JModelica和OpenModelica中都运行良好

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

下面的示例是一个非常简洁的示例,说明了进行代码划分的一种方法。在这里,我让组件数量的值nc在部分包MediumBase中未定义。稍后,当设备库适应实际介质时,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在编译时是已知的,在设备库适配的级别上。这个问题实际上可以通过在MediumBase中为nc指定一个中基的“虚拟”值nc=1来解决,然后在编译期间将nc更改为适配设备库时提供的值

因此,我的问题是:

  • 在我看来,最好保持nc未定义,然后确保在编译过程中设置值,而在编译过程中更改常量看起来有问题,但在Modelica中可能(仍然)允许。在Modelica语言规范中,我可以在附录a中看到常量的要求是(仅)在模拟过程中,即在编译过程中,它是恒定的。在附录E8.2中,我看到可能应该完成nc的初始分配,但不确定。不过,希望对此发表一些评论
  • 对于一个更大的示例,JModelica和OpenModelica编译器如何分别给出警告和错误
  • Modelica规范对此处的内容有何说明
  • 如果需要,我可以提供更大的示例,但我认为这里可能是一个更一般的答案。

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

    2) 事实上,我无法重现这个问题。使用OpenModelica,即使对于
    nc=10000
    ,一切都可以正常运行。速度很慢,但它可以工作(我们正在努力使阵列/向量的速度在将来更快)。我正在使用夜间构建(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!

    1)我对部分模型和包的理解可能很不完整,因为它不是单独使用的。我的部分包MediumBase基本上确保当介质被替换时,该包确实有一个参数nc,当一个完整的包被替换时2)我很高兴JModelica和OpenModelica都接受了我发布的代码,并在一定程度上证实了我的理解。3)但对于更大的模型,不是nc,而是更多的代码层,然后我从JModelica和OpenModelica收到编译器警告和错误。Modelica规范说什么?