参数化的Modelica库和使用模型作为参数的可能性-第2部分

时间:2019-03-14 09:37:14

标签: modelica openmodelica jmodelica

我了解库中的参数化软件包如何适应外部应用程序代码,即我希望将库代码和应用程​​序代码保持非常独立。

在这里的示例中,我的设备包中有两个参数,一个连接器LCon和一个模型CType。连接器会影响“设备”包装中的所有型号。模型CType仅影响设备中的一个模型RType(并具有更紧密的内外关系)。

当我根据LCon2和CTyp2的应用需求调整设备包装时,可以一次完成以下操作。

   code1

   package Equipment2
          import BR5i.Equipment;
          extends Equipment(redeclare connector LCon=LCon2,
                      redeclare model CType=CType2);
   end Equipment2;    

但是,如果我将这两种改编分为两个不同的部分,那么我认为代码(从长远来看)更具可读性。我尝试下面的代码,但不起作用。错误文本:当我在JModelica中运行RType时,找不到类声明。

   code2

   package Equipment2
       import BR5i.Equipment;
       extends Equipment(redeclare connector LCon=LCon2);
   end Equipment2;

   model BRType2        
       import BR5i.Equipment2.RType;
       extends RType(redeclare model CType=CType2);
   end BRType2;

(对于代码2,库进行了修改,因此将参数CType移到了设备级别,移至单个模型RType,其中CType应该作为参数。最后,我希望代码2的BRType2对应于来自代码1)。

我想知道是否有可能在这样的几个步骤中进行更改,即首先RType获得一个新的连接器LCon2,然后在下一步中,现在从Equipment2导入的RType应该将CType替换为CType2吗?

我知道该代码不应被视为“赋值语句”的序列,而应视为并行的。在我眼中,代码2中“等式”的逻辑应该使获得正确的BRType2成为可能。

5 个答案:

答案 0 :(得分:2)

您的“ code2”将导致BRType2 被修改CType。重新声明并不意味着“将程序包A更改为如下所示”,而是“这应类似于程序包A,但进行了这些更改”。因此,要获得所需的结果,您应该执行以下操作:

package Equipment2
    import BR5i.Equipment;
    extends Equipment(redeclare connector LCon=LCon2);
end Equipment2;

model BRType2
    // Equipment2 has the change in LCon, so extend RType from there instead
    import Equipment2.RType;
    extends RType(redeclare model CType=CType2);
end BRType2;

还请注意,如果设备包含Rtype的任何实例或其他引用,则此方法将无法获得预期的结果,因为它们将引用未更改的RType而不是BRType2。

为什么您会得到关于找不到RType的错误,我不能说。可能是一个错误,但我首先要检查一下您是否正确地编写了它的路径。

答案 1 :(得分:1)

根据要求,我在这里提供一个小的独立示例,大约150行。我决定最近重新使用我在其他几篇文章中使用的玩具示例,现在添加了一些必要的东西来例证这里讨论的问题。这意味着与上面所写的相比,我使用了不同的事物名称,但是问题的结构完全相同。

玩具示例描述了从一个容器向另一个容器中泵送介质的过程,并且该示例是通用的,以便我们可以轻松地更换介质,并且泵和油箱的设备会自动更新。最初,介质包含两种物质。通过一个单独的简短应用程序代码,我们定义了一个包含更多组件的介质,并通过重新声明连接器LiquidCon来更新“设备”包,然后简单地重新使用系统设置。

现在,我在收获物上添加一个内部模型,该模型描述了物质之间的某种反应。最初,我们有一个NoReaction反应模型,该物质将这些物质留在收获箱中而没有任何反应。另一个反应模型是显示物质3降解的反应3。

我要强调的问题是,如果我们首先将设备与带有三种物质的连接器相适配。然后在第二轮中,将适配设备3的反应模型更改为反应模型Reaction3,然后JModelica编译器给出错误消息,而OpenModelica不会并产生可以的模拟结果。该代码在代码中标记为替代2。

