3#ifndef DUNE_PDELAB_BACKEND_EIGEN_SOLVERS_HH
4#define DUNE_PDELAB_BACKEND_EIGEN_SOLVERS_HH
9#include <dune/pdelab/constraints/common/constraints.hh>
11#include "../solver.hh"
16#include <Eigen/Sparse>
26 template<
class PreconditionerImp>
27 class EigenBackend_BiCGSTAB_Base
28 :
public LinearResultStorage
36 explicit EigenBackend_BiCGSTAB_Base(
unsigned maxiter_=5000)
47 template<
class M,
class V,
class W>
48 void apply(M& A, V& z, W& r,
typename W::field_type reduction)
50 using Backend::Native;
51 using Backend::native;
53 using Mat = Native<M>;
54 ::Eigen::BiCGSTAB<Mat, PreconditionerImp> solver;
55 solver.setMaxIterations(maxiter);
56 solver.setTolerance(reduction);
59 solver.compute(native(A));
60 native(z) = solver.solve(native(r));
61 double elapsed = watch.
elapsed();
63 res.converged = solver.info() == ::Eigen::ComputationInfo::Success;
64 res.iterations = solver.iterations();
65 res.elapsed = elapsed;
66 res.reduction = solver.error();
72 typename Dune::template FieldTraits<typename V::ElementType >::real_type norm(
const V& v)
const
74 return Backend::native(v).norm();
82 class EigenBackend_BiCGSTAB_IILU
83 :
public EigenBackend_BiCGSTAB_Base<::Eigen::IncompleteLUT<double> >
86 explicit EigenBackend_BiCGSTAB_IILU(
unsigned maxiter_=5000)
87 : EigenBackend_BiCGSTAB_Base(maxiter_)
92 class EigenBackend_BiCGSTAB_Diagonal
93 :
public EigenBackend_BiCGSTAB_Base<::Eigen::DiagonalPreconditioner<double> >
96 explicit EigenBackend_BiCGSTAB_Diagonal(
unsigned maxiter_=5000)
97 : EigenBackend_BiCGSTAB_Base(maxiter_)
101 template<
class Preconditioner,
int UpLo >
102 class EigenBackend_CG_Base
103 :
public SequentialNorm,
public LinearResultStorage
111 explicit EigenBackend_CG_Base(
unsigned maxiter_=5000)
122 template<
class M,
class V,
class W>
123 void apply(M& A, V& z, W& r,
typename W::field_type reduction)
125 using Backend::native;
126 using Mat = Backend::Native<M>;
127 ::Eigen::ConjugateGradient<Mat, UpLo, Preconditioner> solver;
128 solver.setMaxIterations(maxiter);
129 solver.setTolerance(reduction);
132 solver.compute(native(A));
133 native(z) = solver.solve(native(r));
134 double elapsed = watch.
elapsed();
137 res.converged = solver.info() == ::Eigen::ComputationInfo::Success;
138 res.iterations = solver.iterations();
139 res.elapsed = elapsed;
140 res.reduction = solver.error();
150 class EigenBackend_CG_IILU_Up
151 :
public EigenBackend_CG_Base<::Eigen::IncompleteLUT<double>, ::Eigen::Upper >
154 explicit EigenBackend_CG_IILU_Up(
unsigned maxiter_=5000)
155 : EigenBackend_CG_Base(maxiter_)
159 class EigenBackend_CG_Diagonal_Up
160 :
public EigenBackend_CG_Base<::Eigen::DiagonalPreconditioner<double>, ::Eigen::Upper >
163 explicit EigenBackend_CG_Diagonal_Up(
unsigned maxiter_=5000)
164 : EigenBackend_CG_Base(maxiter_)
168 class EigenBackend_CG_IILU_Lo
169 :
public EigenBackend_CG_Base<::Eigen::IncompleteLUT<double>, ::Eigen::Lower >
172 explicit EigenBackend_CG_IILU_Lo(
unsigned maxiter_=5000)
173 : EigenBackend_CG_Base(maxiter_)
177 class EigenBackend_CG_Diagonal_Lo
178 :
public EigenBackend_CG_Base<::Eigen::DiagonalPreconditioner<double>, ::Eigen::Lower >
181 explicit EigenBackend_CG_Diagonal_Lo(
unsigned maxiter_=5000)
182 : EigenBackend_CG_Base(maxiter_)
186#if EIGEN_VERSION_AT_LEAST(3,2,2)
187 template<
template<
class,
int,
class>
class Solver,
int UpLo>
189 template<
template<
class,
int>
class Solver,
int UpLo>
191 class EigenBackend_SPD_Base
192 :
public SequentialNorm,
public LinearResultStorage
200 explicit EigenBackend_SPD_Base()
210 template<
class M,
class V,
class W>
211 void apply(M& A, V& z, W& r,
typename W::field_type reduction)
213 using Backend::native;
214 using Mat = Backend::Native<M>;
215#if EIGEN_VERSION_AT_LEAST(3,2,2)
219 Solver<Mat, UpLo, ::Eigen::AMDOrdering<typename Mat::Index> > solver;
221 Solver<Mat, UpLo> solver;
225 solver.compute(native(A));
226 native(z) = solver.solve(native(r));
227 double elapsed = watch.
elapsed();
229 res.converged = solver.info() == ::Eigen::ComputationInfo::Success;
230 res.iterations = solver.iterations();
231 res.elapsed = elapsed;
232 res.reduction = solver.error();
238 class EigenBackend_SimplicialCholesky_Up
239 :
public EigenBackend_SPD_Base<::Eigen::SimplicialCholesky, ::Eigen::Upper >
242 explicit EigenBackend_SimplicialCholesky_Up()
246 class EigenBackend_SimplicialCholesky_Lo
247 :
public EigenBackend_SPD_Base<::Eigen::SimplicialCholesky, ::Eigen::Lower >
250 explicit EigenBackend_SimplicialCholesky_Lo()
302 class EigenBackend_LeastSquares
303 :
public SequentialNorm,
public LinearResultStorage
306 const static unsigned int defaultFlag = ::Eigen::ComputeThinU | ::Eigen::ComputeThinV;
313 explicit EigenBackend_LeastSquares(
unsigned int flags = defaultFlag)
324 template<
class M,
class V,
class W>
325 void apply(M& A, V& z, W& r,
typename W::field_type reduction)
329 using Backend::native;
330 using Mat = Backend::Native<M>;
331 ::Eigen::JacobiSVD<Mat, ::Eigen::ColPivHouseholderQRPreconditioner> solver(A, flags_);
332 native(z) = solver.solve(native(r));
333 double elapsed = watch.
elapsed();
335 res.converged = solver.info() == ::Eigen::ComputationInfo::Success;
336 res.iterations = solver.iterations();
337 res.elapsed = elapsed;
338 res.reduction = solver.error();
A simple stop watch.
Definition: timer.hh:43
void reset() noexcept
Reset timer while keeping the running/stopped state.
Definition: timer.hh:57
double elapsed() const noexcept
Get elapsed user-time from last reset until now/last stop in seconds.
Definition: timer.hh:77
Helpers for dealing with MPI.
Dune namespace.
Definition: alignedallocator.hh:13