将模型实例化为参数时的固定属性
Fixed attribute when instantiating a model as parameter
我想将一个复杂模型实例化为另一个模型中的参数,并在初始方程部分对其进行初始化,就像我能够对任何 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编译器将方程式变成参数实例的初始方程式?因为否则无法隐式定义复杂模型的参数实例。
编辑 (2019-02-30): 不要使用这个 'solution'。根据 tbeu 的回答,它违反了语言标准。 OpenModelica 允许,但不应该。
我终于找到了部分解决方案。如果我通过在 initial equation
和 equation
部分中使用条件来声明 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;
通过在模型 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。
糟糕的是我必须在 ComplexModel
中写两次基本方程 y*y=x
。在更复杂的方程系统的情况下,这可能是错误的来源。并且:我认为如果有人为 ComplexModel 的非参数实例编写 fixed=false
语法可能会被滥用(导致时间相关方程消失,这与 fixed=false 对原子数据类型的含义完全不同)。
我多么希望有一种语言功能可以自动且一致地执行所有这些操作,但似乎没有。
从 Modelica 规范 v3.4 开始,这是无效的 Modelica,因为前缀 parameter
不能与专门的 class model
.
一起使用
有一些建议可以改进此行为(并满足您的要求),请参阅 https://github.com/modelica/ModelicaSpecification/issues/2311 and its source https://github.com/modelica/ModelicaStandardLibrary/issues/1860。
您在问题中建议的代码几乎可以工作。您只需要省略 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
移动到方程部分
我想将一个复杂模型实例化为另一个模型中的参数,并在初始方程部分对其进行初始化,就像我能够对任何 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编译器将方程式变成参数实例的初始方程式?因为否则无法隐式定义复杂模型的参数实例。
编辑 (2019-02-30): 不要使用这个 'solution'。根据 tbeu 的回答,它违反了语言标准。 OpenModelica 允许,但不应该。
我终于找到了部分解决方案。如果我通过在 initial equation
和 equation
部分中使用条件来声明 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;
通过在模型 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。
糟糕的是我必须在 ComplexModel
中写两次基本方程 y*y=x
。在更复杂的方程系统的情况下,这可能是错误的来源。并且:我认为如果有人为 ComplexModel 的非参数实例编写 fixed=false
语法可能会被滥用(导致时间相关方程消失,这与 fixed=false 对原子数据类型的含义完全不同)。
我多么希望有一种语言功能可以自动且一致地执行所有这些操作,但似乎没有。
从 Modelica 规范 v3.4 开始,这是无效的 Modelica,因为前缀 parameter
不能与专门的 class model
.
有一些建议可以改进此行为(并满足您的要求),请参阅 https://github.com/modelica/ModelicaSpecification/issues/2311 and its source https://github.com/modelica/ModelicaStandardLibrary/issues/1860。
您在问题中建议的代码几乎可以工作。您只需要省略 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
移动到方程部分