替代方法1.另一方面,如果同时执行两个非常不同的重新声明,即都更改了连接器LiquidCon和模型ReactionType,则它在JModelica和OpenModelica中均可使用。

下面的自包含代码和示例Test现在是Alternative 2,在JModelica 2.4中产生错误,但在OpenModelica中有效。我不清楚我对Modelica def的期望是什么。

    package DEMO_v14

        // Here I have put together a small demo-library to illustrate questions
        // around structuring handling of medium. The key structures are taken
        // from MSL fluid, I think it is fair to say.

        // Author: Jan Peter Axelsson

    //  ---------------------------------------------------------------------------------------------
    //     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_v14.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;

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

        model Reaction3
            constant Integer nc = 3;
            outer Real[nc] c;
            outer Real[nc] q;           
        equation
            q[1] = 0;
            q[2] = 0;
            q[3] =-c[3];
        end Reaction3;      

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

        package Equipment
            replaceable connector LiquidCon
            end LiquidCon;

    //      replaceable model ReactionType                         // Alternative 1
    //      end ReactionType;

            model PumpType
                LiquidCon inlet, outlet;                                                     
                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
                // Connection to reaction
                replaceable model ReactionType                     // Alternative 2 
                end ReactionType;

                ReactionType reaction;
                inner Real[medium_nc] c                            "Substance conc";
                inner Real[medium_nc] q                            "Reaction rate";     

                LiquidCon inlet, port;                                   
                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] 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 + q[i];
                    c[i] = m[i]/V;
                    port.c[i] = c[i];
                end for;
                der(V) = inlet.F;               
            end HarvesttankType;

            model NoReaction
                constant Integer nc = Medium.nc;
                outer Real[nc] c;
                outer Real[nc] q;           
            equation
                for i in 1:nc loop
                    q[i] = 0;
                end for;
            end NoReaction;     

        end Equipment;

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

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

    //  ---------------------------------------------------------------------------------------------
    //  Adaptation of library for the actual culture and media
    //  ---------------------------------------------------------------------------------------------

    //  package Equipment3                                                     // Alternative  1
    //      import DEMO_v14.Equipment;
    //      extends Equipment(redeclare connector LiquidCon=LiquidCon3,
    //                        redeclare model ReactionType=Reaction3);
    //  end Equipment3;

        package Equipment3                                                     // Alternative 2
            import DEMO_v14.Equipment;
            extends Equipment(redeclare connector LiquidCon=LiquidCon3);
        end Equipment3;

        model HarvesttankType3
            import DEMO_v14.Equipment3.HarvesttankType;
            extends HarvesttankType(redeclare model ReactionType=Reaction3);
        end HarvesttankType3;

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

        model Test
            Medium3 medium;
            Equipment3.FeedtankType feedtank;
    //      Equipment3.HarvesttankType harvesttank;                            // Alternative 1 
            HarvesttankType3 harvesttank;                                      // Alternative 2
            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_v14;

答案 2 :(得分:1)

我还没有时间详细分析您的问题,但是我想在这里指出,如果某个代码在一个工具中被接受,而在另一工具中不被接受,则不一定意味着该错误已存在于工具中。不接受代码的工具。随着时间的推移,Modelica语义变得更加严格,以使Modelica更安全地使用,并且更易于在各种工具之间移植。由于OpenModelica内核是周围最古老的内核之一,因此众所周知,它接受的许多代码实际上(在许多情况下)在最新版本中都不是合法的Modelica。

对不起,我没有时间从Modelica语义合法性角度深入分析此问题。无论如何,我深信您可以通过合法的Modelica实现您想要的目标。关于建模实践的两点评论:具有空类(在您的情况下为连接器)作为可替换类是不安全的,应避免使用,因为可以用任何本质上不安全的东西来替换它。我还认为,通过在连接器中使用可变长度的向量,您可以实现想要实现的目标,连接器本身不需要更换。

祝你好运,/ Hubertus

答案 3 :(得分:0)

