组件数组

本章中有数个示例使用了组件数组。组件数组在某些情况下很有用。例如,当用户可能希望使用参数来“扩展”所使用部件的数量(正如我们在空间分布的传热以及钟摆的间谐运动的讨论里看到的一样)。

创建组件数组和我们前面在向量与数组一节里讨论的标量数组创建实在没有任何不同。正如我们在这个例子中看到,

  HTC.HeatCapacitor capacitance[n](each final C=C/n, each T(start=T0, fixed=true))
    annotation (Placement(transformation(
        extent={{-10,-10},{10,10}},
        origin={-30,20})));
  HTC.ThermalConductor wall[n](each final G=G_wall/n)
    annotation (Placement(transformation(
        extent={{-10,-10},{10,10}},
        rotation=90, origin={-30,-20})));
  HTC.ThermalConductor rod_conduction[n-1](each final G=G_rod)
    annotation (Placement(transformation(extent={{-10,-10},{10,10}})));

创建组件数组的语法和用于其它类型的语法相同。要做的仅仅是声明的变量名称后加上维度。

然而,和标量不同,部件内会有其他声明。因此,在创建分量的数组时,数组中每个组件的结构都会被复制。Modelica要求数组中的每一个元素都必须为相同的类型。这似乎是显而易见的。但这一定程度上是因为我们还没有讨论过replaceable部件。我们会了解更多关于replaceable组件在下一章当我们谈论的Modelica的配置管理特性。不过现在,我们只会简单地指出,只redeclare数组中的一个元素是不可能的。

正如在钟摆的间谐运动讨论里简要地谈到的一样,我们在对组件数组进行修改语句的时候,该组件中每个变量均被隐式地视为一个数组。举个例子,考虑下面的record定义:

record Point
  Real x;
  Real y;
  Real z;
end Point;

假设我们声明Point组件的数组,如Point p[5]。那么,任何对p.x的引用都会被视为有5个Real变量的数组,即p[1].xp[2].xp[3].xp[4].x以及p[5].x。这就是所谓的切片。最重要的一点是,如果我们省略下标(如p.x),那么下标就对应所有的元素(在技术上说,下标维持在“未限定”状态。而随后则可以“限定”下标)。此外,如果提供的下标为一个范围(例如1:end2:3),那么表达式则会解析为对应于该范围内所有索引的数组子集。上述内容对于含有组件数组的组件数组也一样成立。

下面的例子,说明了一些比较常见的情况:

record Vector3D
  Real x[3];
end Vector3D;

model ArrayExample
  Point p[2];
  Point q[2,3];
  Vector3D v[4];
equation
  p.x = {1, 2}; // p[1].x = 1, p[2].x = 2
  q[:,3].y = {4, 5}; // q[1,3].y = 4, q[2, 3].y = 5;
  q.x = [1, 2, 3; 4, 5, 6] // q[1,1].x = 1,
                           // q[1,2].x = 2,
                           // q[2,3].x = 6
  v.x[1] = {1, 2, 3, 4}; // v[1].x[1] = 1, v[2].x[1] = 2,
                         // v[3].x[1] = 3, v[4].x[1] = 4
  v[:].x[1] = {1, 2, 3, 4}; // v[1].x[1] = 1, v[2].x[1] = 2,
                            // v[3].x[1] = 3, v[4].x[1] = 4
  v[2:3].x[1] = {2, 3}; // v[2].x[1] = 2, v[3].x[1] = 3
  v[1].x = {1, 2, 3};   // v[1].x[1] = 1, v[1].x[2] = 2,
                        // v[1].x[3] = 3
end ArrayExample;