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

时间:2019-02-15 22:03:35

标签: modelica openmodelica

我想实例化一个复杂模型作为另一个模型中的参数,并在初始方程部分中对其进行初始化,就像我可以对任何Real参数进行操作一样。对于一个简单的Real参数,我只写

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 ComplexModel 
  Real x(fixed = false);
  Real y(fixed = false);
equation
  y * y = x;
end ComplexModel;

并尝试以这种方式使用它:

  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编译器将参数实例的方程式转换为初始方程式?因为否则,就不可能隐式定义复杂模型的参数实例。

3 个答案:

答案 0 :(得分:2)

从Modelica Specification v3.4开始,这是无效的Modelica,因为前缀parameter不能与专门的类model一起使用。

有一些建议可以改善这种行为(并满足您的要求),请参见https://github.com/modelica/ModelicaSpecification/issues/2311及其来源https://github.com/modelica/ModelicaStandardLibrary/issues/1860

答案 1 :(得分:0)

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


我终于找到了部分解决方案。如果我在ComplexModelinitial equation部分中使用条件声明了equation,则可以使它正常工作。

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;

通过在模型RefactoredFlatModel中(根据问题)替换行

parameter ComplexModel mStatic;

通过

parameter ComplexModel mStatic (fixed = false);

最终的平面模型最终变为

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;

即我已经以一种可以从外部控制的方式,成功地将mStatic.y的等式处理到了initial equation部分。好处是,ComplexModel现在已完全封装,可以按照我的问题的要求分配为'attribute'fixed = false。

不好的是,我必须在y*y=x中两次编写基础方程ComplexModel。在更复杂的方程组的情况下,这可能是误差的来源。并且:我认为,如果有人为ComplexModel的非参数实例编写fixed=false,则会滥用语法(导致与时间相关的方程式消失,这与fixed = false对于原子数据类型的含义大不相同)。 / p>

我希望能够有一种语言功能来自动且一致地完成所有这些工作,但似乎没有。

答案 2 :(得分:0)

您在问题中建议的代码几乎可以正常工作。您只需要忽略mStatic的参数前缀,并在常规方程式部分中分配其变量即可。

mStatic.x = x

也可以在常规方程式部分的常规变量中分配参数。因此,您不需要模型mStatic的参数前缀。 但是,还必须在连续时间部分中定义mStatic的方程,因此我们必须将方程IF EXISTS(SELECT Id from Smline where Id =@id) BEGIN update dbo.SmLine Set [Payroll_Id]= @Payroll_Id ,ProductCode= @ProductCode ,Description = @Description ,Qty = @Qty WHERE Id = @Id END ELSE BEGIN INSERT INTO SmLine ([Payroll_Id],[ProductCode],[Description],[Qty]) VALUES (@Payroll_Id,@ProductCode ,@Description,@Qty) END 移到方程部分。