我接受这样的想法,即以安全的方式对库包进行参数化,可以使灵活性尽可能小。您可以在包中包含一个常数整数nc,当您改编该包时,您可以给它一个数字Medium3.nc。然后,连接器LiquidCon在包装设备内部定义,并且浓度矢量声明为Real [nc] c;可以在配置级别上将与nc有关的有关Medium的其他信息带到应用程序Test中,而不是作为Package Equipment的改编,在本示例中没有讨论,但在其他相关文章中也没有讨论。这样,包装适应过程将尽可能地“安全”。

涉及将ReactionType引入HarvesttankType的另一种适应(现在已适应实际nc)需要非常灵活,此库包才有兴趣。我们对ReactionType的要求是要有一个接口:外部Real(nc)c,q;,我们可以在部分模型中进行描述,并使用构造约束来带来一定的安全性。

请参见下面的代码DEMO_v17_alt1和d17_alt1_app7。

但是,我更愿意将代码编写为alt2,并仅为HarvesttankType而不是为整个Equipment包保留定义的ReactionType等。这需要考虑到图书馆改编的两步过程。一级使设备适应中型组件的数量。第二层将现在适应的HarvesttankType修改为ReactionType。这在JModelica中是不可能的,但实际上在OpenModelica中。

因此,只有alt1可以在JModelica 2.4中使用,而alt1和alt2都可以在OpenModelica 1.13.2(和1.14 beta)中使用。当前的Modelica定义怎么说?

库代码DEMO_v17_alt1:

    package DEMO_v17_alt1

        // Here I have put together a small demo-library to illustrate questions
        // around structuring handling of medium. The key structures are taken
        // from MSL fluid, I think it is fair to say.

    //  ---------------------------------------------------------------------------------------------
    //     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_v17_alt1.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;

        model Reaction3
            constant Integer nc = 3;
            outer Real[nc] c;
            outer Real[nc] q;           
        equation
            q[1] = 0;
            q[2] = 0;
            q[3] =-c[3];
        end Reaction3;      

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

        package Equipment

            constant Integer nc;

            connector LiquidCon
                Real[nc] c                                         "Substance conc";
                flow Real F (unit="m3/s")                          "Flow rate";
            end LiquidCon;              

            replaceable model ReactionType = NoReaction            // Alternative 1
                constrainedby ReactionTypeInterface;               

            partial model ReactionTypeInterface                    // Alternative 1
                outer Real[nc] c, q;
            end ReactionTypeInterface;

            model NoReaction                                       // Alternative 1
                extends ReactionTypeInterface;          
            equation
                for i in 1:nc loop
                    q[i] = 0;
                end for;
            end NoReaction;             

            model PumpType
                LiquidCon inlet, outlet;                                                     
                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
                // Connection to reaction
                // replaceable model ReactionType = NoReaction constrainedby ReactionTypeInterface;   // Alternative 2

                ReactionType reaction;
                inner Real[medium_nc] c                            "Substance conc";
                inner Real[medium_nc] q                            "Reaction rate";     

                LiquidCon inlet, port;                                   
                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] 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 + q[i];
                    c[i] = m[i]/V;
                    port.c[i] = c[i];
                end for;
                der(V) = inlet.F;               
            end HarvesttankType;

        end Equipment;

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

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

    //  ---------------------------------------------------------------------------------------------
    //     Adaptation of library DEMO_v17_alt1 to Medium3 and Reaction3
    //  ---------------------------------------------------------------------------------------------

        package Equipment3                                         // Alternative 1
            import DEMO_v17_alt1.Equipment;
            extends Equipment(nc=Medium3.nc,
                              redeclare model ReactionType=Reaction3);
        end Equipment3;

    //  package Equipment3                                         // Alternative 2
    //      import DEMO_v17_alt2.Equipment;
    //      extends Equipment(nc=3);
    //  end Equipment3;

    //  model HarvesttankType3
    //      import DEMO_v17_alt2.Equipment3.HarvesttankType;
    //      extends HarvesttankType(redeclare model ReactionType=Reaction3);
    //  end HarvesttankType3;

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

        model Test
            Medium3 medium;
            Equipment3.FeedtankType feedtank;
            Equipment3.HarvesttankType harvesttank;                // Alternative 1 
    //      HarvesttankType3 harvesttank;                          // Alternative 2
            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_v17_alt1;

