feat(topology): Complete topology library with all element types

**Implemented 14 additional topology types with zero-allocation interfaces**

This completes the topology module with all standard FEM element types from
1D to 3D, both linear and quadratic variants.

## New Topologies

### 1D Elements (Segments)
- Seg2: 2-node linear segment
- Seg3: 3-node quadratic segment

### 2D Elements
**Triangles:**
- Tri6: 6-node quadratic triangle
- Tri7: 7-node quadratic triangle (with center node)

**Quadrilaterals:**
- Quad8: 8-node quadratic quad (Serendipity)
- Quad9: 9-node quadratic quad (with center node)

### 3D Elements
**Tetrahedra:**
- Tet4: 4-node linear tetrahedron
- Tet10: 10-node quadratic tetrahedron

**Hexahedra:**
- Hex8: 8-node linear hexahedron
- Hex20: 20-node biquadratic hexahedron (Serendipity)
- Hex27: 27-node quadratic hexahedron (with face/volume nodes)

**Pyramids:**
- Pyr5: 5-node linear pyramid

**Wedges/Prisms:**
- Wedge6: 6-node linear wedge
- Wedge15: 15-node quadratic wedge

## Design Principles

**Zero-allocation throughout:**
- reference_coordinates() → NTuple{N, NTuple{D, Float64}}
- edges() → NTuple{Ne, Tuple{Int, Int}}
- faces() → NTuple{Nf, NTuple{Nn, Int}} or NTuple{Nf, Tuple{Vararg{Int}}}

All topology data is stack-allocated, compile-time sized tuples. No heap
allocations in hot assembly loops.

**Reference coordinates extracted from existing basis files:**
- src/basis/lagrange_segments.jl
- src/basis/lagrange_triangles.jl
- src/basis/lagrange_quadrangles.jl
- src/basis/lagrange_tetrahedrons.jl
- src/basis/lagrange_hexahedrons.jl
- src/basis/lagrange_pyramids.jl
- src/basis/lagrange_wedges.jl

**Complete topology coverage:**
- 1D: linear and quadratic segments
- 2D: triangles (3,6,7 nodes), quads (4,8,9 nodes)
- 3D: tets (4,10), hexes (8,20,27), pyramids (5), wedges (6,15)

This matches the rich set of elements JuliaFEM supported historically.

## Implementation Notes

**Edge/Face Connectivity:**
- edges(): Corner nodes only (defines element boundary)
- faces(): For 2D elements, all nodes; for 3D elements, corner nodes of each face
- Consistent with standard FEM conventions

**Pyramid Special Case:**
- Pyr5 uses Code Aster convention (from lagrange_pyramids.jl)
- Base at z=-1, apex at z=+1
- Mixed face types: 1 quad base + 4 triangular faces

**Wedge/Prism Special Case:**
- Triangular cross-section extruded along w-axis
- Mixed face types: 2 triangular + 3 quadrilateral faces

## Status

Total topology types: 17 (Seg2, Seg3, Tri3, Tri6, Tri7, Quad4, Quad8, Quad9,
Tet4, Tet10, Hex8, Hex20, Hex27, Pyr5, Wedge6, Wedge15)

**Not yet integrated** into src/JuliaFEM.jl (staged approach).

## Next Steps

1. Update topology.jl to export all types
2. Update src/JuliaFEM.jl to include all topology files
3. Add integration rules for all topologies in src/integration/gauss.jl
4. Generate Lagrange basis functions for all topologies

## References

