From 1607d74718300e295ce869925882b5c8349ae39a Mon Sep 17 00:00:00 2001 From: OLSSON Hans Date: Tue, 9 Nov 2021 14:56:20 +0100 Subject: [PATCH 01/15] Consider the derivatives at boundaries in the 2D-table. Updated to current date --- .../C-Sources/ModelicaStandardTables.c | 40 ++++++---- ModelicaTest/Tables/CombiTable2Ds.mo | 80 +++++++++++++++++++ 2 files changed, 106 insertions(+), 14 deletions(-) diff --git a/Modelica/Resources/C-Sources/ModelicaStandardTables.c b/Modelica/Resources/C-Sources/ModelicaStandardTables.c index bc2f7a46b5..47eeba36c5 100644 --- a/Modelica/Resources/C-Sources/ModelicaStandardTables.c +++ b/Modelica/Resources/C-Sources/ModelicaStandardTables.c @@ -39,6 +39,14 @@ Modelica.Blocks.Tables.CombiTable2Dv Changelog: + + Jan. 31, 2022: by Hans Olsson + Added better support for one-sided derivatives of 2d-tables. + The idea is that when we are computing the derivative at a boundary + in the table we should consider the der-value to choose side. + This is less important for 1d-tables and thus ignored in those cases. + (ticket #3893 ) + Nov. 12, 2021: by Thomas Beutlich Fixed derivatives in CombiTable2D for one-sided extrapolation by constant continuation (ticket #3894) @@ -4217,6 +4225,8 @@ double ModelicaStandardTables_CombiTable2D_getDerValue(void* _tableID, double u1 const double u1Max = TABLE_COL0(nRow - 1); const double u2Min = TABLE_ROW0(1); const double u2Max = TABLE_ROW0(nCol - 1); + const double du1 = der_u1 > 0 ? u1*DBL_EPSILON : -u1*DBL_EPSILON; + const double du2 = der_u2 > 0 ? u2*DBL_EPSILON : -u2*DBL_EPSILON; if (nRow == 2) { if (nCol > 2) { @@ -4238,20 +4248,20 @@ double ModelicaStandardTables_CombiTable2D_getDerValue(void* _tableID, double u1 } while (u2 > u2Max); } last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2); + tableID->last2, u2 + du2); tableID->last2 = last2; } - else if (u2 < u2Min) { + else if (u2 + du2 < u2Min) { extrapolate2 = LEFT; last2 = 0; } - else if (u2 > u2Max) { + else if (u2 + du2 > u2Max) { extrapolate2 = RIGHT; last2 = nCol - 3; } else { last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2); + tableID->last2, u2 + du2); tableID->last2 = last2; } @@ -4383,20 +4393,20 @@ double ModelicaStandardTables_CombiTable2D_getDerValue(void* _tableID, double u1 } while (u1 > u1Max); } last1 = findRowIndex(&TABLE(1, 0), nRow - 1, nCol, - tableID->last1, u1); + tableID->last1, u1 + du1); tableID->last1 = last1; } - else if (u1 < u1Min) { + else if (u1 + du1 < u1Min) { extrapolate1 = LEFT; last1 = 0; } - else if (u1 > u1Max) { + else if (u1 + du1 > u1Max) { extrapolate1 = RIGHT; last1 = nRow - 3; } else { last1 = findRowIndex(&TABLE(1, 0), nRow - 1, nCol, - tableID->last1, u1); + tableID->last1, u1 + du1); tableID->last1 = last1; } if (nCol == 2) { @@ -4527,20 +4537,20 @@ double ModelicaStandardTables_CombiTable2D_getDerValue(void* _tableID, double u1 } while (u2 > u2Max); } last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2); + tableID->last2, u2 + du2); tableID->last2 = last2; } - else if (u2 < u2Min) { + else if (u2 + du2 < u2Min) { extrapolate2 = LEFT; last2 = 0; } - else if (u2 > u2Max) { + else if (u2 + du2 > u2Max) { extrapolate2 = RIGHT; last2 = nCol - 3; } else { last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2); + tableID->last2, u2 + du2); tableID->last2 = last2; } @@ -5138,6 +5148,8 @@ double ModelicaStandardTables_CombiTable2D_getDer2Value(void* _tableID, double u const double u1Max = TABLE_COL0(nRow - 1); const double u2Min = TABLE_ROW0(1); const double u2Max = TABLE_ROW0(nCol - 1); + const double du1 = (der_u1 > 0) || (der_u1==0 && der2_u1>0) ? u1*DBL_EPSILON : -u1*DBL_EPSILON; + const double du2 = (der_u2 > 0) || (der_u2==0 && der2_u2>0) ? u2*DBL_EPSILON : -u2*DBL_EPSILON; if (nRow == 2) { if (nCol > 2) { @@ -5159,7 +5171,7 @@ double ModelicaStandardTables_CombiTable2D_getDer2Value(void* _tableID, double u } while (u2 > u2Max); } last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2); + tableID->last2, u2 + du2); tableID->last2 = last2; } else if (u2 < u2Min) { @@ -5172,7 +5184,7 @@ double ModelicaStandardTables_CombiTable2D_getDer2Value(void* _tableID, double u } else { last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2); + tableID->last2, u2 + du2); tableID->last2 = last2; } diff --git a/ModelicaTest/Tables/CombiTable2Ds.mo b/ModelicaTest/Tables/CombiTable2Ds.mo index 836d6bcf47..3687167d53 100644 --- a/ModelicaTest/Tables/CombiTable2Ds.mo +++ b/ModelicaTest/Tables/CombiTable2Ds.mo @@ -1125,4 +1125,84 @@ double mydummyfunc(double dummy_in) { points={{-59,-10},{-52,-10},{-52,4},{-42,4}}, color={0,0,127})); annotation (experiment(StartTime=0, StopTime=14)); end Test33; + + model OneSidedDerivative2D "Test of one sided derivatives in 2D-tables" + // We are diagonally sliding through the table + extends Modelica.Icons.Example; + parameter Real M0[:,:]=[0,-10,1,2,10; -10,2,2,3,4; 1,2,2,3,3; 2,3,3,4,4; 10,3, + 3,4,4]; + parameter Real M[:,:]=[M0[1:1,1:1],M0[1:1,3:end-1];M0[3:end-1,1],M0[3:end-1,3:end-1]]; + Modelica.Blocks.Sources.Ramp ramp( + height=1, + duration=1, + offset=1) + annotation (Placement(transformation(extent={{-76,12},{-56,32}}))); + Modelica.Blocks.Sources.Ramp ramp1( + height=-1, + duration=1, + offset=2) + annotation (Placement(transformation(extent={{-80,-36},{-60,-16}}))); + Modelica.Blocks.Tables.CombiTable2Ds combiTable2Ds1( + tableOnFile=false, + table=M, + smoothness=Modelica.Blocks.Types.Smoothness.LinearSegments, + extrapolation=Modelica.Blocks.Types.Extrapolation.HoldLastPoint) + annotation (Placement(transformation(extent={{40,20},{60,40}}))); + Modelica.Blocks.Continuous.Der der1 + annotation (Placement(transformation(extent={{80,20},{100,40}}))); + Modelica.Blocks.Tables.CombiTable2Ds combiTable2Ds2( + tableOnFile=false, + table=M0, + smoothness=Modelica.Blocks.Types.Smoothness.LinearSegments, + extrapolation=Modelica.Blocks.Types.Extrapolation.LastTwoPoints) + annotation (Placement(transformation(extent={{40,60},{60,80}}))); + Modelica.Blocks.Continuous.Der der2 + annotation (Placement(transformation(extent={{80,60},{100,80}}))); + Modelica.Blocks.Tables.CombiTable2Ds combiTable2Ds3( + tableOnFile=false, + table=M, + smoothness=Modelica.Blocks.Types.Smoothness.LinearSegments, + extrapolation=Modelica.Blocks.Types.Extrapolation.HoldLastPoint) + annotation (Placement(transformation(extent={{40,-80},{60,-60}}))); + Modelica.Blocks.Continuous.Der der3 + annotation (Placement(transformation(extent={{80,-80},{100,-60}}))); + Modelica.Blocks.Tables.CombiTable2Ds combiTable2Ds4( + tableOnFile=false, + table=M0, + smoothness=Modelica.Blocks.Types.Smoothness.LinearSegments, + extrapolation=Modelica.Blocks.Types.Extrapolation.LastTwoPoints) + annotation (Placement(transformation(extent={{40,-40},{60,-20}}))); + Modelica.Blocks.Continuous.Der der4 + annotation (Placement(transformation(extent={{80,-40},{100,-20}}))); + equation + connect(combiTable2Ds1.y, der1.u) + annotation (Line(points={{61,30},{78,30}}, color={0,0,127})); + connect(combiTable2Ds2.y, der2.u) + annotation (Line(points={{61,70},{78,70}}, color={0,0,127})); + connect(ramp.y, combiTable2Ds2.u1) annotation (Line(points={{-55,22},{14,22}, + {14,76},{38,76}}, color={0,0,127})); + connect(ramp.y, combiTable2Ds1.u1) annotation (Line(points={{-55,22},{14,22}, + {14,36},{38,36}}, color={0,0,127})); + connect(ramp1.y, combiTable2Ds2.u2) annotation (Line(points={{-59,-26},{20, + -26},{20,64},{38,64}}, color={0,0,127})); + connect(ramp1.y, combiTable2Ds1.u2) annotation (Line(points={{-59,-26},{20, + -26},{20,24},{38,24}}, color={0,0,127})); + connect(combiTable2Ds3.y,der3. u) + annotation (Line(points={{61,-70},{78,-70}}, color={0,0,127})); + connect(combiTable2Ds4.y, der4.u) + annotation (Line(points={{61,-30},{78,-30}}, color={0,0,127})); + connect(ramp.y, combiTable2Ds4.u2) annotation (Line(points={{-55,22},{14,22}, + {14,-36},{38,-36}}, color={0,0,127})); + connect(combiTable2Ds3.u2, combiTable2Ds4.u2) annotation (Line(points={{38, + -76},{14,-76},{14,-36},{38,-36}}, color={0,0,127})); + connect(combiTable2Ds4.u1, combiTable2Ds2.u2) annotation (Line(points={{38, + -24},{30,-24},{30,-22},{20,-22},{20,64},{38,64}}, color={0,0,127})); + connect(combiTable2Ds3.u1, combiTable2Ds2.u2) annotation (Line(points={{38, + -64},{20,-64},{20,64},{38,64}}, color={0,0,127})); + annotation ( + experiment( + StartTime=-1, + StopTime=4)); + end OneSidedDerivative2D; + end CombiTable2Ds; From 88c839392440335e363ddced6201d217397b4cf3 Mon Sep 17 00:00:00 2001 From: OLSSON Hans Date: Tue, 9 Nov 2021 16:07:18 +0100 Subject: [PATCH 02/15] Improved example to show all issues. --- ModelicaTest/Tables/CombiTable2Ds.mo | 94 +++++++++++++++------------- 1 file changed, 51 insertions(+), 43 deletions(-) diff --git a/ModelicaTest/Tables/CombiTable2Ds.mo b/ModelicaTest/Tables/CombiTable2Ds.mo index 3687167d53..d9c8983479 100644 --- a/ModelicaTest/Tables/CombiTable2Ds.mo +++ b/ModelicaTest/Tables/CombiTable2Ds.mo @@ -1127,7 +1127,10 @@ double mydummyfunc(double dummy_in) { end Test33; model OneSidedDerivative2D "Test of one sided derivatives in 2D-tables" - // We are diagonally sliding through the table + // We are starting at boundaries at the table + // Case 2 and 4 slide diagonally (from different corners) + // Case 1 and 3 start at the edge of the real table and then leave it top-left + // Interpolating in different ways extends Modelica.Icons.Example; parameter Real M0[:,:]=[0,-10,1,2,10; -10,2,2,3,4; 1,2,2,3,3; 2,3,3,4,4; 10,3, 3,4,4]; @@ -1136,20 +1139,12 @@ double mydummyfunc(double dummy_in) { height=1, duration=1, offset=1) - annotation (Placement(transformation(extent={{-76,12},{-56,32}}))); + annotation (Placement(transformation(extent={{-80,40},{-60,60}}))); Modelica.Blocks.Sources.Ramp ramp1( height=-1, duration=1, offset=2) - annotation (Placement(transformation(extent={{-80,-36},{-60,-16}}))); - Modelica.Blocks.Tables.CombiTable2Ds combiTable2Ds1( - tableOnFile=false, - table=M, - smoothness=Modelica.Blocks.Types.Smoothness.LinearSegments, - extrapolation=Modelica.Blocks.Types.Extrapolation.HoldLastPoint) - annotation (Placement(transformation(extent={{40,20},{60,40}}))); - Modelica.Blocks.Continuous.Der der1 - annotation (Placement(transformation(extent={{80,20},{100,40}}))); + annotation (Placement(transformation(extent={{-20,18},{0,38}}))); Modelica.Blocks.Tables.CombiTable2Ds combiTable2Ds2( tableOnFile=false, table=M0, @@ -1158,47 +1153,60 @@ double mydummyfunc(double dummy_in) { annotation (Placement(transformation(extent={{40,60},{60,80}}))); Modelica.Blocks.Continuous.Der der2 annotation (Placement(transformation(extent={{80,60},{100,80}}))); - Modelica.Blocks.Tables.CombiTable2Ds combiTable2Ds3( - tableOnFile=false, - table=M, - smoothness=Modelica.Blocks.Types.Smoothness.LinearSegments, - extrapolation=Modelica.Blocks.Types.Extrapolation.HoldLastPoint) - annotation (Placement(transformation(extent={{40,-80},{60,-60}}))); - Modelica.Blocks.Continuous.Der der3 - annotation (Placement(transformation(extent={{80,-80},{100,-60}}))); Modelica.Blocks.Tables.CombiTable2Ds combiTable2Ds4( tableOnFile=false, table=M0, smoothness=Modelica.Blocks.Types.Smoothness.LinearSegments, extrapolation=Modelica.Blocks.Types.Extrapolation.LastTwoPoints) - annotation (Placement(transformation(extent={{40,-40},{60,-20}}))); + annotation (Placement(transformation(extent={{40,0},{60,20}}))); Modelica.Blocks.Continuous.Der der4 - annotation (Placement(transformation(extent={{80,-40},{100,-20}}))); - equation - connect(combiTable2Ds1.y, der1.u) - annotation (Line(points={{61,30},{78,30}}, color={0,0,127})); + annotation (Placement(transformation(extent={{80,0},{100,20}}))); + Modelica.Blocks.Sources.Ramp ramp2( + height=-1, + duration=1, + offset=1) + annotation (Placement(transformation(extent={{-80,-80},{-60,-60}}))); + Modelica.Blocks.Tables.CombiTable2Ds combiTable2Ds1( + tableOnFile=false, + table=M0, + smoothness=Modelica.Blocks.Types.Smoothness.LinearSegments, + extrapolation=Modelica.Blocks.Types.Extrapolation.LastTwoPoints) + annotation (Placement(transformation(extent={{-20,-40},{0,-20}}))); + Modelica.Blocks.Continuous.Der der1 + annotation (Placement(transformation(extent={{20,-40},{40,-20}}))); + Modelica.Blocks.Tables.CombiTable2Ds combiTable2Ds3( + tableOnFile=false, + table=M, + smoothness=Modelica.Blocks.Types.Smoothness.LinearSegments, + extrapolation=Modelica.Blocks.Types.Extrapolation.HoldLastPoint) + annotation (Placement(transformation(extent={{-20,-80},{0,-60}}))); + Modelica.Blocks.Continuous.Der der3 + annotation (Placement(transformation(extent={{20,-80},{40,-60}}))); + equation connect(combiTable2Ds2.y, der2.u) annotation (Line(points={{61,70},{78,70}}, color={0,0,127})); - connect(ramp.y, combiTable2Ds2.u1) annotation (Line(points={{-55,22},{14,22}, - {14,76},{38,76}}, color={0,0,127})); - connect(ramp.y, combiTable2Ds1.u1) annotation (Line(points={{-55,22},{14,22}, - {14,36},{38,36}}, color={0,0,127})); - connect(ramp1.y, combiTable2Ds2.u2) annotation (Line(points={{-59,-26},{20, - -26},{20,64},{38,64}}, color={0,0,127})); - connect(ramp1.y, combiTable2Ds1.u2) annotation (Line(points={{-59,-26},{20, - -26},{20,24},{38,24}}, color={0,0,127})); - connect(combiTable2Ds3.y,der3. u) - annotation (Line(points={{61,-70},{78,-70}}, color={0,0,127})); + connect(ramp.y, combiTable2Ds2.u1) annotation (Line(points={{-59,50},{18,50},{ + 18,76},{38,76}}, color={0,0,127})); + connect(ramp1.y, combiTable2Ds2.u2) annotation (Line(points={{1,28},{24,28},{24, + 64},{38,64}}, color={0,0,127})); connect(combiTable2Ds4.y, der4.u) - annotation (Line(points={{61,-30},{78,-30}}, color={0,0,127})); - connect(ramp.y, combiTable2Ds4.u2) annotation (Line(points={{-55,22},{14,22}, - {14,-36},{38,-36}}, color={0,0,127})); - connect(combiTable2Ds3.u2, combiTable2Ds4.u2) annotation (Line(points={{38, - -76},{14,-76},{14,-36},{38,-36}}, color={0,0,127})); - connect(combiTable2Ds4.u1, combiTable2Ds2.u2) annotation (Line(points={{38, - -24},{30,-24},{30,-22},{20,-22},{20,64},{38,64}}, color={0,0,127})); - connect(combiTable2Ds3.u1, combiTable2Ds2.u2) annotation (Line(points={{38, - -64},{20,-64},{20,64},{38,64}}, color={0,0,127})); + annotation (Line(points={{61,10},{78,10}}, color={0,0,127})); + connect(ramp.y, combiTable2Ds4.u2) annotation (Line(points={{-59,50},{-38,50}, + {-38,4},{38,4}}, color={0,0,127})); + connect(combiTable2Ds4.u1, combiTable2Ds2.u2) annotation (Line(points={{38,16}, + {34,16},{34,18},{24,18},{24,64},{38,64}}, color={0,0,127})); + connect(ramp2.y, combiTable2Ds1.u1) annotation (Line(points={{-59,-70},{-30,-70}, + {-30,-24},{-22,-24}}, color={0,0,127})); + connect(ramp2.y, combiTable2Ds1.u2) annotation (Line(points={{-59,-70},{-30,-70}, + {-30,-36},{-22,-36}}, color={0,0,127})); + connect(combiTable2Ds1.y, der1.u) + annotation (Line(points={{1,-30},{18,-30}}, color={0,0,127})); + connect(combiTable2Ds3.u1, combiTable2Ds1.u1) annotation (Line(points={{-22,-64}, + {-26,-64},{-26,-70},{-30,-70},{-30,-24},{-22,-24}}, color={0,0,127})); + connect(combiTable2Ds3.u2, combiTable2Ds1.u1) annotation (Line(points={{-22,-76}, + {-24,-76},{-24,-70},{-30,-70},{-30,-24},{-22,-24}}, color={0,0,127})); + connect(combiTable2Ds3.y, der3.u) + annotation (Line(points={{1,-70},{18,-70}}, color={0,0,127})); annotation ( experiment( StartTime=-1, From ef06462f3c58140fe5aee1853b11a453fab7c4aa Mon Sep 17 00:00:00 2001 From: OLSSON Hans Date: Mon, 31 Jan 2022 13:48:05 +0100 Subject: [PATCH 03/15] Avoid using epsilon altogether. --- .../C-Sources/ModelicaStandardTables.c | 85 +++++++++++-------- 1 file changed, 49 insertions(+), 36 deletions(-) diff --git a/Modelica/Resources/C-Sources/ModelicaStandardTables.c b/Modelica/Resources/C-Sources/ModelicaStandardTables.c index 47eeba36c5..653acab723 100644 --- a/Modelica/Resources/C-Sources/ModelicaStandardTables.c +++ b/Modelica/Resources/C-Sources/ModelicaStandardTables.c @@ -499,10 +499,20 @@ static size_t findRowIndex(const double* table, size_t nRow, size_t nCol, * table[i*nCol] <= x * table[(i + 1)*nCol] > x for i + 2 < nRow */ +static size_t findRowIndex2(const double* table, size_t nRow, size_t nCol, + size_t last, double x, double dx); +/* Using dx as tie-breaker if table[i*nCol] == x to treat x as x+dx*eps */ static size_t findColIndex(_In_ const double* table, size_t nCol, size_t last, double x) MODELICA_NONNULLATTR; /* Same as findRowIndex but works on rows */ +static size_t findColIndex2(_In_ const double* table, size_t nCol, size_t last, + double x, double dx) MODELICA_NONNULLATTR; + /* Same as findRowIndex2 but works on rows */ + +static int findLess(double x, double dx, double val) { + return x 0 ? u1*DBL_EPSILON : -u1*DBL_EPSILON; - const double du2 = der_u2 > 0 ? u2*DBL_EPSILON : -u2*DBL_EPSILON; if (nRow == 2) { if (nCol > 2) { @@ -4247,21 +4255,21 @@ double ModelicaStandardTables_CombiTable2D_getDerValue(void* _tableID, double u1 u2 -= T; } while (u2 > u2Max); } - last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2 + du2); + last2 = findColIndex2(&TABLE(0, 1), nCol - 1, + tableID->last2, u2, der_u2); tableID->last2 = last2; } - else if (u2 + du2 < u2Min) { + else if (findLess(u2, der_u2, u2Min)) { extrapolate2 = LEFT; last2 = 0; } - else if (u2 + du2 > u2Max) { + else if (!findLess(u2, der_u2, u2Max)) { extrapolate2 = RIGHT; last2 = nCol - 3; } else { - last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2 + du2); + last2 = findColIndex2(&TABLE(0, 1), nCol - 1, + tableID->last2, u2, der_u2); tableID->last2 = last2; } @@ -4392,21 +4400,21 @@ double ModelicaStandardTables_CombiTable2D_getDerValue(void* _tableID, double u1 u1 -= T; } while (u1 > u1Max); } - last1 = findRowIndex(&TABLE(1, 0), nRow - 1, nCol, - tableID->last1, u1 + du1); + last1 = findRowIndex2(&TABLE(1, 0), nRow - 1, nCol, + tableID->last1, u1, der_u1); tableID->last1 = last1; } - else if (u1 + du1 < u1Min) { + else if (findLess(u1, der_u1, u1Min)) { extrapolate1 = LEFT; last1 = 0; } - else if (u1 + du1 > u1Max) { + else if (!findLess(u1, der_u1, u1Max)) { extrapolate1 = RIGHT; last1 = nRow - 3; } else { - last1 = findRowIndex(&TABLE(1, 0), nRow - 1, nCol, - tableID->last1, u1 + du1); + last1 = findRowIndex2(&TABLE(1, 0), nRow - 1, nCol, + tableID->last1, u1, der_u1); tableID->last1 = last1; } if (nCol == 2) { @@ -4536,21 +4544,21 @@ double ModelicaStandardTables_CombiTable2D_getDerValue(void* _tableID, double u1 u2 -= T; } while (u2 > u2Max); } - last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2 + du2); + last2 = findColIndex2(&TABLE(0, 1), nCol - 1, + tableID->last2, u2, der_u2); tableID->last2 = last2; } - else if (u2 + du2 < u2Min) { + else if (findLess(u2, der_u2, u2Min)) { extrapolate2 = LEFT; last2 = 0; } - else if (u2 + du2 > u2Max) { + else if (!findLess(u2, der_u2, u2Max)) { extrapolate2 = RIGHT; last2 = nCol - 3; } else { - last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2 + du2); + last2 = findColIndex2(&TABLE(0, 1), nCol - 1, + tableID->last2, u2, der_u2); tableID->last2 = last2; } @@ -5148,8 +5156,6 @@ double ModelicaStandardTables_CombiTable2D_getDer2Value(void* _tableID, double u const double u1Max = TABLE_COL0(nRow - 1); const double u2Min = TABLE_ROW0(1); const double u2Max = TABLE_ROW0(nCol - 1); - const double du1 = (der_u1 > 0) || (der_u1==0 && der2_u1>0) ? u1*DBL_EPSILON : -u1*DBL_EPSILON; - const double du2 = (der_u2 > 0) || (der_u2==0 && der2_u2>0) ? u2*DBL_EPSILON : -u2*DBL_EPSILON; if (nRow == 2) { if (nCol > 2) { @@ -5170,8 +5176,8 @@ double ModelicaStandardTables_CombiTable2D_getDer2Value(void* _tableID, double u u2 -= T; } while (u2 > u2Max); } - last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2 + du2); + last2 = findColIndex2(&TABLE(0, 1), nCol - 1, + tableID->last2, u2, der_u2); tableID->last2 = last2; } else if (u2 < u2Min) { @@ -5183,8 +5189,8 @@ double ModelicaStandardTables_CombiTable2D_getDer2Value(void* _tableID, double u last2 = nCol - 3; } else { - last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2 + du2); + last2 = findColIndex2(&TABLE(0, 1), nCol - 1, + tableID->last2, u2, der_u2); tableID->last2 = last2; } @@ -6180,14 +6186,14 @@ static int isNearlyEqual(double x, double y) { return fabs(y - x) < cmp; } -static size_t findRowIndex(const double* table, size_t nRow, size_t nCol, - size_t last, double x) { +static size_t findRowIndex2(const double* table, size_t nRow, size_t nCol, + size_t last, double x, double dx) { size_t i0 = 0; size_t i1 = nRow - 1; - if (x < TABLE_COL0(last)) { + if (findLess(x, dx, TABLE_COL0(last))) { i1 = last; } - else if (x >= TABLE_COL0(last + 1)) { + else if (!findLess(x, dx, TABLE_COL0(last + 1))) { i0 = last; } else { @@ -6197,7 +6203,7 @@ static size_t findRowIndex(const double* table, size_t nRow, size_t nCol, /* Binary search */ while (i1 > i0 + 1) { const size_t i = (i0 + i1)/2; - if (x < TABLE_COL0(i)) { + if (findLess(x, dx, TABLE_COL0(i))) { i1 = i; } else { @@ -6206,15 +6212,19 @@ static size_t findRowIndex(const double* table, size_t nRow, size_t nCol, } return i0; } +static size_t findRowIndex(const double* table, size_t nRow, size_t nCol, + size_t last, double x) { + return findRowIndex2(table, nRow, nCol, last, x, 0.0); +} -static size_t findColIndex(_In_ const double* table, size_t nCol, size_t last, - double x) { +static size_t findColIndex2(_In_ const double* table, size_t nCol, size_t last, + double x, double dx) { size_t i0 = 0; size_t i1 = nCol - 1; - if (x < TABLE_ROW0(last)) { + if (findLess(x, dx, TABLE_ROW0(last))) { i1 = last; } - else if (x >= TABLE_ROW0(last + 1)) { + else if (findLess(x, dx, TABLE_ROW0(last + 1))) { i0 = last; } else { @@ -6224,7 +6234,7 @@ static size_t findColIndex(_In_ const double* table, size_t nCol, size_t last, /* Binary search */ while (i1 > i0 + 1) { const size_t i = (i0 + i1)/2; - if (x < TABLE_ROW0(i)) { + if (findLess(x, dx, TABLE_ROW0(i))) { i1 = i; } else { @@ -6233,6 +6243,9 @@ static size_t findColIndex(_In_ const double* table, size_t nCol, size_t last, } return i0; } +static size_t findColIndex(_In_ const double* table, size_t nCol, size_t last, double x) { + return findColIndex2(table, nCol, last, x, 0.0); +} /* ----- Internal check functions ----- */ From fdf297e5ac199e74c9fd77e89424d659cf8be83f Mon Sep 17 00:00:00 2001 From: OLSSON Hans Date: Mon, 31 Jan 2022 13:55:43 +0100 Subject: [PATCH 04/15] Spelling --- Modelica/Resources/C-Sources/ModelicaStandardTables.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Modelica/Resources/C-Sources/ModelicaStandardTables.c b/Modelica/Resources/C-Sources/ModelicaStandardTables.c index 653acab723..982918ac7a 100644 --- a/Modelica/Resources/C-Sources/ModelicaStandardTables.c +++ b/Modelica/Resources/C-Sources/ModelicaStandardTables.c @@ -505,10 +505,11 @@ static size_t findRowIndex2(const double* table, size_t nRow, size_t nCol, static size_t findColIndex(_In_ const double* table, size_t nCol, size_t last, double x) MODELICA_NONNULLATTR; - /* Same as findRowIndex but works on rows */ + /* Same as findRowIndex but works on columns */ + static size_t findColIndex2(_In_ const double* table, size_t nCol, size_t last, double x, double dx) MODELICA_NONNULLATTR; - /* Same as findRowIndex2 but works on rows */ + /* Same as findRowIndex2 but works on columns */ static int findLess(double x, double dx, double val) { return x Date: Mon, 31 Jan 2022 22:02:52 +0100 Subject: [PATCH 05/15] AddReference --- .../CombiTable2Ds/OneSidedDerivative2D/comparisonSignals.txt | 5 +++++ ModelicaTest/Tables/CombiTable2Ds.mo | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 ModelicaTest/Resources/Reference/ModelicaTest/Tables/CombiTable2Ds/OneSidedDerivative2D/comparisonSignals.txt diff --git a/ModelicaTest/Resources/Reference/ModelicaTest/Tables/CombiTable2Ds/OneSidedDerivative2D/comparisonSignals.txt b/ModelicaTest/Resources/Reference/ModelicaTest/Tables/CombiTable2Ds/OneSidedDerivative2D/comparisonSignals.txt new file mode 100644 index 0000000000..b9fd9b6250 --- /dev/null +++ b/ModelicaTest/Resources/Reference/ModelicaTest/Tables/CombiTable2Ds/OneSidedDerivative2D/comparisonSignals.txt @@ -0,0 +1,5 @@ +time +der1.y +der2.y +der3.y +der4.y diff --git a/ModelicaTest/Tables/CombiTable2Ds.mo b/ModelicaTest/Tables/CombiTable2Ds.mo index d9c8983479..1a528114aa 100644 --- a/ModelicaTest/Tables/CombiTable2Ds.mo +++ b/ModelicaTest/Tables/CombiTable2Ds.mo @@ -1126,7 +1126,7 @@ double mydummyfunc(double dummy_in) { annotation (experiment(StartTime=0, StopTime=14)); end Test33; - model OneSidedDerivative2D "Test of one sided derivatives in 2D-tables" + model OneSidedDerivative2D "Test of one sided derivatives in 2D-tables (Ticket #3893)" // We are starting at boundaries at the table // Case 2 and 4 slide diagonally (from different corners) // Case 1 and 3 start at the edge of the real table and then leave it top-left From a2e0c8450ff09f5e4e01b966cde89b291507d8e2 Mon Sep 17 00:00:00 2001 From: OLSSON Hans Date: Mon, 31 Jan 2022 22:40:21 +0100 Subject: [PATCH 06/15] Add vector-test case (and slight grammatical error). --- ModelicaTest/Tables/CombiTable2Ds.mo | 2 +- ModelicaTest/Tables/CombiTable2Dv.mo | 89 ++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/ModelicaTest/Tables/CombiTable2Ds.mo b/ModelicaTest/Tables/CombiTable2Ds.mo index 1a528114aa..ed9909b99a 100644 --- a/ModelicaTest/Tables/CombiTable2Ds.mo +++ b/ModelicaTest/Tables/CombiTable2Ds.mo @@ -1127,7 +1127,7 @@ double mydummyfunc(double dummy_in) { end Test33; model OneSidedDerivative2D "Test of one sided derivatives in 2D-tables (Ticket #3893)" - // We are starting at boundaries at the table + // We are starting at boundaries of the table // Case 2 and 4 slide diagonally (from different corners) // Case 1 and 3 start at the edge of the real table and then leave it top-left // Interpolating in different ways diff --git a/ModelicaTest/Tables/CombiTable2Dv.mo b/ModelicaTest/Tables/CombiTable2Dv.mo index d13412b1f7..2152be0341 100644 --- a/ModelicaTest/Tables/CombiTable2Dv.mo +++ b/ModelicaTest/Tables/CombiTable2Dv.mo @@ -950,4 +950,93 @@ double mydummyfunc(double dummy_in) { points={{-59,-10},{-52,-10},{-52,4},{-42,4}}, color={0,0,127})); annotation (experiment(StartTime=0, StopTime=14)); end Test33; + + model OneSidedDerivative2D "Test of one sided derivatives in 2D-tables (Ticket #3893)" + // We are starting at boundaries of the table + // Case 2 and 4 slide diagonally (from different corners) + // Case 1 and 3 start at the edge of the real table and then leave it top-left + // Interpolating in different ways + // Note that compared to the scalar variant 1,2, and 4 have been merged + // into one vector component + // Case 3 is separate. + extends Modelica.Icons.Example; + parameter Real M0[:,:]=[0,-10,1,2,10; -10,2,2,3,4; 1,2,2,3,3; 2,3,3,4,4; 10,3, + 3,4,4]; + parameter Real M[:,:]=[M0[1:1,1:1],M0[1:1,3:end-1];M0[3:end-1,1],M0[3:end-1,3:end-1]]; + Modelica.Blocks.Sources.Ramp ramp( + height=1, + duration=1, + offset=1) + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, origin={-90, + 50}))); + Modelica.Blocks.Sources.Ramp ramp1( + height=-1, + duration=1, + offset=2) + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, origin={-90, + 10}))); + Modelica.Blocks.Tables.CombiTable2Dv combiTable2Dv( + n=3, + tableOnFile=false, + table=M0, + smoothness=Modelica.Blocks.Types.Smoothness.LinearSegments, + extrapolation=Modelica.Blocks.Types.Extrapolation.LastTwoPoints) + annotation (Placement(transformation(extent={{-20,-20},{20,20}}, origin={22,40}))); + Modelica.Blocks.Continuous.Der der2 + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, origin={90,30}))); + Modelica.Blocks.Continuous.Der der4 + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, origin={90,90}))); + Modelica.Blocks.Sources.Ramp ramp2( + height=-1, + duration=1, + offset=1) + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, origin={-90, + -70}))); + Modelica.Blocks.Continuous.Der der1 + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, origin={90,-10}))); + Modelica.Blocks.Tables.CombiTable2Dv combiTable2Dv3( + tableOnFile=false, + table=M, + smoothness=Modelica.Blocks.Types.Smoothness.LinearSegments, + extrapolation=Modelica.Blocks.Types.Extrapolation.HoldLastPoint) + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, origin={-30, + -70}))); + Modelica.Blocks.Continuous.Der der3 + annotation (Placement(transformation(extent={{-10,-10},{10,10}}, origin={30,-70}))); + equation + connect(combiTable2Dv.y[2], der2.u) + annotation (Line(points={{44,40},{72,40},{72,30},{78,30}}, + color={0,0,127})); + connect(ramp.y, combiTable2Dv.u1[2]) annotation (Line(points={{-79,50},{-62,50}, + {-62,52},{-2,52}}, + color={0,0,127})); + connect(ramp1.y, combiTable2Dv.u2[2]) annotation (Line(points={{-79,10},{-58,10}, + {-58,28},{-2,28}}, color={0,0,127})); + connect(combiTable2Dv.y[3], der4.u) + annotation (Line(points={{44,40.6667},{56,40.6667},{56,90},{78,90}}, + color={0,0,127})); + connect(ramp.y, combiTable2Dv.u2[3]) annotation (Line(points={{-79,50},{-62, + 50},{-62,29.3333},{-2,29.3333}}, + color={0,0,127})); + connect(combiTable2Dv.u1[3], combiTable2Dv.u2[2]) annotation (Line(points={{-2, + 53.3333},{-58,53.3333},{-58,28},{-2,28}}, color={0,0,127})); + connect(combiTable2Dv.y[1], der1.u) + annotation (Line(points={{44,39.3333},{50,39.3333},{50,-10},{78,-10}}, + color={0,0,127})); + connect(combiTable2Dv3.y[1], der3.u) + annotation (Line(points={{-19,-70},{18,-70}}, + color={0,0,127})); + connect(ramp2.y, combiTable2Dv3.u1[1]) annotation (Line(points={{-79,-70},{-52, + -70},{-52,-64},{-42,-64}}, color={0,0,127})); + connect(ramp2.y, combiTable2Dv3.u2[1]) annotation (Line(points={{-79,-70},{-52, + -70},{-52,-76},{-42,-76}}, color={0,0,127})); + connect(ramp2.y, combiTable2Dv.u2[1]) annotation (Line(points={{-79,-70},{-52, + -70},{-52,26.6667},{-2,26.6667}}, color={0,0,127})); + connect(ramp2.y, combiTable2Dv.u1[1]) annotation (Line(points={{-79,-70},{-52, + -70},{-52,50.6667},{-2,50.6667}}, color={0,0,127})); + annotation ( + experiment( + StartTime=-1, + StopTime=4)); + end OneSidedDerivative2D; end CombiTable2Dv; From 545efc6757f9fb7562635919e64e214f44d41ac6 Mon Sep 17 00:00:00 2001 From: OLSSON Hans Date: Mon, 31 Jan 2022 22:41:42 +0100 Subject: [PATCH 07/15] Reference --- .../CombiTable2Dv/OneSidedDerivative2D/comparisonSignals.txt | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 ModelicaTest/Resources/Reference/ModelicaTest/Tables/CombiTable2Dv/OneSidedDerivative2D/comparisonSignals.txt diff --git a/ModelicaTest/Resources/Reference/ModelicaTest/Tables/CombiTable2Dv/OneSidedDerivative2D/comparisonSignals.txt b/ModelicaTest/Resources/Reference/ModelicaTest/Tables/CombiTable2Dv/OneSidedDerivative2D/comparisonSignals.txt new file mode 100644 index 0000000000..b9fd9b6250 --- /dev/null +++ b/ModelicaTest/Resources/Reference/ModelicaTest/Tables/CombiTable2Dv/OneSidedDerivative2D/comparisonSignals.txt @@ -0,0 +1,5 @@ +time +der1.y +der2.y +der3.y +der4.y From 2a179582555926db67437c443b60e625523c6471 Mon Sep 17 00:00:00 2001 From: Thomas Beutlich Date: Tue, 1 Feb 2022 21:17:19 +0100 Subject: [PATCH 08/15] refs #3893: Fix formatting and update naming --- .../C-Sources/ModelicaStandardTables.c | 61 +++++++++++-------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/Modelica/Resources/C-Sources/ModelicaStandardTables.c b/Modelica/Resources/C-Sources/ModelicaStandardTables.c index 982918ac7a..70c2204a39 100644 --- a/Modelica/Resources/C-Sources/ModelicaStandardTables.c +++ b/Modelica/Resources/C-Sources/ModelicaStandardTables.c @@ -39,14 +39,14 @@ Modelica.Blocks.Tables.CombiTable2Dv Changelog: - - Jan. 31, 2022: by Hans Olsson - Added better support for one-sided derivatives of 2d-tables. + + Jan. 31, 2022: by Hans Olsson, Dassault Systemes + Added better support for one-sided derivatives of CombiTable2D. The idea is that when we are computing the derivative at a boundary in the table we should consider the der-value to choose side. This is less important for 1d-tables and thus ignored in those cases. - (ticket #3893 ) - + (ticket #3893) + Nov. 12, 2021: by Thomas Beutlich Fixed derivatives in CombiTable2D for one-sided extrapolation by constant continuation (ticket #3894) @@ -492,16 +492,17 @@ extern int usertab(char* tableName, int nipo, int dim[], int* colWise, static int isNearlyEqual(double x, double y); /* Compare two floating-point numbers by threshold _EPSILON */ -static size_t findRowIndex(const double* table, size_t nRow, size_t nCol, - size_t last, double x); +static size_t findRowIndex(_In_ const double* table, size_t nRow, size_t nCol, + size_t last, double x) MODELICA_NONNULLATTR; /* Find the row index i using binary search such that * i + 1 < nRow * table[i*nCol] <= x * table[(i + 1)*nCol] > x for i + 2 < nRow */ -static size_t findRowIndex2(const double* table, size_t nRow, size_t nCol, - size_t last, double x, double dx); -/* Using dx as tie-breaker if table[i*nCol] == x to treat x as x+dx*eps */ + +static size_t findRowIndex2(_In_ const double* table, size_t nRow, size_t nCol, + size_t last, double x, double dx) MODELICA_NONNULLATTR; + /* Using dx as tie-breaker if table[i*nCol] == x to treat x as x+dx*eps */ static size_t findColIndex(_In_ const double* table, size_t nCol, size_t last, double x) MODELICA_NONNULLATTR; @@ -511,9 +512,8 @@ static size_t findColIndex2(_In_ const double* table, size_t nCol, size_t last, double x, double dx) MODELICA_NONNULLATTR; /* Same as findRowIndex2 but works on columns */ -static int findLess(double x, double dx, double val) { - return xlast2, u2, der_u2); tableID->last2 = last2; } - else if (findLess(u2, der_u2, u2Min)) { + else if (isLess(u2, der_u2, u2Min)) { extrapolate2 = LEFT; last2 = 0; } - else if (!findLess(u2, der_u2, u2Max)) { + else if (!isLess(u2, der_u2, u2Max)) { extrapolate2 = RIGHT; last2 = nCol - 3; } @@ -4405,11 +4405,11 @@ double ModelicaStandardTables_CombiTable2D_getDerValue(void* _tableID, double u1 tableID->last1, u1, der_u1); tableID->last1 = last1; } - else if (findLess(u1, der_u1, u1Min)) { + else if (isLess(u1, der_u1, u1Min)) { extrapolate1 = LEFT; last1 = 0; } - else if (!findLess(u1, der_u1, u1Max)) { + else if (!isLess(u1, der_u1, u1Max)) { extrapolate1 = RIGHT; last1 = nRow - 3; } @@ -4549,11 +4549,11 @@ double ModelicaStandardTables_CombiTable2D_getDerValue(void* _tableID, double u1 tableID->last2, u2, der_u2); tableID->last2 = last2; } - else if (findLess(u2, der_u2, u2Min)) { + else if (isLess(u2, der_u2, u2Min)) { extrapolate2 = LEFT; last2 = 0; } - else if (!findLess(u2, der_u2, u2Max)) { + else if (!isLess(u2, der_u2, u2Max)) { extrapolate2 = RIGHT; last2 = nCol - 3; } @@ -6191,10 +6191,10 @@ static size_t findRowIndex2(const double* table, size_t nRow, size_t nCol, size_t last, double x, double dx) { size_t i0 = 0; size_t i1 = nRow - 1; - if (findLess(x, dx, TABLE_COL0(last))) { + if (isLess(x, dx, TABLE_COL0(last))) { i1 = last; } - else if (!findLess(x, dx, TABLE_COL0(last + 1))) { + else if (!isLess(x, dx, TABLE_COL0(last + 1))) { i0 = last; } else { @@ -6204,7 +6204,7 @@ static size_t findRowIndex2(const double* table, size_t nRow, size_t nCol, /* Binary search */ while (i1 > i0 + 1) { const size_t i = (i0 + i1)/2; - if (findLess(x, dx, TABLE_COL0(i))) { + if (isLess(x, dx, TABLE_COL0(i))) { i1 = i; } else { @@ -6213,19 +6213,20 @@ static size_t findRowIndex2(const double* table, size_t nRow, size_t nCol, } return i0; } + static size_t findRowIndex(const double* table, size_t nRow, size_t nCol, size_t last, double x) { - return findRowIndex2(table, nRow, nCol, last, x, 0.0); + return findRowIndex2(table, nRow, nCol, last, x, 0.0); } static size_t findColIndex2(_In_ const double* table, size_t nCol, size_t last, double x, double dx) { size_t i0 = 0; size_t i1 = nCol - 1; - if (findLess(x, dx, TABLE_ROW0(last))) { + if (isLess(x, dx, TABLE_ROW0(last))) { i1 = last; } - else if (findLess(x, dx, TABLE_ROW0(last + 1))) { + else if (isLess(x, dx, TABLE_ROW0(last + 1))) { i0 = last; } else { @@ -6235,7 +6236,7 @@ static size_t findColIndex2(_In_ const double* table, size_t nCol, size_t last, /* Binary search */ while (i1 > i0 + 1) { const size_t i = (i0 + i1)/2; - if (findLess(x, dx, TABLE_ROW0(i))) { + if (isLess(x, dx, TABLE_ROW0(i))) { i1 = i; } else { @@ -6244,12 +6245,18 @@ static size_t findColIndex2(_In_ const double* table, size_t nCol, size_t last, } return i0; } + static size_t findColIndex(_In_ const double* table, size_t nCol, size_t last, double x) { - return findColIndex2(table, nCol, last, x, 0.0); + return findColIndex2(table, nCol, last, x, 0.0); } + /* ----- Internal check functions ----- */ +static int isLess(double x, double dx, double val) { + return x < val || (x == val && dx < 0); +} + static int isValidName(_In_z_ const char* name) { int isValid = 0; if (NULL != name) { From fb57949397065a3423c8babacf2f0886a572fa82 Mon Sep 17 00:00:00 2001 From: Thomas Beutlich Date: Tue, 1 Feb 2022 21:25:25 +0100 Subject: [PATCH 09/15] refs #3893: Fix formatting --- Modelica/Resources/C-Sources/ModelicaStandardTables.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Modelica/Resources/C-Sources/ModelicaStandardTables.c b/Modelica/Resources/C-Sources/ModelicaStandardTables.c index 70c2204a39..8f1f6568bb 100644 --- a/Modelica/Resources/C-Sources/ModelicaStandardTables.c +++ b/Modelica/Resources/C-Sources/ModelicaStandardTables.c @@ -6187,8 +6187,8 @@ static int isNearlyEqual(double x, double y) { return fabs(y - x) < cmp; } -static size_t findRowIndex2(const double* table, size_t nRow, size_t nCol, - size_t last, double x, double dx) { +static size_t findRowIndex2(_In_ const double* table, size_t nRow, size_t nCol, + size_t last, double x, double dx) { size_t i0 = 0; size_t i1 = nRow - 1; if (isLess(x, dx, TABLE_COL0(last))) { @@ -6214,13 +6214,13 @@ static size_t findRowIndex2(const double* table, size_t nRow, size_t nCol, return i0; } -static size_t findRowIndex(const double* table, size_t nRow, size_t nCol, +static size_t findRowIndex(_In_ const double* table, size_t nRow, size_t nCol, size_t last, double x) { return findRowIndex2(table, nRow, nCol, last, x, 0.0); } static size_t findColIndex2(_In_ const double* table, size_t nCol, size_t last, - double x, double dx) { + double x, double dx) { size_t i0 = 0; size_t i1 = nCol - 1; if (isLess(x, dx, TABLE_ROW0(last))) { From cdabfdca9fee1caf0c3f7ea8d7747f4e4080ab83 Mon Sep 17 00:00:00 2001 From: OLSSON Hans Date: Fri, 18 Feb 2022 15:06:06 +0100 Subject: [PATCH 10/15] BreakTiesAsBefore --- Modelica/Resources/C-Sources/ModelicaStandardTables.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modelica/Resources/C-Sources/ModelicaStandardTables.c b/Modelica/Resources/C-Sources/ModelicaStandardTables.c index 8f1f6568bb..0137dcd608 100644 --- a/Modelica/Resources/C-Sources/ModelicaStandardTables.c +++ b/Modelica/Resources/C-Sources/ModelicaStandardTables.c @@ -4264,7 +4264,7 @@ double ModelicaStandardTables_CombiTable2D_getDerValue(void* _tableID, double u1 extrapolate2 = LEFT; last2 = 0; } - else if (!isLess(u2, der_u2, u2Max)) { + else if (isLess(u2Max, -der_u2, u2)) { extrapolate2 = RIGHT; last2 = nCol - 3; } From e557f4f951028f83af9a3ddae3cb85478b705017 Mon Sep 17 00:00:00 2001 From: OLSSON Hans Date: Fri, 18 Feb 2022 15:08:01 +0100 Subject: [PATCH 11/15] BreakTiesAsBefore2 --- Modelica/Resources/C-Sources/ModelicaStandardTables.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modelica/Resources/C-Sources/ModelicaStandardTables.c b/Modelica/Resources/C-Sources/ModelicaStandardTables.c index 0137dcd608..74fcf69a90 100644 --- a/Modelica/Resources/C-Sources/ModelicaStandardTables.c +++ b/Modelica/Resources/C-Sources/ModelicaStandardTables.c @@ -4553,7 +4553,7 @@ double ModelicaStandardTables_CombiTable2D_getDerValue(void* _tableID, double u1 extrapolate2 = LEFT; last2 = 0; } - else if (!isLess(u2, der_u2, u2Max)) { + else if (isLess(u2Max, -der_u2, u2)) { extrapolate2 = RIGHT; last2 = nCol - 3; } From 786084856210fb0741a1535209504d9003a770a3 Mon Sep 17 00:00:00 2001 From: OLSSON Hans Date: Fri, 18 Feb 2022 15:11:32 +0100 Subject: [PATCH 12/15] BreakTiesAsBefore --- Modelica/Resources/C-Sources/ModelicaStandardTables.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modelica/Resources/C-Sources/ModelicaStandardTables.c b/Modelica/Resources/C-Sources/ModelicaStandardTables.c index 74fcf69a90..010fe60033 100644 --- a/Modelica/Resources/C-Sources/ModelicaStandardTables.c +++ b/Modelica/Resources/C-Sources/ModelicaStandardTables.c @@ -4409,7 +4409,7 @@ double ModelicaStandardTables_CombiTable2D_getDerValue(void* _tableID, double u1 extrapolate1 = LEFT; last1 = 0; } - else if (!isLess(u1, der_u1, u1Max)) { + else if (isLess(u1Max, -der_u1, u1)) { extrapolate1 = RIGHT; last1 = nRow - 3; } @@ -6226,7 +6226,7 @@ static size_t findColIndex2(_In_ const double* table, size_t nCol, size_t last, if (isLess(x, dx, TABLE_ROW0(last))) { i1 = last; } - else if (isLess(x, dx, TABLE_ROW0(last + 1))) { + else if (!isLess(x, dx, TABLE_ROW0(last + 1))) { i0 = last; } else { From 6237a23c173ee322234cecd229c7b06dc1ffa049 Mon Sep 17 00:00:00 2001 From: OLSSON Hans Date: Fri, 18 Feb 2022 15:14:33 +0100 Subject: [PATCH 13/15] ClearerName --- .../C-Sources/ModelicaStandardTables.c | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Modelica/Resources/C-Sources/ModelicaStandardTables.c b/Modelica/Resources/C-Sources/ModelicaStandardTables.c index 010fe60033..4cdc6b3677 100644 --- a/Modelica/Resources/C-Sources/ModelicaStandardTables.c +++ b/Modelica/Resources/C-Sources/ModelicaStandardTables.c @@ -512,7 +512,7 @@ static size_t findColIndex2(_In_ const double* table, size_t nCol, size_t last, double x, double dx) MODELICA_NONNULLATTR; /* Same as findRowIndex2 but works on columns */ -static int isLess(double x, double dx, double val); +static int isLessOrEqualWNegativeSlope(double x, double dx, double val); /* Check, whether x is less than val, also using dx as tie-breaker */ static int isValidName(_In_z_ const char* name) MODELICA_NONNULLATTR; @@ -4260,11 +4260,11 @@ double ModelicaStandardTables_CombiTable2D_getDerValue(void* _tableID, double u1 tableID->last2, u2, der_u2); tableID->last2 = last2; } - else if (isLess(u2, der_u2, u2Min)) { + else if (isLessOrEqualWNegativeSlope(u2, der_u2, u2Min)) { extrapolate2 = LEFT; last2 = 0; } - else if (isLess(u2Max, -der_u2, u2)) { + else if (isLessOrEqualWNegativeSlope(u2Max, -der_u2, u2)) { extrapolate2 = RIGHT; last2 = nCol - 3; } @@ -4405,11 +4405,11 @@ double ModelicaStandardTables_CombiTable2D_getDerValue(void* _tableID, double u1 tableID->last1, u1, der_u1); tableID->last1 = last1; } - else if (isLess(u1, der_u1, u1Min)) { + else if (isLessOrEqualWNegativeSlope(u1, der_u1, u1Min)) { extrapolate1 = LEFT; last1 = 0; } - else if (isLess(u1Max, -der_u1, u1)) { + else if (isLessOrEqualWNegativeSlope(u1Max, -der_u1, u1)) { extrapolate1 = RIGHT; last1 = nRow - 3; } @@ -4549,11 +4549,11 @@ double ModelicaStandardTables_CombiTable2D_getDerValue(void* _tableID, double u1 tableID->last2, u2, der_u2); tableID->last2 = last2; } - else if (isLess(u2, der_u2, u2Min)) { + else if (isLessOrEqualWNegativeSlope(u2, der_u2, u2Min)) { extrapolate2 = LEFT; last2 = 0; } - else if (isLess(u2Max, -der_u2, u2)) { + else if (isLessOrEqualWNegativeSlope(u2Max, -der_u2, u2)) { extrapolate2 = RIGHT; last2 = nCol - 3; } @@ -6191,10 +6191,10 @@ static size_t findRowIndex2(_In_ const double* table, size_t nRow, size_t nCol, size_t last, double x, double dx) { size_t i0 = 0; size_t i1 = nRow - 1; - if (isLess(x, dx, TABLE_COL0(last))) { + if (isLessOrEqualWNegativeSlope(x, dx, TABLE_COL0(last))) { i1 = last; } - else if (!isLess(x, dx, TABLE_COL0(last + 1))) { + else if (!isLessOrEqualWNegativeSlope(x, dx, TABLE_COL0(last + 1))) { i0 = last; } else { @@ -6204,7 +6204,7 @@ static size_t findRowIndex2(_In_ const double* table, size_t nRow, size_t nCol, /* Binary search */ while (i1 > i0 + 1) { const size_t i = (i0 + i1)/2; - if (isLess(x, dx, TABLE_COL0(i))) { + if (isLessOrEqualWNegativeSlope(x, dx, TABLE_COL0(i))) { i1 = i; } else { @@ -6223,10 +6223,10 @@ static size_t findColIndex2(_In_ const double* table, size_t nCol, size_t last, double x, double dx) { size_t i0 = 0; size_t i1 = nCol - 1; - if (isLess(x, dx, TABLE_ROW0(last))) { + if (isLessOrEqualWNegativeSlope(x, dx, TABLE_ROW0(last))) { i1 = last; } - else if (!isLess(x, dx, TABLE_ROW0(last + 1))) { + else if (!isLessOrEqualWNegativeSlope(x, dx, TABLE_ROW0(last + 1))) { i0 = last; } else { @@ -6236,7 +6236,7 @@ static size_t findColIndex2(_In_ const double* table, size_t nCol, size_t last, /* Binary search */ while (i1 > i0 + 1) { const size_t i = (i0 + i1)/2; - if (isLess(x, dx, TABLE_ROW0(i))) { + if (isLessOrEqualWNegativeSlope(x, dx, TABLE_ROW0(i))) { i1 = i; } else { @@ -6253,7 +6253,7 @@ static size_t findColIndex(_In_ const double* table, size_t nCol, size_t last, d /* ----- Internal check functions ----- */ -static int isLess(double x, double dx, double val) { +static int isLessOrEqualWNegativeSlope(double x, double dx, double val) { return x < val || (x == val && dx < 0); } From 14f3025069e50648c30dbf46897315862cfdc89a Mon Sep 17 00:00:00 2001 From: Thomas Beutlich Date: Tue, 15 Mar 2022 20:07:43 +0100 Subject: [PATCH 14/15] Bump copyright year --- Modelica/Resources/C-Sources/ModelicaStandardTables.c | 3 +-- .../Resources/Licenses/LICENSE_ModelicaStandardTables.txt | 2 +- ModelicaTest/Tables/CombiTable2Ds.mo | 4 ++-- ModelicaTest/Tables/CombiTable2Dv.mo | 4 ++-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Modelica/Resources/C-Sources/ModelicaStandardTables.c b/Modelica/Resources/C-Sources/ModelicaStandardTables.c index 4cdc6b3677..657755b30a 100644 --- a/Modelica/Resources/C-Sources/ModelicaStandardTables.c +++ b/Modelica/Resources/C-Sources/ModelicaStandardTables.c @@ -1,6 +1,6 @@ /* ModelicaStandardTables.c - External table functions - Copyright (C) 2013-2021, Modelica Association and contributors + Copyright (C) 2013-2022, Modelica Association and contributors All rights reserved. Redistribution and use in source and binary forms, with or without @@ -6250,7 +6250,6 @@ static size_t findColIndex(_In_ const double* table, size_t nCol, size_t last, d return findColIndex2(table, nCol, last, x, 0.0); } - /* ----- Internal check functions ----- */ static int isLessOrEqualWNegativeSlope(double x, double dx, double val) { diff --git a/Modelica/Resources/Licenses/LICENSE_ModelicaStandardTables.txt b/Modelica/Resources/Licenses/LICENSE_ModelicaStandardTables.txt index ce519b436d..75336a214a 100644 --- a/Modelica/Resources/Licenses/LICENSE_ModelicaStandardTables.txt +++ b/Modelica/Resources/Licenses/LICENSE_ModelicaStandardTables.txt @@ -1,4 +1,4 @@ -Copyright (C) 2013-2021, Modelica Association and contributors +Copyright (C) 2013-2022, Modelica Association and contributors All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/ModelicaTest/Tables/CombiTable2Ds.mo b/ModelicaTest/Tables/CombiTable2Ds.mo index ed9909b99a..043309a21d 100644 --- a/ModelicaTest/Tables/CombiTable2Ds.mo +++ b/ModelicaTest/Tables/CombiTable2Ds.mo @@ -1125,7 +1125,7 @@ double mydummyfunc(double dummy_in) { points={{-59,-10},{-52,-10},{-52,4},{-42,4}}, color={0,0,127})); annotation (experiment(StartTime=0, StopTime=14)); end Test33; - + model OneSidedDerivative2D "Test of one sided derivatives in 2D-tables (Ticket #3893)" // We are starting at boundaries of the table // Case 2 and 4 slide diagonally (from different corners) @@ -1182,7 +1182,7 @@ double mydummyfunc(double dummy_in) { annotation (Placement(transformation(extent={{-20,-80},{0,-60}}))); Modelica.Blocks.Continuous.Der der3 annotation (Placement(transformation(extent={{20,-80},{40,-60}}))); - equation + equation connect(combiTable2Ds2.y, der2.u) annotation (Line(points={{61,70},{78,70}}, color={0,0,127})); connect(ramp.y, combiTable2Ds2.u1) annotation (Line(points={{-59,50},{18,50},{ diff --git a/ModelicaTest/Tables/CombiTable2Dv.mo b/ModelicaTest/Tables/CombiTable2Dv.mo index 2152be0341..82b9255e6e 100644 --- a/ModelicaTest/Tables/CombiTable2Dv.mo +++ b/ModelicaTest/Tables/CombiTable2Dv.mo @@ -950,7 +950,7 @@ double mydummyfunc(double dummy_in) { points={{-59,-10},{-52,-10},{-52,4},{-42,4}}, color={0,0,127})); annotation (experiment(StartTime=0, StopTime=14)); end Test33; - + model OneSidedDerivative2D "Test of one sided derivatives in 2D-tables (Ticket #3893)" // We are starting at boundaries of the table // Case 2 and 4 slide diagonally (from different corners) @@ -1003,7 +1003,7 @@ double mydummyfunc(double dummy_in) { -70}))); Modelica.Blocks.Continuous.Der der3 annotation (Placement(transformation(extent={{-10,-10},{10,10}}, origin={30,-70}))); - equation + equation connect(combiTable2Dv.y[2], der2.u) annotation (Line(points={{44,40},{72,40},{72,30},{78,30}}, color={0,0,127})); From cb1842dc8135c17d16a46d6e84b926b3f2ccc707 Mon Sep 17 00:00:00 2001 From: Thomas Beutlich Date: Tue, 15 Mar 2022 20:47:43 +0100 Subject: [PATCH 15/15] Add missing cases --- .../C-Sources/ModelicaStandardTables.c | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Modelica/Resources/C-Sources/ModelicaStandardTables.c b/Modelica/Resources/C-Sources/ModelicaStandardTables.c index 657755b30a..7ab0fd8bc3 100644 --- a/Modelica/Resources/C-Sources/ModelicaStandardTables.c +++ b/Modelica/Resources/C-Sources/ModelicaStandardTables.c @@ -5181,11 +5181,11 @@ double ModelicaStandardTables_CombiTable2D_getDer2Value(void* _tableID, double u tableID->last2, u2, der_u2); tableID->last2 = last2; } - else if (u2 < u2Min) { + else if (isLessOrEqualWNegativeSlope(u2, der_u2, u2Min)) { extrapolate2 = LEFT; last2 = 0; } - else if (u2 > u2Max) { + else if (isLessOrEqualWNegativeSlope(u2Max, -der_u2, u2)) { extrapolate2 = RIGHT; last2 = nCol - 3; } @@ -5323,21 +5323,21 @@ double ModelicaStandardTables_CombiTable2D_getDer2Value(void* _tableID, double u u1 -= T; } while (u1 > u1Max); } - last1 = findRowIndex(&TABLE(1, 0), nRow - 1, nCol, - tableID->last1, u1); + last1 = findRowIndex2(&TABLE(1, 0), nRow - 1, nCol, + tableID->last1, u1, der_u1); tableID->last1 = last1; } - else if (u1 < u1Min) { + else if (isLessOrEqualWNegativeSlope(u1, der_u1, u1Min)) { extrapolate1 = LEFT; last1 = 0; } - else if (u1 > u1Max) { + else if (isLessOrEqualWNegativeSlope(u1Max, -der_u1, u1)) { extrapolate1 = RIGHT; last1 = nRow - 3; } else { - last1 = findRowIndex(&TABLE(1, 0), nRow - 1, nCol, - tableID->last1, u1); + last1 = findRowIndex2(&TABLE(1, 0), nRow - 1, nCol, + tableID->last1, u1, der_u1); tableID->last1 = last1; } if (nCol == 2) { @@ -5468,21 +5468,21 @@ double ModelicaStandardTables_CombiTable2D_getDer2Value(void* _tableID, double u u2 -= T; } while (u2 > u2Max); } - last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2); + last2 = findColIndex2(&TABLE(0, 1), nCol - 1, + tableID->last2, u2, der_u2); tableID->last2 = last2; } - else if (u2 < u2Min) { + else if (isLessOrEqualWNegativeSlope(u2, der_u2, u2Min)) { extrapolate2 = LEFT; last2 = 0; } - else if (u2 > u2Max) { + else if (isLessOrEqualWNegativeSlope(u2Max, -der_u2, u2)) { extrapolate2 = RIGHT; last2 = nCol - 3; } else { - last2 = findColIndex(&TABLE(0, 1), nCol - 1, - tableID->last2, u2); + last2 = findColIndex2(&TABLE(0, 1), nCol - 1, + tableID->last2, u2, der_u2); tableID->last2 = last2; }