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.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.vals
20-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.
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