0
votes

I still have problems when using arrays with undifined size in Modelica.
It would be really helpful to understand what is the underlying problem. I read a lot of stuff (known size at compile time, functions, constructor and destructor, records and so on) but I'm still not sure what is the proper way to use flexible arrays in Modelica.
Can somebody give a good explanation, maybe using the following example?

Given data:

x  y
1  7
2  1
3  1
4  7

Modelica model which works fine:

model Test_FixedMatrix

  parameter Real A[4,2] = [1,7;2,1;3,1;4,7];
  parameter Integer nA = size(A,1);
  parameter Integer iA[:] = Modelica.Math.BooleanVectors.index( {A[i,2] == 1 for i in 1:nA});
  parameter Real Aslice[:,:] = A[iA,:];

end Test_FixedMatrix;

The array iA[:] gives the indices of all rows having an y = 1 and Aslice[:,:] includes all this rows in one matrix.

Now instead of using a given matrix, I want to read the data from a file. Using the Modelica library ExternData (https://github.com/tbeu/ExternData) it is possible to read the data from an xlsx-file:

model Test_MatrixFromFile

  ExternData.XLSXFile xlsxfile(fileName="data/ExampleData.xlsx");
  parameter Real B[:,:] = xlsxfile.getRealArray2D("A2","Tabelle1",4,2);
  parameter Integer nB = size(B,1);
  parameter Integer iB[:] = Modelica.Math.BooleanVectors.index( {B[i,2] == 1 for i in 1:nB});
  parameter Real Bslice[:,:] = B[iB,:];

end Test_MatrixFromFile;

The xlsx-file looks like this:

enter image description here

It's exatly the same code, but this time I get the error message: enter image description here

(If I delete the two lines with iB and Bsliece then it works, so the problem is not the xlsxfile.getRealArray2D function)

Application example and further questions:
It would be really nice to be able to just read a data file into Modelica and then prepare the data directly within the Modelica code without using any other software. Of course I can prepare all the data using e.g. a Python script and then use TimeTable components... but sometimes this is not really comfortable.
Is there another way to read in data (txt or csv) without specifying the size of the table in it?
How would it look like, if I want to read-in data from different files e.g. every 10 seconds?
I also found the Modelica functions readFile and countLines in Modelica.Utilities.Streams. Is it maybe only possible to do this using external functions?

1
Try changing parameter Real Bslice[:,:] = B[iB,:]; to parameter Real Bslice[:,:] = B[size(iB,1),:];. Maybe that is the issue.Scott G

1 Answers

0
votes

I assume the fundamental issue is, that Modelica.Math.BooleanVectors.index returns a vector of variable size. The size depends on the input of the function which in the given case is the xlsx file. Therefore the size of iB depends on the content of the xlsx file which can change independently of the model itself. Therefore the problem you originally stated "known size at compile time" is problematic, as the size of iB is dependent on a non-parameter.

Another thing that I learned from my experience with Dymola is that it behaves differently if functions like ExternData.XLSXFile are translated before usage. This means that you need to open the function in Dymola (double-clicking it in the package browser) and press the translate button (or F9). This will generate the respective .exe file in your working directory and make Dymola more "confident" in outputs of the function being parameters rather than variables. I don't know the details of the implementations and therefore can't give exact details, but it is worth a try.