5#ifndef DUNE_AMGSMOOTHER_HH 
    6#define DUNE_AMGSMOOTHER_HH 
   11#include <dune/istl/schwarz.hh> 
   12#include <dune/istl/novlpschwarz.hh> 
   13#include <dune/common/propertymap.hh> 
   71    template<
class X, 
class Y>
 
   78    template<
class X, 
class Y, 
class C, 
class T>
 
   80        : 
public SmootherTraits<T>
 
   83    template<
class C, 
class T>
 
   84    struct SmootherTraits<NonoverlappingBlockPreconditioner<C,T> >
 
   85        : 
public SmootherTraits<T>
 
   94      typedef typename T::matrix_type Matrix;
 
  104      void setMatrix(
const Matrix& matrix)
 
  108      virtual void setMatrix(
const Matrix& matrix, [[maybe_unused]] 
const AggregatesMap& amap)
 
  114      const Matrix& getMatrix()
 const 
  125      void setComm([[maybe_unused]] T1& comm)
 
  128      const SequentialInformation& getComm()
 
  139      const Matrix* matrix_;
 
  142      SequentialInformation comm_;
 
  146    struct ConstructionArgs
 
  150    template<
class T, 
class C=SequentialInformation>
 
  151    class DefaultParallelConstructionArgs
 
  152      : 
public ConstructionArgs<T>
 
  155      virtual ~DefaultParallelConstructionArgs()
 
  158      void setComm(
const C& comm)
 
  163      const C& getComm()
 const 
  172    template<
class X, 
class Y>
 
  173    class DefaultConstructionArgs<Richardson<X,Y>>
 
  175      typedef Richardson<X,Y> T;
 
  177      typedef typename SmootherTraits<T>::Arguments SmootherArgs;
 
  180      virtual ~DefaultConstructionArgs()
 
  183      template <
class... Args>
 
  184      void setMatrix(
const Args&...)
 
  187      void setArgs(
const SmootherArgs& args)
 
  193      void setComm([[maybe_unused]] T1& comm)
 
  196      const SequentialInformation& getComm()
 
  201      const SmootherArgs getArgs()
 const 
  207      const SmootherArgs* args_;
 
  208      SequentialInformation comm_;
 
  214    struct ConstructionTraits;
 
  219    template<
class M, 
class X, 
class Y, 
int l>
 
  226        return std::make_shared<SeqSSOR<M,X,Y,l>>
 
  235    template<
class M, 
class X, 
class Y, 
int l>
 
  242        return std::make_shared<SeqSOR<M,X,Y,l>>
 
  251    template<
class M, 
class X, 
class Y, 
int l>
 
  258        return std::make_shared<SeqJac<M,X,Y,l>>
 
  266    template<
class X, 
class Y>
 
  271      static inline std::shared_ptr<Richardson<X,Y>> 
construct(Arguments& args)
 
  273        return std::make_shared<Richardson<X,Y>>
 
  274          (args.getArgs().relaxationFactor);
 
  279    template<
class M, 
class X, 
class Y>
 
  280    class ConstructionArgs<
SeqILU<M,X,Y> >
 
  284      ConstructionArgs(
int n=0)
 
  306    template<
class M, 
class X, 
class Y>
 
  309      typedef ConstructionArgs<SeqILU<M,X,Y> > 
Arguments;
 
  311      static inline std::shared_ptr<SeqILU<M,X,Y>> 
construct(Arguments& args)
 
  313        return std::make_shared<SeqILU<M,X,Y>>
 
  314          (args.getMatrix(), args.getN(), args.getArgs().relaxationFactor);
 
  321    template<
class M, 
class X, 
class Y, 
class C>
 
  324      typedef DefaultParallelConstructionArgs<M,C> 
Arguments;
 
  326      static inline std::shared_ptr<ParSSOR<M,X,Y,C>> 
construct(Arguments& args)
 
  328        return std::make_shared<ParSSOR<M,X,Y,C>>
 
  329          (args.getMatrix(), args.getArgs().iterations,
 
  330           args.getArgs().relaxationFactor, args.getComm());
 
  334    template<
