DoF handler

Type definitions

Dof handlers are subtypes of AbstractDofhandler{sdim}, i.e. they are parametrized by the spatial dimension. Internally a helper struct InterpolationInfo is utilized to enforce type stability during dof distribution, because the interpolations are not available as concrete types.

Ferrite.InterpolationInfoType
InterpolationInfo

Gathers all the information needed to distribute dofs for a given interpolation. Note that this cache is of the same type no matter the interpolation: the purpose is to make dof-distribution type-stable.

source
Ferrite.PathOrientationInfoType
PathOrientationInfo

Orientation information for 1D entities.

The orientation for 1D entities is defined by the indices of the grid nodes associated to the vertices. To give an example, the oriented path

1 ---> 2

is called regular, indicated by regular=true, while the oriented path

2 ---> 1

is called inverted, indicated by regular=false.

source
Ferrite.SurfaceOrientationInfoType
SurfaceOrientationInfo

Orientation information for 2D entities.

The orientation is defined by the indices of the grid nodes associated to the vertices. 2D entities can be flipped (i.e. the defining vertex order is reverse to the spanning vertex order) and the vertices can be rotated against each other.

The reference entity is one where its first node is the lowest index vertex and its vertices span counter-clock-wise. Take for example the faces

1           2| \         | \|  \        |  \| A \       | B \|    \      |    \2-----3     3-----1

which are rotated against each other by 240° after transforming to an equilateral triangle (shift index is 2). Or the faces

3           2| \         | \|  \        |  \| A \       | B \|    \      |    \2-----1     3-----1

which are flipped against each other.

The same applies to quadrilateral faces. Take for example the faces

1---2     2---3| A |     | B |4---3     1---4

which are rotated against each other by 90° (shift index is 1). Or the faces

1---2     2---1| A |     | B |4---3     3---4

which are flipped against each other.

source

Internal API

The main entry point for dof distribution is __close!.

Ferrite.__close!Function
__close!(dh::DofHandler)

Internal entry point for dof distribution.

Dofs are distributed as follows: For the DofHandler each SubDofHandler is visited in the order they were added. For each field in the SubDofHandler create dofs for the cell. This means that dofs on a particular cell will be numbered in groups for each field, so first the dofs for field 1 are distributed, then field 2, etc. For each cell dofs are first distributed on its vertices, then on the interior of edges (if applicable), then on the interior of faces (if applicable), and finally on the cell interior. The entity ordering follows the geometrical ordering found in vertices, faces and edges.

source
Ferrite.get_gridFunction
get_grid(dh::AbstractDofHandler)

Access some grid representation for the dof handler.

Note

This API function is currently not well-defined. It acts as the interface between distributed assembly and assembly on a single process, because most parts of the functionality can be handled by only acting on the locally owned cell set.

source
Ferrite.find_fieldFunction
find_field(dh::DofHandler, field_name::Symbol)::NTuple{2, Int}

Return the index of the field with name field_name in a DofHandler. The index is a NTuple{2,Int}, where the 1st entry is the index of the SubDofHandler within which the field was found and the 2nd entry is the index of the field within the SubDofHandler.

Note

Always finds the 1st occurrence of a field within DofHandler.

See also: find_field(sdh::SubDofHandler, field_name::Symbol), Ferrite._find_field(sdh::SubDofHandler, field_name::Symbol).

source
find_field(sdh::SubDofHandler, field_name::Symbol)::Int

Return the index of the field with name field_name in a SubDofHandler. Throw an error if the field is not found.

See also: find_field(dh::DofHandler, field_name::Symbol), _find_field(sdh::SubDofHandler, field_name::Symbol).

source
Ferrite._close_subdofhandler!Function
_close_subdofhandler!(dh::DofHandler{sdim}, sdh::SubDofHandler, sdh_index::Int, nextdof::Int, vertexdicts, edgedicts, facedicts) where {sdim}

Main entry point to distribute dofs for a single SubDofHandler on its subdomain.

source
Ferrite._distribute_dofs_for_cell!Function
_distribute_dofs_for_cell!(dh::DofHandler{sdim}, cell::AbstractCell, ip_info::InterpolationInfo, nextdof::Int, vertexdict, edgedict, facedict) where {sdim}

Main entry point to distribute dofs for a single cell.

source
Ferrite.permute_and_push!Function
permute_and_push!

For interpolations with more than one interior dof per edge it may be necessary to adjust the dofs. Since dofs are (initially) enumerated according to the local edge direction there can be a direction mismatch with the neighboring element. For example, in the following nodal interpolation example, with three interior dofs on each edge, the initial pass have distributed dofs 4, 5, 6 according to the local edge directions:

+-----------+|     A     |+--4--5--6->+    local edge on element A ---------->     global edge+<-6--5--4--+    local edge on element B|     B     |+-----------+

For most scalar-valued interpolations we can simply compensate for this by reversing the numbering on all edges that do not match the global edge direction, i.e. for the edge on element B in the example.

In addition, we also have to preserve the ordering at each dof location.

For more details we refer to Scroggs et al. [20] as we follow the methodology described therein.

References

  • [20] Scroggs et al. ACM Trans. Math. Softw. 48 (2022).
source
permute_and_push!(cell_dofs::Vector{Int}, dofs::StepRange{Int, Int}, orientation::SurfaceOrientationInfo, adjust_during_distribution::Bool, interior_facedofs_on_lattice::Bool, nfacevertices::Int, rdim::Int)

Push the dofs belonging to a face onto cell_dofs, in the order corresponding to the local orientation of the face.

For interpolations with multiple interior dofs per face the dofs must be permuted such that all cells sharing the face associate the same dof with the same location on the face. The dofs are stored according to the canonical orientation of the face (the face as spanned by its sorted vertex tuple, see sortface) and this function maps them to the local orientation, given by orientation (see SurfaceOrientationInfo).

This adjustment is necessary for faces that can be shared between 3D cells. Lattice face dofs on 2D cells are canonicalized as well, because a 2D cell can share its interior with a face of a 3D cell when the same field is used in multiple SubDofHandlers. Face dofs on 2D cells that have not opted in to the lattice assumption are pushed in the stored order (such dofs are not necessarily placed on a lattice, e.g. for RaviartThomas{RefTriangle, 2}).

The permutation assumes that the interior dofs are placed on a regular lattice, in the enumeration order specified by facedof_interior_indices. An interpolation must opt in to this assumption via interior_facedofs_on_lattice; otherwise distributing more than one dof on a shared 3D face errors. For a triangular face with vertices $(v_1, v_2, v_3)$ the interior dofs make up a smaller triangular lattice, which is traversed row by row, where rows are lines of constant barycentric $v_2$-weight, starting with the row closest to the edge $(v_3, v_1)$, and each row is traversed with increasing barycentric $v_1$-weight (i.e. starting from the point closest to $v_3$). This matches the interior node ordering of Lagrange{RefTriangle, order}. For a quadrilateral face the interior dofs make up a regular grid which is traversed row by row, where rows are lines of constant local $v_1 \to v_4$ coordinate, starting with the row closest to the edge $(v_1, v_2)$, and each row is traversed in the direction $v_1 \to v_2$. This matches the interior node ordering of Lagrange{RefQuadrilateral, order}.

For more details we refer to Scroggs et al. [20] as we follow the methodology described therein.

References

  • [20] Scroggs et al. ACM Trans. Math. Softw. 48 (2022).
source