};
+/**
+ * Permuted SOR preconditioner using matrix built-in function. The MATRIX
+ * class used is required to have functions
+ * @p{PSOR(VECTOR&, const VECTOR&, double)} and
+ * @p{TPSOR(VECTOR&, const VECTOR&, double)}.
+ *
+ *
+ * @sect2{Usage example}
+ * @begin{itemize}
+ * // Declare related objects
+ *
+ * SparseMatrix<double> A;
+ * Vector<double> x;
+ * Vector<double> b;
+ * SolverCG<> solver(...);
+ *
+ * //...initialize and build A
+ *
+ * std::vector<unsigned int> permutation(x.size());
+ *
+ * //...fill permutation with reasonable values
+ *
+ * // Define and initialize preconditioner
+ *
+ * PreconditionPSOR<SparseMatrix<double> > precondition;
+ * precondition.initialize (A, permutation, .6);
+ *
+ * solver.solve (A, x, b, precondition);
+ * @end{itemize}
+ *
+ * @author Guido Kanschat, 2003
+ */
+template <class MATRIX = SparseMatrix<double> >
+class PreconditionPSOR : public PreconditionRelaxation<MATRIX>
+{
+ public:
+ /**
+ * Initialize matrix and
+ * relaxation parameter. The
+ * matrix is just stored in the
+ * preconditioner object.
+ *
+ * The permutation vector is
+ * stored as a
+ * pointer. Therefore, it has to
+ * be assured that the lifetime
+ * of the vector exceeds the
+ * lifetime of the
+ * preconditioner.
+ *
+ * The relaxation parameter
+ * should be larger than zero and
+ * smaller than 2 for numerical
+ * reasons. It defaults to 1.
+ */
+ void initialize (const MATRIX& A,
+ const std::vector<unsigned int>& permutation,
+ typename PreconditionRelaxation<MATRIX>::AdditionalData
+ parameters = AdditionalData());
+
+ /**
+ * Apply preconditioner.
+ */
+ template<class VECTOR>
+ void vmult (VECTOR&, const VECTOR&) const;
+
+ /**
+ * Apply transpose
+ * preconditioner.
+ */
+ template<class VECTOR>
+ void Tvmult (VECTOR&, const VECTOR&) const;
+ private:
+ /**
+ * Storage for the permutation vector.
+ */
+ const std::vector<unsigned int>* permutation;
+};
+
+
+
/**
* Preconditioner using an iterative solver. This preconditioner uses
* a fully initialized LAC iterative solver for the approximate
}
+//----------------------------------------------------------------------//
+
+template <class MATRIX>
+inline void
+PreconditionPSOR<MATRIX>::initialize (
+ const MATRIX &rA,
+ const std::vector<unsigned int>& p,
+ typename PreconditionRelaxation<MATRIX>::AdditionalData parameters)
+{
+ permutation = &p;
+ PreconditionRelaxation<MATRIX>::initalize(rA, parameters);
+}
+
+
+template <class MATRIX>
+template<class VECTOR>
+inline void
+PreconditionPSOR<MATRIX>::vmult (VECTOR& dst, const VECTOR& src) const
+{
+ Assert (this->A!=0, ExcNotInitialized());
+ dst = src;
+ this->A->PSOR (dst, *permutation, this->relaxation);
+}
+
+
+
+template <class MATRIX>
+template<class VECTOR>
+inline void
+PreconditionPSOR<MATRIX>::Tvmult (VECTOR& dst, const VECTOR& src) const
+{
+ Assert (this->A!=0, ExcNotInitialized());
+ dst = src;
+ this->A->TPSOR (dst, *permutation, this->relaxation);
+}
+
+
//----------------------------------------------------------------------//
* corresponding ``.templates.h'' file and instantiate the respective
* class yourself.
*
- * @author Original version by Roland Becker, Guido Kanschat, Franz-Theo Suttmeier; lots of enhancements, reorganisation and documentation by Wolfgang Bangerth 1998
+ * @author several, 1994-2003
*/
template <typename number>
class SparseMatrix : public Subscriptor
*/
template <typename somenumber>
void TSOR (Vector<somenumber> &v,
+ const number om = 1.) const;
+
+ /**
+ * Perform a permuted SOR
+ * preconditioning in-place.
+ *
+ * The standard SOR method is
+ * applied in the order
+ * prescribed by @p{permutation},
+ * that is, first the row
+ * @p{permutation[0]}, then
+ * @p{permutation[1]} and so
+ * on.
+ *
+ * @p{omega} is the relaxation
+ * parameter.
+ */
+ template <typename somenumber>
+ void PSOR (Vector<somenumber> &v,
+ const std::vector<unsigned int> permutation,
+ const number om = 1.) const;
+
+ /**
+ * Perform a transposed permuted SOR
+ * preconditioning in-place.
+ *
+ * The transposed SOR method is
+ * applied in the order
+ * prescribed by @p{permutation},
+ * that is, first the row
+ * @p{permutation[m()-1]}, then
+ * @p{permutation[m()-2]} and so
+ * on.
+ *
+ * @p{omega} is the relaxation
+ * parameter.
+ */
+ template <typename somenumber>
+ void TPSOR (Vector<somenumber> &v,
+ const std::vector<unsigned int> permutation,
const number om = 1.) const;
/**
}
+template <typename number>
+template <typename somenumber>
+void
+SparseMatrix<number>::PSOR (
+ Vector<somenumber>& dst,
+ const std::vector<unsigned int> permutation,
+ const number om) const
+{
+ Assert (cols != 0, ExcMatrixNotInitialized());
+ Assert (val != 0, ExcMatrixNotInitialized());
+ Assert (m() == n(), ExcMatrixNotSquare());
+ Assert (m() == dst.size(), ExcDimensionMismatch(m(),dst.size()));
+ Assert (m() == permutation.size(),
+ ExcDimensionMismatch(m(), permutation.size()));
+
+ for (unsigned int urow=0; urow<m(); ++urow)
+ {
+ const unsigned int row = permutation[urow];
+ somenumber s = dst(row);
+ for (unsigned int j=cols->rowstart[row]; j<cols->rowstart[row+1]; ++j)
+ {
+ const unsigned int col = permutation[cols->colnums[j]];
+ if (col < row)
+ s -= val[j] * dst(col);
+ }
+
+ dst(row) = s * om / val[cols->rowstart[row]];
+ }
+}
+
+
+template <typename number>
+template <typename somenumber>
+void
+SparseMatrix<number>::TPSOR (
+ Vector<somenumber>& dst,
+ const std::vector<unsigned int> permutation,
+ const number om) const
+{
+ Assert (cols != 0, ExcMatrixNotInitialized());
+ Assert (val != 0, ExcMatrixNotInitialized());
+ Assert (m() == n(), ExcMatrixNotSquare());
+ Assert (m() == dst.size(), ExcDimensionMismatch(m(),dst.size()));
+ Assert (m() == permutation.size(),
+ ExcDimensionMismatch(m(), permutation.size()));
+
+ for (unsigned int urow=m(); urow != 0;)
+ {
+ --urow;
+ const unsigned int row = permutation[urow];
+ somenumber s = dst(row);
+ for (unsigned int j=cols->rowstart[row]; j<cols->rowstart[row+1]; ++j)
+ {
+ const unsigned int col = permutation[cols->colnums[j]];
+ if (col > row)
+ s -= val[j] * dst(col);
+ }
+
+ dst(row) = s * om / val[cols->rowstart[row]];
+ }
+}
+
+
template <typename number>
template <typename somenumber>
void