Skip to content

Commit a1ad133

Browse files
authored
feat: Add function for creating 3D grids (#36)
Adds `form3DGrid` function under the new `gridtools3d` module. - Currently supported grids are: - Pure Tets - Pure Hexs - Mixed Hex/Tet/Pyr meshes - Also adds example for mixed Hex/Tet/Pyr meshes in `examples/mixedMesh3D`
1 parent 0221d07 commit a1ad133

7 files changed

Lines changed: 110 additions & 0 deletions

File tree

example/mixedMesh3D/makeVTK.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/usr/bin/env python
2+
import numpy as np
3+
import vtk
4+
from pathlib import Path
5+
import pyvista as pv
6+
7+
## ---- Set path to this git repository ----
8+
# (so that you can use a "custom" version easily)
9+
import sys
10+
sys.path.insert(0, '../../')
11+
12+
import vtkpytools as vpt
13+
14+
#%% ---- File inputs ----
15+
# Existing files
16+
coordsPath = Path('./mixedMesh3D.crd')
17+
connecPath = Path('./mixedMesh3D.cnn')
18+
19+
vtkPath = Path('result/mixedmesh3d.vtk')
20+
21+
#%% ---- Building the VTK Grid object ----
22+
coords = np.loadtxt(coordsPath, skiprows=1)
23+
coords = coords[:,:]
24+
25+
connec = np.loadtxt(connecPath, dtype=np.int64, skiprows=1)
26+
connec = connec[:,:] -1
27+
28+
# Create the 2D grid from the given information
29+
grid = vpt.form3DGrid(coords, connectivity_array=connec)
30+
grid.save(vtkPath)
31+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
3
2+
1 2 3 4 9 6 7 8
3+
4 3 7 8 5 5 5 5
4+
7 5 10 3 3 3 3 3
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
10
2+
0.0 0.0 0.0
3+
1.0 0.0 0.0
4+
1.0 1.0 0.0
5+
0.0 1.0 0.0
6+
0.5 2.0 -0.5
7+
1.0 0.0 -1.0
8+
1.0 1.0 -1.0
9+
0.0 1.0 -1.0
10+
0.0 0.0 -1.0
11+
1.25 1.75 -0.5
12+
13+
447 Bytes
Binary file not shown.

vtkpytools/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from .barfiletools import *
2+
from .gridtools3d import *
23
from .common import (getGeometricSeries, unstructuredToPoly, orderPolyDataLine,
34
vCutter, Profile, globFile, rotateTensor, makeRotationTensor,
45
symmetric2FullTensor, full2SymmetricTensor, calcStrainRate)

vtkpytools/gridtools3d/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .core import form3DGrid

vtkpytools/gridtools3d/core.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import numpy as np
2+
import vtk
3+
from pathlib import Path
4+
import pyvista as pv
5+
6+
7+
def form3DGrid(coords_array, connectivity_array) -> pv.UnstructuredGrid:
8+
"""Create 3D VTK UnstructuredGrid from coordinates and connectivity
9+
10+
Currently supports tet grids, mixed tet/pyramid/hex grids.
11+
12+
Parameters
13+
----------
14+
coords_array : numpy.ndarray
15+
Coordinates of the points. Shape in (nPoints,2).
16+
connectivity_array : numpy.ndarray
17+
Connectivity array of the cells. Shape is (nCells,PointsPerCell). The
18+
index of points should start from 0. The type of cell will be inferred
19+
based on the number of points per cell. Mixed meshes inferred by
20+
repeated node IDs in a single element.
21+
22+
Returns
23+
-------
24+
pv.UnstructuredGrid
25+
Pyvista UnstructuredGrid object with the grid loaded.
26+
"""
27+
nCells = connectivity_array.shape[0]
28+
nPnts = connectivity_array.shape[1]
29+
cell_type = None
30+
if nPnts == 4:
31+
cell_type = vtk.VTK_TETRA # ==int(10)
32+
elif nPnts == 8:
33+
tetCells = connectivity_array[:,3] == connectivity_array[:,4]
34+
pyrCells = (connectivity_array[:,4] == connectivity_array[:,5]) & ~tetCells
35+
if not np.any(pyrCells + tetCells): # not a mixed mesh
36+
cell_type = vtk.VTK_HEXAHEDRON # ==int(12)
37+
else:
38+
raise ValueError('This connectivity file has the wrong number of points.'
39+
' Must be either 4 or 8 points per cell, this has {}'.format(nPnts))
40+
41+
if cell_type:
42+
connectivity_array = np.hstack((np.ones((nCells,1), dtype=np.int64)*nPnts, connectivity_array))
43+
offsets = np.arange(0, connectivity_array.size+1, nPnts+1, dtype=np.int64)
44+
cell_types = np.ones(nCells, dtype=np.int64) * cell_type
45+
else: # mixed mesh
46+
hexCells = np.invert(tetCells + pyrCells)
47+
cell_types = tetCells*vtk.VTK_TETRA + pyrCells*vtk.VTK_PYRAMID + hexCells*vtk.VTK_HEXAHEDRON
48+
offset = tetCells*np.int64(4) + pyrCells*np.int64(5) + hexCells*np.int64(8)
49+
50+
connectivity_array[tetCells, 4:] = np.int64(-1)
51+
connectivity_array[pyrCells, 5:] = np.int64(-1)
52+
connectivity_array = np.hstack((offset[:,None], connectivity_array))
53+
connectivity_array = connectivity_array[connectivity_array != -1]
54+
55+
offsets = np.roll(np.cumsum(offset+1), 1)
56+
offsets[0] = 0
57+
58+
grid = pv.UnstructuredGrid(offsets, connectivity_array, cell_types, coords_array)
59+
60+
return grid

0 commit comments

Comments
 (0)