Modelica-如何最有效地从库导入应用程序代码

时间:2019-02-26 14:36:05

标签: modelica openmodelica jmodelica

我对在可重用的库部分和特定的应用程序部分中构造Modelica代码有疑问。这个问题涉及依赖于介质的介质和设备,我受到MSL流体库中某些结构的启发,但我想做得更小一些,以适应我的需求,但我也可以随它一起发展。

问题在于如何方便地使库适应应用程序代码中定义的新介质。由于存在不同设备零件的几种模型,因此自然而然会有一个局部模型来定义设备应具有的连接器类型,然后仅在需要修改连接器时才对局部模型进行更改。 在我看来,我需要一个三步骤的库适应过程,而不是我希望的一步。我在下面有一个详细的示例,可以更清楚地提出问题。

该示例是用于将液体从一个容器泵送到另一个容器的模型,即我们有一个进料罐,一个泵和一个收集罐。液体介质最初包含两种物质,现在在应用程序中我们要对七种物质进行建模。

在应用代码中,将包含七种物质的新介质声明为Package7。通过以下三个步骤对泵,饲料罐和收获罐的库模型进行调整:

  1. 将连接器LiquidCon7定义为从库中导入标准连接器LiquidCon的扩展,并将介质重新声明为Medium7
  2. 将部分模型EquipmentMedium7定义为标准部分模型EquipmentMedium的导入的扩展,其中将连接器重新声明为LiquidCon到LiquidCon7
  3. 将包装Equipment7定义为标准包装Equipment导入的扩展,其中部分模型从EquipmentMedium重新声明为EquipmentMedium7。

首先,现在可以使用Equipment7中的设备在应用程序代码中定义适合于Medium7的系统。 - 我希望我可以比上面更直接地进行适应。如果我像在这里一样避免在库和应用程序中划分代码,那么只需更改LiquidConType中使用的介质,然后将更改传播到整个系统,就可以轻松地从Medium2切换到Medium7。

当我阅读Tiller和Fritzson撰写的有关该主题的教科书材料时,或者当我尝试理解MSL代码时,我会发现类似的结构,但仍然没有这里的内容。我还认为,关于如何有效地使库适应新应用程序所要求的接口更改的问题不仅限于中级,还包括范围更广的代码。

只需阅读Tillers于2008年发表的论文“ Modelica中的模式和反模式”,并在第2.3节“中等模型模式”中进行讨论,这与我的问题有关,并考虑了第649页的最后几行。 >

我刚刚意识到我的模型结构违反了Modelica的定义,因为您不允许从部分模型EquipmentMedium扩展PumpType,FeedtankType等,因为我需要EquipmentMedium是可替换的。请参阅Modelica def 3.2 rev 2第6.2.1节“传递不可替换”。

我希望对这个问题发表一些评论,也许还会读一些建议。我的玩具问题的替代解决方案也很受欢迎!

谢谢Jan Peter

我不知道如何添加代码文件,但是下面我显示了上面描述的应用程序代码。库DATA_v04很简单。但是请注意,我需要使用部分模型EquipmentMedium的扩展定义模型PumpType,FeedtankType等,这是不允许的。

    encapsulated package d4_app7 

    //  ------------------------------------------------------------------------
    //     Interfaces  
    //  ------------------------------------------------------------------------

        import Modelica.Blocks.Interfaces.RealInput;
        import Modelica.Blocks.Interfaces.RealOutput;

        package Medium7
            constant String name = "Seven components"   "Medium name";
            constant Integer nc = 7                     "Number of substances; 
            type Concentration 
                 = Real[nc] (each min=0, each unit="kg/m3")  "Substance conc";
        end Medium7;

    //  ------------------------------------------------------------------------
    //     Adaptation of library DEMO to Medium7  
    //  ------------------------------------------------------------------------

        connector LiquidCon7
            import DEMO_v4.LiquidCon;
            extends LiquidCon(redeclare package medium=Medium7);
        end LiquidCon7;

        partial model EquipmentMedium7
            connector LiquidConType=LiquidCon7;
        end EquipmentMedium7;

        package Equipment7
            import DEMO_v4.Equipment;
            extends Equipment
               (redeclare partial model EquipmentMedium=EquipmentMedium7);           
        end Equipment7;

        import DEMO_v4.Control;

    //  ------------------------------------------------------------------------
    //     Examples of systems 
    //  ------------------------------------------------------------------------

        model Test
            LiquidCon7.medium medium;
            Equipment7.PumpType pump;
            Equipment7.FeedtankType feedtank;
            Equipment7.HarvesttankType harvesttank;
            Control.FixValueType Fsp(val=0.2);
        equation
            connect(feedtank.outlet, pump.inlet);
            connect(pump.outlet, harvesttank.inlet);
            connect(Fsp.out, pump.Fsp);
        end Test;

    end d4_app7;

