From: kronbichler
Date: Thu, 27 Aug 2009 15:18:38 +0000 (+0000)
Subject: Finish implementation of Chebyshev preconditioner.
X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=09f139f53e7877d982d4ddcf439d08bbc230801b;p=dealii-svn.git
Finish implementation of Chebyshev preconditioner.
git-svn-id: https://svn.dealii.org/trunk@19348 0785d39b-7218-0410-832d-ea1e28bc413d
---
diff --git a/deal.II/deal.II/include/multigrid/mg_smoother.h b/deal.II/deal.II/include/multigrid/mg_smoother.h
index c80fe1c8b2..ff47759bef 100644
--- a/deal.II/deal.II/include/multigrid/mg_smoother.h
+++ b/deal.II/deal.II/include/multigrid/mg_smoother.h
@@ -130,6 +130,7 @@ class MGSmoother : public MGSmootherBase
* nonzero.
*/
unsigned int debug;
+
/**
* Memory for auxiliary vectors.
*/
@@ -418,6 +419,8 @@ class MGSmootherRelaxation : public MGSmoother
};
+
+
/**
* Smoother using preconditioner classes.
*
diff --git a/deal.II/doc/news/changes.h b/deal.II/doc/news/changes.h
index ef8290ba35..bc8af7f26c 100644
--- a/deal.II/doc/news/changes.h
+++ b/deal.II/doc/news/changes.h
@@ -305,6 +305,14 @@ inconvenience this causes.
(GK 2009/08/26)
+
+ New: The class PreconditionChebyshev implements a
+ preconditioner based on Chebyshev polynomials. It is based on matrix-vector
+ products together with some vector updates.
+
+ (Martin Kronbichler 2009/08/25)
+
+
diff --git a/deal.II/lac/include/lac/precondition.h b/deal.II/lac/include/lac/precondition.h
index 1707b0f450..5103538aba 100644
--- a/deal.II/lac/include/lac/precondition.h
+++ b/deal.II/lac/include/lac/precondition.h
@@ -964,6 +964,15 @@ public:
void vmult (VECTOR &dst,
const VECTOR &src) const;
+ /**
+ * Computes the action of the
+ * transposed preconditioner on
+ * src, storing the result
+ * in dst.
+ */
+ void Tvmult (VECTOR &dst,
+ const VECTOR &src) const;
+
/**
* Resets the preconditioner.
*/
@@ -1670,6 +1679,44 @@ PreconditionChebyshev::vmult (VECTOR &dst,
+template
+inline
+void
+PreconditionChebyshev::Tvmult (VECTOR &dst,
+ const VECTOR &src) const
+{
+ Assert (is_initialized, ExcMessage("Preconditioner not initialized"));
+ double rhok = delta / theta, sigma = theta / delta;
+ if (data.nonzero_starting && !dst.all_zero())
+ {
+ matrix_ptr->Tvmult (update1, dst);
+ update1 -= src;
+ update1 /= theta;
+ update1.scale (diagonal_inverse);
+ dst -= update1;
+ }
+ else
+ {
+ dst.equ (1./theta, src);
+ dst.scale (diagonal_inverse);
+ update1.equ(-1.,dst);
+ }
+
+ for (unsigned int k=0; kTvmult (update2, dst);
+ update2 -= src;
+ update2.scale (diagonal_inverse);
+ const double rhokp = 1./(2.*sigma-rhok);
+ const double factor1 = rhokp * rhok, factor2 = 2.*rhokp/delta;
+ rhok = rhokp;
+ update1.sadd (factor1, factor2, update2);
+ dst -= update1;
+ }
+}
+
+
+
template
inline
void PreconditionChebyshev::clear ()