Proper use of inStream() and and actualStream() in Modelica when no volume present - modelica

I have used the Modelica "stream" concept for connectors for some time. What I understand the functions inStream() and actualStream() are designed for use
when the model has a volume. But here are important cases where there is no
volume and you need for convenience stick to the connectors you have. One example is a ProbeSensor that is mounted into a reactor volume and measures one of the species in the liquid, but does not "consume" any liquid.
The code below works using inStream(). However, I am inclined to instead use actualStream() since it "handles zero flow". But if I do the change the model does not compile and I get translation error that here are more variable than equations.
Is the code with inStream() after all correct?
Or how should it be modified?
LiquidCon
stream Real[2] c;
flow Real F;
Real p;
end LiquidCon;
block ProbeSensor
LiquidCon probe;
output RealOutput out;
constant Integer component = 2 "The liquidphase component measured index";
parameter Real T (unit="h") = 0.05 "Time constant of measurement";
parameter Real x_0 = 0.0 "Initial state of measurement device";
Real x(start=x_0, fixed=true) "State variable measurement device";
Real p (unit="bar") "Pressure";
equation
probe.F = 0;
p = probe.p;
for i in 1:2 loop
if (i==component) then
T*der(x) + x = inStream(probe.c[component]);
inStream(probe.c[component]) = probe.c[component];
out = x;
else
inStream(probe.c[i]) = probe.c[i];
end if;
end for;
end ProbeSensor;

Yes, inStream() is the best solution for this type of sensor/probe model.
inStream() gives you a value for the hypothetical case of fluid streaming into the component model. No matter what the real flow direction is (in this case 0 flow). And that's perfectly right for sensors.
As a general rule: If you can do something with inStream() than go for it. Only use actualStream() if you really need it.
Reason for that: actualStream() is basically an if expression. And that is always nonlinear, which can easily produce ugly nonlinear systems in the overall system model.

Related

Solve equation system only once at initialization

I need modelica to solve an equation system for a variable only once at initialization. After that the variable 'turns' into a parameter and does not change any more. Is there any way to accomplish this?
As background information: I implemented a modelica model for a simple pump which has the input parameters maximum volume flow rate, pressure loss of the system at maximum flow rate, total pipe length and surface roughness. Now I need to calculate the corresponding (mean) hydraulic diameter of the pipes so that I can estimate the pressure loss at variable volume flow rate during the normal simulation. I'm using the Colebrook-White-Approach so I need to solve an equation system.
The code looks like this. The prefix var_ indicates its a variable, param_indicates it's a known parameter. I need var_d.
// calculation of velocity and reynolds number
var_w_max = param_Q_max/(Pi/4*var_d^2);
var_Re_max = var_w_max*var_d/param_my;
// Colebrook-White approach
1/sqrt(var_lambda_max) = -2*log10(2.51/(var_Re_max*var_lambda_max)+param_k/(3.71*var_d));
param_p_loss = var_lambda_max*param_l/var_d*param_rho_h2o*var_w_max^2/2;
If you want to compute a parameter based on values at the start and then freeze it you can use an initial equation.
E.g. if you want to compute param_p_loss and param_k based on the last two equations you do:
parameter Real param_p_loss(fixed=false);
parameter Real param_k(fixed=false);
initial equation
1/sqrt(var_lambda_max) = -2*log10(2.51/(var_Re_max*var_lambda_max)+param_k/(3.71*var_d));
param_p_loss = var_lambda_max*param_l/var_d*param_rho_h2o*var_w_max^2/2;
equation
...
The fixed=false mean that the parameter needs to be solved initially.
You can in fact solve for a parameter value during initialization. The clue lies in the modifier fixed=false.
Below is a simple example of a pressure drop where you solve for a hydraulic diameter during initialization to obtain a desired nominal mass flow.
model SolveParameter
parameter Modelica.SIunits.Diameter dh(fixed=false, start=0.1)
"Hydraulic diameter. Start attribute is guess value";
parameter Real k=0.06 "Roughness, pipe length etc. combined";
parameter Modelica.SIunits.MassFlowRate m_flow_nominal=2
"Nominal mass flow rate";
parameter Modelica.SIunits.PressureDifference dp=1e5
"Differential pressure (boundary condition)";
Modelica.SIunits.MassFlowRate m_flow "Time varying mass flow rate";
initial equation
m_flow = m_flow_nominal;
equation
m_flow = dh*k*sqrt(dp);
end SolveParameter;
If the diameter is a parameter within an instatiated class (pipe model) you can apply the fixed=false when you instantiate the model, i.e.
Modelica.Fluid.Pipes.DynamicPipe pipe(diameter(fixed=false));
Best regards,
Rene Just Nielsen

What is the difference between check a model and tranlate a model in Dymola