1 个答案:

答案 0 :(得分:0)

我从JModelica和OpenModelica支持中获得了一些有关此问题的输入,以简化库代码对应用程序的适应,我在这里共享它。

最初问题中的代码确实可以在JModelica和OpenModelica中使用,但是我发现它“笨拙”,实际上还存在OpenModelica社区中的人们向我指出的主要缺陷。我使用部分模型EquipmentMedium作为包Equipment的参数,并在包中对其进行扩展。从可替换模型进行扩展在此处提供了太多的灵活性,并带来了OpenModelica 2.0-beta错误(但在OM的早期版本中没有)。

在下面的库DEMO_v11.mo和应用程序代码d11_app7.mo的更新代码中,我简化了库的改编,并避免从可替换模型中扩展。毕竟,只有连接器LiquidCon才需要适应该应用,准确地说,只有连接器的中间部分才需要进行适配。因此,我使用Medium作为包Equipment的形式参数,并根据实际的Medium在包内定义连接器。然后,其他设备使用此连接器。因此,从参数化连接器“扩展”包装中的模型的方法被认为是可以接受的,而从参数化模型进行扩展则是不可接受的。

在更新的代码中,我还将“媒体”包中的信息引入了更多内容,并展示了如何将其扩展到新的“媒体”中-这是我在此处发布的另一篇文章的结果。

有关这种方式的参数化软件包中的灵活性程度的更多信息,请参阅Hans Olsson指出的Modelica def 6.2.1和7.3.1。彼得·弗里兹森(Peter Fritzsons)的书(2015年第二版)中也有4.15节对此进行了讨论。

