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


    构建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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92

    这个类的作用是,方便我们读取并构建用于在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()
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

    reader = vtk.vtkUnstructuredGridReader()
    reader.SetFileName(read_fn)
    reader.Update()
    self.FEModel.ugrid = reader.GetOutput()
    
    • 1
    • 2
    • 3
    • 4

    云图可视化

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

    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    结果展示

    在这里插入图片描述

  • 相关阅读:
    一个useState学会React的主要思想
    网络原理,了解xml, json,protobuffer的特点
    ElasticSearch使用入门及拼音搜索介绍
    面试题: 线程池的核心参数
    Java 序列化原理
    [Socket]Unix socket 运行权限问题
    【滤波器】最小均方(LMS)自适应滤波器
    基于深度学习的小学语文“输出驱动”教学研究课题方案
    yarn create vite my-vue-app --template /vue关于yarn创建vite所遇到的坑,创建vite错误
    大模型应用选择对比
  • 原文地址:https://blog.csdn.net/qq_39784672/article/details/127931413