How to construct a balanced connector for liquids in Modelica?
Asked Answered
C

3

7

Status of the post:

200313 Got an answer with code DEMO_v42 that I accept for the bounty!

200310 I comment on two key papers suggested yesterday. Still do not understand how to update DEMO_v41.

200309 I want to underline that the key problem is how to introduce the concept of stream in the code DEMO_v41 (if possible) and in this way make the connector balanced. The variable c that is the concentration should be declared stream, but how should equations be updated with inStream or actualStream - that I would be glad to see!

200226 The post example DEMO_v41 was added and is a simplified and I hope more readable code than the first DEMO_v40.

200225 I gave some comments to the answers given and to tried to focus the readers on the actual problems, but little happened.

200224 I got some input to the post both general and detailed. The detailed comments was of less value and partly an effect of misunderstanding the problem. The more general answer from Rene is good but too general. I really like to understand how to use the concept of stream with small examples, before I think about using Modelica.Media etc. It is a learning process.


I want to know how to correctly define a connector for a liquid that has a number of components with different concentrations in solution and then that solution has a flow rate. Pressure in the liquid is negligible. The standard connector I have used for long time is:

connector LiquidCon
   nc=5;
   Real c[nc]        “Component concentrations”;
   flow Real F       “Flow rate”;
end LiquidCon;

The connector works well in JModelica and OpenModelica, but I get warnings in OpenModelica that the connector is not balanced. In the Modelica language specification, section 9.3.1 I see that my construct is actually not legal, see https://www.modelica.org/documents/ModelicaSpec34.pdf. How can I make a connector that satisfy the demands?

I have spent some time reading chapter 5.10 on the concept of “stream” in Fritzons book 2n edition, but I need to study it in more detail.

The reason my simple connector brings a warning is that when you declare a flow variable the compiler assumes that the other variable is a potential variable to that flow variable, i.e. at least the number of flow and potential variables must be the same in a connector. Then of course in my case the component concentration is not a potential variable, but that the compiler cannot detect.

In the introductory section of chapter 5.10 the scope of the concept of “stream" seems to be “...application of bidirectional flows of matter with associated properties…”. In my area of applications I doubt that I need to consider bidirectional flows. This means that use of stream is an “overkill”. But that seems also to imply that I should not use the concept of “flow” either, which is a bit of a pity. Should we really stop using the concept “flow” here?

Anyway, I have tried to put together a more basic example than could be found in the book of Fritzson on this subject to see how use of the concept of “stream” would look and also what overhead in computation time etc you get. In the example below I model flow of a liquid from feed tank to harvest tank. The flow is governed by a pressure difference now. The code DEMO_v41 works and gives a warning that the connector is not balanced. If I now declare substrate concentration c to be “stream”, how should I now update the code with use of inStream and actualStream to make it work the same way, but now with this balanced connector?

package DEMO_v41

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

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

//  ---------------------------------------------------------------------------------------------
//     Equipment
//  ---------------------------------------------------------------------------------------------

    package EquipmentLib

        connector LiquidCon
            Real P                                             "Pressure"; 
            flow Real F                                        "Flow rate";
            Real c                                             "Substance conc";
        end LiquidCon;

        model PipeType
            LiquidCon inlet, outlet;
            parameter Real area = 1;
        equation
            inlet.F = -outlet.F;
            outlet.F = -area^2*(inlet.P - outlet.P);           // Linearized Bernoulli equation
            outlet.c = inlet.c;
        end PipeType;

        model FeedtankType
            LiquidCon outlet;                                  
            parameter Real P = 0.1                             "Pressure"; 
            parameter Real V_0 = 100                           "Initial feed volume";         
            parameter Real c_in = 1.0                          "Feedtank conc"; 
            Real V(start=V_0, fixed=true)                      "Feed volume";
        equation    
            outlet.c = c_in;
            outlet.P = P;
            der(V) = outlet.F;               
        end FeedtankType;

        model HarvesttankType
            LiquidCon inlet;
            parameter Real P = 0.0                             "Pressure";                      
            parameter Real V_0 = 1.0                           "Initial harvest liquid volume";
            parameter Real m_0 = 0.0                           "Initial substance mass";
            Real V(start=V_0, fixed=true)                      "Harvest liquid volume";
            Real m(start=m_0, fixed=true)                      "Substance mass";
            Real c                                             "Substance conc"; 
        equation
            inlet.P = P;
            der(V) = inlet.F;
            der(m) = inlet.c*inlet.F;
            c = m/V;            
        end HarvesttankType;
    end EquipmentLib;

