1、数据模型
设计基于三个类别:
vtkPartitionedDataSet是数据集的集合(不要与vtkDataSet混淆)。
vtkPartitionedDataSetCollection是vtkPaartitionedDataSet的集合。
vtkDataAssembly定义vtkPartitionedDataSetCollection中项之间的层次关系。
1.1、分区数据集
vtkPartitionedDataSet 仅仅是一个被视为逻辑整体的多个数据集的集合。在数据并行应用程序中,每个数据集可能代表当前工作进程、等级或线程上整个数据集的分区。vtkPartitionedDataSet 中的每个数据集被称为分区,意味着它只是整体的一部分。
所有非空分区具有相似的场和属性数组。例如,如果 vtkPartitionedDataSet 包含 vtkDataSet 子类,它们将具有完全相同数量的点数据/单元数据数组,具有相同的名称、相同数量的组件和相同的数据类型。
1.2、分区数据集集合
vtkPartitionedDataSetCollection 是 vtkPartitionedDataSet 的集合。因此,它仅仅是将多个 vtkPartitionedDataSet 实例组合在一起的机制。由于每个 vtkPartitionedDataSet 代表整个数据集(不要与 vtkDataSet 混淆),我们可以将 vtkPartitionedDataSetCollection 中的每个项目称为分区数据集。
与 vtkPartitionedDataSet 中的项目不同,vtkPartitionedDataSetCollection 中的每个项目(分区数据集)之间没有一致性限制。因此,在多块数据集的术语中,可以将此集合中的每个项目视为一个块。
1.3、数据组合
vtkDataAssembly 是一种定义 vtkPartitionedDataSetCollection 中项目的层次组织的方法。这实际上是由命名节点组成的树。树中的每个节点可以有相关的 dataset-indices。对于与 vtkPartitionedDataSetCollection 相关联的 vtkDataAssembly,每个 dataset-index 都是 vtkPartitionedDataSetCollection 中 partitioned-dataset 的索引。 dataset-index 可以与组装中的多个节点相关联,但是 dataset-index 不能与同一节点关联多次。
组装提供了定义原始数据块更复杂视图的能力,以更特定于应用程序的形式。这与使用简单的 vtkMultiBlockDataSet 可以实现的效果没有太大区别。但是,将存储(vtkPartitionedDataSetCollection)和组织(vtkDataAssembly)分开有几个优点。在涵盖不同用例时,这些优点将变得更加明显。
虽然数据组装中的节点具有唯一的 id,但公共算法 API 不应使用它们。例如,允许用户从 vtkPartitionedDataSetCollection 中选择要提取的块(而不是 partitioned-datasets)的提取块过滤器可以公开一个 API,该 API 允许用户提供路径表达式,以使用其名称识别相关数据组装中的节点。
除了通过查询其名称来访问节点外,vtkDataAssembly 还支持以深度优先或广度优先顺序迭代所有节点。vtkDataAssemblyVisitor 定义了一个 API,可以在访问每个树节点时实现自定义操作。
2、设计概念
由于 vtkPartitionedDataSet 是整体的一部分,分区数量并没有特殊意义。例如,在分布式管道中,每个等级的 vtkPartitionedDataSet 可以任意地有很多分区。此外,过滤器可以根据需要添加或删除分区。由于 vtkDataAssembly 不会引用单个分区,因此对使用层次关系的过滤器没有影响。
在分布式数据并行的情况下构建 vtkPartitionedDataSetCollection 时,每个等级应具有完全相同数量的分区数据集。在这种情况下,所有等级中特定索引的每个 vtkPartitionedDataSet 被视为整个数据集。同样,每个 vtkDataAssembly 都应相同。
在开发过滤器时,值得考虑的是过滤器是否真的是 vtkPartitionedDataSetCollection 过滤器,还是只是需要单独操作每个 vtkPartitionedDataSet 的 vtkPartitionedDataSet 感知过滤器。例如,典型的 multiblock-aware 过滤器(如 ghost-cell-generation、data-redistribution 等)只是 vtkPartitionedDataSet 过滤器。对于仅使用 vtkPartitionedDataSet 的过滤器,当输入是 vtkPartitionedDataSetCollection 时,执行器会处理集合中的每个分区数据集,从而简化了过滤器的开发。
不改变 vtkPartitionedDataSetCollection 中分区数据集数量的过滤器通常不会影响分区数据集之间的关系,因此可以大致通过 vtkDataAssembly。只有像 extract-block 这样的删除分区数据集的过滤器需要更新 vtkDataAssembly。同样,vtkDataAssembly 提供了几种方便的方法来轻松更新树。
可以开发一个使用 vtkDataAssembly 的映射器。使用让用户使用路径查询来指定不同节点的渲染属性的 API,映射器可以支持输入结构不断变化但关系基本保持不变的用例。由于相同的 dataset-index 可以与 vtkDataAssembly 中的多个节点相关联,映射器可以有效地支持场景图类似的功能,用户可以指定变换和其他渲染参数,同时重用大型数据集。映射器可以轻松判断数据集是否已上传到渲染管道,因为即使它是通过树中的不同分支访问的,它也将具有相同的 ID 并且实际上是相同的实例。