14#ifndef MG_MULTIPLICATIVEMULTIGRID_HH
15#define MG_MULTIPLICATIVEMULTIGRID_HH
19#include <boost/timer/timer.hpp>
21#include <dune/istl/preconditioner.hh>
72 template <
class Entry,
class Index,
class Smoother,
class Pro
longation>
95 template <
class MakeSmoother>
97 std::unique_ptr<CoarsePreconditioner>&& coarsePreconditioner_,
int nPre_=3,
int nPost_=3)
98 : mgStack(std::move(mgStack_)), nPre(nPre_), nPost(nPost_), coarsePreconditioner(std::move(coarsePreconditioner_)),
99 linesearch(false), smootherStepSize(1.0)
103 timer.
start(
"smoother construction");
104 for (
int l=1; l<mgStack.levels(); ++l)
105 smoothers.push_back(makeSmoother(mgStack.a(l)));
106 timer.
stop(
"smoother construction");
121 assert(x.two_norm()==0);
123 runMG(x,b,mgStack.levels()-1);
149 assert(nPre>=0 && nPost>=0 && nPre+nPost>0);
160 smootherStepSize = w;
187 return *coarsePreconditioner;
195 return std::make_pair(nPre,nPost);
206 timer.
start(
"coarse grid solver");
207 coarsePreconditioner->pre(x,r);
208 coarsePreconditioner->apply(x,r);
209 coarsePreconditioner->post(x);
210 timer.
stop(
"coarse grid solver");
214 auto& s = smoothers[level-1];
215 auto const& a = mgStack.a(level);
216 double w = smootherStepSize;
221 bool const sRequiresZeroInput = s.requiresInitializedInput();
223 for (
int i=0; i<nPre; ++i)
225 if (sRequiresZeroInput) dx = 0;
226 timer.
start(
"smoother application");
228 timer.
stop(
"smoother application");
230 timer.
start(
"matrix-vector");
233 double dxadx = a.mv(dx,adx);
239 timer.
stop(
"matrix-vector");
246 auto const& p = mgStack.p(level-1);
247 timer.
start(
"restriction");
250 timer.
stop(
"restriction");
252 runMG(cx,cr,level-1);
253 timer.
start(
"prolongation");
255 timer.
stop(
"prolongation");
262 for (
int i=0; i<nPost; ++i)
264 if (sRequiresZeroInput) dx = 0;
265 timer.
start(
"smoother application");
267 timer.
stop(
"smoother application");
269 if (i+1<nPost || linesearch)
271 timer.
start(
"matrix-vector");
274 double dxadx = a.mv(dx,adx);
280 timer.
stop(
"matrix-vector");
290 double omega = (x*r) / (dx*x);
296 MultiGridStack<Prolongation,Entry,Index> mgStack;
297 std::vector<Smoother> smoothers;
299 std::unique_ptr<CoarsePreconditioner> coarsePreconditioner;
301 double smootherStepSize;
319 template <
class Entry,
class Index,
class Pro
longation,
class MakeSmoother,
class CoarsePreconditioner>
321 MakeSmoother
const& makeSmoother,
322 std::unique_ptr<CoarsePreconditioner>&& coarsePreconditioner,
323 int nPre=3,
int nPost=3)
327 std::move(mgStack),makeSmoother,std::move(coarsePreconditioner),nPre,nPost);
340 template <
typename Matrix>
352 template <
typename Space,
typename Scalar=
float>
363 : space(space_), targetCondition(targetCondition_)
366 template <
typename Entry,
typename Index>
370 Index>(space,a,targetCondition);
375 double targetCondition;
382 template <
typename Matrix>
391 template <
class Domain,
class Range,
class SparseIndex>
413 if(endBd != &(bd[0][0]) + bd.dim()) {
414 throw DirectSolverException(
"Copying float to double block-vector failed. End Iterators differ.",__FILE__,__LINE__);
416 directSolver.
apply(xd, bd);
418 if(endX != &(x[0][0]) + x.dim()) {
419 throw DirectSolverException(
"Copying float to double block-vector failed. End Iterators differ.",__FILE__,__LINE__);
435 template <
int domainBlockSize,
int rangeBlockSize,
class Index>
459 template <
class Entry,
class Index,
class Gr
idMan>
465 timer.
start(
"MG stack creation");
467 timer.
stop(
"MG stack creation");
469 timer.
start(
"direct solver creation");
471 timer.
stop(
"direct solver creation");
473 timer.
start(
"MG creation");
475 timer.
stop(
"MG creation");
476 mg.setSmootherStepSize(0.5);
495 template <
class Entry,
class Index,
class Space,
class MakeSmoother>
500 timer.
start(
"create P multigrid stack");
502 timer.
stop(
"create P multigrid stack");
504 timer.
start(
"create MG as coarse solver");
505 auto coarsePreconditioner = makeJacobiMultiGrid(std::move(mgStack.coarseGridMatrix()),space.gridManager(),nPre,nPost,onlyLowerTriangle,directType);
506 coarsePreconditioner.setSmootherStepSize(0.6);
507 timer.
stop(
"create MG as coarse solver");
509 timer.
start(
"create multigrid");
510 auto mg = makeMultiplicativeMultiGrid(std::move(mgStack),makeSmoother,
moveUnique(std::move(coarsePreconditioner)),nPre,nPost);
511 timer.
stop(
"create multigrid");
536 template <
class Entry,
class Index,
class Space,
class CoarseSpace>
542 timer.
start(
"create P multigrid stack");
544 timer.
stop(
"create P multigrid stack");
546 timer.
start(
"create MG as coarse solver");
547 auto coarsePreconditioner = makeJacobiMultiGrid(std::move(mgStack.coarseGridMatrix()),space.gridManager(),nPre,nPost,
false,directType);
548 coarsePreconditioner.setSmootherStepSize(0.6);
549 timer.
stop(
"create MG as coarse solver");
551 timer.
start(
"create multigrid");
553 moveUnique(std::move(coarsePreconditioner)),nPre,nPost);
554 mg.setSmootherStepSize(Space::Grid::dimension==3 ? 0.4 : 0.5);
555 timer.
stop(
"create multigrid");
580 template <
class Entry,
class Index,
class Space>
585 nPre,nPost,onlyLowerTriangle,directType);
586 mg.setSmootherStepSize(Space::Grid::dimension==3 ? 0.4 : 0.5);
602 template <
class Entry,
class Index,
class FineSpace>
606 auto mg = makeMultiplicativePMultiGrid(std::move(A),space,
MakeJacobiSmoother(),nPre,nPost,onlyLowerTriangle,directType);
607 mg.setSmootherStepSize(0.5);
virtual void pre(FloatDomain &, FloatRange &)
static constexpr int rangeBlockSize
DirectPreconditionerFloatWrapper(FloatMatrix const &matA, DirectType directType)
virtual void apply(FloatDomain &x, FloatRange const &b)
static constexpr int domainBlockSize
virtual void post(FloatDomain &)
typename MatrixTraits< DoubleMatrix >::NaturalRange DoubleRange
typename MatrixTraits< DoubleMatrix >::NaturalDomain DoubleDomain
To be raised if a direct solver fails.
virtual void apply(Domain &x, Range &b, Dune::InverseOperatorResult &res)
Solves the system for the given right hand side b.
Functor for creating overlapping Schwarz smoothers.
MakeAdditiveSchwarzSmoother(Space const &space_, double targetCondition_=-1.0)
Constructor.
auto operator()(NumaBCRSMatrix< Entry, Index > const &a) const
Functor for creating Jacobi smoothers.
auto operator()(Matrix const &a) const
Class for multigrid stacks.
A general multiplicative multigrid preconditioner.
CoarsePreconditioner & getCoarsePreconditioner()
Provides access to the coarse grid preconditioner.
void setLinesearch(bool ls)
Enable or disable the line search option.
typename Smoother::domain_type domain_type
typename Smoother::field_type field_type
MultiplicativeMultiGrid(MultiplicativeMultiGrid &&other)=default
MultiplicativeMultiGrid & operator=(MultiplicativeMultiGrid &&other)=default
void setSmoothings(int nPre_, int nPost_)
Sets the number of pre- and post-smoothing iterations to perform.
double getSmootherStepSize() const
virtual field_type applyDp(domain_type &x, range_type const &r)
Computes and returns .
Dune::Preconditioner< domain_type, range_type > CoarsePreconditioner
virtual void apply(domain_type &x, range_type const &r)
Application of preconditioner.
typename Smoother::range_type range_type
MultiplicativeMultiGrid()=default
Default constructor.
void setSmootherStepSize(double w)
Define the smoother step size.
virtual bool requiresInitializedInput() const
Returns true if the target vector x has to be initialized to zero before calling apply or applyDp.
std::pair< int, int > getSmoothings()
Returns a pair of number of pre- and post-smoothing iterations to perform.
MultiplicativeMultiGrid(MultiGridStack< Prolongation, Entry, Index > &&mgStack_, MakeSmoother const &makeSmoother, std::unique_ptr< CoarsePreconditioner > &&coarsePreconditioner_, int nPre_=3, int nPost_=3)
Constructor.
An additive overlapping domain decomposition type preconditioner for higher order finite elements app...
Interface for symmetric preconditioners.
Supports gathering and reporting execution times information for nested program parts.
static Timings & instance()
Returns a reference to a single default instance.
void stop(std::string const &name)
Stops the timing of given section.
struct Times const * start(std::string const &name)
Starts or continues the timing of given section.
DirectType
Available direct solvers for linear equation systems.
@ MUMPS
MUMPS sparse solver.
auto makeBlockJacobiPMultiGrid(NumaBCRSMatrix< Entry, Index > A, Space const &space, NumaBCRSMatrix< Entry, Index > coarseA, CoarseSpace const &coarseSpace, int nPre=3, int nPost=3, DirectType directType=DirectType::MUMPS)
Convenience function creating multiplicative multigrid preconditioner of V-cycle type for higher orde...
auto makeDirectPreconditioner(Matrix &&A, DirectType directType=DirectType::MUMPS)
Creates a direct solver for the given matrix.
auto makeMultiplicativeMultiGrid(MultiGridStack< Prolongation, Entry, Index > &&mgStack, MakeSmoother const &makeSmoother, std::unique_ptr< CoarsePreconditioner > &&coarsePreconditioner, int nPre=3, int nPost=3)
Convenience function creating multiplicative multigrid preconditioner of V-cycle type for P1 elements...
auto makeJacobiMultiGrid(NumaBCRSMatrix< Entry, Index > const &A, GridMan const &gridman, int nPre=3, int nPost=3, bool onlyLowerTriangle=false, DirectType directType=DirectType::MUMPS)
Convenience function creating multiplicative Jacobi multigrid for P1 elements.
auto makeMultiplicativePMultiGrid(NumaBCRSMatrix< Entry, Index > &&A, Space const &space, MakeSmoother const &makeSmoother, int nPre=3, int nPost=3, bool onlyLowerTriangle=false, DirectType directType=DirectType::MUMPS)
Convenience function creating multiplicative multigrid preconditioner of V-cycle type for higher orde...
auto makePMultiGridStack(FineSpace const &space, Matrix &&A, bool onlyLowerTriangle)
convenience routine for creating multigrid stacks based on coarsening by reducing the ansatz order fr...
auto makeBlockJacobiPMultiGrid(NumaBCRSMatrix< Entry, Index > A, Space const &space, int nPre=3, int nPost=3, bool onlyLowerTriangle=false, DirectType directType=DirectType::MUMPS)
Convenience function creating multiplicative multigrid preconditioner of V-cycle type for higher orde...
MultiGridStack< MGProlongation, Entry, Index > makeGeometricMultiGridStack(GridMan const &gridManager, NumaBCRSMatrix< Entry, Index > &&A, size_t minNodes=10000, bool onlyLowerTriangle=false)
convenience routine for creating multigrid stacks based on geometric coarsening for P1 elements
auto makeJacobiPMultiGrid(NumaBCRSMatrix< Entry, Index > A, FineSpace const &space, int nPre=3, int nPost=3, bool onlyLowerTriangle=false, DirectType directType=DirectType::MUMPS)
Convenience function creating multiplicative multigrid preconditioner of V-cycle type with Jacobi smo...
auto moveUnique(A &&a)
Creates a dynamically allocated object from an r-value reference.
A duplicate(A const &a)
Creates a copy of a given object.
OutIter vectorToSequence(double x, OutIter iter)
Convenience typedefs and creation functions for common function spaces.
void NaturalDomain
The natural domain type.
void NaturalRange
The natural range type.