]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Added the possibility to omit constrained dofs. Apply this to step-31 and step-32.
authorkronbichler <kronbichler@0785d39b-7218-0410-832d-ea1e28bc413d>
Wed, 22 Oct 2008 07:48:42 +0000 (07:48 +0000)
committerkronbichler <kronbichler@0785d39b-7218-0410-832d-ea1e28bc413d>
Wed, 22 Oct 2008 07:48:42 +0000 (07:48 +0000)
git-svn-id: https://svn.dealii.org/trunk@17302 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/deal.II/include/dofs/dof_constraints.h
deal.II/deal.II/include/dofs/dof_constraints.templates.h
deal.II/deal.II/include/dofs/dof_tools.h
deal.II/deal.II/source/dofs/dof_constraints.cc
deal.II/deal.II/source/dofs/dof_tools.cc
deal.II/doc/news/changes.h
deal.II/examples/step-31/step-31.cc
deal.II/examples/step-32/step-32.cc

index d04118ec4103bbe156fedb07e5f937c28efd5ccb..f3be1b5ec8b49ca91dad6dc62dbe794c6e4f140f 100644 (file)
@@ -17,6 +17,7 @@
 #include <base/config.h>
 #include <base/exceptions.h>
 #include <base/subscriptor.h>
+#include <base/table.h>
 
 #include <vector>
 #include <map>
@@ -24,6 +25,7 @@
 
 DEAL_II_NAMESPACE_OPEN
 
+template<int dim, class T> class Table;
 template <typename> class Vector;
 template <typename> class FullMatrix;
 class SparsityPattern;
@@ -991,23 +993,52 @@ class ConstraintMatrix : public Subscriptor
                                      * second input argument is not necessary
                                      * here.
                                      *
-                                     * The last argument to this function,
-                                     * keep_constrained_entries determines
-                                     * whether the function shall allocate
-                                     * entries in the sparsity pattern at all
-                                     * for entries that will later be set to
-                                     * zero upon condensation of the
-                                     * matrix. These entries are necessary if
-                                     * the matrix is built unconstrained, and
-                                     * only later condensed. They are not
-                                     * necessary if the matrix is built using
-                                     * the distribute_local_to_global()
+                                     * The third argument to this
+                                     * function,
+                                     * keep_constrained_entries
+                                     * determines whether the
+                                     * function shall allocate
+                                     * entries in the sparsity
+                                     * pattern at all for entries
+                                     * that will later be set to zero
+                                     * upon condensation of the
+                                     * matrix. These entries are
+                                     * necessary if the matrix is
+                                     * built unconstrained, and only
+                                     * later condensed. They are not
+                                     * necessary if the matrix is
+                                     * built using the
+                                     * distribute_local_to_global()
                                      * function of this class which
-                                     * distributes entries right away when
-                                     * copying a local matrix into a global
-                                     * object. The default of this argument
-                                     * is true, meaning to allocate the few
-                                     * entries that may later be set to zero.
+                                     * distributes entries right away
+                                     * when copying a local matrix
+                                     * into a global object. The
+                                     * default of this argument is
+                                     * true, meaning to allocate the
+                                     * few entries that may later be
+                                     * set to zero.
+                                     *
+                                     * By default, the function adds
+                                     * entries for all pairs of
+                                     * indices given in the first
+                                     * argument to the sparsity
+                                     * pattern (unless
+                                     * keep_constrained_entries is
+                                     * false). However, sometimes one
+                                     * would like to only add a
+                                     * subset of all of these
+                                     * pairs. In that case, the last
+                                     * argument can be used which
+                                     * specifies a boolean mask which
+                                     * of the pairs of indices should
+                                     * be considered. If the mask is
+                                     * false for a pair of indices,
+                                     * then no entry will be added to
+                                     * the sparsity pattern for this
+                                     * pair, irrespective of whether
+                                     * one or both of the indices
+                                     * correspond to constrained
+                                     * degrees of freedom.
                                      *
                                      * This function is not typically called
                                      * from user code, but is used in the
@@ -1019,7 +1050,8 @@ class ConstraintMatrix : public Subscriptor
     void
     add_entries_local_to_global (const std::vector<unsigned int> &local_dof_indices,
                                 SparsityType                    &sparsity_pattern,
-                                const bool                       keep_constrained_entries = true) const;
+                                const bool                       keep_constrained_entries = true,
+                                const Table<2,bool>             &dof_mask = default_empty_table) const;
 
                                     /**
                                      * Delete hanging nodes in a
@@ -1297,6 +1329,14 @@ class ConstraintMatrix : public Subscriptor
                                      * weight.
                                      */
     static bool check_zero_weight (const std::pair<unsigned int, double> &p);
+
+    //public:
+                                    /**
+                                     * Dummy table that serves as
+                                     * default argument for function
+                                     * <tt>add_entries_local_to_global()</tt>.
+                                     */
+    static const Table<2,bool> default_empty_table;
 };
 
 
