我正在运行OpenModelica并尝试使用Modelica从简介到物理建模运行示例。我已将示例9.1 - 9.4复制到一个包中。该文件现在看起来像这样:
package gravityPackage
//Test of gravity taken from Intro to Physical modeling with Modelica
//
//
//
//
//
model ParticleField
inner function gravity = TwoBodyField;
Particle p1(x_init = {2,-2,0}, v_init = {0.7,0,0});
Particle p2(x_init = {0,0.5,0}, v_init = {-1,-1,0});
Particle p3(x_init = {0.5,2,0}, v_init = {-1,-0.5,0});
end ParticleField;
function TwoBodyField
extends GravityField;
protected
Modelica.SIunits.Position b1[3],b2[3];
Modelica.SIunits.Velocity n1[3],n2[3];
algorithm
b1:={0,0,0};
b2:={0,1,0};
n1:=-(x - b1) / sqrt((x - b1) * (x - b1));
n2:=-(x - b2) / sqrt((x - b2) * (x - b2));
g:=n1 / ((x - b1) * (x - b1)) + n2 / ((x - b2) * (x - b2));
end TwoBodyField;
partial function GravityField
input Modelica.SIunits.Position x[3];
output Modelica.SIunits.Acceleration g[3];
end GravityField;
model Particle
parameter Modelica.SIunits.Position x_init[3];
parameter Modelica.SIunits.Velocity v_init[3];
protected
outer function gravity = GravityField;
//outer function gravity=ParticleField;
//outer function gravity=TwoBodyField;
Modelica.SIunits.Position x[3](start = x_init);
Modelica.SIunits.Velocity v[3](start = v_init);
Modelica.SIunits.Acceleration a[3];
equation
v = der(x);
a = der(v);
a = gravity(x);
end Particle;
end gravityPackage;
但是,如果我去OMShell尝试运行它,我会得到这个:
>> loadFile("gravityPackage.mo")
true
>> simulate(gravityPackage.ParticleField)
record SimulationResult
resultFile = "",
simulationOptions = "startTime = 0.0, stopTime = 1.0, numberOfIntervals = 500, tolerance = 0.000001, method = 'dassl', fileNamePrefix = 'gravityPackage.ParticleField', options = '', outputFormat = 'mat', variableFilter = '.*', measureTime = false, cflags = '', simflags = ''",
messages = "Simulation failed for model: gravityPackage.ParticleField
[gravityPackage.mo:34:11-34:42:writable] Warning: No corresponding 'inner' declaration found for class gravity declared as 'outer '.
Continuing flattening by only considering the 'outer' class declaration.
[gravityPackage.mo:43:5-43:19:writable] Error: Failed to instantiate equation
a = gravity(x);.
Error: Error occurred while flattening model gravityPackage.ParticleField
",
timeFrontend = 0.0,
timeBackend = 0.0,
timeSimCode = 0.0,
timeTemplates = 0.0,
timeCompile = 0.0,
timeSimulation = 0.0,
timeTotal = 0.0
end SimulationResult;
>>
所以,显然有一些与范围相关的东西我没有得到正确的答案。除了包之外,所有代码都只是直接从本书中复制而来。我认为必须将软件包放入一个文件中(尽管我尝试了其他几种方法但没有成功)。 任何建议表示赞赏。
谢谢,
答案 0 :(得分:1)
好的,所以我认为这里的问题是你试图使用动态范围(即inner
和outer
)在实例树中“传递”一个函数。我没有读过关于这个特定点的规范,但我认为这不会起作用。原因是通常inner
和outer
与实例化的事物(变量,模型等)一起使用。
因此要理解的是,概念上,constant
变量和function
定义都没有实例化。能够将function
视为一个实例(一等值)会产生一些有用的结果,但它也会引入一些语义复杂性。在最近的语言版本中已经开始尝试将功能视为一等公民。主要用例是将函数作为参数传递给其他函数。但我认为这些新语义不能使函数成为真正的第一类值(正如您的示例所示)。但是,这可能与OpenModelica有关。我不能肯定地说。
你可以解决这个问题的一种方法是使用可替换和重新声明。因此,在Particle
模型中,定义gravity
,如下所示:
public
replaceable function gravity = GravityField;
然后,按如下方式实例化:
model ParticleField
Particle p1(x_init = {2,-2,0}, v_init = {0.7,0,0}, redeclare function gravity = TwoBodyField);
Particle p2(x_init = {0,0.5,0}, v_init = {-1,-1,0}, redeclare function gravity = TwoBodyField);
Particle p3(x_init = {0.5,2,0}, v_init = {-1,-0.5,0}, redeclare function gravity = TwoBodyField);
end ParticleField;
注意,我还没有测试过这个解决方案。例如,您的Particle
模型可能需要partial
限定符(因为您必须将gravity
覆盖为非partial
实现。)
我希望有所帮助。
答案 1 :(得分:1)
这是OpenModelica中的一个错误。 如果是内部组件或类而不是函数,它应该可以正常工作。
我添加了一个关于它的错误报告,我们将修复它: https://trac.openmodelica.org/OpenModelica/ticket/2467
现在你可以使用内部/外部包,它应该可以正常工作。
package gravityPackage
package Functions
function TwoBodyField
extends GravityField;
protected
Modelica.SIunits.Position b1[3],b2[3];
Modelica.SIunits.Velocity n1[3],n2[3];
algorithm
b1:={0,0,0};
b2:={0,1,0};
n1:=-(x - b1) / sqrt((x - b1) * (x - b1));
n2:=-(x - b2) / sqrt((x - b2) * (x - b2));
g:=n1 / ((x - b1) * (x - b1)) + n2 / ((x - b2) * (x - b2));
end TwoBodyField;
partial function GravityField
input Modelica.SIunits.Position x[3];
output Modelica.SIunits.Acceleration g[3];
end GravityField;
end Functions;
model ParticleField
inner package funcs = Functions;
Particle p1(x_init = {2,-2,0}, v_init = {0.7,0,0});
Particle p2(x_init = {0,0.5,0}, v_init = {-1,-1,0});
Particle p3(x_init = {0.5,2,0}, v_init = {-1,-0.5,0});
end ParticleField;
model Particle
parameter Modelica.SIunits.Position x_init[3];
parameter Modelica.SIunits.Velocity v_init[3];
protected
outer package funcs = Functions;
function gravity = funcs.TwoBodyField;
//outer function gravity=ParticleField;
//outer function gravity=TwoBodyField;
Modelica.SIunits.Position x[3](start = x_init);
Modelica.SIunits.Velocity v[3](start = v_init);
Modelica.SIunits.Acceleration a[3];
equation
v = der(x);
a = der(v);
a = gravity(x);
end Particle;
end gravityPackage;