Reference documentation for deal.II version 9.1.1
|
Namespaces | |
Compositing | |
Classes | |
class | FEFactory |
class | FEFactoryBase |
Functions | |
template<int dim, int spacedim> | |
void | compute_component_wise (const FiniteElement< dim, spacedim > &fe, std::vector< unsigned int > &renumbering, std::vector< std::vector< unsigned int >> &start_indices) |
template<int dim, int spacedim> | |
void | compute_block_renumbering (const FiniteElement< dim, spacedim > &fe, std::vector< types::global_dof_index > &renumbering, std::vector< types::global_dof_index > &block_data, bool return_start_indices=true) |
template<int dim> | |
void | hierarchic_to_lexicographic_numbering (unsigned int degree, std::vector< unsigned int > &h2l) |
template<int dim> | |
std::vector< unsigned int > | hierarchic_to_lexicographic_numbering (const FiniteElementData< dim > &fe_data) |
template<int dim> | |
void | lexicographic_to_hierarchic_numbering (const FiniteElementData< dim > &fe_data, std::vector< unsigned int > &l2h) |
template<int dim> | |
std::vector< unsigned int > | lexicographic_to_hierarchic_numbering (const FiniteElementData< dim > &fe_data) |
template<int dim, int spacedim = dim> | |
std::unique_ptr< FiniteElement< dim, spacedim > > | get_fe_by_name (const std::string &name) |
template<int dim> | |
FiniteElement< dim, dim > * | get_fe_from_name (const std::string &name) |
template<int dim, int spacedim> | |
void | add_fe_name (const std::string &name, const FEFactoryBase< dim, spacedim > *factory) |
static ::ExceptionBase & | ExcInvalidFEName (std::string arg1) |
static ::ExceptionBase & | ExcInvalidFEDimension (char arg1, int arg2) |
static ::ExceptionBase & | ExcInvalidFE () |
static ::ExceptionBase & | ExcFENotPrimitive () |
static ::ExceptionBase & | ExcTriangulationMismatch () |
static ::ExceptionBase & | ExcHangingNodesNotAllowed () |
static ::ExceptionBase & | ExcGridNotRefinedAtLeastOnce () |
static ::ExceptionBase & | ExcMatrixDimensionMismatch (int arg1, int arg2, int arg3, int arg4) |
static ::ExceptionBase & | ExcLeastSquaresError (double arg1) |
static ::ExceptionBase & | ExcNotGreaterThan (int arg1, int arg2) |
Generation of local matrices | |
template<int dim, typename number , int spacedim> | |
void | get_interpolation_matrix (const FiniteElement< dim, spacedim > &fe1, const FiniteElement< dim, spacedim > &fe2, FullMatrix< number > &interpolation_matrix) |
template<int dim, typename number , int spacedim> | |
void | get_back_interpolation_matrix (const FiniteElement< dim, spacedim > &fe1, const FiniteElement< dim, spacedim > &fe2, FullMatrix< number > &interpolation_matrix) |
template<int dim, typename number , int spacedim> | |
void | get_interpolation_difference_matrix (const FiniteElement< dim, spacedim > &fe1, const FiniteElement< dim, spacedim > &fe2, FullMatrix< number > &difference_matrix) |
template<int dim, typename number , int spacedim> | |
void | get_projection_matrix (const FiniteElement< dim, spacedim > &fe1, const FiniteElement< dim, spacedim > &fe2, FullMatrix< number > &matrix) |
template<int dim, int spacedim> | |
FullMatrix< double > | compute_node_matrix (const FiniteElement< dim, spacedim > &fe) |
template<int dim, typename number , int spacedim> | |
void | compute_embedding_matrices (const FiniteElement< dim, spacedim > &fe, std::vector< std::vector< FullMatrix< number >>> &matrices, const bool isotropic_only=false, const double threshold=1.e-12) |
template<int dim, typename number , int spacedim> | |
void | compute_face_embedding_matrices (const FiniteElement< dim, spacedim > &fe, FullMatrix< number >(&matrices)[GeometryInfo< dim >::max_children_per_face], const unsigned int face_coarse, const unsigned int face_fine, const double threshold=1.e-12) |
template<int dim, typename number , int spacedim> | |
void | compute_projection_matrices (const FiniteElement< dim, spacedim > &fe, std::vector< std::vector< FullMatrix< number >>> &matrices, const bool isotropic_only=false) |
template<int dim, int spacedim> | |
void | compute_projection_from_quadrature_points_matrix (const FiniteElement< dim, spacedim > &fe, const Quadrature< dim > &lhs_quadrature, const Quadrature< dim > &rhs_quadrature, FullMatrix< double > &X) |
template<int dim, int spacedim> | |
void | compute_interpolation_to_quadrature_points_matrix (const FiniteElement< dim, spacedim > &fe, const Quadrature< dim > &quadrature, FullMatrix< double > &I_q) |
template<int dim> | |
void | compute_projection_from_quadrature_points (const FullMatrix< double > &projection_matrix, const std::vector< Tensor< 1, dim >> &vector_of_tensors_at_qp, std::vector< Tensor< 1, dim >> &vector_of_tensors_at_nodes) |
template<int dim> | |
void | compute_projection_from_quadrature_points (const FullMatrix< double > &projection_matrix, const std::vector< SymmetricTensor< 2, dim >> &vector_of_tensors_at_qp, std::vector< SymmetricTensor< 2, dim >> &vector_of_tensors_at_nodes) |
template<int dim, int spacedim> | |
void | compute_projection_from_face_quadrature_points_matrix (const FiniteElement< dim, spacedim > &fe, const Quadrature< dim - 1 > &lhs_quadrature, const Quadrature< dim - 1 > &rhs_quadrature, const typename DoFHandler< dim, spacedim >::active_cell_iterator &cell, const unsigned int face, FullMatrix< double > &X) |
template<int dim, int spacedim, typename number > | |
void | convert_generalized_support_point_values_to_dof_values (const FiniteElement< dim, spacedim > &finite_element, const std::vector< Vector< number >> &support_point_values, std::vector< number > &dof_values) |
Functions which should be in DoFTools | |
template<int dim, int spacedim, template< int, int > class DoFHandlerType1, template< int, int > class DoFHandlerType2, class InVector , class OutVector > | |
void | interpolate (const DoFHandlerType1< dim, spacedim > &dof1, const InVector &u1, const DoFHandlerType2< dim, spacedim > &dof2, OutVector &u2) |
template<int dim, int spacedim, template< int, int > class DoFHandlerType1, template< int, int > class DoFHandlerType2, class InVector , class OutVector > | |
void | interpolate (const DoFHandlerType1< dim, spacedim > &dof1, const InVector &u1, const DoFHandlerType2< dim, spacedim > &dof2, const AffineConstraints< typename OutVector::value_type > &constraints, OutVector &u2) |
template<int dim, template< int, int > class DoFHandlerType, class InVector , class OutVector , int spacedim> | |
void | back_interpolate (const DoFHandlerType< dim, spacedim > &dof1, const InVector &u1, const FiniteElement< dim, spacedim > &fe2, OutVector &u1_interpolated) |
template<int dim, class InVector , class OutVector , int spacedim> | |
void | back_interpolate (const DoFHandler< dim, spacedim > &dof1, const AffineConstraints< typename OutVector::value_type > &constraints1, const InVector &u1, const DoFHandler< dim, spacedim > &dof2, const AffineConstraints< typename OutVector::value_type > &constraints2, OutVector &u1_interpolated) |
template<int dim, class InVector , class OutVector , int spacedim> | |
void | interpolation_difference (const DoFHandler< dim, spacedim > &dof1, const InVector &z1, const FiniteElement< dim, spacedim > &fe2, OutVector &z1_difference) |
template<int dim, class InVector , class OutVector , int spacedim> | |
void | interpolation_difference (const DoFHandler< dim, spacedim > &dof1, const AffineConstraints< typename OutVector::value_type > &constraints1, const InVector &z1, const DoFHandler< dim, spacedim > &dof2, const AffineConstraints< typename OutVector::value_type > &constraints2, OutVector &z1_difference) |
template<int dim, class InVector , class OutVector , int spacedim> | |
void | project_dg (const DoFHandler< dim, spacedim > &dof1, const InVector &u1, const DoFHandler< dim, spacedim > &dof2, OutVector &u2) |
template<int dim, class InVector , class OutVector , int spacedim> | |
void | extrapolate (const DoFHandler< dim, spacedim > &dof1, const InVector &z1, const DoFHandler< dim, spacedim > &dof2, OutVector &z2) |
template<int dim, class InVector , class OutVector , int spacedim> | |
void | extrapolate (const DoFHandler< dim, spacedim > &dof1, const InVector &z1, const DoFHandler< dim, spacedim > &dof2, const AffineConstraints< typename OutVector::value_type > &constraints, OutVector &z2) |
This namespace offers interpolations and extrapolations of discrete functions of one FiniteElement
fe1
to another FiniteElement
fe2
.
It also provides the local interpolation matrices that interpolate on each cell. Furthermore it provides the difference matrix \(id-I_h\) that is needed for evaluating \((id-I_h)z\) for e.g. the dual solution \(z\).
For more information about the spacedim
template parameter check the documentation of FiniteElement or the one of Triangulation.
void FETools::compute_component_wise | ( | const FiniteElement< dim, spacedim > & | fe, |
std::vector< unsigned int > & | renumbering, | ||
std::vector< std::vector< unsigned int >> & | start_indices | ||
) |
Compute the vector required to renumber the dofs of a cell by component. Furthermore, compute the vector storing the start indices of each component in the local block vector.
The second vector is organized such that there is a vector for each base element containing the start index for each component served by this base element.
While the first vector is checked to have the correct size, the second one is reinitialized for convenience.
void FETools::compute_block_renumbering | ( | const FiniteElement< dim, spacedim > & | fe, |
std::vector< types::global_dof_index > & | renumbering, | ||
std::vector< types::global_dof_index > & | block_data, | ||
bool | return_start_indices = true |
||
) |
Compute the vector required to renumber the dofs of a cell by block. Furthermore, compute the vector storing either the start indices or the size of each local block vector.
If the bool
parameter is true, block_data
is filled with the start indices of each local block. If it is false, then the block sizes are returned.
The vector renumbering
will be indexed by the standard numbering of local degrees of freedom, namely the first vertex, then the second vertex, after vertices lines, quads, and hexes. For each index, the entry indicates the index which this degree of freedom receives in a numbering scheme, where the first block is numbered completely before the second.
void FETools::get_interpolation_matrix | ( | const FiniteElement< dim, spacedim > & | fe1, |
const FiniteElement< dim, spacedim > & | fe2, | ||
FullMatrix< number > & | interpolation_matrix | ||
) |
Compute the interpolation matrix that interpolates a fe1-function
to a fe2-function
on each cell. The interpolation_matrix needs to be of size (fe2.dofs_per_cell, fe1.dofs_per_cell)
.
Note, that if the finite element space fe1
is a subset of the finite element space fe2
then the interpolation_matrix
is an embedding matrix.
void FETools::get_back_interpolation_matrix | ( | const FiniteElement< dim, spacedim > & | fe1, |
const FiniteElement< dim, spacedim > & | fe2, | ||
FullMatrix< number > & | interpolation_matrix | ||
) |
Compute the interpolation matrix that interpolates a fe1-function
to a fe2-function
, and interpolates this to a second fe1-function
on each cell. The interpolation_matrix needs to be of size (fe1.dofs_per_cell, fe1.dofs_per_cell)
.
Note, that this function only makes sense if the finite element space due to fe1
is not a subset of the finite element space due to fe2
, as if it were a subset then the interpolation_matrix
would be only the unit matrix.
void FETools::get_interpolation_difference_matrix | ( | const FiniteElement< dim, spacedim > & | fe1, |
const FiniteElement< dim, spacedim > & | fe2, | ||
FullMatrix< number > & | difference_matrix | ||
) |
Compute the identity matrix minus the back interpolation matrix. The difference_matrix
will be of size (fe1.dofs_per_cell, fe1.dofs_per_cell)
after this function. Previous content of the argument will be overwritten.
This function computes the matrix that transforms a fe1
function \(z\) to \(z-I_hz\) where \(I_h\) denotes the interpolation operator from the fe1
space to the fe2
space. This matrix hence is useful to evaluate error-representations where \(z\) denotes the dual solution.
void FETools::get_projection_matrix | ( | const FiniteElement< dim, spacedim > & | fe1, |
const FiniteElement< dim, spacedim > & | fe2, | ||
FullMatrix< number > & | matrix | ||
) |
Compute the local \(L^2\)-projection matrix from fe1 to fe2.
FullMatrix<double> FETools::compute_node_matrix | ( | const FiniteElement< dim, spacedim > & | fe | ) |
This is a rather specialized function used during the construction of finite element objects. It is used to build the basis of shape functions for an element, given a set of polynomials and interpolation points. The function is only implemented for finite elements with exactly dim
vector components. In particular, this applies to classes derived from the FE_PolyTensor class.
Specifically, the purpose of this function is as follows: FE_PolyTensor receives, from its derived classes, an argument that describes a polynomial space. This space may be parameterized in terms of monomials, or in some other way, but is in general not in the form that we use for finite elements where we typically want to use a basis that is derived from some kind of node functional (e.g., the interpolation at specific points). Concretely, assume that the basis used by the polynomial space is \(\{\tilde\varphi_j(\mathbf x)\}_{j=1}^N\), and that the node functionals of the finite element are \(\{\Psi_i\}_{i=1}^N\). We then want to compute a basis \(\{\varphi_j(\mathbf x)\}_{j=1}^N\) for the finite element space so that \(\Psi_i[\varphi_j] = \delta_{ij}\). To do this, we can set \(\varphi_j(\mathbf x) = \sum_{k=1}^N c_{jk} \tilde\varphi_k(\mathbf x)\) where we need to determine the expansion coefficients \(c_{jk}\). We do this by applying \(\Psi_i\) to both sides of the equation, to obtain
\begin{align*} \Psi_i [\varphi_j] = \sum_{k=1}^N c_{jk} \Psi_i[\tilde\varphi_k], \end{align*}
and we know that the left hand side equals \(\delta_{ij}\). If you think of this as a system of \(N\times N\) equations for the elements of a matrix on the left and on the right, then this can be written as
\begin{align*} I = C X^T \end{align*}
where \(C\) is the matrix of coefficients \(c_{jk}\) and \(X_{ik} = \Psi_i[\tilde\varphi_k]\). Consequently, in order to compute the expansion coefficients \(C=X^{-T}\), we need to apply the node functionals to all functions of the "raw" basis of the polynomial space.
Until the finite element receives this matrix \(X\) back, it describes its shape functions (e.g., in FiniteElement::shape_value()) in the form \(\tilde\varphi_j\). After it calls this function, it has the expansion coefficients and can describe its shape functions as \(\varphi_j\).
This function therefore computes this matrix \(X\), for the following specific circumstances:
dim
vector components.fe | The finite element for which the operations above are to be performed. |
void FETools::compute_embedding_matrices | ( | const FiniteElement< dim, spacedim > & | fe, |
std::vector< std::vector< FullMatrix< number >>> & | matrices, | ||
const bool | isotropic_only = false , |
||
const double | threshold = 1.e-12 |
||
) |
For all possible (isotropic and anisotropic) refinement cases compute the embedding matrices from a coarse cell to the child cells. Each column of the resulting matrices contains the representation of a coarse grid basis function by the fine grid basis; the matrices are split such that there is one matrix for every child.
This function computes the coarse grid function in a sufficiently large number of quadrature points and fits the fine grid functions using least squares approximation. Therefore, the use of this function is restricted to the case that the finite element spaces are actually nested.
Note, that matrices[refinement_case-1][child]
includes the embedding (or prolongation) matrix of child child
for the RefinementCase refinement_case
. Here, we use refinement_case-1
instead of refinement_case
as for RefinementCase::no_refinement(=0) there are no prolongation matrices available.
Typically this function is called by the various implementations of FiniteElement classes in order to fill the respective FiniteElement::prolongation matrices.
fe | The finite element class for which we compute the embedding matrices. |
matrices | A reference to RefinementCase<dim>::isotropic_refinement vectors of FullMatrix objects. Each vector corresponds to one RefinementCase refinement_case and is of the vector size GeometryInfo<dim>::n_children(refinement_case). This is the format used in FiniteElement, where we want to use this function mostly. |
isotropic_only | Set to true if you only want to compute matrices for isotropic refinement. |
threshold | is the gap allowed in the least squares algorithm computing the embedding. |
void FETools::compute_face_embedding_matrices | ( | const FiniteElement< dim, spacedim > & | fe, |
FullMatrix< number >(&) | matrices[GeometryInfo< dim >::max_children_per_face], | ||
const unsigned int | face_coarse, | ||
const unsigned int | face_fine, | ||
const double | threshold = 1.e-12 |
||
) |
Compute the embedding matrices on faces needed for constraint matrices.
fe | The finite element for which to compute these matrices. |
matrices | An array of GeometryInfo<dim>::subfaces_per_face = 2dim-1 FullMatrix objects,holding the embedding matrix for each subface. |
face_coarse | The number of the face on the coarse side of the face for which this is computed. |
face_fine | The number of the face on the refined side of the face for which this is computed. |
threshold | is the gap allowed in the least squares algorithm computing the embedding. |
void FETools::compute_projection_matrices | ( | const FiniteElement< dim, spacedim > & | fe, |
std::vector< std::vector< FullMatrix< number >>> & | matrices, | ||
const bool | isotropic_only = false |
||
) |
For all possible (isotropic and anisotropic) refinement cases compute the L2-projection matrices from the children to a coarse cell.
Note, that matrices[refinement_case-1][child]
includes the projection (or restriction) matrix of child child
for the RefinementCase refinement_case
. Here, we use refinement_case-1
instead of refinement_case
as for RefinementCase::no_refinement(=0) there are no projection matrices available.
Typically this function is called by the various implementations of FiniteElement classes in order to fill the respective FiniteElement::restriction matrices.
RefinementCase<dim>::isotropic_refinement
vectors of FullMatrix objects. Each vector corresponds to one RefinementCase refinement_case
and is of the vector size GeometryInfo<dim>::n_children(refinement_case)
. This is the format used in FiniteElement, where we want to use this function mostly.true
, then this function only computes data for the isotropic refinement case. The other elements of the output vector are left untouched (but still exist). void FETools::compute_projection_from_quadrature_points_matrix | ( | const FiniteElement< dim, spacedim > & | fe, |
const Quadrature< dim > & | lhs_quadrature, | ||
const Quadrature< dim > & | rhs_quadrature, | ||
FullMatrix< double > & | X | ||
) |
Project scalar data defined in quadrature points to a finite element space on a single cell.
What this function does is the following: assume that there is scalar data uq, 0 <= q < Q:=quadrature.size()
defined at the quadrature points of a cell, with the points defined by the given rhs_quadrature
object. We may then want to ask for that finite element function (on a single cell) vh
in the finite- dimensional space defined by the given FE object that is the projection of u
in the following sense:
Usually, the projection vh
is that function that satisfies (vh,w)=(u,w)
for all discrete test functions w
. In the present case, we can't evaluate the right hand side, since u
is only defined in the quadrature points given by rhs_quadrature
, so we replace it by a quadrature approximation. Likewise, the left hand side is approximated using the lhs_quadrature
object; if this quadrature object is chosen appropriately, then the integration of the left hand side can be done exactly, without any approximation. The use of different quadrature objects is necessary if the quadrature object for the right hand side has too few quadrature points – for example, if data q
is only defined at the cell center, then the corresponding one-point quadrature formula is obviously insufficient to approximate the scalar product on the left hand side by a definite form.
After these quadrature approximations, we end up with a nodal representation Vh
of vh
that satisfies the following system of linear equations: M Vh = Q U
, where Mij=(phi_i,phi_j)
is the mass matrix approximated by lhs_quadrature
, and Q
is the matrix Qiq=phii(xq) wq
where wq
are quadrature weights; U
is the vector of quadrature point data uq
.
In order to then get the nodal representation Vh
of the projection of U
, one computes Vh = X U, X=M-1 Q
. The purpose of this function is to compute the matrix X
and return it through the last argument of this function.
Note that this function presently only supports scalar data. An extension of the mass matrix is of course trivial, but one has to define the order of data in the vector U
if it contains vector valued data in all quadrature points.
A use for this function is described in the introduction to the step-18 example program.
The opposite of this function, interpolation of a finite element function onto quadrature points is essentially what the FEValues::get_function_values
functions do; to make things a little simpler, the FETools::compute_interpolation_to_quadrature_points_matrix
provides the matrix form of this.
Note that this function works on a single cell, rather than an entire triangulation. In effect, it therefore doesn't matter if you use a continuous or discontinuous version of the finite element.
It is worth noting that there are a few confusing cases of this function. The first one is that it really only makes sense to project onto a finite element that has at most as many degrees of freedom per cell as there are quadrature points; the projection of N quadrature point data into a space with M>N unknowns is well-defined, but often yields funny and non- intuitive results. Secondly, one would think that if the quadrature point data is defined in the support points of the finite element, i.e. the quadrature points of ths_quadrature
equal fe.get_unit_support_points()
, then the projection should be the identity, i.e. each degree of freedom of the finite element equals the value of the given data in the support point of the corresponding shape function. However, this is not generally the case: while the matrix Q
in that case is the identity matrix, the mass matrix M
is not equal to the identity matrix, except for the special case that the quadrature formula lhs_quadrature
also has its quadrature points in the support points of the finite element.
Finally, this function only defines a cell wise projection, while one frequently wants to apply it to all cells in a triangulation. However, if it is applied to one cell after the other, the results from later cells may overwrite nodal values computed already from previous cells if degrees of freedom live on the interfaces between cells. The function is therefore most useful for discontinuous elements.
void FETools::compute_interpolation_to_quadrature_points_matrix | ( | const FiniteElement< dim, spacedim > & | fe, |
const Quadrature< dim > & | quadrature, | ||
FullMatrix< double > & | I_q | ||
) |
Given a (scalar) local finite element function, compute the matrix that maps the vector of nodal values onto the vector of values of this function at quadrature points as given by the second argument. In a sense, this function does the opposite of the FETools::compute_projection_from_quadrature_points_matrix function.
void FETools::compute_projection_from_quadrature_points | ( | const FullMatrix< double > & | projection_matrix, |
const std::vector< Tensor< 1, dim >> & | vector_of_tensors_at_qp, | ||
std::vector< Tensor< 1, dim >> & | vector_of_tensors_at_nodes | ||
) |
Compute the projection of tensorial (first-order tensor) data stored at the quadrature points vector_of_tensors_at_qp
to data vector_of_tensors_at_nodes
at the support points of the cell. The data in vector_of_tensors_at_qp
is ordered sequentially following the quadrature point numbering. The size of vector_of_tensors_at_qp
must correspond to the number of columns of projection_matrix
. The size of vector_of_tensors_at_nodes
must correspond to the number of rows of vector_of_tensors_at_nodes
. The projection matrix projection_matrix
describes the projection of scalar data from the quadrature points and can be obtained from the FETools::compute_projection_from_quadrature_points_matrix function.
void FETools::compute_projection_from_quadrature_points | ( | const FullMatrix< double > & | projection_matrix, |
const std::vector< SymmetricTensor< 2, dim >> & | vector_of_tensors_at_qp, | ||
std::vector< SymmetricTensor< 2, dim >> & | vector_of_tensors_at_nodes | ||
) |
same as last function but for a SymmetricTensor
.
void FETools::compute_projection_from_face_quadrature_points_matrix | ( | const FiniteElement< dim, spacedim > & | fe, |
const Quadrature< dim - 1 > & | lhs_quadrature, | ||
const Quadrature< dim - 1 > & | rhs_quadrature, | ||
const typename DoFHandler< dim, spacedim >::active_cell_iterator & | cell, | ||
const unsigned int | face, | ||
FullMatrix< double > & | X | ||
) |
This method implements the FETools::compute_projection_from_quadrature_points_matrix method for faces of a mesh. The matrix that it returns, X, is face specific and its size is fe.dofs_per_cell by rhs_quadrature.size(). The dimension, dim must be larger than 1 for this class, since Quadrature<dim-1> objects are required. See the documentation on the Quadrature class for more information.
void FETools::convert_generalized_support_point_values_to_dof_values | ( | const FiniteElement< dim, spacedim > & | finite_element, |
const std::vector< Vector< number >> & | support_point_values, | ||
std::vector< number > & | dof_values | ||
) |
Wrapper around FiniteElement::convert_generalized_support_point_values_to_dof_values() that works with arbitrary number types.
[in] | finite_element | The FiniteElement to compute dof values for. |
[in] | support_point_values | An array of size dofs_per_cell (which equals the number of points the get_generalized_support_points() function will return) where each element is a vector with as many entries as the element has vector components. This array should contain the values of a function at the generalized support points of the finite element. |
[out] | dof_values | An array of size dofs_per_cell that contains the node functionals of the element applied to the given function. |
void FETools::interpolate | ( | const DoFHandlerType1< dim, spacedim > & | dof1, |
const InVector & | u1, | ||
const DoFHandlerType2< dim, spacedim > & | dof2, | ||
OutVector & | u2 | ||
) |
Compute the interpolation of a the dof1-function
u1
to a dof2-function
u2
. dof1
and dof2
need to be DoFHandlers based on the same triangulation.
If the elements fe1
and fe2
are either both continuous or both discontinuous then this interpolation is the usual point interpolation. The same is true if fe1
is a continuous and fe2
is a discontinuous finite element. For the case that fe1
is a discontinuous and fe2
is a continuous finite element there is no point interpolation defined at the discontinuities. Therefore the mean value is taken at the DoF values on the discontinuities.
Note that for continuous elements on grids with hanging nodes (i.e. locally refined grids) this function does not give the expected output. Indeed, the resulting output vector does not necessarily respect continuity requirements at hanging nodes: if, for example, you are interpolating a Q2 field to a Q1 field, then at hanging nodes the output field will have the function value of the input field, which however is not usually the mean value of the two adjacent nodes. It is thus not part of the Q1 function space on the whole triangulation, although it is of course Q1 on each cell.
For this case (continuous elements on grids with hanging nodes), please use the interpolate()
function with an additional AffineConstraints object as argument, see below, or make the field conforming yourself by calling the distribute
function of your hanging node constraints object.
void FETools::interpolate | ( | const DoFHandlerType1< dim, spacedim > & | dof1, |
const InVector & | u1, | ||
const DoFHandlerType2< dim, spacedim > & | dof2, | ||
const AffineConstraints< typename OutVector::value_type > & | constraints, | ||
OutVector & | u2 | ||
) |
Compute the interpolation of a the dof1-function
u1
to a dof2-function
u2
. dof1
and dof2
need to be DoFHandlers (or hp::DoFHandlers) based on the same triangulation. constraints
is a hanging node constraints object corresponding to dof2
. This object is particular important when interpolating onto continuous elements on grids with hanging nodes (locally refined grids).
If the elements fe1
and fe2
are either both continuous or both discontinuous then this interpolation is the usual point interpolation. The same is true if fe1
is a continuous and fe2
is a discontinuous finite element. For the case that fe1
is a discontinuous and fe2
is a continuous finite element there is no point interpolation defined at the discontinuities. Therefore the mean value is taken at the DoF values at the discontinuities.
void FETools::back_interpolate | ( | const DoFHandlerType< dim, spacedim > & | dof1, |
const InVector & | u1, | ||
const FiniteElement< dim, spacedim > & | fe2, | ||
OutVector & | u1_interpolated | ||
) |
Compute the interpolation of the fe1-function
u1
to a fe2-function
, and interpolates this to a second fe1-function
named u1_interpolated
.
Note, that this function does not work on continuous elements at hanging nodes. For that case use the back_interpolate
function, below, that takes an additional AffineConstraints
object.
dof1
might be a DoFHandler or a hp::DoFHandler onject.
Furthermore note, that for the specific case when the finite element space corresponding to fe1
is a subset of the finite element space corresponding to fe2
, this function is simply an identity mapping.
void FETools::back_interpolate | ( | const DoFHandler< dim, spacedim > & | dof1, |
const AffineConstraints< typename OutVector::value_type > & | constraints1, | ||
const InVector & | u1, | ||
const DoFHandler< dim, spacedim > & | dof2, | ||
const AffineConstraints< typename OutVector::value_type > & | constraints2, | ||
OutVector & | u1_interpolated | ||
) |
Compute the interpolation of the dof1-function
u1
to a dof2-function
, and interpolates this to a second dof1-function
named u1_interpolated
. constraints1
and constraints2
are the hanging node constraints corresponding to dof1
and dof2
, respectively. These objects are particular important when continuous elements on grids with hanging nodes (locally refined grids) are involved.
Furthermore note, that for the specific case when the finite element space corresponding to dof1
is a subset of the finite element space corresponding to dof2
, this function is simply an identity mapping.
void FETools::interpolation_difference | ( | const DoFHandler< dim, spacedim > & | dof1, |
const InVector & | z1, | ||
const FiniteElement< dim, spacedim > & | fe2, | ||
OutVector & | z1_difference | ||
) |
Compute \((Id-I_h)z_1\) for a given dof1-function
\(z_1\), where \(I_h\) is the interpolation from fe1
to fe2
. The result \((Id-I_h)z_1\) is written into z1_difference
.
Note, that this function does not work for continuous elements at hanging nodes. For that case use the interpolation_difference
function, below, that takes an additional AffineConstraints
object.
void FETools::interpolation_difference | ( | const DoFHandler< dim, spacedim > & | dof1, |
const AffineConstraints< typename OutVector::value_type > & | constraints1, | ||
const InVector & | z1, | ||
const DoFHandler< dim, spacedim > & | dof2, | ||
const AffineConstraints< typename OutVector::value_type > & | constraints2, | ||
OutVector & | z1_difference | ||
) |
Compute \((Id-I_h)z_1\) for a given dof1-function
\(z_1\), where \(I_h\) is the interpolation from fe1
to fe2
. The result \((Id-I_h)z_1\) is written into z1_difference
. constraints1
and constraints2
are the hanging node constraints corresponding to dof1
and dof2
, respectively. These objects are particular important when continuous elements on grids with hanging nodes (locally refined grids) are involved.
For parallel computations, supply z1
with ghost elements and z1_difference
without ghost elements.
void FETools::project_dg | ( | const DoFHandler< dim, spacedim > & | dof1, |
const InVector & | u1, | ||
const DoFHandler< dim, spacedim > & | dof2, | ||
OutVector & | u2 | ||
) |
\(L^2\) projection for discontinuous elements. Operates the same direction as interpolate.
The global projection can be computed by local matrices if the finite element spaces are discontinuous. With continuous elements, this is impossible, since a global mass matrix must be inverted.
void FETools::extrapolate | ( | const DoFHandler< dim, spacedim > & | dof1, |
const InVector & | z1, | ||
const DoFHandler< dim, spacedim > & | dof2, | ||
OutVector & | z2 | ||
) |
Compute the patchwise extrapolation of a dof1
function z1
to a dof2
function z2
. dof1
and dof2
need to be DoFHandler objects based on the same triangulation. This function is used, for example, for extrapolating patchwise a piecewise linear solution to a piecewise quadratic solution.
The function's name is historical and probably not particularly well chosen. The function performs the following operations, one after the other:
dof1
to the corresponding cell of dof2
using the interpolation matrix of the finite element spaces used on these cells and provided by the finite element objects involved. This step is done using the FETools::interpolate() function.dof2
. If such a non-active cell has at least one active child, then we call the children of this cell a "patch". We then interpolate from the children of this patch to the patch, using the finite element space associated with dof2
and immediately interpolate back to the children. In essence, this information throws away all information in the solution vector that lives on a scale smaller than the patch cell.The name of the function originates from the fact that it can be used to construct a representation of a function of higher polynomial degree on a once coarser mesh. For example, if you imagine that you start with a \(Q_1\) function on a globally refined mesh, and that dof2
is associated with a \(Q_2\) element, then this function computes the equivalent of the operator \(I_{2h}^{(2)}\) interpolating the original piecewise linear function onto a quadratic function on a once coarser mesh with mesh size \(2h\) (but representing this function on the original mesh with size \(h\)). If the exact solution is sufficiently smooth, then \(u^\ast=I_{2h}^{(2)}u_h\) is typically a better approximation to the exact solution \(u\) of the PDE than \(u_h\) is. In other words, this function provides a postprocessing step that improves the solution in a similar way one often obtains by extrapolating a sequence of solutions, explaining the origin of the function's name.
extrapolate
function with an additional AffineConstraints argument, see below.void FETools::extrapolate | ( | const DoFHandler< dim, spacedim > & | dof1, |
const InVector & | z1, | ||
const DoFHandler< dim, spacedim > & | dof2, | ||
const AffineConstraints< typename OutVector::value_type > & | constraints, | ||
OutVector & | z2 | ||
) |
Compute the patchwise extrapolation of a dof1
function z1
to a dof2
function z2
. dof1
and dof2
need to be DoFHandler objects based on the same triangulation. constraints
is a hanging node constraints object corresponding to dof2
. This object is necessary when interpolating onto continuous elements on grids with hanging nodes (locally refined grids).
Otherwise, the function does the same as the other extrapolate
function above (for which the documentation provides an extensive description of its operation).
void FETools::hierarchic_to_lexicographic_numbering | ( | unsigned int | degree, |
std::vector< unsigned int > & | h2l | ||
) |
The numbering of the degrees of freedom in continuous finite elements is hierarchic, i.e. in such a way that we first number the vertex dofs, in the order of the vertices as defined by the triangulation, then the line dofs in the order and respecting the direction of the lines, then the dofs on quads, etc. However, we could have, as well, numbered them in a lexicographic way, i.e. with indices first running in x-direction, then in y-direction and finally in z-direction. Discontinuous elements of class FE_DGQ() are numbered in this way, for example.
This function constructs a table which lexicographic index each degree of freedom in the hierarchic numbering would have. It operates on the continuous finite element given as first argument, and outputs the lexicographic indices in the second.
Note that since this function uses specifics of the continuous finite elements, it can only operate on FiniteElementData<dim> objects inherent in FE_Q(). However, this function does not take a FE_Q object as it is also invoked by the FE_Q() constructor.
It is assumed that the size of the output argument already matches the correct size, which is equal to the number of degrees of freedom in the finite element.
std::vector<unsigned int> FETools::hierarchic_to_lexicographic_numbering | ( | const FiniteElementData< dim > & | fe_data | ) |
Like the previous function but instead of returning its result through the last argument return it as a value.
void FETools::lexicographic_to_hierarchic_numbering | ( | const FiniteElementData< dim > & | fe_data, |
std::vector< unsigned int > & | l2h | ||
) |
This is the reverse function to the above one, generating the map from the lexicographic to the hierarchical numbering. All the remarks made about the above function are also valid here.
std::vector<unsigned int> FETools::lexicographic_to_hierarchic_numbering | ( | const FiniteElementData< dim > & | fe_data | ) |
Like the previous function but instead of returning its result through the last argument return it as a value.
std::unique_ptr<FiniteElement<dim, spacedim> > FETools::get_fe_by_name | ( | const std::string & | name | ) |
Parse the name of a finite element and generate a finite element object accordingly. The parser ignores space characters between words (things matching the regular expression [A-Za-z0-9_]).
The name must be in the form which is returned by the FiniteElement::get_name function, where dimension template parameters <2> etc. can be omitted. Alternatively, the explicit number can be replaced by dim
or d
. If a number is given, it must match the template parameter of this function.
The names of FESystem elements follow the pattern FESystem[FE_Base1^p1-FE_Base2^p2]
The powers p1
etc. may either be numbers or can be replaced by dim
or d
.
If no finite element can be reconstructed from this string, an exception of type FETools::ExcInvalidFEName
is thrown.
The function returns a std::unique_ptr to a newly created finite element meaning the caller obtains ownership over the returned object.
Since the value of the template argument can't be deduced from the (string) argument given to this function, you have to explicitly specify it when you call this function.
This function knows about all the standard elements defined in the library. However, it doesn't by default know about elements that you may have defined in your program. To make your own elements known to this function, use the add_fe_name() function. This function does not work if one wants to get a codimension 1 finite element.
FiniteElement<dim, dim>* FETools::get_fe_from_name | ( | const std::string & | name | ) |
void FETools::add_fe_name | ( | const std::string & | name, |
const FEFactoryBase< dim, spacedim > * | factory | ||
) |
Extend the list of finite elements that can be generated by get_fe_by_name() by the one given as name
. If get_fe_by_name() is later called with this name, it will use the object given as second argument to create a finite element object.
The format of the name
parameter should include the name of a finite element. However, it is safe to use either the class name alone or to use the result of FiniteElement::get_name (which includes the space dimension as well as the polynomial degree), since everything after the first non- name character will be ignored.
The FEFactory object should be an object newly created with new
. FETools will take ownership of this object and delete it once it is not used anymore.
In most cases, if you want objects of type MyFE
be created whenever the name my_fe
is given to get_fe_by_name, you will want the second argument to this function be of type FEFactory<MyFE>, but you can of course create your custom finite element factory class.
This function takes over ownership of the object given as second argument, i.e. you should never attempt to destroy it later on. The object will be deleted at the end of the program's lifetime.
If the name of the element is already in use, an exception is thrown. Thus, functionality of get_fe_by_name() can only be added, not changed.
Note also that this table exists once for each space dimension. If you have a program that works with finite elements in different space dimensions (for example, step-4 does something like this), then you should call this function for each space dimension for which you want your finite element added to the map.