库代码DEMO_v11.mo:

    //  ---------------------------------------------------------------------------------------------
    //     Interfaces  
    //  ---------------------------------------------------------------------------------------------

        import Modelica.Blocks.Interfaces.RealInput;
        import Modelica.Blocks.Interfaces.RealOutput;

        package Medium2
            replaceable constant String name = "Two components"    "Medium name";
            replaceable constant Integer nc = 2                    "Number of substances";
            replaceable type Concentration = Real[nc]              "Substance conc";
            replaceable constant Real[nc] mw = {10, 20}            "Substance weight";  
            constant Integer A = 1                                 "Substance index";
            constant Integer B = 2                                 "Substance index";   
        end Medium2;

        package Medium3 
            import M2 = DEMO_v11.Medium2;
            extends M2
                (name="Three components"                           "Medium name",
                 nc=3                                              "Number of substances",
                 mw = cat(1,M2.mw,{30})                            "Substance weight",
                 redeclare type Concentration = Real[nc]           "Substance conc");
            constant Integer C = 3                                 "Substance index";   
        end Medium3;

    //  ---------------------------------------------------------------------------------------------
    //     Equipment dependent on the medium  
    //  ---------------------------------------------------------------------------------------------

        package Equipment
            replaceable package Medium
            end Medium;

            connector LiquidCon
                Medium.Concentration c                             "Substance conc";
                flow Real F (unit="m3/s")                          "Flow rate";
            end LiquidCon;

            model PumpType
                LiquidCon inlet, outlet;                                                     
                input RealInput Fsp;
            equation
                inlet.F = Fsp;                                         
                connect(outlet, inlet);                          
            end PumpType;

            model FeedtankType
                LiquidCon outlet;                                  
                constant Integer medium_nc = size(outlet.c,1);
                parameter Real[medium_nc] c_in (each unit="kg/m3") 
                                = {1.0*k for k in 1:medium_nc}     "Feed inlet conc";                        
                parameter Real V_0 (unit="m3") = 100               "Initial feed volume";
                Real V(start=V_0, fixed=true, unit="m3")           "Feed volume";
            equation    
                for i in 1:medium_nc loop
                    outlet.c[i] = c_in[i];
                end for;
                der(V) = outlet.F;               
            end FeedtankType;

            model HarvesttankType
                LiquidCon inlet;                                   
                constant Integer medium_nc = size(inlet.c,1);
                parameter Real V_0 (unit="m3") = 1.0   "Initial harvest liquid volume";
                parameter Real[medium_nc] m_0 
                      (each unit="kg/m3") = zeros(medium_nc)       "Initial substance mass";
                Real[medium_nc] c                                  "Substance conc";
                Real[medium_nc] m 
                      (start=m_0, each fixed=true)                 "Substance mass";
                Real V(start=V_0, fixed=true, unit="m3")           "Harvest liquid volume";
            equation
                for i in 1:medium_nc loop
                    der(m[i]) = inlet.c[i]*inlet.F;
                    c[i] = m[i]/V;
                end for;
                der(V) = inlet.F;               
            end HarvesttankType;
        end Equipment;

    //  ---------------------------------------------------------------------------------------------   
    //     Control 
    //  ---------------------------------------------------------------------------------------------

        package Control
            block FixValueType
                output RealOutput out;
                parameter Real val=0;
            equation
                out = val;
            end FixValueType;
        end Control;

    //  ---------------------------------------------------------------------------------------------
    //     Examples of systems 
    //  ---------------------------------------------------------------------------------------------

    //  package Equipment3 = Equipment(redeclare package Medium=Medium3);   // Just shorter version

        package Equipment3
            import DEMO_v11.Equipment;
            extends Equipment(redeclare package Medium=Medium3);
        end Equipment3;

        model Test
            Equipment3.Medium medium;
            Equipment3.FeedtankType feedtank;
            Equipment3.HarvesttankType harvesttank;
            Equipment3.PumpType pump;
            Control.FixValueType Fsp(val=0.2);
        equation
            connect(feedtank.outlet, pump.inlet);
            connect(pump.outlet, harvesttank.inlet);
            connect(Fsp.out, pump.Fsp);
        end Test;

    end DEMO_v11;

以及应用程序代码d11_app7.mo:

    //  ---------------------------------------------------------------------------------------------
    //     Interfaces  
    //  ---------------------------------------------------------------------------------------------

        import Modelica.Blocks.Interfaces.RealInput;
        import Modelica.Blocks.Interfaces.RealOutput;

        package Medium7
            import M2 = DEMO_v11.Medium2;
            extends M2
                (name = "Seven components"                      "Medium name", 
                nc = 7                                          "Number of substances",
                mw = cat(1,M2.mw,{30,40,50,60,70})              "Substance weight",
                redeclare type Concentration = Real[nc]         "Substance conc");
            constant Integer C = 3                              "Substance index";
            constant Integer D = 4                              "Substance index";  
            constant Integer E = 5                              "Substance index";  
            constant Integer F = 6                              "Substance index";  
            constant Integer G = 7                              "Substance index";  
        end Medium7;

    //  ---------------------------------------------------------------------------------------------
    //     Adaptation of library DEMO_v11 to Medium7  
    //  ---------------------------------------------------------------------------------------------

        package Equipment7
            import DEMO_v11.Equipment;
            extends Equipment(redeclare package Medium=Medium7);
        end Equipment7;

    //  ---------------------------------------------------------------------------------------------       
    //     Examples of systems 
    //  ---------------------------------------------------------------------------------------------

        import DEMO_v11.Control;

        model Test
            Equipment7.Medium medium;                          // Instance not necessary but helpful for user interface
            Equipment7.PumpType pump;
            Equipment7.FeedtankType feedtank;
            Equipment7.HarvesttankType harvesttank;
            Control.FixValueType Fsp(val=0.2);
        equation
            connect(feedtank.outlet, pump.inlet);
            connect(pump.outlet, harvesttank.inlet);
            connect(Fsp.out, pump.Fsp);
        end Test;

    end d11_app7;