Greetings,
I’d like to share two companion fpm packages for writing finite element codes:
- fortran_cubatures: Gaussian integration points and weights on the six reference elements (line, triangle, quadrilateral, tetrahedron, hexahedron, wedge) for any degree of exactness. No dependencies.
- fortran_shapefuncs: shape functions and their first and second derivatives at those points.
use cubatures
use shapefuncs
type(cubature) :: q
type(shapefunc) :: s
q = cubature(CUB_HEX, 4) ! integration points
s = shapefunc(q, 2) ! 27-node hexahedron at those points
print *, s%nnodes, sum(s%func(:,1)) ! 27 1.0
s = shapefunc(q, 2, family=SHP_SERENDIPITY) ! 20 nodes
Packages’ contents
- Any degree or order, with separate degrees per direction on tensor-product elements. Wedges included.
- All weights positive, all points inside the element. Tests check that each rule integrates every monomial up to its degree exactly.
- Lagrange elements of any order, serendipity elements, and mapped infinite elements for unbounded domains. Node numbering is the classical one or set at run time.
- Pure procedures, no module state.
- CI on Linux with gfortran, ifx, LLVM flang and nvfortran, plus gfortran on macOS and gfortran and ifx on Windows.
As far as I could find, nothing else in Fortran covers this: stdlib and quadpack are one-dimensional, triasymq is FORTRAN 77 without line or wedge rules, and solvers like Elmer keep their shape functions internal. Corrections are welcome if I missed something.
How they were made
I originally wrote these modules for use in FEAP for my research. For this release, I used Claude Code extensively to generalize both modules to arbitrary element order, add serendipity elements, expand the tests, and polish them for GitHub release. I’ve started verifying the packages with an FE modal analysis project, also on my page. The code hasn’t been independently reviewed, so I’d especially welcome eyes on the higher order elements.
Each repo also has an AGENTS.md with instructions for coding agents working on the package, and an llms.txt with the whole API in one plain-text file (it’s also the source of the user manual).
Install (shapefuncs pulls in cubatures):
[dependencies]
fortran_shapefuncs = { git = "https://github.com/willklausler/fortran_shapefuncs", tag = "v0.2.0" }
Docs: cubatures · shapefuncs
DOI: 10.5281/zenodo.23300827 · 10.5281/zenodo.23301496
Question: would hierarchical bases, or node numberings that match Gmsh or VTK, be useful to you?