//  ---------------------------------------------------------------------------------------------
//     Example of 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_v41;

The older example DEMO_v40 below is more general and harder to read, but kept for reference since one early answer around this example.

The compilation (JModelica 2.14) error message I get is: “Error in flattened model: The system is structurally singular. The following variables(s) could not be matched to an equation: harvesttank.inlet.c[1], pipe.outlet.c[1]. OpenModelica (1.16) gives about the same message. What is wrong here?

package DEMO_v40

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

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

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

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

    record Medium_data
        constant String name = Medium1.name;
        constant Integer nc = Medium1.nc;
        constant Real[nc] mw = Medium1.mw;
        constant Integer A = Medium1.A;
    end Medium_data;

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

    package EquipmentLib
        replaceable package Medium = MediumBase                // formal parameter - EquipmentLib
            constrainedby MediumBase;

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

        model PipeType
            LiquidCon inlet, outlet;
            parameter Real area = 1;
        equation
            inlet.F = -outlet.F;
            outlet.F = area^2*(inlet.P - outlet.P);            // Linearized Bernoulli equation
            for i in 1:Medium.nc loop
                outlet.c[i] = inlet.c[i];
            end for;
        end PipeType;

        model FeedtankType
            LiquidCon outlet;                                  
            parameter Real P = 0.1                             "Pressure"; 
            parameter Real V_0 (unit="m3") = 100               "Initial feed volume";         
            parameter Real[Medium.nc] c_in (each unit="kg/m3") 
                            = {1.0*k for k in 1:Medium.nc}     "Feed inlet conc";                        
            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;
            outlet.P = P;
            der(V) = outlet.F;               
        end FeedtankType;

        model HarvesttankType
            LiquidCon inlet;
            parameter Real P = 0.0                             "Pressure";                      
            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[Medium.nc] c                                  "Substance conc"; 
            Real V(start=V_0, fixed=true, unit="m3")           "Harvest liquid volume";
        equation
            inlet.P = P;
            der(V) = inlet.F;
            for i in 1:Medium.nc loop
                der(m[i]) = inStream(inlet.c[i])*inlet.F;
                c[i] = m[i]/V;
            end for;               
        end HarvesttankType;
    end EquipmentLib;

//  ---------------------------------------------------------------------------------------------
//     Adaptation of package Equipment to Medium1 
//  ---------------------------------------------------------------------------------------------

    package Equipment
        import DEMO_v40.EquipmentLib;
        extends EquipmentLib(redeclare package Medium=Medium1);
    end Equipment;

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

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

