From 510004279468dbf7ebbe8dd5831372a465de5731 Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Wed, 10 Jan 2018 19:40:47 -0700 Subject: [PATCH] Update some comments around renumbering DoFs. --- include/deal.II/dofs/dof_handler.h | 33 +++++++++++--- include/deal.II/dofs/dof_renumbering.h | 6 ++- include/deal.II/hp/dof_handler.h | 59 ++++++++++++++++++++------ 3 files changed, 80 insertions(+), 18 deletions(-) diff --git a/include/deal.II/dofs/dof_handler.h b/include/deal.II/dofs/dof_handler.h index 32f2d01481..b357d3d58f 100644 --- a/include/deal.II/dofs/dof_handler.h +++ b/include/deal.II/dofs/dof_handler.h @@ -442,13 +442,12 @@ public: virtual void clear (); /** - * Renumber degrees of freedom based on a list of new dof numbers for all - * the dofs. + * Renumber degrees of freedom based on a list of new DoF indices for each + * of the degrees of freedom. * * This function is called by the functions in DoFRenumbering function after - * computing the ordering of the degrees of freedom. This function is - * called, for example, by the functions in the DoFRenumbering namespace, - * but it can of course also be called from user code. + * computing a new ordering of the degree of freedom indices. However, it + * can of course also be called from user code. * * @arg new_number This array must have a size equal to the number of * degrees of freedom owned by the current processor, i.e. the size must be @@ -459,6 +458,7 @@ public: * IndexSet returned by locally_owned_dofs(). In the case of a sequential * mesh this means that the array is a list of new indices for each of the * degrees of freedom on the current mesh. In the case that we have a + * parallel::shared::Triangulation or * parallel::distributed::Triangulation underlying this DoFHandler object, * the array is a list of new indices for all the locally owned degrees of * freedom, enumerated in the same order as the currently locally owned @@ -469,6 +469,29 @@ public: * locally_owned_dofs() is complete in the sequential case, the latter * convention for the content of the array reduces to the former in the case * that only one processor participates in the mesh. + * + * @note While it follows from the above, it may be surprising to know that + * the number of locally owned degrees of freedom in a parallel + * computation is an invariant + * under renumbering, even if the indices associated with these + * locally owned degrees of freedom are not. At a fundamental level, + * this invariant exists because the decision whether a degree of + * freedom is locally owned or not has nothing to do with that + * degree of freedom's (old or new) index. Indeed, degrees of freedom + * are locally owned if they are on a locally owned cell and not on + * an interface between cells where the neighboring cell has a lower + * @ref GlossSubdomainId "subdomain id". Since both of these conditions + * are independent of the index associated with the DoF, a locally + * owned degree of freedom will also be locally owned after renumbering. + * On the other hand, properties such as whether the set of indices + * of locally owned DoFs forms a contiguous range or not + * (i.e., whether the locally_owned_dofs() returns an IndexSet object + * for which IndexSet::is_contiguous() returns @p true) are of + * course affected by the exact renumbering performed here. For example, + * while the initial numbering of DoF indices done in distribute_dofs() + * yields a contiguous numbering, the renumbering performed by + * DoFRenumbering::component_wise() will, in general, not yield + * contiguous locally owned DoF indices. */ void renumber_dofs (const std::vector &new_numbers); diff --git a/include/deal.II/dofs/dof_renumbering.h b/include/deal.II/dofs/dof_renumbering.h index 21ad83437f..2e3a8710ae 100644 --- a/include/deal.II/dofs/dof_renumbering.h +++ b/include/deal.II/dofs/dof_renumbering.h @@ -29,7 +29,11 @@ DEAL_II_NAMESPACE_OPEN /** * Implementation of a number of renumbering algorithms for the degrees of - * freedom on a triangulation. + * freedom on a triangulation. The functions in this namespace compute + * new indices for each degree of freedom of a DoFHandler or + * hp::DoFHandler object, and then call DoFHandler::renumber_dofs() or + * hp::DoFHandler::renumber_dofs(). + * * *

Cuthill-McKee like algorithms

* diff --git a/include/deal.II/hp/dof_handler.h b/include/deal.II/hp/dof_handler.h index 100604a096..dfe441e216 100644 --- a/include/deal.II/hp/dof_handler.h +++ b/include/deal.II/hp/dof_handler.h @@ -323,21 +323,56 @@ namespace hp virtual void clear (); /** - * Renumber degrees of freedom based on a list of new dof numbers for all - * the dofs. + * Renumber degrees of freedom based on a list of new DoF indices for each + * of the degrees of freedom. * - * @p new_numbers is an array of integers with size equal to the number of - * dofs on the present grid. It stores the new indices after renumbering - * in the order of the old indices. + * This function is called by the functions in DoFRenumbering function after + * computing a new ordering of the degree of freedom indices. However, it + * can of course also be called from user code. * - * This function is called by the functions in DoFRenumbering function - * after computing the ordering of the degrees of freedom. However, you - * can call this function yourself, which is necessary if a user wants to - * implement an ordering scheme herself, for example downwind numbering. + * @arg new_number This array must have a size equal to the number of + * degrees of freedom owned by the current processor, i.e. the size must be + * equal to what n_locally_owned_dofs() returns. If only one processor + * participates in storing the current mesh, then this equals the total + * number of degrees of freedom, i.e. the result of n_dofs(). The contents + * of this array are the new global indices for each freedom listed in the + * IndexSet returned by locally_owned_dofs(). In the case of a sequential + * mesh this means that the array is a list of new indices for each of the + * degrees of freedom on the current mesh. In the case that we have a + * parallel::shared::Triangulation or + * parallel::distributed::Triangulation underlying this DoFHandler object, + * the array is a list of new indices for all the locally owned degrees of + * freedom, enumerated in the same order as the currently locally owned + * DoFs. In other words, assume that degree of freedom i is + * currently locally owned, then + * new_numbers[locally_owned_dofs().index_within_set(i)] + * returns the new global DoF index of i. Since the IndexSet of + * locally_owned_dofs() is complete in the sequential case, the latter + * convention for the content of the array reduces to the former in the case + * that only one processor participates in the mesh. * - * The @p new_number array must have a size equal to the number of degrees - * of freedom. Each entry must state the new global DoF number of the - * degree of freedom referenced. + * @note While it follows from the above, it may be surprising to know that + * the number of locally owned degrees of freedom in a parallel + * computation is an invariant + * under renumbering, even if the indices associated with these + * locally owned degrees of freedom are not. At a fundamental level, + * this invariant exists because the decision whether a degree of + * freedom is locally owned or not has nothing to do with that + * degree of freedom's (old or new) index. Indeed, degrees of freedom + * are locally owned if they are on a locally owned cell and not on + * an interface between cells where the neighboring cell has a lower + * @ref GlossSubdomainId "subdomain id". Since both of these conditions + * are independent of the index associated with the DoF, a locally + * owned degree of freedom will also be locally owned after renumbering. + * On the other hand, properties such as whether the set of indices + * of locally owned DoFs forms a contiguous range or not + * (i.e., whether the locally_owned_dofs() returns an IndexSet object + * for which IndexSet::is_contiguous() returns @p true) are of + * course affected by the exact renumbering performed here. For example, + * while the initial numbering of DoF indices done in distribute_dofs() + * yields a contiguous numbering, the renumbering performed by + * DoFRenumbering::component_wise() will, in general, not yield + * contiguous locally owned DoF indices. */ void renumber_dofs (const std::vector &new_numbers); -- 2.39.5