I am using Dymola, but I am not sure about the difference between check a model and translate a model.
So I did a test.
Here is the code of the connector and the model file
connector Port
flow Real Q;
Real P;
Real T;
end Port;
model Inlet
parameter Real Q = 1;
parameter Real P = 2;
parameter Real T = 3;
Port a;
equation
a.Q = Q;
a.P = P;
a.T = T;
end Inlet;
If I check the model, Dymola would generate a .mof file:
model lab.Inlet
parameter Real Q = 1;
parameter Real P = 2;
parameter Real T = 3;
Real a.Q;
Real a.P;
Real a.T;
// Equations and algorithms
// Component
// class lab.Inlet
equation
a.Q = Q;
a.P = P;
a.T = T;
end lab.Inlet;
If I translate the model, the .mof file is like the following:
model lab.Inlet
parameter Real Q = 1;
parameter Real P = 2;
parameter Real T = 3;
Real a.Q;
Real a.P;
Real a.T;
// Equations and algorithms
// Component
// class lab.Inlet
equation
a.Q = Q;
a.P = P;
a.T = T;
a.Q = 0.0;
end lab.Inlet;
I could see that in the .mof file generated by translation there is one more line: a.Q = 0.0;.
So, my question is what is the detailed difference between check and translation? Is there a detailed document for this topic?
Checking a model should just create a small intermediate model that can be checked for logical errors (#eqs == #unknowns, etc.) but is not used for symbolic manipulations afterwards.
Instantiating a model should create a flat model that can be used for symbolic manipulations.
Translating a model should first run instantiation and afterwards perform symbolic manipulations (BLT, etc.) and actually create simulation code.
OpenModelica kind of does it this way, i can't for sure tell what dymola does, but i guess this gives you an idea. I don't know if there is any further documented explanation for this.
Adding to the other answer.
TL:DR;
Check normally assumes the model will be a sub-component of a larger model.
Translates is intended for running the model, i.e. the model should be complete in itself.
Longer version:
For "Check" the component is normally checked assuming a generic connection to the connector a (in general generic connections to all connectors). That connection will add one equation, and thus there will be one equation too many in this model - but we don't know exactly which one.
There are also some additional checks for instantiation, but normally missing modifiers (parameter values and redeclarations of partial models) is seen as a non-issue - since it is not a complete model.
For "Translate" it is assumed that you are translating a complete model, and non-causal connectors such as a will be default-connected, i.e. flows set to zero - which gives the specific error message you see. (And public top-level inputs would be read from dsu.txt.) Additionally the model is translated to C-code, which requires a bit more.
Normally "Check" stops before "Translate" by e.g., not solving systems of equations as indicated in the other answer.
However, in recent versions of Dymola if the model has "experiment" annotation a "Check" will also check that (it is assumed you are checking a complete model) - ignoring the normally above.
Recent versions of Dymola will also report issues for the connector Port:
The connector is not balanced, it has 1 flow variables and 2
non-causal non-flow variables (including possible over-determined
ones).
For "Check" that will be a problem for some models, as Dymola has to add 1 or 2 equations per Port-connector.

Modelica - freezing a specific time value during simulation

I am having a problem that could be easily solved in a causal environment like Fortran, but has proved difficult in Modelica, considering my limited knowledge
Consider a volume with an inlet and outlet. The inlet mass flow rate is specified, while the outlet mass flow is calculated based on pressure in the volume. When pressure in the volume goes above a set point, the outlet area starts to increase linearly from its initial value to a max value and remains fixed afterwards. In other words:
A = min( const * (t - t*) + A_0, A_max)
if p > p_set
where t* = the time at which pressure in the volume exceeds the set pressure.
The question is: there's a function to capture t* during the simulation? OR how could the model be programmed to do it? I have tried a number of ways, but models are never closed. Thoughts are welcome and appreciated!
Happy holidays/New Year!
Mohammad
You may find the sample and hold example in my book useful. It uses sampling based on time whereas you probably want it based on your pressure value. But the principle is the same. That will allow you to record the time at which your event occurred.
Addressing your specific case, the following (untested) code is probably pretty close to what you want:
...
Modelica.SIunits.Time t_star=-1;
equation
when p >= p_set then
t_star = time;
end when;
A = if t_star<0 then A_max else min(const*(t - t_star) + A_0, A_max);

Inversing the modelica simulation model: steady state model

I want to know if a model can be inversed in modelica. (here inverse means: if in causal statement y= x +a; x and a are input and y is output; but if I want to find 'x' as output and 'y' and 'a' as input, the model is called reversed/inversed model) For example, if I have compressor with input air port and output air port, and port has variables associated with it are pressure(P), temperature(T) and mass flow rate(mdot). I have simple steady state model containing three equations as follow:
OutPort.mdot = InPort.mdot
OutPort.P = rc * InPort.P
OutPort.T = InPort.T * (1 + rc[ (gamma-1)/gamma) - 1][/sup] / eta);
Here, rc, gamma and eta are compression ratio, ratio of specific heat capacitites and efficiency of compressor respectively.
I want to know, if I know values of : gamma, eta, OutPort.mdot, OutPort.P and OutPort.T and InPort.P and InPort.T, can I find the value of rc.
Can I find values of rc and how should be the model of compressor with above equation in Modelica. As far as I know, there are some variables designated as parameters which can not be changed during simulation. How the modelica model should be with above equations
Thanks
Yes, this should not be a problem as long as you make sure that rc is not a parameter, but a normal variable, and you supply the appropriate number of known quantities to achieve a balanced system (roughly, number of unknowns matches number of equations).
E.g. in your case if you know/supply OutPort.P and InPort.P, rc is already determined from eq 2. Then, in the third equation, there are no unknowns left, so either the temperature values are consistent with the equation or you (preferably) leave one temperature value undetermined.
In addition if you only want to compute the parameter rc during steady-state initialization i.e. that nothing changes with time that is also possible:
...
parameter Real rc(fixed=false);
initial equation
Inport.mdot=12; // Or something else indirectly determining rc.
The fixed=false means that rc is indirectly determined from the initialization. However, if the model is not completely stationary it will only find the correct rc during the initialization and then use that afterwards.

