我想实例化一个复杂模型作为另一个模型中的参数,并在初始方程部分中对其进行初始化,就像我可以对任何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编译器将参数实例的方程式转换为初始方程式?因为否则,就不可能隐式定义复杂模型的参数实例。
答案 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允许,但不允许。
我终于找到了部分解决方案。如果我在ComplexModel
和initial 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
移到方程部分。