block CombiTable2D "Table look-up in two dimensions (matrix/file)"
    extends Modelica.Blocks.Interfaces.SI2SO;
    extends Internal.CombiTable2DBase;

    function readTableData = Modelica.Blocks.Tables.Internal.readTable2DData "Read table data from text or MATLAB MAT-file";
    if verboseExtrapolation and (extrapolation == Modelica.Blocks.Types.Extrapolation.LastTwoPoints or extrapolation == Modelica.Blocks.Types.Extrapolation.HoldLastPoint) then 
        assert(noEvent(u_min[1] <= u1), "\nExtrapolation warning: The value u1 (=" + String(u1) + ") must be greater or equal\nthan the minimum abscissa value u_min[1] (=" + String(u_min[1]) + ") defined in the table.\n", level = AssertionLevel.warning);
        assert(noEvent(u1 <= u_max[1]), "\nExtrapolation warning: The value u1 (=" + String(u1) + ") must be less or equal\nthan the maximum abscissa value u_max[1] (=" + String(u_max[1]) + ") defined in the table.\n", level = AssertionLevel.warning);
        assert(noEvent(u_min[2] <= u2), "\nExtrapolation warning: The value u2 (=" + String(u2) + ") must be greater or equal\nthan the minimum abscissa value u_min[2] (=" + String(u_min[2]) + ") defined in the table.\n", level = AssertionLevel.warning);
        assert(noEvent(u2 <= u_max[2]), "\nExtrapolation warning: The value u2 (=" + String(u2) + ") must be less or equal\nthan the maximum abscissa value u_max[2] (=" + String(u_max[2]) + ") defined in the table.\n", level = AssertionLevel.warning);
    end if;
    if smoothness == Modelica.Blocks.Types.Smoothness.ConstantSegments then 
        y = Internal.getTable2DValueNoDer(tableID, u1, u2);
        y = Internal.getTable2DValue(tableID, u1, u2);
    end if;

    annotation (Documentation(info = "<html>\n<p>\n<strong>Bivariate constant</strong>, <strong>bilinear</strong> or <strong>bivariate\nAkima interpolation</strong> of a <strong>two-dimensional table</strong>.\nThe grid points and function values are stored in a matrix \"table[i,j]\",\nwhere:\n</p>\n<ul>\n<li>the first column \"table[2:,1]\" contains the u1 grid points,</li>\n<li>the first row \"table[1,2:]\" contains the u2 grid points,</li>\n<li>the other rows and columns contain the data to be interpolated.</li>\n</ul>\n<p>\nExample:\n</p>\n<pre>\n           |       |       |       |\n           |  1.0  |  2.0  |  3.0  |  // u2\n       ----*-------*-------*-------*\n       1.0 |  1.0  |  3.0  |  5.0  |\n       ----*-------*-------*-------*\n       2.0 |  2.0  |  4.0  |  6.0  |\n       ----*-------*-------*-------*\n     // u1\n   is defined as\n      table = [0.0,   1.0,   2.0,   3.0;\n               1.0,   1.0,   3.0,   5.0;\n               2.0,   2.0,   4.0,   6.0]\n   If, e.g., the input u1 is 1.0, input u2 is 1.0 and smoothness is LinearSegments, the output y is 1.0,\n       e.g., the input u1 is 2.0, input u2 is 1.5 and smoothness is LinearSegments, the output y is 3.0.\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: Bilinear interpolation\n             = 2: Bivariate Akima interpolation: Smooth interpolation by bicubic Hermite\n                  splines such that der(y) is continuous, also if extrapolated.\n             = 3: Constant segments\n             = 4: Fritsch-Butland interpolation: Not supported\n             = 5: Steffen interpolation: Not supported\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 values 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 element</strong>, the table value is returned,\n    independent of the value of the input signal.</li>\n<li>If the input signal <strong>u1</strong> or <strong>u2</strong> is <strong>outside</strong> of the defined\n    <strong>interval</strong>, the corresponding value is also determined by linear\n    interpolation through the last or first two points of the table.</li>\n<li>The grid values (first column and first row) have to be strictly\n    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&reg;\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 table2D_1(3,4)   # comment line\n0.0  1.0  2.0  3.0  # u[2] grid points\n1.0  1.0  3.0  5.0\n2.0  2.0  4.0  6.0\n\ndouble table2D_2(4,4)   # comment line\n0.0  1.0  2.0  3.0  # u[2] grid points\n1.0  1.0  3.0  5.0\n2.0  2.0  4.0  6.0\n3.0  3.0  5.0  7.0\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.\nThe matrix elements are interpreted in exactly the same way\nas if the matrix is given as a parameter. For example, the first\ncolumn \"table2D_1[2:,1]\" contains the u[1] grid points,\nand the first row \"table2D_1[1,2:]\" contains the u[2] grid points.\n</p>\n<p>\nMATLAB is a registered trademark of The MathWorks, Inc.\n</p>\n</html>"));
end CombiTable2D;