- Existing basis files in src/basis/ (reference coordinate source)
- Abaqus Theory Manual (standard element definitions)
- Code Aster documentation (pyramid element convention)
- TECHNICAL_VISION.md (zero-allocation design philosophy)
This commit is contained in:
Jukka Aho
2025-11-09 05:58:34 +02:00
parent ee02f9f37a
commit d18622d41c
14 changed files with 1042 additions and 0 deletions
+92
View File
@@ -0,0 +1,92 @@
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE
"""
Hex20 <: AbstractTopology
20-node biquadratic hexahedral element.
Reference element in 3D parametric space [-1, 1]³ with corner and edge nodes
(Serendipity family - no face or volume interior nodes).
# Node numbering
```
N8---N20---N7
/| /|
N16| N15|
/ N12 / N11
N5---N17-N6 |
| N4-|--N19--N3
N13 / N14 /
| N9 | N10
|/ |/
N1---N18-N2
```
**Zero allocation:** All functions return compile-time sized tuples.
"""
struct Hex20 <: AbstractTopology end
nnodes(::Hex20) = 20
dim(::Hex20) = 3
"""
reference_coordinates(::Hex20) -> NTuple{20, NTuple{3, Float64}}
Reference coordinates for 20-node hexahedron (Serendipity):
- Corner nodes (8): vertices of [-1,1]³
- Edge nodes (12): midpoints of 12 edges
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
reference_coordinates(::Hex20) = (
(-1.0, -1.0, -1.0), # N1
( 1.0, -1.0, -1.0), # N2
( 1.0, 1.0, -1.0), # N3
(-1.0, 1.0, -1.0), # N4
(-1.0, -1.0, 1.0), # N5
( 1.0, -1.0, 1.0), # N6
( 1.0, 1.0, 1.0), # N7
(-1.0, 1.0, 1.0), # N8
( 0.0, -1.0, -1.0), # N9 (edge 1-2)
( 1.0, 0.0, -1.0), # N10 (edge 2-3)
( 0.0, 1.0, -1.0), # N11 (edge 3-4)
(-1.0, 0.0, -1.0), # N12 (edge 4-1)
(-1.0, -1.0, 0.0), # N13 (edge 1-5)
( 1.0, -1.0, 0.0), # N14 (edge 2-6)
( 1.0, 1.0, 0.0), # N15 (edge 3-7)
(-1.0, 1.0, 0.0), # N16 (edge 4-8)
( 0.0, -1.0, 1.0), # N17 (edge 5-6)
( 1.0, 0.0, 1.0), # N18 (edge 6-7)
( 0.0, 1.0, 1.0), # N19 (edge 7-8)
(-1.0, 0.0, 1.0), # N20 (edge 8-5)
)
"""
edges(::Hex20) -> NTuple{12, Tuple{Int, Int}}
Edge connectivity for hexahedron (corner nodes only).
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
edges(::Hex20) = (
(1, 2), (2, 3), (3, 4), (4, 1), # Bottom face
(5, 6), (6, 7), (7, 8), (8, 5), # Top face
(1, 5), (2, 6), (3, 7), (4, 8), # Vertical edges
)
"""
faces(::Hex20) -> NTuple{6, NTuple{4, Int}}
Face connectivity for hexahedron (corner nodes of 6 quadrilateral faces).
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
faces(::Hex20) = (
(1, 4, 3, 2), # Bottom (-z)
(5, 6, 7, 8), # Top (+z)
(1, 2, 6, 5), # Front (-y)
(3, 4, 8, 7), # Back (+y)
(2, 3, 7, 6), # Right (+x)
(1, 5, 8, 4), # Left (-x)
)
+101
View File
@@ -0,0 +1,101 @@
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE
"""
Hex27 <: AbstractTopology
27-node quadratic hexahedral element.
Reference element in 3D parametric space [-1, 1]³ with corner, edge, face,
and volume center nodes.
# Node numbering
```
N8---N20---N7
/| /|
N16| N26 N15|
/ N12 / N11
N5---N17-N6 |
|N25|N27|N23 N3
N13 N4-N24-N19/
| /N21 | N10
|N9 N14/
N1---N18-N2
```
**Zero allocation:** All functions return compile-time sized tuples.
"""
struct Hex27 <: AbstractTopology end
nnodes(::Hex27) = 27
dim(::Hex27) = 3
"""
reference_coordinates(::Hex27) -> NTuple{27, NTuple{3, Float64}}
Reference coordinates for 27-node hexahedron:
- Corner nodes (8): vertices of [-1,1]³
- Edge nodes (12): midpoints of 12 edges
- Face nodes (6): centers of 6 faces
- Volume node (1): center (0,0,0)
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
reference_coordinates(::Hex27) = (
(-1.0, -1.0, -1.0), # N1
( 1.0, -1.0, -1.0), # N2
( 1.0, 1.0, -1.0), # N3
(-1.0, 1.0, -1.0), # N4
(-1.0, -1.0, 1.0), # N5
( 1.0, -1.0, 1.0), # N6
( 1.0, 1.0, 1.0), # N7
(-1.0, 1.0, 1.0), # N8
( 0.0, -1.0, -1.0), # N9 (edge 1-2)
( 1.0, 0.0, -1.0), # N10 (edge 2-3)
( 0.0, 1.0, -1.0), # N11 (edge 3-4)
(-1.0, 0.0, -1.0), # N12 (edge 4-1)
(-1.0, -1.0, 0.0), # N13 (edge 1-5)
( 1.0, -1.0, 0.0), # N14 (edge 2-6)
( 1.0, 1.0, 0.0), # N15 (edge 3-7)
(-1.0, 1.0, 0.0), # N16 (edge 4-8)
( 0.0, -1.0, 1.0), # N17 (edge 5-6)
( 1.0, 0.0, 1.0), # N18 (edge 6-7)
( 0.0, 1.0, 1.0), # N19 (edge 7-8)
(-1.0, 0.0, 1.0), # N20 (edge 8-5)
( 0.0, 0.0, -1.0), # N21 (face center -z)
( 0.0, -1.0, 0.0), # N22 (face center -y)
( 1.0, 0.0, 0.0), # N23 (face center +x)
( 0.0, 1.0, 0.0), # N24 (face center +y)
(-1.0, 0.0, 0.0), # N25 (face center -x)
( 0.0, 0.0, 1.0), # N26 (face center +z)
( 0.0, 0.0, 0.0), # N27 (volume center)
)
"""
edges(::Hex27) -> NTuple{12, Tuple{Int, Int}}
Edge connectivity for hexahedron (corner nodes only).
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
edges(::Hex27) = (
(1, 2), (2, 3), (3, 4), (4, 1), # Bottom face
(5, 6), (6, 7), (7, 8), (8, 5), # Top face
(1, 5), (2, 6), (3, 7), (4, 8), # Vertical edges
)
"""
faces(::Hex27) -> NTuple{6, NTuple{4, Int}}
Face connectivity for hexahedron (corner nodes of 6 quadrilateral faces).
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
faces(::Hex27) = (
(1, 4, 3, 2), # Bottom (-z)
(5, 6, 7, 8), # Top (+z)
(1, 2, 6, 5), # Front (-y)
(3, 4, 8, 7), # Back (+y)
(2, 3, 7, 6), # Right (+x)
(1, 5, 8, 4), # Left (-x)
)
+75
View File
@@ -0,0 +1,75 @@
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE
"""
Hex8 <: AbstractTopology
8-node linear hexahedral element.
Reference element in 3D parametric space [-1, 1]³.
# Node numbering
```
N8-------N7
/| /|
/ | / |
N5-------N6 |
| N4----|--N3
| / | /
|/ |/
N1-------N2
```
**Zero allocation:** All functions return compile-time sized tuples.
"""
struct Hex8 <: AbstractTopology end
nnodes(::Hex8) = 8
dim(::Hex8) = 3
"""
reference_coordinates(::Hex8) -> NTuple{8, NTuple{3, Float64}}
Reference coordinates for 8-node hexahedron in [-1,1]³.
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
reference_coordinates(::Hex8) = (
(-1.0, -1.0, -1.0), # N1
( 1.0, -1.0, -1.0), # N2
( 1.0, 1.0, -1.0), # N3
(-1.0, 1.0, -1.0), # N4
(-1.0, -1.0, 1.0), # N5
( 1.0, -1.0, 1.0), # N6
( 1.0, 1.0, 1.0), # N7
(-1.0, 1.0, 1.0), # N8
)
"""
edges(::Hex8) -> NTuple{12, Tuple{Int, Int}}
Edge connectivity for hexahedron (12 edges).
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
edges(::Hex8) = (
(1, 2), (2, 3), (3, 4), (4, 1), # Bottom face
(5, 6), (6, 7), (7, 8), (8, 5), # Top face
(1, 5), (2, 6), (3, 7), (4, 8), # Vertical edges
)
"""
faces(::Hex8) -> NTuple{6, NTuple{4, Int}}
Face connectivity for hexahedron (6 quadrilateral faces).
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
faces(::Hex8) = (
(1, 4, 3, 2), # Bottom (-z)
(5, 6, 7, 8), # Top (+z)
(1, 2, 6, 5), # Front (-y)
(3, 4, 8, 7), # Back (+y)
(2, 3, 7, 6), # Right (+x)
(1, 5, 8, 4), # Left (-x)
)
+81
View File
@@ -0,0 +1,81 @@
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE
"""
Pyr5 <: AbstractTopology
5-node linear pyramid element.
Reference element in 3D parametric space with square base at z=-1
and apex at (0,0,1).
# Node numbering
```
N5
/\\
/ \\
/ \\
/ \\
/ \\
N4--------N3
| |
| |
N1--------N2
```
Base nodes in [-1,1]² at z=-1, apex at (0,0,1).
**Note:** This uses Code Aster convention (from lagrange_pyramids.jl).
**Zero allocation:** All functions return compile-time sized tuples.
"""
struct Pyr5 <: AbstractTopology end
nnodes(::Pyr5) = 5
dim(::Pyr5) = 3
"""
reference_coordinates(::Pyr5) -> NTuple{5, NTuple{3, Float64}}
Reference coordinates for 5-node pyramid (Code Aster convention):
- Base nodes: (-1,-1,-1), (1,-1,-1), (1,1,-1), (-1,1,-1)
- Apex: (0,0,1)
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
reference_coordinates(::Pyr5) = (
(-1.0, -1.0, -1.0), # N1
( 1.0, -1.0, -1.0), # N2
( 1.0, 1.0, -1.0), # N3
(-1.0, 1.0, -1.0), # N4
( 0.0, 0.0, 1.0), # N5 (apex)
)
"""
edges(::Pyr5) -> NTuple{8, Tuple{Int, Int}}
Edge connectivity for pyramid (4 base edges + 4 edges to apex = 8 edges).
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
edges(::Pyr5) = (
(1, 2), (2, 3), (3, 4), (4, 1), # Base
(1, 5), (2, 5), (3, 5), (4, 5), # Edges to apex
)
"""
faces(::Pyr5) -> NTuple{5, Tuple{Vararg{Int}}}
Face connectivity for pyramid:
- 1 quadrilateral base
- 4 triangular faces
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
faces(::Pyr5) = (
(1, 4, 3, 2), # Base (quad)
(1, 2, 5), # Triangle
(2, 3, 5), # Triangle
(3, 4, 5), # Triangle
(4, 1, 5), # Triangle
)
+64
View File
@@ -0,0 +1,64 @@
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE
"""
Quad8 <: AbstractTopology
8-node quadratic quadrilateral element (Serendipity).
Reference element in 2D parametric space [-1, 1]² with corner and edge nodes
but no center node (Serendipity family).
# Node numbering
```
N4----N7----N3
| |
N8 N6
| |
N1----N5----N2
```
**Zero allocation:** All functions return compile-time sized tuples.
"""
struct Quad8 <: AbstractTopology end
nnodes(::Quad8) = 8
dim(::Quad8) = 2
"""
reference_coordinates(::Quad8) -> NTuple{8, NTuple{2, Float64}}
Reference coordinates for 8-node quadrilateral (Serendipity):
- Corner nodes: (-1,-1), (1,-1), (1,1), (-1,1)
- Edge nodes: (0,-1), (1,0), (0,1), (-1,0)
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
reference_coordinates(::Quad8) = (
(-1.0, -1.0), # N1
( 1.0, -1.0), # N2
( 1.0, 1.0), # N3
(-1.0, 1.0), # N4
( 0.0, -1.0), # N5
( 1.0, 0.0), # N6
( 0.0, 1.0), # N7
(-1.0, 0.0), # N8
)
"""
edges(::Quad8) -> NTuple{4, Tuple{Int, Int}}
Edge connectivity for quadrilateral (corner nodes only).
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
edges(::Quad8) = ((1, 2), (2, 3), (3, 4), (4, 1))
"""
faces(::Quad8) -> NTuple{1, NTuple{8, Int}}
Face connectivity (all nodes) for 2D element.
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
faces(::Quad8) = ((1, 2, 3, 4, 5, 6, 7, 8),)
+65
View File
@@ -0,0 +1,65 @@
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE
"""
Quad9 <: AbstractTopology
9-node quadratic quadrilateral element.
Reference element in 2D parametric space [-1, 1]² with corner, edge, and center nodes.
# Node numbering
```
N4----N7----N3
| |
N8 N9 N6
| |
N1----N5----N2
```
**Zero allocation:** All functions return compile-time sized tuples.
"""
struct Quad9 <: AbstractTopology end
nnodes(::Quad9) = 9
dim(::Quad9) = 2
"""
reference_coordinates(::Quad9) -> NTuple{9, NTuple{2, Float64}}
Reference coordinates for 9-node quadrilateral:
- Corner nodes: (-1,-1), (1,-1), (1,1), (-1,1)
- Edge nodes: (0,-1), (1,0), (0,1), (-1,0)
- Center node: (0,0)
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
reference_coordinates(::Quad9) = (
(-1.0, -1.0), # N1
( 1.0, -1.0), # N2
( 1.0, 1.0), # N3
(-1.0, 1.0), # N4
( 0.0, -1.0), # N5
( 1.0, 0.0), # N6
( 0.0, 1.0), # N7
(-1.0, 0.0), # N8
( 0.0, 0.0), # N9 (center)
)
"""
edges(::Quad9) -> NTuple{4, Tuple{Int, Int}}
Edge connectivity for quadrilateral (corner nodes only).
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
edges(::Quad9) = ((1, 2), (2, 3), (3, 4), (4, 1))
"""
faces(::Quad9) -> NTuple{1, NTuple{9, Int}}
Face connectivity (all nodes) for 2D element.
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
faces(::Quad9) = ((1, 2, 3, 4, 5, 6, 7, 8, 9),)
+49
View File
@@ -0,0 +1,49 @@
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE
"""
Seg2 <: AbstractTopology
2-node linear segment/line element.
Reference element in 1D parametric space [-1, 1].
# Node numbering
```
N1 -------- N2
-1 +1
```
**Zero allocation:** All functions return compile-time sized tuples.
"""
struct Seg2 <: AbstractTopology end
nnodes(::Seg2) = 2
dim(::Seg2) = 1
"""
reference_coordinates(::Seg2) -> NTuple{2, NTuple{1, Float64}}
Reference coordinates for 2-node segment: (-1.0,) and (1.0,).
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
reference_coordinates(::Seg2) = ((-1.0,), (1.0,))
"""
edges(::Seg2) -> NTuple{1, Tuple{Int, Int}}
Edge connectivity for segment (the segment itself).
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
edges(::Seg2) = ((1, 2),)
"""
faces(::Seg2) -> NTuple{0, Tuple{}}
Faces for 1D element (none in 1D).
**Zero allocation:** Returns empty tuple (stack allocated).
"""
faces(::Seg2) = ()
+49
View File
@@ -0,0 +1,49 @@
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE
"""
Seg3 <: AbstractTopology
3-node quadratic segment/line element.
Reference element in 1D parametric space [-1, 1] with midpoint node.
# Node numbering
```
N1 ---- N3 ---- N2
-1 0 +1
```
**Zero allocation:** All functions return compile-time sized tuples.
"""
struct Seg3 <: AbstractTopology end
nnodes(::Seg3) = 3
dim(::Seg3) = 1
"""
reference_coordinates(::Seg3) -> NTuple{3, NTuple{1, Float64}}
Reference coordinates for 3-node segment: (-1.0,), (1.0,), (0.0,).
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
reference_coordinates(::Seg3) = ((-1.0,), (1.0,), (0.0,))
"""
edges(::Seg3) -> NTuple{1, Tuple{Int, Int}}
Edge connectivity for segment (the segment itself, corner nodes only).
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
edges(::Seg3) = ((1, 2),)
"""
faces(::Seg3) -> NTuple{0, Tuple{}}
Faces for 1D element (none in 1D).
**Zero allocation:** Returns empty tuple (stack allocated).
"""
faces(::Seg3) = ()
+82
View File
@@ -0,0 +1,82 @@
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE
"""
Tet10 <: AbstractTopology
10-node quadratic tetrahedral element.
Reference element in 3D parametric space with corner nodes at vertices
and midpoint nodes on each edge.
# Node numbering
```
N4
/|\\
N8 | N10
/ N9 \\
/ | \\
/ | \\
N1-N5--N7----N3
\\ | /
\\ | /
\\ N6 /
\\ | /
\\|/
N2
```
**Zero allocation:** All functions return compile-time sized tuples.
"""
struct Tet10 <: AbstractTopology end
nnodes(::Tet10) = 10
dim(::Tet10) = 3
"""
reference_coordinates(::Tet10) -> NTuple{10, NTuple{3, Float64}}
Reference coordinates for 10-node tetrahedron:
- Corner nodes: (0,0,0), (1,0,0), (0,1,0), (0,0,1)
- Edge nodes: midpoints of all 6 edges
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
reference_coordinates(::Tet10) = (
(0.0, 0.0, 0.0), # N1
(1.0, 0.0, 0.0), # N2
(0.0, 1.0, 0.0), # N3
(0.0, 0.0, 1.0), # N4
(0.5, 0.0, 0.0), # N5 (edge 1-2)
(0.5, 0.5, 0.0), # N6 (edge 2-3)
(0.0, 0.5, 0.0), # N7 (edge 3-1)
(0.0, 0.0, 0.5), # N8 (edge 1-4)
(0.5, 0.0, 0.5), # N9 (edge 2-4)
(0.0, 0.5, 0.5), # N10 (edge 3-4)
)
"""
edges(::Tet10) -> NTuple{6, Tuple{Int, Int}}
Edge connectivity for tetrahedron (corner nodes only).
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
edges(::Tet10) = (
(1, 2), (2, 3), (3, 1), # Base triangle
(1, 4), (2, 4), (3, 4), # Edges to apex
)
"""
faces(::Tet10) -> NTuple{4, NTuple{3, Int}}
Face connectivity for tetrahedron (corner nodes of 4 triangular faces).
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
faces(::Tet10) = (
(1, 3, 2), # Base
(1, 2, 4), # Front
(2, 3, 4), # Right
(3, 1, 4), # Left
)
+74
View File
@@ -0,0 +1,74 @@
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE
"""
Tet4 <: AbstractTopology
4-node linear tetrahedral element.
Reference element in 3D parametric space with vertices at (0,0,0), (1,0,0), (0,1,0), (0,0,1).
# Node numbering
```
N4
/|\\
/ | \\
/ | \\
/ | \\
/ | \\
N1-----|-----N3
\\ | /
\\ | /
\\ | /
\\ | /
\\|/
N2
```
**Zero allocation:** All functions return compile-time sized tuples.
"""
struct Tet4 <: AbstractTopology end
nnodes(::Tet4) = 4
dim(::Tet4) = 3
"""
reference_coordinates(::Tet4) -> NTuple{4, NTuple{3, Float64}}
Reference coordinates for 4-node tetrahedron:
(0,0,0), (1,0,0), (0,1,0), (0,0,1).
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
reference_coordinates(::Tet4) = (
(0.0, 0.0, 0.0), # N1
(1.0, 0.0, 0.0), # N2
(0.0, 1.0, 0.0), # N3
(0.0, 0.0, 1.0), # N4
)
"""
edges(::Tet4) -> NTuple{6, Tuple{Int, Int}}
Edge connectivity for tetrahedron (6 edges).
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
edges(::Tet4) = (
(1, 2), (2, 3), (3, 1), # Base triangle
(1, 4), (2, 4), (3, 4), # Edges to apex
)
"""
faces(::Tet4) -> NTuple{4, NTuple{3, Int}}
Face connectivity for tetrahedron (4 triangular faces).
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
faces(::Tet4) = (
(1, 3, 2), # Base
(1, 2, 4), # Front
(2, 3, 4), # Right
(3, 1, 4), # Left
)
+64
View File
@@ -0,0 +1,64 @@
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE
"""
Tri6 <: AbstractTopology
6-node quadratic triangle element.
Reference element in 2D parametric space with vertices at (0,0), (1,0), (0,1)
and midpoint nodes on each edge.
# Node numbering
```
N3
|\\
| \\
N6 N5
| \\
| \\
N1--N4--N2
```
**Zero allocation:** All functions return compile-time sized tuples.
"""
struct Tri6 <: AbstractTopology end
nnodes(::Tri6) = 6
dim(::Tri6) = 2
"""
reference_coordinates(::Tri6) -> NTuple{6, NTuple{2, Float64}}
Reference coordinates for 6-node triangle:
- Corner nodes: (0,0), (1,0), (0,1)
- Edge nodes: (0.5,0), (0.5,0.5), (0,0.5)
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
reference_coordinates(::Tri6) = (
(0.0, 0.0), # N1
(1.0, 0.0), # N2
(0.0, 1.0), # N3
(0.5, 0.0), # N4
(0.5, 0.5), # N5
(0.0, 0.5), # N6
)
"""
edges(::Tri6) -> NTuple{3, Tuple{Int, Int}}
Edge connectivity for triangle (corner nodes only).
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
edges(::Tri6) = ((1, 2), (2, 3), (3, 1))
"""
faces(::Tri6) -> NTuple{1, NTuple{6, Int}}
Face connectivity (all nodes) for 2D element.
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
faces(::Tri6) = ((1, 2, 3, 4, 5, 6),)
+66
View File
@@ -0,0 +1,66 @@
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE
"""
Tri7 <: AbstractTopology
7-node quadratic triangle element with center node.
Reference element in 2D parametric space with vertices at (0,0), (1,0), (0,1),
midpoint nodes on each edge, and center node.
# Node numbering
```
N3
|\\
| \\
N6 N7 N5
| \\
| \\
N1--N4--N2
```
**Zero allocation:** All functions return compile-time sized tuples.
"""
struct Tri7 <: AbstractTopology end
nnodes(::Tri7) = 7
dim(::Tri7) = 2
"""
reference_coordinates(::Tri7) -> NTuple{7, NTuple{2, Float64}}
Reference coordinates for 7-node triangle:
- Corner nodes: (0,0), (1,0), (0,1)
- Edge nodes: (0.5,0), (0.5,0.5), (0,0.5)
- Center node: (1/3, 1/3)
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
reference_coordinates(::Tri7) = (
(0.0, 0.0), # N1
(1.0, 0.0), # N2
(0.0, 1.0), # N3
(0.5, 0.0), # N4
(0.5, 0.5), # N5
(0.0, 0.5), # N6
(1/3, 1/3), # N7 (center)
)
"""
edges(::Tri7) -> NTuple{3, Tuple{Int, Int}}
Edge connectivity for triangle (corner nodes only).
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
edges(::Tri7) = ((1, 2), (2, 3), (3, 1))
"""
faces(::Tri7) -> NTuple{1, NTuple{7, Int}}
Face connectivity (all nodes) for 2D element.
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
faces(::Tri7) = ((1, 2, 3, 4, 5, 6, 7),)
+94
View File
@@ -0,0 +1,94 @@
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE
"""
Wedge15 <: AbstractTopology
15-node quadratic prismatic/wedge element.
Reference element in 3D with triangular cross-section in (u,v) plane
extruded along w direction, with edge and mid-plane nodes.
# Node numbering
```
N6
/\\
N12 N11
/ \\
N4-N10-N5
| |
N15 N14
| |
N3 |
|\\ |
N9 N8 |
| \\ N13
| \\ |
| \\ |
| \\|
N1--N7--N2
```
**Zero allocation:** All functions return compile-time sized tuples.
"""
struct Wedge15 <: AbstractTopology end
nnodes(::Wedge15) = 15
dim(::Wedge15) = 3
"""
reference_coordinates(::Wedge15) -> NTuple{15, NTuple{3, Float64}}
Reference coordinates for 15-node wedge:
- Corner nodes (6): bottom and top triangles
- Edge nodes (9): 3 on bottom, 3 on top, 3 on vertical edges
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
reference_coordinates(::Wedge15) = (
(0.0, 0.0, -1.0), # N1
(1.0, 0.0, -1.0), # N2
(0.0, 1.0, -1.0), # N3
(0.0, 0.0, 1.0), # N4
(1.0, 0.0, 1.0), # N5
(0.0, 1.0, 1.0), # N6
(0.5, 0.0, -1.0), # N7 (edge 1-2, bottom)
(0.5, 0.5, -1.0), # N8 (edge 2-3, bottom)
(0.0, 0.5, -1.0), # N9 (edge 3-1, bottom)
(0.5, 0.0, 1.0), # N10 (edge 4-5, top)
(0.5, 0.5, 1.0), # N11 (edge 5-6, top)
(0.0, 0.5, 1.0), # N12 (edge 6-4, top)
(0.0, 0.0, 0.0), # N13 (edge 1-4, vertical)
(1.0, 0.0, 0.0), # N14 (edge 2-5, vertical)
(0.0, 1.0, 0.0), # N15 (edge 3-6, vertical)
)
"""
edges(::Wedge15) -> NTuple{9, Tuple{Int, Int}}
Edge connectivity for wedge (corner nodes only).
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
edges(::Wedge15) = (
(1, 2), (2, 3), (3, 1), # Bottom triangle
(4, 5), (5, 6), (6, 4), # Top triangle
(1, 4), (2, 5), (3, 6), # Vertical edges
)
"""
faces(::Wedge15) -> NTuple{5, Tuple{Vararg{Int}}}
Face connectivity for wedge (corner nodes only):
- 2 triangular faces
- 3 quadrilateral faces
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
faces(::Wedge15) = (
(1, 3, 2), # Bottom triangle
(4, 5, 6), # Top triangle
(1, 2, 5, 4), # Side quad
(2, 3, 6, 5), # Side quad
(3, 1, 4, 6), # Side quad
)
+86
View File
@@ -0,0 +1,86 @@
# This file is a part of JuliaFEM.
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE
"""
Wedge6 <: AbstractTopology
6-node linear prismatic/wedge element.
Reference element in 3D with triangular cross-section in (u,v) plane
extruded along w direction from -1 to +1.
# Node numbering
```
N6
/\\
/ \\
/ \\
N4----N5
| |
| |
N3 |
|\\ |
| \\ |
| \\ |
| \\ |
| \\ |
| \\|
N1-----N2
```
Triangle base at w=-1, triangle top at w=+1.
**Zero allocation:** All functions return compile-time sized tuples.
"""
struct Wedge6 <: AbstractTopology end
nnodes(::Wedge6) = 6
dim(::Wedge6) = 3
"""
reference_coordinates(::Wedge6) -> NTuple{6, NTuple{3, Float64}}
Reference coordinates for 6-node wedge:
- Bottom triangle (w=-1): (0,0,-1), (1,0,-1), (0,1,-1)
- Top triangle (w=+1): (0,0,+1), (1,0,+1), (0,1,+1)
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
reference_coordinates(::Wedge6) = (
(0.0, 0.0, -1.0), # N1
(1.0, 0.0, -1.0), # N2
(0.0, 1.0, -1.0), # N3
(0.0, 0.0, 1.0), # N4
(1.0, 0.0, 1.0), # N5
(0.0, 1.0, 1.0), # N6
)
"""
edges(::Wedge6) -> NTuple{9, Tuple{Int, Int}}
Edge connectivity for wedge (3 bottom + 3 top + 3 vertical = 9 edges).
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
edges(::Wedge6) = (
(1, 2), (2, 3), (3, 1), # Bottom triangle
(4, 5), (5, 6), (6, 4), # Top triangle
(1, 4), (2, 5), (3, 6), # Vertical edges
)
"""
faces(::Wedge6) -> NTuple{5, Tuple{Vararg{Int}}}
Face connectivity for wedge:
- 2 triangular faces (top and bottom)
- 3 quadrilateral faces (sides)
**Zero allocation:** Returns tuple of tuples (stack allocated).
"""
faces(::Wedge6) = (
(1, 3, 2), # Bottom triangle
(4, 5, 6), # Top triangle
(1, 2, 5, 4), # Side quad
(2, 3, 6, 5), # Side quad
(3, 1, 4, 6), # Side quad
)