1

我正在开发一个有限元系统。像往常一样,模拟由一组网格节点组成,每个节点都有一组属性(浮点),例如随时间演变的几个材料属性、坐标或物理量。

您可以采用两种极端方法:

  • 属性方面:为每个属性维护一个数组:

    double* x, *y, *z, *e_field, *b_field, *conductivity;

  • 入口方式:维护一个数组,其中每个数组都是 struct

    struct { double x, y, z, e_field, b_field, conductivity; } *meshnodedata;

在这些之间,可以混合使用,例如仅对坐标 x、y、z 应用第二种方法,而对其余属性使用第一种方法。您的模拟为每个网格节点维护的属性越多,混合的可能性就越大。

一方面,我有一个经典问题,就程序性能和代码可维护性而言,这些方法(及其组合)中的哪一种最适合科学计算。另一方面,我想知道如何以使不同方法之间的迁移变得容易的方式来实现代码。此外,它甚至可能是在程序不同部分的不同内存布局之间迁移的解决方案。

言归正传:

  • 您对这些不同的方法有何经验?
  • 这些差异有多大?
  • 您是否获得了在这两种布局之间迁移的经验?
4

1 回答 1

3

您的问题实际上归结为如何设计灵活且快速的有限元软件的问题,这是一个活跃的研究领域。我曾开发过此类软件,我认为您的问题的答案实际上取决于您希望支持哪种功能。例如,您是否需要自适应网格细化和粗化?你会求解 PDE 系统吗?你的代码应该在集群上运行吗?你会有多少未知数?在不知道您的目标的情况下,无论如何我都会尝试制作一些通用的观点。

  1. 那里有大量的 FE 框架和网格管理器——使用其中之一!

  2. 网格管理器比许多人想象的要复杂。只要它只是在一台计算机上进行 3D 测试,它可能仍然可以管理。具有局部细化和并行负载平衡的 3D 混合元素类型的网格管理器是一项艰巨的任务。仅当您知道要改进哪些现有的网格管理器时,才可以开发自己的网格管理器。

  3. 内存布局:现在我们来解决实际问题 :)
    分离网格数据和问题数据。这将使您的代码更易于维护。网格管理器可用于不同类型的问题,每个问题都有自己的一组数据附加到每个元素。

  4. 如果您将诸如电导率之类的东西存储在网格内或外部,就性能而言应该无关紧要。我会出于设计原因将其分开,而不是出于性能原因。

  5. 将您的未知数(可能在您e_fieldb_field示例中)存储在一个连续的内存块中。这将大大提高线性求解器的性能。迭代线性求解器通常受到大型矩阵的内存带宽的限制。

  6. 您的未知数向量的内部结构可能是分组或逐块的(基本上是您自己描述的两种方法)这两种方法中选择哪一种来为未知数编号取决于许多因素,包括您解决的 PDE 的类型和您使用的一种线性求解器。仅关于这个问题就有许多科学出版物。

于 2010-10-31T22:30:48.347 回答