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 StaticArray
s of view
s of field types.
All fields are subtypes of the abstract type AbstractField
julia> using FiniteElementContainers
julia> AbstractField
ERROR: 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.212678 0.550354 0.597103 0.779948 … 0.245429 0.0574546 0.610342 0.993382 0.498349 0.754208 0.363127 0.25076 0.812321 0.0671947
This is stored in a vectorized way as can be seen above
julia> field.vals
20-element Vector{Float64}: 0.2126784028615999 0.9933818511183531 0.5503537964553248 0.4983486734745397 0.597102595280999 0.7542083214022596 0.7799479540581684 0.36312670182834916 0.8919653356370845 0.9821409114202011 0.48338822868981257 0.7165050860834522 0.19780085004994663 0.7461579154693333 0.24542936171430652 0.2507595923574921 0.057454558285943924 0.812321194464102 0.6103418299793856 0.06719466582343758
Fields can be indexed like regular arrays, e.g.
julia> field[1, 1]
0.2126784028615999
julia> field[1, :]
10-element Vector{Float64}: 0.2126784028615999 0.5503537964553248 0.597102595280999 0.7799479540581684 0.8919653356370845 0.48338822868981257 0.19780085004994663 0.24542936171430652 0.057454558285943924 0.6103418299793856
etc.
But they can also be indexed by the symbols provided during construction
julia> field[:field_1]
10-element Vector{Float64}: 0.2126784028615999 0.5503537964553248 0.597102595280999 0.7799479540581684 0.8919653356370845 0.48338822868981257 0.19780085004994663 0.24542936171430652 0.057454558285943924 0.6103418299793856
Abstract type
The base type for fields is the AbstractField
abstract type.
FiniteElementContainers.AbstractField
— Typeabstract type AbstractField{T, N, NF, Vals, SymIDMap} <: AbstractArray{T, N}
Thin wrapper that subtypes AbstractArray
and serves as the base Field
type
Any new field added to FiniteElementContainers
should be a subtype of this type.
Methods for AbstractField
Base.fill!
— Methodfill!(
field::FiniteElementContainers.AbstractField{T, N, NF, V, S},
v
) -> Any
Base.names
— Methodnames(
_::FiniteElementContainers.AbstractField{T, N, NF, Vals, SymIDMap}
) -> Any
FiniteElementContainers._sym_id_map
— Method_sym_id_map(
_::FiniteElementContainers.AbstractField{T, N, NF, Vals, SymIDMap},
sym::Symbol
) -> Any
FiniteElementContainers.num_fields
— Methodnum_fields(
_::FiniteElementContainers.AbstractField{T, N, NF, Vals, SymIDMap}
) -> Any
KernelAbstractions.get_backend
— Methodget_backend(
field::FiniteElementContainers.AbstractField
) -> Any
Implementations
The existing direct subtypes of AbstractField
are the following
Connectivity
The connectivity type is a simple alias for L2ElementField
defined below
FiniteElementContainers.Connectivity
— Typestruct L2ElementField{T, NN, Vals, SymIDMap} <: FiniteElementContainers.AbstractField{T, 2, NN, Vals, SymIDMap}
FiniteElementContainers.Connectivity
— MethodFiniteElementContainers.connectivity
— Methodconnectivity(
conn::Connectivity,
e::Int64
) -> SubArray{_A, 1, P, I, true} where {_A, P<:(Connectivity), I<:Tuple{Base.Slice{T} where T<:Base.OneTo, Int64}}
FiniteElementContainers.connectivity
— Methodconnectivity(conn::Connectivity) -> Any
H1 field
FiniteElementContainers.H1Field
— Typestruct 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.
FiniteElementContainers.H1Field
— MethodH1Field(vals::AbstractMatrix, syms) -> H1Field
FiniteElementContainers.num_nodes
— Methodnum_nodes(field::H1Field{T, NF, Vals, SymIDMap}) -> Any
L2Element field
FiniteElementContainers.L2ElementField
— Typestruct 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.
FiniteElementContainers.L2ElementField
— MethodL2ElementField(vals::AbstractMatrix, syms) -> L2ElementField
FiniteElementContainers.num_elements
— Methodnum_elements(
field::L2ElementField{T, NN, Vals, SymIDMap}
) -> Any
FiniteElementContainers.num_nodes_per_element
— Methodnum_nodes_per_element(field::L2ElementField) -> Any
L2Quadrature field
FiniteElementContainers.L2QuadratureField
— Typestruct 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.
There are plans to add HcurlField
and HdivField
types as well