* Note that the numbers of blocks and rows are implicitly determined
* by the sparsity pattern objects used.
*
+ * Objects of this type are frequently used when a system of differential
+ * equations has solutions with variables that fall into different
+ * classes. For example, solutions of the Stokes or Navier-Stokes equations
+ * have @p dim velocity components and one pressure component. In this case,
+ * it may make sense to consider the linear system of equations as a system of
+ * 2x2 blocks, and one can construct preconditioners or solvers based on this
+ * 2x2 block structure. This class can help you in these cases, as it allows
+ * to view the matrix alternatively as one big matrix, or as a number of
+ * individual blocks.
+ *
* @ref Instantiations: some (<tt>@<float@> @<double@></tt>)
*
* @author Wolfgang Bangerth, 2000
const BlockSparseMatrix<number>* matrix;
/**
- * Iterator of the underlying matrix class.
+ * Iterator of the underlying matrix
+ * class.
*/
typename SparseMatrix<number>::const_iterator base_iterator;
unsigned int row_start;
/**
- * Number of block column where column lies in.
+ * Number of block column where
+ * column lies in.
*/
unsigned int col_block;
* STL conforming iterator.
*/
class const_iterator : private Accessor
- {
- public:
- /**
- * Constructor.
- */
+ {
+ public:
+ /**
+ * Constructor.
+ */
const_iterator(const BlockSparseMatrix<number>*,
unsigned int row,
unsigned short index);
- /**
- * Prefix increment.
- */
+ /**
+ * Prefix increment.
+ */
const_iterator& operator++ ();
- /**
- * Postfix increment.
- */
+ /**
+ * Postfix increment.
+ */
const_iterator& operator++ (int);
- /**
- * Dereferencing operator.
- */
+ /**
+ * Dereferencing operator.
+ */
const Accessor& operator* () const;
- /**
- * Dereferencing operator.
- */
+ /**
+ * Dereferencing operator.
+ */
const Accessor* operator-> () const;
- /**
- * Comparison. True, if
- * both iterators point to
- * the same matrix
- * position.
- */
+ /**
+ * Comparison. True, if
+ * both iterators point to
+ * the same matrix
+ * position.
+ */
bool operator == (const const_iterator&) const;
- /**
- * Inverse of operator==().
- */
+ /**
+ * Inverse of operator==().
+ */
bool operator != (const const_iterator&) const;
- /**
- * Comparison
- * operator. Result is true
- * if either the first row
- * number is smaller or if
- * the row numbers are
- * equal and the first
- * index is smaller.
- */
+ /**
+ * Comparison
+ * operator. Result is true
+ * if either the first row
+ * number is smaller or if
+ * the row numbers are
+ * equal and the first
+ * index is smaller.
+ */
bool operator < (const const_iterator&) const;
- };
+ };
/**
* Constructor; initializes the
// Remember current row inside block
unsigned int local_row = this->base_iterator->row();
- // Advance inside block
+
+ // Advance inside block
++this->base_iterator;
++this->a_index;
+
// If end of row inside block,
// advance to next block
- if (this->base_iterator == this->matrix->block(this->row_block, this->col_block).end(local_row))
+ if (this->base_iterator ==
+ this->matrix->block(this->row_block, this->col_block).end(local_row))
{
- if (this->col_block<this->matrix->n_block_cols()-1)
+ if (this->col_block < this->matrix->n_block_cols()-1)
{
// Advance to next block in
// row
+//TODO: what if this row in that block is empty?
++this->col_block;
this->col_start = this->matrix->sparsity_pattern
- ->get_column_indices().local_to_global(this->col_block, 0);
+ ->get_column_indices().local_to_global(this->col_block, 0);
}
else
{
this->col_start = 0;
this->a_index = 0;
++local_row;
- if (local_row>=this->matrix->block(this->row_block,0).m())
+ if (local_row >= this->matrix->block(this->row_block,0).m())
{
// If final row in
// block, go to next
++this->row_block;
if (this->row_block < this->matrix->n_block_rows())
this->row_start = this->matrix->sparsity_pattern
- ->get_row_indices().local_to_global(this->row_block, 0);
+ ->get_row_indices().local_to_global(this->row_block, 0);
}
}
// Finally, set base_iterator
// defined state for
// comparison. This is the
// end() state.
+//TODO: this is a particularly bad choice, since it is actually a valid iterator. it should rather be something like the end iterator of the last block!
this->base_iterator = this->matrix->block(0, 0).begin();
}
return *this;
BlockSparseMatrix<number>::const_iterator::
operator < (const const_iterator& i) const
{
- if (this->row_block<i->row_block)
+ if (this->row_block < i->row_block)
return true;
if (this->row_block == i->row_block)
{
Iterator & operator = (const Iterator &c);
/**
- * Dereferencing operator. If
- * the template argument
- * <tt>constness</tt> is <tt>true</tt>,
- * then no writing to the
- * result is possible, making
+ * Dereferencing operator. If the
+ * template argument
+ * <tt>constness</tt> is
+ * <tt>true</tt>, then no writing to
+ * the result is possible, making
* this a const_iterator.
*/
reference operator * () const;
/**
- * Dereferencing operator. If
- * the template argument
- * <tt>constness</tt> is <tt>true</tt>,
- * then no writing to the
- * result is possible, making
+ * Dereferencing operator. If the
+ * template argument
+ * <tt>constness</tt> is
+ * <tt>true</tt>, then no writing to
+ * the result is possible, making
* this a const_iterator.
*/
pointer operator -> () const;
reference operator [] (const difference_type d) const;
/**
- * Prefix increment operator. This operator
- * advances the iterator to
- * the next element and
- * returns a reference to
- * <tt>*this</tt>.
+ * Prefix increment operator. This
+ * operator advances the iterator to
+ * the next element and returns a
+ * reference to <tt>*this</tt>.
*/
Iterator & operator ++ ();
Iterator operator ++ (int);
/**
- * Prefix decrement operator. This operator
- * retracts the iterator to
- * the previous element and
- * returns a reference to
- * <tt>*this</tt>.
+ * Prefix decrement operator. This
+ * operator retracts the iterator to
+ * the previous element and returns a
+ * reference to <tt>*this</tt>.
*/
Iterator & operator -- ();
* checks whether the vectors
* pointed to are the same,
* and if not it throws an
- * exception.
+ * exception.
*/
bool operator == (const Iterator &i) const;
* checks whether the vectors
* pointed to are the same,
* and if not it throws an
- * exception.
+ * exception.
*/
bool operator != (const Iterator &i) const;
* block vector with constant block size is supported by constructor
* and reinit() functions.
*
- * The functionality of BlockVector includes everything a Vector can
- * do, plus the access to a single Vector inside the BlockVector by
- * block(i). It also has a complete random access iterator, just as
+ * The functionality of BlockVector includes everything a Vector can do, plus
+ * the access to a single Vector inside the BlockVector by
+ * <tt>block(i)</tt>. It also has a complete random access iterator, just as
* the LAC Vector class or the standard C++ library template
- * <tt>std::vector</tt>. Therefore, all algorithms working on
- * iterators also work with objects of this class.
+ * <tt>std::vector</tt>. Therefore, all algorithms working on iterators also
+ * work with objects of this class.
*
*
* @section BlockVectorAccess Accessing individual blocks, and resizing vectors
/**
* Set all entries to zero. Equivalent to
- * <tt>v = 0</tt>, but more obvious and faster.
- * Note that this function does not change
- * the size of the vector, unlike the
- * STL's <tt>vector<>::clear</tt> function.
+ * <tt>v=0</tt>, but more obvious and
+ * faster. Note that this function does
+ * not change the size of the vector,
+ * unlike the STL's
+ * <tt>vector<>::clear</tt> function.
*/
void clear ();
Number norm_sqr () const;
/**
- * Return the mean value of the elements of
- * this vector.
+ * Return the mean value of the elements
+ * of this vector.
*/
Number mean_value () const;
/**
- * Return the $l_1$-norm of the vector, i.e.
- * the sum of the absolute values.
+ * Return the $l_1$-norm of the vector,
+ * i.e. the sum of the absolute values.
*/
Number l1_norm () const;
/**
- * Return the $l_2$-norm of the vector, i.e.
- * the square root of the sum of the
- * squares of the elements.
+ * Return the $l_2$-norm of the vector,
+ * i.e. the square root of the sum of
+ * the squares of the elements.
*/
Number l2_norm () const;
/**
- * Return the maximum absolute value of the
- * elements of this vector, which is the
- * $l_\infty$-norm of a vector.
+ * Return the maximum absolute value of
+ * the elements of this vector, which is
+ * the $l_\infty$-norm of a vector.
*/
Number linfty_norm () const;
unsigned int n_blocks () const;
/**
- * Return dimension of the vector. This is the
- * sum of the dimensions of all components.
+ * Return dimension of the vector. This
+ * is the sum of the dimensions of all
+ * components.
*/
unsigned int size () const;
* some time.
*/
bool all_zero () const;
+
/**
* Return @p true if the vector has no
* negative entries, i.e. all entries are
*/
//@{
/**
- * Addition operator.
- * Fast equivalent to <tt>U.add(1, V)</tt>.
+ * Addition operator. Fast equivalent to
+ * <tt>U.add(1, V)</tt>.
*/
BlockVector<Number> &
operator += (const BlockVector<Number> &V);
/**
- * Subtraction operator.
- * Fast equivalent to <tt>U.add(-1, V)</tt>.
+ * Subtraction operator. Fast equivalent
+ * to <tt>U.add(-1, V)</tt>.
*/
BlockVector<Number> &
operator -= (const BlockVector<Number> &V);
/**
- * $U(0-DIM)+=s$.
- * Addition of <tt>s</tt> to all components. Note
- * that <tt>s</tt> is a scalar and not a vector.
+ * $U(0-DIM)+=s$. Addition of <tt>s</tt>
+ * to all components. Note that
+ * <tt>s</tt> is a scalar and not a
+ * vector.
*/
void add (const Number s);
*/
//@{
/**
- * Output of vector in user-defined format.
+ * Output of vector in user-defined
+ * format.
*/
void print (const char* format = 0) const;
const bool across = true) const;
/**
- * Write the vector en bloc to a file. This
- * is done in a binary mode, so the output
- * is neither readable by humans nor
- * (probably) by other computers using
- * a different operating system of number
- * format.
+ * Write the vector en bloc to a
+ * stream. This is done in a binary mode,
+ * so the output is neither readable by
+ * humans nor (probably) by other
+ * computers using a different operating
+ * system or number format.
*/
void block_write (std::ostream &out) const;
/**
- * Read a vector en block from a file. This
- * is done using the inverse operations to
- * the above function, so it is reasonably
- * fast because the bitstream is not
- * interpreted.
+ * Read a vector en block from a
+ * file. This is done using the inverse
+ * operations to the above function, so
+ * it is reasonably fast because the
+ * bitstream is not interpreted.
*
* The vector is resized if necessary.
*