10#include "dune/istl/solvers.hh" 
   11#include "dune/istl/istlexception.hh" 
   12#include "dune/istl/operators.hh" 
   13#include "dune/istl/preconditioners.hh" 
   14#include "dune/istl/scalarproducts.hh" 
   15#include <dune/common/timer.hh> 
   16#include <dune/common/static_assert.hh> 
   53    template<
class L, 
class P>
 
   54    RestartedFGMResSolver (L& op, P& prec, 
double reduction, 
int restart, 
int maxit, 
int verbose, 
bool recalc_defect = 
false) : 
 
   56      ssp(), _sp(ssp), _restart(restart),
 
   57      _reduction(reduction), _maxit(maxit), _verbose(verbose),
 
   58      _recalc_defect(recalc_defect)
 
   60      dune_static_assert(
static_cast<int>(P::category) == 
static_cast<int>(SolverCategory::sequential),
 
   61        "P must be sequential!");
 
   62      dune_static_assert(
static_cast<int>(L::category) == 
static_cast<int>(SolverCategory::sequential),
 
   63        "L must be sequential!");
 
   73    template<
class L, 
class S, 
class P>
 
   74    RestartedFGMResSolver (L& op, S& sp, P& prec, 
double reduction, 
int restart, 
int maxit, 
int verbose, 
bool recalc_defect = 
false) :  
 
   76      _sp(sp), _restart(restart),
 
   77      _reduction(reduction), _maxit(maxit), _verbose(verbose),
 
   78      _recalc_defect(recalc_defect)
 
   80      dune_static_assert(
static_cast<int>(P::category) == 
static_cast<int>(SolverCategory::sequential),
 
   81        "P must be sequential!");
 
   82      dune_static_assert(
static_cast<int>(L::category) == 
static_cast<int>(SolverCategory::sequential),
 
   83        "L must be sequential!");
 
   87    virtual void apply (
X& x, 
X& b, Dune::InverseOperatorResult& res)
 
   89      apply(x,b,_reduction,res);
 
   97    virtual void apply (
X& x, 
Y& b, 
double reduction, Dune::InverseOperatorResult& res)
 
  105      std::vector<field_type> s(m+1), cs(m), sn(m);
 
  106      std::vector<field_type> sw(m+1), csw(m), snw(m);
 
  109      std::vector< std::vector<field_type> > H(m+1,s), Hw(m+1,s);
 
  110      std::vector<F> v(1,b);
 
  111      std::vector<X> w(1,b);
 
  121        norm_0 = _sp.norm(b);
 
  123          _A_.applyscaleadd(-1,x,b);  
 
  130        beta = _sp.norm(v[0]);
 
  137      norm = norm_old = _sp.norm(v[0]);
 
  142        std::cout << 
"=== RestartedGMResSolver" << std::endl;
 
  145          this->printHeader(std::cout);
 
  146          this->printOutput(std::cout,0,norm);
 
  151      if (norm <= reduction * norm_0) {
 
  153        res.converged  = 
true;
 
  159      while (j <= _maxit && res.converged != 
true) {
 
  160        v[0] *= (1.0 / beta);
 
  161        for (i=1; i<=m; i++) s[i] = 0.0;
 
  164        for (i = 0; i < m && j <= _maxit && res.converged != 
true; i++, j++) {
 
  165          if(w.size()<i+1) w.push_back(b);
 
  167          if(v.size()<i+2) v.push_back(b);
 
  169          _M.apply(w[i], v[i]);
 
  170          _A_.apply(w[i],  v[i+1]);
 
  171          for (k = 0; k <= i; k++) {
 
  172            H[k][i] = _sp.dot(v[i+1], v[k]);
 
  174            v[i+1].axpy(-H[k][i], v[k]);
 
  176          H[i+1][i] = _sp.norm(v[i+1]);
 
  177          if (H[i+1][i] == 0.0)
 
  178            DUNE_THROW(ISTLError,
"breakdown in GMRes - |w| " 
  179              << w[i] << 
" == 0.0 after " << j << 
" iterations");
 
  181          v[i+1] *= (1.0 / H[i+1][i]);
 
  183          for (k = 0; k < i; k++)
 
  184            applyPlaneRotation(H[k][i], H[k+1][i], cs[k], sn[k]);
 
  186          generatePlaneRotation(H[i][i], H[i+1][i], cs[i], sn[i]);
 
  187          applyPlaneRotation(H[i][i], H[i+1][i], cs[i], sn[i]);
 
  188          applyPlaneRotation(s[i], s[i+1], cs[i], sn[i]);
 
  190          norm = std::abs(s[i+1]);
 
  194            this->printOutput(std::cout,j,norm,norm_old);
 
  199          if (norm < reduction * norm_0) {
 
  200            res.converged = 
true;
 
  206        update(tmp, i - 1, H, s, w);
 
  209          std::cout << 
"|dx|:" << _sp.norm(tmp) << 
" " << std::flush;
 
  214        _A_.applyscaleadd(-1,tmp,  b);
 
  222        res.converged = 
false;
 
  226        if (norm < reduction * norm_0) {
 
  228          res.converged = 
true;
 
  231        if (res.converged != 
true && _verbose > 0)
 
  232          std::cout << 
"=== GMRes::restart\n";
 
  238      res.reduction = norm / norm_0;
 
  239      res.conv_rate  = pow(res.reduction,1.0/j);
 
  240      res.elapsed = watch.elapsed();
 
  248    print_result (
const Dune::InverseOperatorResult & res)
 const 
  250      int j = res.iterations>0?res.iterations:1;
 
  251      std::cout << 
"=== rate=" << res.conv_rate
 
  252                << 
", T=" << res.elapsed
 
  253                << 
", TIT=" << res.elapsed/j
 
  254                << 
", IT=" << res.iterations
 
  260      std::vector< std::vector<field_type> > & h,
 
  261      std::vector<field_type> & s, std::vector<F> v)
 
  263      std::vector<field_type> y(s);
 
  266      for (
int i = k; i >= 0; i--) {
 
  268        for (
int j = i - 1; j >= 0; j--)
 
  269          y[j] -= h[j][i] * y[i];
 
  272      for (
int j = 0; j <= k; j++)
 
  283      } 
else if (std::abs(dy) > std::abs(dx)) {
 
  285        sn = 1.0 / std::sqrt( 1.0 + temp*temp );
 
  289        cs = 1.0 / std::sqrt( 1.0 + temp*temp );
 
  299      dy = -sn * dx + cs * dy;
 
  303    Dune::LinearOperator<X,X>& _A_;
 
  304    Dune::Preconditioner<X,X>& _M;
 
  305    Dune::SeqScalarProduct<X> ssp;
 
  306    Dune::ScalarProduct<X>& _sp;
 
implements the Generalized Minimal Residual (GMRes) method
virtual void apply(X &x, X &b, Dune::InverseOperatorResult &res)
X::field_type field_type
The field type of the operator to be inverted.
Y range_type
The range type of the operator to be inverted.
F basis_type
The field type of the basis vectors.
virtual void apply(X &x, Y &b, double reduction, Dune::InverseOperatorResult &res)
Apply inverse operator.
X domain_type
The domain type of the operator to be inverted.
RestartedFGMResSolver(L &op, S &sp, P &prec, double reduction, int restart, int maxit, int verbose, bool recalc_defect=false)
Set up solver.
RestartedFGMResSolver(L &op, P &prec, double reduction, int restart, int maxit, int verbose, bool recalc_defect=false)
Set up solver.