| """Tetrahedral mesh generation for the 3D PD engine.""" |
| import numpy as np |
|
|
| |
| |
| _CUBE_TETS = np.array([ |
| [0, 1, 3, 7], |
| [0, 3, 2, 7], |
| [0, 2, 6, 7], |
| [0, 6, 4, 7], |
| [0, 4, 5, 7], |
| [0, 5, 1, 7], |
| ], dtype=np.int64) |
|
|
|
|
| def beam_tet_mesh(nx=8, ny=2, nz=2, dx=0.1): |
| """Regular beam of (nx,ny,nz) cells, 6 tets per cell. |
| |
| Returns (verts (V,3) float64, tets (T,4) int64). All tets have |
| positive orientation (det Dm > 0). |
| """ |
| xs = np.arange(nx + 1) * dx |
| ys = np.arange(ny + 1) * dx |
| zs = np.arange(nz + 1) * dx |
| gx, gy, gz = np.meshgrid(xs, ys, zs, indexing="ij") |
| verts = np.stack([gx, gy, gz], axis=-1).reshape(-1, 3) |
|
|
| def vid(i, j, k): |
| return (i * (ny + 1) + j) * (nz + 1) + k |
|
|
| tets = [] |
| for i in range(nx): |
| for j in range(ny): |
| for k in range(nz): |
| corners = np.array([ |
| vid(i + di, j + dj, k + dk) |
| for dk in (0, 1) for dj in (0, 1) for di in (0, 1) |
| ]) |
| for t in _CUBE_TETS: |
| tets.append(corners[t]) |
| tets = np.array(tets, dtype=np.int64) |
|
|
| |
| d = verts[tets] |
| dm = np.stack([d[:, 1] - d[:, 0], d[:, 2] - d[:, 0], d[:, 3] - d[:, 0]], axis=-1) |
| neg = np.linalg.det(dm) < 0 |
| tets[neg] = tets[neg][:, [0, 2, 1, 3]] |
| return verts, tets |
|
|