class X, 
class Y, 
class C, 
class T>
 
  337      typedef DefaultParallelConstructionArgs<T,C> 
Arguments;
 
  339      static inline std::shared_ptr<BlockPreconditioner<X,Y,C,T>> 
construct(
Arguments& args)
 
  341        auto seqPrec = SeqConstructionTraits::construct(args);
 
  342        return std::make_shared<BlockPreconditioner<X,Y,C,T>> (seqPrec, args.getComm());
 
  346    template<
class C, 
class T>
 
  347    struct ConstructionTraits<NonoverlappingBlockPreconditioner<C,T> >
 
  349      typedef DefaultParallelConstructionArgs<T,C> 
Arguments;
 
  350      typedef ConstructionTraits<T> SeqConstructionTraits;
 
  351      static inline std::shared_ptr<NonoverlappingBlockPreconditioner<C,T>> 
construct(
Arguments& args)
 
  353        auto seqPrec = SeqConstructionTraits::construct(args);
 
  354        return std::make_shared<NonoverlappingBlockPreconditioner<C,T>> (seqPrec, args.getComm());
 
  372      typedef typename Smoother::range_type Range;
 
  373      typedef typename Smoother::domain_type Domain;
 
  382      static void preSmooth(Smoother& smoother, Domain& v, 
const Range& d)
 
  394      static void postSmooth(Smoother& smoother, Domain& v, 
const Range& d)
 
  405    template<
