Assemblers

This section describes the assemblers that are currently available and their abstract interface.

All assemblers must possess at minimum a DofManager.

The assemblers possess all the baggage to use the internal method sparse! in SparseArrays.jl. This method allows for a zero allocation instantiation of a SparseMatrixCSC type on the CPU. There are also methods available to ease in the conversion of CSC types and other sparse types such as CSR.

On the GPU, however, this type is first converted to an appropriate COO matrix type on the desired backend. There is unfortunately not a unified sparse matrix API in julia for GPUs, so we implement this functionality in package extensions. On CUDA, for example, the operational sequence to get a CuSparseMatrixCSC is to first sort the COO (row, col, val) triplets so they are ordered by row and then column. Then a CuSparseMatrixCOO type is created and converted to a CuSparseMatrixCSC type via CUDA.jl methods. An identical approach is taken for RocM types.

NOTE: This is one of the most actively developed areas of the package. Please use caution with any method beginning with a "_" as these are internal methods that will change without notice.

Matrix Diagonal

FiniteElementContainers.assemble_diagonal!Method
assemble_diagonal!(assembler, func::Function, Uu, p)

Assemble the diagonal of a matrix (e.g., stiffness or mass) into the assembler's residual storage field. Uses the same physics function as assemble_stiffness! / assemble_mass! but extracts only the diagonal entries of the element matrix at each quadrature point, avoiding full sparse matrix assembly.

The result is stored in the assembler's residual storage and can be retrieved via diagonal(asm).

This is essential for GPU-friendly Jacobi preconditioning: diag(K) gives the true diagonal, whereas the row-sum approximation K·1 can be zero at interior nodes of uniform meshes.

source
FiniteElementContainers.diagonalMethod
diagonal(
    asm::FiniteElementContainers.AbstractAssembler
) -> Any

Return the assembled diagonal vector after a call to assemble_diagonal!. Extracts the unknown DOF subset (non-condensed) or the full vector (condensed).

source

Matrices

FiniteElementContainers.assemble_matrix!Method
assemble_matrix!(
    storage,
    pattern,
    dof,
    func::Function,
    Uu,
    p;
    use_inplace_methods
)

Note this is hard coded to storing the assembled sparse matrix in the stiffness_storage field of assembler.

source

Matrix Action

FiniteElementContainers.assemble_matrix_free_action!Method
assemble_matrix_free_action!(
    assembler,
    func_action::Function,
    Uu,
    Vu,
    p
)

Matrix-free action assembly. func_action has signature funcaction(physics, interps, xel, t, Δt, uel, uelold, vel, stateoldq, statenewq, propsel) → SVector and returns the element-level product Kq·v_el directly, avoiding formation of the full element stiffness/mass matrix.

source

Matrix Action

Scalar

FiniteElementContainers.assemble_quadrature_quantity!Method
assemble_quadrature_quantity!(
    storage::L2Field,
    pattern,
    dof,
    func::Function,
    Uu,
    p
) -> Any
assemble_quadrature_quantity!(
    storage::L2Field,
    pattern,
    dof,
    func::Function,
    Uu,
    p,
    return_type::FiniteElementContainers.AssembledReturnType
) -> Any
source
FiniteElementContainers.assemble_quadrature_quantity!Method
assemble_quadrature_quantity!(
    storage::NamedTuple,
    pattern,
    dof,
    func::Function,
    Uu,
    p
)
assemble_quadrature_quantity!(
    storage::NamedTuple,
    pattern,
    dof,
    func::Function,
    Uu,
    p,
    return_type::FiniteElementContainers.AssembledReturnType
)
source

Sources

Vector

Weakly enforced BCs

FiniteElementContainers._assemble_block_vector_weakly_enforced_bc!Method
_assemble_block_vector_weakly_enforced_bc!(
    field::FiniteElementContainers.AbstractField,
    U::FiniteElementContainers.AbstractField,
    X::FiniteElementContainers.AbstractField,
    conns,
    ref_fe,
    sides,
    vals
)

TODO this method needs to be updated to allow for sparse vectors TODO this method is hardcoded to H1 or L2 spaces

source

Abstract Interface

FiniteElementContainers.hessianMethod
hessian(
    asm::FiniteElementContainers.AbstractAssembler
) -> Any

The Hessian operator currently aliases the assembled stiffness — no FE code path in this repository writes a separate Hessian buffer. If a future caller needs H ≠ K, add a dedicated hessian_storage field on the assembler and specialize this method accordingly.

source

Assembly methods that are safe with Enzyme.jl

FiniteElementContainers._assemble_block_enzyme_safe!Method
_assemble_block_enzyme_safe!(
    _::KernelAbstractions.CPU,
    field::FiniteElementContainers.AbstractField,
    conns::AbstractArray,
    coffset::Int64,
    func::Function,
    physics::AbstractPhysics,
    ref_fe::ReferenceFiniteElements.ReferenceFE,
    X::FiniteElementContainers.AbstractField,
    t::Number,
    dt::Number,
    U::FiniteElementContainers.AbstractField,
    U_old::FiniteElementContainers.AbstractField,
    state_old,
    state_new,
    props::AbstractArray,
    return_type::FiniteElementContainers.AssembledReturnType
)

Assembly method for a block labelled as block_id. This is a CPU implementation with no threading.

TODO add state variables and physics properties

source

SparseMatrixAssembler

FiniteElementContainers.SparseMatrixAssemblerType
struct SparseMatrixAssembler{Condensed, SparseMatrixType, UseInPlaceMethods, UseSparseVec, IV<:AbstractVector{Int64}, RV<:AbstractVector{Float64}, Var<:FiniteElementContainers.AbstractFunction, FieldStorage} <: FiniteElementContainers.AbstractAssembler{DofManager{Condensed, Int64, IV<:AbstractVector{Int64}, Var<:FiniteElementContainers.AbstractFunction}}

General sparse matrix assembler that can handle first or second order problems in time.

source
FiniteElementContainers.SparseMatrixAssemblerMethod
SparseMatrixAssembler(
    dof::DofManager;
    sparse_matrix_type,
    use_inplace_methods,
    use_sparse_vector,
    matrix_free
) -> Union{SparseMatrixAssembler{_A, _B, _C, _D, var"#s177", Vector{Float64}, var"#s1771", H1Field{Float64, Vector{Float64}, _A1}} where {NF, var"#s1771"<:FiniteElementContainers.AbstractFunction{F, NF}, _A1}, SparseMatrixAssembler{_A, _B, _C, _D, var"#s177", Vector{Float64}, Var, H1Field{Float64, Vector{Float64}, _A1}} where {NF, Var<:FiniteElementContainers.AbstractFunction{F, NF}, _A1}} where {_A, _B, _C, _D, var"#s177"<:AbstractVector{Int64}, F<:FunctionSpace}

Construct a SparseMatrixAssembler for a specific field type, e.g. H1Field. Can be used to create block arrays for mixed FEM problems.

source

SparsityPattern