Modelica 将模型实例化为参数时的固定属性

Modelica 将模型实例化为参数时的固定属性,modelica,openmodelica,Modelica,Openmodelica,我想将一个复杂模型实例化为另一个模型中的参数,并在初始方程部分对其进行初始化,就像我能够处理任何实际参数一样。对于一个简单的实数参数,我只写 parameter Real y(fixed = true); 表示应在初始化时使用初始方程(待定义…)计算y。但我不能对一个复杂的模型,也就是 parameter ComplexModel m(fixed = true); 不编译。例如,考虑下面的扁平模型 model FlatModel parameter Real x = 4; param

我想将一个复杂模型实例化为另一个模型中的参数,并在初始方程部分对其进行初始化,就像我能够处理任何实际参数一样。对于一个简单的实数参数,我只写

parameter Real y(fixed = true);
表示应在初始化时使用初始方程(待定义…)计算
y
。但我不能对一个复杂的模型,也就是

parameter ComplexModel m(fixed = true);
不编译。例如,考虑下面的扁平模型

model FlatModel
  parameter Real x = 4;
  parameter Real y(fixed = false);
  Real z;
  // ... + many other model elements
initial equation
  y*y = x;
  // ... + many other equations
equation
  z*z = 4*x;
end FlatModel;
这里,隐式解y=2是在初始化时计算的,而解z=4是以时间相关的方式计算的(至少在原则上,尽管存在可能的优化…)。但两者基本上代表相同的二次关系,所以我想将这个方程封装到一个单独的模型中(注意,并不是每个这样的方程系统都像本例中那样简单):

试着这样使用它:

  model RefactoredFlatModel
    parameter Real x = 4;
    parameter Real y(fixed = false);
    Real z;
    parameter ComplexModel mStatic;
    ComplexModel mDynamic;
  initial equation
    mStatic.x = x;
    y = mStatic.y;
  equation
    mDynamic.x = 4*x;
    z = mDynamic.y;
  end RefactoredFlatModel;
但这似乎不起作用(编译器报告过度终止系统)。检查被编译器展平的模型可以说明原因:

class FixedTests.RefactoredFlatModel
  parameter Real x = 4.0;
  parameter Real y(fixed = false);
  Real z;
  parameter Real mStatic.x(fixed = false);
  parameter Real mStatic.y(fixed = false);
  Real mDynamic.x(fixed = false);
  Real mDynamic.y(fixed = false);
initial equation
  mStatic.x = x;
  y = mStatic.y;
equation
  mStatic.y ^ 2.0 = mStatic.x;
  mDynamic.y ^ 2.0 = mDynamic.x;
  mDynamic.x = 4.0 * x;
  z = mDynamic.y;
end FixedTests.RefactoredFlatModel;
所以
mStatic.y^2.0=mStatic.x
被放在(时间相关的)方程部分,而不是我想要的初始方程部分。很明显,该模型是过度确定的,因为它试图在时间上求解mStatic.y,尽管mStatic.y是一个参数,因此是时不变的

有没有办法告诉modelica编译器将方程转换为参数实例的初始方程?因为否则无法隐式定义复杂模型的参数实例。

编辑(2019-02-30):不要使用此“解决方案”。根据tbeu的回答,它违反了语言标准。OpenModelica允许,但不应该


我终于找到了部分解决办法。如果我通过使用
初始方程
方程
部分中的条件来声明
ComplexModel
,我可以以某种方式使它工作

model ComplexModel
  parameter Boolean fixed = true;
  Real x(fixed = false);
  Real y(fixed = false);
initial equation
  if not fixed then
    y * y = x;
  end if;
equation
  if fixed then
    y * y = x;
  end if;
end ComplexModel;
通过在model
RefacturedFlatModel
(来自问题)中替换行

最终生成的平面模型成为

class AdvancedMultiBody.FixedTests.RefactoredFlatModel
  parameter Real x = 4.0;
  parameter Real y(fixed = false);
  Real z;
  parameter Boolean mStatic.fixed = false;
  parameter Real mStatic.x(fixed = false);
  parameter Real mStatic.y(fixed = false);
  parameter Boolean mDynamic.fixed = true;
  Real mDynamic.x(fixed = false);
  Real mDynamic.y(fixed = false);
initial equation
  mStatic.y ^ 2.0 = mStatic.x;
  mStatic.x = x;
  y = mStatic.y;
equation
  mDynamic.y ^ 2.0 = mDynamic.x;
  mDynamic.x = 4.0 * x;
  z = mDynamic.y;
