【VTK+有限元后处理】可视化结果云图

本文介绍了一个名为FEDataModel的类,该类用于读取有限元计算结果文件,并构建vtkUnstructuredGrid对象以便于在VTK中进行可视化。文中详细说明了如何处理不同类型的单元,如何读取节点属性数据,并提供了保存和加载vtkUnstructuredGrid对象的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

构建vtkUnstructuredGrid对象

为了读取不同格式的有限元计算结果文件,我们先写一个FEDataModel类来管理有限元的几何拓扑和属性信息。

class FEDataModel:
    """有限元数据模型类"""

    def __init__(self):
        self.nodes = []  # 节点几何坐标
        self.elements = []  # 单元拓扑信息
        self.scalars = {}  # 节点标量属性
        self.vectors = {}  # 节点向量属性
        self.ugrid = vtk.vtkUnstructuredGrid()  # 用于VTK可视化的数据模型
        self.ugrid.Allocate(100)

    def read_inp(self, filename):
        with open(filename) as f:
            node_flag, element_flag = False, False
            for line in f.readlines():
                line = line.replace('\n', '').replace(' ', '')
                if '*ELEMENT' in line:
                    node_flag, element_flag = False, True
                    continue
                elif '*NODE' in line:
                    node_flag, element_flag = True, False
                    continue
                elif '*' in line:
                    node_flag, element_flag = False, False
                    continue
                if node_flag:
                    self.nodes.append(list(map(lambda x: float(x), line.split(',')))[1:])
                elif element_flag:
                    self.elements.append(list(map(lambda x: int(x) - 1, line.split(',')))[1:])
        # print(len(self.nodes), len(self.elements))

        nodes = vtk.vtkPoints()
        for i in range(0, len(self.nodes)):
            nodes.InsertPoint(i, self.nodes[i])

        for i in range(0, len(self.elements)):
            if len(self.elements[i]) == 4:  # 四面体单元
                self.ugrid.InsertNextCell(vtk.VTK_TETRA, 4, self.elements[i])
            elif len(self.elements[i]) == 6:  # 六面体单元
                self.ugrid.InsertNextCell(vtk.VTK_POLYGON, 6, self.elements[i])
            elif len(self.elements[i]) == 3:  # 三角面片单元
                self.ugrid.InsertNextCell(vtk.VTK_TRIANGLE, 3, self.elements[i])
            else:
                print("FEDataModel构建中遇到错误单元类型!")
        self.ugrid.SetPoints(nodes)

    def read_ntl(self, filename):
        with open(filename) as f:
            lines = f.readlines()
            attribute_name = ''.join(lines[0].split(' ')[1:-1])
            scalar = []
            for line in lines[4:]:
                line = line.replace('\n', '').split(' ')
                scalar.append(float(line[-1]))
            self.scalars[attribute_name] = scalar
        # print(attribute_name + ' scalar number: ' + str(len(scalar)))

        # 存储标量值
        scalars = vtk.vtkFloatArray()
        scalars.SetName(attribute_name)
        for i in range(0, len(scalar)):
            scalars.InsertTuple1(i, scalar[i])
        # 设定每个节点的标量值
        self.ugrid.GetPointData().SetScalars(scalars)

    def display(self):
        renderer = vtk.vtkRenderer()
        renWin = vtk.vtkRenderWindow()
        renWin.AddRenderer(renderer)
        iren = vtk.vtkRenderWindowInteractor()
        iren.SetRenderWindow(renWin)

        colors = vtk.vtkNamedColors()
        ugridMapper = vtk.vtkDataSetMapper()
        ugridMapper.SetInputData(self.ugrid)

        ugridActor = vtk.vtkActor()
        ugridActor.SetMapper(ugridMapper)
        ugridActor.GetProperty().SetColor(colors.GetColor3d("Peacock"))
        ugridActor.GetProperty().EdgeVisibilityOn()

        renderer.AddActor(ugridActor)
        renderer.SetBackground(colors.GetColor3d("Beige"))

        renderer.ResetCamera()
        renderer.GetActiveCamera().Elevation(60.0)
        renderer.GetActiveCamera().Azimuth(30.0)
        renderer.GetActiveCamera().Dolly(1.2)
        renWin.SetSize(640, 480)
        # Interact with the data.
        renWin.Render()
        iren.Start()

这个类的作用是,方便我们读取并构建用于在VTK中显示的vtkUnstructuredGrid类对象。vtkUnstructuredGrid类是VTK中的非结构化网格类,可用于有限元分析、计算几何和几何建模这类领域。

vtkUnstructuredGrid类详情参见:VTK笔记-使用vtkUnstructuredGrid类构建非结构化数据

其中read_inp成员函数和read_ntl成员函数分别用于读取从ProCAST软件中导出的inp文件(存储有限元的几何拓扑数据)和ntl文件(存储有限元的节点属性数据,如温度、应力等)。

存储vtkUnstructuredGrid对象

为了能一次性读取有限元模型整体数据,我们可以将其保存为vtk格式的文件。

writer = vtk.vtkUnstructuredGridWriter()
writer.SetFileName(save_fn)
writer.SetInputData(self.FEModel.ugrid)
writer.Write()
writer.Update()

下一次只需读取对应的vtk文件即可。

reader = vtk.vtkUnstructuredGridReader()
reader.SetFileName(read_fn)
reader.Update()
self.FEModel.ugrid = reader.GetOutput()

云图可视化

可视化节点属性数据(标量场),关键代码如下:

def drawScalarField(self, scalar_mapper, scalarRange, title):
    # 定义颜色映射表
    lut = vtk.vtkLookupTable()
    lut.SetHueRange(0.67, 0.0)  # 色调范围从红色到蓝色
    # lut.SetAlphaRange(1.0, 1.0) # 透明度范围
    # lut.SetValueRange(1.0, 1.0)
    # lut.SetSaturationRange(1.0, 1.0) # 颜色饱和度
    # lut.SetNumberOfTableValues(256)
    lut.SetNumberOfColors(256)  # 颜色个数
    # lut.SetRange(scalarRange)
    lut.Build()

    scalar_mapper.SetScalarRange(scalarRange)
    scalar_mapper.SetLookupTable(lut)
    scalar_actor = vtk.vtkActor()
    scalar_actor.SetMapper(scalar_mapper)
    self.renderer.AddActor(scalar_actor)
    # 色标带
    scalarBar = vtk.vtkScalarBarActor()
    scalarBar.SetLookupTable(scalar_mapper.GetLookupTable())  # 将颜色查找表传入窗口中的色标带
    scalarBar.SetTitle(title)
    scalarBar.SetNumberOfLabels(5)
    self.renderer.AddActor2D(scalarBar)

结果展示

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值