和应用程序代码d17_alt1_app7

    encapsulated package d17_alt1_app7 


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

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

        package Medium7
            import M2 = DEMO_v17_alt1.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;

        model Reaction7
            constant Integer nc = 7;
            outer Real[nc] c;
            outer Real[nc] q;           
        equation
            q[1] = 0;
            q[2] = 0;
            q[3] = 0;
            q[4] = 0;       
            q[5] = 0;               
            q[6] = 0;       
            q[7] =-c[7];
        end Reaction7;  

    //  ---------------------------------------------------------------------------------------------
    //     Adaptation of library DEMO_v17_alt1 to Medium7 and Reaction7  
    //  ---------------------------------------------------------------------------------------------

        package Equipment7
            import DEMO_v17_alt1.Equipment;
            extends Equipment(nc=Medium7.nc,
                              redeclare model ReactionType=Reaction7);
        end Equipment7;

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

        import DEMO_v17_alt1.Control;

        model Test
            Medium7 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 d17_alt1_app7;

答案 4 :(得分:0)

我最近从与Modelon和OpenModelica有关的人那里得到了一些帮助,对此我深表感谢。下面是库和应用程序的更新文件。呈现的代码在JModelica和OpenModelica中都可以使用,现在在Dymola中也可以使用。

对已纠正的代码错误的一些注释。

  1. 在模型Test中,我习惯于制作一个感兴趣的Media实例。尽管当前版本的JModelica和OpenModelica支持它,但实际上在Modelica中也不允许(也不是很有意义)创建这样的包实例。我对媒体包进行此实例的原因有两个:

    1. 我通常需要在Test(但在本例中不是)中访问介质包中的信息以进行配置。例如,如果我将传感器连接到收割箱,并且该传感器属于原始类型,则需要指定要测量的物质,最好使用助记符来表示包装介质中状态向量存储中的物质位置。当然,我可以逐个导入配置所需的助记符,但使用介质包时更短,更易读。

    2. 可以从FMU访问介质包中的信息。此程序包可能不仅包含助记符,而且还包含有关在设计FMU和交互式仿真的尾部用户界面时要使用的媒体的各种事实。这就是我在Python中使用JModelica所做的事情。这实际上可以正常工作,就像现在使用JModelica和PyFMI一样,但是我所学到的东西在Modelica中是禁止的。

  2. 在几个地方,我将介质nc中的组件数量传输给不同的设备型号。而且我使用连接器间接地进行了nc的传输,并“测量”了向量的大小,在编译时在Modelica中这样做是不行的。目前,这在JModelica和OpenModelica中均适用,但目前尚不可行我在Dymola中解决了这个问题,方法是在未指定的通用包装设备中引入一个局部常量,但稍后在将包装适应应使用的介质时给定一个适当的数字,然后得到值medium.nc

这些修改使代码更普遍地被接受,并且至少对JModelica,OpenModelica和Dymola有效。但是,我对解决方案不太满意,因为它不能解决如上所述的用户需求。

此外,对于此“解决方案”,“替代方案2”(分两个(或更多步骤)对库进行修改)不相关-毕竟这是帖子中的关键问题。我将在稍后的新文章中尝试用一个较小的示例来重新构建这个问题。

