KASKADE 7 development version
chebyshev.hh
Go to the documentation of this file.
1/*
2 * chebyshev.hh
3 *
4 * \brief Chebyshev semi-iteration.
5 *
6 * Created on: 14.12.2013
7 * Author: Lars Lubkoll
8 */
9
10#ifndef CHEBYSHEV_HH_
11#define CHEBYSHEV_HH_
12
13#include <cstdlib>
14#include <iostream>
15
17
18namespace Kaskade
19{
21 namespace ChebyshevDetail
22 {
23 double chebyshev(double x, size_t m)
24 {
25 if(m==0) return 1;
26 if(m==1) return x;
27
28 double n0 = 1, n1 = x;
29
30 for(size_t i=2; i<m+1; ++i)
31 {
32 double n = 2*x*n1 - n0;
33 n0 = n1;
34 n1 = n;
35 }
36 return n1;
37 }
38 }
40
52 template <class Operator, bool isPreconditioner=false>
53 class ChebyshevSemiIteration : public Dune::Preconditioner<typename Operator::Domain,typename Operator::Range>
54 {
55 public:
56 typedef typename Operator::Domain Domain;
57 typedef typename Operator::Range Range;
58
59 ChebyshevSemiIteration(Operator const& A_, double tol, size_t steps, size_t verbose_=0)
60 : A(A_), jac(A), a(0), b(0), eta(0), tolerance(tol), maxSteps(steps), verbose(verbose_), isInitialized(false)
61 {}
62
64
65 virtual void pre(Domain&, Range&){}
66 virtual void post(Domain&){}
67
68 virtual void apply(Domain& x, Range const& y)
69 {
70 if(!isInitialized)
71 {
72 std::cerr << "In file " << __FILE__ << ": line " << __LINE__;
73 std::cerr << ": No spectral bounds have been provided for chebyshev semi-iteration. Aborting." << std::endl;
74 abort();
75 }
76
77 double beta = 0;
78 double gammainv = 0;
79 Domain x0(x), x1(x); x1 *= 0;
80 Range r(y), jr(y), tmp(y), res0(y), res1(y); res1 *= 0;
81 A.applyscaleadd(-1.,x,tmp);
82 jac.apply(res0,tmp);
83 double initialResidual = res0*tmp, currentResidual = 0, desiredResidual = tolerance*tolerance*initialResidual;
84 if(verbose > 1) std::cout << "initial residual: " << initialResidual << std::endl;
85 for(size_t i=0; i<maxSteps; ++i)
86 {
87 if(i==0)
88 {
89 beta = 0;
90 gammainv = -1./a;
91 }
92 else
93 {
94 if(i==1) beta = -0.5*b*b/a;
95 else beta = 0.25*b*b*gammainv;
96 gammainv = -1./(a+beta);
97 }
98
99
100 x*=0;
101 x.axpy(-1.,jr);
102 x.axpy(-a,x0);
103 x.axpy(-beta,x1);
104 x *= gammainv;
105
106 x1 = x0;
107 x0 = x;
108
109 r = y;
110 A.applyscaleadd(-1.,x,r);
111 jac.apply(jr,r);
112
113 currentResidual = r*jr;
114 if((currentResidual < desiredResidual) && (isPreconditioner==false))
115 {
116 if(verbose>0)
117 {
118 std::cout << "Terminating chebyshev semi iteration after " << i << " iterations with final residual: " << currentResidual << "." << std::endl;
119 std::cout << "Residual reduction: " << currentResidual/initialResidual << " (initialResidual=" << initialResidual << ")" << std::endl;
120 }
121 return;
122 }
123 }
124 }
125
134 {
135 // parameters for describing the spectral bounds
136 // i.e. \f$\lambda\in[\lambda_{min},\lambda_{max}]\f$ with \f$\lambda_{min}=a-b\f$ and \f$\lambda_{max}=a+b\f$
137 a = 1.5; // center of spectral bounds
138 b = 1; // half diameter of the spectral bounds
139 eta = -a/b;
140 isInitialized = true;
141 }
142
143 void setSteps(size_t steps) { maxSteps = steps; }
144
145 private:
146 Operator const& A;
148 double a, b, eta, tolerance;
149 size_t maxSteps, verbose;
150 bool isInitialized;
151 };
152
158 template <class Operator>
160 {
161 public:
162 ChebyshevPreconditioner(Operator const& A, size_t steps, size_t verbose=0) : ChebyshevSemiIteration<Operator,true>(A,0,steps,verbose) {}
163 };
164}
165
166#endif /* CHEBYSHEV_HH_ */
Preconditioner based on the Chebyshev semi-iteration. In order to provide a linear preconditioner the...
Definition: chebyshev.hh:160
ChebyshevPreconditioner(Operator const &A, size_t steps, size_t verbose=0)
Definition: chebyshev.hh:162
Preconditioned chebyshev semi iteration.
Definition: chebyshev.hh:54
void setSteps(size_t steps)
Definition: chebyshev.hh:143
void initForMassMatrix_TetrahedralQ1Elements()
Init spectral bounds for the mass matrix arising from tetrahedral discretization of the domain and li...
Definition: chebyshev.hh:133
ChebyshevSemiIteration(Operator const &A_, double tol, size_t steps, size_t verbose_=0)
Definition: chebyshev.hh:59
virtual void pre(Domain &, Range &)
Definition: chebyshev.hh:65
virtual void apply(Domain &x, Range const &y)
Definition: chebyshev.hh:68
virtual void post(Domain &)
Definition: chebyshev.hh:66