KASKADE 7 development version
mg/cg.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the library KASKADE 7 */
4/* https://www.zib.de/research/projects/kaskade7-finite-element-toolbox */
5/* */
6/* Copied from dune/istl/solvers.hh and adapted to NM III notation */
7/* */
8/* KASKADE 7 is distributed under the terms of the ZIB Academic License. */
9/* see $KASKADE/academic.txt */
10/* */
11/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13#ifndef NMII_CG_HH
14#define NMII_CG_HH
15
16#include "dune/istl/istlexception.hh"
17#include "dune/istl/operators.hh"
18#include "dune/istl/preconditioners.hh"
19#include "dune/istl/scalarproducts.hh"
20
21namespace Kaskade {
22
24 template<class X>
25 class NMIIICGSolver : public InverseOperator<X,X> {
26 public:
28 typedef X domain_type;
30 typedef X range_type;
32 typedef typename X::field_type field_type;
33
39 template<class L, class P>
40 NMIIICGSolver (L& op, P& prec, double reduction, int maxit, int verbose) :
41 ssp(), _op(op), _sp(ssp), _reduction(reduction), _maxit(maxit), _verbose(verbose)
42 {
43 dune_static_assert( static_cast<int>(L::category) == static_cast<int>(P::category),
44 "L and P must have the same category!");
45 dune_static_assert( static_cast<int>(L::category) == static_cast<int>(SolverCategory::sequential),
46 "L must be sequential!");
47 }
48
54 virtual void apply (X& u, X& b, InverseOperatorResult& res)
55 {
56 res.clear(); // clear solver statistics
57 Timer watch; // start a timer
58
59 X r(u); // the search direction
60 X p(u); // the search direction
61 X q(u); // a temporary vector
62
63 r = b;
64 _op.applyscaleadd(-1,u,r); // r = r-Au
65 p = r;
66
67 double def0 = _sp.norm(r);// compute norm
68 if (def0<1E-30) // convergence check
69 {
70 res.converged = true;
71 res.iterations = 0; // fill statistics
72 res.reduction = 0;
73 res.conv_rate = 0;
74 res.elapsed=0;
75 if (_verbose>0) // final print
76 std::cout << "=== rate=" << res.conv_rate
77 << ", T=" << res.elapsed << ", TIT=" << res.elapsed
78 << ", IT=0" << std::endl;
79 return;
80 }
81
82 if (_verbose>0) // printing
83 {
84 std::cout << "=== NMIIICGSolver" << std::endl;
85 if (_verbose>1) {
86 this->printHeader(std::cout);
87 this->printOutput(std::cout,0,def0);
88 }
89 }
90
91 // some local variables
92 double def=def0, defnew=def0; // loop variables
93 field_type alpha,beta;
94
95 // the loop
96 int i=1;
97 for ( ; i<=_maxit; i++ )
98 {
99 // minimize in given search direction p
100 _op.apply(p,q); // q=Ap
101 alpha = def/_sp.dot(p,q); // scalar product
102 u.axpy(alpha,p); // update solution
103
104 // convergence test
105
106 if (_verbose>1) // print
107 this->printOutput(std::cout,i,defnew,def);
108
109 if (defnew<def0*_reduction || def<1E-30) // convergence check
110 {
111 res.converged = true;
112 break;
113 }
114
115 r.axpy(-alpha,q); // update defect
116 defnew=_sp.norm(r); // comp defect norm
117
118 // determine new search direction
119 beta = defnew/def; // scaling factor
120 p *= beta; // scale old search direction
121 p += r; // orthogonalization with correction
122 def = defnew; // update norm
123 }
124
125 if (_verbose>0) // printing for non verbose
126 this->printOutput(std::cout,i,def);
127
128 res.iterations = i; // fill statistics
129 res.reduction = def/def0;
130 res.conv_rate = pow(res.reduction,1.0/i);
131 res.elapsed = watch.elapsed();
132
133 if (_verbose>0) // final print
134 {
135 std::cout << "=== rate=" << res.conv_rate
136 << ", T=" << res.elapsed
137 << ", TIT=" << res.elapsed/i
138 << ", IT=" << i << std::endl;
139 }
140 }
141
147 virtual void apply (X& x, X& b, double reduction, InverseOperatorResult& res)
148 {
149 _reduction = reduction;
150 (*this).apply(x,b,res);
151 }
152
153 private:
154 SeqScalarProduct<X> ssp;
155 LinearOperator<X,X>& _op;
156 ScalarProduct<X>& _sp;
157 double _reduction;
158 int _maxit;
159 int _verbose;
160 };
161}
162#endif
conjugate gradient method
Definition: mg/cg.hh:25
X range_type
The range type of the operator to be inverted.
Definition: mg/cg.hh:30
X::field_type field_type
The field type of the operator to be inverted.
Definition: mg/cg.hh:32
X domain_type
The domain type of the operator to be inverted.
Definition: mg/cg.hh:28
virtual void apply(X &x, X &b, double reduction, InverseOperatorResult &res)
Apply inverse operator with given reduction factor.
Definition: mg/cg.hh:147
NMIIICGSolver(L &op, P &prec, double reduction, int maxit, int verbose)
Set up conjugate gradient solver.
Definition: mg/cg.hh:40
virtual void apply(X &u, X &b, InverseOperatorResult &res)
Apply inverse operator.
Definition: mg/cg.hh:54