modelicaopenmodelicajmodelica

How to describe media along a continuous production line with different operations?


I would like to describe a continuous production line with a media flow and with different process units along the line. Outflow of media from one unit is inflow to the next unit. The media can typically be described by a flow rate, pressure and the concentration of a number of substances. A core group of substances go through the whole production line but each unit may need to take into account some extra substances. The easiest way is to have a common media definition and keep substances zero for unit of operation where not relevant. It would be more concise and practical i think, to change media description for each unit to avoid a number of zero-variables.

So how do we in Modelica describe such a translation of core media components from one kind of media to another? And we would like to keep the connectors "balanced".

Let us take a look at a basic example. A feedtank is connected with a pipe to a harvesttank. Then feedtank has media components A and B while harvesttank has components B and C. The adaptation of media is done in the pipe-model. The code below works in both JModelica and OpenModelica and do not give any compiler complaints. Still I wonder if this approach is sound?

    package DEMO_v52

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

        partial package MediumBase
            constant String name                                   "Medium name";
            constant Integer nc = 1                                "Number of substances";
            replaceable type Concentration = Real[nc]              "Substance conc";        
        end MediumBase;

    //  ---------------------------------------------------------------------------------------------
    //     Media specified  
    //  ---------------------------------------------------------------------------------------------

        package MediumAB 
            extends MediumBase
                (name="Two component medium A, B",
                 nc=2);
            constant Real[nc] mw = {10, 20}                        "Substance weight";  
            constant Integer A = 1                                 "Substance index";
            constant Integer B = 2                                 "Substance index";
        end MediumAB;

        package MediumBC 
            extends MediumBase
                (name="Two component medium B, C",
                 nc=2);
            constant Real[nc] mw = {20, 30}                        "Substance weight";  
            constant Integer B = 1                                 "Substance index";
            constant Integer C = 2                                 "Substance index";
        end MediumBC;

    //  ---------------------------------------------------------------------------------------------
    //     Equipment dependent on the medium but written in a general way 
    //  ---------------------------------------------------------------------------------------------

        package EquipmentLib
         
            import DEMO_v52.MediumAB;
            import DEMO_v52.MediumBC;       

            connector LiquidConAB
                Real p                                              "Pressure"; 
                flow Real F (unit="m3/s")                           "Flow rate";
                stream MediumAB.Concentration c                     "Substance conc";
            end LiquidConAB;

            connector LiquidConBC
                Real p                                              "Pressure"; 
                flow Real F (unit="m3/s")                           "Flow rate";
                stream MediumBC.Concentration c                     "Substance conc";
            end LiquidConBC;

            model PipeType
                LiquidConAB inlet;
                LiquidConBC outlet; 
                parameter Real area = 1;
            equation
                inlet.F = -outlet.F;
                outlet.F = area^2*(outlet.p - inlet.p);            // Linearized Bernoulli equation         
                outlet.c[1] = inStream(inlet.c[2]);
                outlet.c[2] = 0;                                   // Reduction of media components 
                inlet.c[2] = inStream(outlet.c[1]);
                inlet.c[1] = 0;                                    // Reduction of media components
            end PipeType;

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

          model HarvesttankType
             LiquidConBC inlet;
                parameter Real p = 0.0                             "Pressure";                      
              parameter Real V_0 (unit="m3") = 1.0                 "Initial harvest liquid volume";
                parameter Real[MediumBC.nc] m_0 
                      (each unit="kg/m3") = zeros(MediumBC.nc)     "Initial substance mass";
                Real[MediumBC.nc] m 
                      (start=m_0, each fixed=true)                 "Substance mass";
                Real[MediumBC.nc] c                                "Substance conc"; 
              Real V(start=V_0, fixed=true, unit="m3")             "Harvest liquid volume";
           equation
                inlet.p = p;
                inlet.c = c;
              der(V) = inlet.F;
                for i in 1:MediumBC.nc loop
                    der(m[i]) = actualStream(inlet.c[i])*inlet.F;
                    c[i] = m[i]/V;
                end for;               
           end HarvesttankType;
        end EquipmentLib;
  
    //  ---------------------------------------------------------------------------------------------
    //     Example of a system 
    //  ---------------------------------------------------------------------------------------------

        model Test
            EquipmentLib.FeedtankType feedtank;
            EquipmentLib.HarvesttankType harvesttank;
            EquipmentLib.PipeType pipe;
        equation
            connect(feedtank.outlet, pipe.inlet);
            connect(pipe.outlet, harvesttank.inlet);
        end Test;

    end DEMO_v52;

In my immediate applications I do not need to model flow reversibility which would require special care if number of substances change between process units. Handling of flow reversibility is one important motivation for using the Modelica stream concept. Still I generally would like to keep using the stream concept even though I do not focus on flow reversibility. But is it good and proper use of the concept?

The alternative approach is, as mentioned above, to have a common media definition for all process units, and then describe describe that these substances are not affected in most units. This introduce a lot of states z _i of type dz_i/dt = 0 and is not only distracting to see, but may also bring a burden to numerical solvers, but I am not too sure. Can someone confirm or reject my worry here?

How is the need for varying detail of media in a continuous production line addressed in Modelica Standard Library?

In a more realistic example you may have an increasing number of substances to describe more downstream of the production line. For instances there are typically more substances related to quality at the end than in the beginning. It is awkward to introduce description of such substances early in the production since not relevant and would be described as zero.


Solution

  • There are several aspects of this question and I perceive some uncertainty around how to think about the impact of the stream concept in the situation of mixed media which it is not designed for really. Media can be much more complex than in the example above used for illustration of the problem. Below I try to summarize what I have got from you and some other knowledgeable people outside this forum.

    1. Here is clear support for the "safe" advice given by Hans and Rene Just, to have a common media definition for many process units along the production line although some substances will be zero all the time.
    2. The extra computational burden for these "zero-substances" are usually small, but may need analysis. There are models where keeping these "zero-substance" becomes a significant computational burden.
    3. There is also in certain applications a tradition to use different media and construct adapter code to allow for transport of media between units with different media definition, as Rene Just describe. To allow for reversible flow you need careful design of the adapter code to make proper approximations. For equipment with the same media the stream concept handle reversible flow automatically in a much more exact way.
    4. In applications where you can guarantee there is no reversible flow the adapter code can likely be simplified. Especially with a media of say incompressible water and trace substances, like my example above. It is some theoretical guidance here I was looking for.