Degrees of Freedom

The distribution and numbering of degrees of freedom (dofs) are handled by the DofHandler. The DofHandler will be used to query information about the dofs. For example we can obtain the dofs for a particular cell, which we need when assembling the system.

The DofHandler is based on the grid. Here we create a simple grid with Triangle cells, and then create a DofHandler based on the grid

grid = generate_grid(Triangle, (20, 20))
dh = DofHandler(grid)
DofHandler
  Fields:
  Not closed!

Fields

Before we can distribute the dofs we need to specify fields. A field is simply the unknown function(s) we are solving for. To add a field we need a name (a Symbol) and we also need to specify number of components for the field. Here we add a vector field :u (2 components for a 2D problem) and a scalar field :p.

add!(dh, :u, 2)
add!(dh, :p, 1)
DofHandler
  Fields:
    :u, interpolation: Lagrange{2, RefTetrahedron, 1}(), dim: 2
    :p, interpolation: Lagrange{2, RefTetrahedron, 1}(), dim: 1
  Not closed!

Finally, when we have added all the fields, we have to close! the DofHandler. When the DofHandler is closed it will traverse the grid and distribute all the dofs for the fields we added.

close!(dh)
DofHandler
  Fields:
    :u, interpolation: Lagrange{2, RefTetrahedron, 1}(), dim: 2
    :p, interpolation: Lagrange{2, RefTetrahedron, 1}(), dim: 1
  Dofs per cell: 9
  Total dofs: 1323

Specifying interpolation for a field

In the example above we did not specify which interpolation should be used for our fields :u and :p. By default iso-parametric elements will be used meaning that the interpolation that matches the grid will be used – for a linear grid a linear interpolation will be used etc. It is sometimes useful to separate the grid interpolation from the interpolation that is used to approximate our fields (e.g. sub- and super-parametric elements).

We can specify which interpolation that should be used for the approximation when we add the fields to the dofhandler. For example, here we add our vector field :u with a quadratic interpolation, and our :p field with a linear approximation.

add!(dh, :u, 2, Lagrange{2,RefTetrahedron,2}())
add!(dh, :p, 1, Lagrange{2,RefTetrahedron,1}())
DofHandler
  Fields:
    :u, interpolation: Lagrange{2, RefTetrahedron, 2}(), dim: 2
    :p, interpolation: Lagrange{2, RefTetrahedron, 1}(), dim: 1
  Not closed!

Ordering of Dofs

ordered in the same order as we add to dofhandler nodes -> (edges ->) faces -> cells