如何阅读有限元网格并将其视为UnstructuredGrid

时间:2017-07-10 16:26:20

标签: paraview

我想从HDF5文件中读取有限元网格(即带坐标的矩阵和带连通性的矩阵),并使用Python界面在ParaView中显示它。

我知道如何做一些简单的事情:

from paraview.simple import *

Sphere()
Show()
Render()

但是,如何做网格?让我们跳过HDF5部分,重点关注这个包含二维四边形的非常简单的二维网格:

from paraview.simple import *
import numpy as np

coor = np.array([
    [ 0.0 , 0.0 ],
    [ 1.0 , 0.0 ],
    [ 2.0 , 0.0 ],
    [ 0.0 , 1.0 ],
    [ 1.0 , 1.0 ],
    [ 2.0 , 1.0 ],
])

conn = np.array([
    [ 0 , 1 , 4 , 3 ],
    [ 1 , 2 , 5 , 4 ],
])
  

从哪里开始?

可能的方法

一种可能的方法是建立vtkUnstructuredGrid。但问题是我不知道该怎么办。即我如何告诉ParaView使用它?

from paraview import vtk

points = vtk.vtkPoints()

for i,(x,y) in enumerate(coor):
    points.InsertNextPoint(x,y,0.0)

grid = vtk.vtkUnstructuredGrid()

for el in conn:
    cell = vtk.vtkQuad()
    for i,ver in enumerate(el): 
        cell.GetPointIds().SetId(i,ver)
    grid.InsertNextCell(cell.GetCellType(),cell.GetPointIds())

grid.SetPoints(points)

了解如何包含单元格数据和点数据会非常有帮助,但我可以从解决此问题的方法开始解决这个问题。

2 个答案:

答案 0 :(得分:2)

首先,重要的是要注意有几个不同的水平" ParaView中的Python用法您的第一个示例是从高级Python接口到ParaView。您可以在用户界面中执行的大多数操作可以通过Python控制台在此级别的ParaView中完成,也可以通过Python控制台运行脚本来完成。

在较低级别,Python可用于定义VTK的操作。 Programmable FilterProgrammable Source是完成此级别编程的地方。值得注意的是,Programmable FilterProgrammable Source对ParaView或paraview.simple一无所知 - 他们在只有VTK可用的Python环境中执行Python脚本。例如,如果导入paraview.simple,则行为未定义。

出于您的目的,较低级别的Python编程似乎是合适的。我会定义Programmable Source,将其Output Data Set Type设置为vtkUnstructuredGrid。接下来,您的脚本将类似于:

import numpy as np

coor = np.array([
    [ 0.0 , 0.0 ],
    [ 1.0 , 0.0 ],
    [ 2.0 , 0.0 ],
    [ 0.0 , 1.0 ],
    [ 1.0 , 1.0 ],
    [ 2.0 , 1.0 ],
])

conn = np.array([
    [ 0 , 1 , 4 , 3 ],
    [ 1 , 2 , 5 , 4 ],
])

import vtk

grid = self.GetOutput()

points = vtk.vtkPoints()
for i,(x,y) in enumerate(coor):
    points.InsertNextPoint(x,y,0.0)
grid.SetPoints(points)

grid.Allocate()
for el in conn:
    cell = vtk.vtkQuad()
    for i,ver in enumerate(el): 
          cell.GetPointIds().InsertId(i,ver)
    grid.InsertNextCell(cell.GetCellType(),cell.GetPointIds())

答案 1 :(得分:0)

请归功于@CoryQuammen,因为这是他的解决方案

供将来参考完整的脚本,包括一些单元格和点数据

from paraview.simple import *

paraview.simple._DisableFirstRenderCameraReset()

# create a new 'Programmable Source'
mesh = ProgrammableSource()
mesh.OutputDataSetType = 'vtkUnstructuredGrid'
mesh.ScriptRequestInformation = ''
mesh.PythonPath = ''
mesh.Script = '''
import numpy as np

coor = np.array([
    [ 0.0 , 0.0 ],
    [ 1.0 , 0.0 ],
    [ 2.0 , 0.0 ],
    [ 0.0 , 1.0 ],
    [ 1.0 , 1.0 ],
    [ 2.0 , 1.0 ],
])

conn = np.array([
    [ 0 , 1 , 4 , 3 ],
    [ 1 , 2 , 5 , 4 ],
])

celldata = [
  1.0 ,
  2.0
]

normals = np.array([
  [ -1.0 , -1.0 ],
  [  0.0 , -1.0 ],
  [ +1.0 , -1.0 ],
  [ -1.0 , +1.0 ],
  [  0.0 , +1.0 ],
  [ +1.0 , +1.0 ],
])

normals /= np.tile(np.sqrt(np.sum(normals**2.,axis=1)).reshape(-1,1),(1,2))

import vtk

grid = self.GetOutput()

points = vtk.vtkPoints()
for i,(x,y) in enumerate(coor):
    points.InsertNextPoint(x,y,0.0)
grid.SetPoints(points)

grid.Allocate()
for el in conn:
    cell = vtk.vtkQuad()
    for i,ver in enumerate(el):
          cell.GetPointIds().InsertId(i,ver)
    grid.InsertNextCell(cell.GetCellType(),cell.GetPointIds())

data = vtk.vtkDoubleArray()
data.SetName("Example data")
for i in celldata:
  data.InsertNextValue(i)

grid.GetCellData().AddArray(data)

data = vtk.vtkDoubleArray()
data.SetNumberOfComponents(3)
data.SetName("Normals")
for i in normals:
  data.InsertNextTuple([i[0],i[1],0.0])

grid.GetPointData().AddArray(data)
'''

# show data from mesh
Mesh = Show(mesh)

Render()