* preconditioners, where each block belongs to a specific component
* of the equation you are presently discretizing.
*
+ * Note that the number of blocks and rows are implicitely determined
+ * by the sparsity pattern objects used.
+ *
*
* @sect2{On template instantiations}
*
*
* @author Wolfgang Bangerth, 2000
*/
-template <typename number, int rows, int columns=rows>
+template <typename number>
class BlockSparseMatrix : public Subscriptor
{
public:
typedef number value_type;
/**
- * Constructor; initializes the matrix to
- * be empty, without any structure, i.e.
- * the matrix is not usable at all. This
- * constructor is therefore only useful
- * for matrices which are members of a
- * class. All other matrices should be
- * created at a point in the data flow
- * where all necessary information is
+ * Constructor; initializes the
+ * matrix to be empty, without
+ * any structure, i.e. the
+ * matrix is not usable at
+ * all. This constructor is
+ * therefore only useful for
+ * matrices which are members of
+ * a class. All other matrices
+ * should be created at a point
+ * in the data flow where all
+ * necessary information is
* available.
*
- * You have to initialize
- * the matrix before usage with
- * @p{reinit(BlockSparsityPattern)}.
+ * You have to initialize the
+ * matrix before usage with
+ * @p{reinit(BlockSparsityPattern)}. The
+ * number of blocks per row and
+ * column are then determined by
+ * that function.
*/
BlockSparseMatrix ();
*/
BlockSparseMatrix (const BlockSparsityPattern &sparsity);
+ /**
+ * Destructor.
+ */
+ virtual ~BlockSparseMatrix ();
+
/**
* Pseudo operator only copying
- * empty objects.
+ * empty objects. The sizes of
+ * the block matrices need to be
+ * the same.
*/
- BlockSparseMatrix<number,rows,columns> &
- operator = (const BlockSparseMatrix<number,rows,columns> &);
-
+ BlockSparseMatrix<number> &
+ operator = (const BlockSparseMatrix<number> &);
/**
* Reinitialize the object but
* necessary if you @p{reinit}'d
* the sparsity structure and
* want to update the size of the
- * matrix. It only calls @p{reinit}
- * on the sub-matrices.
+ * matrix. It only calls
+ * @p{reinit} on the
+ * sub-matrices. The size of this
+ * matrix is unchanged.
*
* If the sparsity pattern has
* not changed, then the effect
virtual void clear ();
/**
- * Return the number of blocks in a
- * column.
+ * Return the number of blocks in
+ * a column. Returns zero if no
+ * sparsity pattern is presently
+ * associated to this matrix.
*/
unsigned int n_block_rows () const;
/**
- * Return the number of blocks in a
- * row.
+ * Return the number of blocks in
+ * a row. Returns zero if no
+ * sparsity pattern is presently
+ * associated to this matrix.
*/
unsigned int n_block_cols () const;
* reference to @p{this}.
*/
template <typename somenumber>
- BlockSparseMatrix<number,rows,columns> &
- copy_from (const BlockSparseMatrix<somenumber,rows,columns> &source);
+ BlockSparseMatrix<number> &
+ copy_from (const BlockSparseMatrix<somenumber> &source);
/**
* Add @p{matrix} scaled by
*/
template <typename somenumber>
void add_scaled (const number factor,
- const BlockSparseMatrix<somenumber,rows,columns> &matrix);
+ const BlockSparseMatrix<somenumber> &matrix);
/**
* Return the value of the entry (i,j).
* throws an exception if the wanted
* element does not exist in the matrix.
*/
- number operator () (const unsigned int i, const unsigned int j) const;
+ number operator () (const unsigned int i,
+ const unsigned int j) const;
/**
* being this matrix.
*/
template <typename somenumber>
- void vmult (BlockVector<somenumber> &dst,
+ void vmult (BlockVector<somenumber> &dst,
const BlockVector<somenumber> &src) const;
/**
* transposed matrix.
*/
template <typename somenumber>
- void Tvmult (BlockVector<somenumber> &dst,
+ void Tvmult (BlockVector<somenumber> &dst,
const BlockVector<somenumber> &src) const;
/**
* matrix.
*/
template <typename somenumber>
- void vmult_add (BlockVector<somenumber> &dst,
+ void vmult_add (BlockVector<somenumber> &dst,
const BlockVector<somenumber> &src) const;
/**
* the transposed matrix.
*/
template <typename somenumber>
- void Tvmult_add (BlockVector<somenumber> &dst,
+ void Tvmult_add (BlockVector<somenumber> &dst,
const BlockVector<somenumber> &src) const;
/**
*/
template <typename somenumber>
somenumber
- matrix_scalar_product (const BlockVector<somenumber> &u,
+ matrix_scalar_product (const BlockVector<somenumber> &u,
const BlockVector<somenumber> &v) const;
/**
* into @p{dst}.
*/
template <typename somenumber>
- somenumber residual (BlockVector<somenumber> &dst,
+ somenumber residual (BlockVector<somenumber> &dst,
const BlockVector<somenumber> &x,
- const BlockVector<somenumber> &b) const;
+ const BlockVector<somenumber> &b) const;
/**
* Apply the Jacobi
* for this operation.
*/
template <typename somenumber>
- void precondition_Jacobi (BlockVector<somenumber> &dst,
+ void precondition_Jacobi (BlockVector<somenumber> &dst,
const BlockVector<somenumber> &src,
- const number omega = 1.) const;
+ const number omega = 1.) const;
/**
* Return a (constant) reference
* Exception
*/
DeclException0 (ExcMatrixNotBlockSquare);
+
+ /**
+ * Exception.
+ */
+ DeclException0 (ExcIncompatibleObjects);
private:
+ /**
+ * Number of block rows in this
+ * matrix. Is set by default to
+ * zero, and is only changed if a
+ * sparsity pattern is given to
+ * the constructor or the
+ * @p{reinit} function.
+ */
+ unsigned int rows;
+
+ /**
+ * Number of block columns in this
+ * matrix. Is set by default to
+ * zero, and is only changed if a
+ * sparsity pattern is given to
+ * the constructor or the
+ * @p{reinit} function.
+ */
+ unsigned int columns;
+
/**
* Pointer to the block sparsity
* pattern used for this
/**
* Array of sub-matrices.
*/
- SparseMatrix<number> sub_objects[rows][columns];
+ vector<vector<SmartPointer<SparseMatrix<number> > > > sub_objects;
};
/* ------------------------- Template functions ---------------------- */
-template <typename number, int rows, int columns>
+template <typename number>
inline
SparseMatrix<number> &
-BlockSparseMatrix<number,rows,columns>::block (const unsigned int row,
- const unsigned int column)
+BlockSparseMatrix<number>::block (const unsigned int row,
+ const unsigned int column)
{
Assert (row<rows, ExcIndexRange (row, 0, rows));
Assert (column<columns, ExcIndexRange (column, 0, columns));
- return sub_objects[row][column];
+ return *sub_objects[row][column];
};
-template <typename number, int rows, int columns>
+template <typename number>
inline
const SparseMatrix<number> &
-BlockSparseMatrix<number,rows,columns>::block (const unsigned int row,
- const unsigned int column) const
+BlockSparseMatrix<number>::block (const unsigned int row,
+ const unsigned int column) const
{
Assert (row<rows, ExcIndexRange (row, 0, rows));
Assert (column<columns, ExcIndexRange (column, 0, columns));
- return sub_objects[row][column];
+ return *sub_objects[row][column];
};
-template <typename number, int rows, int columns>
+template <typename number>
inline
unsigned int
-BlockSparseMatrix<number,rows,columns>::m () const
+BlockSparseMatrix<number>::m () const
{
return sparsity_pattern->n_rows();
};
-template <typename number, int rows, int columns>
+template <typename number>
inline
unsigned int
-BlockSparseMatrix<number,rows,columns>::n () const
+BlockSparseMatrix<number>::n () const
{
return sparsity_pattern->n_cols();
};
-template <typename number, int rows, int columns>
+template <typename number>
inline
void
-BlockSparseMatrix<number,rows,columns>::set (const unsigned int i,
- const unsigned int j,
- const number value)
+BlockSparseMatrix<number>::set (const unsigned int i,
+ const unsigned int j,
+ const number value)
{
const pair<unsigned int,unsigned int>
row_index = sparsity_pattern->row_indices.global_to_local (i),
-template <typename number, int rows, int columns>
+template <typename number>
inline
void
-BlockSparseMatrix<number,rows,columns>::add (const unsigned int i,
- const unsigned int j,
- const number value)
+BlockSparseMatrix<number>::add (const unsigned int i,
+ const unsigned int j,
+ const number value)
{
const pair<unsigned int,unsigned int>
row_index = sparsity_pattern->row_indices.global_to_local (i),
-template <typename number, int rows, int columns>
+template <typename number>
inline
number
-BlockSparseMatrix<number,rows,columns>::operator () (const unsigned int i,
- const unsigned int j) const
+BlockSparseMatrix<number>::operator () (const unsigned int i,
+ const unsigned int j) const
{
const pair<unsigned int,unsigned int>
row_index = sparsity_pattern->row_indices.global_to_local (i),
-template <typename number, int rows, int columns>
+template <typename number>
template <typename somenumber>
-BlockSparseMatrix<number,rows,columns> &
-BlockSparseMatrix<number,rows,columns>::
-copy_from (const BlockSparseMatrix<somenumber,rows,columns> &source)
+BlockSparseMatrix<number> &
+BlockSparseMatrix<number>::
+copy_from (const BlockSparseMatrix<somenumber> &source)
{
for (unsigned int r=0; r<rows; ++r)
for (unsigned int c=0; c<columns; ++c)
-template <typename number, int rows, int columns>
+template <typename number>
template <typename somenumber>
void
-BlockSparseMatrix<number,rows,columns>::
+BlockSparseMatrix<number>::
add_scaled (const number factor,
- const BlockSparseMatrix<somenumber,rows,columns> &matrix)
+ const BlockSparseMatrix<somenumber> &matrix)
{
for (unsigned int r=0; r<rows; ++r)
for (unsigned int c=0; c<columns; ++c)
-template <typename number, int rows, int columns>
+template <typename number>
template <typename somenumber>
void
-BlockSparseMatrix<number,rows,columns>::
-vmult (BlockVector<somenumber> &dst,
- const BlockVector<somenumber> &src) const
+BlockSparseMatrix<number>::vmult (BlockVector<somenumber> &dst,
+ const BlockVector<somenumber> &src) const
{
Assert (dst.n_blocks() == rows,
ExcDimensionMismatch(dst.n_blocks(), rows));
block(row,0).vmult (dst.block(row),
src.block(0));
for (unsigned int col=1; col<columns; ++col)
- block(row,col).vmult_add (dst.block(row),
- src.block(col));
+ block(row,col).vmult_add (dst.block(row),
+ src.block(col));
};
};
-template <typename number, int rows, int columns>
+template <typename number>
template <typename somenumber>
void
-BlockSparseMatrix<number,rows,columns>::
-vmult_add (BlockVector<somenumber> &dst,
- const BlockVector<somenumber> &src) const
+BlockSparseMatrix<number>::vmult_add (BlockVector<somenumber> &dst,
+ const BlockVector<somenumber> &src) const
{
Assert (dst.n_blocks() == rows,
ExcDimensionMismatch(dst.n_blocks(), rows));
block(row,0).vmult_add (dst.block(row),
src.block(0));
for (unsigned int col=1; col<columns; ++col)
- block(row,col).vmult_add (dst.block(row),
- src.block(col));
+ block(row,col).vmult_add (dst.block(row),
+ src.block(col));
};
};
-template <typename number, int rows, int columns>
+template <typename number>
template <typename somenumber>
void
-BlockSparseMatrix<number,rows,columns>::
-Tvmult (BlockVector<somenumber> &/*dst*/,
- const BlockVector<somenumber> &/*src*/) const
+BlockSparseMatrix<number>::Tvmult (BlockVector<somenumber> &/*dst*/,
+ const BlockVector<somenumber> &/*src*/) const
{
// presently not
// implemented. should be simple,
-template <typename number, int rows, int columns>
+template <typename number>
template <typename somenumber>
void
-BlockSparseMatrix<number,rows,columns>::
-Tvmult_add (BlockVector<somenumber> &/*dst*/,
- const BlockVector<somenumber> &/*src*/) const
+BlockSparseMatrix<number>::Tvmult_add (BlockVector<somenumber> &/*dst*/,
+ const BlockVector<somenumber> &/*src*/) const
{
// presently not
// implemented. should be simple,
-template <typename number, int rows, int columns>
+template <typename number>
template <typename somenumber>
somenumber
-BlockSparseMatrix<number,rows,columns>::
-matrix_norm_square (const BlockVector<somenumber> &v) const
+BlockSparseMatrix<number>::matrix_norm_square (const BlockVector<somenumber> &v) const
{
Assert (rows == columns, ExcMatrixNotBlockSquare());
Assert (v.n_blocks() == rows,
-template <typename number, int rows, int columns>
+template <typename number>
template <typename somenumber>
somenumber
-BlockSparseMatrix<number,rows,columns>::
+BlockSparseMatrix<number>::
matrix_scalar_product (const BlockVector<somenumber> &u,
const BlockVector<somenumber> &v) const
{
-template <typename number, int rows, int columns>
+template <typename number>
template <typename somenumber>
somenumber
-BlockSparseMatrix<number,rows,columns>::
+BlockSparseMatrix<number>::
residual (BlockVector<somenumber> &dst,
const BlockVector<somenumber> &x,
const BlockVector<somenumber> &b) const
-template <typename number, int rows, int columns>
+template <typename number>
template <typename somenumber>
void
-BlockSparseMatrix<number,rows,columns>::
+BlockSparseMatrix<number>::
precondition_Jacobi (BlockVector<somenumber> &dst,
const BlockVector<somenumber> &src,
const number omega) const
};
-template <typename number, int rows, int columns>
+template <typename number>
inline
unsigned int
-BlockSparseMatrix<number,rows,columns>::n_block_cols () const
+BlockSparseMatrix<number>::n_block_cols () const
{
return columns;
-}
+};
-template <typename number, int rows, int columns>
+template <typename number>
inline
unsigned int
-BlockSparseMatrix<number,rows,columns>::n_block_rows () const
+BlockSparseMatrix<number>::n_block_rows () const
{
return rows;
-}
+};
#endif // __deal2__block_sparse_matrix_h
-template <typename number, int rows, int columns>
-BlockSparseMatrix<number,rows,columns>::BlockSparseMatrix () :
+template <typename number>
+BlockSparseMatrix<number>::BlockSparseMatrix () :
+ rows (0),
+ columns (0),
sparsity_pattern (0)
{};
-template <typename number, int rows, int columns>
-BlockSparseMatrix<number,rows,columns>::
-BlockSparseMatrix (const BlockSparsityPattern &sparsity)
+template <typename number>
+BlockSparseMatrix<number>::
+BlockSparseMatrix (const BlockSparsityPattern &sparsity) :
+ rows (0),
+ columns (0)
{
reinit (sparsity);
};
-template <typename number, int rows, int columns>
-BlockSparseMatrix<number,rows,columns> &
-BlockSparseMatrix<number,rows,columns>::
-operator = (const BlockSparseMatrix<number,rows,columns> &m)
+template <typename number>
+BlockSparseMatrix<number>::~BlockSparseMatrix ()
{
+ // delete previous content of
+ // the subobjects array
+ for (unsigned int r=0; r<rows; ++r)
+ for (unsigned int c=0; c<columns; ++c)
+ {
+ SparseMatrix<number> *p = sub_objects[r][c];
+ sub_objects[r][c] = 0;
+ delete p;
+ };
+};
+
+
+
+template <typename number>
+BlockSparseMatrix<number> &
+BlockSparseMatrix<number>::
+operator = (const BlockSparseMatrix<number> &m)
+{
+ Assert (rows == m.rows, ExcIncompatibleObjects());
+ Assert (columns == m.columns, ExcIncompatibleObjects());
// this operator does not do
// anything except than checking
// whether the base objects want to
-template <typename number, int rows, int columns>
+template <typename number>
void
-BlockSparseMatrix<number,rows,columns>::reinit ()
+BlockSparseMatrix<number>::reinit ()
{
for (unsigned int r=0; r<rows; ++r)
for (unsigned int c=0; c<columns; ++c)
-template <typename number, int rows, int columns>
+template <typename number>
void
-BlockSparseMatrix<number,rows,columns>::
+BlockSparseMatrix<number>::
reinit (const BlockSparsityPattern &sparsity)
{
+ // first delete previous content of
+ // the subobjects array
+ for (unsigned int r=0; r<rows; ++r)
+ for (unsigned int c=0; c<columns; ++c)
+ {
+ SparseMatrix<number> *p = sub_objects[r][c];
+ sub_objects[r][c] = 0;
+ delete p;
+ };
+ sub_objects.clear ();
+
+ // then associate new sparsity
+ // pattern and resize
sparsity_pattern = &sparsity;
-
+ rows = sparsity.n_block_rows();
+ columns = sparsity.n_block_cols();
+ sub_objects = vector<vector<SmartPointer<SparseMatrix<number> > > >
+ (rows, vector<SmartPointer<SparseMatrix<number> > > (columns, 0));
+
+ // and reinitialize the blocks
for (unsigned int r=0; r<rows; ++r)
for (unsigned int c=0; c<columns; ++c)
- block(r,c).reinit (sparsity.block(r,c));
+ {
+ sub_objects[r][c] = new SparseMatrix<number>();
+ block(r,c).reinit (sparsity.block(r,c));
+ };
};
-template <typename number, int rows, int columns>
+template <typename number>
void
-BlockSparseMatrix<number,rows,columns>::clear ()
+BlockSparseMatrix<number>::clear ()
{
sparsity_pattern = 0;
for (unsigned int r=0; r<rows; ++r)
-template <typename number, int rows, int columns>
+template <typename number>
bool
-BlockSparseMatrix<number,rows,columns>::empty () const
+BlockSparseMatrix<number>::empty () const
{
for (unsigned int r=0; r<rows; ++r)
for (unsigned int c=0; c<columns; ++c)
-template <typename number, int rows, int columns>
+template <typename number>
unsigned int
-BlockSparseMatrix<number,rows,columns>::n_nonzero_elements () const
+BlockSparseMatrix<number>::n_nonzero_elements () const
{
return sparsity_pattern->n_nonzero_elements ();
};
-template <typename number, int rows, int columns>
+template <typename number>
const BlockSparsityPattern &
-BlockSparseMatrix<number,rows,columns>::get_sparsity_pattern () const
+BlockSparseMatrix<number>::get_sparsity_pattern () const
{
return *sparsity_pattern;
};
-template <typename number, int rows, int columns>
+template <typename number>
unsigned int
-BlockSparseMatrix<number,rows,columns>::memory_consumption () const
+BlockSparseMatrix<number>::memory_consumption () const
{
unsigned int mem = sizeof(*this);
+ mem += MemoryConsumption::memory_consumption (sub_objects);
for (unsigned int r=0; r<rows; ++r)
for (unsigned int c=0; c<columns; ++c)
- mem += MemoryConsumption::memory_consumption(sub_objects[r][c]);
+ mem += MemoryConsumption::memory_consumption(*sub_objects[r][c]);
return mem;
};