在库DEMO_v18_alt1下面,然后是应用程序d18_alt1_app7

    package DEMO_v18_alt1

        // Here I have put together a small demo-library to illustrate questions
        // around structuring handling of medium. The key structures are taken
        // from MSL fluid, I think it is fair to say.

    //  ---------------------------------------------------------------------------------------------
    //     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_v18_alt1.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;

        model Reaction3
            constant Integer nc = 3;
            outer Real[nc] c;
            outer Real[nc] q;           
        equation
            q[1] = 0;
            q[2] = 0;
            q[3] =-c[3];
        end Reaction3;      

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

        package Equipment

            constant Integer nc;

            connector LiquidCon
                Real[nc] c                                         "Substance conc";
                flow Real F (unit="m3/s")                          "Flow rate";
            end LiquidCon;              

            replaceable model ReactionType = NoReaction            // Alternative 1
                constrainedby ReactionTypeInterface;               

            partial model ReactionTypeInterface                    // Alternative 1
                outer Real[nc] c, q;
            end ReactionTypeInterface;

            model NoReaction                                       // Alternative 1
                extends ReactionTypeInterface;          
            equation
                for i in 1:nc loop
                    q[i] = 0;
                end for;
            end NoReaction;             

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

            model FeedtankType
                LiquidCon outlet;                                  
                parameter Real[nc] c_in (each unit="kg/m3") 
                                = {1.0*k for k in 1: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:nc loop
                    outlet.c[i] = c_in[i];
                end for;
                der(V) = outlet.F;               
            end FeedtankType;

            model HarvesttankType
                // Connection to reaction
                // replaceable model ReactionType = NoReaction constrainedby ReactionTypeInterface;   // Alternative 2

                ReactionType reaction;
                inner Real[nc] c                            "Substance conc";
                inner Real[nc] q                            "Reaction rate";        

                LiquidCon inlet, port;                                   
                parameter Real V_0 (unit="m3") = 1.0   "Initial harvest liquid volume";
                parameter Real[nc] m_0 
                      (each unit="kg/m3") = zeros(nc)       "Initial substance mass";
                Real[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:nc loop
                    der(m[i]) = inlet.c[i]*inlet.F + q[i];
                    c[i] = m[i]/V;
                    port.c[i] = c[i];
                end for;
                der(V) = inlet.F;               
            end HarvesttankType;

        end Equipment;

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

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

    //  ---------------------------------------------------------------------------------------------
    //  Adaptation of library for the actual culture and media
    //  ---------------------------------------------------------------------------------------------

        package Equipment3                                         // Alternative 1
            import DEMO_v18_alt1.Equipment;
            extends Equipment(nc=Medium3.nc,
                              redeclare model ReactionType=Reaction3);
        end Equipment3;

    //  package Equipment3                                         // Alternative 2
    //      import DEMO_v18_alt2.Equipment;
    //      extends Equipment(nc=Medium3.nc);
    //  end Equipment3;

    //  model HarvesttankType3
    //      import DEMO_v18_alt2.Equipment3.HarvesttankType;
    //      extends HarvesttankType(redeclare model ReactionType=Reaction3);
    //  end HarvesttankType3;

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

        model Test
            package medium = DEMO_v18_alt1.Medium3;                // Not accessible in FMU though
            Equipment3.FeedtankType feedtank;
            Equipment3.HarvesttankType harvesttank;                // Alternative 1 
    //      HarvesttankType3 harvesttank;                          // Alternative 2
            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_v18_alt1;

这里是应用程序代码

    encapsulated package d18_alt1_app7 

        // Here I put together an application for 7 substances - print 8 pt
        // and import code from the library DEMO.

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

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

        package Medium7
            import M2 = DEMO_v18_alt1.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;

        model Reaction7
            constant Integer nc = 7;
            outer Real[nc] c;
            outer Real[nc] q;           
        equation
            q[1] = 0;
            q[2] = 0;
            q[3] = 0;
            q[4] = 0;       
            q[5] = 0;               
            q[6] = 0;       
            q[7] =-c[7];
        end Reaction7;  

    //  ---------------------------------------------------------------------------------------------
    //     Adaptation of library DEMO_v18_alt1 to Medium7 and Reaction7  
    //  ---------------------------------------------------------------------------------------------

        package Equipment7
            import DEMO_v18_alt1.Equipment;
            extends Equipment(nc=Medium7.nc,
                              redeclare model ReactionType=Reaction7);
        end Equipment7;

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

        import DEMO_v18_alt1.Control;

        model Test
            package medium = d18_alt1_app7.Medium7;                // Not accessible in FMU though
            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 d18_alt1_app7;