From: Matthias Maier Date: Fri, 15 Jun 2018 19:31:07 +0000 (-0500) Subject: doc/glossary: Update glossary on constraints X-Git-Tag: v9.1.0-rc1~1028^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F6773%2Fhead;p=dealii.git doc/glossary: Update glossary on constraints --- diff --git a/doc/doxygen/headers/constraints.h b/doc/doxygen/headers/constraints.h index 7c8999e1ef..eeae8ba497 100644 --- a/doc/doxygen/headers/constraints.h +++ b/doc/doxygen/headers/constraints.h @@ -19,8 +19,8 @@ * @ingroup dofs * * This module deals with constraints on degrees of - * freedom. The central class to deal with constraints is the ConstraintMatrix - * class. + * freedom. The central class to deal with constraints is the + * AffineConstraints class. * * Constraints typically come from several sources, for example: * - If you have Dirichlet-type boundary conditions, $u|_{\partial\Omega}=g$, @@ -31,7 +31,7 @@ * at the location of degree * of freedom 12 has the value 42. Such constraints are generated by * those versions of the VectorTools::interpolate_boundary_values - * function that take a ConstraintMatrix argument (though there are + * function that take a AffineConstraints argument (though there are * also other ways of dealing with Dirichlet conditions, using * MatrixTools::apply_boundary_values, see for example step-3 and step-4). * - If you have boundary conditions that set a certain part of the @@ -71,13 +71,10 @@ * solution. An example of this is given in the step-11 tutorial program. * * In all of these examples, constraints on degrees of freedom are linear - * and possibly inhomogeneous. In other words, the always have + * and possibly inhomogeneous. In other words, they always have * the form $x_{i_1} = \sum_{j=2}^M a_{i_j} x_{i_j} + b_i$. The deal.II * class that deals with storing and using these constraints is - * ConstraintMatrix. The naming stems from the fact that the class - * originally only stored the (sparse) matrix $a_{i_j}$. The class name - * component "matrix" no longer makes much sense today since the class has - * learned to also deal with inhomogeneities $b_i$. + * AffineConstraints. * * *

Eliminating constraints

@@ -91,12 +88,12 @@ * the sparsity pattern of the sparse matrices used in finite element * calculations and is thus a quite expensive operation. The general scheme of * things is then that you build your system, you eliminate (condense) away - * constrained nodes using the ConstraintMatrix::condense() functions, then + * constrained nodes using the AffineConstraints::condense() functions, then * you solve the remaining system, and finally you compute the values of * constrained nodes from the values of the unconstrained ones using the - * ConstraintMatrix::distribute() function. Note that the - * ConstraintMatrix::condense() function is applied to matrix and right hand - * side of the linear system, while the ConstraintMatrix::distribute() + * AffineConstraints::distribute() function. Note that the + * AffineConstraints::condense() function is applied to matrix and right hand + * side of the linear system, while the AffineConstraints::distribute() * function is applied to the solution vector. This is the method used in * the first few tutorial programs, see for example step-6. * @@ -107,10 +104,10 @@ * implement for %parallel computations where a process may not have access * to elements of the matrix. We therefore offer a second way of * building linear systems, using the - * ConstraintMatrix::add_entries_local_to_global() and - * ConstraintMatrix::distribute_local_to_global() functions discussed + * AffineConstraints::add_entries_local_to_global() and + * AffineConstraints::distribute_local_to_global() functions discussed * below. The resulting linear systems are equivalent to those one gets after - * calling the ConstraintMatrix::condense() functions. + * calling the AffineConstraints::condense() functions. * * @note Both ways of applying constraints set the value of the matrix * diagonals to constrained entries to a positive entry of the same @@ -215,11 +212,11 @@ * "step-31". * *
  • - * There may not be a ConstraintMatrix::condense() function for the matrix + * There may not be an AffineConstraints::condense() function for the matrix * you use (this is, for example, the case for the PETSc and Trilinos * wrapper classes where we have no access to the underlying representation * of the matrix, and therefore cannot efficiently implement the - * ConstraintMatrix::condense() operation). This is the case discussed + * AffineConstraints::condense() operation). This is the case discussed * in step-17, step-18, step-31, and step-32. * * @@ -228,22 +225,22 @@ * matrices and vectors, and similarly build a sparsity pattern in the * condensed form at the time it is set up originally. * - * The ConstraintMatrix class offers support for these operations as well. For - * example, the ConstraintMatrix::add_entries_local_to_global() function adds + * The AffineConstraints class offers support for these operations as well. For + * example, the AffineConstraints::add_entries_local_to_global() function adds * nonzero entries to a sparsity pattern object. It not only adds a given * entry, but also all entries that we will have to write to if the current * entry corresponds to a constrained degree of freedom that will later be * eliminated. Similarly, one can use the - * ConstraintMatrix::distribute_local_to_global() functions to directly + * AffineConstraints::distribute_local_to_global() functions to directly * distribute entries in vectors and matrices when copying local contributions * into a global matrix or vector. These calls make a subsequent call to - * ConstraintMatrix::condense() unnecessary. For examples of their use see the + * AffineConstraints::condense() unnecessary. For examples of their use see the * tutorial programs referenced above. * * Note that, despite their name which describes what the function really - * does, the ConstraintMatrix::distribute_local_to_global() functions has to + * does, the AffineConstraints::distribute_local_to_global() functions has to * be applied to matrices and right hand side vectors, whereas the - * ConstraintMatrix::distribute() function discussed below is applied to the + * AffineConstraints::distribute() function discussed below is applied to the * solution vector after solving the linear system. * * @@ -251,12 +248,12 @@ * * After solving the condensed system of equations, the solution vector has to * be "distributed": the modification to the original linear system that - * results from calling ConstraintMatrix::condense leads to a linear system + * results from calling AffineConstraints::condense() leads to a linear system * that solves correctly for all degrees of freedom that are unconstrained but * leaves the values of constrained degrees of freedom undefined. To get the * correct values also for these degrees of freedom, you need to "distribute" * the unconstrained values also to their constrained colleagues. This is done - * by the ConstraintMatrix::distribute() function. + * by the AffineConstraints::distribute() function. * The operation of distribution undoes the * condensation process in some sense, but it should be noted that it is not * the inverse operation. Basically, distribution sets the values of the @@ -277,46 +274,48 @@ * respective condense function is called without any matrix (or if the matrix * has already been condensed before). * - * The use of ConstraintMatrix for implementing Dirichlet boundary conditions - * is discussed in the step-22 tutorial program. A further example that applies - * the ConstraintMatrix is step-41. The situation here is little more complicated, - * because there we have some constraints which are not at the boundary. - * There are two ways to apply inhomogeneous constraints after creating the - * ConstraintMatrix: + * The use of the AffineConstraints class for implementing Dirichlet + * boundary conditions is discussed in the step-22 tutorial program. A + * further example that utilizes AffineConstraints is step-41. The + * situation here is little more complicated, because there we have some + * constraints which are not at the boundary. There are two ways to apply + * inhomogeneous constraints after creating an AffineConstraints object: * * First approach: - * - Apply the ConstraintMatrix::distribute_local_to_global() function to the + * - Apply the AffineConstraints::distribute_local_to_global() function to the * system matrix and the right-hand-side with the parameter * use_inhomogeneities_for_rhs = false (i.e., the default) * - Set the solution to zero in the inhomogeneous constrained components - * using the ConstraintMatrix::set_zero() function (or start with a solution + * using the AffineConstraints::set_zero() function (or start with a solution * vector equal to zero) * - solve() the linear system - * - Apply ConstraintMatrix::distribute() to the solution + * - Apply AffineConstraints::distribute() to the solution * * Second approach: - * - Use the ConstraintMatrix::distribute_local_to_global() function with the parameter - * use_inhomogeneities_for_rhs = true and apply it to - * the system matrix and the right-hand-side + * - Use the AffineConstraints::distribute_local_to_global() function with + * the parameter use_inhomogeneities_for_rhs = true and apply it to the + * system matrix and the right-hand-side * - Set the concerning components of the solution to the inhomogeneous - * constrained values (for example using ConstraintMatrix::distribute()) + * constrained values (for example using AffineConstraints::distribute()) * - solve() the linear system - * - Depending on the solver now you have to apply the ConstraintMatrix::distribute() - * function to the solution, because the solver could change the constrained - * values in the solution. For a Krylov based solver this should not be strictly - * necessary, but it is still possible that there is a difference between the - * inhomogeneous value and the solution value in the order of machine precision, - * and you may want to call ConstraintMatrix::distribute() anyway if you have - * additional constraints such as from hanging nodes. + * - Depending on the solver now you have to apply the + * AffineConstraints::distribute() function to the solution, because the + * solver could change the constrained values in the solution. For a + * Krylov based solver this should not be strictly necessary, but it is + * still possible that there is a difference between the inhomogeneous + * value and the solution value in the order of machine precision, and + * you may want to call AffineConstraints::distribute() anyway if you + * have additional constraints such as from hanging nodes. * * Of course, both approaches lead to the same final answer but in different - * ways. Using the first approach (i.e., when using use_inhomogeneities_for_rhs = false - * in ConstraintMatrix::distribute_local_to_global()), the linear system we + * ways. Using the first approach (i.e., when using + * use_inhomogeneities_for_rhs = false + * in AffineConstraints::distribute_local_to_global()), the linear system we * build has zero entries in the right hand side in all those places where a * degree of freedom is constrained, and some positive value on the matrix * diagonal of these lines. Consequently, the solution vector of the linear * system will have a zero value for inhomogeneously constrained degrees of - * freedom and we need to call ConstraintMatrix::distribute() to give these + * freedom and we need to call AffineConstraints::distribute() to give these * degrees of freedom their correct nonzero values. * * On the other hand, in the second approach, the matrix diagonal element and @@ -326,7 +325,7 @@ * the matrix is empty with the exception of the diagonal entry, and * $b_{13}/A_{13,13}=42$ so that the solution of $Ax=b$ must satisfy * $x_{13}=42$ as desired). As a consequence, we do not need to call - * ConstraintMatrix::distribute() after solving to fix up inhomogeneously + * AffineConstraints::distribute() after solving to fix up inhomogeneously * constrained components of the solution, though there is also no harm in * doing so. * @@ -364,17 +363,17 @@ * match the values we want for them at the solution. We can again * circumvent this problem by setting the corresponding elements of the * solution vector to their correct values, by calling - * ConstraintMatrix::distribute() before solving the linear system + * AffineConstraints::distribute() before solving the linear system * (and then, as necessary, a second time after solving). * * In addition to these considerations, consider the case where we have * inhomogeneous constraints of the kind $x_{3}=\tfrac 12 x_1 + \tfrac 12$, * e.g., from a hanging node constraint of the form $x_{3}=\tfrac 12 (x_1 + * x_2)$ where $x_2$ is itself constrained by boundary values to $x_2=1$. - * In this case, the ConstraintMatrix can of course not figure out what - * the final value of $x_3$ should be and, consequently, can not set the - * solution vector's third component correctly. Thus, the second approach will - * not work and you should take the first. + * In this case, the AffineConstraints container can of course not figure + * out what the final value of $x_3$ should be and, consequently, can not + * set the solution vector's third component correctly. Thus, the second + * approach will not work and you should take the first. * * *

    Dealing with conflicting constraints

    @@ -416,22 +415,22 @@ * - If you want the hanging node constraints to win, then first build * these through the DoFTools::make_hanging_node_constraints() function. * Then interpolate the boundary values using - * VectorTools::interpolate_boundary_values() into the same ConstraintMatrix - * object. If the latter function encounters a boundary node that already - * is constrained, it will simply ignore the boundary values at this - * node and leave the constraint untouched. + * VectorTools::interpolate_boundary_values() into the same + * AffineConstraints object. If the latter function encounters a boundary + * node that already is constrained, it will simply ignore the boundary + * values at this node and leave the constraint untouched. * - If you want the boundary value constraint to win, build the hanging * node constraints as above and use these to assemble the matrix using - * the ConstraintMatrix::distribute_local_to_global() function (or, + * the AffineConstraints::distribute_local_to_global() function (or, * alternatively, assemble the matrix and then use - * ConstraintMatrix::condense() on it). In a second step, use the + * AffineConstraints::condense() on it). In a second step, use the * VectorTools::interpolate_boundary_values() function that returns * a std::map and use it as input for MatrixTools::apply_boundary_values() * to set boundary nodes to their correct value. * * Either behavior can also be achieved by building two separate - * ConstraintMatrix objects and calling ConstraintMatrix::merge function with - * a particular second argument. + * AffineConstraints objects and calling AffineConstraints::merge() + * function with a particular second argument. * * *

    Applying constraints indirectly with a LinearOperator

    @@ -455,10 +454,11 @@ * assume that we can apply it to a vector but can not necessarily access * individual matrix entries. $b$ is the corresponding right hand side of a * system of linear equations $A\,x=b$. The matrix $C$ describes the - * homogeneous part of the linear constraints stored in a ConstraintMatrix - * and the vector $k$ is the vector of corresponding inhomogeneities. More - * precisely, the ConstraintMatrix::distribute() operation applied on a - * vector $x$ is the operation + * homogeneous part of the linear constraints stored in an + * AffineConstraints object and the vector $k$ is the vector of + * corresponding inhomogeneities. More precisely, the + * AffineConstraints::distribute() operation applied on a vector $x$ is the + * operation * @f[ x \leftarrow C\,x+k. * @f] @@ -475,19 +475,19 @@ * * // ... * - * // system_matrix - unconstrained and assembled system matrix - * // right_hand_side - unconstrained and assembled right hand side - * // constraint_matrix - a ConstraintMatrix object - * // solver - an appropriate, iterative solver - * // preconditioner - a preconditioner + * // system_matrix - unconstrained and assembled system matrix + * // right_hand_side - unconstrained and assembled right hand side + * // affine_constraints - an AffineConstraints object + * // solver - an appropriate, iterative solver + * // preconditioner - a preconditioner * * const auto op_a = linear_operator(system_matrix); - * const auto op_amod = constrained_linear_operator(constraint_matrix, op_a); - * Vector rhs_mod = constrained_right_hand_side(constraint_matrix, + * const auto op_amod = constrained_linear_operator(affine_constraints, op_a); + * Vector rhs_mod = constrained_right_hand_side(affine_constraints, * op_a, * right_hand_side); * * solver.solve(op_amod, solution, rhs_mod, preconditioner); - * constraint_matrix.distribute(solution); + * affine_constraints.distribute(solution); * @endcode */