5#ifndef DUNE_AMG_AGGREGATES_HH 
    6#define DUNE_AMG_AGGREGATES_HH 
   12#include "combinedfunctor.hh" 
   86        this->setMaxDistance(diameter-1);
 
   91          this->setMaxDistance(this->maxDistance()+diameter-1);
 
   93        this->setMinAggregateSize(csize);
 
   94        this->setMaxAggregateSize(
static_cast<std::size_t
>(csize*1.5));
 
  110        this->setMaxDistance(this->maxDistance()+dim-1);
 
  115    std::ostream& operator<<(std::ostream& os, 
const AggregationCriterion<T>& criterion)
 
  117      os<<
"{ maxdistance="<<criterion.maxDistance()<<
" minAggregateSize=" 
  118      <<criterion.minAggregateSize()<< 
" maxAggregateSize="<<criterion.maxAggregateSize()
 
  119      <<
" connectivity="<<criterion.maxConnectivity()<<
" debugLevel="<<criterion.debugLevel()<<
"}";
 
  134    template<
class M, 
class N>
 
  158      void init(
const Matrix* matrix);
 
  160      void initRow(
const Row& row, 
int index);
 
  162      void examine(
const ColIter& col);
 
  165      void examine(G& graph, 
const typename G::EdgeIterator& edge, 
const ColIter& col);
 
  182      typedef typename FieldTraits<field_type>::real_type real_type;
 
  190      std::vector<real_type> vals_;
 
  191      typename std::vector<real_type>::iterator valIter_;
 
  196    template<
class M, 
class N>
 
  202    template<
class M, 
class N>
 
  203    inline void SymmetricMatrixDependency<M,N>::initRow(
const Row& row, 
int index)
 
  206      vals_.assign(row.size(), 0.0);
 
  207      assert(vals_.size()==row.size());
 
  208      valIter_=vals_.begin();
 
  211      diagonal_=norm_(row[index]);
 
  215    template<
class M, 
class N>
 
  216    inline void SymmetricMatrixDependency<M,N>::examine(
const ColIter& col)
 
  220      real_type eij = norm_(*col);
 
  221      if(!N::is_sign_preserving || eij<0)  
 
  223        *valIter_ = eij/diagonal_*eij/norm_(matrix_->operator[](col.index())[col.index()]);
 
  224        maxValue_ = 
max(maxValue_, *valIter_);
 
  230    template<
class M, 
class N>
 
  232    inline void SymmetricMatrixDependency<M,N>::examine(G&, 
const typename G::EdgeIterator& edge, 
const ColIter&)
 
  234      if(*valIter_ > alpha() * maxValue_) {
 
  235        edge.properties().setDepends();
 
  236        edge.properties().setInfluences();
 
  241    template<
class M, 
class N>
 
  242    inline bool SymmetricMatrixDependency<M,N>::isIsolated()
 
  246      valIter_=vals_.begin();
 
  247      return maxValue_  < beta();
 
  253    template<
class M, 
class N>
 
  277      void init(
const Matrix* matrix);
 
  279      void initRow(
const Row& row, 
int index);
 
  281      void examine(
const ColIter& col);
 
  284      void examine(G& graph, 
const typename G::EdgeIterator& edge, 
const ColIter& col);
 
  301      typedef typename FieldTraits<field_type>::real_type real_type;
 
  314    template<
class M, 
class N>
 
  338      void init(
const Matrix* matrix);
 
  340      void initRow(
const Row& row, 
int index);
 
  342      void examine(
const ColIter& col);
 
  345      void examine(G& graph, 
const typename G::EdgeIterator& edge, 
const ColIter& col);
 
  362      typedef typename FieldTraits<field_type>::real_type real_type;
 
  371      void initRow(
const Row& row, 
int index, 
const std::true_type&);
 
  372      void initRow(
const Row& row, 
int index, 
const std::false_type&);
 
  384        is_sign_preserving = 
true 
  392      typename FieldTraits<typename M::field_type>::real_type 
operator()(
const M& m,
 
  395        typedef typename M::field_type field_type;
 
  396        typedef typename FieldTraits<field_type>::real_type real_type;
 
  397        static_assert( std::is_convertible<field_type, real_type >::value,
 
  398                  "use of diagonal norm in AMG not implemented for complex field_type");
 
  411        typedef typename FieldTraits<M>::real_type real_type;
 
  412        static_assert( std::is_convertible<M, real_type >::value,
 
  413                  "use of diagonal norm in AMG not implemented for complex field_type");
 
  422      static T signed_abs(
const T & v)
 
  429      static T signed_abs(
const std::complex<T> & v)
 
  433        return csgn(v) * std::abs(v);
 
  438      static T csgn(
const T & v)
 
  440        return (T(0) < v) - (v < T(0));
 
  445      static T csgn(std::complex<T> a)
 
  447        return csgn(a.real())+(a.real() == 0.0)*csgn(a.imag());
 
  468        is_sign_preserving = 
false 
  481          return m.infinity_norm();
 
  489        is_sign_preserving = 
false 
  496      typename FieldTraits<typename M::field_type>::real_type 
operator()(
const M& m)
 const 
  498        return m.frobenius_norm();
 
  505        is_sign_preserving = 
false 
  512      typename FieldTraits<typename M::field_type>::real_type 
operator()(
const M& m)
 const 
  523    template<
class M, 
class Norm>
 
  543    template<
class M, 
class Norm>
 
  606        template<
class EdgeIterator>
 
  607        void operator()([[maybe_unused]] 
const EdgeIterator& edge)
 const 
  640      template<
class M, 
class G, 
class C>
 
  641      std::tuple<int,int,int,int> 
buildAggregates(
const M& matrix, G& graph, 
const C& criterion,
 
  661      template<
bool reset, 
class G, 
class F, 
class VM>
 
  666                                     VM& visitedMap) 
const;
 
  691      template<
bool remove, 
bool reset, 
class G, 
class L, 
class F1, 
class F2, 
class VM>
 
  694                                     const G& graph, L& visited, F1& aggregateVisitor,
 
  695                                     F2& nonAggregateVisitor,
 
  696                                     VM& visitedMap) 
const;
 
  731      const_iterator begin()
 const 
  736      const_iterator end()
 const 
  756      AggregatesMap<V>& operator=(
const AggregatesMap<V>&) = 
delete;
 
  766      std::size_t noVertices_;
 
  772    template<
class G, 
class C>
 
  774                         const typename C::Matrix& matrix,
 
  782    template<
class G, 
class S>
 
  791      typedef G MatrixGraph;
 
  826                VertexSet& connectivity, std::vector<Vertex>& front_);
 
  860      typename VertexSet::size_type 
