Fields

Fields serve as loose wrappers around AbstractArray subtypes such that the size of array slices are known at compile time. Although this introduces a type-instability, the idea is to do this at the top most level (mainly at setup time of a FEM simulation). By introducing this type instability, we can gain information about the field type that is used in methods downstream to construct StaticArrays of views of field types.

All fields are subtypes of the abstract type AbstractField

julia> using FiniteElementContainers
julia> AbstractFieldERROR: UndefVarError: `AbstractField` not defined

Example - H1Field a.k.a. NodalField

We can set up a H1Field in one of two ways. The simplest constructor form can be used as follows

julia> using FiniteElementContainers
julia> field = H1Field(rand(2, 10), (:field_1, :field_2))2×10 H1Field{Float64, 2, Vector{Float64}, (field_1 = 1, field_2 = 2)}: 0.451377 0.969066 0.438278 0.178982 … 0.779407 0.683729 0.33337 0.459782 0.0885674 0.917637 0.403944 0.223429 0.487543 0.613777

This is stored in a vectorized way as can be seen above

julia> field.vals20-element Vector{Float64}:
 0.45137713579117145
 0.4597819921140073
 0.9690656663703828
 0.08856743621400542
 0.43827820404704787
 0.9176368122858228
 0.17898154546554157
 0.4039438406946191
 0.3383351119927308
 0.7380317859671546
 0.8577319865177147
 0.7440719386916873
 0.9833626053302903
 0.5001236876783919
 0.7794065793963474
 0.2234290593213245
 0.6837288310673095
 0.48754314672294063
 0.333370277805486
 0.6137771095784643

Fields can be indexed like regular arrays, e.g.

julia> field[1, 1]0.45137713579117145
julia> field[1, :]10-element Vector{Float64}:
 0.45137713579117145
 0.9690656663703828
 0.43827820404704787
 0.17898154546554157
 0.3383351119927308
 0.8577319865177147
 0.9833626053302903
 0.7794065793963474
 0.6837288310673095
 0.333370277805486

etc.

But they can also be indexed by the symbols provided during construction

julia> field[:field_1]10-element Vector{Float64}:
 0.45137713579117145
 0.9690656663703828
 0.43827820404704787
 0.17898154546554157
 0.3383351119927308
 0.8577319865177147
 0.9833626053302903
 0.7794065793963474
 0.6837288310673095
 0.333370277805486

Abstract type

The base type for fields is the AbstractField abstract type.

Any new field added to FiniteElementContainers should be a subtype of this type.

Methods for AbstractField

Base.fill!Method
fill!(
    field::FiniteElementContainers.AbstractField{T, N, NF, V, S},
    v
) -> Any
source
Base.namesMethod
names(
    _::FiniteElementContainers.AbstractField{T, N, NF, Vals, SymIDMap}
) -> Any
source

Implementations

The existing direct subtypes of AbstractField are the following

Connectivity

The connectivity type is a simple alias for L2ElementField defined below

FiniteElementContainers.connectivityMethod
connectivity(
    conn::Connectivity,
    e::Int64
) -> SubArray{_A, 1, P, I, true} where {_A, P<:(Connectivity), I<:Tuple{Base.Slice{T} where T<:Base.OneTo, Int64}}
source

H1 field

FiniteElementContainers.H1FieldType
struct H1Field{T, NF, Vals<:AbstractArray{T, 1}, SymIDMap} <: FiniteElementContainers.AbstractField{T, 2, NF, Vals<:AbstractArray{T, 1}, SymIDMap}

Implementation of fields that live on nodes.

source

L2Element field

FiniteElementContainers.L2ElementFieldType
struct L2ElementField{T, NN, Vals<:AbstractArray{T, 1}, SymIDMap} <: FiniteElementContainers.AbstractField{T, 2, NN, Vals<:AbstractArray{T, 1}, SymIDMap}

Implementation of fields that live on elements.

source

L2Quadrature field

FiniteElementContainers.L2QuadratureFieldType
struct L2QuadratureField{T, NF, NQ, Vals<:AbstractArray{T, 1}, SymIDMap} <: FiniteElementContainers.AbstractField{T, 3, NF, Vals<:AbstractArray{T, 1}, SymIDMap}

Implementation of fields that live on elements.

source

There are plans to add HcurlField and HdivField types as well