Calling several of the same component in Modelica - modelica

I seem to struggle with a modeling problem in Modelica (using Dymola), and I hereby seek your help. The idea is this:
I have modeled some components (models) that I want to connect together through their ports. The models are working. The thing is I want to connect several of the same unit (called myUnit in the pseudo code below) in a series. If the number of units were, let's say, only 5 then I could easily dragged them out 1-by-1 and connected them in a standard manner, but let's say I want 100 units. Is there an easy and elegant way to do this? I don't believe for loops to be working outside the equation part of the model, and I want an elegant way of naming the units. I'll try to illustrate this by doing a pseudo code below, explaining what I wish to achieve:
model someModel
parameter Integer n = 100 "Length of series";
parameter Real optionValue = 123;
myLibrary.myStartUnit startUnit(someOption = optionValue); // First unit
for i in 2:n-1 loop
myLibrary.myUnit unit_'num2str(i)'(someOption = optionValue); // i'th unit
end for;
myLibrary.myEndUnit endUnit(someOption = optionValue); // Last unit
equation
connect(startUnit.outPort,unit_1.inPort);
for i in 2:n-1 loop
connect(unit_'num2str(i)'.outPort,unit_'num2str(i+1)'.inPort)
end for;
connect(unit_'num2str(n-1)'.outPort,endUnit.inport);
end someModel;
I hope I've managed to explain my problem properly, now.
Any tips for solving this problem? I greatly appreciate both strategic advice as to solve the problem as well as purely syntactic advice.
In advance, thanks for all help. :)

You can use arrays to achieve this. For example, using models of the Modelica standard library:
model ArrayDemo
parameter Integer n = 10 "Number of springs/masses";
Modelica.Mechanics.Translational.Sources.ConstantForce constantForce(f_constant=100);
Modelica.Mechanics.Translational.Components.Spring springs[n];
Modelica.Mechanics.Translational.Components.Mass masses[n];
Modelica.Mechanics.Translational.Components.Fixed fixed;
equation
connect(constantForce.flange, springs[1].flange_a);
for i in 1 : n - 1 loop
connect(springs[i].flange_b, masses[i].flange_a);
connect(masses[i].flange_b, springs[i + 1].flange_a);
end for;
connect(springs[n].flange_b, masses[n].flange_a);
connect(masses[n].flange_b, fixed.flange);
end ArrayDemo;
The idea is to declare the components using arrays and then connect them using for loops.

Related

Discrete iteration, how can I make this possible?

I want to decompose a part like this, into an array of x rows and y columns, and then do the operations. Mainly use the loop statement (for). Do you guys have a similar example? thank you all very much.
just be like:
equation
for i in 1:n-1 loop
for j in 1:m-1 loop
//equations
T[i+1,j] = T[i,j]+something+...;
T[i,j+1] = ...;
end for;
end for;
The best example I could find is the following: Modelica.Electrical.Analog.Basic.M_Transformer, although the loop is "only" in the initial equation section.
What is more common, is to use loops in connect statements, like in Modelica.Electrical.Batteries.BaseClasses.BaseStackWithSensors. But that will likely not be a good fit for your task.
Some general advise:
A good read to start with the topic is: https://mbe.modelica.university/behavior/arrays/looping/
For complex for/if-statements it is often simpler to formulate them in an algorithm section. Those can be placed in a function and "ease" some of the pretty strict requirements of the equation section, like allowing a multiple assignments for a single variable. It will be more like a coding in a procedural programming language.
If you prefer to write the statements in the equation section (which can make sense performance-wise) you need to make sure, that every unknown needs exactly one equation to compute it.

Modelica - Is it possible to set name of a variable as the value of another variable?

I’m quite noob in Modelica language and I’d appreciate any help about this simple issue.
I’d like to know if it’s possible to write a variable name as a function of other variable in order to shorten the general code.
Here there is an example about what I’d like to do.
Thanks in advance!
model example
Real variable1;
Real variable2;
Real variable3;
equation
for i in 1:3 loop
variable(i)= […]
end for;
end example;
You probably want to use arrays in some way. This is similar to the code above, but perhaps you only need the array and not variable1 … variable3.
Real variable1;
Real variable2;
Real variable3;
Real variables[3] = {variable1,variable2,variable3};
equation
for i in 1:3 loop
variables[i] = /* … */;
end for;

Framework for Managing Matlab Runs

