【科研脚本工具】使用VTK库:掌握.vtk与.vtu文件的读取艺术

文摘   2024-09-13 16:30   广西  

在科学计算和工程仿真中,VTK(Visualization Toolkit)是常用的数据可视化工具,它支持多种网格数据格式,包括 .vtk.vtu 文件。这两种文件格式分别代表着传统和基于 XML 的网格数据存储方式。在采用部分有限元求解器时(比如FEniCS),求解结果往往会输出.vtk 或.vtu 文件,对此类文件数据的读取可帮助我们掌握具体的数据,本文将介绍如何使用 vtk 库读取这两种文件格式,并展示其主要区别和应用场景。

1. .vtk.vtu 文件的区别

在使用 VTK 时,常见的两种文件格式分别是 .vtk.vtu。它们各自有不同的特点:

  • .vtk 文件:

    • 这是 VTK 的老式文件格式,支持各种网格类型,包括结构化网格和非结构化网格。

    • 可以使用 ASCII 或二进制方式存储数据。ASCII 格式易于阅读和调试,但文件较大。二进制格式节省存储空间,但不易直接查看。

    • 读取时需要根据文件的网格类型选择适当的读取器,如 vtkPolyDataReadervtkUnstructuredGridReader

  • .vtu 文件:

    • .vtu 是基于 XML 的文件格式,专用于存储非结构化网格(unstructured grid)数据。由于采用 XML,它具备更好的扩展性和数据描述能力。

    • 支持数据压缩,适合处理大规模数据。

    • 读取时使用 vtkXMLUnstructuredGridReader,专门处理非结构化网格数据。

2. 读取 .vtk 文件的步骤

要读取 .vtk 文件,我们可以使用 vtkPolyDataReadervtkUnstructuredGridReader 读取器。以下是如何读取一个 .vtk 文件并提取其中数据的示例:

import vtk

# 读取 PolyData 格式的 .vtk 文件
reader = vtk.vtkPolyDataReader()
reader.SetFileName("output-vec.vtk") # 替换为你的 .vtk 文件路径
reader.Update()

# 获取读取的数据
data = reader.GetOutput()

# 打印节点坐标
points = data.GetPoints()
num_points = points.GetNumberOfPoints()

print("节点坐标:")
for i in range(num_points):
x, y, z = points.GetPoint(i)
print(f"Point {i}: x = {x}, y = {y}, z = {z}")

# 获取向量字段(假设向量名称为 "U")
point_data = data.GetPointData()
if point_data.HasArray("U"):
U = point_data.GetVectors("U")
for i in range(U.GetNumberOfTuples()):
u_x, u_y, u_z = U.GetTuple(i)
print(f"Point {i}: Ux = {u_x}, Uy = {u_y}, Uz = {u_z}")

比如,用上述代码读取前面文章(【科研脚本工具】Python VTK库写入向量数据并在ParaView中可视化 )里面记录的脚本所生成的vtk文件,效果如下:

利用vtkPolyDataReader读取vtk文件

3. 读取 .vtu 文件的步骤

.vtu 文件是非结构化网格的 XML 格式存储文件。为了读取 .vtu 文件,可以使用 vtkXMLUnstructuredGridReader 读取器。

以下代码展示了如何读取 .vtu 文件并提取节点和向量数据:

读取节点坐标

import vtk

# 读取 .vtu 文件
reader = vtk.vtkXMLUnstructuredGridReader()
reader.SetFileName("displacement.vtu") # 替换为你的 .vtu 文件路径
reader.Update()

# 获取读取的数据
data = reader.GetOutput()

# 打印节点坐标
points = data.GetPoints()
num_points = points.GetNumberOfPoints()

print("节点坐标:")
for i in range(num_points):
x, y, z = points.GetPoint(i)
print(f"Point {i}: x = {x}, y = {y}, z = {z}")

输出如下:

vtkXMLUnstructuredGridReader读取vtu文件,获取节点坐标

列举向量(标量)组的名称

代码如下,主要用到GetArrayName函数,前面的.vtk文件也可通过该函数获取到相应信息。

num_point_arrays = point_data.GetNumberOfArrays()
print("Available PointData fields:")
for i in range(num_point_arrays):
array_name = point_data.GetArrayName(i)
print(f"PointData Field {i}: {array_name}")

输出如下:

Available PointData fields:
PointData Field 0: f_13

可以发现,f_13即为向量组的名称,与下图对应:

vtu文件(Paraview可视化)

读取某一向量(标量)组下面的具体值

在上面的基础上,想要读取f_13下面的具体值,可进一步编写下面的代码:

# 获取向量字段
point_data = data.GetPointData()
if point_data.HasArray("f_13"):
U = point_data.GetVectors("f_13")
for i in range(U.GetNumberOfTuples()):
u_x, u_y, u_z = U.GetTuple(i)
print(f"Point {i}: Ux = {u_x}, Uy = {u_y}, Uz = {u_z}")

代码运行效果如下:

根据名称获取向量字段

4. .vtk.vtu 文件读取流程的总结

  • .vtk 文件 使用 vtkPolyDataReadervtkUnstructuredGridReader 读取,具体取决于数据网格的类型。对于存储结构化网格和非结构化网格的数据,都可以使用不同的读取器来解析。

  • .vtu 文件 是基于 XML 的格式,专门用于非结构化网格数据存储。它提供了更高效的数据压缩和传输方式,使用 vtkXMLUnstructuredGridReader 进行读取。

5. 应用场景

在实际的工程仿真和科学计算中,根据具体的数据结构和需求选择合适的文件格式和读取器:

  • .vtk 文件由于格式简单,可以用于存储较小规模的网格数据,便于调试和处理。

  • .vtu 文件则适合处理复杂的非结构化网格,尤其是在需要存储大量数据并进行高效传输时,它是更好的选择。

总结

通过了解 .vtk.vtu 文件的区别,我们可以更高效地在 VTK 中处理网格数据。无论是传统的 .vtk 文件,还是基于 XML 的 .vtu 文件,使用正确的读取器,可以帮助我们更顺利地进行数据解析和可视化。

相关阅读推荐:


挨踢的土木佬
一名学习编程的土木佬,计算固体力学,以第一/通讯作者身份在IJNME、IJSS、力学学报、振动工程学报等权威期刊发表论文若干。热衷分享Python编程、数据处理和数值分析(含有限元)新知,不定期更新文章与笔记。
 最新文章