How to use unspecified array dimensions in blocks? - modelica

Using unspecified array dimensions (:) is an essential feature to design flexible components for reuse. I am well aware that the actual dimension has to be fixed when the model is compiled. To my knowledge binding a variable with unspecified array dimensions to one that has clearly defined dimensions should suffice.
So I am a bit confused why the following model Test will not validate in either OpenModelica or the Wolfram System Modeler:
package VectorFunctions
model Test
VectorSum converter "Component taking the sum of a vector input";
InformationSource source "Vector input";
equation
connect( source.y, converter.u );
end Test;
block VectorSum "Take the sum of an input with unspecified dimension"
Modelica.Blocks.Interfaces.RealInput u[:];
Modelica.Blocks.Interfaces.RealOutput y;
equation
y = sum(u);
end VectorSum;
block InformationSource "Provide some vector output"
Modelica.Blocks.Interfaces.RealOutput y[3];
equation
y = ones( 3 );
end InformationSource;
end VectorFunctions;
How can something like this be done then?

My guess would be that the Modelica Spec does not specify, that vector sizes can be automatically detected from connections, so the tools don't support that.
I think you have to set the vector size somehow by yourself, e.g. with a parameter which is set in your Test model as follows:
model Test
VectorSum converter(nu=size(source.y, 1)) "Pass in the vector size";
InformationSource source "Vector input";
equation
connect(source.y, converter.u);
end Test;
block VectorSum "Take the sum of an input with unspecified dimension"
Modelica.Blocks.Interfaces.RealInput u[nu];
parameter Integer nu(min=0)=0;
output Real y;
equation
y = sum(u);
end VectorSum;
Note that Dymola complains in your example code that connect statements can only be applied to connectors. Therefore I changed input Real to Modelica.Blocks.Interfaces.RealInput(and similar in InformationSource)

I have been given (inofficial) feedback on Wolfram Community by someone from Wolfram MathCore (e.g. the developers of the System Modeler):
Hi, I agree with your interpretation, I think we should support it. I have filed a bug to keep track of this issue internally, unfortunately I do not see any work around. We will come back to you when we have fixed this problem.
So, hopefully flexbile array sizes will be supported for blocks as they are for functions.

Related

Modelica annotation derivative: noDerivative versus zeroDerivative

I have successfully used annotation(derivative) in Modelica functions. Now I have reached a point where I think I need to use zeroDerivative or noDerivative, but from the specification I just do not understand what is the difference, and when to use what.
https://specification.modelica.org/v3.4/Ch12.html#declaring-derivatives-of-functions
It seems zeroDerivative is for time-constant parameters??
Does somebody have a simple example?
Use zeroDerivative to refer to inputs that are non-varying, i.e. parameters or constant values.
Use noDerivative for signals that do not have a derivative value. For example if an input signal comes from an external function.
The important case for noDerivative is when the input is "redundant".
As an example consider the computation of density for some media in MSL:
The density computation is found in Modelica.Media.R134a.R134a_ph.density_ph (note this does not contain any derivative in itself):
algorithm
d := rho_props_ph(
p,
h,
derivsOf_ph(
p,
h,
getPhase_ph(p, h)));
where the top function called is:
function rho_props_ph
"Density as function of pressure and specific enthalpy"
extends Modelica.Icons.Function;
input SI.Pressure p "Pressure";
input SI.SpecificEnthalpy h "Specific enthalpy";
input Common.InverseDerivatives_rhoT derivs
"Record for the calculation of rho_ph_der";
output SI.Density d "Density";
algorithm
d := derivs.rho;
annotation (
derivative(noDerivative=derivs) = rho_ph_der ...);
end rho_props_ph;
So the derivs-argument is sort of redundant and is given by p and h; and we don't need to differentiate it again. If you send in a derivs-argument that isn't given in this way may give unpredictable result, but describing this in detail would be too complicated. (There was some idea of noDerivative=something - but even just specifying it turned out to be too complicated.)
For zeroDerivative the corresponding requirement is that the arguments have zero derivative; that is straightforward to verify and if non-zero we cannot use the specific derivative (it is possible to specify multiple derivatives and use another derivative one for that case).

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.

Current version of the modelica translator can only handle array of components with fixed size

I created an part with the AC library, and when I was trying to simulate the model, there is an error says "Current version of the modelica translator can only handle array of components with fixed size".
Not sure what is the meaning of it, and is there anyone has the same issue like this one?
Thank you
enter image description here
Consider the following simple model:
model M
parameter Integer n(start=3, fixed=false);
initial algorithm
n := n;
end M;
It has a parameter n which can be changed before simulation starts. And array dimensions need to be parameter expressions. So you would think that the following model would be legal:
model M2
Real arr[n] = fill(1, n);
parameter Integer n(start=3, fixed=false);
initial algorithm
n := n;
end M2;
But it isn't since Modelica tools will expand the number of equations and variables to get a fixed number. (According to the language specification, n is a structural parameter; it is not well defined what restrictions these have - most Modelica tools seem to require them to behave like constants which means only fixed=true parameters with a binding equation that depends only on other structural parameters or constants).

