19#include <boost/circular_buffer.hpp>
20#include <boost/timer/timer.hpp>
22#include "dune/common/timer.hh"
23#include "dune/istl/istlexception.hh"
24#include "dune/istl/operators.hh"
25#include "dune/istl/preconditioners.hh"
26#include "dune/istl/scalarproducts.hh"
27#include "dune/istl/solvers.hh"
45 template <
class Domain,
class Range>
48 if (
dynamic_cast<Dune::Richardson<Domain,Range> const*
>(p))
51 return sp->requiresInitializedInput();
99 virtual operator bool()
const = 0;
157 virtual operator bool()
const
239 virtual operator bool()
const;
254 std::vector<Real>
const&
gamma2()
const {
return gammas2; }
260 std::vector<Real> gammas2;
279 template<
class X,
class Xstar>
280 class Pcg :
public Dune::InverseOperator<X,Xstar>
305 : proxyOp(op_,zeroDp), op(op_),
306 proxyPrec(prec_,zeroDp), prec(prec_),
321 Pcg(Dune::LinearOperator<X,Xstar>& op_, Dune::Preconditioner<X,Xstar>& prec_,
323 : proxyOp(op_,dp_), op(proxyOp),
324 proxyPrec(prec_,dp_), prec(proxyPrec),
334 virtual void apply (
X& u, Xstar& b, Dune::InverseOperatorResult& res)
340 boost::timer::cpu_timer mvTimer;
342 boost::timer::cpu_timer apTimer;
344 boost::timer::cpu_timer prTimer;
348 op.applyscaleadd(-1,u,r);
355 std::unique_ptr<X> rq(
new X(u)); *rq = 0;
358 std::unique_ptr<X> q(
new X(*rq));
365 sigma = op.dp(*rq,r);
375 std::cout <<
"=== Kaskade7 PCG ===\n";
377 std::cout <<
"Iter precond res. ratio avg. rate step ener \n"
378 <<
" 0" << std::setw(13) << sigma0 << std::endl;
388 if (std::isnan(qAq)) std:: cerr <<
"qAq is nan\n";
391 if (std::abs(qAq) < 1e-28*sigma)
396 +
" vs sigma " + std::to_string(sigma) +
" in PCG.",
405 resDebug.push_back(std::sqrt(sigma));
425 std::cout << std::setw(6) << i
426 << std::setw(13) << std::scientific << std::setprecision(5) << std::abs(sigmaNew)
427 << std::setw(12) << std::fixed << std::setprecision(3) << std::abs(sigmaNew/sigma)
428 << std::setw(12) << std::fixed << std::setprecision(3) << std::pow(std::abs(sigmaNew)/sigma0,1.0/i)
429 << std::setw(12) << std::scientific << std::setprecision(5) << gamma;
432 Xstar Au = u; Au = 0;
434 auto e = op.dp(u,Au);
437 std::cout <<
" " << op.dp(u,Au) <<
" " << e <<
" " << u.two_norm();
439 std::cout << std::endl;
444 if (std::abs(sigmaNew) < 1e-28*sigma0)
447 beta = sigmaNew/sigma;
456 std::cout << std::setw(6) << i << std::setw(12) << std::abs(sigma) << std::endl;
459 res.reduction = std::sqrt(std::abs(sigma)/sigma0);
460 res.conv_rate = pow(res.reduction,1.0/i);
461 res.elapsed = watch.elapsed();
465 std::cout <<
"=== rate=" << res.conv_rate
466 <<
", T=" << res.elapsed
467 <<
", TIT=" << res.elapsed/i
468 <<
", IT=" << i << std::endl;
470 std::cout <<
"Matrix-Vector time: " << mvTimer.format()
471 <<
"vector ops : " << apTimer.format()
472 <<
"preconditioner : " << prTimer.format() <<
'\n';
481 virtual void apply (
X& x, Xstar& b,
double tol, Dune::InverseOperatorResult& res)
484 (*this).apply(x,b,res);
493 virtual Dune::SolverCategory::Category
category()
const override
495 return Dune::SolverCategory::sequential;
520 std::vector<field_type> resDebug;
Abstract base class for dual pairing of and its dual space .
To be raised if the matrix is not positive definite.
PCG termination after a given number of iterations.
virtual void residual(Real)
unused
virtual void step(Real)
supplies energy of step to the termination criterion
virtual PCGTerminationCriterion< R > & tolerance(Real)
unused
PCGCountingTerminationCriterion(int n_)
Constructor.
virtual void clear()
re-initializes the termination criterion for a new IterateType::CG run
TerminationCriterion based on an absolute energy error estimate.
virtual void clear()
re-initializes the termination criterion for a new IterateType::CG run
virtual void residual(Real sigma)
supplies the preconditioned residual to the termination criterion
virtual void step(Real gamma2)
supplies energy of step to the termination criterion
PCGEnergyErrorTerminationCriterion(Real atol, int maxit)
constructor
Real error() const
returns the estimated absolute energy error
PCGEnergyErrorTerminationCriterion< Real > & lookahead(int lah)
set requested lookahead value
void setMaxit(int m)
Sets a new value for the maximal number of iterations.
std::vector< Real > const & gamma2() const
virtual PCGEnergyErrorTerminationCriterion< Real > & tolerance(Real atol)
set requested absolute tolerance
Interface for IterateType::PCG termination criterion policy classes.
virtual void clear()=0
re-initializes the termination criterion for a new IterateType::CG run
virtual void residual(Real sigma)=0
supplies the preconditioned residual to the termination criterion
virtual PCGTerminationCriterion< R > & tolerance(Real tol)=0
set requested tolerance
virtual void step(Real gamma2)=0
supplies energy of step to the termination criterion
preconditioned conjugate gradient method
ScalarTraits< field_type >::Real Real
the real field type corresponding to field_type
virtual void apply(X &x, Xstar &b, double tol, Dune::InverseOperatorResult &res)
Apply inverse operator with given tolerance.
Xstar range_type
The range type of the operator to be inverted.
virtual void apply(X &u, Xstar &b, Dune::InverseOperatorResult &res)
Apply inverse operator by performing a number of IterateType::PCG iterations.
virtual Dune::SolverCategory::Category category() const override
returns the category of the operator
X::field_type field_type
The field type of the operator to be inverted.
Pcg(Dune::LinearOperator< X, Xstar > &op_, Dune::Preconditioner< X, Xstar > &prec_, DualPairing< X, Xstar > const &dp_, PCGTerminationCriterion< Real > &terminate_, int verbose_=0)
Set up conjugate gradient solver.
X domain_type
The domain type of the operator to be inverted.
Pcg(SymmetricLinearOperator< X, Xstar > &op_, SymmetricPreconditioner< X, Xstar > &prec_, PCGTerminationCriterion< Real > &terminate_, int verbose_=0)
Set up conjugate gradient solver.
Helper class for working with (real or complex) scalar field types.
Scalar Real
The real type on which the scalar field is based.
Interface for symmetric linear operators.
Wrapper class to present (hopefully) symmetric linear operators in the SymmetricLinearOperator interf...
Wrapper class presenting a symmetric preconditioner interface for any preconditioner.
Zero dual pairing implementation (mainly useful whenever a dual pairing is needed for formal language...
bool requiresInitializedInput(Dune::Preconditioner< Domain, Range > const *p)
Whether a preconditioner needs zero initialized result vector or not.