Using coupled system of PDEs in modelica

Just few questions, i hope someone will find time to answer :).
What if we have COUPLED model example: system of n indepedent variables X and n nonlinear partial differential equations PDEf(X,PDEf(X)) with respect to TIME that depends of X,PDEf(X)(partial differential equation depending of variables X ). Can you give some advice? Here is one example:
Let’s say that c is output, or desired variable. Let’s say that r is independent variable.Partial differential equation looks like:
∂c/∂t=D*1/r+∂c/∂r+2(D* (∂^2 c)/(∂r^2 ))
D=constant
r=0:0.1:Rp- Matlab syntaxis, how to represent same in Modelica (I use integrator,but didn't work)?
Here is a code (does not work):
model PDEtest
/* Boundary conditions
1. delta(c)/delta(r)=0 for r=0
2. delta(c)/delta(r)=-j*d for r=Rp*/
parameter Real Rp=88*1e-3; // length
parameter Real initialConc=1000;
parameter Real Dp=1e-14;
parameter Integer np=10; // num. of points
Real cp[np](start=fill(initialConc,np));
Modelica.Blocks.Continuous.Integrator r(k=1); // independent x1
Real j;
protected
parameter Real dr=Rp/np;
parameter Real ts= 0.01; // for using when loop (sample(0,ts) )
algorithm
j:=sin(time); // this should be indepedent variable like x2
r.u:=dr;
while r.y<=Rp loop
for i in 2:np-1 loop
der(cp[i]):=2*Dp/r.y+(cp[i]-cp[i-1])/dr+2*(Dp*(cp[i+1]-2*cp[i]+cp[i-1])/dr^2);
end for;
if r.y==Rp then
cp[np]:=-j*Dp;
end if;
cp[1]:=if time >=0 then initialConc else initialConc;
end while;
annotation (uses(Modelica(version="3.2")));
end PDEtest;
Here are more questions:
This code don’t work in OpenModelica 1.8.1, also don’t work in Dymola 2013demo. How can we have continuos function of variable c, not array of functions ?
Can we place values of array cp in combiTable? And how?
If instead “algorithm” stay “equation” code can’t be succesfull checked.Why? In OpenModelica, error is :could not flattening model :S.
Is there any simplified way to use a set of equation (PDE’s) that are coupled? I know for PDEs library in Modelica, but I think they are complicated. I want to write a function for solving PDE and call these function in “main model”, so that output of function be continuos function of “c”.I don’t know what for doing with array of functions.
Can you give me advice how to understand Modelica language, if we “speak” like in Matlab? For example: Values of independent variable r,we can specife in Matlab, like r=0:TimeStep:Rp…How to do same in Modelica? And please explain me how section “equation” works, is there similarity with Matlab, and is there necessary sequancial approach?
Cheers :)
It's hard to answer your question, since you assuming that Modelica ~ Matlab, but that's not the case. So I won't comment your code, since it's really wrong. Let me give you an example model to the burger equation. Maybe you could use it as starting point.
model burgereqn
Real u[N+2](start=u0);
parameter Real h = 1/(N+1);
parameter Integer N = 10;
parameter Real v = 234;
parameter Real Pi = 3.14159265358979;
parameter Real u0[N+2]={((sin(2*Pi*x[i]))+0.5*sin(Pi*x[i])) for i in 1:N+2};
parameter Real x[N+2] = { h*i for i in 1:N+2};
equation
der(u[1]) = 0;
for i in 2:N+1 loop
der(u[i]) = - ((u[i+1]^2-u[i-1]^2)/(4*(x[i+1]-x[i-1])))
+ (v/(x[i+1]-x[i-1])^2)*(u[i+1]-2*u[i]+u[i+1]);
end for;
der(u[N+2]) = 0;
end burgereqn;
Your further questions:
cp is an continuous variable and the array is representing
every discretization point.
Why you should want to do that, as far as I understand cp is
your desired solution variable.
You should try to use almost always equation section
algorithm sections are usually used in functions. I'm pretty
sure you can represent your desire behaviour with equations.
I don't know that library, but the hard thing on a pde is the
discretization and the solving it self. You may run into issues
while solving the pde with a modelica tool, since usually
a Modelica tool has no specialized solving algorithm for pdes.
Please consider for that question further references. You could
start with Modelica.org.