1

我有一个关于在可重用库部分和特定应用程序部分中构建 Modelica 代码的问题。问题涉及依赖于介质的介质和设备,我受到 MSL 流体库中的一些结构的启发,但我想制作更小的东西并适应我的需要,但我也可以随之成长。

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

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

在应用程序代码中,包含七种物质的新介质被声明为包 Medium7。泵、饲料和收获罐的库模型的调整分以下三个步骤进行:

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

首先,现在可以使用 Equipment7 中的设备在为 Medium7 定制的应用程序代码中定义一个系统。——我希望我能比上面描述的更直接地进行改编。如果我避免像这里那样在库和应用程序中划分代码,那么从 Medium2 切换到 Medium7 会容易得多,只需更改 LiquidConType 中使用的介质,然后该更改就会传播到整个系统。

当我阅读 Tiller 和 Fritzson 关于该主题的教科书材料时,或者当我尝试理解 MSL 代码时,我发现了类似的结构,但仍然不是我在这里所拥有的。我还认为我关于如何有效地使库适应新应用程序所要求的接口变化的问题不仅限于介质,而是更广泛的代码。

只需阅读 2008 年的 Tillers 论文“Modelica 中的模式和反模式”,在第 2.3 节“中模型模式”中,这里有一个与我的问题相关的讨论,并考虑了 pg 649 的最后几行。

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

我将不胜感激有关该主题的一些评论,也许还有阅读建议。我的玩具问题的替代解决方案也很受欢迎!

谢谢,简彼得

我不知道如何附加代码文件,但下面我展示了上面描述的应用程序代码。库 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;
4

1 回答 1

0

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

原始问题中的代码在 JModelica 和 OpenModelica 中确实有效,但我发现它“笨拙”并且实际上还有一个核心缺陷,OpenModelica 社区的人们已经向我指出了这一点。我使用部分模型 EquipmentMedium 作为包 Equipment 的参数,并在包中扩展它。从可替换模型扩展在这里提供了太多的灵活性,并且在 OpenModelica 2.0-beta 错误中给出了(但在早期版本的 OM 中没有)。

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

在更新的代码中,我还在 Medium 包中引入了更多信息,并展示了如何将其扩展为新的 Medium - 这是我在此处的另一篇文章的结果。

有关参数化包的灵活性程度的更多信息,请参阅 Hans Olsson 指出的 Modelica def 6.2.1 和 7.3.1。Peter Fritzsons 的书(2015 年第 2 版)中也有第 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;
于 2019-03-18T10:16:05.473 回答