3#ifndef DUNE_ISTL_TWOLEVELMETHODCPR_HH
4#define DUNE_ISTL_TWOLEVELMETHODCPR_HH
9#include <dune/istl/operators.hh>
12#include <dune/istl/paamg/amg.hh>
13#include <dune/istl/paamg/galerkin.hh>
14#include <dune/istl/solver.hh>
16#include <dune/common/unused.hh>
17#include <dune/common/version.hh>
47template<
class FO,
class CO>
156template<
class O,
class C>
157class AggregationLevelTransferPolicyCpr
160 typedef Dune::Amg::AggregatesMap<typename O::matrix_type::size_type> AggregatesMap;
164 typedef SequentialInformation ParallelInformation;
166 explicit AggregationLevelTransferPolicyCpr(
const Criterion& crit)
172 prolongDamp_ = criterion_.getProlongationDampingFactor();
173 GalerkinProduct<ParallelInformation> productBuilder;
174 typedef typename Dune::Amg::MatrixGraph<const typename O::matrix_type> MatrixGraph;
175 typedef typename Dune::Amg::PropertiesGraph<MatrixGraph,Dune::Amg::VertexProperties,
176 Dune::Amg::EdgeProperties,Dune::IdentityMap,Dune::IdentityMap> PropertiesGraph;
177 MatrixGraph mg(fineOperator.getmat());
178 PropertiesGraph pg(mg,Dune::IdentityMap(),Dune::IdentityMap());
179 typedef NegateSet<typename ParallelInformation::OwnerSet> OverlapFlags;
181 aggregatesMap_.reset(
new AggregatesMap(pg.maxVertex()+1));
183 int noAggregates, isoAggregates, oneAggregates, skippedAggregates;
185 std::tie(noAggregates, isoAggregates, oneAggregates, skippedAggregates) =
186 aggregatesMap_->buildAggregates(fineOperator.getmat(), pg, criterion_,
true);
187 std::cout<<
"no aggregates="<<noAggregates<<
" iso="<<isoAggregates<<
" one="<<oneAggregates<<
" skipped="<<skippedAggregates<<std::endl;
189 Dune::Amg::IndicesCoarsener<Dune::Amg::SequentialInformation,int> renumberer;
190 typedef std::vector<bool>::iterator Iterator;
191 typedef Dune::IteratorPropertyMap<Iterator, Dune::IdentityMap> VisitedMap;
192 std::vector<bool> excluded(fineOperator.getmat().N(),
false);
193 VisitedMap vm(excluded.begin(), Dune::IdentityMap());
194 ParallelInformation pinfo;
196 std::size_t aggregates = coarsen(renumberer, pinfo, pg, vm,*aggregatesMap_, noAggregates,
true);
198 std::fill(excluded.begin(), excluded.end(),
false);
199 matrix_.reset(productBuilder.build(mg, vm,
200 SequentialInformation(),
204 productBuilder.calculate(fineOperator.getmat(), *aggregatesMap_, *matrix_, pinfo, OverlapFlags());
205 this->
lhs_.resize(this->matrix_->M());
206 this->
rhs_.resize(this->matrix_->N());
212 Transfer<std::size_t,typename FatherType::FineRangeType,ParallelInformation>
213 ::restrictVector(*aggregatesMap_, this->
rhs_, fineRhs, ParallelInformation());
219 Transfer<std::size_t,typename FatherType::FineRangeType,ParallelInformation>
220 ::prolongateVector(*aggregatesMap_, this->
lhs_, fineLhs,
221 prolongDamp_, ParallelInformation());
224 AggregationLevelTransferPolicyCpr*
clone()
const
226 return new AggregationLevelTransferPolicyCpr(*
this);
231 template <
typename RN,
typename PI,
typename PG,
typename VM,
typename AM>
232 auto coarsen(RN& renumberer,
238 bool useFixedOrder) ->
239 decltype(renumberer.coarsen(pinfo, pg, vm, aggregatesMap, pinfo, noAggregates, useFixedOrder))
241 return renumberer.coarsen(pinfo, pg, vm, aggregatesMap, pinfo, noAggregates, useFixedOrder);
244 template <
typename RN,
typename PI,
typename PG,
typename VM,
typename AM>
245 auto coarsen(RN& renumberer,
250 int noAggregates, ...)
252 return renumberer.coarsen(pinfo, pg, vm, aggregatesMap, pinfo, noAggregates);
255 typename O::matrix_type::field_type prolongDamp_;
256 std::shared_ptr<AggregatesMap> aggregatesMap_;
257 Criterion criterion_;
258 std::shared_ptr<typename O::matrix_type> matrix_;
267template<
class O,
class S,
class C>
274 typedef typename O::range_type
X;
289 : smootherArgs_(args), criterion_(c)
293 : coarseOperator_(other.coarseOperator_), smootherArgs_(other.smootherArgs_),
294 criterion_(other.criterion_)
303 struct AMGInverseOperator :
public InverseOperator<X,X>
305 AMGInverseOperator(
const typename AMGType::Operator& op,
307 const typename AMGType::SmootherArgs& args)
308 : amg_(op, crit,args), first_(true)
311 void apply(
X& x,
X& b, [[maybe_unused]]
double reduction, [[maybe_unused]] InverseOperatorResult& res)
322 void apply(
X& x,
X& b, InverseOperatorResult& res)
324 return apply(x,b,1e-8,res);
327 virtual SolverCategory::Category category()
const
329 return amg_.category();
332 ~AMGInverseOperator()
337 AMGInverseOperator(
const AMGInverseOperator& other)
338 : x_(other.x_), amg_(other.amg_), first_(other.first_)
361 coarseOperator_=transferPolicy.getCoarseLevelOperator();
362 AMGInverseOperator* inv =
new AMGInverseOperator(*coarseOperator_,
372 std::shared_ptr<Operator> coarseOperator_;
384template<
class FO,
class CSP,
class S>
386 public Preconditioner<typename FO::domain_type, typename FO::range_type>
437 std::shared_ptr<SmootherType> smoother,
441 std::size_t preSteps = 1, std::size_t postSteps = 1)
442 : operator_(&op), smoother_(smoother),
443 preSteps_(preSteps), postSteps_(postSteps)
445 policy_ = policy.clone();
446 policy_->createCoarseLevelSystem(*operator_);
447 coarseSolver_=coarsePolicy.createCoarseLevelSolver(*policy_);
451 : operator_(other.operator_), coarseSolver_(new
CoarseLevelSolver(*other.coarseSolver_)),
452 smoother_(other.smoother_), policy_(other.policy_->clone()),
453 preSteps_(other.preSteps_), postSteps_(other.postSteps_)
460 delete coarseSolver_;
464 std::shared_ptr<SmootherType> smoother,
467 updatePreconditioner(smoother, coarsePolicy);
470 void updatePreconditioner(std::shared_ptr<SmootherType> smoother,
473 smoother_ = smoother;
477 policy_->calculateCoarseEntries(*operator_);
478 coarsePolicy.setCoarseOperator(*policy_);
479 coarseSolver_->updatePreconditioner();
482 policy_->createCoarseLevelSystem(*operator_);
483 coarseSolver_ = coarsePolicy.createCoarseLevelSolver(*policy_);
489 if (x.dim() != u_.dim()) {
492 if (b.dim() != rhs_.dim()) {
493 rhs_.resize(b.dim());
502 bool hasPerfectUpdate()
const
505 return smoother_->hasPerfectUpdate() && coarseSolver_->hasPerfectUpdate();
512 LevelContext context;
513 SequentialInformation info;
517 context.smoother=smoother_;
519 context.matrix=operator_;
521 presmooth(context, preSteps_);
523 policy_->moveToCoarseLevel(*context.rhs);
524 InverseOperatorResult res;
525 coarseSolver_->apply(policy_->getCoarseLevelLhs(), policy_->getCoarseLevelRhs(), res);
527 policy_->moveToFineLevel(*context.lhs);
528 *context.update += *context.lhs;
530 postsmooth(context, postSteps_);
534 virtual SolverCategory::Category category()
const
536 return SolverCategory::sequential;
546 typedef S SmootherType;
548 std::shared_ptr<SmootherType> smoother;
564 SequentialInformation* pinfo;
576 std::shared_ptr<S> smoother_;
578 LevelTransferPolicyCpr<FO,typename CSP::Operator>* policy_;
580 std::size_t preSteps_;
582 std::size_t postSteps_;
void moveToFineLevel(typename FatherType::FineDomainType &fineLhs)
Updates the fine level linear system after the correction of the coarse levels system.
Definition twolevelmethodcpr.hh:217
void createCoarseLevelSystem(const O &fineOperator)
Algebraically creates the coarse level system.
Definition twolevelmethodcpr.hh:170
AggregationLevelTransferPolicyCpr * clone() const
Clone the current object.
Definition twolevelmethodcpr.hh:224
Abstract base class for transfer between levels and creation of the coarse level system.
Definition twolevelmethodcpr.hh:49
CoarseOperatorType::range_type CoarseRangeType
Definition twolevelmethodcpr.hh:72
CoarseDomainType & getCoarseLevelLhs()
Get the coarse level left hand side.
Definition twolevelmethodcpr.hh:98
virtual LevelTransferPolicyCpr * clone() const =0
Clone the current object.
FineOperator FineOperatorType
Definition twolevelmethodcpr.hh:55
virtual void createCoarseLevelSystem(const FineOperatorType &fineOperator)=0
Algebraically creates the coarse level system.
virtual void moveToCoarseLevel(const FineRangeType &fineRhs)=0
Transfers the data to the coarse level.
CoarseOperatorType::domain_type CoarseDomainType
Definition twolevelmethodcpr.hh:76
FineOperatorType::range_type FineRangeType
Definition twolevelmethodcpr.hh:59
CoarseRangeType & getCoarseLevelRhs()
Get the coarse level right hand side.
Definition twolevelmethodcpr.hh:89
virtual ~LevelTransferPolicyCpr()
Destructor.
Definition twolevelmethodcpr.hh:140
virtual void moveToFineLevel(FineDomainType &fineLhs)=0
Updates the fine level linear system after the correction of the coarse levels system.
virtual void calculateCoarseEntries(const FineOperatorType &fineOperator)=0
?
CoarseDomainType lhs_
Definition twolevelmethodcpr.hh:146
CoarseRangeType rhs_
Definition twolevelmethodcpr.hh:144
FineOperatorType::domain_type FineDomainType
Definition twolevelmethodcpr.hh:63
CoarseOperator CoarseOperatorType
Definition twolevelmethodcpr.hh:68
std::shared_ptr< CoarseOperatorType > & getCoarseLevelOperator()
Get the coarse level operator.
Definition twolevelmethodcpr.hh:81
std::shared_ptr< CoarseOperatorType > operator_
Definition twolevelmethodcpr.hh:148
AMG< Operator, X, Smoother > AMGType
The type of the AMG construct on the coarse level.
Definition twolevelmethodcpr.hh:282
OneStepAMGCoarseSolverPolicyCpr(const OneStepAMGCoarseSolverPolicyCpr &other)
Copy constructor.
Definition twolevelmethodcpr.hh:292
AMGInverseOperator CoarseLevelSolver
The type of solver constructed for the coarse level.
Definition twolevelmethodcpr.hh:349
S Smoother
The type of the smoother used in AMG.
Definition twolevelmethodcpr.hh:278
C Criterion
The type of the crition used for the aggregation within AMG.
Definition twolevelmethodcpr.hh:276
Dune::Amg::SmootherTraits< S >::Arguments SmootherArgs
The type of the arguments used for constructing the smoother.
Definition twolevelmethodcpr.hh:280
CoarseLevelSolver * createCoarseLevelSolver(P &transferPolicy)
Constructs a coarse level solver.
Definition twolevelmethodcpr.hh:359
O::range_type X
The type of the range and domain of the operator.
Definition twolevelmethodcpr.hh:274
OneStepAMGCoarseSolverPolicyCpr(const SmootherArgs &args, const Criterion &c)
Constructs the coarse solver policy.
Definition twolevelmethodcpr.hh:288
O Operator
The type of the linear operator used.
Definition twolevelmethodcpr.hh:272
Definition twolevelmethodcpr.hh:387
Dune::PreconditionerWithUpdate< VectorType, VectorType > SmootherType
Definition twolevelmethodcpr.hh:422
FineOperatorType::range_type FineRangeType
Definition twolevelmethodcpr.hh:401
TwoLevelMethodCpr(const FineOperatorType &op, std::shared_ptr< SmootherType > smoother, const LevelTransferPolicyCpr< FineOperatorType, CoarseOperatorType > &policy, CoarseLevelSolverPolicy &coarsePolicy, std::size_t preSteps=1, std::size_t postSteps=1)
Constructs a two level method.
Definition twolevelmethodcpr.hh:436
FineOperatorType::domain_type FineDomainType
Definition twolevelmethodcpr.hh:405
CoarseOperatorType::domain_type CoarseDomainType
Definition twolevelmethodcpr.hh:418
CoarseSolverPolicy::Operator CoarseOperatorType
Definition twolevelmethodcpr.hh:410
CoarseSolverPolicy CoarseLevelSolverPolicy
Definition twolevelmethodcpr.hh:390
CoarseLevelSolverPolicy::CoarseLevelSolver CoarseLevelSolver
Definition twolevelmethodcpr.hh:392
CoarseOperatorType::range_type CoarseRangeType
Definition twolevelmethodcpr.hh:414
OperatorType FineOperatorType
Definition twolevelmethodcpr.hh:397