如何覆盖默认方程?

时间:2012-04-30 08:45:46

标签: modelica

所有派生类都应该从其基类继承一些默认方程。如果默认等式对派生类无效,则应重新声明它。下面这个极简主义的例子有点傻。

我是否在正确的轨道上实现上述目标?或者有更好的方式用Modelica语言来表达它吗?

package Pkg

  partial class Equations
    Real x;
  end Equations;

  class DefaultEquations
    extends Equations;
    equation
      x = 0.0;
  end DefaultEquations;

  class Base
    replaceable class T = DefaultEquations;
    replaceable T equations extends Equations;
  end Base;

end Pkg;

model TestEquations

  import Pkg.*;

  class CustomEquation
    extends Equations;
    equation
      x = 3;
  end CustomEquation;

  class CustomizedClass
    extends Base(redeclare class T = CustomEquation);
  end CustomizedClass;

  CustomizedClass customized;

end TestEquations;

1 个答案:

答案 0 :(得分:3)

如果我理解你的目标,有一种非常简单的方法可以实现这一目标。考虑这个替代方案:

package Pkg
  partial class Equations
    Real x;
  end Equations;

  class DefaultEquations
    extends Equations(x=0);
  end DefaultEquations;

  class Base
    replaceable class T = DefaultEquations;
    replaceable T equations extends Equations;
  end Base;
end Pkg;

model TestEquations
  import Pkg.*;

  class CustomEquation
    extends Equations(x=3);
  end CustomEquation;

  class CustomizedClass
    extends Base(redeclare class T = CustomEquation);
  end CustomizedClass;

  CustomizedClass customized;
end TestEquations;

但是如果你愿意消除所有的重新声明,你可以进一步简化它:

package Pkg
  class Equations
    Real x;
  end Equations;

  class Base
    Equations equations;
  end Base;
end Pkg;

model TestEquations
  import Pkg.*;

  class CustomizedClass
    extends Base(equations(x=3));
  end CustomizedClass;

  CustomizedClass customized;
end TestEquations;

...如果你不需要所有的继承层,那么还要进一步:

package Pkg
  class Equations
    Real x;
  end Equations;
end Pkg;

model TestEquations
  import Pkg.*;

  Equations equations(x=3);
end TestEquations;

这些修改(x=3部分)对变量的作用与对参数的作用相同。因此,您可以为任何变量(变量声明后出现的部分)和覆盖采用“初始化方程式”。这种方法的局限性在于它不允许您覆盖一般方程式,只是明确求解单个变量的方程式。

更新(2012年5月2日)

如果你需要处理一般方程(包括引入内部状态的可能性),那么你还必须处理“平衡”方程的问题。也就是说,Modelica(v 3 +)包括关于被认为是部分(非可实例化)模型与非部分模型的某些语义。关键是,你需要给编译器足够的信息,说明内部计算的内容以及外部提供的内容,以便确定定义是否真的是部分的。

通常,您应该定义一个部分模型/块来描述潜在的外部交互,然后使用可替换组件来替换方程式。根据您的原始示例,它可能看起来像这样:

package Pkg
  partial block Equations
    input Real y; // Input for any information it will need in the calculation
    output Real x; // Output to indicate something the model will compute
  end Equations;

  block DefaultEquations
    extends Equations;
  equation
    x = 0;
  end DefaultEquations;

  class Base
    replaceable DefaultEquations equations constrainedby Equations;
  end Base;
end Pkg;

model TestEquations
  import Pkg.*;

  block CustomEquation
    extends Equations
  equation
    x*x + y*y = 25.0; // example of non explicit equation
  end CustomEquation;

  class CustomizedClass
    extends Base(redeclare CustomEquation equations);
  end CustomizedClass;

  CustomizedClass customized;
end TestEquations;

我应该补充一下(至少在上面的示例中),您可以完全消除BaseCustomizedClass。但是我让他们离开了因为我认为他们以某种方式映射到你的实际问题。最后,我从未在实际代码中使用class(我尝试更具体),因此我将一些定义更改为block定义。