size();
 
  907      std::vector<Vertex>& front_;
 
  957      template<
class M, 
class C>
 
  958      std::tuple<int,int,int,int> 
build(
const M& m, G& graph,
 
  976      typedef std::set<Vertex,std::less<Vertex>,
Allocator> VertexSet;
 
  981      typedef std::size_t* SphereMap;
 
  996      std::vector<Vertex> front_;
 
 1001      VertexSet connected_;
 
 1014        static const Vertex NullEntry;
 
 1022        enum { N = 1300000 };
 
 1056                                    const AggregatesMap<Vertex>& aggregates,
 
 1064      class AggregateVisitor
 
 1124      class FrontNeighbourCounter : 
public Counter
 
 1148      class TwoWayCounter : 
public Counter
 
 1171      class OneWayCounter : 
public Counter
 
 1189                            const AggregatesMap<Vertex>& aggregates) 
const;
 
 1197      class ConnectivityCounter : 
public Counter
 
 1211        const VertexSet& connected_;
 
 1256      class DependencyCounter : 
public Counter
 
 1288        std::vector<Vertex>& front_;
 
 1403    template<
class M, 
class N>
 
 1409    template<
class M, 
class N>
 
 1410    inline void SymmetricDependency<M,N>::initRow(
const Row& row, 
int index)
 
 1412      initRow(row, index, std::is_convertible<field_type, real_type>());
 
 1415    template<
class M, 
class N>
 
 1416    inline void SymmetricDependency<M,N>::initRow(
const Row& row, 
int index, 
const std::false_type&)
 
 1418      DUNE_THROW(InvalidStateException, 
"field_type needs to convertible to real_type");
 
 1421    template<
class M, 
class N>
 
 1422    inline void SymmetricDependency<M,N>::initRow([[maybe_unused]] 
const Row& row, 
int index, 
const std::true_type&)
 
 1427      diagonal_ = norm_(matrix_->operator[](row_)[row_]);
 
 1430    template<
class M, 
class N>
 
 1431    inline void SymmetricDependency<M,N>::examine(
const ColIter& col)
 
 1434      real_type eij = norm_(*col);
 
 1436        matrix_->operator[](col.index()).find(row_);
 
 1437      if ( opposite_entry == matrix_->operator[](col.index()).end() )
 
 1442      real_type eji = norm_(*opposite_entry);
 
 1445      if(!N::is_sign_preserving || eij<0 || eji<0)
 
 1446        maxValue_ = 
max(maxValue_,
 
 1447                             eij /diagonal_ * eji/
 
 1448                             norm_(matrix_->operator[](col.index())[col.index()]));
 
 1451    template<
