有限体积实现

计算科学 有限体积 网格生成 麻木的
2021-12-16 04:18:14

我正在尝试实现一个简单的有限体积法求解器。前段时间我上过关于 FVM 的课程,但我仍然了解主要概念。但是为非笛卡尔或一维网格实现 FVM 对我来说并不简单。

例如,我有一个网格代表我的控制体积。我计算了稍后用作我的自由度的单元质心。我将如何计算细胞质心之间的连通性?我可以通过搜索共享细胞表面的细胞来计算它,但这是非常幼稚的,因此计算效率非常低。此外,我只是没有看到复杂的软件这样做。

我正在寻找任何可以帮助我理解有效实现 FVM 求解器的技巧的东西!与基础数学/数值方案不直接相关的事物,而是与设置相关的事物。

1个回答

我有一个用python编写的以细胞为中心的网格的一维有限体积代码,

以单元为中心的网格

首先生成一个序列,它是人的位置,{Xj-1/2}. 例如,对于域 [0,1] 上的均匀间距,这很简单,

a = 0
b = 1
J = 50 
faces = numpy.linspace(a, b, J}

有了面之后,剩下的就很容易了,因为面唯一地确定了细胞中心,

Xj=12(Xj-1/2+Xj+1/2)

和细胞体积(仅 3D 中的真实体积,但我们坚持使用措辞),

Hj=Xj+1/2-Xj-1/2.

为方便起见,您可以定义质心间距,这在向/从中心/面插入值时很有用。按照Hundsorfer 的方法

H-=Xj-Xj-1=12(Hj-1+Hj)H+=Xj+1-Xj=12(Hj+Hj+1)

github 上的以下项目可能有用,https://github.com/danieljfarrell/FVM看看如何在实践中实现它。我使用 aMeshCellVariable对象(受 Fipy 启发)。您可以实例化网格并查询其质心位置、网格体积等。CellVariable该类使用网格对解变量进行透明线性插值。

这是网格类和如何使用它的示例。它可能是您实施的有用基础,

class Mesh(object):
    """A 1D cell centered mesh defined by faces for the finite volume method."""

    def __init__(self, faces):
        super(Mesh, self).__init__()

        # Check for duplicated points
        if len(faces) != len(set(faces)):
            raise ValueError("The faces array contains duplicated positions. No cell can have zero volume so please update with unique face positions.")
        self.faces = np.array(faces)
        self.cells = 0.5 * (self.faces[0:-1] + self.faces[1:])
        self.J = len(self.cells)
        self.cell_widths = (self.faces[1:] - self.faces[0:-1])

    def h(self, i):
        """Returns the width of the cell at the specified index."""
        return self.cell_widths[i]

    def hm(self, i):
        """Distance between centroids in the backwards direction."""
        if not check_index_within_bounds(i,1,self.J-1):
            raise ValueError("hm index runs out of bounds")
        return (self.cells[i] - self.cells[i-1])

    def hp(self, i):
        """Distance between centroids in the forward direction."""
        if not check_index_within_bounds(i,0,self.J-2):
            raise ValueError("hp index runs out of bounds")
        return (self.cells[i+1] - self.cells[i])

import numpy
faces = numpy.linspace(0,1,6)
mesh = Mesh(faces)
mesh.cells # i.e. cell centres
# array([ 0.1,  0.3,  0.5,  0.7,  0.9])
mesh.cell_widths # i.e. cell volumes
# array([ 0.2,  0.2,  0.2,  0.2,  0.2])