OpenModelica- 책 예제를 실행하려고하지만 내부 우터 문제가 있습니다.

StackOverflow https://stackoverflow.com/questions/19841314

  •  29-07-2022
  •  | 
  •  

문제

나는 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;

>> 

따라서 분명히 제가 정확하지 않은 범위와 관련된 것이 있습니다. 패키지를 제외한 모든 코드는 책에서 직접 복사됩니다. 패키지가 단일 파일로 가져 오려면 패키지가 필요하다고 생각합니다 (성공하지 못한 상태에서 몇 가지 다른 방법을 시도했지만). 모든 제안에 감사드립니다.

감사,

도움이 되었습니까?

해결책

이것은 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;

다른 팁

자, 여기서 문제는 동적 범위를 사용하여 인스턴스 트리를 "전달"하려고한다는 것입니다. 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 구현).

도움이되기를 바랍니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top