From 7cd2481379d4a3c3a006084848e82e40070fceaf Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Tue, 22 Jul 2014 20:59:08 -0500 Subject: [PATCH] Rewrite the documentation of DoFTools::compute_intergrid_constraints(). The previous version of the documentation basically stated why the function exists, not what it does. This is the focus of the new version. I also indented the arguments of this function and the (related) following one. --- include/deal.II/dofs/dof_tools.h | 158 +++++++++++++------------------ 1 file changed, 64 insertions(+), 94 deletions(-) diff --git a/include/deal.II/dofs/dof_tools.h b/include/deal.II/dofs/dof_tools.h index 5daf49d9de..23c785612f 100644 --- a/include/deal.II/dofs/dof_tools.h +++ b/include/deal.II/dofs/dof_tools.h @@ -704,31 +704,27 @@ namespace DoFTools ConstraintMatrix &constraints); /** - * This function can be used when different variables shall be - * discretized on different grids, where one grid is coarser than - * the other. This idea might seem nonsensical at first, but has - * reasonable applications in inverse (parameter estimation) - * problems, where there might not be enough information to recover - * the parameter on the same grid as the state variable; - * furthermore, the smoothness properties of state variable and - * parameter might not be too much related, so using different grids - * might be an alternative to using stronger regularization of the - * problem. - * - * The basic idea of this function is explained in the - * following. Let us, for convenience, denote by ``parameter grid'' - * the coarser of the two grids, and by ``state grid'' the finer of - * the two. We furthermore assume that the finer grid can be - * obtained by refinement of the coarser one, i.e. the fine grid is - * at least as much refined as the coarse grid at each point of the - * domain. Then, each shape function on the coarse grid can be - * represented as a linear combination of shape functions on the - * fine grid (assuming identical ansatz spaces). Thus, if we - * discretize as usual, using shape functions on the fine grid, we - * can consider the restriction that the parameter variable shall in - * fact be discretized by shape functions on the coarse grid as a - * constraint. These constraints are linear and happen to have the - * form managed by the ``ConstraintMatrix'' class. + * This function is used when different variables in a problem are + * discretized on different grids, where one grid is strictly coarser than + * the other. An example are optimization problems where the control + * variable is often discretized on a coarser mesh than the state variable. + * + * The function's result can be stated as follows mathematically: Let ${\cal + * T}_0$ and ${\cal T}_1$ be two meshes where ${\cal T}_1$ results from + * ${\cal T}_0$ strictly by refining or leaving alone the cells of ${\cal + * T}_0$. Using the same finite element on both, there are function spaces + * ${\cal V}_0$ and ${\cal V}_1$ associated with these meshes. Then every + * function $v_0 \in {\cal V}_0$ can of course also be represented exactly + * in ${\cal V}_1$ since by construction ${\cal V}_0 \subset {\cal + * V}_1$. However, not every function in ${\cal V}_1$ can be expressed as a + * linear combination of the shape functions of ${\cal V}_0$. The functions + * that can be represented lie in a homogenous subspace of ${\cal V}_1$ + * (namely, ${\cal V}_0$, of course) and this subspace can be represented by + * a linear constraint of the form $CV=0$ where $V$ is the vector of nodal + * values of functions $v\in {\cal V}_1$. In other words, every function + * $v_h=\sum_j V_j \varphi_j^{(1)} \in {\cal V}_1$ that also satisfies + * $v_h\in {\cal V}_0$ automatically satisfies $CV=0$. This function + * computes the matrix $C$ in the form of a ConstraintMatrix object. * * The construction of these constraints is done as follows: for * each of the degrees of freedom (i.e. shape functions) on the @@ -742,73 +738,47 @@ namespace DoFTools * complicated and is best understood by reading the source code, * which contains many comments. * - * Before explaining the use of this function, we would like to - * state that the total number of degrees of freedom used for the - * discretization is not reduced by the use of this function, - * i.e. even though we discretize one variable on a coarser grid, - * the total number of degrees of freedom is that of the fine - * grid. This seems to be counter-productive, since it does not give - * us a benefit from using a coarser grid. The reason why it may be - * useful to choose this approach nonetheless is three-fold: first, - * as stated above, there might not be enough information to recover - * a parameter on a fine grid, i.e. we chose to discretize it on the - * coarse grid not to save DoFs, but for other reasons. Second, the - * ``ConstraintMatrix'' includes the constraints into the linear - * system of equations, by which constrained nodes become dummy - * nodes; we may therefore exclude them from the linear algebra, for - * example by sorting them to the back of the DoF numbers and simply - * calling the solver for the upper left block of the matrix which - * works on the non-constrained nodes only, thus actually realizing - * the savings in numerical effort from the reduced number of actual - * degrees of freedom. The third reason is that for some or other - * reason we have chosen to use two different grids, it may be - * actually quite difficult to write a function that assembles the - * system matrix for finite element spaces on different grids; using - * the approach of constraints as with this function allows to use - * standard techniques when discretizing on only one grid (the finer - * one) without having to take care of the fact that one or several - * of the variable actually belong to different grids. - * - * The use of this function is as follows: it accepts as parameters - * two DoF Handlers, the first of which refers to the coarse grid - * and the second of which is the fine grid. On both, a finite - * element is represented by the DoF handler objects, which will - * usually have several components, which may belong to different - * finite elements. The second and fourth parameter of this function - * therefore state which variable on the coarse grid shall be used - * to restrict the stated component on the fine grid. Of course, the - * finite elements used for the respective components on the two - * grids need to be the same. An example may clarify this: consider - * the parameter estimation mentioned briefly above; there, on the - * fine grid the whole discretization is done, thus the variables - * are ``u'', ``q'', and the Lagrange multiplier ``lambda'', which - * are discretized using continuous linear, piecewise constant - * discontinuous, and continuous linear elements, respectively. Only - * the parameter ``q'' shall be represented on the coarse grid, thus - * the DoFHandler object on the coarse grid represents only one - * variable, discretized using piecewise constant discontinuous - * elements. Then, the parameter denoting the component on the - * coarse grid would be zero (the only possible choice, since the - * variable on the coarse grid is scalar), and one on the fine grid - * (corresponding to the variable ``q''; zero would be ``u'', two - * would be ``lambda''). Furthermore, an object of type IntergridMap - * is needed; this could in principle be generated by the function - * itself from the two DoFHandler objects, but since it is probably - * available anyway in programs that use this function, we shall use - * it instead of re-generating it. Finally, the computed constraints - * are entered into a variable of type ConstraintMatrix; the - * constraints are added, i.e. previous contents which may have, for - * example, be obtained from hanging nodes, are not deleted, so that - * you only need one object of this type. + * The use of this function is as follows: it accepts as parameters two DoF + * Handlers, the first of which refers to the coarse grid and the second of + * which is the fine grid. On both, a finite element is represented by the + * DoF handler objects, which will usually have several vector components, + * which may belong to different base elements. The second and fourth + * parameter of this function therefore state which vector component on the + * coarse grid shall be used to restrict the stated component on the fine + * grid. The finite element used for the respective components on the two + * grids needs to be the same. An example may clarify this: consider an + * optimization problem with controls $q$ discretized on a coarse mesh and a + * state variable $u$ (and corresponding Lagrange multiplier $\lambda) + * discretized on the fine mesh. These are discretized using piecewise + * constant discontinuous, continuous linear, and continuous linear + * elements, respectively. Only the parameter $q$ is represented on the + * coarse grid, thus the DoFHandler object on the coarse grid represents + * only one variable, discretized using piecewise constant discontinuous + * elements. Then, the parameter denoting the vector component on the coarse + * grid would be zero (the only possible choice, since the variable on the + * coarse grid is scalar). If the ordering of variables in the fine mesh + * FESystem is $u, q, \lambda$, then the fourth argument of the function + * corresponding to the vector component would be one (corresponding to the + * variable $q$; zero would be $u$, two would be $\lambda$). + * + * The function also requires an object of type IntergridMap representing + * how to get from the coarse mesh cells to the corresponding cells on the + * fine mesh. This could in principle be generated by the function itself + * from the two DoFHandler objects, but since it is probably available + * anyway in programs that use different meshes, the function simply takes + * it as an argument. + * + * The computed constraints are entered into a variable of type + * ConstraintMatrix; previous contents are not deleted. */ template void - compute_intergrid_constraints (const DoFHandler &coarse_grid, - const unsigned int coarse_component, - const DoFHandler &fine_grid, - const unsigned int fine_component, + compute_intergrid_constraints (const DoFHandler &coarse_grid, + const unsigned int coarse_component, + const DoFHandler &fine_grid, + const unsigned int fine_component, const InterGridMap > &coarse_to_fine_grid_map, - ConstraintMatrix &constraints); + ConstraintMatrix &constraints); /** @@ -817,7 +787,7 @@ namespace DoFTools * component on the coarse grid is multiplied to this matrix, we * obtain a vector with as many elements as there are global * degrees of freedom on the fine grid. All the elements of the - * other components of the finite element fields on the fine grid + * other vector components of the finite element fields on the fine grid * are not touched. * * The output of this function is a compressed format that can be @@ -826,11 +796,11 @@ namespace DoFTools */ template void - compute_intergrid_transfer_representation (const DoFHandler &coarse_grid, - const unsigned int coarse_component, - const DoFHandler &fine_grid, - const unsigned int fine_component, - const InterGridMap > &coarse_to_fine_grid_map, + compute_intergrid_transfer_representation (const DoFHandler &coarse_grid, + const unsigned int coarse_component, + const DoFHandler &fine_grid, + const unsigned int fine_component, + const InterGridMap > &coarse_to_fine_grid_map, std::vector > &transfer_representation); //@} -- 2.39.5