index 3a89ede4823dff6d150495cfe9493dd8b350347d..c9b41d476219cdefc8d5a07f407760e8ebbea557 100644 (file)
@@ -824,18 +824,50 @@ void
 ConstraintMatrix::
 add_entries_local_to_global (const std::vector<unsigned int> &local_dof_indices,
                             SparsityType                    &sparsity_pattern,
-                            const bool                       keep_constrained_entries) const
+                            const bool                       keep_constrained_entries,
+                            const Table<2,bool>             &dof_mask) const
 {
                                   // similar to the function for distributing
                                   // matrix entries; see there for comments.
   const unsigned int n_local_dofs = local_dof_indices.size();
-  
+  bool dof_mask_is_active = false;
+  if (dof_mask.n_rows() == n_local_dofs)
+    {
+      dof_mask_is_active = true;
+      Assert (dof_mask.n_cols() == n_local_dofs,
+             ExcDimensionMismatch(dof_mask.n_cols(), n_local_dofs));
+    }
+
   if (lines.size() == 0)
     {
+      bool add_these_indices;
       for (unsigned int i=0; i<n_local_dofs; ++i)
         for (unsigned int j=0; j<n_local_dofs; ++j)
-          sparsity_pattern.add(local_dof_indices[i],
-                              local_dof_indices[j]);
+         {
+                                       // There is one complication when 
+                                       // we call this function with
+                                       // dof_mask argument: When the
+                                       // mask is empty, we cannot
+                                       // access the respective
+                                       // position, and it would even
+                                       // be inefficient to create
+                                       // such a mask. Hence, we need
+                                       // to first check whether
+                                       // there is some information
+                                       // in the mask at all.
+           if (dof_mask_is_active)
+             {
+               if (dof_mask[i][j] == true)
+                 add_these_indices = true;
+               else
+                 add_these_indices = false;
+             }
+           else
+             add_these_indices = true;
+           if (add_these_indices == true)
+             sparsity_pattern.add(local_dof_indices[i],
+                                  local_dof_indices[j]);
+         }
     }
   else
     {
@@ -866,67 +898,86 @@ add_entries_local_to_global (const std::vector<unsigned int> &local_dof_indices,
         }
 
 
+      bool add_these_indices;
       for (unsigned int i=0; i<n_local_dofs; ++i)
         {
           const ConstraintLine *position_i = constraint_lines[i];
           const bool is_constrained_i = (position_i != 0);
-          
+
           for (unsigned int j=0; j<n_local_dofs; ++j)
-            {
-              const ConstraintLine *position_j = constraint_lines[j];
-              const bool is_constrained_j = (position_j != 0);
+           {
+                                       // Again, first check whether
+                                       // the mask contains any
+                                       // information, and decide
+                                       // then whether the current
+                                       // index should be added.                       
+             if (dof_mask_is_active)
+               {
+                 if (dof_mask[i][j] == true)
+                   add_these_indices = true;
+                 else
+                   add_these_indices = false;
+               }
+             else
+               add_these_indices = true;
+
+             if (add_these_indices == true)
+             {
+               const ConstraintLine *position_j = constraint_lines[j];
+               const bool is_constrained_j = (position_j != 0);
 
                                               // if so requested, add the
                                               // entry unconditionally, even
                                               // if it is going to be
                                               // constrained away
-             if (keep_constrained_entries == true)
-               sparsity_pattern.add (local_dof_indices[i],
-                                     local_dof_indices[j]);
-
-             
-              if ((is_constrained_i == false) &&
-                  (is_constrained_j == false) &&
-                 (keep_constrained_entries == false))
-                {
-                  sparsity_pattern.add (local_dof_indices[i],
+               if (keep_constrained_entries == true)
+                 sparsity_pattern.add (local_dof_indices[i],
                                        local_dof_indices[j]);
-                }
-              else if ((is_constrained_i == true) &&
-                       (is_constrained_j == false))
-                {
-                  for (unsigned int q=0; q<position_i->entries.size(); ++q)
-                    sparsity_pattern.add (position_i->entries[q].first,
+
+
+               if ((is_constrained_i == false) &&
+                   (is_constrained_j == false) &&
+                   (keep_constrained_entries == false))
+                 {
+                   sparsity_pattern.add (local_dof_indices[i],
                                          local_dof_indices[j]);
-                }
-              else if ((is_constrained_i == false) &&
-                       (is_constrained_j == true))
-                {
-                  for (unsigned int q=0; q<position_j->entries.size(); ++q)
-                    sparsity_pattern.add (local_dof_indices[i],
-                                         position_j->entries[q].first);
-                }
-              else if ((is_constrained_i == true) &&
-                       (is_constrained_j == true))
-                {
-                  for (unsigned int p=0; p<position_i->entries.size(); ++p)
-                    for (unsigned int q=0; q<position_j->entries.size(); ++q)
-                      sparsity_pattern.add (position_i->entries[p].first,
+                 }
+               else if ((is_constrained_i == true) &&
+                        (is_constrained_j == false))
+                 {
+                   for (unsigned int q=0; q<position_i->entries.size(); ++q)
+                     sparsity_pattern.add (position_i->entries[q].first,
+                                           local_dof_indices[j]);
+                 }
+               else if ((is_constrained_i == false) &&
+                        (is_constrained_j == true))
+                 {
+                   for (unsigned int q=0; q<position_j->entries.size(); ++q)
+                     sparsity_pattern.add (local_dof_indices[i],
                                            position_j->entries[q].first);
-
-                  if (i == j)
-                    sparsity_pattern.add (local_dof_indices[i],
-                                         local_dof_indices[i]);
-                }
-              else
+                 }
+               else if ((is_constrained_i == true) &&
+                        (is_constrained_j == true))
+                 {
+                   for (unsigned int p=0; p<position_i->entries.size(); ++p)
+                     for (unsigned int q=0; q<position_j->entries.size(); ++q)
+                       sparsity_pattern.add (position_i->entries[p].first,
+                                             position_j->entries[q].first);
+
+                   if (i == j)
+                     sparsity_pattern.add (local_dof_indices[i],
+                                           local_dof_indices[i]);
+                 }
+               else
                                                 // the only case that can
                                                 // happen here is one that we
                                                 // have already taken care of
-                Assert ((is_constrained_i == false) &&
-                       (is_constrained_j == false) &&
-                       (keep_constrained_entries == true),
-                       ExcInternalError());
-            }
+                 Assert ((is_constrained_i == false) &&
+                         (is_constrained_j == false) &&
+                         (keep_constrained_entries == true),
+                         ExcInternalError());
+             }
+           }
         }
     }
 }
index e2a3962092397d01b79b14e75099c6678f8d8989..3e9a12263b0ae95d423b8a87c0762ecea64b03e1 100644 (file)
@@ -168,7 +168,7 @@ template <int dim> class Mapping;
  *
  *
  * @ingroup dofs
- * @author Wolfgang Bangerth, Guido Kanschat and others, 1998 - 2005
+ * @author Wolfgang Bangerth, Guido Kanschat and others, 1998 - 2008
  */
 class DoFTools
 {
@@ -375,6 +375,7 @@ class DoFTools
                                      * BlockSparsityPattern,
                                      * BlockCompressedSparsityPattern,
                                      * BlockCompressedSetSparsityPattern,
+                                     * BlockCompressedSimpleSparsityPattern,
                                      * or any other class that
                                      * satisfies similar
                                      * requirements. It is assumed
@@ -403,18 +404,38 @@ class DoFTools
                                      * taken into account at the time of
                                      * creating the sparsity pattern. For
                                      * this, pass the ConstraintMatrix object
-                                     * as the last argument to the current
+                                     * as the third argument to the current
                                      * function. No call to
                                      * ConstraintMatrix::condense() is then
                                      * necessary. This process is explained
                                      * in @ref step_27 "step-27".
+                                     *
+                                     * In case the constraints are
+                                     * already taken care of in this
+                                     * function, it is possible to
+                                     * neglect off-diagonal entries
+                                     * in the sparsity pattern. When
+                                     * using
+                                     * ConstraintMatrix::distribute_local_to_global
+                                     * during assembling, no entries
+                                     * will ever be written into
+                                     * these matrix position, so that
+                                     * one can save some computing
+                                     * time in matrix-vector products
+                                     * by not even creating these
+                                     * elements. In that case, the
+                                     * variable
+                                     * <tt>keep_constrained_dofs</tt>
+                                     * needs to be set to
+                                     * <tt>false</tt>.
                                      */
     template <class DH, class SparsityPattern>
     static
     void
-    make_sparsity_pattern (const DH        &dof,
-                          SparsityPattern &sparsity_pattern,
-                          const ConstraintMatrix &constraints = ConstraintMatrix());
+    make_sparsity_pattern (const DH               &dof,
+                          SparsityPattern        &sparsity_pattern,
+                          const ConstraintMatrix &constraints = ConstraintMatrix(),
+                          const bool              keep_constrained_dofs = true);
 
                                     /**
                                      * Locate non-zero entries for
@@ -499,13 +520,60 @@ class DoFTools
                                      *
                                      * Not implemented for
                                      * hp::DoFHandler.
+                                     *
+                                     * As mentioned before, the
+                                     * creation of the sparsity
+                                     * pattern is a purely local
+                                     * process and the sparsity
+                                     * pattern does not provide for
+                                     * entries introduced by the
+                                     * elimination of hanging
+                                     * nodes. They have to be taken
+                                     * care of by a call to
+                                     * ConstraintMatrix::condense()
+                                     * afterwards.
+                                     *
+                                     * Alternatively, the constraints
+                                     * on degrees of freedom can
+                                     * already be taken into account
+                                     * at the time of creating the
+                                     * sparsity pattern. For this,
+                                     * pass the ConstraintMatrix
+                                     * object as the third argument
+                                     * to the current function. No
+                                     * call to
+                                     * ConstraintMatrix::condense()
+                                     * is then necessary. This
+                                     * process is explained in @ref
+                                     * step_27 "step-27".
+                                     *
+                                     * In case the constraints are
+                                     * already taken care of in this
+                                     * function, it is possible to
+                                     * neglect off-diagonal entries
+                                     * in the sparsity pattern. When
+                                     * using
+                                     * ConstraintMatrix::distribute_local_to_global
+                                     * during assembling, no entries
+                                     * will ever be written into
+                                     * these matrix position, so that
+                                     * one can save some computing
+                                     * time in matrix-vector products
+                                     * by not even creating these
+                                     * elements. In that case, the
+                                     * variable
+                                     * <tt>keep_constrained_dofs</tt>
+                                     * needs to be set to
+                                     * <tt>false</tt>.
                                      */
     template <class DH, class SparsityPattern>
     static
     void
     make_sparsity_pattern (const DH                 &dof,
                           const Table<2, Coupling> &coupling,
-                          SparsityPattern&          sparsity_pattern);
+                          SparsityPattern          &sparsity_pattern,
+                          const ConstraintMatrix   &constraints = ConstraintMatrix(),
+                          const bool                keep_constrained_dofs = true);
     
                                     /**
                                      * @deprecated This is the old
index 348d11b0518b31c50866da590c532e4ff6c1b53b..5dbd6097a969c1bab0f75743011ea6e041cc0e33 100644 (file)
 DEAL_II_NAMESPACE_OPEN
 
 
+
+                                       // Static member variable
+const Table<2,bool> ConstraintMatrix::default_empty_table = Table<2,bool>();
+
+
+
 bool
 ConstraintMatrix::check_zero_weight (const std::pair<unsigned int, double> &p)
 {
@@ -1802,37 +1808,45 @@ MATRIX_FUNCTIONS(TrilinosWrappers::BlockSparseMatrix);
 template void ConstraintMatrix::
 add_entries_local_to_global<SparsityPattern> (const std::vector<unsigned int> &,
                                              SparsityPattern                 &,
-                                             const bool) const;
+                                             const bool,
+                                             const Table<2,bool> &) const;
 template void ConstraintMatrix::
 add_entries_local_to_global<CompressedSparsityPattern> (const std::vector<unsigned int> &,
                                              CompressedSparsityPattern       &,
-                                             const bool) const;
+                                             const bool,
+                                             const Table<2,bool> &) const;
 template void ConstraintMatrix::
 add_entries_local_to_global<CompressedSetSparsityPattern> (const std::vector<unsigned int> &,
                                              CompressedSetSparsityPattern       &,
-                                             const bool) const;
+                                             const bool,
+                                             const Table<2,bool> &) const;
 
 template void ConstraintMatrix::
 add_entries_local_to_global<CompressedSimpleSparsityPattern> (const std::vector<unsigned int> &,
                                              CompressedSimpleSparsityPattern       &,
-                                             const bool) const;
+                                             const bool,
+                                             const Table<2,bool> &) const;
 
 template void ConstraintMatrix::
 add_entries_local_to_global<BlockSparsityPattern> (const std::vector<unsigned int> &,
                                              BlockSparsityPattern       &,
-                                             const bool) const;
+                                             const bool,
+                                             const Table<2,bool> &) const;
 template void ConstraintMatrix::
 add_entries_local_to_global<BlockCompressedSparsityPattern> (const std::vector<unsigned int> &,
                                              BlockCompressedSparsityPattern       &,
-                                             const bool) const;
+                                             const bool,
+                                             const Table<2,bool> &) const;
 template void ConstraintMatrix::
 add_entries_local_to_global<BlockCompressedSetSparsityPattern> (const std::vector<unsigned int> &,
                                              BlockCompressedSetSparsityPattern       &,
-                                             const bool) const;
+                                             const bool,
+                                             const Table<2,bool> &) const;
 
 template void ConstraintMatrix::
 add_entries_local_to_global<BlockCompressedSimpleSparsityPattern> (const std::vector<unsigned int> &,
                                               BlockCompressedSimpleSparsityPattern       &,
-                                              const bool) const;
+                                              const bool,
+                                             const Table<2,bool> &) const;
 
 DEAL_II_NAMESPACE_CLOSE
index 980f15b1c9a58bbdf63bfec95e1e93ddbc69b105..710cf479708932a26e4ebc94042c6723043e6b80 100644 (file)
@@ -48,9 +48,10 @@ DEAL_II_NAMESPACE_OPEN
 
 template <class DH, class SparsityPattern>
 void
-DoFTools::make_sparsity_pattern (const DH        &dof,
-                                SparsityPattern &sparsity,
-                                const ConstraintMatrix &constraints)
+DoFTools::make_sparsity_pattern (const DH               &dof,
+                                SparsityPattern        &sparsity,
+                                const ConstraintMatrix &constraints,
+                                const bool              keep_constrained_dofs)
 {
   const unsigned int n_dofs = dof.n_dofs();
 
@@ -74,7 +75,8 @@ DoFTools::make_sparsity_pattern (const DH        &dof,
                                       // given, then the following call acts
                                       // as if simply no constraints existed
       constraints.add_entries_local_to_global (dofs_on_this_cell,
-                                              sparsity);
+                                              sparsity,
+                                              keep_constrained_dofs);
     }
 }
 
@@ -85,7 +87,9 @@ void
 DoFTools::make_sparsity_pattern (
   const DH                &dof,
   const Table<2,Coupling> &couplings,
-  SparsityPattern&         sparsity)
+  SparsityPattern         &sparsity,
+  const ConstraintMatrix  &constraints,
+  const bool               keep_constrained_dofs)
 {
   const unsigned int n_dofs = dof.n_dofs();
 
@@ -107,13 +111,12 @@ DoFTools::make_sparsity_pattern (
                                   // respect to non-primitive shape
                                   // functions, which takes some additional
                                   // thought
-  std::vector<std::vector<std::vector<bool> > > dof_mask(fe_collection.size());
+  std::vector<Table<2,bool> > dof_mask(fe_collection.size());
   for (unsigned int f=0; f<fe_collection.size(); ++f)
     {
       const unsigned int dofs_per_cell = fe_collection[f].dofs_per_cell;
 
-      dof_mask[f].resize (dofs_per_cell,
-                         std::vector<bool>(dofs_per_cell, false));
+      dof_mask[f].reinit (dofs_per_cell, dofs_per_cell);
       
       for (unsigned int i=0; i<dofs_per_cell; ++i)
        for (unsigned int j=0; j<dofs_per_cell; ++j)
@@ -155,19 +158,22 @@ DoFTools::make_sparsity_pattern (
     {
       const unsigned int fe_index
        = cell->active_fe_index();
-      
+
       const unsigned int dofs_per_cell
        = fe_collection[fe_index].dofs_per_cell;
-      
+
       dofs_on_this_cell.resize (dofs_per_cell);
       cell->get_dof_indices (dofs_on_this_cell);
-      
-                                      // make sparsity pattern for this cell
-      for (unsigned int i=0; i<dofs_per_cell; ++i)
-       for (unsigned int j=0; j<dofs_per_cell; ++j)
-         if (dof_mask[fe_index][i][j] == true)
-           sparsity.add (dofs_on_this_cell[i],
-                         dofs_on_this_cell[j]);
+
+
+                                      // make sparsity pattern for this
+                                      // cell. if no constraints pattern was
+                                      // given, then the following call acts
+                                      // as if simply no constraints existed
+      constraints.add_entries_local_to_global (dofs_on_this_cell,
+                                              sparsity,
+                                              keep_constrained_dofs,
+                                              dof_mask[fe_index]);
     }
 }
 
@@ -5113,56 +5119,65 @@ DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension>,
                                SparsityPattern>
 (const DoFHandler<deal_II_dimension> &dof,
  SparsityPattern    &sparsity,
- const ConstraintMatrix &);
+ const ConstraintMatrix &,
+ const bool);
 template void
 DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension>,
                                CompressedSparsityPattern>
 (const DoFHandler<deal_II_dimension> &dof,
  CompressedSparsityPattern    &sparsity,
- const ConstraintMatrix &);
+ const ConstraintMatrix &,
+ const bool);
 template void
 DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension>,
                                CompressedSetSparsityPattern>
 (const DoFHandler<deal_II_dimension> &dof,
  CompressedSetSparsityPattern    &sparsity,
- const ConstraintMatrix &);
+ const ConstraintMatrix &,
+ const bool);
 template void
 DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension>,
                                CompressedSimpleSparsityPattern>
 (const DoFHandler<deal_II_dimension> &dof,
  CompressedSimpleSparsityPattern &sparsity,
- const ConstraintMatrix &);
+ const ConstraintMatrix &,
+ const bool);
 template void
 DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension>,
                                BlockSparsityPattern>
 (const DoFHandler<deal_II_dimension> &dof,
  BlockSparsityPattern                &sparsity,
- const ConstraintMatrix &);
+ const ConstraintMatrix &,
+ const bool);
 template void
 DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension>,
                                BlockCompressedSparsityPattern>
 (const DoFHandler<deal_II_dimension> &dof,
  BlockCompressedSparsityPattern      &sparsity,
- const ConstraintMatrix &);
+ const ConstraintMatrix &,
+ const bool);
 template void
 DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension>,
                                BlockCompressedSetSparsityPattern>
 (const DoFHandler<deal_II_dimension> &dof,
  BlockCompressedSetSparsityPattern      &sparsity,
- const ConstraintMatrix &);
+ const ConstraintMatrix &,
+ const bool);
 template void
 DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension>,
                                BlockCompressedSimpleSparsityPattern>
 (const DoFHandler<deal_II_dimension> &dof,
  BlockCompressedSimpleSparsityPattern      &sparsity,
- const ConstraintMatrix &);
+ const ConstraintMatrix &,
+ const bool);
 
 template void
 DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,
                                SparsityPattern>
 (const hp::DoFHandler<deal_II_dimension> &dof,
  SparsityPattern    &sparsity,
- const ConstraintMatrix &);
+ const ConstraintMatrix &,
+ const bool);
 
 
 template void
@@ -5170,21 +5185,24 @@ DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,
                                CompressedSparsityPattern>
 (const hp::DoFHandler<deal_II_dimension> &dof,
  CompressedSparsityPattern    &sparsity,
- const ConstraintMatrix &);
+ const ConstraintMatrix &,
+ const bool);
 
 template void
 DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,
                                CompressedSetSparsityPattern>
 (const hp::DoFHandler<deal_II_dimension> &dof,
  CompressedSetSparsityPattern    &sparsity,
- const ConstraintMatrix &);
+ const ConstraintMatrix &,
+ const bool);
 
 template void
 DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,
                                CompressedSimpleSparsityPattern>
 (const hp::DoFHandler<deal_II_dimension> &dof,
  CompressedSimpleSparsityPattern    &sparsity,
- const ConstraintMatrix &);
+ const ConstraintMatrix &,
+ const bool);
 
 
 template void
@@ -5192,25 +5210,29 @@ DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,
                                BlockSparsityPattern>
 (const hp::DoFHandler<deal_II_dimension> &dof,
  BlockSparsityPattern                &sparsity,
- const ConstraintMatrix &);
+ const ConstraintMatrix &,
+ const bool);
 template void
 DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,
                                BlockCompressedSparsityPattern>
 (const hp::DoFHandler<deal_II_dimension> &dof,
  BlockCompressedSparsityPattern      &sparsity,
- const ConstraintMatrix &);
+ const ConstraintMatrix &,
+ const bool);
 template void
 DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,
                                BlockCompressedSetSparsityPattern>
 (const hp::DoFHandler<deal_II_dimension> &dof,
  BlockCompressedSetSparsityPattern      &sparsity,
- const ConstraintMatrix &);
+ const ConstraintMatrix &,
+ const bool);
 template void
 DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,
                                BlockCompressedSimpleSparsityPattern>
 (const hp::DoFHandler<deal_II_dimension> &dof,
  BlockCompressedSimpleSparsityPattern      &sparsity,
- const ConstraintMatrix &);
+ const ConstraintMatrix &,
+ const bool);
 
 
 template void 
@@ -5218,98 +5240,130 @@ DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension>,
                                SparsityPattern>
 (const DoFHandler<deal_II_dimension>&,
  const Table<2,Coupling>&,
- SparsityPattern&);
+ SparsityPattern&,
+ const ConstraintMatrix &,
+ const bool);
 template void 
 DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension>,
                                CompressedSparsityPattern>
 (const DoFHandler<deal_II_dimension>&,
  const Table<2,Coupling>&,
- CompressedSparsityPattern&);
+ CompressedSparsityPattern&,
+ const ConstraintMatrix &,
+ const bool);
 template void 
 DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension>,
                                CompressedSetSparsityPattern>
 (const DoFHandler<deal_II_dimension>&,
  const Table<2,Coupling>&,
- CompressedSetSparsityPattern&);
+ CompressedSetSparsityPattern&,
+ const ConstraintMatrix &,
+ const bool);
 template void 
 DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension>,
                                CompressedSimpleSparsityPattern>
 (const DoFHandler<deal_II_dimension>&,
  const Table<2,Coupling>&,
- CompressedSimpleSparsityPattern&);
+ CompressedSimpleSparsityPattern&,
+ const ConstraintMatrix &,
+ const bool);
 template void
 DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension>,
                                BlockSparsityPattern>
 (const DoFHandler<deal_II_dimension>&,
  const Table<2,Coupling>&,
- BlockSparsityPattern&);
+ BlockSparsityPattern&,
+ const ConstraintMatrix &,
+ const bool);
 template void 
 DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension>,
                                BlockCompressedSparsityPattern>
 (const DoFHandler<deal_II_dimension>&,
  const Table<2,Coupling>&,
- BlockCompressedSparsityPattern&);
+ BlockCompressedSparsityPattern&,
+ const ConstraintMatrix &,
+ const bool);
 template void 
 DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension>,
                                BlockCompressedSetSparsityPattern>
 (const DoFHandler<deal_II_dimension>&,
  const Table<2,Coupling>&,
- BlockCompressedSetSparsityPattern&);
+ BlockCompressedSetSparsityPattern&,
+ const ConstraintMatrix &,
+ const bool);
 template void
 DoFTools::make_sparsity_pattern<DoFHandler<deal_II_dimension>,
                                BlockCompressedSimpleSparsityPattern>
 (const DoFHandler<deal_II_dimension>&,
  const Table<2,Coupling>&,
- BlockCompressedSimpleSparsityPattern&);
+ BlockCompressedSimpleSparsityPattern&,
+ const ConstraintMatrix &,
+ const bool);
 
 template void 
 DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,
                                SparsityPattern>
 (const hp::DoFHandler<deal_II_dimension>&,
  const Table<2,Coupling>&,
- SparsityPattern&);
+ SparsityPattern&,
+ const ConstraintMatrix &,
+ const bool);
 template void 
 DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,
                                CompressedSparsityPattern>
 (const hp::DoFHandler<deal_II_dimension>&,
  const Table<2,Coupling>&,
- CompressedSparsityPattern&);
+ CompressedSparsityPattern&,
+ const ConstraintMatrix &,
+ const bool);
 template void 
 DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,
                                CompressedSetSparsityPattern>
 (const hp::DoFHandler<deal_II_dimension>&,
  const Table<2,Coupling>&,
- CompressedSetSparsityPattern&);
+ CompressedSetSparsityPattern&,
+ const ConstraintMatrix &,
+ const bool);
 template void 
 DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,
                                CompressedSimpleSparsityPattern>
 (const hp::DoFHandler<deal_II_dimension>&,
  const Table<2,Coupling>&,
- CompressedSimpleSparsityPattern&);
+ CompressedSimpleSparsityPattern&,
+ const ConstraintMatrix &,
+ const bool);
 template void
 DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,
                                BlockSparsityPattern>
 (const hp::DoFHandler<deal_II_dimension>&,
  const Table<2,Coupling>&,
- BlockSparsityPattern&);
+ BlockSparsityPattern&,
+ const ConstraintMatrix &,
+ const bool);
 template void 
 DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,
                                BlockCompressedSparsityPattern>
 (const hp::DoFHandler<deal_II_dimension>&,
  const Table<2,Coupling>&,
- BlockCompressedSparsityPattern&);
+ BlockCompressedSparsityPattern&,
+ const ConstraintMatrix &,
+ const bool);
 template void 
 DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,
                                BlockCompressedSetSparsityPattern>
 (const hp::DoFHandler<deal_II_dimension>&,
  const Table<2,Coupling>&,
- BlockCompressedSetSparsityPattern&);
+ BlockCompressedSetSparsityPattern&,
+ const ConstraintMatrix &,
+ const bool);
 template void
 DoFTools::make_sparsity_pattern<hp::DoFHandler<deal_II_dimension>,
                                BlockCompressedSimpleSparsityPattern>
 (const hp::DoFHandler<deal_II_dimension>&,
  const Table<2,Coupling>&,
- BlockCompressedSimpleSparsityPattern&);
+ BlockCompressedSimpleSparsityPattern&,
+ const ConstraintMatrix &,
+ const bool);
 
 
 template void
index 94005cd21631088bb4374d267cb9b8e9a4c4a7b1..6e67d2d13768d85a0c331e2d15dcc97913dc9fde 100644 (file)
@@ -353,6 +353,13 @@ inconvenience this causes.
 <h3>deal.II</h3>
 
 <ol>
+  <li>
+  <p>
+  New: When calling function DoFTools::make_sparsity_pattern with a ConstraintMatrix, it is now possible to set a bool argument keep_constrained_dofs. When this flag is set to false, constrained rows and columns will not be part of the sparsity pattern, which increases the performance of matrix operations and decrease memory consumption in case there are many constraints.
+  <br>
+  (Martin Kronbichler 2008/10/21)
+  </p> 
+
   <li>
   <p>
   New: There is now a second DoFTools::count_dofs_with_subdomain_association function that
index f2e86205557909d2a4289135c45bdc5e82d5a5af..2cdf2f6e245754c72626e4f98099196e4bb75be8 100644 (file)
@@ -1,5 +1,5 @@
 /* $Id$ */
-/* Author: Martin Kronbichler, University of Uppsala,
+/* Author: Martin Kronbichler, Uppsala University,
            Wolfgang Bangerth, Texas A&M University 2007, 2008 */
 
 /*    $Id$       */
                                 // interfaces to the matrix and vector
                                 // classes based on Trilinos as well as
                                 // Trilinos preconditioners:
-#include <lac/trilinos_block_vector.h>
 #include <lac/trilinos_sparse_matrix.h>
 #include <lac/trilinos_block_sparse_matrix.h>
+#include <lac/trilinos_vector.h>
+#include <lac/trilinos_block_vector.h>
 #include <lac/trilinos_precondition.h>
 
                                 // Finally, here are two C++ headers that
@@ -1053,13 +1054,36 @@ void BoussinesqFlowProblem<dim>::setup_dofs ()
                                   // components at the boundary
                                   // again.
                                   //
-                                  // Then, constraints are applied to
-                                  // the temporary sparsity patterns,
-                                  // which are finally copied into an
-                                  // object of type SparsityPattern
-                                  // and used to initialize the
-                                  // nonzero pattern of the Trilinos
-                                  // matrix objects we use.
+                                  // When generating the sparsity
+                                  // pattern, we directly apply the
+                                  // constraints from hanging nodes
+                                  // and no-flux boundary
+                                  // conditions. This approach was
+                                  // already used in step-27, but is
+                                  // different from the one in early
+                                  // tutorial programs. The reason
+                                  // for doing so is that later
+                                  // during assembly we are going to
+                                  // distribute the constraints
+                                  // immediately when transferring
+                                  // local to global
+                                  // dofs. Consequently, there will
+                                  // be no data written at positions
+                                  // of constrained degrees of
+                                  // freedom, so we can let the
+                                  // DoFTools::make_sparsity_pattern
+                                  // function omit these entries by
+                                  // setting the last boolean flag to
+                                  // <tt>false</tt>. Once the
+                                  // sparsity pattern is ready, we
+                                  // can use it to initialize the
+                                  // Trilinos matrices. Note that the
+                                  // Trilinos matrices store the
+                                  // sparsity pattern internally, so
+                                  // there is no need to keep the
+                                  // sparsity pattern around after
+                                  // the initialization of the
+                                  // matrix.
   stokes_block_sizes.resize (2);
   stokes_block_sizes[0] = n_u;
   stokes_block_sizes[1] = n_p;
@@ -1084,8 +1108,8 @@ void BoussinesqFlowProblem<dim>::setup_dofs ()
        else
          coupling[c][d] = DoFTools::none;
 
-    DoFTools::make_sparsity_pattern (stokes_dof_handler, coupling, csp);
-    stokes_constraints.condense (csp);
+    DoFTools::make_sparsity_pattern (stokes_dof_handler, coupling, csp,
+                                    stokes_constraints, false);
 
     BlockSparsityPattern stokes_sparsity_pattern;    
     stokes_sparsity_pattern.copy_from (csp);
@@ -1116,8 +1140,8 @@ void BoussinesqFlowProblem<dim>::setup_dofs ()
        else
          coupling[c][d] = DoFTools::none;
 
-    DoFTools::make_sparsity_pattern (stokes_dof_handler, coupling, csp);
-    stokes_constraints.condense (csp);
+    DoFTools::make_sparsity_pattern (stokes_dof_handler, coupling, csp,
+                                    stokes_constraints, false);
     
     BlockSparsityPattern stokes_preconditioner_sparsity_pattern;
     stokes_preconditioner_sparsity_pattern.copy_from (csp);
@@ -1126,14 +1150,20 @@ void BoussinesqFlowProblem<dim>::setup_dofs ()
     stokes_preconditioner_matrix.collect_sizes();
   }
 
+                                  // The generation of the
+                                  // temperature matrix follows the
+                                  // generation of the Stokes matrix
+                                  // &ndash; except that it is much
+                                  // easier since we do not need to
+                                  // take care of any blocks.
   {
     temperature_mass_matrix.clear ();
     temperature_stiffness_matrix.clear ();
     temperature_matrix.clear ();
 
     CompressedSetSparsityPattern csp (n_T, n_T);      
-    DoFTools::make_sparsity_pattern (temperature_dof_handler, csp);
-    temperature_constraints.condense (csp);
+    DoFTools::make_sparsity_pattern (temperature_dof_handler, csp,
+                                    temperature_constraints, false);
 
     SparsityPattern temperature_sparsity_pattern;
     temperature_sparsity_pattern.copy_from (csp);
@@ -1440,36 +1470,33 @@ BoussinesqFlowProblem<dim>::build_stokes_preconditioner ()
                                 // work by doing the full assembly
                                 // only when it is needed.
                                 // 
-                                // Regarding the technical details
-                                // of implementation, not much has
+                                // Regarding the technical details of
+                                // implementation, not much has
                                 // changed from step-22. We reset
-                                // matrix and vector, create 
-                                // a quadrature formula on the 
-                                // cells and one on cell faces
-                                // (for implementing Neumann 
-                                // boundary conditions). Then,
-                                // we create a respective
-                                // FEValues object for both the 
-                                // cell and the face integration.
-                                // For the the update flags of
-                                // the first, we perform the
+                                // matrix and vector, create a
+                                // quadrature formula on the cells
+                                // and one on cell faces (for
+                                // implementing Neumann boundary
+                                // conditions). Then, we create a
+                                // respective FEValues object for
+                                // both the cell and the face
+                                // integration.  For the the update
+                                // flags of the first, we perform the
                                 // calculations of basis function
-                                // derivatives only in
-                                // case of a full assembly, since
-                                // they are not needed otherwise,
-                                // which makes the call of
-                                // the FEValues::reinit function
-                                // further down in the program 
-                                // more efficient.
+                                // derivatives only in case of a full
+                                // assembly, since they are not
+                                // needed otherwise, which makes the
+                                // call of the FEValues::reinit
+                                // function further down in the
+                                // program more efficient.
                                 // 
-                                // The declarations proceed 
-                                // with some shortcuts for 
-                                // array sizes, the creation of
-                                // the local matrix and right 
-                                // hand side as well as the
-                                // vector for the indices of
-                                // the local dofs compared to
-                                // the global system.
+                                // The declarations proceed with some
+                                // shortcuts for array sizes, the
+                                // creation of the local matrix and
+                                // right hand side as well as the
+                                // vector for the indices of the
+                                // local dofs compared to the global
+                                // system.
 template <int dim>
 void BoussinesqFlowProblem<dim>::assemble_stokes_system ()
 {
@@ -1520,20 +1547,20 @@ void BoussinesqFlowProblem<dim>::assemble_stokes_system ()
                                   // term in the momentum equation.
                                   // 
                                   // The set of vectors we create
-                                  // next hold the evaluations of
-                                  // the basis functions that will
-                                  // be used for creating the
+                                  // next hold the evaluations of the
+                                  // basis functions that will be
+                                  // used for creating the
                                   // matrices. This gives faster
                                   // access to that data, which
-                                  // increases the performance
-                                  // of the assembly. See step-22 
-                                  // for details.
+                                  // increases the performance of the
+                                  // assembly. See step-22 for
+                                  // details.
                                   // 
-                                  // The last two declarations 
-                                  // are used to extract the 
-                                  // individual blocks (velocity,
-                                  // pressure, temperature) from
-                                  // the total FE system.
+                                  // The last two declarations are
+                                  // used to extract the individual
+                                  // blocks (velocity, pressure,
+                                  // temperature) from the total FE
+                                  // system.
   std::vector<double>               boundary_values (n_face_q_points);
 
   std::vector<double>               old_temperature_values(n_q_points);
index 668a1df56552c550d6cba124f53d34b2747aa12b..b0dd2d33ec8bde24d12b3762680aff559f164c95 100644 (file)
@@ -1,5 +1,5 @@
 /* $Id$ */
-/* Author: Martin Kronbichler, University of Uppsala,
+/* Author: Martin Kronbichler, Uppsala University,
            Wolfgang Bangerth, Texas A&M University 2007, 2008 */
 /*                                                                */
 /*    Copyright (C) 2008 by the deal.II authors */
@@ -659,8 +659,8 @@ void BoussinesqFlowProblem<dim>::setup_dofs ()
        else
          coupling[c][d] = DoFTools::none;
 
-    DoFTools::make_sparsity_pattern (stokes_dof_handler, coupling, csp);
-    stokes_constraints.condense (csp);
+    DoFTools::make_sparsity_pattern (stokes_dof_handler, coupling, csp,
+                                    stokes_constraints, false);
 
     stokes_sparsity_pattern.copy_from (csp);
 
@@ -691,7 +691,8 @@ void BoussinesqFlowProblem<dim>::setup_dofs ()
        else
          coupling[c][d] = DoFTools::none;
 
-    DoFTools::make_sparsity_pattern (stokes_dof_handler, coupling, csp);
+    DoFTools::make_sparsity_pattern (stokes_dof_handler, coupling, csp,
+                                    stokes_constraints, false);
     stokes_constraints.condense (csp);
 
     stokes_preconditioner_sparsity_pattern.copy_from (csp);
@@ -716,7 +717,8 @@ void BoussinesqFlowProblem<dim>::setup_dofs ()
     SparsityPattern temperature_sparsity_pattern;
 
     CompressedSetSparsityPattern csp (n_T, n_T);
-    DoFTools::make_sparsity_pattern (temperature_dof_handler, csp);
+    DoFTools::make_sparsity_pattern (temperature_dof_handler, csp,
+                                    temperature_constraints, false);
     temperature_constraints.condense (csp);
 
     temperature_sparsity_pattern.copy_from (csp);

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.