tetmesh¶
tetmesh¶
Linear tetrahedral volume-mesh container (TetMesh) and its ops.
Deliberately thin, mirroring trimesh: a tet mesh here exists
to solve a field or walk a volume, not to be exported – a mesher’s actual output is
the hex mesh built around what the solve decided. gmsh (tetmesh.ops.tet_mesh) is an optional extra, imported only inside that one
function.
- class nekmeshpy.tetmesh.TetMesh[source]¶
Bases:
objectA linear tetrahedral volume mesh:
points(P,3)andtets(T,4)connectivity.Deliberately linear only – unlike the point/line/quad/hex ladder, a
TetMeshcarries no order, no interior nodes and no tags. It exists to solve a field or walk a volume (tetmesh.ops), not to be exported: a mesher’s actual output is the hex mesh built around what the solve decided, never the tets themselves.- FACE_POINTS = array([[0, 1, 2], [0, 1, 3], [0, 2, 3], [1, 2, 3]])¶
- __init__(points, tets)[source]¶
- Parameters:
points (NDArray[float64])
tets (NDArray[int64])
- Return type:
None
tetmesh.tetmesh¶
Linear tetrahedral volume-mesh container (points + tets, both 0-based).
- class nekmeshpy.tetmesh.tetmesh.TetMesh[source]¶
Bases:
objectA linear tetrahedral volume mesh:
points(P,3)andtets(T,4)connectivity.Deliberately linear only – unlike the point/line/quad/hex ladder, a
TetMeshcarries no order, no interior nodes and no tags. It exists to solve a field or walk a volume (tetmesh.ops), not to be exported: a mesher’s actual output is the hex mesh built around what the solve decided, never the tets themselves.- FACE_POINTS = array([[0, 1, 2], [0, 1, 3], [0, 2, 3], [1, 2, 3]])¶
- __init__(points, tets)[source]¶
- Parameters:
points (NDArray[float64])
tets (NDArray[int64])
- Return type:
None
- points: NDArray[float64]¶
- tets: NDArray[int64]¶
tetmesh.ops¶
Volumetric algorithms on a TetMesh as free functions. All indices 0-based.
The gmsh dependency lives entirely inside tet_mesh(), imported at call time –
mirrors the toolkit-wide rule that gmsh is an optional extra (pip install
.[mesh]), never a hard import of any module here.
- nekmeshpy.tetmesh.ops.cap_surface(surf, loops)[source]¶
Close an open surface by fan-triangulating each boundary loop
loops(point ids intosurf) from its centroid. Returns(capped, cap_node_sets); the wall vertices keep their indices.
- nekmeshpy.tetmesh.ops.tet_mesh(capped, near, far, ramp, centre)[source]¶
Tet-mesh the closed surface
cappedwith gmsh, keeping its nodes in place.Element size is graded by a background field:
nearatcentre, growing tofaroverramp.gmsh cannot refine a discrete surface, so the triangles handed in set the floor on the size and shape of every tet at the wall – the surface has to be good before it gets here. Reparametrizing it (
classifySurfaces+createGeometry) so gmsh could remesh it does not work on a smooth closed tube with no sharp edges to split on: it comes out either as one unparametrizable patch or, at an angle small enough to succeed, as hundreds of them, every boundary of which would then be forced into the mesh as a feature curve.The three
MeshSizeFrom*switches are turned off so the field is the only thing setting size; otherwise the surface mesh’s own spacing is extended into the volume and quietly overrides it.gmsh does not tetrahedralize the same way twice – not across machines, not run to run on one. A caller freezing a result against this should freeze the tets themselves, not just the knobs that produced them.
- nekmeshpy.tetmesh.ops.cap_nodes(mesh, loops, tol=1e-06)[source]¶
Which boundary nodes of
meshlie on each openingloops(point coordinates, one array per opening).Remeshing throws away the numbering the caps used to be identified by, so find them geometrically instead. Each opening is planar and nothing else in the domain lies in its plane, which makes the test both simple and unambiguous.
- nekmeshpy.tetmesh.ops.tet_gradients(mesh)[source]¶
(grad (E,4,3), volume (E,))of the P1 basis on each tet.
- nekmeshpy.tetmesh.ops.tet_laplacian(mesh)[source]¶
P1 stiffness
K_ij = vol * grad(lam_i) . grad(lam_j)(recomputed each call) – the tet sibling oftrimesh.ops.cotan_laplacian.- Parameters:
mesh (TetMesh)
- Return type:
- nekmeshpy.tetmesh.ops.solve_dirichlet(mesh, dpoints, dvals)[source]¶
Solve the Laplace system with Dirichlet values at
dpoints; returns an(n_points,)field. Assemblestet_laplacian()fresh – a caller solving several right-hand sides against the same mesh (likeseam_fields()) should assemble once and go throughtet_laplacian()directly instead.- Parameters:
mesh (TetMesh)
dpoints (NDArray[int64])
dvals (NDArray[float64])
- Return type:
NDArray[float64]
- nekmeshpy.tetmesh.ops.seam_fields(mesh, caps)[source]¶
The three conduction fields, one per leg: no-flux on that leg’s cap,
0and1on the other two, shifted to zero mean on the free cap.Exactly
trimesh.ops.seam_fields, with the solve moved into the volume – and the one stiffness assembly shared across all three solves, sincetet_laplacian()is the expensive part at junction resolution.
- nekmeshpy.tetmesh.ops.leg_label(mesh, U)[source]¶
Which leg each tet of
meshbelongs to (1, 2 or 3), from the sign pattern of the three seam fieldsU(n_points, 3)at its centroid – the volumetric form oftrimesh.ops.leg_label, which reads a node’s sign pattern since the surface cut retriangulates; a tet is not split, so its whole-element label comes from the centroid instead.- Parameters:
mesh (TetMesh)
U (NDArray[float64])
- Return type:
NDArray[int64]