隐式与显式域分解方法

计算科学 线性代数 有限元 分区 域分解
2021-12-01 03:33:54

我一直在研究非结构化方法的有限元代码,我使用 Schur 补码方法对其进行了并行化。以下是我如何做到的摘要:

  1. 将网格的每个三角形分配给一个域
  2. 对于每个节点,确定它在哪个域中或是否在人工边界上
  3. 向每个处理器发送它的网格部分——它拥有的三角形以及它拥有的任何节点,即使它与其他域共享这些节点
  4. 在每个处理器上并行构建矩阵
  5. 解决一些问题,使用某种方式在处理器之间交换节点数据

我正在求解椭圆 PDE 的拟线性系统,因此每个线性求解只是 Picard 方法的迭代。特别是,我需要在每一步更改刚度矩阵的条目,因为它取决于解的梯度。(矩阵的非零结构不会改变。)

这一切都很好。但是,它与我看到的通常方法不一致。

我的代码在进程之间划分了三角形,其中一些必须共享节点。这意味着额外的存储空间,但刚度矩阵的条目可以完全并行填充。另一方面,像 PETSc 和 METIS 这样的库将所有节点划分为不相交的集合,并将它们与刚度矩阵中的相应行一起发送到每个过程。但是,您必须进行沟通以填充刚度矩阵。

那么:为什么大型科学图书馆对划分节点而不是元素有明显的偏好?我错过了什么吗?

3个回答

按元素分区会导致组装过程中的少量简化,但代价是求解器中的负载平衡不佳、无法使用许多流行的求解方法以及更多的沟通来应用操作员。使用元素分区的最常见原因仅仅是因为尚未编写处理重叠或在组装期间将贡献传递到进程外行的代码。(PETSc 将自动进行通信。)从长远来看,它很少会更快。

现在,如果您只在本地组装,您最终会在每个子域上遇到“Neumann 问题”。由于这些问题没有边界条件,它们对于没有零阶“质量”项的微分方程是奇异的。这需要使用更复杂的预处理器,例如 FETI-DP 或 BDDC,其性能对分区非常敏感,并且如果物理系统的特性发生变化,通常需要特殊工作。如果您组装到基于顶点的运算符(如 PETSc 的默认矩阵格式),则可以使用许多“更容易”使用的方法,例如加法 Schwarz 和代数多重网格。(从广义上讲,“更容易”意味着他们有更广泛的表现“甜蜜点”,

有些人,包括 2004 年戈登·贝尔奖得主,到处使用顶点分区,并在重叠的元素中冗余集成,在没有通信的情况下组装算子。这通常最有利于性能,但需要扩展网格以包含一个重叠单元格,这在您的代码中可能会或可能不会方便。

两者都是有效的技术,但都有各自的权衡。特别是 PETSc,有作为线性代数库的历史,鉴于此,将行明确分配给处理器是有意义的。对于具有元素矩阵形成和通常某种矩阵组合的有限元方法,将元素唯一分配给处理器通常是有意义的。一些代码以这种方式形成元素矩阵,然后在矩阵组装和求解期间调用 PETSc 之前选择将节点分配给处理器。

所有这些技术都可以发挥作用。

您看到的部分脱节是历史偏好。域分解方法在 1990 年代很流行,当时没有线性代数库来处理(相当复杂的)矩阵条目的通信任务,如果你将顶点(或者更确切地说,自由度)分割成不相交的集合;当时并行机器上的处理器数量也只有几十个。如果您必须自己在如此小的(按照今天的标准)机器上编写用于并行数据通信的算法,那么域分解方法很有意义。

但是时代变了。PETSc 等库可以很好地处理矩阵元素的通信,无需用户交互。今天的机器有成百上千或更多的处理器,域分解方法根本不能很好地扩展到这些类型的机器。因此,在单元格上拆分的域分解方法不再那么流行。