diff --git a/docs/src/devdocs/elements.md b/docs/src/devdocs/elements.md index 1fd5a548f6..88c799665a 100644 --- a/docs/src/devdocs/elements.md +++ b/docs/src/devdocs/elements.md @@ -2,24 +2,34 @@ ## Type definitions -Elements or cells are subtypes of `AbstractCell{dim,N,M}`. They are parametrized by -the dimension of their nodes via `dim`, the number of nodes `N` and the number -of faces `M`. +Elements or cells are subtypes of `AbstractCell{<:AbstractRefShape}`. As shown, they are parametrized +by the associated reference element. ### Required methods to implement for all subtypes of `AbstractCell` to define a new element +```@docs +Ferrite.get_node_ids +``` + +### Common utilities and definitions when working with grids internally. + +First we have some topological queries on the element + ```@docs Ferrite.vertices(::Ferrite.AbstractCell) Ferrite.edges(::Ferrite.AbstractCell) -Ferrite.reference_faces(::Ferrite.AbstractRefShape) Ferrite.faces(::Ferrite.AbstractCell) +Ferrite.facets(::Ferrite.AbstractCell) +Ferrite.boundaryfunction(::Type{<:Ferrite.BoundaryIndex}) +Ferrite.reference_vertices(::Ferrite.AbstractCell) +Ferrite.reference_edges(::Ferrite.AbstractCell) +Ferrite.reference_faces(::Ferrite.AbstractCell) ``` -### Common utilities and definitions when working with grids internally. +and some generic utils which are commonly found in finite element codes ```@docs Ferrite.BoundaryIndex -Ferrite.boundaryfunction(::Type{<:Ferrite.BoundaryIndex}) Ferrite.get_coordinate_eltype(::Ferrite.AbstractGrid) Ferrite.get_coordinate_eltype(::Node) Ferrite.toglobal diff --git a/docs/src/devdocs/reference_cells.md b/docs/src/devdocs/reference_cells.md index e48e99264c..e75cf006a0 100644 --- a/docs/src/devdocs/reference_cells.md +++ b/docs/src/devdocs/reference_cells.md @@ -15,3 +15,18 @@ Ferrite.RefTetrahedron Ferrite.RefHexahedron Ferrite.RefPrism ``` + +### Required methods to implement for all subtypes of `AbstractRefShape` to define a new reference shape + +```@docs +Ferrite.reference_vertices(::Type{<:Ferrite.AbstractRefShape}) +Ferrite.reference_edges(::Type{<:Ferrite.AbstractRefShape}) +Ferrite.reference_faces(::Type{<:Ferrite.AbstractRefShape}) +``` + +which automatically defines + + +```@docs +Ferrite.reference_facets(::Type{<:Ferrite.AbstractRefShape}) +``` diff --git a/docs/src/topics/degrees_of_freedom.md b/docs/src/topics/degrees_of_freedom.md index 151834cb09..e044eea9d3 100644 --- a/docs/src/topics/degrees_of_freedom.md +++ b/docs/src/topics/degrees_of_freedom.md @@ -25,8 +25,8 @@ need to specify number of components for the field. Here we add a vector field ` (2 components for a 2D problem) and a scalar field `:p`. ```@example dofs -add!(dh, :u, Lagrange{2,RefTetrahedron,1}()^2) -add!(dh, :p, Lagrange{2,RefTetrahedron,1}()) +add!(dh, :u, Lagrange{RefTriangle, 1}()^2) +add!(dh, :p, Lagrange{RefTriangle, 1}()) # hide ``` @@ -53,12 +53,12 @@ quadratic interpolation, and our `:p` field with a linear approximation. ```@example dofs dh = DofHandler(grid) # hide -add!(dh, :u, Lagrange{2,RefTetrahedron,2}()^2) -add!(dh, :p, Lagrange{2,RefTetrahedron,1}()) +add!(dh, :u, Lagrange{RefTriangle, 2}()^2) +add!(dh, :p, Lagrange{RefTriangle, 1}()) # hide ``` ## Ordering of Dofs ordered in the same order as we add to dofhandler -nodes -> (edges ->) faces -> cells +vertices -> edges -> faces -> volumes diff --git a/src/Grid/grid.jl b/src/Grid/grid.jl index b6d172df7b..a1d2113fab 100644 --- a/src/Grid/grid.jl +++ b/src/Grid/grid.jl @@ -56,6 +56,16 @@ nedges( ::Type{T}) where {T <: AbstractRefShape} = length(reference_edges(T)) nfaces( ::Type{T}) where {T <: AbstractRefShape} = length(reference_faces(T)) nfacets( ::Type{T}) where {T <: AbstractRefShape} = length(reference_facets(T)) + +""" + reference_vertices(::Type{<:AbstractRefShape}) + reference_vertices(::AbstractCell) + +Returns a tuple of integers containing the local node indices corresponding to +the vertices (i.e. corners or endpoints) of the cell. +""" +reference_vertices(::Union{Type{<:AbstractRefShape}, AbstractCell}) + """ Ferrite.vertices(::AbstractCell) @@ -65,6 +75,15 @@ corresponds to the local index into this tuple. """ vertices(::AbstractCell) +""" + reference_edges(::Type{<:AbstractRefShape}) + reference_edges(::AbstractCell) + +Returns a tuple of 2-tuples containing the ordered local node indices +(corresponding to the vertices) that define an edge. +""" +reference_edges(::Union{Type{<:AbstractRefShape}, AbstractCell}) + """ Ferrite.edges(::AbstractCell) @@ -77,17 +96,13 @@ Note that the vertices are sufficient to define an edge uniquely. edges(::AbstractCell) """ - reference_faces(::AbstractRefShape) - -Returns a tuple of n-tuples containing the ordered local node indices corresponding to -the vertices that define an *oriented face*. + reference_faces(::Type{<:AbstractRefShape}) + reference_faces(::AbstractCell) -An *oriented face* is a face with the first node having the local index and the other -nodes spanning such that the normal to the face is pointing outwards. - -Note that the vertices are sufficient to define a face uniquely. +Returns a tuple of n-tuples containing the ordered local node indices +(corresponding to the vertices) that define a face. """ -reference_faces(::AbstractRefShape) +reference_faces(::Union{Type{<:AbstractRefShape}, AbstractCell}) """ Ferrite.faces(::AbstractCell) @@ -120,11 +135,12 @@ facets(::AbstractCell) """ Ferrite.reference_facets(::Type{<:AbstractRefShape}) + Ferrite.reference_facets(::AbstractCell) -Returns a tuple of n-tuples containing the ordered local node indices corresponding to -the vertices that define an oriented facet. +Returns a tuple of n-tuples containing the ordered local node indices +(corresponding to the vertices) that define a facet. -See also [`reference_vertices`](@ref), [`reference_edges`](@ref), and [`reference_faces`](@ref) +See also [`reference_vertices`](@ref), [`reference_edges`](@ref), and [`reference_faces`](@ref). """ reference_facets(::Type{<:AbstractRefShape}) @@ -132,9 +148,14 @@ reference_facets(::Type{<:AbstractRefShape}) @inline reference_facets(refshape::Type{<:AbstractRefShape{2}}) = reference_edges(refshape) @inline reference_facets(refshape::Type{<:AbstractRefShape{3}}) = reference_faces(refshape) +@inline reference_faces(::AbstractCell{refshape}) where refshape = reference_faces(refshape) +@inline reference_edges(::AbstractCell{refshape}) where refshape = reference_edges(refshape) +@inline reference_vertices(::AbstractCell{refshape}) where refshape = reference_vertices(refshape) +@inline reference_facets(::AbstractCell{refshape}) where refshape = reference_facets(refshape) + """ - geometric_interpolation(::AbstractCell) - geometric_interpolation(::Type{<:AbstractCell}) + geometric_interpolation(::AbstractCell)::ScalarInterpolation + geometric_interpolation(::Type{<:AbstractCell})::ScalarInterpolation Each `AbstractCell` type has a unique geometric interpolation describing its geometry. This function returns that interpolation, which is always a scalar interpolation. diff --git a/test/test_grid_dofhandler_vtk.jl b/test/test_grid_dofhandler_vtk.jl index 7677f67348..a3f9d8803a 100644 --- a/test/test_grid_dofhandler_vtk.jl +++ b/test/test_grid_dofhandler_vtk.jl @@ -96,6 +96,11 @@ end @test minv ≈ 2left @test maxv ≈ 2right + # Consistency check for topological queries + @test Ferrite.reference_vertices(getcells(grid,1)) == Ferrite.reference_vertices(Ferrite.getrefshape(celltype)) + @test Ferrite.reference_edges(getcells(grid,1)) == Ferrite.reference_edges(Ferrite.getrefshape(celltype)) + @test Ferrite.reference_faces(getcells(grid,1)) == Ferrite.reference_faces(Ferrite.getrefshape(celltype)) + @test Ferrite.reference_facets(getcells(grid,1)) == Ferrite.reference_facets(Ferrite.getrefshape(celltype)) end end # of testset