Quazim0t0's picture
Import from Quazim0t0/neural-physics-engine; repoint refs to NeuralVerified
24c2ab9 verified
Raw
History Blame Contribute Delete
1.49 kB
"""Tetrahedral mesh generation for the 3D PD engine."""
import numpy as np
# 6-tet decomposition of a unit cube (indices into the cube's 8 corners,
# corner order: (i,j,k) bits -> idx = i + 2*j + 4*k)
_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)
# enforce positive orientation
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