end DEMO_v40;
Cookie answered 22/2, 2020 at 9:54 Comment(4)
Note, that if we take a way the prefix stream in LiquidCon and in HarvesttankType do not use inStream, but write: der(m[i] = inlet.c[i]*inlet.F then the system work. So the error is about my usage and lack of understanding of stream and inStream (or actualStream)Cookie
Related, balanced physical connector: modelica.org/events/modelica2008/Proceedings/sessions/… To my understanding, stream connectors should have exactly one potential variable and one flow variable, and as many stream variables as you want.Collodion
Related, the stream connectors paper: doi.org/10.3384/ecp09430078Collodion
Thanks for the reading references which I think is important. I have actually read them briefly a few weeks ago and read again now. The last paper “Stream connector…” in section 3 has a connector like mine if we exchange enthalpy to concentration. Thus in my case the energy balance is replaced by a mass balance. My example is a degenerated version of what we have in section 3, something like Figure 3. But, how to use inStream() in the right way in the code DEMO_v41 remains not clear to me.Cookie
P
2

After some thought I believe the following is your example converted to use stream variables directly (although I agree that making it compatible with MSL would be good, as @ReneJustNielsen suggested).

package DEMO_v42

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

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

//  ---------------------------------------------------------------------------------------------
//     Equipment
//  ---------------------------------------------------------------------------------------------

    package EquipmentLib

        connector LiquidCon
            Real P                                             "Pressure";
            flow Real F                                        "Flow rate";
      stream Real c_outflow "Substance conc";
        end LiquidCon;

        model PipeType
            LiquidCon inlet, outlet;
            parameter Real area = 1;
        equation 
            inlet.F = -outlet.F;
            outlet.F = -area^2*(inlet.P - outlet.P);           // Linearized Bernoulli equation
            outlet.c_outflow = inStream(inlet.c_outflow);
            inlet.c_outflow=inStream(outlet.c_outflow);
        end PipeType;

        model FeedtankType
            LiquidCon outlet;
            parameter Real P = 0.1                             "Pressure";
            parameter Real V_0 = 100                           "Initial feed volume";
            parameter Real c_in = 1.0                          "Feedtank conc";
            Real V(start=V_0, fixed=true)                      "Feed volume";
        equation 
            outlet.c_outflow = c_in;
            outlet.P = P;
            der(V) = outlet.F;
        end FeedtankType;

        model HarvesttankType
            LiquidCon inlet;
            parameter Real P = 0.0                             "Pressure";
            parameter Real V_0 = 1.0                           "Initial harvest liquid volume";
            parameter Real m_0 = 0.0                           "Initial substance mass";
            Real V(start=V_0, fixed=true)                      "Harvest liquid volume";
            Real m(start=m_0, fixed=true)                      "Substance mass";
            Real c                                             "Substance conc";
            Real inletC=actualStream(inlet.c_outflow);
        equation 
            inlet.P = P;
            inlet.c_outflow=c;
            der(V) = inlet.F;
            der(m) = actualStream(inlet.c_outflow)*inlet.F;
            c = m/V;
        end HarvesttankType;
    end EquipmentLib;

//  ---------------------------------------------------------------------------------------------
//     Example of 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_v42;

I added inletC to be able to compare the concentrations with the previous models.

The major change is that for a stream variable, c_outflow, there are in fact two/three different variables to use:

  • If you want the concentration if the medium were flowing out use c_outflow
  • If you want the concentration if the medium were flowing in use inStream(c_outflow)
  • If you just want the actual concentration in the flow use actualStream(c_outflow)

So for the pipe you write that the concentration flowing out from one port equals the concentration flowing into the other port, and vice versa. For the tank you just write the equation for c_outflow, but use actualStream to get the actual concentration in the flow.

Pneumonia answered 13/3, 2020 at 11:31 Comment(1)
I just would like to clarify that the variable c in harvest tank in both DEMO_v42 and DEMO_v41 represent the same variable. The variable inletC, represent as the name indicate, the concentration in the inlet before it is mixed in the harvest tank, i.e. the concentration in the feed tank.Cookie
G
5

Personally, I would "go all the way" and use stream connectors for the following reasons:

  1. During the last 15–20 years, many attempts have been made to create good thermo-hydraulic connectors in Modelica. The effort resulted in stream connectors in 2008 which is currently state-of-the-art in Modelica. It allows you to transport specific enthalpy and substance fractions (or species concentrations) with one flow variable and it enables flow reversal. Using stream connectors is not overkill.
  2. Adhering to e.g. Modelica.Fluid.Interfaces.FluidPort, your work will be compatible with many existing libraries and models and you don't need to make pumps, pipes, valves, tank models etc. yourself.

You will be faced with a couple of challenges, though:

  1. You'll need to learn the syntax and the workings of stream connectors. You can find inspiration in https://github.com/justnielsen/ModelicaTutorials
  2. You must implement a medium model based on Modelica.Media for the fluid that you will be transporting in the stream connectors. A medium models doesn't have to be very complex if you can assume constant density and/or specific heat capacity, for example. If the medium model is simple, it is computationally easy to switch between volume/mass flow rate when you specify the boundary conditions (source/sinks).
Gesture answered 24/2, 2020 at 17:11 Comment(2)
I consider to "go all the way", but from Fritzsons writing and brief reading of original papers, the motivation for introducing stream seems to be describing flow reversal, and of less interest for me. Perhaps I misunderstand though. I think it is of interest to make my small example with the concepts for "stream" to work, at least for educational purpose. I will take a look at your material also.Cookie
Benefits of stream connectors are: 1) conservation of energy (mixing of flow times enthalpy). 2) conservation of mass fractions (mixing of flow times mass fractions). 3) mass fractions/concentrations don't need corresponding flow/potential variables. 4) only one potential and one flow variable.Gesture
S
2

The correct way would be either

connector LiquidCon
   nc=5;
   Real c[nc]        “Component concentrations”;
   flow Real F[nc]       “Flow rate”;
end LiquidCon;

or

connector LiquidCon
   Real c        “Component concentrations”;
   flow Real F       “Flow rate”;
end LiquidCon;