how to resolve a dimensionality-related error in this code?

I have written a code in Modelica to train a feedforward two-layer neural network for my Master thesis. The code receives a vector of six elements (u[nin]) and provides an output vector of two elements y[nout]. When I translate the code in dymola, I receive an error saying that the dimensionality of the parts included in a specific line of code must be equal. Once I remove this particular line, the code is translated successfully. I really spent much effort trying to resolve this error but in vain! Any help regarding the problem would be very much appreciated.
The code can be found below: (Please note that the line which causes the generation of the translation error is marked with // in the code).
model NN_block
Modelica.Blocks.Interfaces.RealInput
u[nin] "Connector of Real input signals"
annotation (Placement(transformation(extent={{-140,-20},{-100,20}},
rotation=0)));
Modelica.Blocks.Interfaces.RealOutput y[nout]
annotation (Placement(transformation(extent={{100,-10},{120,10}})));
parameter Integer nin2=1;
parameter Integer nin=6;
parameter Integer nout=2;
Real wji[10,6];
Real delta_wij[6,10];
Real bj[10,1];
Real delta_bjT[1,10];
Real wkj[2,10];
Real delta_wjk[10,2];
Real bk[2,1];
Real delta_bkT[1,2];
Real E;
Real ek[1,2];
Real yj[10,1];
Modelica.Blocks.Interfaces.BooleanOutput Input_trigger
annotation (Placement(
transformation(extent={{100,-46},{120,-26}}), iconTransformation(extent=
{{100,-46},{120,-26}})));
Modelica.Blocks.Interfaces.RealInput eTau1 annotation (Placement(
transformation(extent={{-182,36},{-142,76}}), iconTransformation(
extent={{10,-10},{-10,10}},
rotation=90,
origin={-44,90})));
Modelica.Blocks.Interfaces.RealInput eTau2 annotation (Placement(
transformation(extent={{-148,46},{-108,86}}), iconTransformation(
extent={{10,-10},{-10,10}},
rotation=90,
origin={50,90})));
annotation (Placement(transformation(extent={{-10,-10},{10,10}},
rotation=-90,
origin={-50,90}), iconTransformation(
extent={{-10,-10},{10,10}},
rotation=-90,
origin={0,90})));
algorithm
E:=1;
wji:=0.5*ones(10,6);
bj:=0.25*ones(10,1);
wkj:=0.75*ones(2,10);
bk:=0.6*ones(2,1);
delta_wij:=zeros(6,10);
delta_bjT:=zeros(1,10);
delta_wjk:=zeros(10,2);
delta_bkT:=zeros(1,2);
while E>0.01 loop
Input_trigger:=true;
y:=wkj*NeuralNetwork.Utilities.LogSig(wji*u+bj[:,1])+bk[:,1];
yj[:,1]:=NeuralNetwork.Utilities.LogSig(wji*u+bj[:,1]);
ek:=[eTau1,eTau2];
E:=0.5*(eTau1^2+eTau2^2);
if E>0.01 then
// delta_wij:=0.01*u*transpose(yj)*(ones(10,1)-yj)*ek*wkj+0.9*delta_wij;
delta_bjT:=0.01*transpose(yj)*(ones(10,1)-yj)*ek*wkj + 0.9*delta_bjT;
delta_wjk:=0.01*yj*ek + 0.9*delta_wjk;
delta_bkT:=0.01*ek + 0.9*delta_bkT;
wji:=wji+transpose(delta_wij);
bj:=bj+transpose(delta_bjT);
wkj:=wkj+transpose(delta_wjk);
bk:=bk+transpose(delta_bkT);
else
break;
end if;
end while;
annotation (Placement(transformation(extent={{-140,44},{-100,84}})),
uses(Modelica(version="3.2")), Icon(graphics={Rectangle(
extent={{-100,-100},{100,80}},
lineColor={0,0,255},
lineThickness=1), Text(
extent={{-68,20},{78,-16}},
lineColor={0,0,255},
lineThickness=1,
textString="Two-LayerNeural Network")}),
Diagram(graphics));
end NN_block;
Once I remove the lines using LogSig I could get OpenModelica to produce an error-message for you:
[a.mo:59:3-59:71] Error: Incompatible argument types to operation matrix multiplication, left type: Real[6], right type: Real[1, 10]
[a.mo:59:3-59:71] Error: Cannot resolve type of expression 0.01 * u * transpose(yj). The operands have types Real[6], Real[1, 10] in component .
u and yj' have dimensions 6 and 1,10
Looking at the code, it appears that there is mismatch in the sizes of the matrices on the right hand side of the equation concerned.
Try defining u as a 2D matrix of size 6x1.
Have you tested this line in the command line? This could be done by creating the variables used in your model in the workspace and then running the commented out line in the command line to check the sizing is correct. You can do this in the Dymola command line but I am not familiar enough with OpenModelica to tell if you can perform the same check there.

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.