From fb58d68e3b0f8ee41610ba21ae3c0fe604d7197f Mon Sep 17 00:00:00 2001 From: kronbichler Date: Wed, 22 Oct 2008 13:31:48 +0000 Subject: [PATCH] Omit the constrained entries that will never be created anyway. git-svn-id: https://svn.dealii.org/trunk@17305 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/examples/step-27/doc/intro.dox | 48 ++++++++++++++++---------- deal.II/examples/step-27/step-27.cc | 36 +++++++++++-------- 2 files changed, 52 insertions(+), 32 deletions(-) diff --git a/deal.II/examples/step-27/doc/intro.dox b/deal.II/examples/step-27/doc/intro.dox index d89cf30e7f..e019caef32 100644 --- a/deal.II/examples/step-27/doc/intro.dox +++ b/deal.II/examples/step-27/doc/intro.dox @@ -649,22 +649,24 @@ the CompressedSparsityPattern class. This solution is slower than directly building a SparsityPattern object, but only uses as much memory as is really necessary. -As it now turns out, the storage format used in the CompressedSparsityPattern -class is not very good for matrices with truly large numbers of entries per -row — where truly large numbers mean in the hundreds. This isn't -typically the case for lower order elements even in 3d, but happens for high -order elements in 3d; for example, a vertex degree of freedom of a $Q_5$ -element in 3d may couple to as many as 1700 other degrees of freedom. In such -a CompressedSparsityPattern will work, but by tuning the memory storage format -used internally in that class a bit will make it work several times -faster. This is what we did with the CompressedSetSparsityPattern class -— it has exactly the same interface as the CompressedSparsityPattern -class but internally stores things somewhat differently. For most cases, there -is not much of a difference in performance in the classes (though the old -class has a slight advantage for lower order elements in 3d), but for high -order and $hp$ elements in 3d, the CompressedSetSparsityPattern has a definite -edge. We will therefore use it later when we build the sparsity pattern in -this tutorial program. +As it now turns out, the storage format used in the +CompressedSparsityPattern class is not very good for matrices with +truly large numbers of entries per row — where truly large +numbers mean in the hundreds. This isn't typically the case for lower +order elements even in 3d, but happens for high order elements in 3d; +for example, a vertex degree of freedom of a $Q_5$ element in 3d may +couple to as many as 1700 other degrees of freedom. In such a case +CompressedSparsityPattern will work, but by tuning the memory storage +format used internally in that class a bit will make it work several +times faster. This is what we did with the +CompressedSetSparsityPattern class — it has exactly the same +interface as the CompressedSparsityPattern class but internally stores +things somewhat differently. For most cases, there is not much of a +difference in performance in the classes (though the old class has a +slight advantage for lower order elements in 3d), but for high order +and $hp$ elements in 3d, the CompressedSetSparsityPattern has a +definite edge. We will therefore use it later when we build the +sparsity pattern in this tutorial program.

Eliminating constrained degrees of freedom

@@ -692,7 +694,7 @@ the number of unknowns, whereas an ideal finite element program would of course only have algorithms that are linear in the number of unknowns. The solution to this problem is to use the ConstraintMatrix object already at the time of creating the sparsity pattern, or while copying local contributions -into the global matrix object (or global vector). +into the global matrix object (or global vector). So, instead of the code snippet (taken from @ref step_6 "step-6") @code @@ -710,9 +712,19 @@ we now use the following: hanging_node_constraints.close (); DoFTools::make_sparsity_pattern (dof_handler, sparsity_pattern, - hanging_node_constraints); + hanging_node_constraints, false); @endcode +Note also the last argument false for the creation of the +sparsity pattern. It tells the sparsity pattern that constrained +entries should not be inserted into the sparsity pattern. This makes +sense for the way we're going to do assembly, which does the +elimination of constraints already locally. Hence, we will never write +touch the constrained entries. This gives some additional performance +gain, since the system matrix will use have less entries — this +saves both memory and computing time when doing matrix-vector +multiplications or using a preconditioner. + In a similar vein, we have to slightly modify the way we copy local contributions into global matrices and vectors. In previous tutorial programs, we have always used a process like this: diff --git a/deal.II/examples/step-27/step-27.cc b/deal.II/examples/step-27/step-27.cc index 6a440b5b57..ea13fc6048 100644 --- a/deal.II/examples/step-27/step-27.cc +++ b/deal.II/examples/step-27/step-27.cc @@ -210,19 +210,27 @@ LaplaceProblem::~LaplaceProblem () // @sect4{LaplaceProblem::setup_system} // - // This function is again an almost verbatim - // copy of what we already did in step-6, - // with the main difference that we don't - // directly build the sparsity pattern, but - // first create an intermediate object that - // we later copy into the right data - // structure. In another slight deviation, we - // do not first build the sparsity pattern - // then condense away constrained degrees of - // freedom, but pass the constraint matrix - // object directly to the function that - // builds the sparsity pattern. Both of these - // steps are explained in the introduction of + // This function is again an almost + // verbatim copy of what we already + // did in step-6, with the main + // difference that we don't directly + // build the sparsity pattern, but + // first create an intermediate + // object that we later copy into the + // right data structure. In another + // slight deviation, we do not first + // build the sparsity pattern then + // condense away constrained degrees + // of freedom, but pass the + // constraint matrix object directly + // to the function that builds the + // sparsity pattern. We disable the + // insertion of constrained entries + // with false as fourth + // argument in the + // DoFTools::make_sparsity_pattern + // function. Both of these steps are + // explained in the introduction of // this program. // // The second change, maybe hidden in plain @@ -247,7 +255,7 @@ void LaplaceProblem::setup_system () CompressedSetSparsityPattern csp (dof_handler.n_dofs(), dof_handler.n_dofs()); DoFTools::make_sparsity_pattern (dof_handler, csp, - hanging_node_constraints); + hanging_node_constraints, false); sparsity_pattern.copy_from (csp); system_matrix.reinit (sparsity_pattern); -- 2.39.5