Depending on what you want to model. Rule of thumb is: number of potentials = number of flows. Since you only use one flow and multiple concentrations it implies that you have multiple tanks-like components each with some concentration, connected by pipe-like components that allow a flow rate.

For these i would recommend the second version i posted!

Some background information: A connector is never balanced, it is assumed to provide half the number of equations compared to its unknowns. Whenever you add a connector to a component, that component has to balance it. The reason is quite simple: E.g. a connector with one potential and one flow. The direction in which the information flows is unclear, but certain is, that either the flow variable is considered known or the potential is considered known, the other one will be computed by the equations of the component. For the tank the concentration is computed by its own equations and the flow is passed by the connector (vice versa for the pipe).

Whenever two or more connector are connected all potentials are set equal and all flows sum up to be zero (Modelica Language Specification section 9.2).

I changed your example such that i can actually individually test the components. Note that i added a default value to nc, otherwise it is not possible to check single components for consistency.

package DEMO_v40

//  ---------------------------------------------------------------------------------------------

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

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

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

    record Medium_data
        constant String name = Medium1.name;
        constant Integer nc = Medium1.nc;
        constant Real[nc] mw = Medium1.mw;
        constant Integer A = Medium1.A;
    end Medium_data;

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

    package EquipmentLib

        replaceable package Medium = MediumBase                "formal parameter EquipmentLib";


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

        model PipeType
            LiquidCon inlet, outlet;
            parameter Real area = 1;
        equation
            inlet.F = -outlet.F;
            outlet.F = area^2*(inlet.P - outlet.P);            // Linearized Bernoulli equation
            for i in 1:Medium.nc loop
                outlet.c[i] = inlet.c[i];
            end for;
        end PipeType;

        model FeedtankType
            LiquidCon outlet;                                  
            parameter Real P = 0.1                             "Pressure"; 
            parameter Real V_0 (unit="m3") = 100               "Initial feed volume";         
            parameter Real[Medium.nc] c_in (each unit="kg/m3") 
                            = {1.0*k for k in 1:Medium.nc}     "Feed inlet conc";                        
            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;
            outlet.P = P;
            der(V) = outlet.F;               
        end FeedtankType;

        model HarvesttankType
            LiquidCon inlet;
            parameter Real P = 0.0                             "Pressure";                      
            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[Medium.nc] c                                  "Substance conc"; 
            Real V(start=V_0, fixed=true, unit="m3")           "Harvest liquid volume";
        equation
            inlet.P = P;
            der(V) = inlet.F;
            for i in 1:Medium.nc loop
                der(m[i]) = inStream(inlet.c[i])*inlet.F;
                c[i] = m[i]/V;
            end for;               
        end HarvesttankType;

    end EquipmentLib;

  //  ---------------------------------------------------------------------------------------------
  //     Adaptation of package Equipment to Medium1
  //  ---------------------------------------------------------------------------------------------

    package Equipment
        import DEMO_v40.EquipmentLib;
        extends EquipmentLib(redeclare package Medium=Medium1);
    end Equipment;

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

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

end DEMO_v40;

With this i went to OMEdit and checked every component individually with the CheckModel button (Single check mark on green circle in the top middle of OMEdit). I realized that your connector has 3 unknowns and 1 equation which is illegal (as i said it should be 2:1 ratio). That also results in all your other components being illegal.

Since it would be quite the work to debug all your stuff i can only provide something i made some time ago for a student project but it should showcase what has to be done. You don't need to pass both pressure and concentration since they should be algebraically connected anyways. I used the height instead.

