File size: 1,493 Bytes
24c2ab9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
"""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