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

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.

Related

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

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.

Determine the number of a specific component in a Modelica model at translation (using Dymola)

How could you determine the number of instances of a given class within this model at translation. This size is to be used to set the size of a vector.
model ModelToBeCounted
end ModelToBeCounted;
model Example
ModelToBeCounted A;
ModelToBeCounted B;
ModelToBeCounted C;
end Example;
So in this example I would like to like to determine the number instances of ModelToBeCounted. These instances could also be within instances of other classes. The code at the top level could be altered to do this and the ModelToBeCounted could also be altered.
I tried using external objects however I could not find a way to ensure that the external objects are all created before the function used to report the total number of external objects was run.
Any ideas?
Thanks
If you can modify the model ModelToBeCounted you can do this using inner/outer:
connector C
Real totalNum;
flow Real addNum;
end C;
model InnerObjectCounter
C c;
equation
c.totalNum+c.addNum=0 "Correct sign";
annotation(missingInnerMessage="Add inner component to count objects");
end InnerObjectCounter;
model FlowSource
C c;
equation
c.addNum=1;
end FlowSource;
model AddCounter
outer InnerObjectCounter objectCounter;
final Integer totalNum=integer(flowSource.c.totalNum);
FlowSource flowSource;
equation
connect(flowSource.c, objectCounter.c);
end AddCounter;
model ModelToBeCounted
AddCounter c;
end ModelToBeCounted;
All components are automatically connected to the inner object using inner/outer-mechanism, and they have a flow of 1 that is summed together.
If you cannot modify the model ModelToBeCounted, and you are willing to use non-standarized methods you can set the flag:
Hidden.AllowAutomaticInstanceOf=true;
and then use:
final parameter Integer m=sum(1 for m in P.ModelToBeCounted);
From:
https://github.com/modelica/ModelicaSpecification/blob/MCP/0021/RationaleMCP/0021/
The ModelManagement library can do that.
In fact, there is exactly what you need available as a function:
ModelManagement.Structure.Instantiated.CountUsedModels("Example", {"ModelToBeCounted"});
= {3}
The library is installed with Dymola and available with the standard license.
You just have to open it from the Libraries menu.
A problem could be, that this function has to translate your model. I am not sure how well this will work for your requirement:
This size is to be used to set the size of a vector.

Error using the library Modelica_LinearSystems2 in OpenModelica

I am trying to use the Kalman Filter from the Modelica_LinearSystem2 Library (Modelica_LinearSystems2.WorkInProgress.Controller.KalmanFilter.KF) in OpenModelica, but it seems the functions of the library are not working properly in my test models.
To find the problem I copied the code example from the documentation (https://build.openmodelica.org/Documentation/Modelica_LinearSystems2.StateSpace.%27constructor%27.fromABCDMatrices.html)
model test3
Real A[1,1] = [1];
Real B[1,1] = [1];
Real C[1,1] = [1];
Real D[1,1] = [0];
public
Modelica_LinearSystems2.StateSpace ss;
algorithm
ss := Modelica_LinearSystems2.StateSpace.'constructor'.fromABCDMatrices(A, B, C, D);
equation
end test3;
When I click on check model I receive the Error:
[Modelica_LinearSystems2.StateSpace: 7:3-8:68]: Failed to deduce dimension 1 of A due to missing binding equation.
This refers to the line
Real A[:,size(A, 1)];
When I predefine this (and other) matrices with for example
Real A[4,4];
I get the error
Internal error Instantiation of test3 failed with no error message.
My question is: Why is this and how can I prevent these errors?
Findings
It looks like Modelica_LinearSystems2 is only supported by Dymola. The landing page of their github repository states:
Please note that the library is known to work with Dymola only.
It looks as this is still the case. At least on my machine the library Modelica_LinearSystems2 v2.4.1 has serious issues in OpenModelica v1.18.0. Most examples exit with errors or do nothing.
Still, the code in the question does not work in Dymola. Below you find an explanation and corrected examples, which were successfully tested with Dymola. The fundamental problem should be the same in all tools and I hope my solution will also work in OpenModelica once it support the Modelica_LinearSystems2 library.
Original answer (most relevant for Dymola users)
The problem with your example code is that Modelica tools must know the size of vectors, matrices and arrays when a simulation is performed, but not when a function is called. Since you are building a model, the tool assumes that you want to simulate it.
Your code instantiates the StateSpace record ss. ss holds the matrices A, B, C and D. As long as you don't assign anything to ss, their sizes are not known. Of course there is an algorithm, which sets ss, but this happens during simulation. During translation, the size of the matrices in ss cannot be determined. Therefore, a typical Modelica tool requires you to use a binding equation.
To make your snipped work, you can change it to this:
model Demo
Real A[1,1] = [1];
Real B[1,1] = [1];
Real C[1,1] = [1];
Real D[1,1] = [0];
Modelica_LinearSystems2.StateSpace ss = Modelica_LinearSystems2.StateSpace.'constructor'.fromABCDMatrices(A, B, C, D);
end Demo;
Note that ss now has a binding equation. Hence, the size of the matrices inside ss can be determined.
The question is, if you really want to run a simulation with your StateSpace record. Typically, the functions in the liner systems library are used in Modelica functions. In this case your code could look as follows:
function demo
output Modelica_LinearSystems2.StateSpace ss;
protected
Real A[1,1] = [1];
Real B[1,1] = [1];
Real C[1,1] = [1];
Real D[1,1] = [0];
algorithm
ss = Modelica_LinearSystems2.StateSpace.'constructor'.fromABCDMatrices(A, B, C, D);
end demo;
I suggest looking at the various examples in the package Modelica_LinearSystems2.Examples.StateSpace for the correct usage of the StateSpace record.

Input/Output connectors causing Modelica model to be unbalanced

I'm building a custom fluid model to eventually allow for a 3-dimensional velocity. I've designed the equations such that the model runs with the following boundary conditions:
pressure_out = 500000;
hin=3000e3;
mdot[1] = 66.3;
The inlet pressure, outlet enthalpy, and outlet mass flow rates should then all be calculated via the model. I then put in an outlet connector (standard Modelica fluid port named Outlet):
Outlet.m_flow + mdot[3]=0;
Outlet.p = pressure_out;
Outlet.h_outflow = hout;
and correspondingly remove the boundary condition for pressure_out so that:
hin=3000e3;
mdot[1] = 66.3;
and the model is still balanced. However, once I add in the Inlet connector and set its connections:
Inlet.m_flow =mdot[1];
Inlet.p = pressure_in;
Inlet.h_outflow = hin;
I remove the boundary conditions because the model should be capable of being informed of a pressure, mass flow rate, and enthalpy. However, when I remove my boundary conditions the model believes that I'm missing an equation. I cannot for the life of me figure out what to do. If I re-add in any of the initial boundary conditions, the model breaks because a boundary is singularly over-determined.
In summary,
pout = 500000; replaced by Outlet.p = pout;
hout = states[2].h; add Outlet.h_outflow = hout;
p[1] = pin; add Inlet.p = pin;
hin=3000e3; replaced by Inlet.h_outflow = hin;
mdot[1] = 66.3; replaced by Inlet.m_flow = mdot[1];
I've tried using inStream for the flow variables, I've tried bypassing my internal variables, and I've tried each port one at a time. The Inlet port is unhappy, and I'm at a loss as far as why it is.
As you point out yourself, the problem lies in the usage of stream connectors. When you use stream connectors in a model it must always provide a value of the outflowing stream variable for each connector. That is, in your case you need an expression of the outflowing enthalpy of each connector.
This Github Wiki page might be helpful to you
Best regards,
Rene Just Nielsen

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.