class M, 
class N>
 
 1453    inline void SymmetricDependency<M,N>::examine(G& graph, 
const typename G::EdgeIterator& edge, 
const ColIter& col)
 
 1455      real_type eij = norm_(*col);
 
 1457        matrix_->operator[](col.index()).find(row_);
 
 1459      if ( opposite_entry == matrix_->operator[](col.index()).end() )
 
 1464      real_type eji = norm_(*opposite_entry);
 
 1466      if(!N::is_sign_preserving || (eij<0 || eji<0))
 
 1467        if(eji / norm_(matrix_->operator[](edge.target())[edge.target()]) *
 
 1468           eij/ diagonal_ > alpha() * maxValue_) {
 
 1469          edge.properties().setDepends();
 
 1470          edge.properties().setInfluences();
 
 1471          typename G::EdgeProperties& other = graph.getEdgeProperties(edge.target(), edge.source());
 
 1472          other.setInfluences();
 
 1477    template<
class M, 
class N>
 
 1478    inline bool SymmetricDependency<M,N>::isIsolated()
 
 1480      return maxValue_  < beta();
 
 1484    template<
class M, 
class N>
 
 1485    inline void Dependency<M,N>::init(
const Matrix* matrix)
 
 1490    template<
class M, 
class N>
 
 1491    inline void Dependency<M,N>::initRow([[maybe_unused]] 
const Row& row, 
int index)
 
 1496      diagonal_ = norm_(matrix_->operator[](row_)[row_]);
 
 1499    template<
class M, 
class N>
 
 1500    inline void Dependency<M,N>::examine(
const ColIter& col)
 
 1503      maxValue_ = 
max(maxValue_, -norm_(*col));
 
 1506    template<
class M, 
class N>
 
 1508    inline void Dependency<M,N>::examine(G& graph, 
const typename G::EdgeIterator& edge, 
const ColIter& col)
 
 1510      if(-norm_(*col) >= maxValue_ * alpha()) {
 
 1511        edge.properties().setDepends();
 
 1512        typedef typename G::EdgeDescriptor ED;
 
 1513        ED e= graph.findEdge(edge.target(), edge.source());
 
 1516          typename G::EdgeProperties& other = graph.getEdgeProperties(e);
 
 1517          other.setInfluences();
 
 1522    template<
class M, 
class N>
 
 1523    inline bool Dependency<M,N>::isIsolated()
 
 1525      return maxValue_  < beta() * diagonal_;
 
 1528    template<
class G,
class S>
 
 1530                              VertexSet& connected, std::vector<Vertex>& 
front)
 
 1531      : vertices_(), id_(-1), graph_(graph), aggregates_(aggregates),
 
 1532        connected_(connected), front_(
front)
 
 1535    template<
class G,
class S>
 
 1543      throw "Not yet implemented";
 
 1551    template<
class G,
class S>
 
 1554      dvverb<<
"Connected cleared"<<std::endl;
 
 1557      connected_.insert(
vertex);
 
 1558      dvverb << 
" Inserting "<<
vertex<<
" size="<<connected_.size();
 
 1564    template<
class G,
class S>
 
 1567      vertices_.insert(
vertex);
 
 1570        front_.erase(std::lower_bound(front_.begin(), front_.end(), 
vertex));
 
 1574      const iterator end = graph_.endEdges(
vertex);
 
 1575      for(iterator edge = graph_.beginEdges(
vertex); edge != end; ++edge) {
 
 1576        dvverb << 
" Inserting "<<aggregates_[edge.target()];
 
 1577        connected_.insert(aggregates_[edge.target()]);
 
 1578        dvverb <<
" size="<<connected_.size();
 
 1580           !graph_.getVertexProperties(edge.target()).front())
 
 1582          front_.push_back(edge.target());
 
 1583          graph_.getVertexProperties(edge.target()).setFront();
 
 1587      std::sort(front_.begin(), front_.end());
 
 1590    template<
class G,
class S>
 
 1594      std::size_t oldsize = vertices_.size();
 
 1596      typedef typename std::vector<Vertex>::iterator Iterator;
 
 1598      typedef typename VertexSet::iterator SIterator;
 
 1600      SIterator pos=vertices_.begin();
 
 1601      std::vector<Vertex> newFront;
 
 1602      newFront.reserve(front_.capacity());
 
 1604      std::set_difference(front_.begin(), front_.end(), vertices.begin(), vertices.end(),
 
 1605                          std::back_inserter(newFront));
 
 1610        pos=vertices_.insert(pos,*
vertex);
 
 1611        vertices_.insert(*
vertex);
 
 1612        graph_.getVertexProperties(*vertex).resetFront(); 
 
 1613        aggregates_[*
vertex]=id_;
 
 1616        const iterator end = graph_.endEdges(*
vertex);
 
 1617        for(iterator edge = graph_.beginEdges(*
vertex); edge != end; ++edge) {
 
 1618          dvverb << 
" Inserting "<<aggregates_[edge.target()];
 
 1619          connected_.insert(aggregates_[edge.target()]);
 
 1621             !graph_.getVertexProperties(edge.target()).front())
 
 1623            front_.push_back(edge.target());
 
 1624            graph_.getVertexProperties(edge.target()).setFront();
 
 1626          dvverb <<
" size="<<connected_.size();
 
 1630      std::sort(front_.begin(), front_.end());
 
 1631      assert(oldsize+vertices.size()==vertices_.size());
 
 1633    template<
class G,
class S>
 
 1641    template<
class G,
class S>
 
 1642    inline typename Aggregate<G,S>::VertexSet::size_type
 
 1645      return vertices_.size();
 
 1648    template<
class G,
class S>
 
 1649    inline typename Aggregate<G,S>::VertexSet::size_type
 
 1652      return connected_.size();
 
 1655    template<
class G,
class S>
 
 1661    template<
class G,
class S>
 
 1664      return vertices_.begin();
 
 1667    template<
class G,
class S>
 
 1670      return vertices_.end();
 
 1688        delete[] aggregates_;
 
 1695      allocate(noVertices);
 
 1708      noVertices_ = noVertices;
 
 1710      for(std::size_t i=0; i < noVertices; i++)
 
 1711        aggregates_[i]=UNAGGREGATED;
 
 1717      assert(aggregates_ != 0);
 
 1718      delete[] aggregates_;
 
 1726      return aggregates_[v];
 
 1733      return aggregates_[v];
 
 1737    template<
bool reset, 
class G, 
class F,
class VM>
 
 1740                                                            const G& graph, F& aggregateVisitor,
 
 1741                                                            VM& visitedMap)
 const 
 1745      DummyEdgeVisitor dummy;
 
 1746      return breadthFirstSearch<true,reset>(start, aggregate, graph, vlist, aggregateVisitor, dummy, visitedMap);
 
 1750    template<
bool remove, 
bool reset, 
class G, 
class L, 
class F1, 
class F2, 
class VM>
 
 1755                                                     F1& aggregateVisitor,
 
 1756                                                     F2& nonAggregateVisitor,
 
 1757                                                     VM& visitedMap)
 const 
 1759      typedef typename L::const_iterator ListIterator;
 
 1760      int visitedSpheres = 0;
 
 1762      visited.push_back(start);
 
 1763      put(visitedMap, start, 
true);
 
 1765      ListIterator current = visited.begin();
 
 1766      ListIterator end = visited.end();
 
 1767      std::size_t i=0, 
