4#include <dune/istl/eigenvalue/arpackpp.hh>
5#include <dune/istl/scalarproducts.hh>
6#include <dune/common/timer.hh>
21 typedef typename FieldTraits<field_type>::real_type
real_type;
25 using InverseOperator<X,X>::InverseOperator;
32 template<
class L,
class P>
34 ssp(), _op(op), _prec(prec), _sp(ssp), _reduction(reduction), _maxit(maxit), _verbose(verbose)
46 template<
class L,
class S,
class P>
48 _op(op), _prec(prec), _sp(sp), _reduction(reduction), _maxit(maxit), _verbose(verbose)
56 CGSolverFork (LinearOperator<X,X>& op, Preconditioner<X,X>& prec,
57 real_type reduction,
int maxit,
int verbose,
bool condition_estimate) :
CGSolverFork<X>(op, prec, reduction, maxit, verbose)
59 _condition_estimate = condition_estimate;
62 CGSolverFork (LinearOperator<X,X>& op, ScalarProduct<X>& sp, Preconditioner<X,X>& prec,
63 real_type reduction,
int maxit,
int verbose,
bool condition_estimate) :
CGSolverFork<X>(op, sp, prec, reduction, maxit, verbose)
65 _condition_estimate = condition_estimate;
80 virtual void apply (X& x, X& b, InverseOperatorResult& res)
87 _op.applyscaleadd(-1,x,b);
97 std::cout <<
"=== CGSolver: abort due to infinite or NaN initial defect"
99 DUNE_THROW(SolverAbort,
"CGSolver: initial defect=" << def0
100 <<
" is infinite or NaN");
105 res.converged =
true;
111 std::cout <<
"=== rate=" << res.conv_rate
112 <<
", T=" << res.elapsed <<
", TIT=" << res.elapsed
113 <<
", IT=0" << std::endl;
119 std::cout <<
"=== CGSolver" << std::endl;
121 this->printHeader(std::cout);
122 this->printOutput(std::cout,
real_type(0),def0);
133 rholast = _sp.dot(p,b);
136 std::vector<real_type> alphas(0);
137 std::vector<real_type> betas(0);
142 for ( ; i<=_maxit; i++ )
162 alpha = _sp.dot(p,q);
163 lambda = rholast/alpha;
164 alphas.push_back(lambda);
172 this->printOutput(std::cout,
real_type(i),defnew,def);
178 std::cout <<
"=== CGSolver: abort due to infinite or NaN defect"
180 DUNE_THROW(SolverAbort,
181 "CGSolver: defect=" << def <<
" is infinite or NaN");
184 if (def<def0*_reduction || def<1E-30)
186 res.converged =
true;
195 betas.push_back(beta);
202 i=std::min(_maxit,i);
204 res.elapsed = watch.elapsed();
206 if (_condition_estimate) {
210 MAT T(i, i, MAT::row_wise);
212 for (
auto row = T.createbegin(); row != T.createend(); ++row) {
214 row.insert(row.index()-1);
215 row.insert(row.index());
216 if (row.index() < T.N() - 1)
217 row.insert(row.index()+1);
219 for (
int row = 0; row < i; ++row) {
221 T[row][row-1] = std::sqrt(betas[row-1]) / alphas[row-1];
224 T[row][row] = 1.0 / alphas[row];
226 T[row][row] += betas[row-1] / alphas[row-1];
230 T[row][row+1] = std::sqrt(betas[row]) / alphas[row];
235 Dune::ArPackPlusPlus_Algorithms<MAT, VEC> arpack(T);
239 double min_eigv, max_eigv;
240 arpack.computeSymMinMagnitude (eps, eigv, min_eigv);
241 arpack.computeSymMaxMagnitude (eps, eigv, max_eigv);
244 std::cout <<
"Min eigv: " << min_eigv << std::endl;
245 std::cout <<
"Max eigv: " << max_eigv << std::endl;
246 std::cout <<
"Condition: " << max_eigv / min_eigv << std::endl;
250 std::cerr <<
"WARNING: Condition estimate was requested. This requires ARPACK, but ARPACK was not found!" << std::endl;
255 this->printOutput(std::cout,
real_type(i),def);
259 res.reduction =
static_cast<double>(def/def0);
260 res.conv_rate =
static_cast<double>(pow(res.reduction,1.0/i));
264 std::cout <<
"=== rate=" << res.conv_rate
265 <<
", T=" << res.elapsed
266 <<
", TIT=" << res.elapsed/i
267 <<
", IT=" << i << std::endl;
282 virtual void apply (X& x, X& b,
double reduction,
283 InverseOperatorResult& res)
286 _reduction = reduction;
287 (*this).apply(x,b,res);
288 _reduction = saved_reduction;
292 typedef Dune::BCRSMatrix<Dune::FieldMatrix<real_type,1,1> > MAT;
293 typedef Dune::BlockVector<Dune::FieldVector<real_type,1> > VEC;
294 bool _condition_estimate;
296 SeqScalarProduct<X> ssp;
297 LinearOperator<X,X>& _op;
298 Preconditioner<X,X>& _prec;
299 ScalarProduct<X>& _sp;
conjugate gradient method
Definition: cg_fork.hh:12
X domain_type
The domain type of the operator to be inverted.
Definition: cg_fork.hh:15
virtual void apply(X &x, X &b, InverseOperatorResult &res)
Apply inverse operator.
Definition: cg_fork.hh:80
CGSolverFork(L &op, P &prec, real_type reduction, int maxit, int verbose)
Set up conjugate gradient solver.
Definition: cg_fork.hh:33
CGSolverFork(L &op, S &sp, P &prec, real_type reduction, int maxit, int verbose)
Set up conjugate gradient solver.
Definition: cg_fork.hh:47
X range_type
The range type of the operator to be inverted.
Definition: cg_fork.hh:17
FieldTraits< field_type >::real_type real_type
The real type of the field type (is the same if using real numbers, but differs for std::complex)
Definition: cg_fork.hh:21
virtual void apply(X &x, X &b, double reduction, InverseOperatorResult &res)
Apply inverse operator with given reduction factor.
Definition: cg_fork.hh:282
X::field_type field_type
The field type of the operator to be inverted.
Definition: cg_fork.hh:19