Dune Core Modules (2.8.0)

fastamg.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_ISTL_FASTAMG_HH
4#define DUNE_ISTL_FASTAMG_HH
5
6#include <memory>
12#include <dune/istl/solvers.hh>
14#include <dune/istl/superlu.hh>
15#include <dune/istl/umfpack.hh>
17#include <dune/istl/io.hh>
19
20#include "fastamgsmoother.hh"
21
30namespace Dune
31{
32 namespace Amg
33 {
56 template<class M, class X, class PI=SequentialInformation, class A=std::allocator<X> >
57 class FastAMG : public Preconditioner<X,X>
58 {
59 public:
61 typedef M Operator;
73
75 typedef X Domain;
77 typedef X Range;
80
88 FastAMG(OperatorHierarchy& matrices, CoarseSolver& coarseSolver,
89 const Parameters& parms,
90 bool symmetric=true);
91
103 template<class C>
104 FastAMG(const Operator& fineOperator, const C& criterion,
105 const Parameters& parms=Parameters(),
106 bool symmetric=true,
108
112 FastAMG(const FastAMG& amg);
113
115 void pre(Domain& x, Range& b);
116
118 void apply(Domain& v, const Range& d);
119
122 {
124 }
125
127 void post(Domain& x);
128
133 template<class A1>
134 void getCoarsestAggregateNumbers(std::vector<std::size_t,A1>& cont);
135
136 std::size_t levels();
137
138 std::size_t maxlevels();
139
149 {
150 matrices_->recalculateGalerkin(NegateSet<typename PI::OwnerSet>());
151 }
152
157 bool usesDirectCoarseLevelSolver() const;
158
159 private:
166 template<class C>
167 void createHierarchies(C& criterion,
168 const std::shared_ptr<const Operator>& matrixptr,
169 const PI& pinfo);
170
177 struct LevelContext
178 {
190 typename OperatorHierarchy::RedistributeInfoList::const_iterator redist;
194 typename OperatorHierarchy::AggregatesMapList::const_iterator aggregates;
210 std::size_t level;
211 };
212
214 void mgc(LevelContext& levelContext, Domain& x, const Range& b);
215
222 void presmooth(LevelContext& levelContext, Domain& x, const Range& b);
223
230 void postsmooth(LevelContext& levelContext, Domain& x, const Range& b);
231
238 void moveToFineLevel(LevelContext& levelContext, bool processedFineLevel,
239 Domain& fineX);
240
245 bool moveToCoarseLevel(LevelContext& levelContext);
246
251 void initIteratorsWithFineLevel(LevelContext& levelContext);
252
254 std::shared_ptr<OperatorHierarchy> matrices_;
256 std::shared_ptr<CoarseSolver> solver_;
258 std::shared_ptr<Hierarchy<Range,A>> rhs_;
260 std::shared_ptr<Hierarchy<Domain,A>> lhs_;
262 std::shared_ptr<Hierarchy<Domain,A>> residual_;
263
267 std::shared_ptr<ScalarProduct> scalarProduct_;
269 std::size_t gamma_;
271 std::size_t preSteps_;
273 std::size_t postSteps_;
274 std::size_t level;
275 bool buildHierarchy_;
276 bool symmetric;
277 bool coarsesolverconverged;
279 typedef std::shared_ptr<Smoother> SmootherPointer;
280 SmootherPointer coarseSmoother_;
282 std::size_t verbosity_;
283 };
284
285 template<class M, class X, class PI, class A>
287 : matrices_(amg.matrices_), solver_(amg.solver_),
288 rhs_(), lhs_(), residual_(), scalarProduct_(amg.scalarProduct_),
289 gamma_(amg.gamma_), preSteps_(amg.preSteps_), postSteps_(amg.postSteps_),
290 symmetric(amg.symmetric), coarsesolverconverged(amg.coarsesolverconverged),
291 coarseSmoother_(amg.coarseSmoother_), verbosity_(amg.verbosity_)
292 {}
293
294 template<class M, class X, class PI, class A>
296 const Parameters& parms, bool symmetric_)
297 : matrices_(stackobject_to_shared_ptr(matrices)), solver_(&coarseSolver),
298 rhs_(), lhs_(), residual_(), scalarProduct_(),
299 gamma_(parms.getGamma()), preSteps_(parms.getNoPreSmoothSteps()),
300 postSteps_(parms.getNoPostSmoothSteps()), buildHierarchy_(false),
301 symmetric(symmetric_), coarsesolverconverged(true),
302 coarseSmoother_(), verbosity_(parms.debugLevel())
303 {
304 if(preSteps_>1||postSteps_>1)
305 {
306 std::cerr<<"WARNING only one step of smoothing is supported!"<<std::endl;
307 preSteps_=postSteps_=0;
308 }
309 assert(matrices_->isBuilt());
310 static_assert(std::is_same<PI,SequentialInformation>::value,
311 "Currently only sequential runs are supported");
312 }
313 template<class M, class X, class PI, class A>
314 template<class C>
316 const C& criterion,
317 const Parameters& parms,
318 bool symmetric_,
319 const PI& pinfo)
320 : solver_(), rhs_(), lhs_(), residual_(), scalarProduct_(), gamma_(parms.getGamma()),
321 preSteps_(parms.getNoPreSmoothSteps()), postSteps_(parms.getNoPostSmoothSteps()),
322 buildHierarchy_(true),
323 symmetric(symmetric_), coarsesolverconverged(true),
324 coarseSmoother_(), verbosity_(criterion.debugLevel())
325 {
326 if(preSteps_>1||postSteps_>1)
327 {
328 std::cerr<<"WARNING only one step of smoothing is supported!"<<std::endl;
329 preSteps_=postSteps_=1;
330 }
331 static_assert(std::is_same<PI,SequentialInformation>::value,
332 "Currently only sequential runs are supported");
333 // TODO: reestablish compile time checks.
334 //static_assert(static_cast<int>(PI::category)==static_cast<int>(S::category),
335 // "Matrix and Solver must match in terms of category!");
336 auto matrixptr = stackobject_to_shared_ptr(matrix);
337 createHierarchies(criterion, matrixptr, pinfo);
338 }
339
340 template<class M, class X, class PI, class A>
341 template<class C>
342 void FastAMG<M,X,PI,A>::createHierarchies(C& criterion,
343 const std::shared_ptr<const Operator>& matrixptr,
344 const PI& pinfo)
345 {
346 Timer watch;
347 matrices_ = std::make_shared<OperatorHierarchy>(
348 std::const_pointer_cast<Operator>(matrixptr),
349 stackobject_to_shared_ptr(const_cast<PI&>(pinfo)));
350
351 matrices_->template build<NegateSet<typename PI::OwnerSet> >(criterion);
352
353 if(verbosity_>0 && matrices_->parallelInformation().finest()->communicator().rank()==0)
354 std::cout<<"Building Hierarchy of "<<matrices_->maxlevels()<<" levels took "<<watch.elapsed()<<" seconds."<<std::endl;
355
356 if(buildHierarchy_ && matrices_->levels()==matrices_->maxlevels()) {
357 // We have the carsest level. Create the coarse Solver
358 typedef typename SmootherTraits<Smoother>::Arguments SmootherArgs;
359 SmootherArgs sargs;
360 sargs.iterations = 1;
361
363 cargs.setArgs(sargs);
364 if(matrices_->redistributeInformation().back().isSetup()) {
365 // Solve on the redistributed partitioning
366 cargs.setMatrix(matrices_->matrices().coarsest().getRedistributed().getmat());
367 cargs.setComm(matrices_->parallelInformation().coarsest().getRedistributed());
368 }else{
369 cargs.setMatrix(matrices_->matrices().coarsest()->getmat());
370 cargs.setComm(*matrices_->parallelInformation().coarsest());
371 }
372
373 coarseSmoother_ = ConstructionTraits<Smoother>::construct(cargs);
374 scalarProduct_ = createScalarProduct<X>(cargs.getComm(),category());
375
376#if HAVE_SUPERLU|| HAVE_SUITESPARSE_UMFPACK
377#if HAVE_SUITESPARSE_UMFPACK
378#define DIRECTSOLVER UMFPack
379#else
380#define DIRECTSOLVER SuperLU
381#endif
382 // Use superlu if we are purely sequential or with only one processor on the coarsest level.
383 if(std::is_same<ParallelInformation,SequentialInformation>::value // sequential mode
384 || matrices_->parallelInformation().coarsest()->communicator().size()==1 //parallel mode and only one processor
385 || (matrices_->parallelInformation().coarsest().isRedistributed()
386 && matrices_->parallelInformation().coarsest().getRedistributed().communicator().size()==1
387 && matrices_->parallelInformation().coarsest().getRedistributed().communicator().size()>0)) { // redistribute and 1 proc
388 if(verbosity_>0 && matrices_->parallelInformation().coarsest()->communicator().rank()==0)
389 std::cout<<"Using superlu"<<std::endl;
390 if(matrices_->parallelInformation().coarsest().isRedistributed())
391 {
392 if(matrices_->matrices().coarsest().getRedistributed().getmat().N()>0)
393 // We are still participating on this level
394 solver_.reset(new DIRECTSOLVER<typename M::matrix_type>(matrices_->matrices().coarsest().getRedistributed().getmat(), false, false));
395 else
396 solver_.reset();
397 }else
398 solver_.reset(new DIRECTSOLVER<typename M::matrix_type>(matrices_->matrices().coarsest()->getmat(), false, false));
399 }else
400#undef DIRECTSOLVER
401#endif // HAVE_SUPERLU|| HAVE_SUITESPARSE_UMFPACK
402 {
403 if(matrices_->parallelInformation().coarsest().isRedistributed())
404 {
405 if(matrices_->matrices().coarsest().getRedistributed().getmat().N()>0)
406 // We are still participating on this level
407 solver_.reset(new BiCGSTABSolver<X>(const_cast<M&>(matrices_->matrices().coarsest().getRedistributed()),
408 *scalarProduct_,
409 *coarseSmoother_, 1E-2, 1000, 0));
410 else
411 solver_.reset();
412 }else
413 solver_.reset(new BiCGSTABSolver<X>(const_cast<M&>(*matrices_->matrices().coarsest()),
414 *scalarProduct_,
415 *coarseSmoother_, 1E-2, 1000, 0));
416 }
417 }
418
419 if(verbosity_>0 && matrices_->parallelInformation().finest()->communicator().rank()==0)
420 std::cout<<"Building Hierarchy of "<<matrices_->maxlevels()<<" levels took "<<watch.elapsed()<<" seconds."<<std::endl;
421 }
422
423
424 template<class M, class X, class PI, class A>
426 {
427 Timer watch, watch1;
428 // Detect Matrix rows where all offdiagonal entries are
429 // zero and set x such that A_dd*x_d=b_d
430 // Thus users can be more careless when setting up their linear
431 // systems.
432 typedef typename M::matrix_type Matrix;
433 typedef typename Matrix::ConstRowIterator RowIter;
434 typedef typename Matrix::ConstColIterator ColIter;
435 typedef typename Matrix::block_type Block;
436 Block zero;
437 zero=typename Matrix::field_type();
438
439 const Matrix& mat=matrices_->matrices().finest()->getmat();
440 for(RowIter row=mat.begin(); row!=mat.end(); ++row) {
441 bool isDirichlet = true;
442 bool hasDiagonal = false;
443 ColIter diag;
444 for(ColIter col=row->begin(); col!=row->end(); ++col) {
445 if(row.index()==col.index()) {
446 diag = col;
447 hasDiagonal = (*col != zero);
448 }else{
449 if(*col!=zero)
450 isDirichlet = false;
451 }
452 }
453 if(isDirichlet && hasDiagonal)
454 diag->solve(x[row.index()], b[row.index()]);
455 }
456 if (verbosity_>0)
457 std::cout<<" Preprocessing Dirichlet took "<<watch1.elapsed()<<std::endl;
458 watch1.reset();
459 // No smoother to make x consistent! Do it by hand
460 matrices_->parallelInformation().coarsest()->copyOwnerToAll(x,x);
461 rhs_ = std::make_shared<Hierarchy<Range,A>>(std::make_shared<Range>(b));
462 lhs_ = std::make_shared<Hierarchy<Domain,A>>(std::make_shared<Domain>(x));
463 residual_ = std::make_shared<Hierarchy<Domain,A>>(std::make_shared<Domain>(x));
464 matrices_->coarsenVector(*rhs_);
465 matrices_->coarsenVector(*lhs_);
466 matrices_->coarsenVector(*residual_);
467
468 // The preconditioner might change x and b. So we have to
469 // copy the changes to the original vectors.
470 x = *lhs_->finest();
471 b = *rhs_->finest();
472 }
473 template<class M, class X, class PI, class A>
474 std::size_t FastAMG<M,X,PI,A>::levels()
475 {
476 return matrices_->levels();
477 }
478 template<class M, class X, class PI, class A>
479 std::size_t FastAMG<M,X,PI,A>::maxlevels()
480 {
481 return matrices_->maxlevels();
482 }
483
485 template<class M, class X, class PI, class A>
487 {
488 LevelContext levelContext;
489 // Init all iterators for the current level
490 initIteratorsWithFineLevel(levelContext);
491
492 assert(v.two_norm()==0);
493
494 level=0;
495 if(matrices_->maxlevels()==1){
496 // The coarse solver might modify the d!
497 Range b(d);
498 mgc(levelContext, v, b);
499 }else
500 mgc(levelContext, v, d);
501 if(postSteps_==0||matrices_->maxlevels()==1)
502 levelContext.pinfo->copyOwnerToAll(v, v);
503 }
504
505 template<class M, class X, class PI, class A>
506 void FastAMG<M,X,PI,A>::initIteratorsWithFineLevel(LevelContext& levelContext)
507 {
508 levelContext.matrix = matrices_->matrices().finest();
509 levelContext.pinfo = matrices_->parallelInformation().finest();
510 levelContext.redist =
511 matrices_->redistributeInformation().begin();
512 levelContext.aggregates = matrices_->aggregatesMaps().begin();
513 levelContext.lhs = lhs_->finest();
514 levelContext.residual = residual_->finest();
515 levelContext.rhs = rhs_->finest();
516 levelContext.level=0;
517 }
518
519 template<class M, class X, class PI, class A>
520 bool FastAMG<M,X,PI,A>
521 ::moveToCoarseLevel(LevelContext& levelContext)
522 {
523 bool processNextLevel=true;
524
525 if(levelContext.redist->isSetup()) {
526 throw "bla";
527 levelContext.redist->redistribute(static_cast<const Range&>(*levelContext.residual),
528 levelContext.residual.getRedistributed());
529 processNextLevel = levelContext.residual.getRedistributed().size()>0;
530 if(processNextLevel) {
531 //restrict defect to coarse level right hand side.
532 ++levelContext.pinfo;
533 Transfer<typename OperatorHierarchy::AggregatesMap::AggregateDescriptor,Range,ParallelInformation>
534 ::restrictVector(*(*levelContext.aggregates), *levelContext.rhs,
535 static_cast<const Range&>(levelContext.residual.getRedistributed()),
536 *levelContext.pinfo);
537 }
538 }else{
539 //restrict defect to coarse level right hand side.
540 ++levelContext.rhs;
541 ++levelContext.pinfo;
542 Transfer<typename OperatorHierarchy::AggregatesMap::AggregateDescriptor,Range,ParallelInformation>
543 ::restrictVector(*(*levelContext.aggregates), *levelContext.rhs,
544 static_cast<const Range&>(*levelContext.residual), *levelContext.pinfo);
545 }
546
547 if(processNextLevel) {
548 // prepare coarse system
549 ++levelContext.residual;
550 ++levelContext.lhs;
551 ++levelContext.matrix;
552 ++levelContext.level;
553 ++levelContext.redist;
554
555 if(levelContext.matrix != matrices_->matrices().coarsest() || matrices_->levels()<matrices_->maxlevels()) {
556 // next level is not the globally coarsest one
557 ++levelContext.aggregates;
558 }
559 // prepare the lhs on the next level
560 *levelContext.lhs=0;
561 *levelContext.residual=0;
562 }
563 return processNextLevel;
564 }
565
566 template<class M, class X, class PI, class A>
567 void FastAMG<M,X,PI,A>
568 ::moveToFineLevel(LevelContext& levelContext, bool processNextLevel, Domain& x)
569 {
570 if(processNextLevel) {
571 if(levelContext.matrix != matrices_->matrices().coarsest() || matrices_->levels()<matrices_->maxlevels()) {
572 // previous level is not the globally coarsest one
573 --levelContext.aggregates;
574 }
575 --levelContext.redist;
576 --levelContext.level;
577 //prolongate and add the correction (update is in coarse left hand side)
578 --levelContext.matrix;
579 --levelContext.residual;
580
581 }
582
583 typename Hierarchy<Domain,A>::Iterator coarseLhs = levelContext.lhs--;
584 if(levelContext.redist->isSetup()) {
585
586 // Need to redistribute during prolongate
587 Transfer<typename OperatorHierarchy::AggregatesMap::AggregateDescriptor,Range,ParallelInformation>
588 ::prolongateVector(*(*levelContext.aggregates), *coarseLhs, x,
589 levelContext.lhs.getRedistributed(),
590 matrices_->getProlongationDampingFactor(),
591 *levelContext.pinfo, *levelContext.redist);
592 }else{
593 Transfer<typename OperatorHierarchy::AggregatesMap::AggregateDescriptor,Range,ParallelInformation>
594 ::prolongateVector(*(*levelContext.aggregates), *coarseLhs, x,
595 matrices_->getProlongationDampingFactor(), *levelContext.pinfo);
596
597 // printvector(std::cout, *lhs, "prolongated coarse grid correction", "lhs", 10, 10, 10);
598 }
599
600
601 if(processNextLevel) {
602 --levelContext.rhs;
603 }
604
605 }
606
607
608 template<class M, class X, class PI, class A>
609 void FastAMG<M,X,PI,A>
610 ::presmooth(LevelContext& levelContext, Domain& x, const Range& b)
611 {
612 constexpr auto bl = blockLevel<typename M::matrix_type>();
613 GaussSeidelPresmoothDefect<bl>::apply(levelContext.matrix->getmat(),
614 x,
615 *levelContext.residual,
616 b);
617 }
618
619 template<class M, class X, class PI, class A>
620 void FastAMG<M,X,PI,A>
621 ::postsmooth(LevelContext& levelContext, Domain& x, const Range& b)
622 {
623 constexpr auto bl = blockLevel<typename M::matrix_type>();
624 GaussSeidelPostsmoothDefect<bl>
625 ::apply(levelContext.matrix->getmat(), x, *levelContext.residual, b);
626 }
627
628
629 template<class M, class X, class PI, class A>
631 {
632 return IsDirectSolver< CoarseSolver>::value;
633 }
634
635 template<class M, class X, class PI, class A>
636 void FastAMG<M,X,PI,A>::mgc(LevelContext& levelContext, Domain& v, const Range& b){
637
638 if(levelContext.matrix == matrices_->matrices().coarsest() && levels()==maxlevels()) {
639 // Solve directly
641 res.converged=true; // If we do not compute this flag will not get updated
642 if(levelContext.redist->isSetup()) {
643 levelContext.redist->redistribute(b, levelContext.rhs.getRedistributed());
644 if(levelContext.rhs.getRedistributed().size()>0) {
645 // We are still participating in the computation
646 levelContext.pinfo.getRedistributed().copyOwnerToAll(levelContext.rhs.getRedistributed(),
647 levelContext.rhs.getRedistributed());
648 solver_->apply(levelContext.lhs.getRedistributed(), levelContext.rhs.getRedistributed(), res);
649 }
650 levelContext.redist->redistributeBackward(v, levelContext.lhs.getRedistributed());
651 levelContext.pinfo->copyOwnerToAll(v, v);
652 }else{
653 levelContext.pinfo->copyOwnerToAll(b, b);
654 solver_->apply(v, const_cast<Range&>(b), res);
655 }
656
657 // printvector(std::cout, *lhs, "coarse level update", "u", 10, 10, 10);
658 // printvector(std::cout, *rhs, "coarse level rhs", "rhs", 10, 10, 10);
659 if (!res.converged)
660 coarsesolverconverged = false;
661 }else{
662 // presmoothing
663 presmooth(levelContext, v, b);
664 // printvector(std::cout, *lhs, "update", "u", 10, 10, 10);
665 // printvector(std::cout, *residual, "post presmooth residual", "r", 10);
666#ifndef DUNE_AMG_NO_COARSEGRIDCORRECTION
667 bool processNextLevel = moveToCoarseLevel(levelContext);
668
669 if(processNextLevel) {
670 // next level
671 for(std::size_t i=0; i<gamma_; i++)
672 mgc(levelContext, *levelContext.lhs, *levelContext.rhs);
673 }
674
675 moveToFineLevel(levelContext, processNextLevel, v);
676#else
677 *lhs=0;
678#endif
679
680 if(levelContext.matrix == matrices_->matrices().finest()) {
681 coarsesolverconverged = matrices_->parallelInformation().finest()->communicator().prod(coarsesolverconverged);
682 if(!coarsesolverconverged)
683 DUNE_THROW(MathError, "Coarse solver did not converge");
684 }
685
686 postsmooth(levelContext, v, b);
687 }
688 }
689
690
692 template<class M, class X, class PI, class A>
693 void FastAMG<M,X,PI,A>::post([[maybe_unused]] Domain& x)
694 {
695 lhs_=nullptr;
696 rhs_=nullptr;
697 residual_=nullptr;
698 }
699
700 template<class M, class X, class PI, class A>
701 template<class A1>
702 void FastAMG<M,X,PI,A>::getCoarsestAggregateNumbers(std::vector<std::size_t,A1>& cont)
703 {
704 matrices_->getCoarsestAggregatesOnFinest(cont);
705 }
706
707 } // end namespace Amg
708} // end namespace Dune
709
710#endif
A fast (sequential) algebraic multigrid based on agglomeration that saves memory bandwidth.
Definition: fastamg.hh:58
LevelIterator< Hierarchy< ParallelInformation, Allocator >, ParallelInformation > Iterator
Type of the mutable iterator.
Definition: hierarchy.hh:214
LevelIterator< const Hierarchy< MatrixOperator, Allocator >, const MatrixOperator > ConstIterator
Type of the const iterator.
Definition: hierarchy.hh:217
The hierarchies build by the coarsening process.
Definition: matrixhierarchy.hh:59
All parameters for AMG.
Definition: parameters.hh:391
ConstIterator class for sequential access.
Definition: matrix.hh:402
A generic dynamic dense matrix.
Definition: matrix.hh:559
typename Imp::BlockTraits< T >::field_type field_type
Export the type representing the underlying field.
Definition: matrix.hh:563
row_type::const_iterator ConstColIterator
Const iterator for the entries of each row.
Definition: matrix.hh:587
T block_type
Export the type representing the components.
Definition: matrix.hh:566
The negation of a set. An item is contained in the set if and only if it is not contained in the nega...
Definition: enumset.hh:94
Base class for matrix free definition of preconditioners.
Definition: preconditioner.hh:30
Base class for scalar product and norm computation.
Definition: scalarproducts.hh:50
Sequential SSOR preconditioner.
Definition: preconditioners.hh:139
A simple stop watch.
Definition: timer.hh:41
void reset() noexcept
Reset timer while keeping the running/stopped state.
Definition: timer.hh:55
double elapsed() const noexcept
Get elapsed user-time from last reset until now/last stop in seconds.
Definition: timer.hh:75
A few common exception classes.
Traits for type conversions and type information.
Some generic functions for pretty printing vectors and matrices.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
OperatorHierarchy::ParallelMatrixHierarchy::ConstIterator matrix
The iterator over the matrices.
Definition: fastamg.hh:182
void getCoarsestAggregateNumbers(std::vector< std::size_t, A1 > &cont)
Get the aggregate number of each unknown on the coarsest level.
Definition: fastamg.hh:702
ParallelInformationHierarchy::Iterator pinfo
The iterator over the parallel information.
Definition: fastamg.hh:186
void recalculateHierarchy()
Recalculate the matrix hierarchy.
Definition: fastamg.hh:148
void post(Domain &x)
Clean up.
Definition: fastamg.hh:693
X Domain
The domain type.
Definition: fastamg.hh:75
Hierarchy< Domain, A >::Iterator residual
The iterator over the residuals.
Definition: fastamg.hh:202
virtual SolverCategory::Category category() const
Category of the preconditioner (see SolverCategory::Category)
Definition: fastamg.hh:121
MatrixHierarchy< M, ParallelInformation, A > OperatorHierarchy
The operator hierarchy type.
Definition: fastamg.hh:70
OperatorHierarchy::RedistributeInfoList::const_iterator redist
The iterator over the redistribution information.
Definition: fastamg.hh:190
X Range
The range type.
Definition: fastamg.hh:77
PI ParallelInformation
The type of the parallel information. Either OwnerOverlapCommunication or another type describing the...
Definition: fastamg.hh:68
M Operator
The matrix operator type.
Definition: fastamg.hh:61
InverseOperator< X, X > CoarseSolver
the type of the coarse solver.
Definition: fastamg.hh:79
bool usesDirectCoarseLevelSolver() const
Check whether the coarse solver used is a direct solver.
Definition: fastamg.hh:630
Hierarchy< Domain, A >::Iterator lhs
The iterator over the left hand side.
Definition: fastamg.hh:198
Hierarchy< Range, A >::Iterator rhs
The iterator over the right hand sided.
Definition: fastamg.hh:206
std::size_t level
The level index.
Definition: fastamg.hh:210
void apply(Domain &v, const Range &d)
Apply one step of the preconditioner to the system A(v)=d.
Definition: fastamg.hh:486
OperatorHierarchy::ParallelInformationHierarchy ParallelInformationHierarchy
The parallal data distribution hierarchy type.
Definition: fastamg.hh:72
void pre(Domain &x, Range &b)
Prepare the preconditioner.
Definition: fastamg.hh:425
FastAMG(OperatorHierarchy &matrices, CoarseSolver &coarseSolver, const Parameters &parms, bool symmetric=true)
Construct a new amg with a specific coarse solver.
Definition: fastamg.hh:295
OperatorHierarchy::AggregatesMapList::const_iterator aggregates
The iterator over the aggregates maps.
Definition: fastamg.hh:194
void presmooth(LevelContext &levelContext, size_t steps)
Apply pre smoothing on the current level.
Definition: smoother.hh:404
const void * Arguments
A type holding all the arguments needed to call the constructor.
Definition: construction.hh:42
static std::shared_ptr< T > construct(Arguments &args)
Construct an object with the specified arguments.
Definition: construction.hh:50
void postsmooth(LevelContext &levelContext, size_t steps)
Apply post smoothing on the current level.
Definition: smoother.hh:426
Provides a classes representing the hierarchies in AMG.
Dune namespace.
Definition: alignedallocator.hh:11
std::shared_ptr< T > stackobject_to_shared_ptr(T &t)
Create a shared_ptr for a stack-allocated object.
Definition: shared_ptr.hh:70
Define general preconditioner interface.
Define base class for scalar product and norm.
Classes for the generic construction and application of the smoothers.
Implementations of the inverse operator interface.
Templates characterizing the type of a solver.
Traits class for getting the attribute class of a smoother.
Definition: smoother.hh:64
Statistics about the application of an inverse operator.
Definition: solver.hh:46
bool converged
True if convergence criterion has been met.
Definition: solver.hh:71
Category
Definition: solvercategory.hh:21
@ sequential
Category for sequential solvers.
Definition: solvercategory.hh:23
Classes for using SuperLU with ISTL matrices.
Prolongation and restriction for amg.
Classes for using UMFPack with ISTL matrices.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Sep 26, 22:29, 2024)