Loading...
Searching...
No Matches
kamg.hh
Go to the documentation of this file.
// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root
// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_AMG_KAMG_HH
#define DUNE_AMG_KAMG_HH
#include <dune/istl/preconditioners.hh>
#include "amg.hh"
namespace Dune
{
namespace Amg
{
template<class AMG>
class KAmgTwoGrid
: public Preconditioner<typename AMG::Domain,typename AMG::Range>
{
typedef typename AMG::Domain Domain;
typedef typename AMG::Range Range;
public:
virtual SolverCategory::Category category() const
{
return amg_.category();
};
KAmgTwoGrid(AMG& amg, std::shared_ptr<InverseOperator<Domain,Range> > coarseSolver)
: amg_(amg), coarseSolver_(coarseSolver)
{}
void pre([[maybe_unused]] typename AMG::Domain& x, [[maybe_unused]] typename AMG::Range& b)
{}
void post([[maybe_unused]] typename AMG::Domain& x)
{}
void apply(typename AMG::Domain& v, const typename AMG::Range& d)
{
// Copy data
*levelContext_->update=0;
*levelContext_->rhs = d;
*levelContext_->lhs = v;
presmooth(*levelContext_, amg_.preSteps_);
bool processFineLevel =
amg_.moveToCoarseLevel(*levelContext_);
if(processFineLevel) {
typename AMG::Range b=*levelContext_->rhs;
typename AMG::Domain x=*levelContext_->update;
InverseOperatorResult res;
coarseSolver_->apply(x, b, res);
*levelContext_->update=x;
}
amg_.moveToFineLevel(*levelContext_, processFineLevel);
postsmooth(*levelContext_, amg_.postSteps_);
v=*levelContext_->update;
}
InverseOperator<Domain,Range>* coarseSolver()
{
return coarseSolver_;
}
void setLevelContext(std::shared_ptr<typename AMG::LevelContext> p)
{
levelContext_=p;
}
~KAmgTwoGrid()
{}
private:
AMG& amg_;
std::shared_ptr<InverseOperator<Domain,Range> > coarseSolver_;
std::shared_ptr<typename AMG::LevelContext> levelContext_;
};
template<class M, class X, class S, class PI=SequentialInformation,
class K=GeneralizedPCGSolver<X>, class A=std::allocator<X> >
class KAMG : public Preconditioner<X,X>
{
public:
typedef AMG<M,X,S,PI,A> Amg;
typedef K KrylovSolver;
typedef typename Amg::OperatorHierarchy OperatorHierarchy;
typedef typename Amg::CoarseSolver CoarseSolver;
typedef typename Amg::ParallelInformation ParallelInformation;
typedef typename Amg::SmootherArgs SmootherArgs;
typedef typename Amg::Operator Operator;
typedef typename Amg::Domain Domain;
typedef typename Amg::Range Range;
typedef typename Amg::ParallelInformationHierarchy ParallelInformationHierarchy;
typedef typename Amg::ScalarProduct ScalarProduct;
virtual SolverCategory::Category category() const
{
return amg.category();
};
KAMG(OperatorHierarchy& matrices, CoarseSolver& coarseSolver,
const SmootherArgs& smootherArgs, const Parameters& parms,
std::size_t maxLevelKrylovSteps=3, double minDefectReduction=1e-1);
template<class C>
KAMG(const Operator& fineOperator, const C& criterion,
const SmootherArgs& smootherArgs=SmootherArgs(),
std::size_t maxLevelKrylovSteps=3, double minDefectReduction=1e-1,
const ParallelInformation& pinfo=ParallelInformation());
void pre(Domain& x, Range& b);
void post(Domain& x);
void apply(Domain& v, const Range& d);
std::size_t maxlevels();
private:
Amg amg;
std::size_t maxLevelKrylovSteps;
double levelDefectReduction;
std::vector<std::shared_ptr<typename Amg::ScalarProduct> > scalarproducts;
std::vector<std::shared_ptr<KAmgTwoGrid<Amg> > > ksolvers;
};
template<class M, class X, class S, class P, class K, class A>
KAMG<M,X,S,P,K,A>::KAMG(OperatorHierarchy& matrices, CoarseSolver& coarseSolver,
const SmootherArgs& smootherArgs, const Parameters& params,
std::size_t ksteps, double reduction)
: amg(matrices, coarseSolver, smootherArgs, params),
maxLevelKrylovSteps(ksteps), levelDefectReduction(reduction)
{}
template<class M, class X, class S, class P, class K, class A>
template<class C>
KAMG<M,X,S,P,K,A>::KAMG(const Operator& fineOperator, const C& criterion,
const SmootherArgs& smootherArgs,
std::size_t ksteps, double reduction,
const ParallelInformation& pinfo)
: amg(fineOperator, criterion, smootherArgs, pinfo),
maxLevelKrylovSteps(ksteps), levelDefectReduction(reduction)
{}
template<class M, class X, class S, class P, class K, class A>
void KAMG<M,X,S,P,K,A>::pre(Domain& x, Range& b)
{
amg.pre(x,b);
scalarproducts.reserve(amg.levels());
ksolvers.reserve(amg.levels());
typename OperatorHierarchy::ParallelMatrixHierarchy::Iterator
matrix = amg.matrices_->matrices().coarsest();
typename ParallelInformationHierarchy::Iterator
pinfo = amg.matrices_->parallelInformation().coarsest();
bool hasCoarsest=(amg.levels()==amg.maxlevels());
if(hasCoarsest) {
if(matrix==amg.matrices_->matrices().finest())
return;
--matrix;
--pinfo;
ksolvers.push_back(std::shared_ptr<KAmgTwoGrid<Amg> >(new KAmgTwoGrid<Amg>(amg, amg.solver_)));
}else
ksolvers.push_back(std::shared_ptr<KAmgTwoGrid<Amg> >(new KAmgTwoGrid<Amg>(amg, std::shared_ptr<InverseOperator<Domain,Range> >())));
std::ostringstream s;
if(matrix!=amg.matrices_->matrices().finest())
while(true) {
scalarproducts.push_back(createScalarProduct<X>(*pinfo,category()));
std::shared_ptr<InverseOperator<Domain,Range> > ks =
std::shared_ptr<InverseOperator<Domain,Range> >(new KrylovSolver(*matrix, *(scalarproducts.back()),
*(ksolvers.back()), levelDefectReduction,
maxLevelKrylovSteps, 0));
ksolvers.push_back(std::shared_ptr<KAmgTwoGrid<Amg> >(new KAmgTwoGrid<Amg>(amg, ks)));
--matrix;
--pinfo;
if(matrix==amg.matrices_->matrices().finest())
break;
}
}
template<class M, class X, class S, class P, class K, class A>
void KAMG<M,X,S,P,K,A>::post(Domain& x)
{
amg.post(x);
}
template<class M, class X, class S, class P, class K, class A>
void KAMG<M,X,S,P,K,A>::apply(Domain& v, const Range& d)
{
if(ksolvers.size()==0)
{
Range td=d;
InverseOperatorResult res;
amg.solver_->apply(v,td,res);
}else
{
typedef typename Amg::LevelContext LevelContext;
std::shared_ptr<LevelContext> levelContext(new LevelContext);
amg.initIteratorsWithFineLevel(*levelContext);
typedef typename std::vector<std::shared_ptr<KAmgTwoGrid<Amg> > >::iterator Iter;
for(Iter solver=ksolvers.begin(); solver!=ksolvers.end(); ++solver)
(*solver)->setLevelContext(levelContext);
ksolvers.back()->apply(v,d);
}
}
template<class M, class X, class S, class P, class K, class A>
std::size_t KAMG<M,X,S,P,K,A>::maxlevels()
{
return amg.maxlevels();
}
} // Amg
} // Dune
#endif
preconditioners.hh
Define general preconditioner interface.
amg.hh
The AMG preconditioner.
Dune::Amg::KAMG::apply
void apply(Domain &v, const Range &d)
Apply one step of the preconditioner to the system A(v)=d.
Definition kamg.hh:300
Dune::Amg::AMG::Domain
X Domain
The domain type.
Definition amg.hh:88
Dune::Amg::KAMG::KAMG
KAMG(OperatorHierarchy &matrices, CoarseSolver &coarseSolver, const SmootherArgs &smootherArgs, const Parameters &parms, std::size_t maxLevelKrylovSteps=3, double minDefectReduction=1e-1)
Construct a new amg with a specific coarse solver.
Definition kamg.hh:233
Dune::Amg::KAMG::maxlevels
std::size_t maxlevels()
Definition kamg.hh:320
Dune::Amg::AMG< M, X, S, PI, A >::SmootherArgs
SmootherTraits< Smoother >::Arguments SmootherArgs
Definition amg.hh:101
Dune::Amg::AMG< M, X, S, PI, A >::Operator
M Operator
Definition amg.hh:74
Dune::Amg::KAMG::post
void post(Domain &x)
Clean up.
Definition kamg.hh:293
Dune::Amg::AMG::Range
X Range
The range type.
Definition amg.hh:90
Dune::Amg::presmooth
void presmooth(LevelContext &levelContext, size_t steps)
Apply pre smoothing on the current level.
Definition smoother.hh:406
Dune::Amg::AMG< M, X, S, PI, A >::ParallelInformationHierarchy
OperatorHierarchy::ParallelInformationHierarchy ParallelInformationHierarchy
Definition amg.hh:85
Dune::Amg::AMG< M, X, S, PI, A >::CoarseSolver
InverseOperator< X, X > CoarseSolver
Definition amg.hh:92
Dune::Amg::postsmooth
void postsmooth(LevelContext &levelContext, size_t steps)
Apply post smoothing on the current level.
Definition smoother.hh:428
Dune::Amg::AMG< M, X, S, PI, A >::OperatorHierarchy
MatrixHierarchy< M, ParallelInformation, A > OperatorHierarchy
Definition amg.hh:83
Dune::Amg::KAMG::pre
void pre(Domain &x, Range &b)
Prepare the preconditioner.
Definition kamg.hh:253
Dune::Amg::AMG< M, X, S, PI, A >::ParallelInformation
PI ParallelInformation
Definition amg.hh:81
Dune
Definition allocator.hh:11
Dune::createScalarProduct
std::shared_ptr< ScalarProduct< X > > createScalarProduct(const Comm &comm, SolverCategory::Category category)
Definition scalarproducts.hh:242
Dune::Amg
Definition novlpschwarz.hh:256
Dune::Amg::KAMG::Domain
Amg::Domain Domain
the type of the domain.
Definition kamg.hh:157
Dune::Amg::KAMG::SmootherArgs
Amg::SmootherArgs SmootherArgs
The type of the arguments for construction of the smoothers.
Definition kamg.hh:153
Dune::Amg::KAMG::ParallelInformation
Amg::ParallelInformation ParallelInformation
the type of the parallelinformation to use.
Definition kamg.hh:151
Dune::Amg::KAMG::CoarseSolver
Amg::CoarseSolver CoarseSolver
The type of the coarse solver.
Definition kamg.hh:149
Dune::Amg::KAMG::OperatorHierarchy
Amg::OperatorHierarchy OperatorHierarchy
The type of the hierarchy of operators.
Definition kamg.hh:147
Dune::Amg::KAMG::Range
Amg::Range Range
The type of the range.
Definition kamg.hh:159
Dune::Amg::KAMG::ScalarProduct
Amg::ScalarProduct ScalarProduct
The type of the scalar product.
Definition kamg.hh:163
Dune::Amg::KAMG::Amg
AMG< M, X, S, PI, A > Amg
The type of the underlying AMG.
Definition kamg.hh:143
Dune::Amg::KAMG::Operator
Amg::Operator Operator
the type of the lineatr operator.
Definition kamg.hh:155
Dune::Amg::KAMG::ParallelInformationHierarchy
Amg::ParallelInformationHierarchy ParallelInformationHierarchy
The type of the hierarchy of parallel information.
Definition kamg.hh:161
Dune::Amg::KAMG::category
virtual SolverCategory::Category category() const
Category of the preconditioner (see SolverCategory::Category).
Definition kamg.hh:166
Dune::Amg::KAMG::KrylovSolver
K KrylovSolver
The type of the Krylov solver for the cycle.
Definition kamg.hh:145
Dune::Amg::KAmgTwoGrid
Two grid operator for AMG with Krylov cycle.
Definition kamg.hh:33
Dune::Amg::KAmgTwoGrid::pre
void pre(typename AMG::Domain &x, typename AMG::Range &b)
Prepare the preconditioner.
Definition kamg.hh:58
Dune::Amg::KAmgTwoGrid::KAmgTwoGrid
KAmgTwoGrid(AMG &amg, std::shared_ptr< InverseOperator< Domain, Range > > coarseSolver)
Constructor.
Definition kamg.hh:53
Dune::Amg::KAmgTwoGrid::~KAmgTwoGrid
~KAmgTwoGrid()
Destructor.
Definition kamg.hh:110
Dune::Amg::KAmgTwoGrid::post
void post(typename AMG::Domain &x)
Clean up.
Definition kamg.hh:62
Dune::Amg::KAmgTwoGrid::category
virtual SolverCategory::Category category() const
Category of the preconditioner (see SolverCategory::Category).
Definition kamg.hh:41
Dune::Amg::KAmgTwoGrid::setLevelContext
void setLevelContext(std::shared_ptr< typename AMG::LevelContext > p)
Set the level context pointer.
Definition kamg.hh:104
Dune::Amg::KAmgTwoGrid::coarseSolver
InverseOperator< Domain, Range > * coarseSolver()
Get a pointer to the coarse grid solver.
Definition kamg.hh:95
Dune::Amg::KAmgTwoGrid::apply
void apply(typename AMG::Domain &v, const typename AMG::Range &d)
Apply one step of the preconditioner to the system A(v)=d.
Definition kamg.hh:66
Dune::Amg::AMG
Parallel algebraic multigrid based on agglomeration.
Definition amg.hh:66
Dune::Amg::Hierarchy< ParallelInformation, Allocator >::Iterator
LevelIterator< Hierarchy< ParallelInformation, Allocator >, ParallelInformation > Iterator
Definition hierarchy.hh:220
Dune::Amg::Parameters
All parameters for AMG.
Definition parameters.hh:416
Dune::Preconditioner
Base class for matrix free definition of preconditioners.
Definition preconditioner.hh:33
Dune::InverseOperatorResult
Statistics about the application of an inverse operator.
Definition solver.hh:50
Dune::InverseOperator
Abstract base class for all solvers.
Definition solver.hh:101
Dune::SolverCategory::Category
Category
Definition solvercategory.hh:23
Dune::GeneralizedPCGSolver
Generalized preconditioned conjugate gradient solver.
Definition solvers.hh:1308