dune-istl 2.12-git
Loading...
Searching...
No Matches
fastamg.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root
2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
4// vi: set et ts=4 sw=2 sts=2:
5#ifndef DUNE_ISTL_FASTAMG_HH
6#define DUNE_ISTL_FASTAMG_HH
7
8#include <memory>
10#include <dune/common/simd/simd.hh>
15#include <dune/istl/solvers.hh>
17#include <dune/istl/superlu.hh>
18#include <dune/istl/umfpack.hh>
20#include <dune/istl/io.hh>
22
23#include "fastamgsmoother.hh"
24
33namespace Dune
34{
35 namespace Amg
36 {
59 template<class M, class X, class PI=SequentialInformation, class A=std::allocator<X> >
60 class FastAMG : public Preconditioner<X,X>
61 {
62 public:
64 typedef M Operator;
76
78 typedef X Domain;
80 typedef X Range;
83
91 FastAMG(OperatorHierarchy& matrices, CoarseSolver& coarseSolver,
92 const Parameters& parms,
93 bool symmetric=true);
94
106 template<class C>
108 const C& criterion,
109 const Parameters& parms=Parameters(),
110 bool symmetric=true,
112
125 template<class C>
126 FastAMG(const Operator& fineOperator,
127 const C& criterion,
128 const Parameters& parms=Parameters(),
129 bool symmetric=true,
131 : FastAMG(stackobject_to_shared_ptr(fineOperator),
132 criterion, parms, symmetric, pinfo)
133 {}
134
138 FastAMG(const FastAMG& amg);
139
141 void pre(Domain& x, Range& b);
142
144 void apply(Domain& v, const Range& d);
145
148 {
150 }
151
153 void post(Domain& x);
154
159 template<class A1>
161
163
165
175 {
176 matrices_->recalculateGalerkin(NegateSet<typename PI::OwnerSet>());
177 }
178
183 bool usesDirectCoarseLevelSolver() const;
184
185 private:
192 template<class C>
193 void createHierarchies(C& criterion,
195 const PI& pinfo);
196
203 struct LevelContext
204 {
208 typename OperatorHierarchy::ParallelMatrixHierarchy::ConstIterator matrix;
216 typename OperatorHierarchy::RedistributeInfoList::const_iterator redist;
220 typename OperatorHierarchy::AggregatesMapList::const_iterator aggregates;
237 };
238
240 void mgc(LevelContext& levelContext, Domain& x, const Range& b);
241
248 void presmooth(LevelContext& levelContext, Domain& x, const Range& b);
249
256 void postsmooth(LevelContext& levelContext, Domain& x, const Range& b);
257
264 void moveToFineLevel(LevelContext& levelContext, bool processedFineLevel,
265 Domain& fineX);
266
271 bool moveToCoarseLevel(LevelContext& levelContext);
272
277 void initIteratorsWithFineLevel(LevelContext& levelContext);
278
289
293 std::shared_ptr<ScalarProduct> scalarProduct_;
295 std::size_t gamma_;
297 std::size_t preSteps_;
299 std::size_t postSteps_;
300 std::size_t level;
301 bool buildHierarchy_;
302 bool symmetric;
303 bool coarsesolverconverged;
306 SmootherPointer coarseSmoother_;
308 std::size_t verbosity_;
309 };
310
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_)
318 {}
319
320 template<class M, class X, class PI, class A>
322 const Parameters& parms, bool symmetric_)
323 : matrices_(stackobject_to_shared_ptr(matrices)), solver_(&coarseSolver),
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())
329 {
330 if(preSteps_>1||postSteps_>1)
331 {
332 std::cerr<<"WARNING only one step of smoothing is supported!"<<std::endl;
333 preSteps_=postSteps_=0;
334 }
335 assert(matrices_->isBuilt());
337 "Currently only sequential runs are supported");
338 }
339 template<class M, class X, class PI, class A>
340 template<class C>
342 const C& criterion,
343 const Parameters& parms,
344 bool symmetric_,
345 const PI& pinfo)
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())
351 {
352 if(preSteps_>1||postSteps_>1)
353 {
354 std::cerr<<"WARNING only one step of smoothing is supported!"<<std::endl;
355 preSteps_=postSteps_=1;
356 }
358 "Currently only sequential runs are supported");
359 // TODO: reestablish compile time checks.
360 //static_assert(static_cast<int>(PI::category)==static_cast<int>(S::category),
361 // "Matrix and Solver must match in terms of category!");
362 createHierarchies(criterion, std::move(fineOperator), pinfo);
363 }
364
365 template<class M, class X, class PI, class A>
366 template<class C>
367 void FastAMG<M,X,PI,A>::createHierarchies(C& criterion,
369 const PI& pinfo)
370 {
371 Timer watch;
372 matrices_ = std::make_shared<OperatorHierarchy>(
373 std::const_pointer_cast<Operator>(std::move(fineOperator)),
374 stackobject_to_shared_ptr(const_cast<PI&>(pinfo)));
375
376 matrices_->template build<NegateSet<typename PI::OwnerSet> >(criterion);
377
378 if(verbosity_>0 && matrices_->parallelInformation().finest()->communicator().rank()==0)
379 std::cout<<"Building Hierarchy of "<<matrices_->maxlevels()<<" levels took "<<watch.elapsed()<<" seconds."<<std::endl;
380
381 if(buildHierarchy_ && matrices_->levels()==matrices_->maxlevels()) {
382 // We have the carsest level. Create the coarse Solver
383 typedef typename SmootherTraits<Smoother>::Arguments SmootherArgs;
384 SmootherArgs sargs;
385 sargs.iterations = 1;
386
388 cargs.setArgs(sargs);
389 if(matrices_->redistributeInformation().back().isSetup()) {
390 // Solve on the redistributed partitioning
391 cargs.setMatrix(matrices_->matrices().coarsest().getRedistributed().getmat());
392 cargs.setComm(matrices_->parallelInformation().coarsest().getRedistributed());
393 }else{
394 cargs.setMatrix(matrices_->matrices().coarsest()->getmat());
395 cargs.setComm(*matrices_->parallelInformation().coarsest());
396 }
397
398 coarseSmoother_ = ConstructionTraits<Smoother>::construct(cargs);
399 scalarProduct_ = createScalarProduct<X>(cargs.getComm(),category());
400
401#if HAVE_SUPERLU|| HAVE_SUITESPARSE_UMFPACK
402#if HAVE_SUITESPARSE_UMFPACK
403#define DIRECTSOLVER UMFPack
404#else
405#define DIRECTSOLVER SuperLU
406#endif
407 // Use superlu if we are purely sequential or with only one processor on the coarsest level.
409 || matrices_->parallelInformation().coarsest()->communicator().size()==1 //parallel mode and only one processor
410 || (matrices_->parallelInformation().coarsest().isRedistributed()
411 && matrices_->parallelInformation().coarsest().getRedistributed().communicator().size()==1
412 && matrices_->parallelInformation().coarsest().getRedistributed().communicator().size()>0)) { // redistribute and 1 proc
413 if(verbosity_>0 && matrices_->parallelInformation().coarsest()->communicator().rank()==0)
414 std::cout<<"Using superlu"<<std::endl;
415 if(matrices_->parallelInformation().coarsest().isRedistributed())
416 {
417 if(matrices_->matrices().coarsest().getRedistributed().getmat().N()>0)
418 // We are still participating on this level
419 solver_.reset(new DIRECTSOLVER<typename M::matrix_type>(matrices_->matrices().coarsest().getRedistributed().getmat(), false, false));
420 else
421 solver_.reset();
422 }else
423 solver_.reset(new DIRECTSOLVER<typename M::matrix_type>(matrices_->matrices().coarsest()->getmat(), false, false));
424 }else
425#undef DIRECTSOLVER
426#endif // HAVE_SUPERLU|| HAVE_SUITESPARSE_UMFPACK
427 {
428 if(matrices_->parallelInformation().coarsest().isRedistributed())
429 {
430 if(matrices_->matrices().coarsest().getRedistributed().getmat().N()>0)
431 // We are still participating on this level
432 solver_.reset(new BiCGSTABSolver<X>(const_cast<M&>(matrices_->matrices().coarsest().getRedistributed()),
433 *scalarProduct_,
434 *coarseSmoother_, 1E-2, 1000, 0));
435 else
436 solver_.reset();
437 }else
438 solver_.reset(new BiCGSTABSolver<X>(const_cast<M&>(*matrices_->matrices().coarsest()),
439 *scalarProduct_,
440 *coarseSmoother_, 1E-2, 1000, 0));
441 }
442 }
443
444 if(verbosity_>0 && matrices_->parallelInformation().finest()->communicator().rank()==0)
445 std::cout<<"Building Hierarchy of "<<matrices_->maxlevels()<<" levels took "<<watch.elapsed()<<" seconds."<<std::endl;
446 }
447
448
449 template<class M, class X, class PI, class A>
451 {
452 Timer watch, watch1;
453 // Detect Matrix rows where all offdiagonal entries are
454 // zero and set x such that A_dd*x_d=b_d
455 // Thus users can be more careless when setting up their linear
456 // systems.
457 typedef typename M::matrix_type Matrix;
458 typedef typename Matrix::ConstRowIterator RowIter;
459 typedef typename Matrix::ConstColIterator ColIter;
460 typedef typename Matrix::block_type Block;
461 Block zero;
462 zero=typename Matrix::field_type();
463
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;
468 ColIter diag;
469 for(ColIter col=row->begin(); col!=row->end(); ++col) {
470 if(row.index()==col.index()) {
471 diag = col;
472 hasDiagonal = (*col != zero);
473 }else{
474 if(*col!=zero)
475 isDirichlet = false;
476 }
477 }
478 if(isDirichlet && hasDiagonal)
479 {
480 if constexpr (Dune::IsNumber<Block>::value)
481 x[row.index()] = b[row.index()]/(*diag);
482 else
483 diag->solve(x[row.index()], b[row.index()]);
484 }
485 }
486 if (verbosity_>0)
487 std::cout<<" Preprocessing Dirichlet took "<<watch1.elapsed()<<std::endl;
488 watch1.reset();
489 // No smoother to make x consistent! Do it by hand
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_);
497
498 // The preconditioner might change x and b. So we have to
499 // copy the changes to the original vectors.
500 x = *lhs_->finest();
501 b = *rhs_->finest();
502 }
503 template<class M, class X, class PI, class A>
505 {
506 return matrices_->levels();
507 }
508 template<class M, class X, class PI, class A>
510 {
511 return matrices_->maxlevels();
512 }
513
515 template<class M, class X, class PI, class A>
517 {
518 LevelContext levelContext;
519 // Init all iterators for the current level
520 initIteratorsWithFineLevel(levelContext);
521
522 assert(Dune::Simd::allTrue(v.two_norm()==0));
523
524 level=0;
525 if(matrices_->maxlevels()==1){
526 // The coarse solver might modify the d!
527 Range b(d);
528 mgc(levelContext, v, b);
529 }else
530 mgc(levelContext, v, d);
531 if(postSteps_==0||matrices_->maxlevels()==1)
532 levelContext.pinfo->copyOwnerToAll(v, v);
533 }
534
535 template<class M, class X, class PI, class A>
536 void FastAMG<M,X,PI,A>::initIteratorsWithFineLevel(LevelContext& levelContext)
537 {
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;
547 }
548
549 template<class M, class X, class PI, class A>
550 bool FastAMG<M,X,PI,A>
551 ::moveToCoarseLevel(LevelContext& levelContext)
552 {
553 bool processNextLevel=true;
554
555 if(levelContext.redist->isSetup()) {
556 throw "bla";
557 levelContext.redist->redistribute(static_cast<const Range&>(*levelContext.residual),
558 levelContext.residual.getRedistributed());
559 processNextLevel = levelContext.residual.getRedistributed().size()>0;
560 if(processNextLevel) {
561 //restrict defect to coarse level right hand side.
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);
567 }
568 }else{
569 //restrict defect to coarse level right hand side.
570 ++levelContext.rhs;
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);
575 }
576
577 if(processNextLevel) {
578 // prepare coarse system
579 ++levelContext.residual;
580 ++levelContext.lhs;
581 ++levelContext.matrix;
582 ++levelContext.level;
583 ++levelContext.redist;
584
585 if(levelContext.matrix != matrices_->matrices().coarsest() || matrices_->levels()<matrices_->maxlevels()) {
586 // next level is not the globally coarsest one
587 ++levelContext.aggregates;
588 }
589 // prepare the lhs on the next level
590 *levelContext.lhs=0;
591 *levelContext.residual=0;
592 }
593 return processNextLevel;
594 }
595
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)
599 {
600 if(processNextLevel) {
601 if(levelContext.matrix != matrices_->matrices().coarsest() || matrices_->levels()<matrices_->maxlevels()) {
602 // previous level is not the globally coarsest one
603 --levelContext.aggregates;
604 }
605 --levelContext.redist;
606 --levelContext.level;
607 //prolongate and add the correction (update is in coarse left hand side)
608 --levelContext.matrix;
609 --levelContext.residual;
610
611 }
612
613 typename Hierarchy<Domain,A>::Iterator coarseLhs = levelContext.lhs--;
614 if(levelContext.redist->isSetup()) {
615
616 // Need to redistribute during prolongate
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);
622 }else{
623 Transfer<typename OperatorHierarchy::AggregatesMap::AggregateDescriptor,Range,ParallelInformation>
624 ::prolongateVector(*(*levelContext.aggregates), *coarseLhs, x,
625 matrices_->getProlongationDampingFactor(), *levelContext.pinfo);
626
627 // printvector(std::cout, *lhs, "prolongated coarse grid correction", "lhs", 10, 10, 10);
628 }
629
630
631 if(processNextLevel) {
632 --levelContext.rhs;
633 }
634
635 }
636
637
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)
641 {
642 constexpr auto bl = blockLevel<typename M::matrix_type>();
643 GaussSeidelPresmoothDefect<bl>::apply(levelContext.matrix->getmat(),
644 x,
645 *levelContext.residual,
646 b);
647 }
648
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)
652 {
653 constexpr auto bl = blockLevel<typename M::matrix_type>();
654 GaussSeidelPostsmoothDefect<bl>
655 ::apply(levelContext.matrix->getmat(), x, *levelContext.residual, b);
656 }
657
658
659 template<class M, class X, class PI, class A>
664
665 template<class M, class X, class PI, class A>
666 void FastAMG<M,X,PI,A>::mgc(LevelContext& levelContext, Domain& v, const Range& b){
667
668 if(levelContext.matrix == matrices_->matrices().coarsest() && levels()==maxlevels()) {
669 // Solve directly
671 res.converged=true; // If we do not compute this flag will not get updated
672 if(levelContext.redist->isSetup()) {
673 levelContext.redist->redistribute(b, levelContext.rhs.getRedistributed());
674 if(levelContext.rhs.getRedistributed().size()>0) {
675 // We are still participating in the computation
676 levelContext.pinfo.getRedistributed().copyOwnerToAll(levelContext.rhs.getRedistributed(),
677 levelContext.rhs.getRedistributed());
678 solver_->apply(levelContext.lhs.getRedistributed(), levelContext.rhs.getRedistributed(), res);
679 }
680 levelContext.redist->redistributeBackward(v, levelContext.lhs.getRedistributed());
681 levelContext.pinfo->copyOwnerToAll(v, v);
682 }else{
683 levelContext.pinfo->copyOwnerToAll(b, b);
684 solver_->apply(v, const_cast<Range&>(b), res);
685 }
686
687 // printvector(std::cout, *lhs, "coarse level update", "u", 10, 10, 10);
688 // printvector(std::cout, *rhs, "coarse level rhs", "rhs", 10, 10, 10);
689 if (!res.converged)
690 coarsesolverconverged = false;
691 }else{
692 // presmoothing
693 presmooth(levelContext, v, b);
694 // printvector(std::cout, *lhs, "update", "u", 10, 10, 10);
695 // printvector(std::cout, *residual, "post presmooth residual", "r", 10);
696#ifndef DUNE_AMG_NO_COARSEGRIDCORRECTION
697 bool processNextLevel = moveToCoarseLevel(levelContext);
698
699 if(processNextLevel) {
700 // next level
701 for(std::size_t i=0; i<gamma_; i++)
702 mgc(levelContext, *levelContext.lhs, *levelContext.rhs);
703 }
704
705 moveToFineLevel(levelContext, processNextLevel, v);
706#else
707 *lhs=0;
708#endif
709
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");
714 }
715
716 postsmooth(levelContext, v, b);
717 }
718 }
719
720
722 template<class M, class X, class PI, class A>
723 void FastAMG<M,X,PI,A>::post([[maybe_unused]] Domain& x)
724 {
725 lhs_=nullptr;
726 rhs_=nullptr;
727 residual_=nullptr;
728 }
729
730 template<class M, class X, class PI, class A>
731 template<class A1>
733 {
734 matrices_->getCoarsestAggregatesOnFinest(cont);
735 }
736
737 } // end namespace Amg
738} // end namespace Dune
739
740#endif
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
void reset() noexcept
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
T endl(T... args)