Paraview 中的体积渲染 3D VTK *.vtu UnstructuredGrid 文件

计算科学 视界 VTK
2021-12-03 23:44:59

我想在 Paraview 中体积渲染 3D 标量数据,我不确定我无法这样做是否是 VTK 或 Paraview 的错误使用。

我已经构建了一个 *.vtu VTK 非结构化网格文件,其中包含 2 个单元,这些单元由 10 个 PolyVertex 对象组成,每个点都具有标量数据。这些用于表示空间中数值解的值已知的点(例如,有限元的正交点)。我可以将文件加载到 Paraview 并以点的形式查看输出:

在此处输入图像描述

没问题。但是,当我选择“体积”表示而不是点时,点就会消失,没有任何体积渲染。我正在寻找 paraview 在每个单元格的点之间线性插值解决方案,就像我从数据文件提供图像(统一直线网格)一样:

在此处输入图像描述

但是,我似乎无法找到有关如何执行此操作的文档。我想有限元社区通常必须呈现非结构化的体积数据,所以这令人惊讶。

以及用于在 Python 中写出 VTK 文件的源代码:

class VtkPolyVertCloud(object):
    """ save each finite element as a set of polyvertices, but lose cell information """

    def __init__(self):

        # geometry
        self.points= vtk.vtkPoints()
        self.grid = vtk.vtkUnstructuredGrid()

        # data
        self.values = vtk.vtkDoubleArray()
        self.values.SetName('point_values_array')

        self.grid.SetPoints(self.points)
        self.grid.GetPointData().SetScalars(self.values)

    def add_polyVertex_cell(self, points, data):
        """
        adds points according to user-supplied numpy arrays, for convenience and to eliminate loops
        in calling code

        @param points: numpy array of 3d point coords -- points.shape = (npoints, 3)
        @param data: scalar-valued data belonging to each point -- data.shape = (npoints,)
        """
        npts = points.shape[0]
        assert(points.shape[1] == 3)             # make sure 3d points passed in
        assert(data.shape[0] == npts) # make sure same number of data, points

        pv = vtk.vtkPolyVertex()
        pv.GetPointIds().SetNumberOfIds(npts)
        for idx, point in enumerate(points):
            pointID = self.points.InsertNextPoint(point)
            pv.GetPointIds().SetId(idx, pointID)
            self.values.InsertNextValue(data[idx])

        self.grid.InsertNextCell(pv.GetCellType(), pv.GetPointIds())

和调用代码:

def test_vtkPolyVertexCloud_writeToFile():
    """ adds a set of polyvertices meant to represent a finite element """
    pc = vtku.VtkPolyVertCloud()
    points, data = get_random_points_and_data(10)
    pc.add_polyVertex_cell(points, data)
    pc.add_polyVertex_cell(points + 1, data)

    # write
    fn = 'test_PolyVertexCloud.vtu'
    writer = vtk.vtkXMLUnstructuredGridWriter()
    writer.SetFileName(fn)
    writer.SetInputData(pc.grid)
    writer.Write()

更新:我注意到下面接受的答案并做了以下事情: 1. 对我的每个有限元执行空间 Delaunay 三角剖分(数值解在每个有限元的节点处是已知的)。三角剖分很快,因为即使是高阶有限元也没有那么多点。2. 构造了一个VTK 文件,其中每个单元格都是来自每个元素的空间Delaunay 三角剖分的四面体。

Paraview 能够以体积方式绘制此图。 在此处输入图像描述

1个回答

VTK 不能为 poly_vertex 单元类型生成体渲染也就不足为奇了,因为没有与该类型单元相关的拓扑。

有限元积分点结果的处理方式通常描述如下:

在单元积分点计算结果(例如应力)在有限元方法中很常见。但是,通常,出于绘图目的,节点处需要结果量。实现这一点的一种方法是,对于每个元素,将参数函数拟合到积分点数据。然后可以在每个元素节点处评估此函数。该函数的确切形式取决于特定的元素拓扑和积分点的数量,但它通常类似于用于元素的形状函数。

通常,由于此过程是逐个元素应用的,因此当多个元素连接到一个节点时,结果函数将是不连续的。大多数可视化库(例如 VTK)不直接支持不连续节点结果,因此通常使用以下方法之一。

  1. 您可以简单地平均附加到特定节点的所有元素的元素节点值。

  2. 您可以为附加到特定节点的每个元素创建“额外”节点。这些节点与实际节点位于同一位置。但是拥有重复节点允许每个元素拥有自己的、唯一的集合节点,结果可以附加到这些节点上。例如,这是 Deal II 使用的方法。