如何读取有限元网格并将其视为非结构化网格
How to read finite element mesh and view it as UnstructuredGrid
我想从 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 ],
])
Where to go from here?
可能的方法
一种可能的方法是构建 vtkUnstructuredGrid
。但问题是我不知道该怎么办。 IE。我如何告诉 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)
了解如何包含单元格数据和点数据会非常有帮助,但我可能可以从解决这个问题开始解决这个问题。
首先,重要的是要注意在 ParaView 中有几个不同的 "levels" 和 Python 用法。您的第一个示例是从高级 Python 接口到 ParaView。您可以在用户界面中执行的大多数操作都可以在 ParaView 中通过 Python 控制台或通过 运行 脚本通过 Python 控制台在该级别完成。
在较低级别,Python 可用于定义 VTK 的操作。 Programmable Filter
和 Programmable Source
是完成此级别编程的地方。重要的是要注意 Programmable Filter
和 Programmable Source
对 ParaView 或 paraview.simple
一无所知 - 他们在 Python 环境中执行他们的 Python 脚本VTK 可用。例如,如果您导入 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())
请感谢@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()
我想从 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 ],
])
Where to go from here?
可能的方法
一种可能的方法是构建 vtkUnstructuredGrid
。但问题是我不知道该怎么办。 IE。我如何告诉 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)
了解如何包含单元格数据和点数据会非常有帮助,但我可能可以从解决这个问题开始解决这个问题。
首先,重要的是要注意在 ParaView 中有几个不同的 "levels" 和 Python 用法。您的第一个示例是从高级 Python 接口到 ParaView。您可以在用户界面中执行的大多数操作都可以在 ParaView 中通过 Python 控制台或通过 运行 脚本通过 Python 控制台在该级别完成。
在较低级别,Python 可用于定义 VTK 的操作。 Programmable Filter
和 Programmable Source
是完成此级别编程的地方。重要的是要注意 Programmable Filter
和 Programmable Source
对 ParaView 或 paraview.simple
一无所知 - 他们在 Python 环境中执行他们的 Python 脚本VTK 可用。例如,如果您导入 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())
请感谢@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()