Degrees of Freedom

Degrees of freedom (dofs) are distributed by the DofHandler or the MixedDofHandler.

Ferrite.DofHandlerType
DofHandler(grid::Grid)

Construct a DofHandler based on grid.

Operates slightly faster than MixedDofHandler. Supports:

  • Grids with a single concrete cell type.
  • One or several fields on the whole domaine.
source
Ferrite.MixedDofHandlerType
MixedDofHandler(grid::Grid)

Construct a MixedDofHandler based on grid. Supports:

  • Grids with or without concrete element type (E.g. "mixed" grids with several different element types.)
  • One or several fields, which can live on the whole domain or on subsets of the Grid.
source

Adding fields to the DofHandlers

Ferrite.add!Method
add!(dh::AbstractDofHandler, name::Symbol, dim::Int[, ip::Interpolation])

Add a dim-dimensional Field called name which is approximated by ip to dh.

The field is added to all cells of the underlying grid. In case no interpolation ip is given, the default interpolation of the grid's celltype is used. If the grid uses several celltypes, add!(dh::MixedDofHandler, fh::FieldHandler) must be used instead.

source
Ferrite.FieldType
Field(name::Symbol, interpolation::Interpolation, dim::Int)

Construct dim-dimensional Field called name which is approximated by interpolation.

The interpolation is used for distributing the degrees of freedom.

source
Ferrite.FieldHandlerType
FieldHandler(fields::Vector{Field}, cellset::Set{Int})

Construct a FieldHandler based on an array of Fields and assigns it a set of cells.

A FieldHandler must fulfill the following requirements:

  • All Cells in cellset are of the same type.
  • Each field only uses a single interpolation on the cellset.
  • Each cell belongs only to a single FieldHandler, i.e. all fields on a cell must be added within the same FieldHandler.

Notice that a FieldHandler can hold several fields.

source
Ferrite.close!Method
close!(dh::AbstractDofHandler)

Closes dh and creates degrees of freedom for each cell.

If there are several fields, the dofs are added in the following order: For a MixedDofHandler, go through each FieldHandler in the order they were added. For each field in the FieldHandler or in the DofHandler (again, in the order the fields were added), create dofs for the cell. This means that dofs on a particular cell, the dofs will be numbered according to the fields; first dofs for field 1, then field 2, etc.

source

Dof renumbering

Ferrite.renumber!Function
renumber!(dh::AbstractDofHandler, order)
renumber!(dh::AbstractDofHandler, ch::ConstraintHandler, order)

Renumber the degrees of freedom in the DofHandler and/or ConstraintHandler according to the ordering order.

order can be given by one of the following options:

  • A permutation vector perm::AbstractVector{Int} such that dof i is renumbered to perm[i].
  • DofOrder.FieldWise() for renumbering dofs field wise.
  • DofOrder.ComponentWise() for renumbering dofs component wise.
  • DofOrder.Ext{T} for "external" renumber permutations, see documentation for DofOrder.Ext for details.
Warning

The dof numbering in the DofHandler and ConstraintHandler must always be consistent. It is therefore necessary to either renumber before creating the ConstraintHandler in the first place, or to renumber the DofHandler and the ConstraintHandler together.

source
Ferrite.DofOrder.FieldWiseType
DofOrder.FieldWise()
DofOrder.FieldWise(target_blocks::Vector{Int})

Dof order passed to renumber! to renumber global dofs field wise resulting in a globally blocked system.

The default behavior is to group dofs of each field into their own block, with the same order as in the DofHandler. This can be customized by passing a vector of the same length as the total number of fields in the DofHandler (see getfieldnames(dh)) that maps each field to a "target block": to renumber a DofHandler with three fields :u, :v, :w such that dofs for :u and :w end up in the first global block, and dofs for :v in the second global block use DofOrder.FieldWise([1, 2, 1]).

This renumbering is stable such that the original relative ordering of dofs within each target block is maintained.

source
Ferrite.DofOrder.ComponentWiseType
DofOrder.ComponentWise()
DofOrder.ComponentWise(target_blocks::Vector{Int})

Dof order passed to renumber! to renumber global dofs component wise resulting in a globally blocked system.