end AdvancedMultiBody.FixedTests.RefactoredFlatModel;
i、 e.我已经成功地将
mStatic.y
的方程变戏法到
初始方程
部分,并且可以从外部进行控制。好的方面是ComplexModel现在已经完全封装,并且可以按照我的问题中的要求指定'attribute'fixed=false

糟糕的是,我必须在
ComplexModel
中编写两次基本方程
y*y=x
。对于更复杂的方程系统,这可能是一个误差源。而且:我认为,如果有人为ComplexModel的非参数实例编写
fixed=false
(导致时间相关方程消失,这与fixed=false对于原子数据类型的含义大不相同),语法可能会被滥用


不知何故,我希望有一种语言功能能够自动且一致地完成所有这些,但似乎没有。

从Modelica规范v3.4开始,这是无效的Modelica,因为前缀
参数
不能与专用类
model
一起使用


有一些建议可以改进此行为(并满足您的要求),请参阅及其来源。

您在问题中建议的代码几乎可以正常工作。您只需省去mStatic的参数前缀,并在正则表达式部分指定其变量

model RefactoredFlatModel
  parameter Real x=4;
  parameter Real y(fixed=false);
  Real z;
  ComplexModel mStatic;
  ComplexModel mDynamic;
initial equation 
  y = mStatic.y;
equation 
  // The assignment is needed to have enough equations, even though its static
  mStatic.x = x;

  mDynamic.x = 4*x;
  z = mDynamic.y;
end RefactoredFlatModel;
参数也可以从正则变量在初始方程部分赋值。因此,您不需要模型mStatic的参数前缀。
但是,mStatic的方程也必须在连续时间段中定义,因此我们必须将方程
mStatic.x=x
移动到方程段。

您是说,将模型作为参数进行稳定通常是非法的(不管某些假设属性“固定”)?然后,我发现OpenModelica(可以说是参考实现)允许它是相当令人困惑的。如果您允许我有一点抱怨:很难理解,为什么您可以在flat modelica中完美地表达一个非常基本的概念(解一个静态方程组)(非线性静态解的存在性和唯一性是一个问题,但在flat modelica中也是如此),但您不能在那里使用面向对象。这就像Modelica只向面向对象走了一半。是的,这是非法的Modelica,OpenModelica应该拒绝它。在变量上使用参数前缀的目的是使用户界面能够在参数化对话框中显示变量。当使用purel时对于文本模型来说,这似乎无关紧要,但对我来说很重要。我不确定你的建议是否能解决这一问题……那么你想在gui中显示ComplexModel mStatic吗?你可以通过添加
注释(对话框)
来激发这一点(但在OpenModelica中,它没有多大用处,因为它只显示一个文本框。在Dymola中,您可以获得一个子菜单来设置其所有参数)。或者您只是想将参数传递给mStatic?您可以一如既往地这样做。
model RefactoredFlatModel
  parameter Real x=4;
  parameter Real y(fixed=false);
  Real z;
  ComplexModel mStatic;
  ComplexModel mDynamic;
initial equation 
  y = mStatic.y;
equation 
  // The assignment is needed to have enough equations, even though its static
  mStatic.x = x;

  mDynamic.x = 4*x;
  z = mDynamic.y;
end RefactoredFlatModel;
class AdvancedMultiBody.FixedTests.RefactoredFlatModel
  parameter Real x = 4.0;
  parameter Real y(fixed = false);
  Real z;
  parameter Boolean mStatic.fixed = false;
  parameter Real mStatic.x(fixed = false);
  parameter Real mStatic.y(fixed = false);
  parameter Boolean mDynamic.fixed = true;
  Real mDynamic.x(fixed = false);
  Real mDynamic.y(fixed = false);
initial equation
  mStatic.y ^ 2.0 = mStatic.x;
  mStatic.x = x;
  y = mStatic.y;
equation
  mDynamic.y ^ 2.0 = mDynamic.x;
  mDynamic.x = 4.0 * x;
  z = mDynamic.y;
end AdvancedMultiBody.FixedTests.RefactoredFlatModel;
model RefactoredFlatModel
  parameter Real x=4;
  parameter Real y(fixed=false);
  Real z;
  ComplexModel mStatic;
  ComplexModel mDynamic;
initial equation 
  y = mStatic.y;
equation 
  // The assignment is needed to have enough equations, even though its static
  mStatic.x = x;

  mDynamic.x = 4*x;
  z = mDynamic.y;
end RefactoredFlatModel;