Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# CHANGES

## v1.2.0 June 25, 2025
- major documentation and docstring overhaul
- improved show functions and constructors for FEMatrix, FEVector
- added range check in getindex functions for FEVector
- added slice views for FEVectorBlocks
- added Array conversions for FEVector and FEVectorBlock

## v1.1.1 June 16, 2025
- docstring improvements

Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "ExtendableFEMBase"
uuid = "12fb9182-3d4c-4424-8fd1-727a0899810c"
authors = ["Christian Merdon <[email protected]>", "Patrick Jaap <[email protected]>"]
version = "1.1.1"
version = "1.2.0"

[deps]
DiffResults = "163ba53b-c6d8-5494-b064-1a9d43ac40c5"
Expand Down
22 changes: 8 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,13 @@

# ExtendableFEMBase

This package provides basic finite element structures to setup finite element schemes on ExtendableGrids. For a full high-level API
see [ExtendableFEM.jl](https://github.com/WIAS-PDELib/ExtendableFEM.jl).
ExtendableFEMBase.jl provides foundational data structures and tools for assembling custom finite element solvers in Julia. It is designed for flexibility, efficiency, and extensibility, and serves as the low-level backend for [ExtendableFEM.jl](https://github.com/WIAS-PDELib/ExtendableFEM.jl). All functionality is built on top of [ExtendableGrids.jl](https://github.com/WIAS-PDELib/ExtendableGrids.jl).

This low level structures in the package incorporate:
## Features

- Finite element types (Basis functions on reference geometries and dof management for several H1, Hdiv and Hcurl elements)
- FESpace (Discrete finite element space with respect to a mesh from ExtendableGrids, knows the Dofmaps)
- FEMatrix (block overlay for an ExtendableSparse matrix, where each block corresponds to a coupling between two FESpaces in a system)
- FEVector (block overlay for an array, where each block corresponds to a FESpace)
- FunctionOperators (primitive linear operators like Identity, Gradient, Divergence) and rules how to evaluate them for for different finite element types
- FEEvaluator (finite element basis evaluators for different FunctionOperators and entities of the grid)
- QuadratureRule (basic quadrature rules for different ElementGeometries from ExtendableGrids)
- interpolations (standard interpolations into the provided finite element spaces, averaging routines and interpolations between meshes/FESpaces)
- reconstruction operators (special FunctionOperators that involve an interpolation into a different finite element type)


- Wide range of finite element types (H1, Hdiv, Hcurl, etc.)
- Flexible finite element spaces (`FESpace`)
- Block-structured matrices and vectors (`FEMatrix`, `FEVector`)
- Primitive and composite function operators (e.g., gradient, divergence)
- Efficient basis evaluation and quadrature routines
- Interpolation and reconstruction operators
32 changes: 14 additions & 18 deletions docs/src/examples_intro.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,24 @@
# About the examples
# About the Examples

The examples have been designed with the following issues in mind:
- they run from the Julia REPL
- each example is a Julia module named similar to the basename of the example file.
- an example can be used as the starting point for a project
- some examples define test cases for the test suite
- ExampleXYZ with X = A can be considered advanced and uses low-level structures
and/or demonstrates customisation features or experimental features
- the default output of the main function is printed on the website and can be
used to check if the code runs as expected (unfortunately REPL messages are not recorded)
- printed assembly and solving times (especially in a first iteration) can be much larger due to first-run compilation times
The provided examples are designed with the following goals in mind:
- They can be run directly from the Julia REPL.
- Each example is implemented as a Julia module, named similarly to the file's basename.
- Examples can serve as starting points for your own projects.
- Some examples include test cases that are integrated into the test suite.
- Assembly and solve times (especially for the first run) may be significantly higher due to Julia's just-in-time compilation.


## Running the examples

In order to run `ExampleXXX`, perform the following steps:

- Download the example file (e.g. via the source code link at the top)
- Make sure all used packages are installed in your Julia environment
- In the REPL:
```
julia> include("ExampleXXX.jl")`
- Download the example file (e.g., using the source code link at the top of the page).
- Ensure all required packages are installed in your Julia environment.
- In the Julia REPL, run:

```julia
julia> include("ExampleXXX.jl")
julia> ExampleXXX.main()
```
- Some examples offer visual output via the optional argument Plotter = PyPlot or Plotter = GLMakie
(provided the package PyPlot/GLMakie is installed and loaded)

- Some examples provide visual output via the optional argument `Plotter = PyPlot` or `Plotter = GLMakie` (these require the corresponding plotting package to be installed and loaded).
3 changes: 2 additions & 1 deletion docs/src/feevaluator.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@

# FEEvaluator

FEEvaluators provide a structure that handles the evaluation of finite element basis functions for a given function operator, quadrature rule and item geometry. It stores the evaluations on the reference geometry (where derivatives are computed by automatic differentiation) and on the current mesh item. The current mesh item can be changed via the update! call.
The `FEEvaluator` provides a unified interface for evaluating finite element basis functions, their derivatives, and related quantities for a given function operator, quadrature rule, and mesh entity. It manages the storage and reuse of basis evaluations both on the reference element (where derivatives are computed via automatic differentiation) and on the current mesh item. The mesh item context can be updated dynamically using the `update!` function.


```@autodocs
Modules = [ExtendableFEMBase]
Expand Down
2 changes: 1 addition & 1 deletion docs/src/fematrix.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# FEMatrix

A FEMatrix consists of FEMatrixBlocks that share a common ExtendableSparseMatrix. Each block is associated to two FESpaces and can only write into a submatrix of the common sparse matrix specified by offsets.
A `FEMatrix` represents a block-structured finite element matrix, where each block (a `FEMatrixBlock`) corresponds to a pair of finite element spaces and operates on a submatrix of a shared `ExtendableSparseMatrix`.

```@autodocs
Modules = [ExtendableFEMBase]
Expand Down
34 changes: 15 additions & 19 deletions docs/src/fems.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@

# Implemented Finite Elements

This page describes the finite element type-tree and lists all implemented finite elements.


This page provides an overview of the finite element type hierarchy and lists all finite elements currently implemented in ExtendableFEMBase.

## The Finite Element Type-Tree
## The Finite Element Type Hierarchy

Finite elements are abstract type leaves in a type-tree. The complete tree looks like this:
Finite elements in ExtendableFEMBase are organized as leaves in an abstract type hierarchy. The complete type tree is as follows:

```
AbstractFiniteElement
Expand Down Expand Up @@ -40,21 +37,20 @@ AbstractFiniteElement


#### Remarks
- each type depends on one/two or three parameters, the first one is always the number of components (ncomponents) that determines if the
finite element is scalar- or veector-valued; some elements additionally require the parameter edim <: Int if they are structurally different in different space dimensions; arbitrary order elements require a third parameter that determines the order
- each finite elements mainly comes with a set of basis functions in reference coordinates for each applicable AbstractElementGeometry and degrees of freedom maps for each mesh entity
- broken finite elements are possible via the broken switch in the [FESpace](@ref) constructor
- the type steers how the basis functions are transformed from local to global coordinates and how FunctionOperators are evaluated
- depending on additional continuity properties of the element types more basis function sets are defined:
- AbstractH1FiniteElements additionally have evaluations of nonzero basisfunctions on faces/bfaces
- AbstractHdivFiniteElements additionally have evaluations of nonzero normalfluxes of basisfunctions on faces/bfaces
- AbstractHcurlFiniteElements additionally have evaluations of nonzero tangentfluxes of basisfunctions on edges/bedges
- each finite element has its own implemented standard interpolation interpolate! (see [Finite Element Interpolations](@ref)) that can be applied to a function with header function(result, qpinfo), below it is shortly described what this means for each finite element
- Each finite element type depends on one, two, or three parameters. The first parameter is always the number of components (`ncomponents`), which determines whether the element is scalar- or vector-valued. Some elements also require the parameter `edim <: Int` if their structure differs by spatial dimension. Arbitrary order elements require a third parameter specifying the polynomial order.
- Each finite element provides a set of basis functions in reference coordinates for each applicable `AbstractElementGeometry`, as well as degree-of-freedom (dof) maps for each mesh entity.
- Discontinuous (broken) finite elements can be created using the `broken` switch in the [`FESpace`](@ref) constructor.
- The element type determines how basis functions are transformed from local to global coordinates and how `FunctionOperators` are evaluated.
- Additional continuity properties of element types lead to more specialized basis function sets:
- `AbstractH1FiniteElement` types provide evaluations of nonzero basis functions on faces/boundary faces.
- `AbstractHdivFiniteElement` types provide evaluations of nonzero normal fluxes of basis functions on faces/boundary faces.
- `AbstractHcurlFiniteElement` types provide evaluations of nonzero tangential fluxes of basis functions on edges/boundary edges.
- Each finite element has its own standard interpolation routine `interpolate!` (see [Finite Element Interpolations](@ref)), which can be applied to a function with the signature `function(result, qpinfo)`. The specific interpolation behavior is described for each element below.


## List of implemented Finite Elements
## List of Implemented Finite Elements

The following table lists all currently implemented finite elements and on which geometries they are available (in brackets a dofmap pattern for CellDofs is shown and the number of local degrees of freedom for a vector-valued realisation). Click on the FEType to find out more details.
The following table summarizes all finite elements currently implemented in ExtendableFEMBase and indicates the reference geometries on which they are available. For each entry, the dofmap pattern for cell degrees of freedom is shown in brackets, along with the number of local degrees of freedom for a vector-valued realization. Click on an FEType to view more details.

| FEType | Triangle2D | Parallelogram2D | Tetrahedron3D | Parallelepiped3D |
| :----------------: | :----------------: | :----------------: | :----------------: | :----------------: |
Expand Down Expand Up @@ -86,7 +82,7 @@ The following table lists all currently implemented finite elements and on which
| [`HDIVRTkENRICH`](@ref) | ✓ (order-dep) | | ✓ (order-dep) | |


Note: the dofmap pattern describes the connection of the local degrees of freedom to entities of the grid and also hints to the continuity. Here, "N" or "n" means nodes, "F" or "f" means faces, "E" or "e" means edges and "I" means interior (dofs without any continuity across elements). Capital letters cause that every component has its own degree of freedom, while small letters signalize that only one dof is associated to the entity. As an example "N1f1" (for the Bernardi-Raugel element) means that at each node sits one dof per component and at each face sits a single dof. Usually finite elements that involve small letters are only defined vector-valued (i.e. the number of components has to match the element dimension), while finite elements that only involve capital letters are available for any number of components.
Note: The dofmap pattern describes how local degrees of freedom are associated with grid entities and provides insight into the continuity properties of the element. Here, "N" or "n" denotes nodes, "F" or "f" denotes faces, "E" or "e" denotes edges, and "I" denotes interior degrees of freedom (i.e., those without continuity across elements). Capital letters indicate that each component has its own degree of freedom, while lowercase letters mean only one degree of freedom is associated with the entity. For example, "N1f1" (as in the Bernardi-Raugel element) means that each node has one dof per component and each face has a single dof. Typically, finite elements involving lowercase letters are only defined for vector-valued cases (i.e., the number of components must match the element dimension), while those with only capital letters are available for any number of components.


## H1-conforming finite elements
Expand Down
2 changes: 1 addition & 1 deletion docs/src/fespace.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

# FESpace

To generate a finite element space only a finite element type and a grid is needed, dofmaps are generated automatically on their first demand.
A **finite element space** (FESpace) represents the set of all functions that can be expressed using a particular finite element type on a given computational grid. In ExtendableFEMBase, constructing a finite element space requires only specifying the finite element type and the grid; all necessary degree-of-freedom (dof) mappings are generated automatically on first access.

```@autodocs
Modules = [ExtendableFEMBase]
Expand Down
2 changes: 1 addition & 1 deletion docs/src/fevector.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# FEVector

A FEVector consists of FEVectorBlocks that share a common one-dimensional array. Each block is associated to a FESpace and can only write into a region of the common array specified by offsets that stores the degrees of freedom of that FEspace.
A `FEVector` represents a block-structured vector used in finite element computations. It consists of one or more `FEVectorBlock`s, each associated with a specific `FESpace`. All blocks share a common one-dimensional array that stores the global degrees of freedom (DoFs). Each block can only write to a region of the array specified by offsets, ensuring that each `FESpace` manages its own DoFs within the global vector.


```@autodocs
Expand Down
32 changes: 12 additions & 20 deletions docs/src/functionoperators.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@

# Function Operators

## StandardFunctionOperators

StandardFunctionOperators are abstract types that encode primitive (linear) operators (like Identity, Gradient etc.)
used to dispatch different evaluations of finite element basis functions.
`StandardFunctionOperators` are abstract types that represent fundamental (linear) operators, such as the identity, gradient, divergence, and others. These operators provide a unified interface for evaluating finite element basis functions in various ways.

### List of primitive operators
### List of Primitive Operators

| StandardFunctionOperator | Description | Mathematically |
| :--------------------------------------------------- | :------------------------------------------------------- | :------------------------------------------------------------------------ |
Expand All @@ -28,12 +26,9 @@ used to dispatch different evaluations of finite element basis functions.

!!! note

As each finite element type is transformed differently from the reference domain to the general domain,
the evaluation of each function operator has to be implemented for each finite element class.
Currently, not every function operator works in any dimension and for any finite element. More evaluations
are added as soon as they are needed (and possibly upon request).
Also, the function operators can be combined with user-defined actions to evaluate other operators that
can be build from the ones available (e.g. the deviator).
The transformation from the reference domain to the physical domain differs for each finite element class. As a result, the evaluation of each function operator must be implemented specifically for every finite element class. Not all function operators are currently available for every dimension or element type, but new implementations are added as needed or upon request.

Additionally, function operators can be combined with user-defined kernels to postprocess/construct more advanced operators from the available primitives (for example, the deviatoric part of a tensor).


```@autodocs
Expand All @@ -45,25 +40,22 @@ Order = [:type, :function]

## ReconstructionOperators

There are special operators that allow to evaluate a primitive operator of some discrete
reconstructed version of a testfunction.
Special operators are provided to evaluate a primitive operator on a reconstructed version of a test function. These are useful for advanced discretizations and post-processing.

```@autodocs
Modules = [ExtendableFEMBase]
Pages = ["reconstructionoperators.jl"]
Order = [:type, :function]
```

### Divergence-free reconstruction operators
For gradient-robust discretisations of certain classical non divergence-conforming ansatz spaces,
reconstruction operators are available that map a discretely divergence-free H1 function to a pointwise divergence-free
Hdiv function. So far such operators are available for the vector-valued Crouzeix-Raviart (H1CR) and Bernardi--Raugel (H1BR) finite element types,
as well as for the P2-bubble (H1P2B) finite element type in two dimensions.
### Divergence-Free Reconstruction Operators

For gradient-robust discretizations of certain classical non-divergence-conforming ansatz spaces, reconstruction operators are available that map a discretely divergence-free H1 function to a pointwise divergence-free H(div) function. Currently, such operators are implemented for the vector-valued Crouzeix-Raviart (H1CR) and Bernardi–Raugel (H1BR) finite element types, as well as for the P2-bubble (H1P2B) element in two dimensions.

**Example:** Reconst{HDIVRT0{d}, Identity} gives the reconstruction of the Identity operator into HDIVRT0 (and is available for H1BR{d} and H1CR{d} for d = 1,2)
**Example:** `Reconst{HDIVRT0{d}, Identity}` reconstructs the identity operator into HDIVRT0, and is available for `H1BR{d}` and `H1CR{d}` for `d = 1, 2`.



## Operator Pairs (experimental)
## Operator Pairs (Experimental)

Two function operators can be put into an OperatorPair so that one can provide effectively two operators in each argument of an assembly pattern. However, the user should make sure that both operators can be evaluated together reasonably (meaning both should be well-defined on the element geometries and the finite element space where the argument will be evaluated, and the action of the operator has to operate with coressponding input and result fields). This feature is still experimental and might have issues in some cases. OperatorTriple for a combination of three operators is also available.
Two function operators can be combined into an `OperatorPair`, allowing you to provide two operators in each argument of an assembly pattern. Both operators must be well-defined on the relevant element geometries and finite element spaces, and their actions must be compatible with the input and result fields. This feature is experimental and may have limitations in some cases. An `OperatorTriple` is also available for combining three operators.
2 changes: 1 addition & 1 deletion docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

# ExtendableFEMBase.jl

This package provides some low level structures like finite element spaces, interpolors, matrices and vectors to assemble custom finite element solvers based on [ExtendableGrids.jl](https://github.com/j-fu/ExtendableGrids.jl) infrastructure.
ExtendableFEMBase.jl provides foundational data structures and tools for building custom finite element solvers in Julia. The package includes flexible representations for finite element spaces, interpolators, matrices, and vectors, all designed to work seamlessly with the [ExtendableGrids.jl](https://github.com/j-fu/ExtendableGrids.jl) infrastructure.


### Dependencies on other Julia packages
Expand Down
Loading
Loading