The default behavior is to group dofs of each component into their own block, with the same order as in the DofHandler. This can be customized by passing a vector of length ncomponents that maps each component to a "target block" (see DofOrder.FieldWise for details).

This renumbering is stable such that the original relative ordering of dofs within each target block is maintained.

source

Common methods

Ferrite.ndofsFunction
ndofs(dh::AbstractDofHandler)

Return the number of degrees of freedom in dh

source
Ferrite.ndofs_per_cellFunction
ndofs_per_cell(dh::AbstractDofHandler[, cell::Int=1])

Return the number of degrees of freedom for the cell with index cell.

See also ndofs.

source
Ferrite.dof_rangeFunction
dof_range(fh::FieldHandler, field_idx::Int)
dof_range(fh::FieldHandler, field_name::Symbol)
dof_range(dh:MixedDofHandler, field_name::Symbol)

Return the local dof range for a given field. The field can be specified by its name or index, where field_idx represents the index of a field within a FieldHandler and field_idxs is a tuple of the FieldHandler-index within the MixedDofHandler and the field_idx.

Note

The dof_range of a field can vary between different FieldHandlers. Therefore, it is advised to use the field_idxs or refer to a given FieldHandler directly in case several FieldHandlers exist. Using the field_name will always refer to the first occurrence of field within the MixedDofHandler.

Example:

julia> grid = generate_grid(Triangle, (3, 3))
Grid{2, Triangle, Float64} with 18 Triangle cells and 16 nodes

julia> dh = MixedDofHandler(grid); add!(dh, :u, 3); add!(dh, :p, 1); close!(dh);

julia> dof_range(dh, :u)
1:9

julia> dof_range(dh, :p)
10:12

julia> dof_range(dh, (1,1)) # field :u
1:9

julia> dof_range(dh.fieldhandlers[1], 2) # field :p
10:12
source
dof_range(dh:DofHandler, field_name)

Return the local dof range for field_name. Example:

julia> grid = generate_grid(Triangle, (3, 3))
Grid{2, Triangle, Float64} with 18 Triangle cells and 16 nodes

julia> dh = DofHandler(grid); add!(dh, :u, 3); add!(dh, :p, 1); close!(dh);

julia> dof_range(dh, :u)
1:9

julia> dof_range(dh, :p)
10:12
source
Ferrite.celldofsFunction
celldofs(dh::AbstractDofHandler, i::Int)

Return a vector with the degrees of freedom that belong to cell i.

See also celldofs!.

source
Ferrite.celldofs!Function
celldofs!(global_dofs::Vector{Int}, dh::AbstractDofHandler, i::Int)

Store the degrees of freedom that belong to cell i in global_dofs.

See also celldofs.

source

CellIterator

Ferrite.CellCacheType
CellCache(grid::Grid)
CellCache(dh::AbstractDofHandler)

Create a cache object with pre-allocated memory for the nodes, coordinates, and dofs of a cell. The cache is updated for a new cell by calling reinit!(cache, cellid) where cellid::Int is the cell id.

Struct fields of CellCache

  • cc.nodes :: Vector{Int}: global node ids
  • cc.coords :: Vector{<:Vec}: node coordinates
  • cc.dofs :: Vector{Int}: global dof ids (empty when constructing the cache from a grid)

Methods with CellCache

  • reinit!(cc, i): reinitialize the cache for cell i
  • cellid(cc): get the cell id of the currently cached cell
  • getnodes(cc): get the global node ids of the cell
  • getcoordinates(cc): get the coordinates of the cell
  • celldofs(cc): get the global dof ids of the cell
  • reinit!(fev, cc): reinitialize CellValues or FaceValues

See also CellIterator.

source
Ferrite.CellIteratorType
CellIterator(grid::Grid, cellset=1:getncells(grid))
CellIterator(dh::AbstractDofHandler, cellset=1:getncells(dh))

Create a CellIterator to conveniently iterate over all, or a subset, of the cells in a grid. The elements of the iterator are CellCaches which are properly reinit!ialized. See CellCache for more details.

Looping over a CellIterator, i.e.:

for cc in CellIterator(grid, cellset)
    # ...
end

is thus simply convenience for the following equivalent snippet:

cc = CellCache(grid)
for idx in cellset
    reinit!(cc, idx)
    # ...
end
source