and it is somewhat implicitly assumed that the basis for the element is a nodal basis, e.g. N(xi, eta) = (xi, eta, 1-xi-eta) in this particular case. We should extend this definition by explicitly giving a basis, which defaults to nodal basis. So we can have Tri3{CG}, Tri3{Morley}, Tri3{DKT} and so on. We could implement this several ways, here's couple options:
abstract type AbstractBasis end
struct CG <: AbstractBasis end
struct Morley <: AbstractBasis end
abstract type AbstractTopology end
struct Tet10{T<:AbstractBasis} <: AbstractTopology end
abstract type AbstractElement end
struct Element{T<:AbstractTopology} <: AbstractElement
# rest of stuff ...
topology :: T
end
Element(Tet10{CG}())
# output
Element{Tet10{CG}}(Tet10{CG}())
Other way is
struct Tet4 <: AbstractTopology end
struct Element2{T<:AbstractTopology, B<:AbstractBasis} <: AbstractElement
# rest of stuff ...
topology :: T
basis :: B
end
Element2(Tet4(), CG())
# output
Element2{Tet4,CG}(Tet4(), CG())
I don't know which one is better or is there maybe third and better way to think this. Anyway we can do this change so that element = Element(Tri3, [1, 2, 3]) is still working and having CG basis as default one:
function Element2(::Type{T}, connectivity) where {T <: AbstractTopology}
return Element2(T(), CG())
end
Element2(Tet4, [1, 2, 3, 4])
# output
Element2{Tet4,CG}(Tet4(), CG())
Currently, we define elements using style
and it is somewhat implicitly assumed that the basis for the element is a nodal basis, e.g.
N(xi, eta) = (xi, eta, 1-xi-eta)
in this particular case. We should extend this definition by explicitly giving a basis, which defaults to nodal basis. So we can haveTri3{CG}
,Tri3{Morley}
,Tri3{DKT}
and so on. We could implement this several ways, here's couple options:Other way is
I don't know which one is better or is there maybe third and better way to think this. Anyway we can do this change so that
element = Element(Tri3, [1, 2, 3])
is still working and having CG basis as default one: