mirror of
https://github.com/JuliaFEM/JuliaFEM.jl.git
synced 2026-09-17 09:12:09 +00:00
e0d81543f6
Deleted files:
- src/basis/lagrange_generated.jl (451 lines) - Old generated basis implementations
- src/basis/lagrange_generator.jl (904 lines) - Old generator with complex dispatch
New files:
- src/basis/basis_generated.jl (461 lines) - New generated implementations using get_basis_functions/derivatives API
- src/basis/basis_generator.jl (622 lines) - Simplified generator with VandermondeBasisDescription
Key changes:
- Generator: Simplified from 904 → 622 lines, removed complex dispatch logic
- Generated: New API using get_basis_functions(topology, Lagrange{P}, xi) instead of eval_basis!(Lagrange{T,P}, xi)
- Return types: NTuple → SVector for type stability and StaticArrays compatibility
- Numerical filtering: Added round_coefficient for clean fractions (1/2, 1/3, 1/18, etc.)
- Basis descriptions: Uses VandermondeBasisDescription for element metadata
Net result: 1355 lines removed, 1083 lines added (272 line reduction with cleaner design)
462 lines
39 KiB
Julia
462 lines
39 KiB
Julia
# This file is a part of JuliaFEM.
|
|
# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE
|
|
|
|
# ============================================================================
|
|
# AUTO-GENERATED BASIS FUNCTIONS (All Families)
|
|
# ============================================================================
|
|
# Generated by: src/basis/basis_generator.jl
|
|
# WARNING: DO NOT EDIT MANUALLY
|
|
#
|
|
# This file contains generated basis function implementations for:
|
|
# - Lagrange bases (standard nodal interpolation)
|
|
# - Serendipity bases (reduced tensor-product for quads/hexes)
|
|
# - Future: Hierarchical, modal, and exotic basis families
|
|
#
|
|
# Return Types:
|
|
# get_basis_functions → SVector{N, Float64}
|
|
# get_basis_derivatives → SVector{N, Vec{D, Float64}}
|
|
#
|
|
# Why SVector? Enables natural vector operations:
|
|
# u_interp = dot(node_values, N)
|
|
# grad_u = sum(node_values[i] * dN[i] for i in 1:N)
|
|
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
# Lagrange{1} on Seg2: 2-node linear segment element
|
|
# (legacy name: Seg2)
|
|
|
|
@inline function get_basis_functions(::Seg2, ::Lagrange{1}, xi::Vec{1, T}) where T
|
|
(u,) = xi
|
|
N1 = 1/2 - 1/2 * u
|
|
N2 = 1/2 + 1/2 * u
|
|
return SVector{2, T}(N1, N2)
|
|
end
|
|
|
|
@inline function get_basis_derivatives(::Seg2, ::Lagrange{1}, xi::Vec{1, T}) where T
|
|
(u,) = xi
|
|
dN1 = Vec{1, T}((-1/2,))
|
|
dN2 = Vec{1, T}((1/2,))
|
|
return SVector{2, Vec{1, T}}(dN1, dN2)
|
|
end
|
|
|
|
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
# Lagrange{2} on Seg3: 3-node quadratic segment element
|
|
# (legacy name: Seg3)
|
|
|
|
@inline function get_basis_functions(::Seg3, ::Lagrange{2}, xi::Vec{1, T}) where T
|
|
(u,) = xi
|
|
N1 = -1/2 * u + 1/2 * u ^ 2
|
|
N2 = 1/2 * u + 1/2 * u ^ 2
|
|
N3 = 1 - u ^ 2
|
|
return SVector{3, T}(N1, N2, N3)
|
|
end
|
|
|
|
@inline function get_basis_derivatives(::Seg3, ::Lagrange{2}, xi::Vec{1, T}) where T
|
|
(u,) = xi
|
|
dN1 = Vec{1, T}((-1/2 + u,))
|
|
dN2 = Vec{1, T}((1/2 + u,))
|
|
dN3 = Vec{1, T}((-2 * u,))
|
|
return SVector{3, Vec{1, T}}(dN1, dN2, dN3)
|
|
end
|
|
|
|
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
# Lagrange{1} on Tri3: 3-node linear triangular element
|
|
# (legacy name: Tri3)
|
|
|
|
@inline function get_basis_functions(::Tri3, ::Lagrange{1}, xi::Vec{2, T}) where T
|
|
(u, v) = xi
|
|
N1 = 1 - u - v
|
|
N2 = u
|
|
N3 = v
|
|
return SVector{3, T}(N1, N2, N3)
|
|
end
|
|
|
|
@inline function get_basis_derivatives(::Tri3, ::Lagrange{1}, xi::Vec{2, T}) where T
|
|
(u, v) = xi
|
|
dN1 = Vec{2, T}((-1, -1))
|
|
dN2 = Vec{2, T}((1, 0))
|
|
dN3 = Vec{2, T}((0, 1))
|
|
return SVector{3, Vec{2, T}}(dN1, dN2, dN3)
|
|
end
|
|
|
|
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
# Lagrange{2} on Tri6: 6-node quadratic triangular element
|
|
# (legacy name: Tri6)
|
|
|
|
@inline function get_basis_functions(::Tri6, ::Lagrange{2}, xi::Vec{2, T}) where T
|
|
(u, v) = xi
|
|
N1 = 1 - 3 * u - 3 * v + 2 * u ^ 2 + 4 * u * v + 2 * v ^ 2
|
|
N2 = -u + 2 * u ^ 2
|
|
N3 = -v + 2 * v ^ 2
|
|
N4 = 4 * u - 4 * u ^ 2 - 4 * u * v
|
|
N5 = 4 * u * v
|
|
N6 = 4 * v - 4 * u * v - 4 * v ^ 2
|
|
return SVector{6, T}(N1, N2, N3, N4, N5, N6)
|
|
end
|
|
|
|
@inline function get_basis_derivatives(::Tri6, ::Lagrange{2}, xi::Vec{2, T}) where T
|
|
(u, v) = xi
|
|
dN1 = Vec{2, T}((-3 + 4 * u + 4 * v, -3 + 4 * u + 4 * v))
|
|
dN2 = Vec{2, T}((-1 + 4 * u, 0))
|
|
dN3 = Vec{2, T}((0, -1 + 4 * v))
|
|
dN4 = Vec{2, T}((4 - 8 * u - 4 * v, -4 * u))
|
|
dN5 = Vec{2, T}((4 * v, 4 * u))
|
|
dN6 = Vec{2, T}((-4 * v, 4 - 4 * u - 8 * v))
|
|
return SVector{6, Vec{2, T}}(dN1, dN2, dN3, dN4, dN5, dN6)
|
|
end
|
|
|
|
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
# Lagrange{1} on Quad4: 4-node bilinear quadrilateral element
|
|
# (legacy name: Quad4)
|
|
|
|
@inline function get_basis_functions(::Quad4, ::Lagrange{1}, xi::Vec{2, T}) where T
|
|
(u, v) = xi
|
|
N1 = 1/4 - 1/4 * u - 1/4 * v + 1/4 * u * v
|
|
N2 = 1/4 + 1/4 * u - 1/4 * v - 1/4 * u * v
|
|
N3 = 1/4 + 1/4 * u + 1/4 * v + 1/4 * u * v
|
|
N4 = 1/4 - 1/4 * u + 1/4 * v - 1/4 * u * v
|
|
return SVector{4, T}(N1, N2, N3, N4)
|
|
end
|
|
|
|
@inline function get_basis_derivatives(::Quad4, ::Lagrange{1}, xi::Vec{2, T}) where T
|
|
(u, v) = xi
|
|
dN1 = Vec{2, T}((-1/4 + 1/4 * v, -1/4 + 1/4 * u))
|
|
dN2 = Vec{2, T}((1/4 - 1/4 * v, -1/4 - 1/4 * u))
|
|
dN3 = Vec{2, T}((1/4 + 1/4 * v, 1/4 + 1/4 * u))
|
|
dN4 = Vec{2, T}((-1/4 - 1/4 * v, 1/4 - 1/4 * u))
|
|
return SVector{4, Vec{2, T}}(dN1, dN2, dN3, dN4)
|
|
end
|
|
|
|
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
# Serendipity{2} on Quad8: 8-node serendipity quadrilateral element
|
|
# (legacy name: Quad8)
|
|
|
|
@inline function get_basis_functions(::Quad8, ::Serendipity{2}, xi::Vec{2, T}) where T
|
|
(u, v) = xi
|
|
N1 = -1/4 + 1/4 * u ^ 2 + 1/4 * u * v + 1/4 * v ^ 2 - 1/4 * u ^ 2 * v - 1/4 * u * v ^ 2
|
|
N2 = -1/4 + 1/4 * u ^ 2 - 1/4 * u * v + 1/4 * v ^ 2 - 1/4 * u ^ 2 * v + 1/4 * u * v ^ 2
|
|
N3 = -1/4 + 1/4 * u ^ 2 + 1/4 * u * v + 1/4 * v ^ 2 + 1/4 * u ^ 2 * v + 1/4 * u * v ^ 2
|
|
N4 = -1/4 + 1/4 * u ^ 2 - 1/4 * u * v + 1/4 * v ^ 2 + 1/4 * u ^ 2 * v - 1/4 * u * v ^ 2
|
|
N5 = 1/2 - 1/2 * v - 1/2 * u ^ 2 + 1/2 * u ^ 2 * v
|
|
N6 = 1/2 + 1/2 * u - 1/2 * v ^ 2 - 1/2 * u * v ^ 2
|
|
N7 = 1/2 + 1/2 * v - 1/2 * u ^ 2 - 1/2 * u ^ 2 * v
|
|
N8 = 1/2 - 1/2 * u - 1/2 * v ^ 2 + 1/2 * u * v ^ 2
|
|
return SVector{8, T}(N1, N2, N3, N4, N5, N6, N7, N8)
|
|
end
|
|
|
|
@inline function get_basis_derivatives(::Quad8, ::Serendipity{2}, xi::Vec{2, T}) where T
|
|
(u, v) = xi
|
|
dN1 = Vec{2, T}((1/2 * u + 1/4 * v - 1/2 * u * v - 1/4 * v ^ 2, 1/4 * u + 1/2 * v - 1/4 * u ^ 2 - 1/2 * u * v))
|
|
dN2 = Vec{2, T}((1/2 * u - 1/4 * v - 1/2 * u * v + 1/4 * v ^ 2, -1/4 * u + 1/2 * v - 1/4 * u ^ 2 + 1/2 * u * v))
|
|
dN3 = Vec{2, T}((1/2 * u + 1/4 * v + 1/2 * u * v + 1/4 * v ^ 2, 1/4 * u + 1/2 * v + 1/4 * u ^ 2 + 1/2 * u * v))
|
|
dN4 = Vec{2, T}((1/2 * u - 1/4 * v + 1/2 * u * v - 1/4 * v ^ 2, -1/4 * u + 1/2 * v + 1/4 * u ^ 2 - 1/2 * u * v))
|
|
dN5 = Vec{2, T}((-u + u * v, -1/2 + 1/2 * u ^ 2))
|
|
dN6 = Vec{2, T}((1/2 - 1/2 * v ^ 2, -v - u * v))
|
|
dN7 = Vec{2, T}((-u - u * v, 1/2 - 1/2 * u ^ 2))
|
|
dN8 = Vec{2, T}((-1/2 + 1/2 * v ^ 2, -v + u * v))
|
|
return SVector{8, Vec{2, T}}(dN1, dN2, dN3, dN4, dN5, dN6, dN7, dN8)
|
|
end
|
|
|
|
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
# Lagrange{2} on Quad9: 9-node biquadratic quadrilateral element
|
|
# (legacy name: Quad9)
|
|
|
|
@inline function get_basis_functions(::Quad9, ::Lagrange{2}, xi::Vec{2, T}) where T
|
|
(u, v) = xi
|
|
N1 = 1/4 * u * v - 1/4 * u ^ 2 * v - 1/4 * u * v ^ 2 + 1/4 * u ^ 2 * v ^ 2
|
|
N2 = -1/4 * u * v - 1/4 * u ^ 2 * v + 1/4 * u * v ^ 2 + 1/4 * u ^ 2 * v ^ 2
|
|
N3 = 1/4 * u * v + 1/4 * u ^ 2 * v + 1/4 * u * v ^ 2 + 1/4 * u ^ 2 * v ^ 2
|
|
N4 = -1/4 * u * v + 1/4 * u ^ 2 * v - 1/4 * u * v ^ 2 + 1/4 * u ^ 2 * v ^ 2
|
|
N5 = -1/2 * v + 1/2 * v ^ 2 + 1/2 * u ^ 2 * v - 1/2 * u ^ 2 * v ^ 2
|
|
N6 = 1/2 * u + 1/2 * u ^ 2 - 1/2 * u * v ^ 2 - 1/2 * u ^ 2 * v ^ 2
|
|
N7 = 1/2 * v + 1/2 * v ^ 2 - 1/2 * u ^ 2 * v - 1/2 * u ^ 2 * v ^ 2
|
|
N8 = -1/2 * u + 1/2 * u ^ 2 + 1/2 * u * v ^ 2 - 1/2 * u ^ 2 * v ^ 2
|
|
N9 = 1 - u ^ 2 - v ^ 2 + u ^ 2 * v ^ 2
|
|
return SVector{9, T}(N1, N2, N3, N4, N5, N6, N7, N8, N9)
|
|
end
|
|
|
|
@inline function get_basis_derivatives(::Quad9, ::Lagrange{2}, xi::Vec{2, T}) where T
|
|
(u, v) = xi
|
|
dN1 = Vec{2, T}((1/4 * v - 1/2 * u * v - 1/4 * v ^ 2 + 1/2 * u * v ^ 2, 1/4 * u - 1/4 * u ^ 2 - 1/2 * u * v + 1/2 * u ^ 2 * v))
|
|
dN2 = Vec{2, T}((-1/4 * v - 1/2 * u * v + 1/4 * v ^ 2 + 1/2 * u * v ^ 2, -1/4 * u - 1/4 * u ^ 2 + 1/2 * u * v + 1/2 * u ^ 2 * v))
|
|
dN3 = Vec{2, T}((1/4 * v + 1/2 * u * v + 1/4 * v ^ 2 + 1/2 * u * v ^ 2, 1/4 * u + 1/4 * u ^ 2 + 1/2 * u * v + 1/2 * u ^ 2 * v))
|
|
dN4 = Vec{2, T}((-1/4 * v + 1/2 * u * v - 1/4 * v ^ 2 + 1/2 * u * v ^ 2, -1/4 * u + 1/4 * u ^ 2 - 1/2 * u * v + 1/2 * u ^ 2 * v))
|
|
dN5 = Vec{2, T}((u * v - u * v ^ 2, -1/2 + v + 1/2 * u ^ 2 - u ^ 2 * v))
|
|
dN6 = Vec{2, T}((1/2 + u - 1/2 * v ^ 2 - u * v ^ 2, -u * v - u ^ 2 * v))
|
|
dN7 = Vec{2, T}((-u * v - u * v ^ 2, 1/2 + v - 1/2 * u ^ 2 - u ^ 2 * v))
|
|
dN8 = Vec{2, T}((-1/2 + u + 1/2 * v ^ 2 - u * v ^ 2, u * v - u ^ 2 * v))
|
|
dN9 = Vec{2, T}((-2 * u + 2 * u * v ^ 2, -2 * v + 2 * u ^ 2 * v))
|
|
return SVector{9, Vec{2, T}}(dN1, dN2, dN3, dN4, dN5, dN6, dN7, dN8, dN9)
|
|
end
|
|
|
|
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
# Lagrange{1} on Tet4: 4-node linear tetrahedral element
|
|
# (legacy name: Tet4)
|
|
|
|
@inline function get_basis_functions(::Tet4, ::Lagrange{1}, xi::Vec{3, T}) where T
|
|
(u, v, w) = xi
|
|
N1 = 1 - u - v - w
|
|
N2 = u
|
|
N3 = v
|
|
N4 = w
|
|
return SVector{4, T}(N1, N2, N3, N4)
|
|
end
|
|
|
|
@inline function get_basis_derivatives(::Tet4, ::Lagrange{1}, xi::Vec{3, T}) where T
|
|
(u, v, w) = xi
|
|
dN1 = Vec{3, T}((-1, -1, -1))
|
|
dN2 = Vec{3, T}((1, 0, 0))
|
|
dN3 = Vec{3, T}((0, 1, 0))
|
|
dN4 = Vec{3, T}((0, 0, 1))
|
|
return SVector{4, Vec{3, T}}(dN1, dN2, dN3, dN4)
|
|
end
|
|
|
|
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
# Lagrange{2} on Tet10: 10-node quadratic tetrahedral element
|
|
# (legacy name: Tet10)
|
|
|
|
@inline function get_basis_functions(::Tet10, ::Lagrange{2}, xi::Vec{3, T}) where T
|
|
(u, v, w) = xi
|
|
N1 = 1 - 3 * u - 3 * v - 3 * w + 2 * u ^ 2 + 2 * v ^ 2 + 2 * w ^ 2 + 4 * u * v + 4 * u * w + 4 * v * w
|
|
N2 = -u + 2 * u ^ 2
|
|
N3 = -v + 2 * v ^ 2
|
|
N4 = -w + 2 * w ^ 2
|
|
N5 = 4 * u - 4 * u ^ 2 - 4 * u * v - 4 * u * w
|
|
N6 = 4 * u * v
|
|
N7 = 4 * v - 4 * v ^ 2 - 4 * u * v - 4 * v * w
|
|
N8 = 4 * w - 4 * w ^ 2 - 4 * u * w - 4 * v * w
|
|
N9 = 4 * u * w
|
|
N10 = 4 * v * w
|
|
return SVector{10, T}(N1, N2, N3, N4, N5, N6, N7, N8, N9, N10)
|
|
end
|
|
|
|
@inline function get_basis_derivatives(::Tet10, ::Lagrange{2}, xi::Vec{3, T}) where T
|
|
(u, v, w) = xi
|
|
dN1 = Vec{3, T}((-3 + 4 * u + 4 * v + 4 * w, -3 + 4 * v + 4 * u + 4 * w, -3 + 4 * w + 4 * u + 4 * v))
|
|
dN2 = Vec{3, T}((-1 + 4 * u, 0, 0))
|
|
dN3 = Vec{3, T}((0, -1 + 4 * v, 0))
|
|
dN4 = Vec{3, T}((0, 0, -1 + 4 * w))
|
|
dN5 = Vec{3, T}((4 - 8 * u - 4 * v - 4 * w, -4 * u, -4 * u))
|
|
dN6 = Vec{3, T}((4 * v, 4 * u, 0))
|
|
dN7 = Vec{3, T}((-4 * v, 4 - 8 * v - 4 * u - 4 * w, -4 * v))
|
|
dN8 = Vec{3, T}((-4 * w, -4 * w, 4 - 8 * w - 4 * u - 4 * v))
|
|
dN9 = Vec{3, T}((4 * w, 0, 4 * u))
|
|
dN10 = Vec{3, T}((0, 4 * w, 4 * v))
|
|
return SVector{10, Vec{3, T}}(dN1, dN2, dN3, dN4, dN5, dN6, dN7, dN8, dN9, dN10)
|
|
end
|
|
|
|
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
# Lagrange{1} on Hex8: 8-node trilinear hexahedral element
|
|
# (legacy name: Hex8)
|
|
|
|
@inline function get_basis_functions(::Hex8, ::Lagrange{1}, xi::Vec{3, T}) where T
|
|
(u, v, w) = xi
|
|
N1 = 1/8 - 1/8 * u - 1/8 * v - 1/8 * w + 1/8 * u * v + 1/8 * u * w + 1/8 * v * w - 1/8 * u * v * w
|
|
N2 = 1/8 + 1/8 * u - 1/8 * v - 1/8 * w - 1/8 * u * v - 1/8 * u * w + 1/8 * v * w + 1/8 * u * v * w
|
|
N3 = 1/8 + 1/8 * u + 1/8 * v - 1/8 * w + 1/8 * u * v - 1/8 * u * w - 1/8 * v * w - 1/8 * u * v * w
|
|
N4 = 1/8 - 1/8 * u + 1/8 * v - 1/8 * w - 1/8 * u * v + 1/8 * u * w - 1/8 * v * w + 1/8 * u * v * w
|
|
N5 = 1/8 - 1/8 * u - 1/8 * v + 1/8 * w + 1/8 * u * v - 1/8 * u * w - 1/8 * v * w + 1/8 * u * v * w
|
|
N6 = 1/8 + 1/8 * u - 1/8 * v + 1/8 * w - 1/8 * u * v + 1/8 * u * w - 1/8 * v * w - 1/8 * u * v * w
|
|
N7 = 1/8 + 1/8 * u + 1/8 * v + 1/8 * w + 1/8 * u * v + 1/8 * u * w + 1/8 * v * w + 1/8 * u * v * w
|
|
N8 = 1/8 - 1/8 * u + 1/8 * v + 1/8 * w - 1/8 * u * v - 1/8 * u * w + 1/8 * v * w - 1/8 * u * v * w
|
|
return SVector{8, T}(N1, N2, N3, N4, N5, N6, N7, N8)
|
|
end
|
|
|
|
@inline function get_basis_derivatives(::Hex8, ::Lagrange{1}, xi::Vec{3, T}) where T
|
|
(u, v, w) = xi
|
|
dN1 = Vec{3, T}((-1/8 + 1/8 * v + 1/8 * w - 1/8 * v * w, -1/8 + 1/8 * u + 1/8 * w - 1/8 * u * w, -1/8 + 1/8 * u + 1/8 * v - 1/8 * u * v))
|
|
dN2 = Vec{3, T}((1/8 - 1/8 * v - 1/8 * w + 1/8 * v * w, -1/8 - 1/8 * u + 1/8 * w + 1/8 * u * w, -1/8 - 1/8 * u + 1/8 * v + 1/8 * u * v))
|
|
dN3 = Vec{3, T}((1/8 + 1/8 * v - 1/8 * w - 1/8 * v * w, 1/8 + 1/8 * u - 1/8 * w - 1/8 * u * w, -1/8 - 1/8 * u - 1/8 * v - 1/8 * u * v))
|
|
dN4 = Vec{3, T}((-1/8 - 1/8 * v + 1/8 * w + 1/8 * v * w, 1/8 - 1/8 * u - 1/8 * w + 1/8 * u * w, -1/8 + 1/8 * u - 1/8 * v + 1/8 * u * v))
|
|
dN5 = Vec{3, T}((-1/8 + 1/8 * v - 1/8 * w + 1/8 * v * w, -1/8 + 1/8 * u - 1/8 * w + 1/8 * u * w, 1/8 - 1/8 * u - 1/8 * v + 1/8 * u * v))
|
|
dN6 = Vec{3, T}((1/8 - 1/8 * v + 1/8 * w - 1/8 * v * w, -1/8 - 1/8 * u - 1/8 * w - 1/8 * u * w, 1/8 + 1/8 * u - 1/8 * v - 1/8 * u * v))
|
|
dN7 = Vec{3, T}((1/8 + 1/8 * v + 1/8 * w + 1/8 * v * w, 1/8 + 1/8 * u + 1/8 * w + 1/8 * u * w, 1/8 + 1/8 * u + 1/8 * v + 1/8 * u * v))
|
|
dN8 = Vec{3, T}((-1/8 - 1/8 * v - 1/8 * w - 1/8 * v * w, 1/8 - 1/8 * u + 1/8 * w - 1/8 * u * w, 1/8 - 1/8 * u + 1/8 * v - 1/8 * u * v))
|
|
return SVector{8, Vec{3, T}}(dN1, dN2, dN3, dN4, dN5, dN6, dN7, dN8)
|
|
end
|
|
|
|
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
# Serendipity{2} on Hex20: 20-node serendipity hexahedral element
|
|
# (legacy name: Hex20)
|
|
|
|
@inline function get_basis_functions(::Hex20, ::Serendipity{2}, xi::Vec{3, T}) where T
|
|
(u, v, w) = xi
|
|
N1 = -1/4 + 1/8 * u + 1/8 * v + 1/8 * w + 1/12 * u * v + 1/12 * u * w + 1/12 * v * w + 1/8 * u ^ 2 + 1/8 * v ^ 2 + 1/8 * w ^ 2 - 1/8 * u ^ 2 * v - 1/8 * u * v ^ 2 - 1/8 * u ^ 2 * w - 1/8 * u * w ^ 2 - 1/8 * v ^ 2 * w - 1/8 * v * w ^ 2
|
|
N2 = -1/4 - 1/8 * u + 1/8 * v + 1/8 * w - 1/12 * u * v - 1/12 * u * w + 1/12 * v * w + 1/8 * u ^ 2 + 1/8 * v ^ 2 + 1/8 * w ^ 2 - 1/8 * u ^ 2 * v + 1/8 * u * v ^ 2 - 1/8 * u ^ 2 * w + 1/8 * u * w ^ 2 - 1/8 * v ^ 2 * w - 1/8 * v * w ^ 2
|
|
N3 = -1/4 - 1/8 * u - 1/8 * v + 1/8 * w + 1/12 * u * v - 1/12 * u * w - 1/12 * v * w + 1/8 * u ^ 2 + 1/8 * v ^ 2 + 1/8 * w ^ 2 + 1/8 * u ^ 2 * v + 1/8 * u * v ^ 2 - 1/8 * u ^ 2 * w + 1/8 * u * w ^ 2 - 1/8 * v ^ 2 * w + 1/8 * v * w ^ 2
|
|
N4 = -1/4 + 1/8 * u - 1/8 * v + 1/8 * w - 1/12 * u * v + 1/12 * u * w - 1/12 * v * w + 1/8 * u ^ 2 + 1/8 * v ^ 2 + 1/8 * w ^ 2 + 1/8 * u ^ 2 * v - 1/8 * u * v ^ 2 - 1/8 * u ^ 2 * w - 1/8 * u * w ^ 2 - 1/8 * v ^ 2 * w + 1/8 * v * w ^ 2
|
|
N5 = -1/4 + 1/8 * u + 1/8 * v - 1/8 * w + 1/12 * u * v - 1/12 * u * w - 1/12 * v * w + 1/8 * u ^ 2 + 1/8 * v ^ 2 + 1/8 * w ^ 2 - 1/8 * u ^ 2 * v - 1/8 * u * v ^ 2 + 1/8 * u ^ 2 * w - 1/8 * u * w ^ 2 + 1/8 * v ^ 2 * w - 1/8 * v * w ^ 2
|
|
N6 = -1/4 - 1/8 * u + 1/8 * v - 1/8 * w - 1/12 * u * v + 1/12 * u * w - 1/12 * v * w + 1/8 * u ^ 2 + 1/8 * v ^ 2 + 1/8 * w ^ 2 - 1/8 * u ^ 2 * v + 1/8 * u * v ^ 2 + 1/8 * u ^ 2 * w + 1/8 * u * w ^ 2 + 1/8 * v ^ 2 * w - 1/8 * v * w ^ 2
|
|
N7 = -1/4 - 1/8 * u - 1/8 * v - 1/8 * w + 1/12 * u * v + 1/12 * u * w + 1/12 * v * w + 1/8 * u ^ 2 + 1/8 * v ^ 2 + 1/8 * w ^ 2 + 1/8 * u ^ 2 * v + 1/8 * u * v ^ 2 + 1/8 * u ^ 2 * w + 1/8 * u * w ^ 2 + 1/8 * v ^ 2 * w + 1/8 * v * w ^ 2
|
|
N8 = -1/4 + 1/8 * u - 1/8 * v - 1/8 * w - 1/12 * u * v - 1/12 * u * w + 1/12 * v * w + 1/8 * u ^ 2 + 1/8 * v ^ 2 + 1/8 * w ^ 2 + 1/8 * u ^ 2 * v - 1/8 * u * v ^ 2 + 1/8 * u ^ 2 * w - 1/8 * u * w ^ 2 + 1/8 * v ^ 2 * w + 1/8 * v * w ^ 2
|
|
N9 = 1/4 - 1/4 * v - 1/4 * w + 1/12 * v * w - 1/4 * u ^ 2 + 1/4 * u ^ 2 * v + 1/4 * u ^ 2 * w
|
|
N10 = 1/4 + 1/4 * u - 1/4 * w - 1/12 * u * w - 1/4 * v ^ 2 - 1/4 * u * v ^ 2 + 1/4 * v ^ 2 * w
|
|
N11 = 1/4 + 1/4 * v - 1/4 * w - 1/12 * v * w - 1/4 * u ^ 2 - 1/4 * u ^ 2 * v + 1/4 * u ^ 2 * w
|
|
N12 = 1/4 - 1/4 * u - 1/4 * w + 1/12 * u * w - 1/4 * v ^ 2 + 1/4 * u * v ^ 2 + 1/4 * v ^ 2 * w
|
|
N13 = 1/4 - 1/4 * v + 1/4 * w - 1/12 * v * w - 1/4 * u ^ 2 + 1/4 * u ^ 2 * v - 1/4 * u ^ 2 * w
|
|
N14 = 1/4 + 1/4 * u + 1/4 * w + 1/12 * u * w - 1/4 * v ^ 2 - 1/4 * u * v ^ 2 - 1/4 * v ^ 2 * w
|
|
N15 = 1/4 + 1/4 * v + 1/4 * w + 1/12 * v * w - 1/4 * u ^ 2 - 1/4 * u ^ 2 * v - 1/4 * u ^ 2 * w
|
|
N16 = 1/4 - 1/4 * u + 1/4 * w - 1/12 * u * w - 1/4 * v ^ 2 + 1/4 * u * v ^ 2 - 1/4 * v ^ 2 * w
|
|
N17 = 1/4 - 1/4 * u - 1/4 * v + 1/12 * u * v - 1/4 * w ^ 2 + 1/4 * u * w ^ 2 + 1/4 * v * w ^ 2
|
|
N18 = 1/4 + 1/4 * u - 1/4 * v - 1/12 * u * v - 1/4 * w ^ 2 - 1/4 * u * w ^ 2 + 1/4 * v * w ^ 2
|
|
N19 = 1/4 + 1/4 * u + 1/4 * v + 1/12 * u * v - 1/4 * w ^ 2 - 1/4 * u * w ^ 2 - 1/4 * v * w ^ 2
|
|
N20 = 1/4 - 1/4 * u + 1/4 * v - 1/12 * u * v - 1/4 * w ^ 2 + 1/4 * u * w ^ 2 - 1/4 * v * w ^ 2
|
|
return SVector{20, T}(N1, N2, N3, N4, N5, N6, N7, N8, N9, N10, N11, N12, N13, N14, N15, N16, N17, N18, N19, N20)
|
|
end
|
|
|
|
@inline function get_basis_derivatives(::Hex20, ::Serendipity{2}, xi::Vec{3, T}) where T
|
|
(u, v, w) = xi
|
|
dN1 = Vec{3, T}((1/8 + 1/12 * v + 1/12 * w + 1/4 * u - 1/4 * u * v - 1/8 * v ^ 2 - 1/4 * u * w - 1/8 * w ^ 2, 1/8 + 1/12 * u + 1/12 * w + 1/4 * v - 1/8 * u ^ 2 - 1/4 * u * v - 1/4 * v * w - 1/8 * w ^ 2, 1/8 + 1/12 * u + 1/12 * v + 1/4 * w - 1/8 * u ^ 2 - 1/4 * u * w - 1/8 * v ^ 2 - 1/4 * v * w))
|
|
dN2 = Vec{3, T}((-1/8 - 1/12 * v - 1/12 * w + 1/4 * u - 1/4 * u * v + 1/8 * v ^ 2 - 1/4 * u * w + 1/8 * w ^ 2, 1/8 - 1/12 * u + 1/12 * w + 1/4 * v - 1/8 * u ^ 2 + 1/4 * u * v - 1/4 * v * w - 1/8 * w ^ 2, 1/8 - 1/12 * u + 1/12 * v + 1/4 * w - 1/8 * u ^ 2 + 1/4 * u * w - 1/8 * v ^ 2 - 1/4 * v * w))
|
|
dN3 = Vec{3, T}((-1/8 + 1/12 * v - 1/12 * w + 1/4 * u + 1/4 * u * v + 1/8 * v ^ 2 - 1/4 * u * w + 1/8 * w ^ 2, -1/8 + 1/12 * u - 1/12 * w + 1/4 * v + 1/8 * u ^ 2 + 1/4 * u * v - 1/4 * v * w + 1/8 * w ^ 2, 1/8 - 1/12 * u - 1/12 * v + 1/4 * w - 1/8 * u ^ 2 + 1/4 * u * w - 1/8 * v ^ 2 + 1/4 * v * w))
|
|
dN4 = Vec{3, T}((1/8 - 1/12 * v + 1/12 * w + 1/4 * u + 1/4 * u * v - 1/8 * v ^ 2 - 1/4 * u * w - 1/8 * w ^ 2, -1/8 - 1/12 * u - 1/12 * w + 1/4 * v + 1/8 * u ^ 2 - 1/4 * u * v - 1/4 * v * w + 1/8 * w ^ 2, 1/8 + 1/12 * u - 1/12 * v + 1/4 * w - 1/8 * u ^ 2 - 1/4 * u * w - 1/8 * v ^ 2 + 1/4 * v * w))
|
|
dN5 = Vec{3, T}((1/8 + 1/12 * v - 1/12 * w + 1/4 * u - 1/4 * u * v - 1/8 * v ^ 2 + 1/4 * u * w - 1/8 * w ^ 2, 1/8 + 1/12 * u - 1/12 * w + 1/4 * v - 1/8 * u ^ 2 - 1/4 * u * v + 1/4 * v * w - 1/8 * w ^ 2, -1/8 - 1/12 * u - 1/12 * v + 1/4 * w + 1/8 * u ^ 2 - 1/4 * u * w + 1/8 * v ^ 2 - 1/4 * v * w))
|
|
dN6 = Vec{3, T}((-1/8 - 1/12 * v + 1/12 * w + 1/4 * u - 1/4 * u * v + 1/8 * v ^ 2 + 1/4 * u * w + 1/8 * w ^ 2, 1/8 - 1/12 * u - 1/12 * w + 1/4 * v - 1/8 * u ^ 2 + 1/4 * u * v + 1/4 * v * w - 1/8 * w ^ 2, -1/8 + 1/12 * u - 1/12 * v + 1/4 * w + 1/8 * u ^ 2 + 1/4 * u * w + 1/8 * v ^ 2 - 1/4 * v * w))
|
|
dN7 = Vec{3, T}((-1/8 + 1/12 * v + 1/12 * w + 1/4 * u + 1/4 * u * v + 1/8 * v ^ 2 + 1/4 * u * w + 1/8 * w ^ 2, -1/8 + 1/12 * u + 1/12 * w + 1/4 * v + 1/8 * u ^ 2 + 1/4 * u * v + 1/4 * v * w + 1/8 * w ^ 2, -1/8 + 1/12 * u + 1/12 * v + 1/4 * w + 1/8 * u ^ 2 + 1/4 * u * w + 1/8 * v ^ 2 + 1/4 * v * w))
|
|
dN8 = Vec{3, T}((1/8 - 1/12 * v - 1/12 * w + 1/4 * u + 1/4 * u * v - 1/8 * v ^ 2 + 1/4 * u * w - 1/8 * w ^ 2, -1/8 - 1/12 * u + 1/12 * w + 1/4 * v + 1/8 * u ^ 2 - 1/4 * u * v + 1/4 * v * w + 1/8 * w ^ 2, -1/8 - 1/12 * u + 1/12 * v + 1/4 * w + 1/8 * u ^ 2 - 1/4 * u * w + 1/8 * v ^ 2 + 1/4 * v * w))
|
|
dN9 = Vec{3, T}((-1/2 * u + 1/2 * u * v + 1/2 * u * w, -1/4 + 1/12 * w + 1/4 * u ^ 2, -1/4 + 1/12 * v + 1/4 * u ^ 2))
|
|
dN10 = Vec{3, T}((1/4 - 1/12 * w - 1/4 * v ^ 2, -1/2 * v - 1/2 * u * v + 1/2 * v * w, -1/4 - 1/12 * u + 1/4 * v ^ 2))
|
|
dN11 = Vec{3, T}((-1/2 * u - 1/2 * u * v + 1/2 * u * w, 1/4 - 1/12 * w - 1/4 * u ^ 2, -1/4 - 1/12 * v + 1/4 * u ^ 2))
|
|
dN12 = Vec{3, T}((-1/4 + 1/12 * w + 1/4 * v ^ 2, -1/2 * v + 1/2 * u * v + 1/2 * v * w, -1/4 + 1/12 * u + 1/4 * v ^ 2))
|
|
dN13 = Vec{3, T}((-1/2 * u + 1/2 * u * v - 1/2 * u * w, -1/4 - 1/12 * w + 1/4 * u ^ 2, 1/4 - 1/12 * v - 1/4 * u ^ 2))
|
|
dN14 = Vec{3, T}((1/4 + 1/12 * w - 1/4 * v ^ 2, -1/2 * v - 1/2 * u * v - 1/2 * v * w, 1/4 + 1/12 * u - 1/4 * v ^ 2))
|
|
dN15 = Vec{3, T}((-1/2 * u - 1/2 * u * v - 1/2 * u * w, 1/4 + 1/12 * w - 1/4 * u ^ 2, 1/4 + 1/12 * v - 1/4 * u ^ 2))
|
|
dN16 = Vec{3, T}((-1/4 - 1/12 * w + 1/4 * v ^ 2, -1/2 * v + 1/2 * u * v - 1/2 * v * w, 1/4 - 1/12 * u - 1/4 * v ^ 2))
|
|
dN17 = Vec{3, T}((-1/4 + 1/12 * v + 1/4 * w ^ 2, -1/4 + 1/12 * u + 1/4 * w ^ 2, -1/2 * w + 1/2 * u * w + 1/2 * v * w))
|
|
dN18 = Vec{3, T}((1/4 - 1/12 * v - 1/4 * w ^ 2, -1/4 - 1/12 * u + 1/4 * w ^ 2, -1/2 * w - 1/2 * u * w + 1/2 * v * w))
|
|
dN19 = Vec{3, T}((1/4 + 1/12 * v - 1/4 * w ^ 2, 1/4 + 1/12 * u - 1/4 * w ^ 2, -1/2 * w - 1/2 * u * w - 1/2 * v * w))
|
|
dN20 = Vec{3, T}((-1/4 - 1/12 * v + 1/4 * w ^ 2, 1/4 - 1/12 * u - 1/4 * w ^ 2, -1/2 * w + 1/2 * u * w - 1/2 * v * w))
|
|
return SVector{20, Vec{3, T}}(dN1, dN2, dN3, dN4, dN5, dN6, dN7, dN8, dN9, dN10, dN11, dN12, dN13, dN14, dN15, dN16, dN17, dN18, dN19, dN20)
|
|
end
|
|
|
|
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
# Lagrange{2} on Hex27: 27-node triquadratic hexahedral element
|
|
# (legacy name: Hex27)
|
|
|
|
@inline function get_basis_functions(::Hex27, ::Lagrange{2}, xi::Vec{3, T}) where T
|
|
(u, v, w) = xi
|
|
N1 = 1/18 * u + 1/18 * v + 1/18 * w - 1/12 * u ^ 2 * v - 1/12 * u * v ^ 2 - 1/12 * u ^ 2 * w - 1/12 * u * w ^ 2 - 1/12 * v ^ 2 * w - 1/12 * v * w ^ 2 + 1/8 * u ^ 2 * v * w + 1/8 * u * v ^ 2 * w + 1/8 * u * v * w ^ 2 + 1/8 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N2 = -1/18 * u + 1/18 * v + 1/18 * w - 1/12 * u ^ 2 * v + 1/12 * u * v ^ 2 - 1/12 * u ^ 2 * w + 1/12 * u * w ^ 2 - 1/12 * v ^ 2 * w - 1/12 * v * w ^ 2 + 1/8 * u ^ 2 * v * w - 1/8 * u * v ^ 2 * w - 1/8 * u * v * w ^ 2 + 1/8 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N3 = -1/18 * u - 1/18 * v + 1/18 * w + 1/12 * u ^ 2 * v + 1/12 * u * v ^ 2 - 1/12 * u ^ 2 * w + 1/12 * u * w ^ 2 - 1/12 * v ^ 2 * w + 1/12 * v * w ^ 2 - 1/8 * u ^ 2 * v * w - 1/8 * u * v ^ 2 * w + 1/8 * u * v * w ^ 2 + 1/8 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N4 = 1/18 * u - 1/18 * v + 1/18 * w + 1/12 * u ^ 2 * v - 1/12 * u * v ^ 2 - 1/12 * u ^ 2 * w - 1/12 * u * w ^ 2 - 1/12 * v ^ 2 * w + 1/12 * v * w ^ 2 - 1/8 * u ^ 2 * v * w + 1/8 * u * v ^ 2 * w - 1/8 * u * v * w ^ 2 + 1/8 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N5 = 1/18 * u + 1/18 * v - 1/18 * w - 1/12 * u ^ 2 * v - 1/12 * u * v ^ 2 + 1/12 * u ^ 2 * w - 1/12 * u * w ^ 2 + 1/12 * v ^ 2 * w - 1/12 * v * w ^ 2 - 1/8 * u ^ 2 * v * w - 1/8 * u * v ^ 2 * w + 1/8 * u * v * w ^ 2 + 1/8 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N6 = -1/18 * u + 1/18 * v - 1/18 * w - 1/12 * u ^ 2 * v + 1/12 * u * v ^ 2 + 1/12 * u ^ 2 * w + 1/12 * u * w ^ 2 + 1/12 * v ^ 2 * w - 1/12 * v * w ^ 2 - 1/8 * u ^ 2 * v * w + 1/8 * u * v ^ 2 * w - 1/8 * u * v * w ^ 2 + 1/8 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N7 = -1/18 * u - 1/18 * v - 1/18 * w + 1/12 * u ^ 2 * v + 1/12 * u * v ^ 2 + 1/12 * u ^ 2 * w + 1/12 * u * w ^ 2 + 1/12 * v ^ 2 * w + 1/12 * v * w ^ 2 + 1/8 * u ^ 2 * v * w + 1/8 * u * v ^ 2 * w + 1/8 * u * v * w ^ 2 + 1/8 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N8 = 1/18 * u - 1/18 * v - 1/18 * w + 1/12 * u ^ 2 * v - 1/12 * u * v ^ 2 + 1/12 * u ^ 2 * w - 1/12 * u * w ^ 2 + 1/12 * v ^ 2 * w + 1/12 * v * w ^ 2 + 1/8 * u ^ 2 * v * w - 1/8 * u * v ^ 2 * w - 1/8 * u * v * w ^ 2 + 1/8 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N9 = -1/9 * v - 1/9 * w + 1/4 * v * w + 1/6 * u ^ 2 * v + 1/6 * u ^ 2 * w - 1/12 * v ^ 2 * w - 1/12 * v * w ^ 2 + 1/4 * v ^ 2 * w ^ 2 - 1/4 * u ^ 2 * v * w - 1/4 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N10 = 1/9 * u - 1/9 * w - 1/4 * u * w - 1/6 * u * v ^ 2 - 1/12 * u ^ 2 * w + 1/12 * u * w ^ 2 + 1/6 * v ^ 2 * w + 1/4 * u ^ 2 * w ^ 2 + 1/4 * u * v ^ 2 * w - 1/4 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N11 = 1/9 * v - 1/9 * w - 1/4 * v * w - 1/6 * u ^ 2 * v + 1/6 * u ^ 2 * w - 1/12 * v ^ 2 * w + 1/12 * v * w ^ 2 + 1/4 * v ^ 2 * w ^ 2 + 1/4 * u ^ 2 * v * w - 1/4 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N12 = -1/9 * u - 1/9 * w + 1/4 * u * w + 1/6 * u * v ^ 2 - 1/12 * u ^ 2 * w - 1/12 * u * w ^ 2 + 1/6 * v ^ 2 * w + 1/4 * u ^ 2 * w ^ 2 - 1/4 * u * v ^ 2 * w - 1/4 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N13 = -1/9 * v + 1/9 * w - 1/4 * v * w + 1/6 * u ^ 2 * v - 1/6 * u ^ 2 * w + 1/12 * v ^ 2 * w - 1/12 * v * w ^ 2 + 1/4 * v ^ 2 * w ^ 2 + 1/4 * u ^ 2 * v * w - 1/4 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N14 = 1/9 * u + 1/9 * w + 1/4 * u * w - 1/6 * u * v ^ 2 + 1/12 * u ^ 2 * w + 1/12 * u * w ^ 2 - 1/6 * v ^ 2 * w + 1/4 * u ^ 2 * w ^ 2 - 1/4 * u * v ^ 2 * w - 1/4 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N15 = 1/9 * v + 1/9 * w + 1/4 * v * w - 1/6 * u ^ 2 * v - 1/6 * u ^ 2 * w + 1/12 * v ^ 2 * w + 1/12 * v * w ^ 2 + 1/4 * v ^ 2 * w ^ 2 - 1/4 * u ^ 2 * v * w - 1/4 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N16 = -1/9 * u + 1/9 * w - 1/4 * u * w + 1/6 * u * v ^ 2 + 1/12 * u ^ 2 * w - 1/12 * u * w ^ 2 - 1/6 * v ^ 2 * w + 1/4 * u ^ 2 * w ^ 2 + 1/4 * u * v ^ 2 * w - 1/4 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N17 = -1/9 * u - 1/9 * v + 1/4 * u * v - 1/12 * u ^ 2 * v - 1/12 * u * v ^ 2 + 1/6 * u * w ^ 2 + 1/6 * v * w ^ 2 + 1/4 * u ^ 2 * v ^ 2 - 1/4 * u * v * w ^ 2 - 1/4 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N18 = 1/9 * u - 1/9 * v - 1/4 * u * v - 1/12 * u ^ 2 * v + 1/12 * u * v ^ 2 - 1/6 * u * w ^ 2 + 1/6 * v * w ^ 2 + 1/4 * u ^ 2 * v ^ 2 + 1/4 * u * v * w ^ 2 - 1/4 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N19 = 1/9 * u + 1/9 * v + 1/4 * u * v + 1/12 * u ^ 2 * v + 1/12 * u * v ^ 2 - 1/6 * u * w ^ 2 - 1/6 * v * w ^ 2 + 1/4 * u ^ 2 * v ^ 2 - 1/4 * u * v * w ^ 2 - 1/4 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N20 = -1/9 * u + 1/9 * v - 1/4 * u * v + 1/12 * u ^ 2 * v - 1/12 * u * v ^ 2 + 1/6 * u * w ^ 2 - 1/6 * v * w ^ 2 + 1/4 * u ^ 2 * v ^ 2 + 1/4 * u * v * w ^ 2 - 1/4 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N21 = -5/18 * w + 1/2 * w ^ 2 + 1/6 * u ^ 2 * w + 1/6 * v ^ 2 * w - 1/2 * u ^ 2 * w ^ 2 - 1/2 * v ^ 2 * w ^ 2 + 1/2 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N22 = 5/18 * w + 1/2 * w ^ 2 - 1/6 * u ^ 2 * w - 1/6 * v ^ 2 * w - 1/2 * u ^ 2 * w ^ 2 - 1/2 * v ^ 2 * w ^ 2 + 1/2 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N23 = -5/18 * v + 1/2 * v ^ 2 + 1/6 * u ^ 2 * v + 1/6 * v * w ^ 2 - 1/2 * u ^ 2 * v ^ 2 - 1/2 * v ^ 2 * w ^ 2 + 1/2 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N24 = 5/18 * v + 1/2 * v ^ 2 - 1/6 * u ^ 2 * v - 1/6 * v * w ^ 2 - 1/2 * u ^ 2 * v ^ 2 - 1/2 * v ^ 2 * w ^ 2 + 1/2 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N25 = -5/18 * u + 1/2 * u ^ 2 + 1/6 * u * v ^ 2 + 1/6 * u * w ^ 2 - 1/2 * u ^ 2 * v ^ 2 - 1/2 * u ^ 2 * w ^ 2 + 1/2 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N26 = 5/18 * u + 1/2 * u ^ 2 - 1/6 * u * v ^ 2 - 1/6 * u * w ^ 2 - 1/2 * u ^ 2 * v ^ 2 - 1/2 * u ^ 2 * w ^ 2 + 1/2 * u ^ 2 * v ^ 2 * w ^ 2
|
|
N27 = 1 - u ^ 2 - v ^ 2 - w ^ 2 + u ^ 2 * v ^ 2 + u ^ 2 * w ^ 2 + v ^ 2 * w ^ 2 - u ^ 2 * v ^ 2 * w ^ 2
|
|
return SVector{27, T}(N1, N2, N3, N4, N5, N6, N7, N8, N9, N10, N11, N12, N13, N14, N15, N16, N17, N18, N19, N20, N21, N22, N23, N24, N25, N26, N27)
|
|
end
|
|
|
|
@inline function get_basis_derivatives(::Hex27, ::Lagrange{2}, xi::Vec{3, T}) where T
|
|
(u, v, w) = xi
|
|
dN1 = Vec{3, T}((1/18 - 1/6 * u * v - 1/12 * v ^ 2 - 1/6 * u * w - 1/12 * w ^ 2 + 1/4 * u * v * w + 1/8 * v ^ 2 * w + 1/8 * v * w ^ 2 + 1/4 * u * v ^ 2 * w ^ 2, 1/18 - 1/12 * u ^ 2 - 1/6 * u * v - 1/6 * v * w - 1/12 * w ^ 2 + 1/8 * u ^ 2 * w + 1/4 * u * v * w + 1/8 * u * w ^ 2 + 1/4 * u ^ 2 * v * w ^ 2, 1/18 - 1/12 * u ^ 2 - 1/6 * u * w - 1/12 * v ^ 2 - 1/6 * v * w + 1/8 * u ^ 2 * v + 1/8 * u * v ^ 2 + 1/4 * u * v * w + 1/4 * u ^ 2 * v ^ 2 * w))
|
|
dN2 = Vec{3, T}((-1/18 - 1/6 * u * v + 1/12 * v ^ 2 - 1/6 * u * w + 1/12 * w ^ 2 + 1/4 * u * v * w - 1/8 * v ^ 2 * w - 1/8 * v * w ^ 2 + 1/4 * u * v ^ 2 * w ^ 2, 1/18 - 1/12 * u ^ 2 + 1/6 * u * v - 1/6 * v * w - 1/12 * w ^ 2 + 1/8 * u ^ 2 * w - 1/4 * u * v * w - 1/8 * u * w ^ 2 + 1/4 * u ^ 2 * v * w ^ 2, 1/18 - 1/12 * u ^ 2 + 1/6 * u * w - 1/12 * v ^ 2 - 1/6 * v * w + 1/8 * u ^ 2 * v - 1/8 * u * v ^ 2 - 1/4 * u * v * w + 1/4 * u ^ 2 * v ^ 2 * w))
|
|
dN3 = Vec{3, T}((-1/18 + 1/6 * u * v + 1/12 * v ^ 2 - 1/6 * u * w + 1/12 * w ^ 2 - 1/4 * u * v * w - 1/8 * v ^ 2 * w + 1/8 * v * w ^ 2 + 1/4 * u * v ^ 2 * w ^ 2, -1/18 + 1/12 * u ^ 2 + 1/6 * u * v - 1/6 * v * w + 1/12 * w ^ 2 - 1/8 * u ^ 2 * w - 1/4 * u * v * w + 1/8 * u * w ^ 2 + 1/4 * u ^ 2 * v * w ^ 2, 1/18 - 1/12 * u ^ 2 + 1/6 * u * w - 1/12 * v ^ 2 + 1/6 * v * w - 1/8 * u ^ 2 * v - 1/8 * u * v ^ 2 + 1/4 * u * v * w + 1/4 * u ^ 2 * v ^ 2 * w))
|
|
dN4 = Vec{3, T}((1/18 + 1/6 * u * v - 1/12 * v ^ 2 - 1/6 * u * w - 1/12 * w ^ 2 - 1/4 * u * v * w + 1/8 * v ^ 2 * w - 1/8 * v * w ^ 2 + 1/4 * u * v ^ 2 * w ^ 2, -1/18 + 1/12 * u ^ 2 - 1/6 * u * v - 1/6 * v * w + 1/12 * w ^ 2 - 1/8 * u ^ 2 * w + 1/4 * u * v * w - 1/8 * u * w ^ 2 + 1/4 * u ^ 2 * v * w ^ 2, 1/18 - 1/12 * u ^ 2 - 1/6 * u * w - 1/12 * v ^ 2 + 1/6 * v * w - 1/8 * u ^ 2 * v + 1/8 * u * v ^ 2 - 1/4 * u * v * w + 1/4 * u ^ 2 * v ^ 2 * w))
|
|
dN5 = Vec{3, T}((1/18 - 1/6 * u * v - 1/12 * v ^ 2 + 1/6 * u * w - 1/12 * w ^ 2 - 1/4 * u * v * w - 1/8 * v ^ 2 * w + 1/8 * v * w ^ 2 + 1/4 * u * v ^ 2 * w ^ 2, 1/18 - 1/12 * u ^ 2 - 1/6 * u * v + 1/6 * v * w - 1/12 * w ^ 2 - 1/8 * u ^ 2 * w - 1/4 * u * v * w + 1/8 * u * w ^ 2 + 1/4 * u ^ 2 * v * w ^ 2, -1/18 + 1/12 * u ^ 2 - 1/6 * u * w + 1/12 * v ^ 2 - 1/6 * v * w - 1/8 * u ^ 2 * v - 1/8 * u * v ^ 2 + 1/4 * u * v * w + 1/4 * u ^ 2 * v ^ 2 * w))
|
|
dN6 = Vec{3, T}((-1/18 - 1/6 * u * v + 1/12 * v ^ 2 + 1/6 * u * w + 1/12 * w ^ 2 - 1/4 * u * v * w + 1/8 * v ^ 2 * w - 1/8 * v * w ^ 2 + 1/4 * u * v ^ 2 * w ^ 2, 1/18 - 1/12 * u ^ 2 + 1/6 * u * v + 1/6 * v * w - 1/12 * w ^ 2 - 1/8 * u ^ 2 * w + 1/4 * u * v * w - 1/8 * u * w ^ 2 + 1/4 * u ^ 2 * v * w ^ 2, -1/18 + 1/12 * u ^ 2 + 1/6 * u * w + 1/12 * v ^ 2 - 1/6 * v * w - 1/8 * u ^ 2 * v + 1/8 * u * v ^ 2 - 1/4 * u * v * w + 1/4 * u ^ 2 * v ^ 2 * w))
|
|
dN7 = Vec{3, T}((-1/18 + 1/6 * u * v + 1/12 * v ^ 2 + 1/6 * u * w + 1/12 * w ^ 2 + 1/4 * u * v * w + 1/8 * v ^ 2 * w + 1/8 * v * w ^ 2 + 1/4 * u * v ^ 2 * w ^ 2, -1/18 + 1/12 * u ^ 2 + 1/6 * u * v + 1/6 * v * w + 1/12 * w ^ 2 + 1/8 * u ^ 2 * w + 1/4 * u * v * w + 1/8 * u * w ^ 2 + 1/4 * u ^ 2 * v * w ^ 2, -1/18 + 1/12 * u ^ 2 + 1/6 * u * w + 1/12 * v ^ 2 + 1/6 * v * w + 1/8 * u ^ 2 * v + 1/8 * u * v ^ 2 + 1/4 * u * v * w + 1/4 * u ^ 2 * v ^ 2 * w))
|
|
dN8 = Vec{3, T}((1/18 + 1/6 * u * v - 1/12 * v ^ 2 + 1/6 * u * w - 1/12 * w ^ 2 + 1/4 * u * v * w - 1/8 * v ^ 2 * w - 1/8 * v * w ^ 2 + 1/4 * u * v ^ 2 * w ^ 2, -1/18 + 1/12 * u ^ 2 - 1/6 * u * v + 1/6 * v * w + 1/12 * w ^ 2 + 1/8 * u ^ 2 * w - 1/4 * u * v * w - 1/8 * u * w ^ 2 + 1/4 * u ^ 2 * v * w ^ 2, -1/18 + 1/12 * u ^ 2 - 1/6 * u * w + 1/12 * v ^ 2 + 1/6 * v * w + 1/8 * u ^ 2 * v - 1/8 * u * v ^ 2 - 1/4 * u * v * w + 1/4 * u ^ 2 * v ^ 2 * w))
|
|
dN9 = Vec{3, T}((1/3 * u * v + 1/3 * u * w - 1/2 * u * v * w - 1/2 * u * v ^ 2 * w ^ 2, -1/9 + 1/4 * w + 1/6 * u ^ 2 - 1/6 * v * w - 1/12 * w ^ 2 + 1/2 * v * w ^ 2 - 1/4 * u ^ 2 * w - 1/2 * u ^ 2 * v * w ^ 2, -1/9 + 1/4 * v + 1/6 * u ^ 2 - 1/12 * v ^ 2 - 1/6 * v * w + 1/2 * v ^ 2 * w - 1/4 * u ^ 2 * v - 1/2 * u ^ 2 * v ^ 2 * w))
|
|
dN10 = Vec{3, T}((1/9 - 1/4 * w - 1/6 * v ^ 2 - 1/6 * u * w + 1/12 * w ^ 2 + 1/2 * u * w ^ 2 + 1/4 * v ^ 2 * w - 1/2 * u * v ^ 2 * w ^ 2, -1/3 * u * v + 1/3 * v * w + 1/2 * u * v * w - 1/2 * u ^ 2 * v * w ^ 2, -1/9 - 1/4 * u - 1/12 * u ^ 2 + 1/6 * u * w + 1/6 * v ^ 2 + 1/2 * u ^ 2 * w + 1/4 * u * v ^ 2 - 1/2 * u ^ 2 * v ^ 2 * w))
|
|
dN11 = Vec{3, T}((-1/3 * u * v + 1/3 * u * w + 1/2 * u * v * w - 1/2 * u * v ^ 2 * w ^ 2, 1/9 - 1/4 * w - 1/6 * u ^ 2 - 1/6 * v * w + 1/12 * w ^ 2 + 1/2 * v * w ^ 2 + 1/4 * u ^ 2 * w - 1/2 * u ^ 2 * v * w ^ 2, -1/9 - 1/4 * v + 1/6 * u ^ 2 - 1/12 * v ^ 2 + 1/6 * v * w + 1/2 * v ^ 2 * w + 1/4 * u ^ 2 * v - 1/2 * u ^ 2 * v ^ 2 * w))
|
|
dN12 = Vec{3, T}((-1/9 + 1/4 * w + 1/6 * v ^ 2 - 1/6 * u * w - 1/12 * w ^ 2 + 1/2 * u * w ^ 2 - 1/4 * v ^ 2 * w - 1/2 * u * v ^ 2 * w ^ 2, 1/3 * u * v + 1/3 * v * w - 1/2 * u * v * w - 1/2 * u ^ 2 * v * w ^ 2, -1/9 + 1/4 * u - 1/12 * u ^ 2 - 1/6 * u * w + 1/6 * v ^ 2 + 1/2 * u ^ 2 * w - 1/4 * u * v ^ 2 - 1/2 * u ^ 2 * v ^ 2 * w))
|
|
dN13 = Vec{3, T}((1/3 * u * v - 1/3 * u * w + 1/2 * u * v * w - 1/2 * u * v ^ 2 * w ^ 2, -1/9 - 1/4 * w + 1/6 * u ^ 2 + 1/6 * v * w - 1/12 * w ^ 2 + 1/2 * v * w ^ 2 + 1/4 * u ^ 2 * w - 1/2 * u ^ 2 * v * w ^ 2, 1/9 - 1/4 * v - 1/6 * u ^ 2 + 1/12 * v ^ 2 - 1/6 * v * w + 1/2 * v ^ 2 * w + 1/4 * u ^ 2 * v - 1/2 * u ^ 2 * v ^ 2 * w))
|
|
dN14 = Vec{3, T}((1/9 + 1/4 * w - 1/6 * v ^ 2 + 1/6 * u * w + 1/12 * w ^ 2 + 1/2 * u * w ^ 2 - 1/4 * v ^ 2 * w - 1/2 * u * v ^ 2 * w ^ 2, -1/3 * u * v - 1/3 * v * w - 1/2 * u * v * w - 1/2 * u ^ 2 * v * w ^ 2, 1/9 + 1/4 * u + 1/12 * u ^ 2 + 1/6 * u * w - 1/6 * v ^ 2 + 1/2 * u ^ 2 * w - 1/4 * u * v ^ 2 - 1/2 * u ^ 2 * v ^ 2 * w))
|
|
dN15 = Vec{3, T}((-1/3 * u * v - 1/3 * u * w - 1/2 * u * v * w - 1/2 * u * v ^ 2 * w ^ 2, 1/9 + 1/4 * w - 1/6 * u ^ 2 + 1/6 * v * w + 1/12 * w ^ 2 + 1/2 * v * w ^ 2 - 1/4 * u ^ 2 * w - 1/2 * u ^ 2 * v * w ^ 2, 1/9 + 1/4 * v - 1/6 * u ^ 2 + 1/12 * v ^ 2 + 1/6 * v * w + 1/2 * v ^ 2 * w - 1/4 * u ^ 2 * v - 1/2 * u ^ 2 * v ^ 2 * w))
|
|
dN16 = Vec{3, T}((-1/9 - 1/4 * w + 1/6 * v ^ 2 + 1/6 * u * w - 1/12 * w ^ 2 + 1/2 * u * w ^ 2 + 1/4 * v ^ 2 * w - 1/2 * u * v ^ 2 * w ^ 2, 1/3 * u * v - 1/3 * v * w + 1/2 * u * v * w - 1/2 * u ^ 2 * v * w ^ 2, 1/9 - 1/4 * u + 1/12 * u ^ 2 - 1/6 * u * w - 1/6 * v ^ 2 + 1/2 * u ^ 2 * w + 1/4 * u * v ^ 2 - 1/2 * u ^ 2 * v ^ 2 * w))
|
|
dN17 = Vec{3, T}((-1/9 + 1/4 * v - 1/6 * u * v - 1/12 * v ^ 2 + 1/6 * w ^ 2 + 1/2 * u * v ^ 2 - 1/4 * v * w ^ 2 - 1/2 * u * v ^ 2 * w ^ 2, -1/9 + 1/4 * u - 1/12 * u ^ 2 - 1/6 * u * v + 1/6 * w ^ 2 + 1/2 * u ^ 2 * v - 1/4 * u * w ^ 2 - 1/2 * u ^ 2 * v * w ^ 2, 1/3 * u * w + 1/3 * v * w - 1/2 * u * v * w - 1/2 * u ^ 2 * v ^ 2 * w))
|
|
dN18 = Vec{3, T}((1/9 - 1/4 * v - 1/6 * u * v + 1/12 * v ^ 2 - 1/6 * w ^ 2 + 1/2 * u * v ^ 2 + 1/4 * v * w ^ 2 - 1/2 * u * v ^ 2 * w ^ 2, -1/9 - 1/4 * u - 1/12 * u ^ 2 + 1/6 * u * v + 1/6 * w ^ 2 + 1/2 * u ^ 2 * v + 1/4 * u * w ^ 2 - 1/2 * u ^ 2 * v * w ^ 2, -1/3 * u * w + 1/3 * v * w + 1/2 * u * v * w - 1/2 * u ^ 2 * v ^ 2 * w))
|
|
dN19 = Vec{3, T}((1/9 + 1/4 * v + 1/6 * u * v + 1/12 * v ^ 2 - 1/6 * w ^ 2 + 1/2 * u * v ^ 2 - 1/4 * v * w ^ 2 - 1/2 * u * v ^ 2 * w ^ 2, 1/9 + 1/4 * u + 1/12 * u ^ 2 + 1/6 * u * v - 1/6 * w ^ 2 + 1/2 * u ^ 2 * v - 1/4 * u * w ^ 2 - 1/2 * u ^ 2 * v * w ^ 2, -1/3 * u * w - 1/3 * v * w - 1/2 * u * v * w - 1/2 * u ^ 2 * v ^ 2 * w))
|
|
dN20 = Vec{3, T}((-1/9 - 1/4 * v + 1/6 * u * v - 1/12 * v ^ 2 + 1/6 * w ^ 2 + 1/2 * u * v ^ 2 + 1/4 * v * w ^ 2 - 1/2 * u * v ^ 2 * w ^ 2, 1/9 - 1/4 * u + 1/12 * u ^ 2 - 1/6 * u * v - 1/6 * w ^ 2 + 1/2 * u ^ 2 * v + 1/4 * u * w ^ 2 - 1/2 * u ^ 2 * v * w ^ 2, 1/3 * u * w - 1/3 * v * w + 1/2 * u * v * w - 1/2 * u ^ 2 * v ^ 2 * w))
|
|
dN21 = Vec{3, T}((1/3 * u * w - u * w ^ 2 + u * v ^ 2 * w ^ 2, 1/3 * v * w - v * w ^ 2 + u ^ 2 * v * w ^ 2, -5/18 + w + 1/6 * u ^ 2 + 1/6 * v ^ 2 - u ^ 2 * w - v ^ 2 * w + u ^ 2 * v ^ 2 * w))
|
|
dN22 = Vec{3, T}((-1/3 * u * w - u * w ^ 2 + u * v ^ 2 * w ^ 2, -1/3 * v * w - v * w ^ 2 + u ^ 2 * v * w ^ 2, 5/18 + w - 1/6 * u ^ 2 - 1/6 * v ^ 2 - u ^ 2 * w - v ^ 2 * w + u ^ 2 * v ^ 2 * w))
|
|
dN23 = Vec{3, T}((1/3 * u * v - u * v ^ 2 + u * v ^ 2 * w ^ 2, -5/18 + v + 1/6 * u ^ 2 + 1/6 * w ^ 2 - u ^ 2 * v - v * w ^ 2 + u ^ 2 * v * w ^ 2, 1/3 * v * w - v ^ 2 * w + u ^ 2 * v ^ 2 * w))
|
|
dN24 = Vec{3, T}((-1/3 * u * v - u * v ^ 2 + u * v ^ 2 * w ^ 2, 5/18 + v - 1/6 * u ^ 2 - 1/6 * w ^ 2 - u ^ 2 * v - v * w ^ 2 + u ^ 2 * v * w ^ 2, -1/3 * v * w - v ^ 2 * w + u ^ 2 * v ^ 2 * w))
|
|
dN25 = Vec{3, T}((-5/18 + u + 1/6 * v ^ 2 + 1/6 * w ^ 2 - u * v ^ 2 - u * w ^ 2 + u * v ^ 2 * w ^ 2, 1/3 * u * v - u ^ 2 * v + u ^ 2 * v * w ^ 2, 1/3 * u * w - u ^ 2 * w + u ^ 2 * v ^ 2 * w))
|
|
dN26 = Vec{3, T}((5/18 + u - 1/6 * v ^ 2 - 1/6 * w ^ 2 - u * v ^ 2 - u * w ^ 2 + u * v ^ 2 * w ^ 2, -1/3 * u * v - u ^ 2 * v + u ^ 2 * v * w ^ 2, -1/3 * u * w - u ^ 2 * w + u ^ 2 * v ^ 2 * w))
|
|
dN27 = Vec{3, T}((-2 * u + 2 * u * v ^ 2 + 2 * u * w ^ 2 - 2 * u * v ^ 2 * w ^ 2, -2 * v + 2 * u ^ 2 * v + 2 * v * w ^ 2 - 2 * u ^ 2 * v * w ^ 2, -2 * w + 2 * u ^ 2 * w + 2 * v ^ 2 * w - 2 * u ^ 2 * v ^ 2 * w))
|
|
return SVector{27, Vec{3, T}}(dN1, dN2, dN3, dN4, dN5, dN6, dN7, dN8, dN9, dN10, dN11, dN12, dN13, dN14, dN15, dN16, dN17, dN18, dN19, dN20, dN21, dN22, dN23, dN24, dN25, dN26, dN27)
|
|
end
|
|
|
|
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
# Lagrange{1} on Pyr5: 5-node linear pyramid element
|
|
# (legacy name: Pyr5)
|
|
|
|
@inline function get_basis_functions(::Pyr5, ::Lagrange{1}, xi::Vec{3, T}) where T
|
|
(u, v, w) = xi
|
|
N1 = 1/4 - 1/4 * u - 1/4 * v - 1/4 * w
|
|
N2 = 1/4 + 1/4 * u - 1/4 * v - 1/4 * w
|
|
N3 = 1/4 + 1/4 * u + 1/4 * v - 1/4 * w
|
|
N4 = 1/4 - 1/4 * u + 1/4 * v - 1/4 * w
|
|
N5 = w
|
|
return SVector{5, T}(N1, N2, N3, N4, N5)
|
|
end
|
|
|
|
@inline function get_basis_derivatives(::Pyr5, ::Lagrange{1}, xi::Vec{3, T}) where T
|
|
(u, v, w) = xi
|
|
dN1 = Vec{3, T}((-1/4, -1/4, -1/4))
|
|
dN2 = Vec{3, T}((1/4, -1/4, -1/4))
|
|
dN3 = Vec{3, T}((1/4, 1/4, -1/4))
|
|
dN4 = Vec{3, T}((-1/4, 1/4, -1/4))
|
|
dN5 = Vec{3, T}((0, 0, 1))
|
|
return SVector{5, Vec{3, T}}(dN1, dN2, dN3, dN4, dN5)
|
|
end
|
|
|
|
|
|
# ──────────────────────────────────────────────────────────────────────────────
|
|
# Lagrange{1} on Wedge6: 6-node linear wedge (prism) element
|
|
# (legacy name: Wedge6)
|
|
|
|
@inline function get_basis_functions(::Wedge6, ::Lagrange{1}, xi::Vec{3, T}) where T
|
|
(u, v, w) = xi
|
|
N1 = 1/2 - 1/2 * u - 1/2 * v - 1/2 * w + 1/2 * u * w + 1/2 * v * w
|
|
N2 = 1/2 * u - 1/2 * u * w
|
|
N3 = 1/2 * v - 1/2 * v * w
|
|
N4 = 1/2 - 1/2 * u - 1/2 * v + 1/2 * w - 1/2 * u * w - 1/2 * v * w
|
|
N5 = 1/2 * u + 1/2 * u * w
|
|
N6 = 1/2 * v + 1/2 * v * w
|
|
return SVector{6, T}(N1, N2, N3, N4, N5, N6)
|
|
end
|
|
|
|
@inline function get_basis_derivatives(::Wedge6, ::Lagrange{1}, xi::Vec{3, T}) where T
|
|
(u, v, w) = xi
|
|
dN1 = Vec{3, T}((-1/2 + 1/2 * w, -1/2 + 1/2 * w, -1/2 + 1/2 * u + 1/2 * v))
|
|
dN2 = Vec{3, T}((1/2 - 1/2 * w, 0, -1/2 * u))
|
|
dN3 = Vec{3, T}((0, 1/2 - 1/2 * w, -1/2 * v))
|
|
dN4 = Vec{3, T}((-1/2 - 1/2 * w, -1/2 - 1/2 * w, 1/2 - 1/2 * u - 1/2 * v))
|
|
dN5 = Vec{3, T}((1/2 + 1/2 * w, 0, 1/2 * u))
|
|
dN6 = Vec{3, T}((0, 1/2 + 1/2 * w, 1/2 * v))
|
|
return SVector{6, Vec{3, T}}(dN1, dN2, dN3, dN4, dN5, dN6)
|
|
end
|
|
|