block CombiTable1Ds "Table look-up in one dimension (matrix/file) with one input and n outputs"
extends Modelica.Blocks.Interfaces.SIMO(final nout = size(columns, 1));
parameter Boolean tableOnFile = false "= true, if table is defined on file or in function usertab"
annotation (Dialog(group = "Table data definition"));
parameter Real table[:,:] = fill(0, 0, 2) "Table matrix (grid = first column; e.g., table=[0, 0; 1, 1; 2, 4])"
annotation (Dialog(
group = "Table data definition",
enable = not tableOnFile));
parameter String tableName = "NoName" "Table name on file or in function usertab (see docu)"
annotation (Dialog(
group = "Table data definition",
enable = tableOnFile));
parameter String fileName = "NoName" "File where matrix is stored"
annotation (Dialog(
group = "Table data definition",
enable = tableOnFile,
loadSelector(
filter = "Text files (*.txt);;MATLAB MAT-files (*.mat)",
caption = "Open file in which table is present")));
parameter Boolean verboseRead = true "= true, if info message that file is loading is to be printed"
annotation (Dialog(
group = "Table data definition",
enable = tableOnFile));
parameter Integer columns[:] = 2:size(table, 2) "Columns of table to be interpolated"
annotation (Dialog(group = "Table data interpretation"));
parameter Modelica.Blocks.Types.Smoothness smoothness = Modelica.Blocks.Types.Smoothness.LinearSegments "Smoothness of table interpolation"
annotation (Dialog(group = "Table data interpretation"));
parameter Modelica.Blocks.Types.Extrapolation extrapolation = Modelica.Blocks.Types.Extrapolation.LastTwoPoints "Extrapolation of data outside the definition range"
annotation (Dialog(group = "Table data interpretation"));
parameter Boolean verboseExtrapolation = false "= true, if warning messages are to be printed if table input is outside the definition range"
annotation (Dialog(
group = "Table data interpretation",
enable = extrapolation == Modelica.Blocks.Types.Extrapolation.LastTwoPoints or extrapolation == Modelica.Blocks.Types.Extrapolation.HoldLastPoint));
final parameter Real u_min = Internal.getTable1DAbscissaUmin(tableID) "Minimum abscissa value defined in table";
final parameter Real u_max = Internal.getTable1DAbscissaUmax(tableID) "Maximum abscissa value defined in table";
protected
parameter Modelica.Blocks.Types.ExternalCombiTable1D tableID = Modelica.Blocks.Types.ExternalCombiTable1D(if tableOnFile then tableName else "NoName", if tableOnFile and fileName <> "NoName" and not Modelica.Utilities.Strings.isEmpty(fileName) then fileName else "NoName", table, columns, smoothness, extrapolation, if tableOnFile then verboseRead else false) "External table object";
function readTableData = Modelica.Blocks.Tables.Internal.readTable1DData "Read table data from text or MATLAB MAT-file";
equation
if verboseExtrapolation and (extrapolation == Modelica.Blocks.Types.Extrapolation.LastTwoPoints or extrapolation == Modelica.Blocks.Types.Extrapolation.HoldLastPoint) then
assert(noEvent(u_min <= u), "\nExtrapolation warning: The value u (=" + String(u) + ") must be greater or equal\nthan the minimum abscissa value u_min (=" + String(u_min) + ") defined in the table.\n", level = AssertionLevel.warning);
assert(noEvent(u <= u_max), "\nExtrapolation warning: The value u (=" + String(u) + ") must be less or equal\nthan the maximum abscissa value u_max (=" + String(u_max) + ") defined in the table.\n", level = AssertionLevel.warning);
end if;
if tableOnFile then
assert(tableName <> "NoName", "tableOnFile = true and no table name given");
else
assert(0 < size(table, 1) and 0 < size(table, 2), "tableOnFile = false and parameter table is an empty matrix");
end if;
if smoothness == Modelica.Blocks.Types.Smoothness.ConstantSegments then
for i in 1:nout loop
y[i] = Internal.getTable1DValueNoDer(tableID, i, u);
end for;
else
for i in 1:nout loop
y[i] = Internal.getTable1DValue(tableID, i, u);
end for;
end if;
annotation (
Documentation(info = "<html>\n<p>\n<strong>Univariate constant</strong>, <strong>linear</strong> or <strong>cubic Hermite\nspline interpolation</strong> in <strong>one</strong> dimension of a\n<strong>table</strong>.\nVia parameter <strong>columns</strong> it can be defined how many columns of the\ntable are interpolated. If, e.g., columns={2,4}, it is assumed that\n2 output signals are present and that the first output interpolates\nvia column 2 and the second output interpolates via column 4 of the\ntable matrix.\n</p>\n<p>\nThe grid points and function values are stored in a matrix \"table[i,j]\",\nwhere the first column \"table[:,1]\" contains the grid points and the\nother columns contain the data to be interpolated. Example:\n</p>\n<pre>\n table = [0, 0;\n 1, 1;\n 2, 4;\n 4, 16]\n If, e.g., the input u = 1.0, the output y = 1.0,\n e.g., the input u = 1.5, the output y = 2.5,\n e.g., the input u = 2.0, the output y = 4.0,\n e.g., the input u =-1.0, the output y = -1.0 (i.e., extrapolation).\n</pre>\n<ul>\n<li>The interpolation interval is found by a binary search where the interval used in the\n last call is used as start interval.</li>\n<li>Via parameter <strong>smoothness</strong> it is defined how the data is interpolated:\n<pre>\n smoothness = 1: Linear interpolation\n = 2: Akima interpolation: Smooth interpolation by cubic Hermite\n splines such that der(y) is continuous, also if extrapolated.\n = 3: Constant segments\n = 4: Fritsch-Butland interpolation: Smooth interpolation by cubic\n Hermite splines such that y preserves the monotonicity and\n der(y) is continuous, also if extrapolated.\n = 5: Steffen interpolation: Smooth interpolation by cubic Hermite\n splines such that y preserves the monotonicity and der(y)\n is continuous, also if extrapolated.\n</pre></li>\n<li>Values <strong>outside</strong> of the table range, are computed by\n extrapolation according to the setting of parameter <strong>extrapolation</strong>:\n<pre>\n extrapolation = 1: Hold the first or last value of the table,\n if outside of the table scope.\n = 2: Extrapolate by using the derivative at the first/last table\n points if outside of the table scope.\n (If smoothness is LinearSegments or ConstantSegments\n this means to extrapolate linearly through the first/last\n two table points.).\n = 3: Periodically repeat the table data (periodical function).\n = 4: No extrapolation, i.e. extrapolation triggers an error\n</pre></li>\n<li>If the table has only <strong>one row</strong>, the table value is returned,\n independent of the value of the input signal.</li>\n<li>The grid values (first column) have to be strictly increasing.</li>\n</ul>\n<p>\nThe table matrix can be defined in the following ways:\n</p>\n<ol>\n<li>Explicitly supplied as <strong>parameter matrix</strong> \"table\",\n and the other parameters have the following values:\n<pre>\n tableName is \"NoName\" or has only blanks,\n fileName is \"NoName\" or has only blanks.\n</pre></li>\n<li><strong>Read</strong> from a <strong>file</strong> \"fileName\" where the matrix is stored as\n \"tableName\". Both text and MATLAB MAT-file format is possible.\n (The text format is described below).\n The MAT-file format comes in four different versions: v4, v6, v7 and v7.3.\n The library supports at least v4, v6 and v7 whereas v7.3 is optional.\n It is most convenient to generate the MAT-file from FreeMat or MATLAB®\n by command\n<pre>\n save tables.mat tab1 tab2 tab3\n</pre>\n or Scilab by command\n<pre>\n savematfile tables.mat tab1 tab2 tab3\n</pre>\n when the three tables tab1, tab2, tab3 should be used from the model.<br>\n Note, a fileName can be defined as URI by using the helper function\n <a href=\"modelica://Modelica.Utilities.Files.loadResource\">loadResource</a>.</li>\n<li>Statically stored in function \"usertab\" in file \"usertab.c\".\n The matrix is identified by \"tableName\". Parameter\n fileName = \"NoName\" or has only blanks. Row-wise storage is always to be\n preferred as otherwise the table is reallocated and transposed.\n See the <a href=\"modelica://Modelica.Blocks.Tables\">Tables</a> package\n documentation for more details.</li>\n</ol>\n<p>\nWhen the constant \"NO_FILE_SYSTEM\" is defined, all file I/O related parts of the\nsource code are removed by the C-preprocessor, such that no access to files takes place.\n</p>\n<p>\nIf tables are read from a text file, the file needs to have the\nfollowing structure (\"-----\" is not part of the file content):\n</p>\n<pre>\n-----------------------------------------------------\n#1\ndouble tab1(5,2) # comment line\n 0 0\n 1 1\n 2 4\n 3 9\n 4 16\ndouble tab2(5,2) # another comment line\n 0 0\n 2 2\n 4 8\n 6 18\n 8 32\n-----------------------------------------------------\n</pre>\n<p>\nNote, that the first two characters in the file need to be\n\"#1\" (a line comment defining the version number of the file format).\nAfterwards, the corresponding matrix has to be declared\nwith type (= \"double\" or \"float\"), name and actual dimensions.\nFinally, in successive rows of the file, the elements of the matrix\nhave to be given. The elements have to be provided as a sequence of\nnumbers in row-wise order (therefore a matrix row can span several\nlines in the file and need not start at the beginning of a line).\nNumbers have to be given according to C syntax (such as 2.3, -2, +2.e4).\nNumber separators are spaces, tab (\\t), comma (,), or semicolon (;).\nSeveral matrices may be defined one after another. Line comments start\nwith the hash symbol (#) and can appear everywhere.\nText files should either be ASCII or UTF-8 encoded, where UTF-8 encoded strings are only allowed in line comments and an optional UTF-8 BOM at the start of the text file is ignored.\nOther characters, like trailing non comments, are not allowed in the file.\n</p>\n<p>\nMATLAB is a registered trademark of The MathWorks, Inc.\n</p>\n</html>"),
Icon(
coordinateSystem(
preserveAspectRatio = true,
extent = {
{-100, -100},
{100, 100}}),
graphics = {
Line(points = {
{-60, 40},
{-60, -40},
{60, -40},
{60, 40},
{30, 40},
{30, -40},
{-30, -40},
{-30, 40},
{-60, 40},
{-60, 20},
{60, 20},
{60, 0},
{-60, 0},
{-60, -20},
{60, -20},
{60, -40},
{-60, -40},
{-60, 40},
{60, 40},
{60, -40}}),
Line(points = {
{0, 40},
{0, -40}}),
Rectangle(
fillColor = {255, 215, 136},
fillPattern = FillPattern.Solid,
extent = {
{-60, 20},
{-30, 40}}),
Rectangle(
fillColor = {255, 215, 136},
fillPattern = FillPattern.Solid,
extent = {
{-60, 0},
{-30, 20}}),
Rectangle(
fillColor = {255, 215, 136},
fillPattern = FillPattern.Solid,
extent = {
{-60, -20},
{-30, 0}}),
Rectangle(
fillColor = {255, 215, 136},
fillPattern = FillPattern.Solid,
extent = {
{-60, -40},
{-30, -20}})}),
Diagram(
coordinateSystem(
preserveAspectRatio = true,
extent = {
{-100, -100},
{100, 100}}),
graphics = {
Rectangle(
extent = {
{-60, 60},
{60, -60}},
fillColor = {235, 235, 235},
fillPattern = FillPattern.Solid,
lineColor = {0, 0, 255}),
Line(
points = {
{-100, 0},
{-58, 0}},
color = {0, 0, 255}),
Line(
points = {
{60, 0},
{100, 0}},
color = {0, 0, 255}),
Text(
extent = {
{-100, 100},
{100, 64}},
textString = "Univariate constant, linear or cubic Hermite spline table interpolation",
lineColor = {0, 0, 255}),
Line(
points = {
{-54, 40},
{-54, -40},
{54, -40},
{54, 40},
{28, 40},
{28, -40},
{-28, -40},
{-28, 40},
{-54, 40},
{-54, 20},
{54, 20},
{54, 0},
{-54, 0},
{-54, -20},
{54, -20},
{54, -40},
{-54, -40},
{-54, 40},
{54, 40},
{54, -40}},
color = {0, 0, 0}),
Line(points = {
{0, 40},
{0, -40}}),
Rectangle(
extent = {
{-54, 40},
{-28, 20}},
fillColor = {255, 255, 0},
fillPattern = FillPattern.Solid),
Rectangle(
extent = {
{-54, 20},
{-28, 0}},
fillColor = {255, 255, 0},
fillPattern = FillPattern.Solid),
Rectangle(
extent = {
{-54, 0},
{-28, -20}},
fillColor = {255, 255, 0},
fillPattern = FillPattern.Solid),
Rectangle(
extent = {
{-54, -20},
{-28, -40}},
fillColor = {255, 255, 0},
fillPattern = FillPattern.Solid),
Text(
extent = {
{-52, 56},
{-34, 44}},
textString = "u",
lineColor = {0, 0, 255}),
Text(
extent = {
{-22, 54},
{2, 42}},
textString = "y[1]",
lineColor = {0, 0, 255}),
Text(
extent = {
{4, 54},
{28, 42}},
textString = "y[2]",
lineColor = {0, 0, 255}),
Text(
extent = {
{0, -40},
{32, -54}},
textString = "columns",
lineColor = {0, 0, 255})}));
end CombiTable1Ds;