在并行有限元计算中管理网格的最佳方法?

计算科学 有限元 并行计算 网格生成 域分解
2021-12-24 04:13:56

我目前正在开发一种解决散射问题的域分解方法。基本上我正在迭代地解决亥姆霍兹 BVP 系统。我使用有限元方法在三角形或四面体网格上离散方程。我正在为我的博士论文开发代码。我知道一些现有的有限元库,例如 deal.ii 或 DUNE,尽管我认为它们很棒,具有启发性的设计和 API,但出于学习目的,我想从头开始开发自己的小应用程序。

我正在运行我的串行版本,现在我想并行化它们。毕竟,至少在原则上,制定易于并行化的算法是域分解框架的优势之一。然而,在实践中,必须考虑许多细节。网格管理就是其中之一。如果应用程序要在很好地扩展到许多 CPU 的同时实现高分辨率,那么在每个 CPU 上复制整个网格是低效的。

我想问问那些在高性能计算环境中开发类似应用程序的开发人员他们是如何处理这个问题的。

有用于分布式网格管理的 p4est 库。我不需要 AMR,所以这可能是一种矫枉过正,因为我只对使用均匀网格感兴趣,我不确定它是否可以细化三角形网格。我也可以简单地创建一个统一的网格,然后将其输入其中一个网格分区器并对输出进行一些后处理。

最简单的方法似乎是为每个分区创建一个单独的文件,其中包含仅与该特定分区相关的网格信息。该文件将由一个 CPU 读取,该 CPU 将负责在网格的该部分上组装离散系统。当然,一些全局分区连接/邻居信息也需要存储在所有 CPU 读取的文件中,以便进行进程间通信。

还有哪些其他方法?如果有小伙伴可以分享一下,业界或政府研究机构处理这个问题有哪些常用的方法?我对并行有限元求解器的编程非常陌生,我想了解我是否正确地考虑了这个问题以及其他人是如何解决这个问题的。任何有关研究文章的建议或指示将不胜感激!

提前致谢!

3个回答

如果您不使用 AMR 并且不想扩展到超过 1K-4K 内核,那么只需执行此操作。

  1. Rank 0 读取整个网格并使用 METIS/Scotch 等对其进行分区(注意:这是一个串行操作)。

  2. Rank 0 向所有其他 rank 广播元素/节点分区信息并释放内存(用于存储网格)

  3. 所有排名都从同一个输入文件中读取他们拥有的节点/元素(包括幽灵节点)(注意:访问同一输入文件的 2000 个排名可能听起来很慢,但实际上并非如此,尽管这可能对文件系统不利,但随后我们只做一次)。

  4. 所有等级都需要创建本地到全局节点/元素/自由度的映射,以用于 BC 的应用和矩阵的组装并重新编号节点。

在一切都说完之后,排名上的所有数据都将是本地的,因此您应该能够很好地扩展(内存方面)。我在我的一个小代码中用大约 100 行(参见此处的第 35-132 行)完成所有这些工作。

现在,如果您的网格太大(例如,> 100-2.5 亿个元素),您无法在单个节点上使用 METIS 对其进行分区并且需要 ParMETIS/PT-Scotch,那么您需要在所有内核/之前并行分区它的额外工作/等级可以阅读它。在这种情况下,出于逻辑原因,将分区阶段与主代码分开可能更容易。

顺便说一句,AMR 库通常不做 tets。PETSc 也是代码并行化的好选择。

编辑:另见herehere

鉴于我开发了 deal.II,您可能不会对此感到惊讶,但这是我的观点:当我与学生交谈时,我通常会告诉他们一开始就开发自己的原型,以便他们了解它是如何完成的。但是,一旦他们有了一些小的运行,我让他们使用一个库,让他们走得更远,因为他们基本上不必在每一步都重新发明轮子。

就您而言,您已经了解了如何实现一个简单的亥姆霍兹求解器。但是您将在接下来的 6 个月中编写并行执行所需的代码,如果您想使用更复杂的几何图形,您将再花费 3 个月。如果您想要一个高效的求解器,您将再花费 6 个月的时间。而所有这些时间你都在编写已经由其他人编写的代码,从某种意义上说,这并没有让你更接近你真正需要为你的博士学位做的事情:开发一些新的东西之前做过。如果你沿着这条路走下去,你将花费 2-3 年的博士时间来重新做别人做过的事情,也许还有 1 年的时间去做一些新的事情。

另一种选择是你现在花 6 个月的时间学习现有的图书馆之一,但在那之后你将有 2-3 年的时间真正做新的东西,每隔一周你可以走进你的顾问办公室并向他展示/她的东西是真正的新东西,可以大规模运行,或者在其他方面非常酷。我想你现在可能已经知道我要处理这个问题了。

这不是一个完整的答案。

对于并行域分解方法的实现,我遇到了一些复杂情况。首先,可以为一个子域使用多个处理器,或者为一个处理器提供多个子域,并且可能希望实现这两种范例。其次,域分解方法的子结构形式需要分离出子域(不是元素)的面、边、顶点。我不认为这些复杂性很容易包含在并行网格管理中。如果您考虑为一个子域使用一个处理器并使用重叠的 RAS/RASHO 方法,情况会变得更简单。即使在这种情况下,您最好自己管理并行布局,