Skip to content

About

Extra finite element spaces for Ferrite.jl

Resources

Stars

7 stars

Watchers

1 watching

Forks

Latest commit

 

History

74 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FerriteInterpolations.jl

Finite element interpolations from the DefElement encyclopedia for use with Ferrite.jl.

The implementations are, to a large extent, automated/robot translations of the element tabulations in DefElement (through its reference implementation symfem) into Ferrite's conventions: reference cells, entity numbering, DOF ordering, and orientation handling. Every implemented basis is cross-checked against symfem in the test suite, except where an element deliberately follows its original paper instead of DefElement (Fortin–Soulie, Crouzeix–Falk; see the table).

This package implements elements that Ferrite does not (yet) provide itself. Elements that already exist in Ferrite are deliberately not re-implemented here — see Implemented in Ferrite for that list, including notes on degrees/cells Ferrite covers and gaps.

Elements

Element names link to their DefElement entries. The Type column gives the interpolation type to use; "-" means the element is not available.

Implemented

Interpolations implemented in this package.

Element Type Notes
bernstein Bernstein line 1–3, triangle 1–3, tetrahedron 1–2 (tet ≥ 3 needs #5)
brezzi-douglas-fortin-marini BrezziDouglasFortinMarini triangle, degrees 1–2
brezzi-douglas-marini BDM triangle, degree 2 (degree 1 is Ferrite's BrezziDouglasMarini, see below)
bubble Bubble line 2–3, triangle 3–4, tetrahedron 4
conforming-crouzeix-raviart ConformingCrouzeixRaviart triangle, degrees 2–4 (degree 1 coincides with P1 Lagrange)
crouzeix-falk CrouzeixFalk triangle (degree 3), as in the original paper: edge DOFs at the three Gauss–Legendre points of each edge. Differs from DefElement, which uses the equispaced points 1/4, 1/2, 3/4; with those the patch test fails and the method loses two orders of convergence. Only the span (full P3) is cross-checked against symfem
dPc DPC quadrilateral 1–3, hexahedron 1–2, with the L2 Piola mapping; on the interval it coincides with DiscontinuousLagrange
enriched-galerkin EnrichedGalerkin every cell/degree Ferrite's Lagrange supports
fortin-soulie FortinSoulie triangle (degree 2), as in the original paper: continuous P2 plus one neutral function per cell, continuous at the Gauss–Legendre points of each edge (spans the full Gauss-continuous space on simply connected domains; a proper subspace on domains with holes). Differs from DefElement's definition, which uses an asymmetric local element (and, in symfem up to 2025.12, the edge points 1/3 and 2/3, see mscroggs/symfem#344); see the file header and #33
gauss-legendre GaussLegendre line/quadrilateral/hexahedron, any degree (modal basis, following symfem)
nedelec2 NedelecSecondKind triangle, degrees 1–2
radau Radau interval degree 2 (degree ≥ 3 has no symfem reference; quad/hex need #2)
taylor Taylor line/triangle, degrees 1–2, with the cell-dependent TaylorMapping
tnt-curl TNTCurl quadrilateral, degree 1
tnt-div TNTDiv quadrilateral, degree 1
transition Transition triangle, interior order 2, per-edge orders 1–2 (tuple type parameter)
trimmed-serendipity-curl TrimmedSerendipityCurl quadrilateral, degree 1
trimmed-serendipity-div TrimmedSerendipityDiv quadrilateral, degree 1
vector dPc DPC^vdim vectorized DPC (VectorizedInterpolation)

Blocked

Elements that cannot currently be implemented against Ferrite (each linked issue describes the required upstream changes), or that are out of scope.

Element Type Notes
alfeld-sorokina - blocked (macro split + derivative DOFs): #21
argyris - blocked (derivative DOFs): #7
arnold-boffi-falk - blocked (Kirby mapping): #14
arnold-winther - blocked (matrix-valued): #25
bell - blocked (derivative DOFs): #8
bernardi-raugel - blocked (geometry-dependent facet DOFs): #13
bogner-fox-schmitt - blocked (derivative DOFs): #12
brezzi-douglas-duran-fortin - blocked (3D face DOF orientation): #28
buffa-christiansen - out of scope (dual polygon element)
direct-serendipity - blocked (basis built on the physical cell): #29
dual - out of scope (dual polygon element)
gopalakrishnan-lederer-schoberl - blocked (matrix-valued): #27
guzman-neilan (first kind) - blocked (macro split): #22
guzman-neilan (second kind) - blocked (macro split): #22
hellan-herrmann-johnson - blocked (matrix-valued): #26
hermite - blocked (derivative DOFs): #6
hsieh-clough-tocher - blocked (macro split): #18
huang-zhang - blocked (tangential edge moments): #16
johnson-mercier - blocked (macro split, matrix-valued): #23
mardal-tai-winther - blocked (tangential edge moments): #15
morley - blocked (normal-derivative DOFs): #9
morley-wang-xu - blocked (normal-derivative DOFs): #10
nonconforming-arnold-winther - blocked (matrix-valued): #25
p1-iso-p2 - blocked (macro split): #19
p1-macro - blocked (macro split): #20
reduced-hsieh-clough-tocher - blocked (macro split): #18
regge - blocked (matrix-valued): #24
rotated-buffa-christiansen - out of scope (dual polygon element)
tnt (scalar) - blocked (sign-flipping edge moment weights): #17

Implemented in Ferrite

These DefElement entries are not re-implemented in this package because Ferrite.jl (v1.6) already provides them, possibly for a subset of the degrees and reference cells that DefElement defines. Extending their coverage belongs upstream in Ferrite — except where a note says a gap is filled here under a different type name.

Degrees are given in Ferrite's numbering. For Raviart–Thomas and Nédélec (first kind), DefElement degree k corresponds to Ferrite degree k + 1.

Element Type Notes
brezzi-douglas-marini BrezziDouglasMarini triangle 1. Degree 2 is BDM in this package (distinct name to avoid clashing with Ferrite's type); triangle ≥ 3 missing; tetrahedron blocked upstream (face-orientation DOF transformations)
bubble-enriched-lagrange BubbleEnrichedLagrange triangle 1; DefElement degree 2 missing
crouzeix-raviart CrouzeixRaviart triangle 1, tetrahedron 1; higher odd degrees missing
crouzeix-raviart (quad/hex) RannacherTurek quadrilateral 1, hexahedron 1
lagrange Lagrange line 1–2, triangle 1–5, quadrilateral 1–3, tetrahedron 1–4, hexahedron 1–3, prism 1–2, pyramid 1–2; higher degrees missing on all cells (DefElement is unbounded)
lagrange (discontinuous) DiscontinuousLagrange as Lagrange, plus degree 0 on every cell
nedelec1 Nedelec triangle 1–2, quadrilateral 1, tetrahedron 1, hexahedron 1; same gaps as RaviartThomas, prism missing entirely
raviart-thomas RaviartThomas triangle 1–2, quadrilateral 1, tetrahedron 1, hexahedron 1; triangle ≥ 3 and quadrilateral ≥ 2 missing; tet/hex ≥ 2 additionally blocked upstream (> 1 DOF per face needs face-orientation DOF transformations)
serendipity Serendipity quadrilateral 2, hexahedron 2. Ferrite uses edge-midpoint point evaluations instead of DefElement's integral moments (same span, different basis). Degree ≥ 3 missing (edge DOFs become integral moments; the edge-reversal permutation no longer applies — needs upstream DOF transformations)
vector-bubble-enriched-lagrange BubbleEnrichedLagrange^2 via vectorization; follows the scalar element
vector-lagrange Lagrange^vdim via vectorization; follows Lagrange
vector-q Lagrange^vdim via vectorization; follows Lagrange

Boundary conditions

The elements are defined on a single cell; how boundary conditions are applied in a mesh depends on what the DOFs on the boundary facets determine. Natural (Neumann) conditions are applied as usual (facet integrals with FacetValues) for every element. For Dirichlet conditions, the elements fall into these classes (each is tested by solving a model problem whose exact solution lies in the discrete space, see test/test_utils.jl):

Class How to apply Dirichlet conditions Where the boundary condition holds Elements
Nodal, conforming Dirichlet on the whole boundary facet (for data in the trace space; otherwise the facet interpolant of the data) ConformingCrouzeixRaviart, Radau, Transition (on order-1 edges the trace is the linear interpolant)
Nonconforming Dirichlet at the points where the global space is continuous: the Gauss–Legendre points of the boundary edges CrouzeixFalk, FortinSoulie (the conditions act on the vertex/midpoint DOFs; the neutral cell function is nonzero on the boundary except at the Gauss points)
H(div) / H(curl) ProjectedDirichlet (facet L2 projection of the normal / tangential component) normal / tangential trace on the whole boundary facet (for data in the trace space) BDM, BrezziDouglasFortinMarini, TrimmedSerendipityDiv, TNTDiv; NedelecSecondKind, TrimmedSerendipityCurl, TNTCurl
Discontinuous / no boundary DOFs weakly, e.g. Nitsche / symmetric interior penalty (Dirichlet constrains nothing or errors) weakly DPC, GaussLegendre, Taylor, EnrichedGalerkin (the per-cell constant is nonzero on the boundary, so constraining the Lagrange DOFs would not fix the trace)
Vanishes on the boundary nothing to apply (homogeneous by construction) everywhere on the boundary Bubble (used as an enrichment)
Not supported weakly, or through AffineConstraints with the Bernstein coefficients of the data (Dirichlet needs point-evaluation DOFs, ProjectedDirichlet is H(div)/H(curl) only) – Bernstein

For Ferrite's own interpolations the same classes apply: Lagrange, Serendipity and BubbleEnrichedLagrange are nodal and conforming; RaviartThomas, BrezziDouglasMarini and Nedelec use ProjectedDirichlet; CrouzeixRaviart is nonconforming (Dirichlet acts at the facet midpoints); DiscontinuousLagrange accepts Dirichlet on the nodes of the boundary facets but is typically used with weak conditions.

Structure

  • One source file per element in src/, defining an interpolation type in Ferrite's style (e.g. Bernstein{RefTriangle, 2}()).
  • Elements that cannot currently be implemented against Ferrite (they need upstream changes, e.g. general DOF transformations, matrix-valued interpolations, or macro-element support) also get one file each, containing a description of the required upstream changes and a placeholder type whose constructor throws. These are not exported.
  • One test file per element in test/, with interpolation-level tests (properties, reference tabulation tables) and integration tests via CellValues/FacetValues.
  • Elements that exist in Ferrite also get one test file each, with symfem cross-checks only (Ferrite's own test suite covers the rest). Their bases agree with symfem up to a signed permutation (scaled by the Piola factor of the reference-cell map for RaviartThomas/Nedelec on hypercubes), except Serendipity, where only the spans agree since Ferrite uses edge-midpoint point evaluations instead of integral moments.

Development setup

The package is developed against a local Ferrite checkout (sibling directory ../Ferrite):

julia --project=. -e 'using Pkg; Pkg.develop(path="../Ferrite"); Pkg.instantiate()'
julia --project=. -e 'using Pkg; Pkg.test()'

Manifest.toml is intentionally not committed.

Caveats

  • Ferrite's interpolation interface is unexported and documented as not fully stable; this package implements Ferrite.-qualified internal methods and pins Ferrite = "1.6" in [compat] as a guard.
  • The test suite cross-checks every basis against symfem (DefElement's reference implementation), imported live via PythonCall — a test-only dependency; test/CondaPkg.toml provisions Python and symfem automatically. Note that symfem/DefElement and Ferrite differ in reference cell coordinates and in entity numbering/ordering — test_symfem_reference maps the coordinates, and each element's test file documents its DOF permutation.

About

Extra finite element spaces for Ferrite.jl

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages