10#include "dune/istl/istlexception.hh" 
   11#include "dune/istl/operators.hh" 
   12#include "dune/istl/preconditioners.hh" 
   13#include "dune/istl/scalarproducts.hh" 
   14#include <dune/common/timer.hh> 
   15#include <dune/common/static_assert.hh> 
   61    template<
class L, 
class P>
 
   63        double reduction, 
int maxit, 
int verbose) : 
 
   64      ssp(), _op(op), _prec(prec), _sp(ssp), _reduction(reduction), _maxit(maxit), _verbose(verbose)
 
   66        dune_static_assert(
static_cast<int>(L::category) == 
static_cast<int>(P::category), 
"L and P must be of the same category!");
 
   67        dune_static_assert(
static_cast<int>(L::category) == 
static_cast<int>(SolverCategory::sequential), 
"L must be sequential!");
 
   74    template<
class L, 
class S, 
class P>
 
   76        double reduction, 
int maxit, 
int verbose) : 
 
   77      _op(op), _prec(prec), _sp(sp), _reduction(reduction), _maxit(maxit), _verbose(verbose)
 
   79        dune_static_assert( 
static_cast<int>(L::category) == 
static_cast<int>(P::category),
 
   80                            "L and P must have the same category!");
 
   81        dune_static_assert( 
static_cast<int>(L::category) == 
static_cast<int>(S::category),
 
   82                            "L and S must have the same category!");
 
   90    virtual void apply (
X& x, 
X& b, InverseOperatorResult& res)
 
   92    const double EPSILON=1e-80;
 
   95    field_type           rho, rho_new(0), alpha, beta, h, omega;
 
  117      _op.applyscaleadd(-1,x,r);  
 
  126    norm = norm_old = norm_0 = _sp.norm(r);
 
  137      std::cout << 
"=== KBiCGSTABSolver" << std::endl;
 
  140        this->printHeader(std::cout);
 
  141        this->printOutput(std::cout,0,norm_0);
 
  147    if ( norm < (_reduction * norm_0)  || norm<1E-30)
 
  154      res.elapsed = watch.elapsed();
 
  162    for (it = 0.5; it < _maxit; it+=.5)
 
  169      if(!(it < 1)) rho_new = _sp.dot(rt,r);
 
  172      if (std::abs(rho) <= EPSILON)
 
  173            DUNE_THROW(ISTLError,
"breakdown in KBiCGSTAB - rho " 
  174                       << rho << 
" <= EPSILON " << EPSILON
 
  175                       << 
" after " << it << 
" iterations");
 
  176          if (std::abs(omega) <= EPSILON)
 
  177            DUNE_THROW(ISTLError,
"breakdown in KBiCGSTAB - omega " 
  178                       << omega << 
" <= EPSILON " << EPSILON
 
  179                       << 
" after " << it << 
" iterations");
 
  186        beta = ( rho_new / rho ) * ( alpha / omega );       
 
  199        rho_new = _sp.dot(rt,r);
 
  208      if ( std::abs(h) < EPSILON )
 
  209      DUNE_THROW(ISTLError,
"h=0 in KBiCGSTAB");
 
  228        this->printOutput(std::cout,it,norm,norm_old);
 
  231      if ( norm < (_reduction * norm_0) )
 
  248      omega = _sp.dot(t,r)/_sp.dot(t,t);
 
  268        this->printOutput(std::cout,it,norm,norm_old);
 
  271      if ( norm < (_reduction * norm_0)  || norm<1E-30)
 
  281      this->printOutput(std::cout,it,norm);
 
  284    res.iterations = 
static_cast<int>(std::ceil(it));              
 
  285    res.reduction = norm/norm_0;
 
  286    res.conv_rate  = pow(res.reduction,1.0/it);
 
  287    res.elapsed = watch.elapsed();
 
  289              std::cout << 
"=== rate=" << res.conv_rate
 
  290                        << 
", T=" << res.elapsed
 
  291                        << 
", TIT=" << res.elapsed/it
 
  292                        << 
", IT=" << it << std::endl;
 
  300    virtual void apply (
X& x, 
X& b, 
double reduction, InverseOperatorResult& res)
 
  302      _reduction = reduction;
 
  303      (*this).apply(x,b,res);
 
  307    SeqScalarProduct<X> ssp;
 
  308    LinearOperator<X,X>& _op;
 
  309    Preconditioner<X,X>& _prec;
 
  310    ScalarProduct<X>& _sp;
 
Statistics about the application of an inverse operator.
KBiCGSTABSolver(L &op, S &sp, P &prec, double reduction, int maxit, int verbose)
Set up solver.
X domain_type
The domain type of the operator to be inverted.
KBiCGSTABSolver(L &op, P &prec, double reduction, int maxit, int verbose)
Set up solver.
X range_type
The range type of the operator to be inverted.
virtual void apply(X &x, X &b, double reduction, InverseOperatorResult &res)
Apply inverse operator with given reduction factor.
virtual void apply(X &x, X &b, InverseOperatorResult &res)
Apply inverse operator.
X::field_type field_type
The field type of the operator to be inverted.