5#ifndef DUNE_AMG_AGGREGATES_HH
6#define DUNE_AMG_AGGREGATES_HH
14#include <dune/common/timer.hh>
15#include <dune/common/stdstreams.hh>
16#include <dune/common/poolallocator.hh>
17#include <dune/common/sllist.hh>
18#include <dune/common/ftraits.hh>
19#include <dune/common/scalarmatrixview.hh>
20#include <dune/common/typetraits.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);
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>
165 void examine(G& graph,
const typename G::EdgeIterator& edge,
const ColIter&
col);
182 typedef typename FieldTraits<field_type>::real_type
real_type;
191 typename std::vector<real_type>::iterator
valIter_;
196 template<
class M,
class N>
202 template<
class M,
class N>
206 vals_.assign(row.size(), 0.0);
207 assert(
vals_.size()==row.size());
210 maxValue_ = min(- std::numeric_limits<real_type>::max(), std::numeric_limits<real_type>::min());
215 template<
class M,
class N>
221 if(!N::is_sign_preserving || eij<0)
230 template<
class M,
class N>
235 edge.properties().setDepends();
236 edge.properties().setInfluences();
241 template<
class M,
class N>
253 template<
class M,
class N>
301 typedef typename FieldTraits<field_type>::real_type
real_type;
314 template<
class M,
class N>
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&);
392 typename FieldTraits<typename M::field_type>::real_type
operator()(
const M& m,
393 [[maybe_unused]]
typename std::enable_if_t<!Dune::IsNumber<M>::value>* sfinae =
nullptr)
const
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");
409 typename std::enable_if_t<Dune::IsNumber<M>::value>* =
nullptr)
const
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());
478 if constexpr(Dune::IsNumber<M>::value)
481 return m.infinity_norm();
496 typename FieldTraits<typename M::field_type>::real_type
operator()(
const M& m)
const
498 return m.frobenius_norm();
512 typename FieldTraits<typename M::field_type>::real_type
operator()(
const M& )
const
523 template<
class M,
class Norm>
543 template<
class M,
class Norm>
554 template<
class G>
class Aggregator;
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;
766 std::size_t noVertices_;
772 template<
class G,
class C>
774 const typename C::Matrix& matrix,
782 template<
class G,
class S>
831 VertexSet& connectivity, std::vector<Vertex>& front_);
856 void add(std::vector<Vertex>& vertex);
912 std::vector<Vertex>& front_;
962 template<
class M,
class C>
963 std::tuple<int,int,int,int>
build(
const M& m, G& graph,
971 typedef PoolAllocator<Vertex,100> Allocator;
976 typedef SLList<Vertex,Allocator> VertexList;
981 typedef std::set<Vertex,std::less<Vertex>,Allocator> VertexSet;
986 typedef std::size_t* SphereMap;
1001 std::vector<Vertex> front_;
1006 VertexSet connected_;
1027 enum { N = 1300000 };
1069 class AggregateVisitor
1129 class FrontNeighbourCounter :
public Counter
1148 int noFrontNeighbours(
const Vertex& vertex)
const;
1153 class TwoWayCounter :
public Counter
1176 class OneWayCounter :
public Counter
1202 class ConnectivityCounter :
public Counter
1216 const VertexSet& connected_;
1251 bool connected(
const Vertex& vertex,
const SLList<AggregateDescriptor>& aggregateList,
1261 class DependencyCounter :
public Counter
1293 std::vector<Vertex>& front_;
1332 std::pair<int,int> neighbours(
const Vertex& vertex,
1389 void nonisoNeighbourAggregate(
const Vertex& vertex,
1391 SLList<Vertex>& neighbours)
const;
1408 template<
class M,
class N>
1414 template<
class M,
class N>
1417 initRow(row, index, std::is_convertible<field_type, real_type>());
1420 template<
class M,
class N>
1423 DUNE_THROW(InvalidStateException,
"field_type needs to convertible to real_type");
1426 template<
class M,
class N>
1430 maxValue_ = min(- std::numeric_limits<typename Matrix::field_type>::max(), std::numeric_limits<typename Matrix::field_type>::min());
1432 diagonal_ = norm_(matrix_->operator[](row_)[row_]);
1435 template<
class M,
class N>
1439 real_type eij = norm_(*
col);
1441 matrix_->operator[](
col.index()).find(row_);
1442 if ( opposite_entry == matrix_->operator[](
col.index()).end() )
1447 real_type eji = norm_(*opposite_entry);
1450 if(!N::is_sign_preserving || eij<0 || eji<0)
1451 maxValue_ = max(maxValue_,
1452 eij /diagonal_ * eji/
1453 norm_(matrix_->operator[](
col.index())[
col.index()]));
1456 template<
class M,
class N>
1460 real_type eij = norm_(*
col);
1462 matrix_->operator[](
col.index()).find(row_);
1464 if ( opposite_entry == matrix_->operator[](
col.index()).end() )
1469 real_type eji = norm_(*opposite_entry);
1471 if(!N::is_sign_preserving || (eij<0 || eji<0))
1472 if(eji / norm_(matrix_->operator[](edge.target())[edge.target()]) *
1473 eij/ diagonal_ > alpha() * maxValue_) {
1474 edge.properties().setDepends();
1475 edge.properties().setInfluences();
1476 typename G::EdgeProperties& other = graph.getEdgeProperties(edge.target(), edge.source());
1477 other.setInfluences();
1482 template<
class M,
class N>
1485 return maxValue_ < beta();
1489 template<
class M,
class N>
1495 template<
class M,
class N>
1499 maxValue_ = min(- std::numeric_limits<real_type>::max(), std::numeric_limits<real_type>::min());
1501 diagonal_ = norm_(matrix_->operator[](row_)[row_]);
1504 template<
class M,
class N>
1508 maxValue_ = max(maxValue_, -norm_(*
col));
1511 template<
class M,
class N>
1515 if(-norm_(*
col) >= maxValue_ * alpha()) {
1516 edge.properties().setDepends();
1517 typedef typename G::EdgeDescriptor ED;
1518 ED e= graph.findEdge(edge.target(), edge.source());
1519 if(e!=std::numeric_limits<ED>::max())
1521 typename G::EdgeProperties& other = graph.getEdgeProperties(e);
1522 other.setInfluences();
1527 template<
class M,
class N>
1530 return maxValue_ < beta() * diagonal_;
1533 template<
class G,
class S>
1535 VertexSet& connected, std::vector<Vertex>& front)
1536 : vertices_(), id_(-1), graph_(graph), aggregates_(aggregates),
1537 connected_(connected), front_(front)
1540 template<
class G,
class S>
1548 throw "Not yet implemented";
1556 template<
class G,
class S>
1559 dvverb<<
"Connected cleared"<<std::endl;
1562 connected_.insert(vertex);
1563 dvverb <<
" Inserting "<<vertex<<
" size="<<connected_.size();
1569 template<
class G,
class S>
1572 vertices_.insert(vertex);
1573 aggregates_[vertex]=id_;
1575 front_.erase(std::lower_bound(front_.begin(), front_.end(), vertex));
1579 const iterator end = graph_.endEdges(vertex);
1580 for(iterator edge = graph_.beginEdges(vertex); edge != end; ++edge) {
1581 dvverb <<
" Inserting "<<aggregates_[edge.target()];
1582 connected_.insert(aggregates_[edge.target()]);
1583 dvverb <<
" size="<<connected_.size();
1585 !graph_.getVertexProperties(edge.target()).front())
1587 front_.push_back(edge.target());
1588 graph_.getVertexProperties(edge.target()).setFront();
1592 std::sort(front_.begin(), front_.end());
1595 template<
class G,
class S>
1599 std::size_t oldsize = vertices_.size();
1601 typedef typename std::vector<Vertex>::iterator Iterator;
1603 typedef typename VertexSet::iterator SIterator;
1605 SIterator pos=vertices_.begin();
1606 std::vector<Vertex> newFront;
1607 newFront.reserve(front_.capacity());
1609 std::set_difference(front_.begin(), front_.end(), vertices.begin(), vertices.end(),
1610 std::back_inserter(newFront));
1613 for(Iterator vertex=vertices.begin(); vertex != vertices.end(); ++vertex)
1615 pos=vertices_.insert(pos,*vertex);
1616 vertices_.insert(*vertex);
1617 graph_.getVertexProperties(*vertex).resetFront();
1618 aggregates_[*vertex]=id_;
1621 const iterator end = graph_.endEdges(*vertex);
1622 for(iterator edge = graph_.beginEdges(*vertex); edge != end; ++edge) {
1623 dvverb <<
" Inserting "<<aggregates_[edge.target()];
1624 connected_.insert(aggregates_[edge.target()]);
1626 !graph_.getVertexProperties(edge.target()).front())
1628 front_.push_back(edge.target());
1629 graph_.getVertexProperties(edge.target()).setFront();
1631 dvverb <<
" size="<<connected_.size();
1635 std::sort(front_.begin(), front_.end());
1636 assert(oldsize+vertices.size()==vertices_.size());
1638 template<
class G,
class S>
1646 template<
class G,
class S>
1650 return vertices_.size();
1653 template<
class G,
class S>
1657 return connected_.size();
1660 template<
class G,
class S>
1666 template<
class G,
class S>
1669 return vertices_.begin();
1672 template<
class G,
class S>
1675 return vertices_.end();
1693 delete[] aggregates_;
1700 allocate(noVertices);
1713 noVertices_ = noVertices;
1715 for(std::size_t i=0; i < noVertices; i++)
1716 aggregates_[i]=UNAGGREGATED;
1722 assert(aggregates_ != 0);
1723 delete[] aggregates_;
1731 return aggregates_[v];
1738 return aggregates_[v];
1742 template<
bool reset,
class G,
class F,
class VM>
1745 const G& graph, F& aggregateVisitor,
1746 VM& visitedMap)
const
1750 DummyEdgeVisitor dummy;
1751 return breadthFirstSearch<true,reset>(start, aggregate, graph, vlist, aggregateVisitor, dummy, visitedMap);
1755 template<
bool remove,
bool reset,
class G,
class L,
class F1,
class F2,
class VM>
1760 F1& aggregateVisitor,
1761 F2& nonAggregateVisitor,
1762 VM& visitedMap)
const
1764 typedef typename L::const_iterator ListIterator;
1765 int visitedSpheres = 0;
1767 visited.push_back(start);
1768 put(visitedMap, start,
true);
1770 ListIterator current = visited.begin();
1771 ListIterator end = visited.end();
1772 std::size_t i=0, size=visited.size();
1776 while(current != end) {
1778 for(; i<size; ++current, ++i) {
1779 typedef typename G::ConstEdgeIterator EdgeIterator;
1780 const EdgeIterator endEdge = graph.endEdges(*current);
1782 for(EdgeIterator edge = graph.beginEdges(*current);
1783 edge != endEdge; ++edge) {
1785 if(aggregates_[edge.target()]==aggregate) {
1786 if(!
get(visitedMap, edge.target())) {
1787 put(visitedMap, edge.target(),
true);
1788 visited.push_back(edge.target());
1789 aggregateVisitor(edge);
1792 nonAggregateVisitor(edge);
1795 end = visited.end();
1796 size = visited.size();
1802 for(current = visited.begin(); current != end; ++current)
1803 put(visitedMap, *current,
false);
1809 return visitedSpheres;
1814 : graph_(0), aggregate_(0), front_(), connected_(), size_(-1)
1823 template<
class G,
class C>
1825 const typename C::Matrix& matrix,
1826 C criterion,
bool firstlevel)
1829 typedef typename C::Matrix Matrix;
1830 typedef typename G::VertexIterator VertexIterator;
1832 criterion.init(&matrix);
1834 for(VertexIterator vertex = graph.begin(); vertex != graph.end(); ++vertex) {
1837 const Row& row = matrix[*vertex];
1842 criterion.initRow(row, *vertex);
1847 ColIterator end = row.end();
1848 typename FieldTraits<typename Matrix::field_type>::real_type absoffdiag=0.;
1852 for(ColIterator
col = row.begin();
col != end; ++
col)
1853 if(
col.index()!=*vertex) {
1854 criterion.examine(
col);
1855 absoffdiag = max(absoffdiag, Impl::asMatrix(*col).frobenius_norm());
1859 vertex.properties().setExcludedBorder();
1862 for(ColIterator
col = row.begin();
col != end; ++
col)
1863 if(
col.index()!=*vertex)
1864 criterion.examine(
col);
1870 if(criterion.isIsolated()) {
1872 vertex.properties().setIsolated();
1875 auto eEnd = vertex.end();
1876 auto col = matrix[*vertex].begin();
1878 for(
auto edge = vertex.begin(); edge!= eEnd; ++edge, ++
col) {
1880 while(
col.index()!=edge.target())
1882 criterion.examine(graph, edge,
col);
1894 : aggregates_(aggregates), aggregate_(aggregate), visitor_(&visitor)
1901 if(aggregates_[edge.target()]==aggregate_)
1902 visitor_->operator()(edge);
1909 const AggregatesMap<Vertex>& aggregates,
1913 AggregateVisitor<V> v(aggregates, aggregate, visitor);
1943 if(edge.properties().isTwoWay())
1949 const AggregatesMap<Vertex>& aggregates)
const
1951 TwoWayCounter counter;
1952 visitAggregateNeighbours(vertex, aggregate, aggregates, counter);
1953 return counter.value();
1958 const AggregatesMap<Vertex>& aggregates)
const
1960 OneWayCounter counter;
1961 visitAggregateNeighbours(vertex, aggregate, aggregates, counter);
1962 return counter.value();
1968 if(edge.properties().isOneWay())
1974 const AggregatesMap<Vertex>& aggregates)
1975 : Counter(), connected_(connected), aggregates_(aggregates)
1994 ConnectivityCounter counter(connected_, aggregates);
1996 return (
double)counter.value()/noNeighbours;
2007 if(edge.properties().depends())
2009 if(edge.properties().influences())
2022 const AggregatesMap<Vertex>& aggregates)
const
2024 DependencyCounter unused, aggregated;
2025 typedef AggregateVisitor<DependencyCounter> CounterT;
2026 typedef std::tuple<CounterT,CounterT> CounterTuple;
2029 return std::make_pair(unused.value(), aggregated.value());
2036 DependencyCounter counter;
2037 visitAggregateNeighbours(vertex, aggregate, aggregates, counter);
2038 return counter.value();
2045 typename PropertyMapTypeSelector<VertexVisitedTag,G>::Type visitedMap =
get(VertexVisitedTag(), *graph_);
2047 typename AggregatesMap<Vertex>::DummyEdgeVisitor dummy;
2048 return aggregates.template breadthFirstSearch<true,true>(vertex,
2049 aggregate_->id(), *graph_,
2050 vlist, dummy, dummy, visitedMap);
2055 : front_(front), graph_(graph)
2061 Vertex target = edge.target();
2063 if(!graph_.getVertexProperties(target).front()) {
2064 front_.push_back(target);
2065 graph_.getVertexProperties(target).setFront();
2073 Dune::dvverb<<
" Admissible not yet implemented!"<<std::endl;
2080 Iterator vend = graph_->endEdges(vertex);
2081 for(Iterator edge = graph_->beginEdges(vertex); edge != vend; ++edge) {
2083 if(edge.properties().isStrong()
2084 && aggregates[edge.target()]==aggregate)
2087 Iterator edge1 = edge;
2088 for(++edge1; edge1 != vend; ++edge1) {
2090 if(edge1.properties().isStrong()
2091 && aggregates[edge.target()]==aggregate)
2096 Iterator v2end = graph_->endEdges(edge.target());
2097 for(Iterator edge2 = graph_->beginEdges(edge.target()); edge2 != v2end; ++edge2) {
2098 if(edge2.target()==edge1.target() &&
2099 edge2.properties().isStrong()) {
2115 vend = graph_->endEdges(vertex);
2116 for(Iterator edge = graph_->beginEdges(vertex); edge != vend; ++edge) {
2118 if(edge.properties().isStrong()
2119 && aggregates[edge.target()]==aggregate)
2122 Iterator v1end = graph_->endEdges(edge.target());
2124 for(Iterator edge1=graph_->beginEdges(edge.target()); edge1 != v1end; ++edge1) {
2126 if(edge1.properties().isStrong()
2127 && aggregates[edge1.target()]==aggregate)
2131 Iterator v2end = graph_->endEdges(vertex);
2132 for(Iterator edge2 = graph_->beginEdges(vertex); edge2 != v2end; ++edge2) {
2133 if(edge2.target()==edge1.target()) {
2134 if(edge2.properties().isStrong())
2153 typedef typename std::vector<Vertex>::const_iterator Iterator;
2155 for(Iterator vertex=front_.begin(); vertex != front_.end(); ++vertex)
2156 graph_->getVertexProperties(*vertex).resetFront();
2164 const AggregatesMap<Vertex>& aggregates,
2165 SLList<Vertex>& neighbours)
const
2168 Iterator end=graph_->beginEdges(vertex);
2171 for(Iterator edge=graph_->beginEdges(vertex); edge!=end; ++edge)
2174 neighbours.push_back(aggregates[edge.target()]);
2183 Iterator end = graph_->endEdges(vertex);
2184 for(Iterator edge = graph_->beginEdges(vertex); edge != end; ++edge) {
2186 graph_->getVertexProperties(edge.target()).isolated() == graph_->getVertexProperties(edge.source()).isolated()) {
2187 if( graph_->getVertexProperties(vertex).isolated() ||
2188 ((edge.properties().depends() || edge.properties().influences())
2189 && admissible(vertex, aggregates[edge.target()], aggregates)))
2190 return edge.target();
2198 : Counter(), graph_(graph)
2204 if(graph_.getVertexProperties(edge.target()).front())
2211 FrontNeighbourCounter counter(*graph_);
2213 return counter.value();
2218 const AggregatesMap<Vertex>& aggregates)
const
2220 typedef typename G::ConstEdgeIterator iterator;
2221 const iterator end = graph_->endEdges(vertex);
2222 for(iterator edge = graph_->beginEdges(vertex); edge != end; ++edge)
2223 if(aggregates[edge.target()]==aggregate)
2229 const SLList<AggregateDescriptor>& aggregateList,
2230 const AggregatesMap<Vertex>& aggregates)
const
2232 typedef typename SLList<AggregateDescriptor>::const_iterator Iter;
2233 for(Iter i=aggregateList.begin(); i!=aggregateList.end(); ++i)
2234 if(connected(vertex, *i, aggregates))
2243 SLList<Vertex> connectedAggregates;
2244 nonisoNeighbourAggregate(seed, aggregates,connectedAggregates);
2246 while(aggregate_->size()< c.minAggregateSize() && aggregate_->connectSize() < c.maxConnectivity()) {
2248 std::size_t maxFrontNeighbours=0;
2252 typedef typename std::vector<Vertex>::const_iterator Iterator;
2254 for(Iterator vertex = front_.begin(); vertex != front_.end(); ++vertex) {
2255 if(distance(*vertex, aggregates)>c.maxDistance())
2258 if(connectedAggregates.size()>0) {
2262 if(!connected(*vertex, connectedAggregates, aggregates))
2266 double con = connectivity(*vertex, aggregates);
2269 std::size_t frontNeighbours = noFrontNeighbours(*vertex);
2271 if(frontNeighbours >= maxFrontNeighbours) {
2272 maxFrontNeighbours = frontNeighbours;
2273 candidate = *vertex;
2275 }
else if(con > maxCon) {
2277 maxFrontNeighbours = noFrontNeighbours(*vertex);
2278 candidate = *vertex;
2285 aggregate_->add(candidate);
2295 std::size_t distance_ =0;
2296 while(aggregate_->size() < c.minAggregateSize()&& distance_<c.maxDistance()) {
2297 int maxTwoCons=0, maxOneCons=0, maxNeighbours=-1;
2300 std::vector<Vertex> candidates;
2301 candidates.reserve(30);
2303 typedef typename std::vector<Vertex>::const_iterator Iterator;
2305 for(Iterator vertex = front_.begin(); vertex != front_.end(); ++vertex) {
2307 if(graph_->getVertexProperties(*vertex).isolated())
2310 int twoWayCons = twoWayConnections(*vertex, aggregate_->id(), aggregates);
2313 if( maxTwoCons == twoWayCons && twoWayCons > 0) {
2314 double con = connectivity(*vertex, aggregates);
2317 int neighbours = noFrontNeighbours(*vertex);
2319 if(neighbours > maxNeighbours) {
2320 maxNeighbours = neighbours;
2322 candidates.push_back(*vertex);
2324 candidates.push_back(*vertex);
2326 }
else if( con > maxCon) {
2328 maxNeighbours = noFrontNeighbours(*vertex);
2330 candidates.push_back(*vertex);
2332 }
else if(twoWayCons > maxTwoCons) {
2333 maxTwoCons = twoWayCons;
2334 maxCon = connectivity(*vertex, aggregates);
2335 maxNeighbours = noFrontNeighbours(*vertex);
2337 candidates.push_back(*vertex);
2340 maxOneCons = std::numeric_limits<int>::max();
2349 int oneWayCons = oneWayConnections(*vertex, aggregate_->id(), aggregates);
2354 if(!admissible(*vertex, aggregate_->id(), aggregates))
2357 if( maxOneCons == oneWayCons && oneWayCons > 0) {
2358 double con = connectivity(*vertex, aggregates);
2361 int neighbours = noFrontNeighbours(*vertex);
2363 if(neighbours > maxNeighbours) {
2364 maxNeighbours = neighbours;
2366 candidates.push_back(*vertex);
2368 if(neighbours==maxNeighbours)
2370 candidates.push_back(*vertex);
2373 }
else if( con > maxCon) {
2375 maxNeighbours = noFrontNeighbours(*vertex);
2377 candidates.push_back(*vertex);
2379 }
else if(oneWayCons > maxOneCons) {
2380 maxOneCons = oneWayCons;
2381 maxCon = connectivity(*vertex, aggregates);
2382 maxNeighbours = noFrontNeighbours(*vertex);
2384 candidates.push_back(*vertex);
2389 if(!candidates.size())
2391 distance_=distance(seed, aggregates);
2392 candidates.resize(min(candidates.size(), c.maxAggregateSize()-
2393 aggregate_->size()));
2394 aggregate_->add(candidates);
2398 template<
typename V>
2399 template<
typename M,
typename G,
typename C>
2404 return aggregator.build(matrix, graph, *
this, criterion, finestLevel);
2408 template<
class M,
class C>
2409 std::tuple<int,int,int,int>
Aggregator<G>::build(
const M& m, G& graph, AggregatesMap<Vertex>& aggregates,
const C& c,
2415 Stack stack_(graph, *
this, aggregates);
2419 aggregate_ =
new Aggregate<G,VertexSet>(graph, aggregates, connected_, front_);
2426 dverb<<
"Build dependency took "<< watch.elapsed()<<
" seconds."<<std::endl;
2427 int noAggregates, conAggregates, isoAggregates, oneAggregates;
2428 std::size_t maxA=0, minA=1000000, avg=0;
2429 int skippedAggregates;
2430 noAggregates = conAggregates = isoAggregates = oneAggregates =
2431 skippedAggregates = 0;
2434 Vertex seed = stack_.pop();
2441 if((noAggregates+1)%10000 == 0)
2445 if(graph.getVertexProperties(seed).excludedBorder()) {
2447 ++skippedAggregates;
2451 if(graph.getVertexProperties(seed).isolated()) {
2452 if(c.skipIsolated()) {
2455 ++skippedAggregates;
2459 aggregate_->seed(seed);
2460 growIsolatedAggregate(seed, aggregates, c);
2463 aggregate_->seed(seed);
2464 growAggregate(seed, aggregates, c);
2468 while(!(graph.getVertexProperties(seed).isolated()) && aggregate_->size() < c.maxAggregateSize()) {
2470 std::vector<Vertex> candidates;
2471 candidates.reserve(30);
2473 typedef typename std::vector<Vertex>::const_iterator Iterator;
2475 for(Iterator vertex = front_.begin(); vertex != front_.end(); ++vertex) {
2477 if(graph.getVertexProperties(*vertex).isolated())
2480 if(twoWayConnections( *vertex, aggregate_->id(), aggregates) == 0 &&
2481 (oneWayConnections( *vertex, aggregate_->id(), aggregates) == 0 ||
2482 !admissible( *vertex, aggregate_->id(), aggregates) ))
2485 std::pair<int,int> neighbourPair=neighbours(*vertex, aggregate_->id(),
2491 if(neighbourPair.first >= neighbourPair.second)
2494 if(distance(*vertex, aggregates) > c.maxDistance())
2496 candidates.push_back(*vertex);
2500 if(!candidates.size())
break;
2502 candidates.resize(min(candidates.size(), c.maxAggregateSize()-
2503 aggregate_->size()));
2504 aggregate_->add(candidates);
2509 if(aggregate_->size()==1 && c.maxAggregateSize()>1) {
2510 if(!graph.getVertexProperties(seed).isolated()) {
2511 Vertex mergedNeighbour = mergeNeighbour(seed, aggregates);
2515 aggregates[seed] = aggregates[mergedNeighbour];
2516 aggregate_->invalidate();
2519 minA=min(minA,
static_cast<std::size_t
>(1));
2520 maxA=max(maxA,
static_cast<std::size_t
>(1));
2526 minA=min(minA,
static_cast<std::size_t
>(1));
2527 maxA=max(maxA,
static_cast<std::size_t
>(1));
2533 avg+=aggregate_->size();
2534 minA=min(minA,aggregate_->size());
2535 maxA=max(maxA,aggregate_->size());
2536 if(graph.getVertexProperties(seed).isolated())
2544 Dune::dinfo<<
"connected aggregates: "<<conAggregates;
2545 Dune::dinfo<<
" isolated aggregates: "<<isoAggregates;
2546 if(conAggregates+isoAggregates>0)
2547 Dune::dinfo<<
" one node aggregates: "<<oneAggregates<<
" min size="
2548 <<minA<<
" max size="<<maxA
2549 <<
" avg="<<avg/(conAggregates+isoAggregates)<<std::endl;
2552 return std::make_tuple(conAggregates+isoAggregates,isoAggregates,
2553 oneAggregates,skippedAggregates);
2559 const AggregatesMap<Vertex>& aggregates)
2560 : graph_(graph), aggregatesBuilder_(aggregatesBuilder), aggregates_(aggregates), begin_(graph.begin()), end_(graph.end())
2574 = std::numeric_limits<typename G::VertexDescriptor>::max();
2583 typename G::VertexDescriptor current=*begin_;
2597 std::ios_base::fmtflags oldOpts=os.flags();
2599 os.setf(std::ios_base::right, std::ios_base::adjustfield);
2604 for(
int i=0; i< n*m; i++)
2605 maxVal=max(maxVal, aggregates[i]);
2607 for(
int i=10; i < 1000000; i*=10)
2613 for(
int j=0, entry=0; j < m; j++) {
2614 for(
int i=0; i<n; i++, entry++) {
2616 os<<aggregates[entry]<<
" ";
Provides classes for building the matrix graph.
Parameter classes for customizing AMG.
Provides classes for handling internal properties in a graph.
Matrix::ConstColIterator ColIter
Constant column iterator of the matrix.
Definition aggregates.hh:275
std::vector< real_type >::iterator valIter_
Definition aggregates.hh:191
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
iterator begin()
Definition aggregates.hh:743
int id()
Get the id identifying the aggregate.
Norm norm_
The functor for calculating the norm.
Definition aggregates.hh:304
size_type size()
Get the size of the aggregate.
MatrixGraph::VertexDescriptor Vertex
The vertex identifier.
Definition aggregates.hh:931
AggregationCriterion()
Constructor.
Definition aggregates.hh:68
const Matrix * matrix_
The matrix we work on.
Definition aggregates.hh:359
void initRow(const Row &row, int index)
SymmetricMatrixDependency(const Parameters &parms)
Definition aggregates.hh:170
M Matrix
The matrix type we build the dependency of.
Definition aggregates.hh:260
double alpha() const
Get the scaling value for marking connections as strong. Default value is 1/3.
Definition parameters.hh:70
G MatrixGraph
The matrix graph type used.
Definition aggregates.hh:926
Norm norm_
The functor for calculating the norm.
Definition aggregates.hh:365
void operator()(const EdgeIterator &edge) const
Definition aggregates.hh:607
typename VertexSet::size_type size_type
Type of size used by allocator of sllist.
Definition aggregates.hh:812
SymmetricCriterion()
Definition aggregates.hh:530
Dependency()
Definition aggregates.hh:292
void examine(const ColIter &col)
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
iterator end()
Definition aggregates.hh:748
UnSymmetricCriterion(const Parameters &parms)
Definition aggregates.hh:547
void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)
void initRow(const Row &row, int index)
Definition aggregates.hh:203
static const Vertex NullEntry
Definition aggregates.hh:1019
void examine(const ColIter &col)
Definition aggregates.hh:216
Dependency(const Parameters &parms)
Definition aggregates.hh:288
int row_
index of the currently evaluated row.
Definition aggregates.hh:187
void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)
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.
Parameters(int maxLevel=100, int coarsenTarget=1000, double minCoarsenRate=1.2, double prolongDamp=1.6, AccumulationMode accumulate=successiveAccu, bool useFixedOrder=false)
Constructor.
Definition parameters.hh:516
double beta() const
Get the threshold for marking nodes as isolated. The default value is 1.0E-5.
Definition parameters.hh:52
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
size_type connectSize()
Get the number of connections to other aggregates.
const AggregateDescriptor & operator[](const VertexDescriptor &v) const
Get the aggregate a vertex belongs to.
void examine(G &graph, const typename G::EdgeIterator &edge, const ColIter &col)
AggregateVisitor(const AggregatesMap< Vertex > &aggregates, const AggregateDescriptor &aggregate, Visitor &visitor)
Constructor.
Matrix::ConstColIterator ColIter
Constant column iterator of the matrix.
Definition aggregates.hh:336
FieldTraits< typenameM::field_type >::real_type operator()(const M &) const
compute the norm of a matrix.
Definition aggregates.hh:512
~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:1075
std::size_t * SphereMap
Type of the mapping of aggregate members onto distance spheres.
Definition aggregates.hh:820
AggregationCriterion(const Parameters &parms)
Definition aggregates.hh:72
Matrix::row_type Row
Constant Row iterator of the matrix.
Definition aggregates.hh:270
std::vector< real_type > vals_
Definition aggregates.hh:190
N Norm
The norm to use for examining the matrix entries.
Definition aggregates.hh:326
void printAggregates2d(const AggregatesMap< V > &aggregates, int n, int m, std::ostream &os)
Definition aggregates.hh:2593
void invalidate()
Definition aggregates.hh:833
const_iterator begin() const
Definition aggregates.hh:731
real_type maxValue_
Definition aggregates.hh:183
Norm norm_
The functor for calculating the norm.
Definition aggregates.hh:185
void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)
VertexSet::const_iterator const_iterator
Const iterator over a vertex list.
Definition aggregates.hh:815
SymmetricCriterion(const Parameters &parms)
Definition aggregates.hh:527
MatrixGraph::VertexDescriptor AggregateDescriptor
The type of the aggregate descriptor.
Definition aggregates.hh:934
real_type maxValue_
Definition aggregates.hh:363
void init(const Matrix *matrix)
Definition aggregates.hh:197
real_type diagonal_
The norm of the current diagonal.
Definition aggregates.hh:369
AggregateDescriptor * iterator
Definition aggregates.hh:741
SymmetricDependency(const Parameters &parms)
Definition aggregates.hh:350
FieldTraits< field_type >::real_type real_type
Definition aggregates.hh:362
void examine(G &graph, const typename G::EdgeIterator &edge, const ColIter &col)
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 add(std::vector< Vertex > &vertex)
void examine(const ColIter &col)
void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)
Examine an edge.
FrontMarker(std::vector< Vertex > &front, MatrixGraph &graph)
Constructor.
void init(const Matrix *matrix)
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
const_iterator end() const
Definition aggregates.hh:736
V AggregateDescriptor
The aggregate descriptor type.
Definition aggregates.hh:586
static const T ISOLATED
Definition aggregates.hh:577
int row_
index of the currently evaluated row.
Definition aggregates.hh:367
SymmetricMatrixDependency()
Definition aggregates.hh:173
DependencyCounter()
Constructor.
real_type diagonal_
The norm of the current diagonal.
Definition aggregates.hh:308
std::size_t noVertices() const
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.
const_iterator end() const
get an iterator over the vertices of the aggregate.
void init(const Matrix *matrix)
UnSymmetricCriterion()
Definition aggregates.hh:550
void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)
const AggregateDescriptor * const_iterator
Definition aggregates.hh:729
int row_
index of the currently evaluated row.
Definition aggregates.hh:306
Stack(const MatrixGraph &graph, const Aggregator< G > &aggregatesBuilder, const AggregatesMap< Vertex > &aggregates)
FieldTraits< field_type >::real_type real_type
Definition aggregates.hh:182
void initRow(const Row &row, int index)
M Matrix
The matrix type we build the dependency of.
Definition aggregates.hh:141
FieldTraits< field_type >::real_type real_type
Definition aggregates.hh:301
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 T UNAGGREGATED
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.
auto operator()(const M &m, typename std::enable_if_t< Dune::IsNumber< M >::value > *=nullptr) const
Compute the norm of a scalar.
Definition aggregates.hh:408
Matrix::field_type field_type
The current max value.
Definition aggregates.hh:300
void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)
std::ostream & operator<<(std::ostream &os, const AggregationCriterion< T > &criterion)
Definition aggregates.hh:115
bool isIsolated()
Definition aggregates.hh:242
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.
SymmetricDependency()
Definition aggregates.hh:353
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
real_type maxValue_
Definition aggregates.hh:302
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
G MatrixGraph
Definition aggregates.hh:791
void operator()(const typename MatrixGraph::ConstEdgeIterator &edge)
@ is_sign_preserving
Definition aggregates.hh:505
@ is_sign_preserving
Definition aggregates.hh:489
@ is_sign_preserving
Definition aggregates.hh:468
@ is_sign_preserving
Definition aggregates.hh:384
Definition allocator.hh:11
PropertyMapTypeSelector< Amg::VertexVisitedTag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > >::Type get(const Amg::VertexVisitedTag &tag, Amg::PropertiesGraph< G, Amg::VertexProperties, EP, VM, EM > &graph)
Definition dependency.hh:293
MatrixSparsityPatternGatherScatter< M, I >::ColIter MatrixSparsityPatternGatherScatter< M, I >::col
Definition matrixredistribute.hh:591
Definition novlpschwarz.hh:256
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
Base class of all aggregation criterions.
Definition aggregates.hh:51
Dependency policy for symmetric matrices.
Definition aggregates.hh:255
Dependency policy for symmetric matrices.
Definition aggregates.hh:316
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
Functor using the row sum (infinity) norm to determine strong couplings.
Definition aggregates.hh:465
Definition aggregates.hh:486
Definition aggregates.hh:502
Class providing information about the mapping of the vertices onto aggregates.
Definition aggregates.hh:566
A Dummy visitor that does nothing for each visited edge.
Definition aggregates.hh:604
A class for temporarily storing the vertices of an aggregate in.
Definition aggregates.hh:784
The (undirected) graph of a matrix.
Definition graph.hh:51
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
All parameters for AMG.
Definition parameters.hh:416