See following answer for model, it does not fit in this (and i can't add files here).

EDIT: I just made a git repository. Much easier actually:

HTTPS: https://github.com/kabdelhak/TankSystem

SSH: [email protected]:kabdelhak/TankSystem.git

Smashed answered 24/2, 2020 at 14:8 Comment(5)
> Some background information: A connector is never balanced, it is assumed to provide half the number of equations compared to its unknowns. Whenever you add a connector to a component, that component has to balance it. I am curious about this: What does that tell you about the "proper" amount of equations in a component - when is it "right", especially when fluids are involved? E.g. when checking the MSL Modelica.Fluid.Valves.ValveIncompressible (which is not partial), I get 18 equation(s) and 16 variable(s), which seems wrong? But it's an MSL model, so that cannot be correct?Canorous
> I realized that your connector has 3 unknowns and 1 equation which is illegal (as i said it should be 2:1 ratio). Hm, when I check the MSL Modelica.Fluid.Interfaces.FluidPort, that connector also has 1 equation(s) and 3 variable(s), but I suspect it would not be illegal (as it's widely used). What's behind this?Canorous
It seems like i just did not know about following restriction on the (2:1)-rule. For each non-partial connector class the number of flow variables shall be equal to the number of variables that are neither parameter, constant, input, output, stream nor flow. (Modelica Specification v3.4 chapter 9.3.1) It seems like your connectors are actually correct, sorry! The problem seems to be the component HarvesttankType which is not balanced.Smashed
1) I think you misunderstand the problem somewhat. Let me clarify. The liquid we are working with has a few different substances dissolved, with concentration listed in vector c. This is quite typical for describing a chemical process. 2) The flow-potential pair is here flow-rate and pressure and concentration has nothing to do with that, normally. And stream is intended for such variables of property, what I understand. 3) A brief look at you github-materai show that it contains flow-potential variables but there is no use of stream and that is what I am looking for.Cookie
Yes you are right, unfortunately i am not really familiar with these stream connectors. My suggestion would be to look at HarvesttankType and try to see if you missed an equation here. As i said connectors are not supposed to be balanced (if they contain flow variables) so they have to be balanced by the component using it. If you use a connector in a component you need to provide an extra equation for each flow variable in that connector. And in the case of stream variables it seems like you also need to provide extra equations for each of those since they are considered unknown.Smashed
P
2

After some thought I believe the following is your example converted to use stream variables directly (although I agree that making it compatible with MSL would be good, as @ReneJustNielsen suggested).

package DEMO_v42

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

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

//  ---------------------------------------------------------------------------------------------
//     Equipment
//  ---------------------------------------------------------------------------------------------

    package EquipmentLib

        connector LiquidCon
            Real P                                             "Pressure";
            flow Real F                                        "Flow rate";
      stream Real c_outflow "Substance conc";
        end LiquidCon;

        model PipeType
            LiquidCon inlet, outlet;
            parameter Real area = 1;
        equation 
            inlet.F = -outlet.F;
            outlet.F = -area^2*(inlet.P - outlet.P);           // Linearized Bernoulli equation
            outlet.c_outflow = inStream(inlet.c_outflow);
            inlet.c_outflow=inStream(outlet.c_outflow);
        end PipeType;

        model FeedtankType
            LiquidCon outlet;
            parameter Real P = 0.1                             "Pressure";
            parameter Real V_0 = 100                           "Initial feed volume";
            parameter Real c_in = 1.0                          "Feedtank conc";
            Real V(start=V_0, fixed=true)                      "Feed volume";
        equation 
            outlet.c_outflow = c_in;
            outlet.P = P;
            der(V) = outlet.F;
        end FeedtankType;

        model HarvesttankType
            LiquidCon inlet;
            parameter Real P = 0.0                             "Pressure";
            parameter Real V_0 = 1.0                           "Initial harvest liquid volume";
            parameter Real m_0 = 0.0                           "Initial substance mass";
            Real V(start=V_0, fixed=true)                      "Harvest liquid volume";
            Real m(start=m_0, fixed=true)                      "Substance mass";
            Real c                                             "Substance conc";
            Real inletC=actualStream(inlet.c_outflow);
        equation 
            inlet.P = P;
            inlet.c_outflow=c;
            der(V) = inlet.F;
            der(m) = actualStream(inlet.c_outflow)*inlet.F;
            c = m/V;
        end HarvesttankType;
    end EquipmentLib;

//  ---------------------------------------------------------------------------------------------
//     Example of 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_v42;

I added inletC to be able to compare the concentrations with the previous models.

The major change is that for a stream variable, c_outflow, there are in fact two/three different variables to use:

  • If you want the concentration if the medium were flowing out use c_outflow
  • If you want the concentration if the medium were flowing in use inStream(c_outflow)
  • If you just want the actual concentration in the flow use actualStream(c_outflow)

So for the pipe you write that the concentration flowing out from one port equals the concentration flowing into the other port, and vice versa. For the tank you just write the equation for c_outflow, but use actualStream to get the actual concentration in the flow.

Pneumonia answered 13/3, 2020 at 11:31 Comment(1)
I just would like to clarify that the variable c in harvest tank in both DEMO_v42 and DEMO_v41 represent the same variable. The variable inletC, represent as the name indicate, the concentration in the inlet before it is mixed in the harvest tank, i.e. the concentration in the feed tank.Cookie

© 2022 - 2024 — McMap. All rights reserved.