5#ifndef DUNE_ISTL_FASTAMG_HH
6#define DUNE_ISTL_FASTAMG_HH
10#include <dune/common/simd/simd.hh>
59 template<
class M,
class X,
class PI=SequentialInformation,
class A=std::allocator<X> >
132 criterion, parms, symmetric, pinfo)
193 void createHierarchies(C& criterion,
208 typename OperatorHierarchy::ParallelMatrixHierarchy::ConstIterator
matrix;
216 typename OperatorHierarchy::RedistributeInfoList::const_iterator
redist;
220 typename OperatorHierarchy::AggregatesMapList::const_iterator
aggregates;
240 void mgc(LevelContext& levelContext,
Domain& x,
const Range& b);
248 void presmooth(LevelContext& levelContext,
Domain& x,
const Range& b);
256 void postsmooth(LevelContext& levelContext,
Domain& x,
const Range& b);
264 void moveToFineLevel(LevelContext& levelContext,
bool processedFineLevel,
271 bool moveToCoarseLevel(LevelContext& levelContext);
277 void initIteratorsWithFineLevel(LevelContext& levelContext);
301 bool buildHierarchy_;
303 bool coarsesolverconverged;
311 template<
class M,
class X,
class PI,
class A>
313 : matrices_(amg.matrices_), solver_(amg.solver_),
314 rhs_(), lhs_(), residual_(), scalarProduct_(amg.scalarProduct_),
315 gamma_(amg.gamma_), preSteps_(amg.preSteps_), postSteps_(amg.postSteps_),
316 symmetric(amg.symmetric), coarsesolverconverged(amg.coarsesolverconverged),
317 coarseSmoother_(amg.coarseSmoother_), verbosity_(amg.verbosity_)
320 template<
class M,
class X,
class PI,
class A>
324 rhs_(), lhs_(), residual_(), scalarProduct_(),
325 gamma_(parms.getGamma()), preSteps_(parms.getNoPreSmoothSteps()),
326 postSteps_(parms.getNoPostSmoothSteps()), buildHierarchy_(false),
327 symmetric(symmetric_), coarsesolverconverged(true),
328 coarseSmoother_(), verbosity_(parms.debugLevel())
330 if(preSteps_>1||postSteps_>1)
333 preSteps_=postSteps_=0;
335 assert(matrices_->isBuilt());
337 "Currently only sequential runs are supported");
339 template<
class M,
class X,
class PI,
class A>
346 : solver_(), rhs_(), lhs_(), residual_(), scalarProduct_(), gamma_(parms.getGamma()),
347 preSteps_(parms.getNoPreSmoothSteps()), postSteps_(parms.getNoPostSmoothSteps()),
348 buildHierarchy_(true),
349 symmetric(symmetric_), coarsesolverconverged(true),
350 coarseSmoother_(), verbosity_(criterion.debugLevel())
352 if(preSteps_>1||postSteps_>1)
355 preSteps_=postSteps_=1;
358 "Currently only sequential runs are supported");
362 createHierarchies(criterion, std::move(fineOperator), pinfo);
365 template<
class M,
class X,
class PI,
class A>
372 matrices_ = std::make_shared<OperatorHierarchy>(
373 std::const_pointer_cast<Operator>(std::move(fineOperator)),
376 matrices_->template build<NegateSet<typename PI::OwnerSet> >(criterion);
378 if(verbosity_>0 && matrices_->parallelInformation().finest()->communicator().rank()==0)
381 if(buildHierarchy_ && matrices_->levels()==matrices_->maxlevels()) {
388 cargs.setArgs(sargs);
389 if(matrices_->redistributeInformation().back().isSetup()) {
391 cargs.setMatrix(matrices_->matrices().coarsest().getRedistributed().getmat());
392 cargs.setComm(matrices_->parallelInformation().coarsest().getRedistributed());
394 cargs.setMatrix(matrices_->matrices().coarsest()->getmat());
395 cargs.setComm(*matrices_->parallelInformation().coarsest());
399 scalarProduct_ = createScalarProduct<X>(cargs.getComm(),category());
401#if HAVE_SUPERLU|| HAVE_SUITESPARSE_UMFPACK
402#if HAVE_SUITESPARSE_UMFPACK
403#define DIRECTSOLVER UMFPack
405#define DIRECTSOLVER SuperLU
409 || matrices_->parallelInformation().coarsest()->communicator().size()==1
410 || (matrices_->parallelInformation().coarsest().isRedistributed()
411 && matrices_->parallelInformation().coarsest().getRedistributed().communicator().size()==1
412 && matrices_->parallelInformation().coarsest().getRedistributed().communicator().size()>0)) {
413 if(verbosity_>0 && matrices_->parallelInformation().coarsest()->communicator().rank()==0)
415 if(matrices_->parallelInformation().coarsest().isRedistributed())
417 if(matrices_->matrices().coarsest().getRedistributed().getmat().N()>0)
419 solver_.reset(
new DIRECTSOLVER<typename M::matrix_type>(matrices_->matrices().coarsest().getRedistributed().getmat(),
false,
false));
423 solver_.reset(
new DIRECTSOLVER<typename M::matrix_type>(matrices_->matrices().coarsest()->getmat(),
false,
false));
428 if(matrices_->parallelInformation().coarsest().isRedistributed())
430 if(matrices_->matrices().coarsest().getRedistributed().getmat().N()>0)
432 solver_.reset(
new BiCGSTABSolver<X>(
const_cast<M&
>(matrices_->matrices().coarsest().getRedistributed()),
434 *coarseSmoother_, 1E-2, 1000, 0));
438 solver_.reset(
new BiCGSTABSolver<X>(
const_cast<M&
>(*matrices_->matrices().coarsest()),
440 *coarseSmoother_, 1E-2, 1000, 0));
444 if(verbosity_>0 && matrices_->parallelInformation().finest()->communicator().rank()==0)
449 template<
class M,
class X,
class PI,
class A>
457 typedef typename M::matrix_type
Matrix;
464 const Matrix&
mat=matrices_->matrices().finest()->getmat();
465 for(RowIter row=
mat.begin(); row!=
mat.end(); ++row) {
466 bool isDirichlet =
true;
467 bool hasDiagonal =
false;
469 for(ColIter
col=row->begin();
col!=row->end(); ++
col) {
470 if(row.index()==
col.index()) {
472 hasDiagonal = (*
col != zero);
478 if(isDirichlet && hasDiagonal)
481 x[row.index()] = b[row.index()]/(*diag);
483 diag->solve(x[row.index()], b[row.index()]);
490 matrices_->parallelInformation().coarsest()->copyOwnerToAll(x,x);
491 rhs_ = std::make_shared<Hierarchy<Range,A>>(std::make_shared<Range>(b));
492 lhs_ = std::make_shared<Hierarchy<Domain,A>>(std::make_shared<Domain>(x));
493 residual_ = std::make_shared<Hierarchy<Domain,A>>(std::make_shared<Domain>(x));
494 matrices_->coarsenVector(*rhs_);
495 matrices_->coarsenVector(*lhs_);
496 matrices_->coarsenVector(*residual_);
503 template<
class M,
class X,
class PI,
class A>
506 return matrices_->levels();
508 template<
class M,
class X,
class PI,
class A>
511 return matrices_->maxlevels();
515 template<
class M,
class X,
class PI,
class A>
518 LevelContext levelContext;
520 initIteratorsWithFineLevel(levelContext);
525 if(matrices_->maxlevels()==1){
528 mgc(levelContext, v, b);
530 mgc(levelContext, v, d);
531 if(postSteps_==0||matrices_->maxlevels()==1)
532 levelContext.pinfo->copyOwnerToAll(v, v);
535 template<
class M,
class X,
class PI,
class A>
538 levelContext.matrix = matrices_->matrices().finest();
539 levelContext.pinfo = matrices_->parallelInformation().finest();
540 levelContext.redist =
541 matrices_->redistributeInformation().begin();
542 levelContext.aggregates = matrices_->aggregatesMaps().begin();
543 levelContext.lhs = lhs_->finest();
544 levelContext.residual = residual_->finest();
545 levelContext.rhs = rhs_->finest();
546 levelContext.level=0;
549 template<
class M,
class X,
class PI,
class A>
550 bool FastAMG<M,X,PI,A>
551 ::moveToCoarseLevel(LevelContext& levelContext)
553 bool processNextLevel=
true;
555 if(levelContext.redist->isSetup()) {
557 levelContext.redist->redistribute(
static_cast<const Range&
>(*levelContext.residual),
558 levelContext.residual.getRedistributed());
559 processNextLevel = levelContext.residual.getRedistributed().size()>0;
560 if(processNextLevel) {
562 ++levelContext.pinfo;
563 Transfer<typename OperatorHierarchy::AggregatesMap::AggregateDescriptor,Range,ParallelInformation>
564 ::restrictVector(*(*levelContext.aggregates), *levelContext.rhs,
565 static_cast<const Range&
>(levelContext.residual.getRedistributed()),
566 *levelContext.pinfo);
571 ++levelContext.pinfo;
572 Transfer<typename OperatorHierarchy::AggregatesMap::AggregateDescriptor,Range,ParallelInformation>
573 ::restrictVector(*(*levelContext.aggregates), *levelContext.rhs,
574 static_cast<const Range&
>(*levelContext.residual), *levelContext.pinfo);
577 if(processNextLevel) {
579 ++levelContext.residual;
581 ++levelContext.matrix;
582 ++levelContext.level;
583 ++levelContext.redist;
585 if(levelContext.matrix != matrices_->matrices().coarsest() || matrices_->levels()<matrices_->maxlevels()) {
587 ++levelContext.aggregates;
591 *levelContext.residual=0;
593 return processNextLevel;
596 template<
class M,
class X,
class PI,
class A>
597 void FastAMG<M,X,PI,A>
598 ::moveToFineLevel(LevelContext& levelContext,
bool processNextLevel, Domain& x)
600 if(processNextLevel) {
601 if(levelContext.matrix != matrices_->matrices().coarsest() || matrices_->levels()<matrices_->maxlevels()) {
603 --levelContext.aggregates;
605 --levelContext.redist;
606 --levelContext.level;
608 --levelContext.matrix;
609 --levelContext.residual;
613 typename Hierarchy<Domain,A>::Iterator coarseLhs = levelContext.lhs--;
614 if(levelContext.redist->isSetup()) {
617 Transfer<typename OperatorHierarchy::AggregatesMap::AggregateDescriptor,Range,ParallelInformation>
618 ::prolongateVector(*(*levelContext.aggregates), *coarseLhs, x,
619 levelContext.lhs.getRedistributed(),
620 matrices_->getProlongationDampingFactor(),
621 *levelContext.pinfo, *levelContext.redist);
623 Transfer<typename OperatorHierarchy::AggregatesMap::AggregateDescriptor,Range,ParallelInformation>
624 ::prolongateVector(*(*levelContext.aggregates), *coarseLhs, x,
625 matrices_->getProlongationDampingFactor(), *levelContext.pinfo);
631 if(processNextLevel) {
638 template<
class M,
class X,
class PI,
class A>
639 void FastAMG<M,X,PI,A>
640 ::presmooth(LevelContext& levelContext, Domain& x,
const Range& b)
642 constexpr auto bl = blockLevel<typename M::matrix_type>();
645 *levelContext.residual,
649 template<
class M,
class X,
class PI,
class A>
650 void FastAMG<M,X,PI,A>
651 ::postsmooth(LevelContext& levelContext, Domain& x,
const Range& b)
653 constexpr auto bl = blockLevel<typename M::matrix_type>();
654 GaussSeidelPostsmoothDefect<bl>
655 ::apply(levelContext.matrix->getmat(), x, *levelContext.residual, b);
659 template<
class M,
class X,
class PI,
class A>
665 template<
class M,
class X,
class PI,
class A>
668 if(levelContext.matrix == matrices_->matrices().coarsest() && levels()==maxlevels()) {
672 if(levelContext.redist->isSetup()) {
673 levelContext.redist->redistribute(b, levelContext.rhs.getRedistributed());
674 if(levelContext.rhs.getRedistributed().size()>0) {
676 levelContext.pinfo.getRedistributed().copyOwnerToAll(levelContext.rhs.getRedistributed(),
677 levelContext.rhs.getRedistributed());
678 solver_->apply(levelContext.lhs.getRedistributed(), levelContext.rhs.getRedistributed(), res);
680 levelContext.redist->redistributeBackward(v, levelContext.lhs.getRedistributed());
681 levelContext.pinfo->copyOwnerToAll(v, v);
683 levelContext.pinfo->copyOwnerToAll(b, b);
684 solver_->apply(v,
const_cast<Range&
>(b), res);
690 coarsesolverconverged =
false;
696#ifndef DUNE_AMG_NO_COARSEGRIDCORRECTION
697 bool processNextLevel = moveToCoarseLevel(levelContext);
699 if(processNextLevel) {
702 mgc(levelContext, *levelContext.lhs, *levelContext.rhs);
705 moveToFineLevel(levelContext, processNextLevel, v);
710 if(levelContext.matrix == matrices_->matrices().finest()) {
711 coarsesolverconverged = matrices_->parallelInformation().finest()->communicator().prod(coarsesolverconverged);
712 if(!coarsesolverconverged)
713 DUNE_THROW(MathError,
"Coarse solver did not converge");
722 template<
class M,
class X,
class PI,
class A>
730 template<
class M,
class X,
class PI,
class A>
734 matrices_->getCoarsestAggregatesOnFinest(cont);
Prolongation and restriction for amg.
Classes for the generic construction and application of the smoothers.
Provides a classes representing the hierarchies in AMG.
Some generic functions for pretty printing vectors and matrices.
Define base class for scalar product and norm.
Classes for using SuperLU with ISTL matrices.
Classes for using UMFPack with ISTL matrices.
Define general preconditioner interface.
Templates characterizing the type of a solver.
Implementations of the inverse operator interface.
Col col
Definition matrixmatrix.hh:351
Matrix & mat
Definition matrixmatrix.hh:347
static std::shared_ptr< T > construct(Arguments &)
Construct an object with the specified arguments.
Definition construction.hh:52
void presmooth(LevelContext &levelContext, size_t steps)
Apply pre smoothing on the current level.
Definition smoother.hh:407
const void * Arguments
A type holding all the arguments needed to call the constructor.
Definition construction.hh:44
void postsmooth(LevelContext &levelContext, size_t steps)
Apply post smoothing on the current level.
Definition smoother.hh:429
int iterations
The number of iterations to perform.
Definition smoother.hh:48
OperatorHierarchy::ParallelMatrixHierarchy::ConstIterator matrix
The iterator over the matrices.
Definition fastamg.hh:208
void getCoarsestAggregateNumbers(std::vector< std::size_t, A1 > &cont)
Get the aggregate number of each unknown on the coarsest level.
Definition fastamg.hh:732
ParallelInformationHierarchy::Iterator pinfo
The iterator over the parallel information.
Definition fastamg.hh:212
void recalculateHierarchy()
Recalculate the matrix hierarchy.
Definition fastamg.hh:174
void post(Domain &x)
Clean up.
Definition fastamg.hh:723
std::size_t maxlevels()
Definition fastamg.hh:509
X Domain
The domain type.
Definition fastamg.hh:78
Hierarchy< Domain, A >::Iterator residual
The iterator over the residuals.
Definition fastamg.hh:228
virtual SolverCategory::Category category() const
Category of the preconditioner (see SolverCategory::Category)
Definition fastamg.hh:147
MatrixHierarchy< M, ParallelInformation, A > OperatorHierarchy
The operator hierarchy type.
Definition fastamg.hh:73
OperatorHierarchy::RedistributeInfoList::const_iterator redist
The iterator over the redistribution information.
Definition fastamg.hh:216
X Range
The range type.
Definition fastamg.hh:80
PI ParallelInformation
The type of the parallel information. Either OwnerOverlapCommunication or another type describing the...
Definition fastamg.hh:71
M Operator
The matrix operator type.
Definition fastamg.hh:64
std::size_t levels()
Definition fastamg.hh:504
FastAMG(const Operator &fineOperator, const C &criterion, const Parameters &parms=Parameters(), bool symmetric=true, const ParallelInformation &pinfo=ParallelInformation())
Construct an AMG with an inexact coarse solver based on the smoother.
Definition fastamg.hh:126
InverseOperator< X, X > CoarseSolver
the type of the coarse solver.
Definition fastamg.hh:82
bool usesDirectCoarseLevelSolver() const
Check whether the coarse solver used is a direct solver.
Definition fastamg.hh:660
Hierarchy< Domain, A >::Iterator lhs
The iterator over the left hand side.
Definition fastamg.hh:224
Hierarchy< Range, A >::Iterator rhs
The iterator over the right hand sided.
Definition fastamg.hh:232
std::size_t level
The level index.
Definition fastamg.hh:236
void apply(Domain &v, const Range &d)
Apply one step of the preconditioner to the system A(v)=d.
Definition fastamg.hh:516
OperatorHierarchy::ParallelInformationHierarchy ParallelInformationHierarchy
The parallal data distribution hierarchy type.
Definition fastamg.hh:75
void pre(Domain &x, Range &b)
Prepare the preconditioner.
Definition fastamg.hh:450
FastAMG(OperatorHierarchy &matrices, CoarseSolver &coarseSolver, const Parameters &parms, bool symmetric=true)
Construct a new amg with a specific coarse solver.
Definition fastamg.hh:321
OperatorHierarchy::AggregatesMapList::const_iterator aggregates
The iterator over the aggregates maps.
Definition fastamg.hh:220
static constexpr size_type M()
#define DUNE_THROW(E,...)
bool allTrue(const Mask &mask)
std::shared_ptr< T > stackobject_to_shared_ptr(T &t)
ConstIterator class for sequential access.
Definition matrix.hh:404
A generic dynamic dense matrix.
Definition matrix.hh:561
typename Imp::BlockTraits< T >::field_type field_type
Export the type representing the underlying field.
Definition matrix.hh:565
row_type::const_iterator ConstColIterator
Const iterator for the entries of each row.
Definition matrix.hh:589
T block_type
Export the type representing the components.
Definition matrix.hh:568
double elapsed() const noexcept
A fast (sequential) algebraic multigrid based on agglomeration that saves memory bandwidth.
Definition fastamg.hh:61
static void apply(const M &A, X &x, Y &d, const Y &b)
Definition fastamgsmoother.hh:20
LevelIterator< Hierarchy< ParallelInformation, Allocator >, ParallelInformation > Iterator
Type of the mutable iterator.
Definition hierarchy.hh:220
Iterator over the levels in the hierarchy.
Definition hierarchy.hh:120
The hierarchies build by the coarsening process.
Definition matrixhierarchy.hh:61
All parameters for AMG.
Definition parameters.hh:416
The default class for the smoother arguments.
Definition smoother.hh:39
Base class for matrix free definition of preconditioners.
Definition preconditioner.hh:33
Sequential SSOR preconditioner.
Definition preconditioners.hh:142
Base class for scalar product and norm computation.
Definition scalarproducts.hh:52
Statistics about the application of an inverse operator.
Definition solver.hh:50
bool converged
True if convergence criterion has been met.
Definition solver.hh:75
Abstract base class for all solvers.
Definition solver.hh:101
Category
Definition solvercategory.hh:23
@ sequential
Category for sequential solvers.
Definition solvercategory.hh:25
Definition solvertype.hh:16