TL;DR: How should custom simulation runs be managed in Matlab? Detailed Questions at the end.
I am working with matlab where i created some code to check the influence of various parameters on a simulated system. It has a lot of inputs and outputs but a MWE would be:
function [number2x,next_letter] = test(number, letter)
number2x = number * 2;
next_letter = letter + 1;
disp(['next letter is ' next_letter])
disp(['number times 2 is ' num2str(number2x)])
end
This works if this is all there is to test. However with time multiple new inputs and outputs had to be added. Also because of the growing number of paramters that have been test some sort of log had to be created:
xlswrite('testfile.xlsx',[num2str(number), letter,num2str(number2x),next_letter],'append');
Also because the calculation takes a few hours and should run over night multiple parameter sets had to be started at one point. This is easily done with [x1,y1] = test(1,'a');[x2,y2] = test(2,'b'); in one line or adding new tasks while the old still run. However this way you can't keep track on how many are still open.
So in total I need some sort of testing framework, that can keep up with changeging inpus and outputs, keeps track on already doen calculations and ideally also handles the open runs.
I feel like i can't be the only one who faces this issue, in fact I think so many people face this issue that Mathworks would already came up with a solution.
For Simulink this has been done in form of a Simluationmanager, but for Matlab functions the closest thing i found is the Testing framework (example below) which seems to be rather for software development and debugging and not at all for what i am trying. And somepoint there seem to be 3rd party solutions but they are no longer continued in favor of this Testing framework.
function solutions = sampleTest
solutions = functiontests({#paramtertest});
end
function paramtertest(vargin)
test(1,'a');
test(2,'b');
end
function [number2x,next_letter] = test(number, letter)
number2x = number * 2;
next_letter = letter + 1;
disp(['next letter is ' next_letter])
disp(['number times 2 is ' num2str(number2x)])
xlswrite('testfile.xlsx',[num2str(number), letter,num2str(number2x),next_letter],'append');
end
Alternatively I could create my test as a class, create an interface similar to the Simulationmanager, create numerous functions for managing inputs and outputs and visualize the progress and then spawn multiple instances of if i want to set up a new set of parameters while already running a simulation. Possible, yet a lot of work that does not involve the simulation directly.
In total following questions arise:
Is there a build in Matlab function for managing simulations that i totally missed so far?
Can the the Testing framework be used for this purpose?
Is there already some Framework (not from Mathworks) that can handle this?
If i create my own class, could multiple instances run individually and keep track of their own progress? And would those be handled simultaniously or would matlab end up running the in the order they started?
I know this question is somewhat in the off-topic: recommend or find a tool, library or favorite off-site resource area. If you feel it is too much so, please focus on the last question.
Thank you!
I've done similar tests using GUI elements. Basic part of simulation was inside while loop, for example in your case:
iter = 0;
iter_max = 5; %the number of your times, you will call script
accu_step = 2; %the accuracy of stored data
Alphabet = 'abcdefghijklmnopqrstuvwxyz'
while iter < iter_max
iter = iter+1;
[x1,y1] = test(i,Alphabet(i));
end
Now you should create a handle to progress bar inside your computation script. It will show you both on which step you are, and the progress of current step.
global h;
global iter_opt;
if isempty(h)
h=waitbar(0,'Solving...');
else
waitbar(t/t_end,h,sprintf('Solving... current step is:%d',iter));
end
You didn't specified which function you use, if it is for example time-depended the above t/t_end example is an estimation of current progress.
The solving of result also require to be changed on every execution of loop, for example:
global iter;
i_line = (t_end/accu_step+2)*(iter-1);
xlswrite('results.xlsx',{'ITERATION ', iter},sheet,strcat('A',num2str(i_line+5)))
xlswrite('results.xlsx',results_matrix(1:6),sheet,strcat('D',num2str(i_line+5)))
The above example were also with assumption that your results are time-related, so you store data every 2 units of time (day, hours, min, what you need), from t_0 to t_end, with additional 2 rows of separation, between steps. The number of columns is just exemplary, you can adjust it to your needs.
After the calculation is done, you can close waitbar with:
global h
close(h)

MATLAB: Vectorize for loop in MATLAB

I wanted to vectorize this piece of code. Is it possible to do this? I tried finding a solution, but I was not able to find any good result on google.
for pos=length1+1:length
X1(pos) = sim(net1, [demandPred(pos), demand(pos-1), X1(pos-1), X1(pos-2)]')';
X2(pos) = sim(net1, [demandPred(pos), demand(pos-1), X2(pos-1), X2(pos-2)]')';
end
Thanks in advance. :)
Edit 1:
The model which I am going to simulate is a simple GRNN.
net1 = newgrnn([demand(169:trainElem), demand(169-1:trainElem-1), X1(169 - 1:trainElem - 1), X1(169 - 2:trainElem - 2)]', 0.09);
Can Simulink models be vectorized? Sometimes.
Can your Simulink model be vectorised? It's impossible to tell without seeing the model -- and how it is being called from m-code (as you've shown in your question) is no indication.
An example of vectorization would be: consider a model with signal s1 that gets added to constant K, and assume that you need to run the models for different values if K. You could use a loop (like the m-code you show) and run the model for each individual required value for K. Alternatively, you can make K a vector, in which case all values would get added to s1 and the result would be a vector of signals s1+K(1), s1+K(2),..., s1+K(n), and the model only needs to be executed once for all of these summations to occur.
But, whether that sort of thing can be done in your model cannot be determined without seeing the model.

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.