size=visited.size();
 
 1771      while(current != end) {
 
 1773        for(; i<
size; ++current, ++i) {
 
 1774          typedef typename G::ConstEdgeIterator EdgeIterator;
 
 1775          const EdgeIterator endEdge = graph.endEdges(*current);
 
 1777          for(EdgeIterator edge = graph.beginEdges(*current);
 
 1778              edge != endEdge; ++edge) {
 
 1780            if(aggregates_[edge.target()]==aggregate) {
 
 1781              if(!
get(visitedMap, edge.target())) {
 
 1782                put(visitedMap, edge.target(), 
true);
 
 1783                visited.push_back(edge.target());
 
 1784                aggregateVisitor(edge);
 
 1787              nonAggregateVisitor(edge);
 
 1790        end = visited.end();
 
 1791        size = visited.size();
 
 1797        for(current = visited.begin(); current != end; ++current)
 
 1798          put(visitedMap, *current, 
false);
 
 1804      return visitedSpheres;
 
 1809      : graph_(0), aggregate_(0), front_(), connected_(), size_(-1)
 
 1818    template<
class G, 
class C>
 
 1820                         const typename C::Matrix& matrix,
 
 1821                         C criterion, 
bool firstlevel)
 
 1824      typedef typename C::Matrix Matrix;
 
 1825      typedef typename G::VertexIterator VertexIterator;
 
 1827      criterion.init(&matrix);
 
 1832        const Row& row = matrix[*
vertex];
 
 1837        criterion.initRow(row, *
vertex);
 
 1842        ColIterator end = row.end();
 
 1843        typename FieldTraits<typename Matrix::field_type>::real_type absoffdiag=0.;
 
 1847          for(ColIterator col = row.begin(); col != end; ++col)
 
 1848            if(col.index()!=*
vertex) {
 
 1849              criterion.examine(col);
 
 1850              absoffdiag = 
max(absoffdiag, Impl::asMatrix(*col).frobenius_norm());
 
 1854            vertex.properties().setExcludedBorder();
 
 1857          for(ColIterator col = row.begin(); col != end; ++col)
 
 1859              criterion.examine(col);
 
 1865        if(criterion.isIsolated()) {
 
 1867          vertex.properties().setIsolated();
 
 1870          auto eEnd = 
vertex.end();
 
 1871          auto col = matrix[*
vertex].begin();
 
 1873          for(
auto edge = 
vertex.begin(); edge!= eEnd; ++edge, ++col) {
 
 1875            while(col.index()!=edge.target())
 
 1877            criterion.examine(graph, edge, col);
 
 1887    inline Aggregator<G>::AggregateVisitor<V>::AggregateVisitor(
const AggregatesMap<Vertex>& aggregates,
 
 1889      : aggregates_(aggregates), aggregate_(aggregate), visitor_(&visitor)
 
 1896      if(aggregates_[edge.target()]==aggregate_)
 
 1897        visitor_->operator()(edge);
 
 1902    inline void Aggregator<G>::visitAggregateNeighbours(
const Vertex& 
vertex,
 
 1904                                                        const AggregatesMap<Vertex>& aggregates,
 
 1908      AggregateVisitor<V> v(aggregates, aggregate, visitor);
 
 1914    inline Aggregator<G>::Counter::Counter()
 
 1919    inline void Aggregator<G>::Counter::increment()
 
 1925    inline void Aggregator<G>::Counter::decrement()
 
 1930    inline int Aggregator<G>::Counter::value()
 
 1938      if(edge.properties().isTwoWay())
 
 1939        Counter::increment();
 
 1944                                         const AggregatesMap<Vertex>& aggregates)
 const 
 1946      TwoWayCounter counter;
 
 1947      visitAggregateNeighbours(
vertex, aggregate, aggregates, counter);
 
 1948      return counter.value();
 
 1953                                         const AggregatesMap<Vertex>& aggregates)
 const 
 1955      OneWayCounter counter;
 
 1956      visitAggregateNeighbours(
vertex, aggregate, aggregates, counter);
 
 1957      return counter.value();
 
 1963      if(edge.properties().isOneWay())
 
 1964        Counter::increment();
 
 1968    inline Aggregator<G>::ConnectivityCounter::ConnectivityCounter(
const VertexSet& connected,
 
 1969                                                                   const AggregatesMap<Vertex>& aggregates)
 
 1970      : Counter(), connected_(connected), aggregates_(aggregates)
 
 1979        Counter::increment();
 
 1981        Counter::increment();
 
 1982        Counter::increment();
 
 1987    inline double Aggregator<G>::connectivity(
const Vertex& 
vertex, 
const AggregatesMap<Vertex>& aggregates)
 const 
 1989      ConnectivityCounter counter(connected_, aggregates);
 
 1991      return (
double)counter.value()/noNeighbours;
 
 1995    inline Aggregator<G>::DependencyCounter::DependencyCounter()
 
 2002      if(edge.properties().depends())
 
 2003        Counter::increment();
 
 2004      if(edge.properties().influences())
 
 2005        Counter::increment();
 
 2009    int Aggregator<G>::unusedNeighbours(
const Vertex& 
vertex, 
const AggregatesMap<Vertex>& aggregates)
 const 
 2015    std::pair<int,int> Aggregator<G>::neighbours(
const Vertex& 
vertex,
 
 2017                                                 const AggregatesMap<Vertex>& aggregates)
 const 
 2019      DependencyCounter unused, aggregated;
 
 2020      typedef AggregateVisitor<DependencyCounter> CounterT;
 
 2021      typedef std::tuple<CounterT,CounterT> CounterTuple;
 
 2024      return std::make_pair(unused.value(), aggregated.value());
 
 2031      DependencyCounter counter;
 
 2032      visitAggregateNeighbours(
vertex, aggregate, aggregates, counter);
 
 2033      return counter.value();
 
 2037    std::size_t Aggregator<G>::distance(
const Vertex& 
vertex, 
const AggregatesMap<Vertex>& aggregates)
 
 2040      typename PropertyMapTypeSelector<VertexVisitedTag,G>::Type visitedMap = 
get(VertexVisitedTag(), *graph_);
 
 2042      typename AggregatesMap<Vertex>::DummyEdgeVisitor dummy;
 
 2043      return aggregates.template breadthFirstSearch<true,true>(
vertex,
 
 2044                                                               aggregate_->
id(), *graph_,
 
 2045                                                               vlist, dummy, dummy, visitedMap);
 
 2049    inline Aggregator<G>::FrontMarker::FrontMarker(std::vector<Vertex>& 
front, 
MatrixGraph& graph)
 
 2050      : front_(
front), graph_(graph)
 
 2056      Vertex target = edge.target();
 
 2058      if(!graph_.getVertexProperties(target).front()) {
 
 2059        front_.push_back(target);
 
 2060        graph_.getVertexProperties(target).setFront();
 
 2068      Dune::dvverb<<
" Admissible not yet implemented!"<<std::endl;
 
 2075      Iterator vend = graph_->endEdges(
vertex);
 
 2076      for(Iterator edge = graph_->beginEdges(
vertex); edge != vend; ++edge) {
 
 2078        if(edge.properties().isStrong()
 
 2079           && aggregates[edge.target()]==aggregate)
 
 2082          Iterator edge1 = edge;
 
 2083          for(++edge1; edge1 != vend; ++edge1) {
 
 2085            if(edge1.properties().isStrong()
 
 2086               && aggregates[edge.target()]==aggregate)
 
 2091              Iterator v2end = graph_->endEdges(edge.target());
 
 2092              for(Iterator edge2 = graph_->beginEdges(edge.target()); edge2 != v2end; ++edge2) {
 
 2093                if(edge2.target()==edge1.target() &&
 
 2094                   edge2.properties().isStrong()) {
 
 2110      vend = graph_->endEdges(
vertex);
 
 2111      for(Iterator edge = graph_->beginEdges(
vertex); edge != vend; ++edge) {
 
 2113        if(edge.properties().isStrong()
 
 2114           && aggregates[edge.target()]==aggregate)
 
 2117          Iterator v1end = graph_->endEdges(edge.target());
 
 2119          for(Iterator edge1=graph_->beginEdges(edge.target()); edge1 != v1end; ++edge1) {
 
 2121            if(edge1.properties().isStrong()
 
 2122               && aggregates[edge1.target()]==aggregate)
 
 2126              Iterator v2end = graph_->endEdges(
vertex);
 
 2127              for(Iterator edge2 = graph_->beginEdges(
vertex); edge2 != v2end; ++edge2) {
 
 2128                if(edge2.target()==edge1.target()) {
 
 2129                  if(edge2.properties().isStrong())
 
 2146    void Aggregator<G>::unmarkFront()
 
 2148      typedef typename std::vector<Vertex>::const_iterator Iterator;
 
 2151        graph_->getVertexProperties(*vertex).resetFront();
 
 2158    Aggregator<G>::nonisoNeighbourAggregate(
const Vertex& 
vertex,
 
 2159                                            const AggregatesMap<Vertex>& aggregates,
 
 2160                                            SLList<Vertex>& neighbours)
 const 
 2163      Iterator end=graph_->beginEdges(
vertex);
 
 2166      for(Iterator edge=graph_->beginEdges(
vertex); edge!=end; ++edge)
 
 2169          neighbours.push_back(aggregates[edge.target()]);
 
 2174    inline typename G::VertexDescriptor Aggregator<G>::mergeNeighbour(
const Vertex& 
vertex, 
const AggregatesMap<Vertex>& aggregates)
 const 
 2178      Iterator end = graph_->endEdges(
vertex);
 
 2179      for(Iterator edge = graph_->beginEdges(
vertex); edge != end; ++edge) {
 
 2181           graph_->getVertexProperties(edge.target()).isolated() == graph_->getVertexProperties(edge.source()).isolated()) {
 
 2182          if( graph_->getVertexProperties(
vertex).isolated() ||
 
 2183              ((edge.properties().depends() || edge.properties().influences())
 
 2184               && admissible(
vertex, aggregates[edge.target()], aggregates)))
 
 2185            return edge.target();
 
 2192    Aggregator<G>::FrontNeighbourCounter::FrontNeighbourCounter(
const MatrixGraph& graph)
 
 2193      : Counter(), graph_(graph)
 
 2199      if(graph_.getVertexProperties(edge.target()).front())
 
 2200        Counter::increment();
 
 2204    int Aggregator<G>::noFrontNeighbours(
const Vertex& 
vertex)
 const 
 2206      FrontNeighbourCounter counter(*graph_);
 
 2208      return counter.value();
 
 2211    inline bool Aggregator<G>::connected(
const Vertex& 
vertex,
 
 2213                                         const AggregatesMap<Vertex>& aggregates)
 const 
 2215      typedef typename G::ConstEdgeIterator iterator;
 
 2216      const iterator end = graph_->endEdges(
vertex);
 
 2217      for(iterator edge = graph_->beginEdges(
vertex); edge != end; ++edge)
 
 2218        if(aggregates[edge.target()]==aggregate)
 
 2223    inline bool Aggregator<G>::connected(
const Vertex& 
vertex,
 
 2224                                         const SLList<AggregateDescriptor>& aggregateList,
 
 2225                                         const AggregatesMap<Vertex>& aggregates)
 const 
 2228      for(Iter i=aggregateList.begin(); i!=aggregateList.end(); ++i)
 
 2229        if(connected(
vertex, *i, aggregates))
 
 2236    void Aggregator<G>::growIsolatedAggregate(
const Vertex& seed, 
const AggregatesMap<Vertex>& aggregates, 
const C& c)
 
 2238      SLList<Vertex> connectedAggregates;
 
 2239      nonisoNeighbourAggregate(seed, aggregates,connectedAggregates);
 
 2241      while(aggregate_->
size()< c.minAggregateSize() && aggregate_->
connectSize() < c.maxConnectivity()) {
 
 2243        std::size_t maxFrontNeighbours=0;
 
 2247        typedef typename std::vector<Vertex>::const_iterator Iterator;
 
 2250          if(distance(*
vertex, aggregates)>c.maxDistance())
 
 2253          if(connectedAggregates.size()>0) {
 
 2257            if(!connected(*
vertex, connectedAggregates, aggregates))
 
 2261          double con = connectivity(*
vertex, aggregates);
 
 2264            std::size_t frontNeighbours = noFrontNeighbours(*
vertex);
 
 2266            if(frontNeighbours >= maxFrontNeighbours) {
 
 2267              maxFrontNeighbours = frontNeighbours;
 
 2270          }
else if(con > maxCon) {
 
 2272            maxFrontNeighbours = noFrontNeighbours(*
vertex);
 
 2280        aggregate_->
add(candidate);
 
 2286    void Aggregator<G>::growAggregate(
const Vertex& seed, 
const AggregatesMap<Vertex>& aggregates, 
const C& c)
 
 2290      std::size_t distance_ =0;
 
 2291      while(aggregate_->
size() < c.minAggregateSize()&& distance_<c.maxDistance()) {
 
 2292        int maxTwoCons=0, maxOneCons=0, maxNeighbours=-1;
 
 2295        std::vector<Vertex> candidates;
 
 2296        candidates.reserve(30);
 
 2298        typedef typename std::vector<Vertex>::const_iterator Iterator;
 
 2302          if(graph_->getVertexProperties(*vertex).isolated())
 
 2305          int twoWayCons = twoWayConnections(*
vertex, aggregate_->
id(), aggregates);
 
 2308          if( maxTwoCons == twoWayCons && twoWayCons > 0) {
 
 2309            double con = connectivity(*
vertex, aggregates);
 
 2312              int neighbours = noFrontNeighbours(*
vertex);
 
 2314              if(neighbours > maxNeighbours) {
 
 2315                maxNeighbours = neighbours;
 
 2317                candidates.push_back(*
vertex);
 
 2319                candidates.push_back(*
vertex);
 
 2321            }
else if( con > maxCon) {
 
 2323              maxNeighbours = noFrontNeighbours(*
vertex);
 
 2325              candidates.push_back(*
vertex);
 
 2327          }
else if(twoWayCons > maxTwoCons) {
 
 2328            maxTwoCons = twoWayCons;
 
 2329            maxCon = connectivity(*
vertex, aggregates);
 
 2330            maxNeighbours = noFrontNeighbours(*
vertex);
 
 2332            candidates.push_back(*
vertex);
 
 2344          int oneWayCons = oneWayConnections(*
vertex, aggregate_->
id(), aggregates);
 
 2349          if(!admissible(*
vertex, aggregate_->
id(), aggregates))
 
 2352          if( maxOneCons == oneWayCons && oneWayCons > 0) {
 
 2353            double con = connectivity(*
vertex, aggregates);
 
 2356              int neighbours = noFrontNeighbours(*
vertex);
 
 2358              if(neighbours > maxNeighbours) {
 
 2359                maxNeighbours = neighbours;
 
 2361                candidates.push_back(*
vertex);
 
 2363                if(neighbours==maxNeighbours)
 
 2365                  candidates.push_back(*
vertex);
 
 2368            }
else if( con > maxCon) {
 
 2370              maxNeighbours = noFrontNeighbours(*
vertex);
 
 2372              candidates.push_back(*
vertex);
 
 2374          }
else if(oneWayCons > maxOneCons) {
 
 2375            maxOneCons = oneWayCons;
 
 2376            maxCon = connectivity(*
vertex, aggregates);
 
 2377            maxNeighbours = noFrontNeighbours(*
vertex);
 
 2379            candidates.push_back(*
vertex);
 
 2384        if(!candidates.size())
 
 2386        distance_=distance(seed, aggregates);
 
 2387        candidates.resize(
min(candidates.size(), c.maxAggregateSize()-
 
 2388                                   aggregate_->
size()));
 
 2389        aggregate_->
add(candidates);
 
 2393    template<
typename V>
 
 2394    template<
typename M, 
typename G, 
typename C>
 
 2398      Aggregator<G> aggregator;
 
 2399      return aggregator.build(matrix, graph, *
this, criterion, finestLevel);
 
 2403    template<
class M, 
class C>
 
 2404    std::tuple<int,int,int,int> 
Aggregator<G>::build(
const M& m, G& graph, AggregatesMap<Vertex>& aggregates, 
const C& c,
 
 2410      Stack stack_(graph, *
this, aggregates);
 
 2414      aggregate_ = 
new Aggregate<G,VertexSet>(graph, aggregates, connected_, front_);
 
 2421      dverb<<
"Build dependency took "<< watch.elapsed()<<
" seconds."<<std::endl;
 
 2422      int noAggregates, conAggregates, isoAggregates, oneAggregates;
 
 2423      std::size_t maxA=0, minA=1000000, avg=0;
 
 2424      int skippedAggregates;
 
 2425      noAggregates = conAggregates = isoAggregates = oneAggregates =
 
 2426                                                       skippedAggregates = 0;
 
 2429        Vertex seed = stack_.pop();
 
 2431        if(seed == Stack::NullEntry)
 
 2436        if((noAggregates+1)%10000 == 0)
 
 2440        if(graph.getVertexProperties(seed).excludedBorder()) {
 
 2442          ++skippedAggregates;
 
 2446        if(graph.getVertexProperties(seed).isolated()) {
 
 2447          if(c.skipIsolated()) {
 
 2450            ++skippedAggregates;
 
 2454            aggregate_->
seed(seed);
 
 2455            growIsolatedAggregate(seed, aggregates, c);
 
 2458          aggregate_->
seed(seed);
 
 2459          growAggregate(seed, aggregates, c);
 
 2463        while(!(graph.getVertexProperties(seed).isolated()) && aggregate_->
size() < c.maxAggregateSize()) {
 
 2465          std::vector<Vertex> candidates;
 
 2466          candidates.reserve(30);
 
 2468          typedef typename std::vector<Vertex>::const_iterator Iterator;
 
 2472            if(graph.getVertexProperties(*vertex).isolated())
 
 2475            if(twoWayConnections( *
vertex, aggregate_->
id(), aggregates) == 0 &&
 
 2476               (oneWayConnections( *
vertex, aggregate_->
id(), aggregates) == 0 ||
 
 2477                !admissible( *
vertex, aggregate_->
id(), aggregates) ))
 
 2480            std::pair<int,int> neighbourPair=neighbours(*
vertex, aggregate_->
id(),
 
 2486            if(neighbourPair.first >= neighbourPair.second)
 
 2489            if(distance(*
vertex, aggregates) > c.maxDistance())
 
 2491            candidates.push_back(*
vertex);
 
 2495          if(!candidates.size()) 
break; 
 
 2497          candidates.resize(
min(candidates.size(), c.maxAggregateSize()-
 
 2498                                     aggregate_->
size()));
 
 2499          aggregate_->
add(candidates);
 
 2504        if(aggregate_->
size()==1 && c.maxAggregateSize()>1) {
 
 2505          if(!graph.getVertexProperties(seed).isolated()) {
 
 2506            Vertex mergedNeighbour = mergeNeighbour(seed, aggregates);
 
 2510              aggregates[seed] = aggregates[mergedNeighbour];
 
 2511              aggregate_->invalidate();
 
 2514              minA=
min(minA,
static_cast<std::size_t
>(1));
 
 2515              maxA=
max(maxA,
static_cast<std::size_t
>(1));
 
 2521            minA=
min(minA,
static_cast<std::size_t
>(1));
 
 2522            maxA=
max(maxA,
static_cast<std::size_t
>(1));
 
 2528          avg+=aggregate_->
size();
 
 2529          minA=
min(minA,aggregate_->
size());
 
 2530          maxA=
max(maxA,aggregate_->
size());
 
 2531          if(graph.getVertexProperties(seed).isolated())
 
 2539      Dune::dinfo<<
"connected aggregates: "<<conAggregates;
 
 2540      Dune::dinfo<<
" isolated aggregates: "<<isoAggregates;
 
 2541      if(conAggregates+isoAggregates>0)
 
 2542        Dune::dinfo<<
" one node aggregates: "<<oneAggregates<<
" min size=" 
 2543                   <<minA<<
" max size="<<maxA
 
 2544                   <<
" avg="<<avg/(conAggregates+isoAggregates)<<std::endl;
 
 2547      return std::make_tuple(conAggregates+isoAggregates,isoAggregates,
 
 2548                             oneAggregates,skippedAggregates);
 
 2553    Aggregator<G>::Stack::Stack(
const MatrixGraph& graph, 
const Aggregator<G>& aggregatesBuilder,
 
 2554                                const AggregatesMap<Vertex>& aggregates)
 
 2555      : graph_(graph), aggregatesBuilder_(aggregatesBuilder), aggregates_(aggregates), begin_(graph.begin()), end_(graph.end())
 
 2561    Aggregator<G>::Stack::~Stack()
 
 2572    inline typename G::VertexDescriptor Aggregator<G>::Stack::pop()
 
 2578        typename G::VertexDescriptor current=*begin_;
 
 2588    void printAggregates2d(
const AggregatesMap<V>& aggregates, 
int n, 
int m,  std::ostream& os)
 
 2592      std::ios_base::fmtflags oldOpts=os.flags();
 
 2594      os.setf(std::ios_base::right, std::ios_base::adjustfield);
 
 2599      for(
int i=0; i< n*m; i++)
 
 2600        maxVal=
max(maxVal, aggregates[i]);
 
 2602      for(
int i=10; i < 1000000; i*=10)
 
 2608      for(
int j=0, entry=0; j < m; j++) {
 
 2609        for(
int i=0; i<n; i++, entry++) {
 
 2611          os<<aggregates[entry]<<
" ";
 
A class for temporarily storing the vertices of an aggregate in.
Definition: aggregates.hh:784
 
A Dummy visitor that does nothing for each visited edge.
Definition: aggregates.hh:604
 
Class providing information about the mapping of the vertices onto aggregates.
Definition: aggregates.hh:566
 
Base class of all aggregation criterions.
Definition: aggregates.hh:51
 
Class for building the aggregates.
Definition: aggregates.hh:915
 
Dependency policy for symmetric matrices.
Definition: aggregates.hh:255
 
Norm that uses only the [N][N] entry of the block to determine couplings.
Definition: aggregates.hh:381
 
Norm that uses only the [0][0] entry of the block to determine couplings.
Definition: aggregates.hh:457
 
Iterator over all edges starting from a vertex.
Definition: graph.hh:95
 
The vertex iterator type of the graph.
Definition: graph.hh:209
 
The (undirected) graph of a matrix.
Definition: graph.hh:51
 
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
 
All parameters for AMG.
Definition: parameters.hh:416
 
Criterion taking advantage of symmetric matrices.
Definition: aggregates.hh:525
 
Dependency policy for symmetric matrices.
Definition: aggregates.hh:316
 
Dependency policy for symmetric matrices.
Definition: aggregates.hh:136
 
Criterion suitable for unsymmetric matrices.
Definition: aggregates.hh:545
 
derive error class from the base class in common
Definition: istlexception.hh:19
 
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
 
MatrixImp::DenseMatrixBase< T, A >::window_type row_type
The type implementing a matrix row.
Definition: matrix.hh:574
 
An allocator managing a pool of objects for reuse.
Definition: poolallocator.hh:223
 
A single linked list.
Definition: sllist.hh:44
 
Type traits to determine the type of reals (when working with complex numbers)
 
Provides classes for building the matrix graph.
 
SLListConstIterator< T, A > const_iterator
The constant iterator of the list.
Definition: sllist.hh:74
 
#define DUNE_THROW(E,...)
Definition: exceptions.hh:314
 
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
 
constexpr auto min
Function object that returns the smaller of the given values.
Definition: hybridutilities.hh:507
 
Matrix::ConstColIterator ColIter
Constant column iterator of the matrix.
Definition: aggregates.hh:275
 
Matrix::ConstColIterator ColIter
Constant column iterator of the matrix.
Definition: aggregates.hh:156
 
std::size_t breadthFirstSearch(const VertexDescriptor &start, const AggregateDescriptor &aggregate, const G &graph, L &visited, F1 &aggregateVisitor, F2 &nonAggregateVisitor, VM &visitedMap) const
Breadth first search within an aggregate.
 
PoolAllocator< VertexDescriptor, 100 > Allocator
The allocator we use for our lists and the set.
Definition: aggregates.hh:592
 
int id()
Get the id identifying the aggregate.
 
Norm norm_
The functor for calculating the norm.
Definition: aggregates.hh:304
 
MatrixGraph::VertexDescriptor Vertex
The vertex identifier.
Definition: aggregates.hh:926
 
AggregationCriterion()
Constructor.
Definition: aggregates.hh:68
 
const Matrix * matrix_
The matrix we work on.
Definition: aggregates.hh:359
 
auto operator()(const M &m, typename std::enable_if_t< Dune::IsNumber< M >::value > *sfinae=nullptr) const
Compute the norm of a scalar.
Definition: aggregates.hh:408
 
M Matrix
The matrix type we build the dependency of.
Definition: aggregates.hh:260
 
G MatrixGraph
The matrix graph type used.
Definition: aggregates.hh:921
 
Norm norm_
The functor for calculating the norm.
Definition: aggregates.hh:365
 
M Matrix
The matrix type we build the dependency of.
Definition: aggregates.hh:321
 
real_type diagonal_
The norm of the current diagonal.
Definition: aggregates.hh:189
 
N Norm
The norm to use for examining the matrix entries.
Definition: aggregates.hh:265
 
int row_
index of the currently evaluated row.
Definition: aggregates.hh:187
 
std::tuple< int, int, int, int > build(const M &m, G &graph, AggregatesMap< Vertex > &aggregates, const C &c, bool finestLevel)
Build the aggregates.
 
FrontNeighbourCounter(const MatrixGraph &front)
Constructor.
 
Matrix::row_type Row
Constant Row iterator of the matrix.
Definition: aggregates.hh:331
 
const Matrix * matrix_
The matrix we work on.
Definition: aggregates.hh:298
 
const AggregateDescriptor & operator[](const VertexDescriptor &v) const
Get the aggregate a vertex belongs to.
 
AggregateVisitor(const AggregatesMap< Vertex > &aggregates, const AggregateDescriptor &aggregate, Visitor &visitor)
Constructor.
 
Matrix::ConstColIterator ColIter
Constant column iterator of the matrix.
Definition: aggregates.hh:336
 
~AggregatesMap()
Destructor.
 
Matrix::field_type field_type
The current max value.
Definition: aggregates.hh:181
 
void decrement()
Decrement counter.
 
Aggregate(MatrixGraph &graph, AggregatesMap< Vertex > &aggregates, VertexSet &connectivity, std::vector< Vertex > &front_)
Constructor.
 
V Visitor
The type of the adapted visitor.
Definition: aggregates.hh:1070
 
std::size_t * SphereMap
Type of the mapping of aggregate members onto distance spheres.
Definition: aggregates.hh:815
 
Matrix::row_type Row
Constant Row iterator of the matrix.
Definition: aggregates.hh:270
 
VertexSet::size_type connectSize()
Get the number of connections to other aggregates.
 
N Norm
The norm to use for examining the matrix entries.
Definition: aggregates.hh:326
 
Norm norm_
The functor for calculating the norm.
Definition: aggregates.hh:185
 
VertexSet::const_iterator const_iterator
Const iterator over a vertex list.
Definition: aggregates.hh:810
 
MatrixGraph::VertexDescriptor AggregateDescriptor
The type of the aggregate descriptor.
Definition: aggregates.hh:929
 
real_type diagonal_
The norm of the current diagonal.
Definition: aggregates.hh:369
 
void add(const Vertex &vertex)
Add a vertex to the aggregate.
 
T DependencyPolicy
The policy for calculating the dependency graph.
Definition: aggregates.hh:57
 
auto operator()(const M &m) const
compute the norm of a matrix.
Definition: aggregates.hh:475
 
void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)
Examine an edge.
 
FrontMarker(std::vector< Vertex > &front, MatrixGraph &graph)
Constructor.
 
FieldTraits< typenameM::field_type >::real_type operator()(const M &m) const
compute the norm of a matrix.
Definition: aggregates.hh:512
 
int visitNeighbours(const G &graph, const typename G::VertexDescriptor &vertex, V &visitor)
Visit all neighbour vertices of a vertex in a graph.
 
void setDefaultValuesIsotropic(std::size_t dim, std::size_t diameter=2)
Sets reasonable default values for an isotropic problem.
Definition: aggregates.hh:84
 
V AggregateDescriptor
The aggregate descriptor type.
Definition: aggregates.hh:586
 
static const V ISOLATED
Identifier of isolated vertices.
Definition: aggregates.hh:577
 
int row_
index of the currently evaluated row.
Definition: aggregates.hh:367
 
DependencyCounter()
Constructor.
 
real_type diagonal_
The norm of the current diagonal.
Definition: aggregates.hh:308
 
std::size_t noVertices() const
Get the number of vertices.
 
void setDefaultValuesAnisotropic(std::size_t dim, std::size_t diameter=2)
Sets reasonable default values for an aisotropic problem.
Definition: aggregates.hh:107
 
AggregatesMap(std::size_t noVertices)
Constructs with allocating memory.
 
Matrix::field_type field_type
The current max value.
Definition: aggregates.hh:361
 
AggregateDescriptor & operator[](const VertexDescriptor &v)
Get the aggregate a vertex belongs to.
 
AggregatesMap()
Constructs without allocating memory.
 
int value()
Access the current count.
 
SLList< VertexDescriptor, Allocator > VertexList
The type of a single linked list of vertex descriptors.
Definition: aggregates.hh:598
 
ConnectivityCounter(const VertexSet &connected, const AggregatesMap< Vertex > &aggregates)
Constructor.
 
VertexSet::size_type size()
Get the size of the aggregate.
 
const_iterator end() const
get an iterator over the vertices of the aggregate.
 
int row_
index of the currently evaluated row.
Definition: aggregates.hh:306
 
M Matrix
The matrix type we build the dependency of.
Definition: aggregates.hh:141
 
const Matrix * matrix_
The matrix we work on.
Definition: aggregates.hh:179
 
S VertexSet
The type of a single linked list of vertex descriptors.
Definition: aggregates.hh:807
 
FieldTraits< typenameM::field_type >::real_type operator()(const M &m) const
compute the norm of a matrix.
Definition: aggregates.hh:496
 
static const V UNAGGREGATED
Identifier of not yet aggregated vertices.
Definition: aggregates.hh:572
 
std::size_t breadthFirstSearch(const VertexDescriptor &start, const AggregateDescriptor &aggregate, const G &graph, F &aggregateVisitor, VM &visitedMap) const
Breadth first search within an aggregate.
 
Matrix::field_type field_type
The current max value.
Definition: aggregates.hh:300
 
void allocate(std::size_t noVertices)
Allocate memory for holding the information.
 
N Norm
The norm to use for examining the matrix entries.
Definition: aggregates.hh:146
 
void reconstruct(const Vertex &vertex)
Reconstruct the aggregat from an seed node.
 
const_iterator begin() const
get an iterator over the vertices of the aggregate.
 
FieldTraits< typenameM::field_type >::real_type operator()(const M &m, typename std::enable_if_t<!Dune::IsNumber< M >::value > *sfinae=nullptr) const
compute the norm of a matrix.
Definition: aggregates.hh:392
 
MatrixGraph::VertexDescriptor Vertex
The vertex descriptor type.
Definition: aggregates.hh:795
 
void seed(const Vertex &vertex)
Initialize the aggregate with one vertex.
 
void clear()
Clear the aggregate.
 
void free()
Free the allocated memory.
 
void increment()
Increment counter.
 
void buildDependency(G &graph, const typename C::Matrix &matrix, C criterion, bool finestLevel)
Build the dependency of the matrix graph.
 
V VertexDescriptor
The vertex descriptor type.
Definition: aggregates.hh:581
 
std::tuple< int, int, int, int > buildAggregates(const M &matrix, G &graph, const C &criterion, bool finestLevel)
Build the aggregates.
 
Matrix::row_type Row
Constant Row iterator of the matrix.
Definition: aggregates.hh:151
 
PoolAllocator< Vertex, 100 > Allocator
The allocator we use for our lists and the set.
Definition: aggregates.hh:801
 
DVVerbType dvverb(std::cout)
stream for very verbose output.
Definition: stdstreams.hh:96
 
DInfoType dinfo(std::cout)
Stream for informative output.
Definition: stdstreams.hh:141
 
DVerbType dverb(std::cout)
Singleton of verbose debug stream.
Definition: stdstreams.hh:117
 
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 std::integral_constant< T, I0 > front(std::integer_sequence< T, I0, II... >)
Return the first entry of the sequence.
Definition: integersequence.hh:39
 
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
 
Parameter classes for customizing AMG.
 
An stl-compliant pool allocator.
 
Provides classes for handling internal properties in a graph.
 
Implements a scalar matrix view wrapper around an existing scalar.
 
Implements a singly linked list together with the necessary iterators.
 
Standard Dune debug streams.
 
Functor using the row sum (infinity) norm to determine strong couplings.
Definition: aggregates.hh:465
 
Whether this type acts as a scalar in the context of (hierarchically blocked) containers.
Definition: typetraits.hh:194
 
Traits for type conversions and type information.