I am trying to create a modular simulation of flow components (at first without using the standard Modelica.Fluid, for learning and simplicity). I have decided to start with only worrying about mass flow (not temperature/enthalpy) and have created a connector Stream
shown below:
connector Stream
Real pressure;
flow Real m_flow;
end Stream;
Using this connector, I want to track pressure and flow throughout a simple system:
flow source >> valve >> tank >> pump >> flow sink
I have created the following models for these components:
model FlowSource "Flow Source can be used as a starting point of a flow"
parameter Real pressure = 1.0 "Pressure of the source";
Stream outlet;
equation
outlet.pressure = pressure;
end FlowSource;
model Valve
parameter Real Cv "Valve Coefficient, Cv";
Real setpoint(min=0,max=1) "Valve setpoint";
Real dp(start=1) "Pressure drop across the valve";
Real m(start=Cv) "Flow through the valve";
Real f(min=0,max=1) "Valve Characteristic f(setpoint)";
Stream inlet, outlet;
equation
inlet.m_flow + outlet.m_flow= 0.0; // Conservation of mass
dp = inlet.pressure - outlet.pressure; // Pressure drop calculation
f = setpoint; // linear valve
m = inlet.m_flow;
m = if(dp >= 0) then Cv*f*sqrt(dp) else -Cv*f*sqrt(-dp);
end Valve;
model Tank "Simple model of a tank"
parameter Real volume=1 "tank volume (m^3)";
parameter Integer num_ports=1 "Number of ports";
parameter Real static_pressure=1 "Internal Tank Pressure";
parameter Real initial_level = 0;
Stream[num_ports] ports "Stream Connectors";
Real level "Level in % 0-100";
protected
Real vol "Volume of medium in the tank";
initial equation
level = initial_level;
equation
for i in 1:num_ports loop
ports[i].pressure = static_pressure;
end for;
der(vol) = sum(ports.m_flow); // need to add density conversion
level = vol * 100 / volume;
end Tank;
model Pump "Simple model of a Pump"
Real setpoint(min=0,max=1) "setpoint of the pump (0.0 to 1.0)";
Stream inlet, outlet;
protected
Real dp "Pressure differential across the pump";
Real f "flow rate inside pump";
equation
inlet.m_flow+ outlet.m_flow= 0.0;
dp = outlet.pressure - inlet.pressure;
f = inlet.m_flow;
dp = (100-400*(f^2)); // insert better pump char. curve here
end Pump;
model FlowSource "Flow Source can be used as a starting point of a flow"
parameter Real pressure = 1.0 "Pressure of the source";
Stream outlet;
equation
outlet.pressure = pressure;
end FlowSource;
I can create instances of these models and connect them together in a separate model. However I am running into an issue of what I think is boundary conditions. I would like to specify the pressure of the incoming fluid source. The valve will then have a pressure drop across it as the flow moves to the tank. This is determined by the difference between the nominal pressure inside the tank and the fluid source, and should work ok.
The issue is when the pump meets the fluid sink (or if I had a pump going directly into a tank). Setting the pressure of the fluid sink causes problems with my pump because it also sets the pressure of the pump outlet (they are connected). The pressure of the pump needs to be a function of the inlet pressure and flow rate (it should add some pressure to the system), and the sink's pressure should be calculated based on this. However that pressure is also needed in the calculation for dp... so I end up in a circle.
What am I doing wrong, and is there a better way to implement a system like this?
Thanks!
Edit: I forgot to mention that the setpoints (pump does not yet implement it) are set in the main model that uses these models with an equation. So all of my models are balanced. (See my comment on the answer below).
My first advice is to "unit test" each of your component. Already at that point you will see that both the pump and the valve model have one variable too may (or are missing one equation).
If you want to unit test your tank model you should make a model of a mass flow source (the one you call FlowSource
is actually a pressure source) and connect two of them to your tank.
In the valve model you should make setpoint
a parameter or an external input. In the pump model the variable setpoint
is not used, so you can either delete it or make it a parameter.
Once you have fixed that you model works fine.
I put the fixes in an mo file that you can grab here:
https://drive.google.com/file/d/0B8ojPn4YxnI9blRodUVWUjVGTE0/view?usp=sharing
Regards, Rene Just Nielsen