From 96ed42ac489fe740d8f5daa3c6c2981c1d75c8a7 Mon Sep 17 00:00:00 2001 From: Martin Kronbichler Date: Thu, 27 Aug 2009 15:18:38 +0000 Subject: [PATCH] Finish implementation of Chebyshev preconditioner. git-svn-id: https://svn.dealii.org/trunk@19348 0785d39b-7218-0410-832d-ea1e28bc413d --- .../deal.II/include/multigrid/mg_smoother.h | 3 ++ deal.II/doc/news/changes.h | 8 ++++ deal.II/lac/include/lac/precondition.h | 47 +++++++++++++++++++ 3 files changed, 58 insertions(+) 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 () -- 2.39.5