传值¶
在建立子系统模型时,子系统很经常会包含一些会传递到其自身部件的参数。例如,考虑我们在对基本旋转组件的讨论中使用的以下系统模型:
within ModelicaByExample.Components.Rotational.Examples;
model SMD
Components.Damper damper2(d=1);
Components.Ground ground;
Components.Spring spring2(c=5);
Components.Inertia inertia2(J=1,
phi(fixed=true, start=1),
w(fixed=true, start=0));
Components.Damper damper1(d=0.2);
Components.Spring spring1(c=11);
Components.Inertia inertia1(
J=0.4,
phi(fixed=true, start=0),
w(fixed=true, start=0));
equation
// ...
end SMD;
有时候,我们会想在不同的上下文中使用这个模型,并改变一些部件参数的值,例如d
。我们可以让d
成为子系统级别的参数,然后利用修改语句将值通过层次结构传递。结果应是如此:
within ModelicaByExample.Components.Rotational.Examples;
model SMD
import Modelica.SIunits.*;
parameter RotationalDampingConstant d;
Components.Damper damper2(d=d);
// ...
这里有一个问题。用户可能会去下层改变damper2.d
的值,而不在SMD
模型修改d
参数。要避免d
参数和damper2.d
参数的不同步(具有不同的值),我们可以使用final
限定词将其永久绑定起来:
within ModelicaByExample.Components.Rotational.Examples;
model SMD
import Modelica.SIunits.*;
parameter RotationalDampingConstant d;
Components.Damper damper2(final d=d);
// ...
通过添加final
限定词,我们表明参数damper2.d
的值不可以再修改。任何修改必须指向d
。
用相同方式代替在SMD
模型里所有在代码里固定的数值,如下模型会得到很高的可重用性:
within ModelicaByExample.Components.Rotational.Examples;
model SMD
import Modelica.SIunits.*;
parameter RotationalDampingConstant d1, d2;
parameter RotationalSpringConstant c1, c2;
parameter Inertia J1, J2;
parameter Angle phi1_init=0, phi2_init=0;
parameter AngularVelocity w1_init=0, w2_init=0;
Components.Damper damper2(final d=d2);
Components.Ground ground;
Components.Spring spring2(final c=c2);
Components.Inertia inertia2(
final J=J2,
phi(fixed=true, final start=phi2_init),
w(fixed=true, final start=w2_init));
Components.Damper damper1(final d=d1);
Components.Spring spring1(final c=c1);
Components.Inertia inertia1(
final J=J1,
phi(fixed=true, final start=phi1_init),
w(fixed=true, final start=w1_init));
equation
// ...
end SMD;
如果我们想用某组特定的参数值,有两种可行的方法。一种方法是扩展上述的参数化模型,并在extends
声明包括修改语句,如:
model SpecificSMD
extends SMD(d2=1, c2=5, J2=1,
d1=0.5, c1=11, J1=0.4,
phi1_init=1);
需要注意的是,我们并不需要为phi2_init
、w1_init
、w2_init
添加修改语句,因为这些参数在声明都带有默认值。一般情况下,只有在参数的默认值适用于绝大部分情况时,才应该设定。这样做的原因在于如果参数没有默认值,大多数的Modelica编译器会生成警告,以提醒你必须进行赋值。但是,如果存在默认值,编译器会默默地使用默认值。如果默认值不合理或不典型,那么你会默默地在模型里引入一个不合理的值。
另一方面,我们回到关于传值的主题。另一个可用的方法将是实例化SMD
模型,并在声明的变量使用修改语句去指定参数值,如:
SMD mysmd(d2=1, c2=5, J2=1,
d1=0.5, c1=11, J1=0.4,
phi1_init=1);
在下章架构模型之前,我们暂时不会讨论哪种方法更好。