From c6f18d040fbe319686d15850ab43f349c18a7742 Mon Sep 17 00:00:00 2001 From: Jukka Aho Date: Sat, 22 Nov 2025 12:06:40 +0200 Subject: [PATCH] feat(basis): Add basis_descriptions.jl catalog for code generation Create centralized catalog of 14 basis element descriptions for automatic code generation. Each description specifies: - Topology type (Segment, Triangle, Quadrilateral, Tetrahedron, Hexahedron, etc.) - Basis family (Lagrange{order}, Serendipity{order}) - Polynomial ansatz for Vandermonde system Covers standard finite elements: - 1D: Seg2, Seg3 - 2D: Tri3, Tri6, Quad4, Quad8, Quad9 - 3D: Tet4, Tet10, Hex8, Hex20, Hex27, Pyr5, Wedge6 Uses canonical topology types (Triangle{3}, Quadrilateral{9}) instead of legacy aliases (Tri3, Quad9) for clarity and consistency. --- src/basis/basis_descriptions.jl | 155 ++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 src/basis/basis_descriptions.jl diff --git a/src/basis/basis_descriptions.jl b/src/basis/basis_descriptions.jl new file mode 100644 index 0000000..f98e968 --- /dev/null +++ b/src/basis/basis_descriptions.jl @@ -0,0 +1,155 @@ +# Catalog of basis descriptions used by the generator. +# +# Each entry provides: +# - name: legacy short name (e.g., "Tri3") +# - description: human-readable text +# - topology: reference topology type (with node count parameter) +# - basis: basis family and order (Lagrange{P}, Serendipity{P}, etc.) +# - ansatz: polynomial terms used to build the Vandermonde system + +const BASIS_DESCRIPTIONS = VandermondeBasisDescription[] + +# 1D SEGMENTS +push!(BASIS_DESCRIPTIONS, VandermondeBasisDescription( + name="Seg2", + description="2-node linear segment element", + family=Lagrange{1}, + topology=Segment{2}, + ansatz=(:(1), :(u)) +)) + +push!(BASIS_DESCRIPTIONS, VandermondeBasisDescription( + name="Seg3", + description="3-node quadratic segment element", + family=Lagrange{2}, + topology=Segment{3}, + ansatz=(:(1), :(u), :(u^2)) +)) + +# 2D TRIANGLES +push!(BASIS_DESCRIPTIONS, VandermondeBasisDescription( + name="Tri3", + description="3-node linear triangular element", + family=Lagrange{1}, + topology=Triangle{3}, + ansatz=(:(1), :(u), :(v)) +)) + +push!(BASIS_DESCRIPTIONS, VandermondeBasisDescription( + name="Tri6", + description="6-node quadratic triangular element", + family=Lagrange{2}, + topology=Triangle{6}, + ansatz=(:(1), :(u), :(v), :(u^2), :(u * v), :(v^2)) +)) + +# 2D QUADS +push!(BASIS_DESCRIPTIONS, VandermondeBasisDescription( + name="Quad4", + description="4-node bilinear quadrilateral element", + family=Lagrange{1}, + topology=Quadrilateral{4}, + ansatz=(:(1), :(u), :(v), :(u * v)) +)) + +push!(BASIS_DESCRIPTIONS, VandermondeBasisDescription( + name="Quad8", + description="8-node serendipity quadrilateral element", + family=Serendipity{2}, + topology=Quadrilateral{8}, + ansatz=(:(1), :(u), :(v), :(u^2), :(u * v), :(v^2), :(u^2 * v), :(u * v^2)) +)) + +push!(BASIS_DESCRIPTIONS, VandermondeBasisDescription( + name="Quad9", + description="9-node biquadratic quadrilateral element", + family=Lagrange{2}, + topology=Quadrilateral{9}, + ansatz=(:(1), :(u), :(v), :(u^2), :(u * v), :(v^2), :(u^2 * v), :(u * v^2), :(u^2 * v^2)) +)) + +# 3D TETS +push!(BASIS_DESCRIPTIONS, VandermondeBasisDescription( + name="Tet4", + description="4-node linear tetrahedral element", + family=Lagrange{1}, + topology=Tetrahedron{4}, + ansatz=(:(1), :(u), :(v), :(w)) +)) + +push!(BASIS_DESCRIPTIONS, VandermondeBasisDescription( + name="Tet10", + description="10-node quadratic tetrahedral element", + family=Lagrange{2}, + topology=Tetrahedron{10}, + ansatz=(:(1), :(u), :(v), :(w), :(u^2), :(v^2), :(w^2), :(u * v), :(u * w), :(v * w)) +)) + +# 3D HEXES +push!(BASIS_DESCRIPTIONS, VandermondeBasisDescription( + name="Hex8", + description="8-node trilinear hexahedral element", + family=Lagrange{1}, + topology=Hexahedron{8}, + ansatz=(:(1), :(u), :(v), :(w), :(u * v), :(u * w), :(v * w), :(u * v * w)) +)) + +push!(BASIS_DESCRIPTIONS, VandermondeBasisDescription( + name="Hex20", + description="20-node serendipity hexahedral element", + family=Serendipity{2}, + topology=Hexahedron{20}, + ansatz=( + :(1), :(u), :(v), :(w), + :(u * v), :(u * w), :(v * w), + :(u^2), :(v^2), :(w^2), + :(u^2 * v), :(u * v^2), :(u^2 * w), :(u * w^2), :(v^2 * w), :(v * w^2) + ) +)) + +push!(BASIS_DESCRIPTIONS, VandermondeBasisDescription( + name="Hex27", + description="27-node triquadratic hexahedral element", + family=Lagrange{2}, + topology=Hexahedron{27}, + ansatz=( + :(1), :(u), :(v), :(w), + :(u^2), :(v^2), :(w^2), + :(u * v), :(u * w), :(v * w), + :(u^2 * v), :(u * v^2), :(u^2 * w), :(u * w^2), :(v^2 * w), :(v * w^2), + :(u^2 * v^2), :(u^2 * w^2), :(v^2 * w^2), + :(u^2 * v * w), :(u * v^2 * w), :(u * v * w^2), :(u^2 * v^2 * w^2) + ) +)) + +# 3D PYRAMID +push!(BASIS_DESCRIPTIONS, VandermondeBasisDescription( + name="Pyr5", + description="5-node linear pyramid element", + family=Lagrange{1}, + topology=Pyramid{5}, + ansatz=(:(1), :(u), :(v), :(w)) +)) + +# 3D WEDGE / PRISM +push!(BASIS_DESCRIPTIONS, VandermondeBasisDescription( + name="Wedge6", + description="6-node linear wedge (prism) element", + family=Lagrange{1}, + topology=Wedge{6}, + ansatz=(:(1), :(u), :(v), :(w), :(u * w), :(v * w)) +)) + +# TODO: Wedge15 ansatz needs proper polynomial basis for triangular prism +# The standard Lagrange tensor product doesn't work - need special formulation +# push!(BASIS_DESCRIPTIONS, VandermondeBasisDescription( +# name="Wedge15", +# description="15-node quadratic wedge (prism) element", +# family=Lagrange{2}, +# topology=Wedge{15}, +# ansatz=( +# :(1), :(u), :(v), :(w), +# :(u^2), :(v^2), :(w^2), :(u * v), :(u * w), :(v * w), +# :(u^2 * w), :(v^2 * w), :(u * v * w), :(u^2 * v), :(u * v^2) +# ) +# ))