#include <base/config.h>
#include <base/exceptions.h>
#include <base/subscriptor.h>
+#include <base/table.h>
#include <vector>
#include <map>
DEAL_II_NAMESPACE_OPEN
+template<int dim, class T> class Table;
template <typename> class Vector;
template <typename> class FullMatrix;
class SparsityPattern;
* 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
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
* 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;
};
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
{
}
+ 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());
+ }
+ }
}
}
}
*
*
* @ingroup dofs
- * @author Wolfgang Bangerth, Guido Kanschat and others, 1998 - 2005
+ * @author Wolfgang Bangerth, Guido Kanschat and others, 1998 - 2008
*/
class DoFTools
{
* BlockSparsityPattern,
* BlockCompressedSparsityPattern,
* BlockCompressedSetSparsityPattern,
+ * BlockCompressedSimpleSparsityPattern,
* or any other class that
* satisfies similar
* requirements. It is assumed
* 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
*
* 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
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)
{
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
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();
// 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);
}
}
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();
// 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)
{
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]);
}
}
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
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
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
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
<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
/* $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
// 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;
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);
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);
stokes_preconditioner_matrix.collect_sizes();
}
+ // The generation of the
+ // temperature matrix follows the
+ // generation of the Stokes matrix
+ // – 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);
// 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 ()
{
// 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);
/* $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 */
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);
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);
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);