简体   繁体   中英

Function to Interpolate using openmodelica

I have some data extracted from matlab which i want them to be accessible in openmodelica. The data are in the form of table of x,y and the value z. I want to create a function the reproduce the point z out of x and y, in which the function can also interpolates nicely between x and y. So basically the Modelica interpolation will have to load the table of results and do the interpolation. Is this possible? can anyone lead me to the way? thanks for the help in advance.

I attached my data with this message, the first row and the first column corresponds to the x and y values respectively.

https://www.dropbox.com/s/75z2ejcjru8hiu8/data.zip?dl=0

You need to adapt the data file according to https://doc.modelica.org/Modelica%203.2.3/Resources/helpOM/Modelica.Blocks.Tables.CombiTable2D.html , ie, do not leave the element at position (0,0) empty. See https://gist.github.com/tbeu/2004db0f7753e69f42da39aec3a00b3d for the fix.

Then, you can load and interpolate the data using MSL v3.2.3, for example

model Model
  Modelica.Blocks.Tables.CombiTable2D combiTable2D(
    tableOnFile=true,
    tableName="A'_Coefficient",
    fileName="c:\\temp\\data.txt") annotation(Placement(transformation(extent={{-95,60},{-75,80}})));
  Modelica.Blocks.Sources.RealExpression realExpression1(y=time*10) annotation(Placement(transformation(extent={{-140,65},{-120,85}})));
  Modelica.Blocks.Sources.RealExpression realExpression2(y=time*100) annotation(Placement(transformation(extent={{-140,40},{-120,60}})));
  equation
    connect(realExpression1.y,combiTable2D.u1) annotation(Line(points={{-119,75},{-114,75},{-102,75},{-102,76},{-97,76}}, color={0,0,127}));
    connect(realExpression2.y,combiTable2D.u2) annotation(Line(points={{-119,50},{-114,50},{-102,50},{-102,64},{-97,64}}, color={0,0,127}));
  annotation(uses(Modelica(version="3.2.3")));
end Model;

Here is a 3D scatterplot of your data and a 3D polynomial surface fitted to it. Because the data has considerable surface curvature I could not find a simple approximating equation for the interpolation. Here I have used a surface polynomial with 3rd order terms, and this should extrapolate poorly outside the data bounds. For this reason I recommend using it for interpolation only.

分散

表面

# taken from source code output of fitting software
a = -4.8044356996540731E+00
b = -1.7238982381056298E+00
c = 9.7121730188860766E+00
d = 2.0725836239688458E-02
f = -2.3810662793461059E+00
g = -6.8495593999129412E-05
h = 1.7294254445305737E-01
i = 2.6034147965619335E-02
j = -8.6126736653591163E-04
k = 5.8779369562417683E-05

z = a
z += b * x
z += c * y
z += d * pow(x, 2.0)
z += f * pow(y, 2.0)
z += g * pow(x, 3.0)
z += h* pow(y, 3.0)
z += i * x * y
z += j * pow(x, 2.0) * y
z += k * x * pow(y, 2.0)
return z

You can use the plain external table object , if you prefer the direct interface via function getTable2DValue . For example,

model Model2
  parameter Modelica.Blocks.Types.ExternalCombiTable2D tableID=Modelica.Blocks.Types.ExternalCombiTable2D(
    "A'_Coefficient",
    "c:\\temp\\data.txt",
    fill(0.0, 0, 2),
    Modelica.Blocks.Types.Smoothness.LinearSegments) "External table object";
  parameter Real x=3 "First coordinate";
  parameter Real y=12 "Second coordinate";
  Real z "Interpolated value at (x,y)";
  equation
    z = Modelica.Blocks.Tables.Internal.getTable2DValue(tableID, x, y);
  annotation(uses(Modelica(version="3.2.3")));
end Model2;

function TestBend

input Real angle;
input Real radius;
output Real coefficient_a;
output Real  coefficient_b;

 Modelica.Blocks.Tables.CombiTable2D A_Coefficient(fileName = "C:\Users\AWH7RNG\Desktop\a_data.txt", smoothness = Modelica.Blocks.Types.Smoothness.ContinuousDerivative, tableName = "A'_Coefficient", tableOnFile = true)  annotation(
Placement(visible = true, transformation(origin = {-10, 54}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));


  Modelica.Blocks.Sources.RealExpression Radius_A(y = radius)  annotation(
Placement(visible = true, transformation(origin = {-62, 64}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
Modelica.Blocks.Sources.RealExpression Angle_A(y = angle)  annotation(
Placement(visible = true, transformation(origin = {-62, 32}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
 Modelica.Blocks.Tables.CombiTable2D B_Coefficient(fileName = "C:\Users\AWH7RNG\Desktop\b_data.txt", tableName = "B_Coefficient")  annotation(
Placement(visible = true, transformation(origin = {4, -20}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
 Modelica.Blocks.Sources.RealExpression Radius_B(y = radius)  annotation(
Placement(visible = true, transformation(origin = {-56, -8}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
 Modelica.Blocks.Sources.RealExpression Angle_B(y = angle)  annotation(
Placement(visible = true, transformation(origin = {-56, -32}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
algorithm
radius := Radius_B.y;
angle :=  Angle_A.y ;
angle := Angle_B.y;
radius := Radius_A.y;
coefficient_a := A_Coefficient.y;
coefficient_b := B_Coefficient.y;
equation
connect(Angle_B.y, B_Coefficient.u2) annotation(
Line(points = {{-44, -32}, {-24, -32}, {-24, -26}, {-8, -26}, {-8, -26}}, color = {0, 0, 127}));
connect(Radius_B.y, B_Coefficient.u1) annotation(
Line(points = {{-44, -8}, {-22, -8}, {-22, -14}, {-8, -14}, {-8, -14}}, color = {0, 0, 127}));
 connect(Angle_A.y, A_Coefficient.u2) annotation(
Line(points = {{-51, 32}, {-37, 32}, {-37, 48}, {-21, 48}, {-21, 48}, {-23, 48}, {-23, 48}}, color = {0, 0, 127}));
 connect(Radius_A.y, A_Coefficient.u1) annotation(
Line(points = {{-51, 64}, {-35, 64}, {-35, 60}, {-21, 60}, {-21, 60}, {-23, 60}, {-23, 60}}, color = {0, 0, 127}));
annotation(
uses(Modelica(version = "3.2.3")));


end TestBend;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM