在非结构化网格上进行局部自适应网格细化(局部 AMR)的策略是什么?

计算科学 图书馆 参考请求 自适应网格细化 开放式泡沫
2021-12-21 08:33:51

我对非结构化网格上的本地 AMR 感兴趣。目前,我正在使用 OpenFOAM 库——它支持完全非结构化的本地 AMR:

  • 细胞细化标准确定被切割的细胞列表
  • 选定的单元格被细化:整个网格被重建
  • 地图从旧网格创建到新网格
  • 重新计算连通性(面单元、边面等)
  • 场被映射到新的网格

由于所涉及的数据结构基本上是 C++ 向量,因此网格会被膨胀、复制。

我需要了解可以在使用静态数据结构的网格上构建的替代方法。其中之一是并行的 Octree Forrest 本地 AMR,存在于p4estDendro中。

有人可以指出我最近关于非结构化网格的局部自适应 AMR 策略的评论论文吗?

基于经验的建议会更好:哪个本地 AMR 引擎是基于固定数据结构的非结构化网格的最佳选择?

在阅读论文第一页上关于平衡树间通信的内容之前,我需要一个概述。:)

1个回答

从上面的评论中,我了解到您希望在添加更多单元格时避免复制向量。最简单的方法是为您可能希望拥有的最大单元格数量保留空间:

std::vector<YourCellType> myVectorOfCells;
vectorOfCells.reserve(maxNoCells);

您的向量已分配空间用于创建 maxNoCells 单元格,但尚未创建单元格。您现在可以在每个操作中O(1)及时将 maxNoCells 添加到您的向量中,而无需向量复制自身。但是,C++ 标准要求 push_back 操作摊销 O(1)时间。如果您添加的数量超过 maxNoCells,则向量将自行复制,为之前的k 倍单元保留空间(典型实现选择 1.4 和 2 之间的 ak),以便您可以及时将单元添加到向量中O(1)此调整大小操作不是 O(1).

AMR 策略需要动态数据结构,例如支持插入/删除的单元格链表O(1)然而,链表比向量慢得多,因为遍历它需要在内存中从一个单元到另一个单元随机跳转,从而产生大量缓存未命中:在现代处理器中元素交换到为了插入一个元素而不是遍历链表的所以在实践中,向量是要走的路:它们是可定制的(你可以为它们提供你自己的分配器),你的单元格在内存中对齐,你可以随机访问n/2n/2O(1)时间...只要您首先保留内存,您也可以在 O(1) 时间内添加元素!正如 Bangerth 教授上面提到的,像树这样的分层数据结构也在内部使用向量来存储它们的数据。

但是,我认为在模拟开始时分配内存是更好的做法。您必须知道您可能需要多少个单元格才能检查您是否有足够的可用内存。您不希望您在 200.000 个处理器中的模拟不得不重新分配您的数据结构或内存不足并不得不交换到磁盘。如果发生这种情况,我的意见是您的程序应该由于用户输入错误而大声失败。