typename LevelContext>
 
  406    void presmooth(LevelContext& levelContext, 
size_t steps)
 
  408        for(std::size_t i=0; i < steps; ++i) {
 
  411            ::preSmooth(*levelContext.smoother, *levelContext.lhs,
 
  414          *levelContext.update += *levelContext.lhs;
 
  417          levelContext.matrix->applyscaleadd(-1, *levelContext.lhs, *levelContext.rhs);
 
  418          levelContext.pinfo->project(*levelContext.rhs);
 
  427    template<
typename LevelContext>
 
  430        for(std::size_t i=0; i < steps; ++i) {
 
  432          levelContext.matrix->applyscaleadd(-1, *levelContext.lhs,
 
  435          levelContext.pinfo->project(*levelContext.rhs);
 
  437            ::postSmooth(*levelContext.smoother, *levelContext.lhs, *levelContext.rhs);
 
  439          *levelContext.update += *levelContext.lhs;
 
  443    template<
class M, 
class X, 
class Y, 
int l>
 
  444    struct SmootherApplier<
SeqSOR<M,X,Y,l> >
 
  447      typedef typename Smoother::range_type Range;
 
  448      typedef typename Smoother::domain_type Domain;
 
  450      static void preSmooth(Smoother& smoother, Domain& v, Range& d)
 
  452        smoother.template apply<true>(v,d);
 
  456      static void postSmooth(Smoother& smoother, Domain& v, Range& d)
 
  458        smoother.template apply<false>(v,d);
 
  462    template<
class M, 
class X, 
class Y, 
class C, 
int l>
 
  463    struct SmootherApplier<BlockPreconditioner<X,Y,C,SeqSOR<M,X,Y,l> > >
 
  465      typedef BlockPreconditioner<X,Y,C,SeqSOR<M,X,Y,l> > Smoother;
 
  466      typedef typename Smoother::range_type Range;
 
  467      typedef typename Smoother::domain_type Domain;
 
  469      static void preSmooth(Smoother& smoother, Domain& v, Range& d)
 
  471        smoother.template apply<true>(v,d);
 
  475      static void postSmooth(Smoother& smoother, Domain& v, Range& d)
 
  477        smoother.template apply<false>(v,d);
 
  481    template<
class M, 
class X, 
class Y, 
class C, 
int l>
 
  482    struct SmootherApplier<NonoverlappingBlockPreconditioner<C,SeqSOR<M,X,Y,l> > >
 
  484      typedef NonoverlappingBlockPreconditioner<C,SeqSOR<M,X,Y,l> > Smoother;
 
  485      typedef typename Smoother::range_type Range;
 
  486      typedef typename Smoother::domain_type Domain;
 
  488      static void preSmooth(Smoother& smoother, Domain& v, Range& d)
 
  490        smoother.template apply<true>(v,d);
 
  494      static void postSmooth(Smoother& smoother, Domain& v, Range& d)
 
  496        smoother.template apply<false>(v,d);
 
  503  template<
class M, 
class X, 
class MO, 
class MS, 
class A>
 
  504  class SeqOverlappingSchwarz;
 
  506  struct MultiplicativeSchwarzMode;
 
  510    template<
class M, 
class X, 
class MS, 
class TA>
 
  511    struct SmootherApplier<SeqOverlappingSchwarz<M,X,MultiplicativeSchwarzMode,
 
  514      typedef SeqOverlappingSchwarz<M,X,MultiplicativeSchwarzMode,MS,TA> Smoother;
 
  515      typedef typename Smoother::range_type Range;
 
  516      typedef typename Smoother::domain_type Domain;
 
  518      static void preSmooth(Smoother& smoother, Domain& v, 
const Range& d)
 
  520        smoother.template apply<true>(v,d);
 
  524      static void postSmooth(Smoother& smoother, Domain& v, 
const Range& d)
 
  526        smoother.template apply<false>(v,d);
 
  535    struct SeqOverlappingSchwarzSmootherArgs
 
  536      : 
public DefaultSmootherArgs<T>
 
  543      SeqOverlappingSchwarzSmootherArgs(Overlap overlap_=
vertex,
 
  544                                        bool onthefly_=
false)
 
  545        : overlap(overlap_), onthefly(onthefly_)
 
  549    template<
class M, 
class X, 
class TM, 
class TS, 
class TA>
 
  550    struct SmootherTraits<SeqOverlappingSchwarz<M,X,TM,TS,TA> >
 
  552      typedef  SeqOverlappingSchwarzSmootherArgs<typename M::field_type> Arguments;
 
  555    template<
class M, 
class X, 
class TM, 
class TS, 
class TA>
 
  556    class ConstructionArgs<SeqOverlappingSchwarz<M,X,TM,TS,TA> >
 
  557      : 
public DefaultConstructionArgs<SeqOverlappingSchwarz<M,X,TM,TS,TA> >
 
  559      typedef DefaultConstructionArgs<SeqOverlappingSchwarz<M,X,TM,TS,TA> > Father;
 
  566      typedef typename Vector::value_type Subdomain;
 
  568      virtual void setMatrix(
const M& matrix, 
const AggregatesMap& amap)
 
  570        Father::setMatrix(matrix);
 
  572        std::vector<bool> visited(amap.noVertices(), 
false);
 
  573        typedef IteratorPropertyMap<std::vector<bool>::iterator,IdentityMap> VisitedMapType;
 
  574        VisitedMapType visitedMap(visited.begin());
 
  576        MatrixGraph<const M> graph(matrix);
 
  578        typedef SeqOverlappingSchwarzSmootherArgs<typename M::field_type> SmootherArgs;
 
  580        switch(Father::getArgs().overlap) {
 
  583          VertexAdder visitor(subdomains, amap);
 
  584          createSubdomains(matrix, graph, amap, visitor,  visitedMap);
 
  587        case SmootherArgs::pairwise :
 
  589          createPairDomains(graph);
 
  592        case SmootherArgs::aggregate :
 
  594          AggregateAdder<VisitedMapType> visitor(subdomains, amap, graph, visitedMap);
 
  595          createSubdomains(matrix, graph, amap, visitor, visitedMap);
 
  600          createSubdomains(matrix, graph, amap, visitor, visitedMap);
 
  603          DUNE_THROW(NotImplemented, 
"This overlapping scheme is not supported!");
 
  606      void setMatrix(
const M& matrix)
 
  608        Father::setMatrix(matrix);
 
  611        AggregatesMap amap(matrix.N());
 
  612        VertexDescriptor v=0;
 
  613        for(
typename AggregatesMap::iterator iter=amap.begin();
 
  614            iter!=amap.end(); ++iter)
 
  617        std::vector<bool> visited(amap.noVertices(), 
false);
 
  618        typedef IteratorPropertyMap<std::vector<bool>::iterator,IdentityMap> VisitedMapType;
 
  619        VisitedMapType visitedMap(visited.begin());
 
  621        MatrixGraph<const M> graph(matrix);
 
  623        typedef SeqOverlappingSchwarzSmootherArgs<typename M::field_type> SmootherArgs;
 
  625        switch(Father::getArgs().overlap) {
 
  628          VertexAdder visitor(subdomains, amap);
 
  629          createSubdomains(matrix, graph, amap, visitor,  visitedMap);
 
  632        case SmootherArgs::aggregate :
 
  634          DUNE_THROW(NotImplemented, 
"Aggregate overlap is not supported yet");
 
  641        case SmootherArgs::pairwise :
 
  643          createPairDomains(graph);
 
  648          createSubdomains(matrix, graph, amap, visitor, visitedMap);
 
  653      const Vector& getSubDomains()
 
  661        VertexAdder(Vector& subdomains_, 
const AggregatesMap& aggregates_)
 
  662          : subdomains(subdomains_), 
max(-1), subdomain(-1), aggregates(aggregates_)
 
  665        void operator()(
const T& edge)
 
  668            subdomains[subdomain].insert(edge.target());
 
  670        int setAggregate(
const AggregateDescriptor& aggregate_)
 
  672          subdomain=aggregate_;
 
  673          max = std::max(subdomain, aggregate_);
 
  676        int noSubdomains()
 const 
  682        AggregateDescriptor 
max;
 
  683        AggregateDescriptor subdomain;
 
  684        const AggregatesMap& aggregates;
 
  689        void operator()(
const T& edge)
 
  691        int setAggregate(
const AggregateDescriptor& aggregate_)
 
  695        int noSubdomains()
 const 
  702      struct AggregateAdder
 
  704        AggregateAdder(Vector& subdomains_, 
const AggregatesMap& aggregates_,
 
  705                       const MatrixGraph<const M>& graph_, VM& visitedMap_)
 
  706          : subdomains(subdomains_), subdomain(-1), aggregates(aggregates_),
 
  707            adder(subdomains_, aggregates_), graph(graph_), visitedMap(visitedMap_)
 
  710        void operator()(
const T& edge)
 
  712          subdomains[subdomain].insert(edge.target());
 
  717            assert(aggregates[edge.target()]!=aggregate);
 
  719            aggregates.template breadthFirstSearch<true,false>(edge.target(), aggregate,
 
  720                                                               graph, vlist, adder, adder,
 
  725        int setAggregate(
const AggregateDescriptor& aggregate_)
 
  727          adder.setAggregate(aggregate_);
 
  728          aggregate=aggregate_;
 
  731        int noSubdomains()
 const 
  737        AggregateDescriptor aggregate;
 
  740        const AggregatesMap& aggregates;
 
  742        const MatrixGraph<const M>& graph;
 
  746      void createPairDomains(
const MatrixGraph<const M>& graph)
 
  750        typedef typename M::size_type size_type;
 
  752        std::set<std::pair<size_type,size_type> > pairs;
 
  754        for(VIter v=graph.begin(), ve=graph.end(); ve != v; ++v)
 
  755          for(EIter e = v.begin(), ee=v.end(); ee!=e; ++e)
 
  758            if(e.source()<e.target())
 
  759              pairs.insert(std::make_pair(e.source(),e.target()));
 
  761              pairs.insert(std::make_pair(e.target(),e.source()));
 
  765        subdomains.resize(pairs.size());
 
  766        Dune::dinfo <<std::endl<< 
"Created "<<pairs.size()<<
" ("<<total<<
") pair domains"<<std::endl<<std::endl;
 
  767        typedef typename std::set<std::pair<size_type,size_type> >::const_iterator SIter;
 
  768        typename Vector::iterator subdomain=subdomains.begin();
 
  770        for(SIter s=pairs.begin(), se =pairs.end(); se!=s; ++s)
 
  772          subdomain->insert(s->first);
 
  773          subdomain->insert(s->second);
 
  776        std::size_t minsize=10000;
 
  777        std::size_t maxsize=0;
 
  779        for(
typename Vector::size_type i=0; i < subdomains.size(); ++i) {
 
  780          sum+=subdomains[i].size();
 
  781          minsize=std::min(minsize, subdomains[i].
size());
 
  782          maxsize=std::max(maxsize, subdomains[i].
size());
 
  784        Dune::dinfo<<
"Subdomain size: min="<<minsize<<
" max="<<maxsize<<
" avg="<<(sum/subdomains.size())
 
  785                   <<
" no="<<subdomains.size()<<std::endl;
 
  788      template<
class Visitor>
 
  789      void createSubdomains(
const M& matrix, 
const MatrixGraph<const M>& graph,
 
  790                            const AggregatesMap& amap, Visitor& overlapVisitor,
 
  791                            IteratorPropertyMap<std::vector<bool>::iterator,IdentityMap>& visitedMap )
 
  798        AggregateDescriptor maxAggregate=0;
 
  800        for(std::size_t i=0; i < amap.noVertices(); ++i)
 
  804            maxAggregate = std::max(maxAggregate, amap[i]);
 
  806        subdomains.resize(maxAggregate+1+isolated);
 
  809        for(
typename Vector::size_type i=0; i < subdomains.size(); ++i)
 
  810          subdomains[i].clear();
 
  815        VertexAdder aggregateVisitor(subdomains, amap);
 
  817        for(VertexDescriptor i=0; i < amap.noVertices(); ++i)
 
  818          if(!
get(visitedMap, i)) {
 
  819            AggregateDescriptor aggregate=amap[i];
 
  823              subdomains.push_back(Subdomain());
 
  824              aggregate=subdomains.size()-1;
 
  826            overlapVisitor.setAggregate(aggregate);
 
  827            aggregateVisitor.setAggregate(aggregate);
 
  828            subdomains[aggregate].insert(i);
 
  830            amap.template breadthFirstSearch<false,false>(i, aggregate, graph, vlist, aggregateVisitor,
 
  831                                                          overlapVisitor, visitedMap);
 
  834        std::size_t minsize=10000;
 
  835        std::size_t maxsize=0;
 
  837        for(
typename Vector::size_type i=0; i < subdomains.size(); ++i) {
 
  838          sum+=subdomains[i].size();
 
  839          minsize=std::min(minsize, subdomains[i].
size());
 
  840          maxsize=std::max(maxsize, subdomains[i].
size());
 
  842        Dune::dinfo<<
"Subdomain size: min="<<minsize<<
" max="<<maxsize<<
" avg="<<(sum/subdomains.size())
 
  843                   <<
" no="<<subdomains.size()<<
" isolated="<<isolated<<std::endl;
 
  852    template<
class M, 
class X, 
class TM, 
class TS, 
class TA>
 
  853    struct ConstructionTraits<SeqOverlappingSchwarz<M,X,TM,TS,TA> >
 
  855      typedef ConstructionArgs<SeqOverlappingSchwarz<M,X,TM,TS,TA> > 
Arguments;
 
  857      static inline std::shared_ptr<SeqOverlappingSchwarz<M,X,TM,TS,TA>> 
construct(
Arguments& args)
 
  859        return std::make_shared<SeqOverlappingSchwarz<M,X,TM,TS,TA>>
 
  861           args.getSubDomains(),
 
  862           args.getArgs().relaxationFactor,
 
  863           args.getArgs().onthefly);
 
Provides classes for the Coloring process of AMG.
 
Class providing information about the mapping of the vertices onto aggregates.
Definition: aggregates.hh:566
 
Construction Arguments for the default smoothers.
Definition: smoother.hh:93
 
VertexIteratorT< const MatrixGraph< Matrix > > ConstVertexIterator
The constant vertex iterator type.
Definition: graph.hh:308
 
M::size_type VertexDescriptor
The vertex descriptor.
Definition: graph.hh:73
 
EdgeIteratorT< const MatrixGraph< Matrix > > ConstEdgeIterator
The constant edge iterator type.
Definition: graph.hh:298
 
Block parallel preconditioner.
Definition: schwarz.hh:278
 
Richardson preconditioner.
Definition: preconditioners.hh:878
 
Sequential ILU preconditioner.
Definition: preconditioners.hh:697
 
The sequential jacobian preconditioner.
Definition: preconditioners.hh:413
 
std::vector< subdomain_type, typename std::allocator_traits< TA >::template rebind_alloc< subdomain_type > > subdomain_vector
The vector type containing the subdomain to row index mapping.
Definition: overlappingschwarz.hh:797
 
Sequential SOR preconditioner.
Definition: preconditioners.hh:262
 
Sequential SSOR preconditioner.
Definition: preconditioners.hh:142
 
Helper classes for the construction of classes without empty constructor.
 
Type traits to determine the type of reals (when working with complex numbers)
 
#define DUNE_THROW(E,...)
Definition: exceptions.hh:314
 
constexpr GeometryType none(unsigned int dim)
Returns a GeometryType representing a singular of dimension dim.
Definition: type.hh:471
 
constexpr GeometryType vertex
GeometryType representing a vertex.
Definition: type.hh:492
 
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:485
 
void presmooth(LevelContext &levelContext, size_t steps)
Apply pre smoothing on the current level.
Definition: smoother.hh:406
 
V AggregateDescriptor
The aggregate descriptor type.
Definition: aggregates.hh:586
 
static const V ISOLATED
Identifier of isolated vertices.
Definition: aggregates.hh:577
 
DefaultSmootherArgs()
Default constructor.
Definition: smoother.hh:56
 
const void * Arguments
A type holding all the arguments needed to call the constructor.
Definition: construction.hh:44
 
static void postSmooth(Smoother &smoother, Domain &v, const Range &d)
apply post smoothing in forward direction
Definition: smoother.hh:394
 
static std::shared_ptr< T > construct(Arguments &args)
Construct an object with the specified arguments.
Definition: construction.hh:52
 
FieldTraits< T >::real_type RelaxationFactor
The type of the relaxation factor.
Definition: smoother.hh:42
 
SLList< VertexDescriptor, Allocator > VertexList
The type of a single linked list of vertex descriptors.
Definition: aggregates.hh:598
 
void postsmooth(LevelContext &levelContext, size_t steps)
Apply post smoothing on the current level.
Definition: smoother.hh:428
 
RelaxationFactor relaxationFactor
The relaxation factor to use.
Definition: smoother.hh:51
 
static void preSmooth(Smoother &smoother, Domain &v, const Range &d)
apply pre smoothing in forward direction
Definition: smoother.hh:382
 
int iterations
The number of iterations to perform.
Definition: smoother.hh:47
 
DInfoType dinfo(std::cout)
Stream for informative output.
Definition: stdstreams.hh:141
 
PartitionSet<... > Overlap
Type of PartitionSet for the overlap partition.
Definition: partitionset.hh:249
 
Dune namespace.
Definition: alignedallocator.hh:13
 
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
 
constexpr auto get(std::integer_sequence< T, II... >, std::integral_constant< std::size_t, pos >={})
Return the entry at position pos of the given sequence.
Definition: integersequence.hh:22
 
Define general preconditioner interface.
 
Traits class for generically constructing non default constructable types.
Definition: construction.hh:39
 
The default class for the smoother arguments.
Definition: smoother.hh:38
 
Helper class for applying the smoothers.
Definition: smoother.hh:370
 
Traits class for getting the attribute class of a smoother.
Definition: smoother.hh:66