46#ifndef MUELU_LOCALAGGREGATIONALGORITHM_DEF_HPP
47#define MUELU_LOCALAGGREGATIONALGORITHM_DEF_HPP
49#include <Teuchos_Comm.hpp>
50#include <Teuchos_CommHelpers.hpp>
52#include <Xpetra_Vector.hpp>
56#include "MueLu_Aggregates.hpp"
61#include "MueLu_Utilities.hpp"
65 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
67 : ordering_(
"natural"), minNodesPerAggregate_(1), maxNeighAlreadySelected_(0)
70 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
72 Monitor m(*
this,
"Coarsen Uncoupled");
74 GetOStream(
Runtime1) <<
"Ordering: " << ordering_ << std::endl;
75 GetOStream(
Runtime1) <<
"Min nodes per aggregate: " << minNodesPerAggregate_ << std::endl;
76 GetOStream(
Runtime1) <<
"Max nbrs already selected: " << maxNeighAlreadySelected_ << std::endl;
87 Teuchos::ArrayRCP<CANodeState> aggStat;
89 if (nRows > 0) aggStat = Teuchos::arcp<CANodeState>(nRows);
101 Teuchos::ArrayRCP<LO> randomVector;
102 RCP<MueLu::LinkedList> nodeList;
106 if ( ordering_ ==
"random" )
110 randomVector = Teuchos::arcp<LO>(nRows);
111 for (
my_size_t i = 0; i < nRows; ++i) randomVector[i] = i;
112 RandomReorder(randomVector);
114 else if ( ordering_ ==
"graph" )
125 Teuchos::ArrayRCP<LO> vertex2AggId = aggregates.
GetVertex2AggId()->getDataNonConst(0);
127 while (iNode2 < nRows)
134 if ( ordering_ ==
"natural" ) iNode = iNode2++;
135 else if ( ordering_ ==
"random" ) iNode = randomVector[iNode2++];
136 else if ( ordering_ ==
"graph" )
138 if ( nodeList->IsEmpty() )
140 for (
int jNode = 0; jNode < nRows; ++jNode )
144 nodeList->Add(jNode);
149 if ( nodeList->IsEmpty() )
break;
151 iNode = nodeList->Pop();
165 typename Teuchos::ArrayView<const LO>::size_type length = neighOfINode.size();
169 supernode->
list = Teuchos::arcp<int>(length+1);
170 }
catch (std::bad_alloc&) {
171 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"MueLu::LocalAggregationAlgorithm::CoarsenUncoupled(): Error: couldn't allocate memory for supernode! length=" + Teuchos::toString(length));
174 supernode->maxLength = length;
175 supernode->length = 1;
176 supernode->list[0] = iNode;
185 for (
typename Teuchos::ArrayView<const LO>::const_iterator it = neighOfINode.begin(); it != neighOfINode.end(); ++it)
192 supernode->list[supernode->length++] = index;
204 if ( count > GetMaxNeighAlreadySelected() ) selectFlag = 0;
213 if (selectFlag != 1 ||
214 supernode->length <= GetMinNodesPerAggregate())
218 if ( ordering_ ==
"graph" )
220 for (
typename Teuchos::ArrayView<const LO>::const_iterator it = neighOfINode.begin(); it != neighOfINode.end(); ++it)
223 if ( index < nRows && aggStat[index] ==
CA_READY )
225 nodeList->Add(index);
233 for (
int j = 0; j < supernode->length; ++j )
235 int jNode = supernode->list[j];
237 vertex2AggId[jNode] = nAggregates;
238 if ( ordering_ ==
"graph" )
243 for (
typename Teuchos::ArrayView<const LO>::const_iterator it = neighOfJNode.begin(); it != neighOfJNode.end(); ++it)
246 if ( index < nRows && aggStat[index] ==
CA_READY )
248 nodeList->Add(index);
253 supernode->next = NULL;
254 supernode->index = nAggregates;
255 if ( nAggregates == 0 )
258 aggCurrent = supernode;
262 aggCurrent->
next = supernode;
263 aggCurrent = supernode;
275 nodeList = Teuchos::null;
282 const RCP<const Teuchos::Comm<int> > & comm = graph.
GetComm();
285 GO localReady=0, globalReady;
289 if (aggStat[i] ==
CA_READY) localReady++;
295 GetOStream(
Warnings0) << globalReady <<
" CA_READY nodes left" << std::endl;
305 GO globalSelected;
MueLu_sumAll(comm, (GO)localSelected, globalSelected);
308 GO globalNRows;
MueLu_sumAll(comm, (GO)nRows, globalNRows);
310 GetOStream(
Statistics1) <<
"Nodes aggregated = " << globalSelected <<
" (" << globalNRows <<
")" << std::endl;
314 GO nAggregatesGlobal;
MueLu_sumAll(comm, (GO)nAggregates, nAggregatesGlobal);
315 GetOStream(
Statistics1) <<
"Total aggregates = " << nAggregatesGlobal << std::endl;
324 aggCurrent = aggHead;
325 while ( aggCurrent != NULL )
327 supernode = aggCurrent;
328 aggCurrent = aggCurrent->
next;
334 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
338 for(
int i=0; i<n-1; i++) {
339 std::swap(list[i], list[RandomOrdinal(i,n-1)]);
343 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
345 return min + Teuchos::as<int>((max-min+1) * (
static_cast<double>(std::rand()) / (RAND_MAX + 1.0)));
#define MueLu_sumAll(rcpComm, in, out)
Container class for aggregation information.
void SetIsRoot(LO i, bool value=true)
Set root node information.
const RCP< LOMultiVector > & GetVertex2AggId() const
Returns constant vector that maps local node IDs to local aggregates IDs.
void SetNumAggregates(LO nAggregates)
Set number of local aggregates on current processor.
Exception throws to report errors in the internal logical of the program.
MueLu representation of a graph.
virtual const RCP< const Teuchos::Comm< int > > GetComm() const =0
virtual Teuchos::ArrayView< const LocalOrdinal > getNeighborVertices(LocalOrdinal v) const =0
Return the list of vertices adjacent to the vertex 'v'.
virtual size_t GetNodeNumVertices() const =0
Return number of vertices owned by the calling node.
int RandomOrdinal(int min, int max) const
Generate a random number in the range [min, max].
void RandomReorder(Teuchos::ArrayRCP< LO > list) const
Utility to take a list of integers and reorder them randomly (by using a local permutation).
LocalAggregationAlgorithm()
Constructor.
void CoarsenUncoupled(GraphBase const &graph, Aggregates &aggregates) const
Local aggregation.
Timer to be used in non-factories.
Namespace for MueLu classes and methods.
@ Warnings0
Important warning messages (one line)
@ Statistics1
Print more statistics.
@ Runtime1
Description of what is happening (more verbose)
struct MueLu::MueLu_SuperNode_Struct MueLu_SuperNode
struct MueLu_SuperNode_Struct * next
Teuchos::ArrayRCP< int > list