我正在尝试为有限元代码实现自适应网格细化。代码使用(至少现在)线性三角形,所以当我进行网格细化时,我希望三角形网格保持保形,即没有悬挂节点:
我计划使用 Rivara [33,34] 的最长边二等分法。不幸的是,我无法访问这些论文,因为我还没有找到可免费下载的 pdf。我查看了描述此方法的其他几篇论文/资源,即fea8.pdf以及 Wolfgang Bangerth 的视频系列讲座 14-18,但是我对如何实际实现该算法的细节有疑问。
到目前为止我所做的是假设一个初始的粗网格,即:
在我的程序中,我的网格由二叉树数组表示,其中每个原始粗三角形是数组中二叉树之一的根节点。因此,例如在上面的网格中,我将有一个大小为 2 的二叉树数组。从图形上看,我的树看起来像:
现在说例如三角形被标记为细化。我们用最长边平分这个三角形,创建两个新的子三角形:
和树结构:
问题是那个三角形有一个悬挂节点,最糟糕的是三角形树中的根节点不“知道”它沿着该边缘有一个悬挂节点,也不“知道”这个悬挂节点的编号为 5。我想出的一个解决方案是让每个节点代表一个三角形,以使其还有额外的指针指向那个三角形的邻居。然而,这很快使树数组变得非常复杂,到处都是节点之间的指针,试图跟踪哪些三角形是其他三角形的邻居。
例如,在 C++ 中,我的二叉树数据结构类似于:
template <class T>
class Tree
{
private:
struct Node
{
T element;
Node *parent;
Node *left;
Node *right;
Node *neigh01;
Node *neigh12;
Node *neigh20;
int hnode01; //store hanging node numbers for this node
int hnode12;
int hnode20;
bool refine; //refinement flag saying this node is in need of refinement
Node(T e) : element(e), parent(NULL), left(NULL), right(NULL), neigh01(NULL), neigh12(NULL), neigh20(NULL), hnode01(-1), hnode12(-1), hnode20(-1)
{
}
};
//rest of class ...constuctors, methods, etc...
};
你可以看到我已经包含了额外的节点指针,它们试图跟踪邻居节点的存储位置。实际上实现这种自适应网格细化的二等分方法似乎相当复杂,我不知道如何去做。我的想法是有额外的指针来跟踪邻居是解决这个问题的正确方法吗?有没有人有免费可用的资源来更详细地解释二分算法,即解释使用的数据结构等?谁能指出我使用二等分进行自适应网格细化的算法?用fea8.pdf写的那个似乎表明我们首先遍历所有需要细化的节点并将它们拆分。然后我们通过(迭代地?)纠正挂起的节点。这是正确的/通常会做什么?我将我的网格表示为二叉树数组的想法是表示将自适应细化的网格的良好/标准方式吗?基本上我需要任何帮助来实现这种自适应网格细化算法。
谢谢
[33] MC里瓦拉。完全自适应多重网格有限元软件的设计和数据结构。ACM 数学软件交易,10:242 264,1984。
[34] MC里瓦拉。基于单纯形的广义二等分的网格细化过程。SIAM 数值分析杂志,21:604 613,1984。










