16#include "dune/istl/solvers.hh"
17#include "dune/istl/istlexception.hh"
18#include "dune/istl/operators.hh"
19#include "dune/istl/preconditioners.hh"
20#include "dune/istl/scalarproducts.hh"
40 template<
class L,
class P>
41 NMIIIAPCGSolver (L& op, P& prec,
double reduction,
int maxit,
int verbose,
int addedIterations = 2) :
42 ssp(), _op(op), _prec(prec), _sp(ssp), _reduction(reduction), _maxit(maxit), _verbose(verbose), _addedIterations(addedIterations)
44 gammas.resize(_addedIterations);
45 allGammas.resize(_maxit);
46 allEstimates.resize(_maxit);
48 for (k=0; k<_addedIterations; k++) gammas[k] = 0.0;
49 for (k=0; k<_maxit; k++) allGammas[k] = allEstimates[k] = 0.0;
50 static_assert(
static_cast<int>(L::category) ==
static_cast<int>(P::category),
51 "L and P must have the same category!");
52 static_assert(
static_cast<int>(L::category) ==
static_cast<int>(Dune::SolverCategory::sequential),
53 "L must be sequential!");
61 virtual void apply (
X& u,
X& b, Dune::InverseOperatorResult& res)
72 _op.applyscaleadd(-1,u,r);
77 double def0 = _sp.norm(rq);
86 std::cout <<
"=== rate=" << res.conv_rate
87 <<
", T=" << res.elapsed <<
", TIT=" << res.elapsed
88 <<
", IT=0" << std::endl;
94 std::cout <<
"=== NMIIIAPCGSolver" << std::endl;
96 this->printHeader(std::cout);
97 this->printOutput(std::cout,(
double) 0,def0);
102 double def=def0, defnew=def0;
104 sigma = _sp.dot(r,rq);
108 double eps0 = 0.0, epsk;
109 for ( ; i<=_maxit; i++ )
113 alpha = sigma/_sp.dot(q,h);
116 gammas[i%_addedIterations] = gamma;
117 allGammas[i] = gamma;
122 this->printOutput(std::cout,(
double) i,defnew,def);
124 if (i==_addedIterations)
126 for (i=0; i<_addedIterations; i++)
128 allEstimates[_addedIterations] = eps0;
131 if (i>_addedIterations)
134 for (
int k=0; k<_addedIterations; k++)
136 allEstimates[i] = epsk;
137 if (epsk<=_reduction)
150 double sigmaNew = _sp.dot(r,rq);
151 beta = sigmaNew/sigma;
159 this->printOutput(std::cout,(
double) i,def);
162 res.reduction = def/def0;
163 res.conv_rate = pow(res.reduction,1.0/i);
164 res.elapsed = watch.elapsed();
168 std::cout <<
"=== rate=" << res.conv_rate
169 <<
", T=" << res.elapsed
170 <<
", TIT=" << res.elapsed/i
171 <<
", IT=" << i << std::endl;
191 virtual void apply (
X& x,
X& b,
double reduction, Dune::InverseOperatorResult& res)
193 _reduction = reduction;
194 (*this).apply(x,b,res);
198 Dune::SeqScalarProduct<X> ssp;
199 Dune::LinearOperator<X,X>& _op;
200 Dune::Preconditioner<X,X>& _prec;
201 Dune::ScalarProduct<X>& _sp;
205 int _addedIterations;
206 std::vector<double> gammas;
207 std::vector<double> allGammas;
208 std::vector<double> allEstimates;
conjugate gradient method
X::field_type field_type
The field type of the operator to be inverted.
virtual void apply(X &x, X &b, double reduction, Dune::InverseOperatorResult &res)
Apply inverse operator with given reduction factor.
NMIIIAPCGSolver(L &op, P &prec, double reduction, int maxit, int verbose, int addedIterations=2)
Set up conjugate gradient solver.
X domain_type
The domain type of the operator to be inverted.
virtual void apply(X &u, X &b, Dune::InverseOperatorResult &res)
Apply inverse operator.
X range_type
The range type of the operator to be inverted.