使用 openmodelica 进行插值的函数
Function to Interpolate using openmodelica
我有一些从 matlab 中提取的数据,我希望它们可以在 openmodelica 中访问。
数据采用 x,y 和值 z 的 table 形式。我想创建一个函数来从 x 和 y 中重现点 z,其中该函数还可以很好地在 x 和 y 之间进行插值。所以基本上,Modelica 插值必须加载 table 结果并进行插值。这可能吗 ?谁能带我上路?
提前感谢您的帮助。
我在这封邮件中附上了我的数据,第一行和第一列分别对应于 x 和 y 值。
这是数据的 3D 散点图和拟合到它的 3D 多项式曲面。因为数据具有相当大的表面曲率,所以我找不到用于插值的简单近似方程。在这里,我使用了具有三阶项的曲面多项式,这在数据范围外的推断效果不佳。因此,我建议仅将其用于插值。
# 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
您需要根据https://doc.modelica.org/Modelica%203.2.3/Resources/helpOM/Modelica.Blocks.Tables.CombiTable2D.html, i.e., do not leave the element at position (0,0) empty. See https://gist.github.com/tbeu/2004db0f7753e69f42da39aec3a00b3d修改数据文件才能修复。
然后,您可以使用 MSL v3.2.3 加载和插入数据,例如
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;
你可以使用普通的external table object, if you prefer the direct interface via function getTable2DValue。例如,
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;
我有一些从 matlab 中提取的数据,我希望它们可以在 openmodelica 中访问。 数据采用 x,y 和值 z 的 table 形式。我想创建一个函数来从 x 和 y 中重现点 z,其中该函数还可以很好地在 x 和 y 之间进行插值。所以基本上,Modelica 插值必须加载 table 结果并进行插值。这可能吗 ?谁能带我上路? 提前感谢您的帮助。
我在这封邮件中附上了我的数据,第一行和第一列分别对应于 x 和 y 值。
这是数据的 3D 散点图和拟合到它的 3D 多项式曲面。因为数据具有相当大的表面曲率,所以我找不到用于插值的简单近似方程。在这里,我使用了具有三阶项的曲面多项式,这在数据范围外的推断效果不佳。因此,我建议仅将其用于插值。
# 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
您需要根据https://doc.modelica.org/Modelica%203.2.3/Resources/helpOM/Modelica.Blocks.Tables.CombiTable2D.html, i.e., do not leave the element at position (0,0) empty. See https://gist.github.com/tbeu/2004db0f7753e69f42da39aec3a00b3d修改数据文件才能修复。
然后,您可以使用 MSL v3.2.3 加载和插入数据,例如
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;
你可以使用普通的external table object, if you prefer the direct interface via function getTable2DValue。例如,
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;