MueLu  Version of the Day
MueLu_AggregationStructuredAlgorithm_def.hpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // MueLu: A package for multigrid based preconditioning
6 // Copyright 2012 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact
39 // Jonathan Hu (jhu@sandia.gov)
40 // Andrey Prokopenko (aprokop@sandia.gov)
41 // Ray Tuminaro (rstumin@sandia.gov)
42 //
43 // ***********************************************************************
44 //
45 // @HEADER
46 #ifndef MUELU_AGGREGATIONSTRUCTUREDALGORITHM_DEF_HPP_
47 #define MUELU_AGGREGATIONSTRUCTUREDALGORITHM_DEF_HPP_
48 
49 
50 #include <Teuchos_Comm.hpp>
51 #include <Teuchos_CommHelpers.hpp>
52 
53 #include <Xpetra_MapFactory.hpp>
54 #include <Xpetra_Map.hpp>
55 #include <Xpetra_CrsGraphFactory.hpp>
56 #include <Xpetra_CrsGraph.hpp>
57 
59 
60 #include "MueLu_GraphBase.hpp"
61 #include "MueLu_Aggregates.hpp"
62 #include "MueLu_IndexManager.hpp"
63 #include "MueLu_Exceptions.hpp"
64 #include "MueLu_Monitor.hpp"
65 
66 namespace MueLu {
67 
68  template <class LocalOrdinal, class GlobalOrdinal, class Node>
70  BuildAggregates(const Teuchos::ParameterList& params, const GraphBase& graph,
71  Aggregates& aggregates, std::vector<unsigned>& aggStat,
72  LO& numNonAggregatedNodes) const {
73  Monitor m(*this, "BuildAggregates");
74 
75  RCP<Teuchos::FancyOStream> out;
76  if(const char* dbg = std::getenv("MUELU_STRUCTUREDALGORITHM_DEBUG")) {
77  out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
78  out->setShowAllFrontMatter(false).setShowProcRank(true);
79  } else {
80  out = Teuchos::getFancyOStream(rcp(new Teuchos::oblackholestream()));
81  }
82 
83  RCP<IndexManager> geoData = aggregates.GetIndexManager();
84  const bool coupled = geoData->isAggregationCoupled();
85  ArrayRCP<LO> vertex2AggId = aggregates.GetVertex2AggId()->getDataNonConst(0);
86  ArrayRCP<LO> procWinner = aggregates.GetProcWinner() ->getDataNonConst(0);
87  Array<LO> ghostedCoarseNodeCoarseLIDs;
88  Array<int> ghostedCoarseNodeCoarsePIDs;
89  Array<GO> ghostedCoarseNodeCoarseGIDs;
90 
91  *out << "Extract data for ghosted nodes" << std::endl;
92  geoData->getGhostedNodesData(graph.GetDomainMap(), ghostedCoarseNodeCoarseLIDs,
93  ghostedCoarseNodeCoarsePIDs, ghostedCoarseNodeCoarseGIDs);
94 
95  LO rem, rate;
96  Array<LO> ghostedIdx(3), coarseIdx(3);
97  LO ghostedCoarseNodeCoarseLID, aggId;
98  *out << "Loop over fine nodes and assign them to an aggregate and a rank" << std::endl;
99  for(LO nodeIdx = 0; nodeIdx < geoData->getNumLocalFineNodes(); ++nodeIdx) {
100  // Compute coarse ID associated with fine LID
101  geoData->getFineNodeGhostedTuple(nodeIdx, ghostedIdx[0], ghostedIdx[1], ghostedIdx[2]);
102 
103  for(int dim = 0; dim < 3; ++dim) {
104  coarseIdx[dim] = ghostedIdx[dim] / geoData->getCoarseningRate(dim);
105  rem = ghostedIdx[dim] % geoData->getCoarseningRate(dim);
106  if(ghostedIdx[dim] - geoData->getOffset(dim)
107  < geoData->getLocalFineNodesInDir(dim) - geoData->getCoarseningEndRate(dim)) {
108  rate = geoData->getCoarseningRate(dim);
109  } else {
110  rate = geoData->getCoarseningEndRate(dim);
111  }
112  if(rem > (rate / 2)) {++coarseIdx[dim];}
113  if(coupled && (geoData->getStartGhostedCoarseNode(dim)*geoData->getCoarseningRate(dim)
114  > geoData->getStartIndex(dim))) {--coarseIdx[dim];}
115  }
116 
117  geoData->getCoarseNodeGhostedLID(coarseIdx[0], coarseIdx[1], coarseIdx[2],
118  ghostedCoarseNodeCoarseLID);
119 
120  aggId = ghostedCoarseNodeCoarseLIDs[ghostedCoarseNodeCoarseLID];
121  vertex2AggId[nodeIdx] = aggId;
122  procWinner[nodeIdx] = ghostedCoarseNodeCoarsePIDs[ghostedCoarseNodeCoarseLID];
123  aggStat[nodeIdx] = AGGREGATED;
124  --numNonAggregatedNodes;
125 
126  } // Loop over fine points
127  } // BuildAggregates()
128 
129 
130  template <class LocalOrdinal, class GlobalOrdinal, class Node>
132  BuildGraph(const GraphBase& graph, RCP<IndexManager>& geoData, RCP<CrsGraph>& myGraph,
133  RCP<const Map>& coarseCoordinatesFineMap, RCP<const Map>& coarseCoordinatesMap) const {
134  Monitor m(*this, "BuildAggregates");
135 
136  RCP<Teuchos::FancyOStream> out;
137  if(const char* dbg = std::getenv("MUELU_STRUCTUREDALGORITHM_DEBUG")) {
138  out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
139  out->setShowAllFrontMatter(false).setShowProcRank(true);
140  } else {
141  out = Teuchos::getFancyOStream(rcp(new Teuchos::oblackholestream()));
142  }
143 
144  const bool coupled = geoData->isAggregationCoupled();
145 
146  // Compute the number of coarse points needed to interpolate quantities to a fine point
147  int numInterpolationPoints = 0;
148  if(geoData->getInterpolationOrder() == 0) {
149  numInterpolationPoints = 1;
150  } else if(geoData->getInterpolationOrder() == 1) {
151  // Compute 2^numDimensions using bit logic to avoid round-off errors
152  numInterpolationPoints = 1 << geoData->getNumDimensions();
153  }
154  *out << "numInterpolationPoints=" << numInterpolationPoints << std::endl;
155 
156  Array<LO> colIndex( geoData->getNumLocalCoarseNodes() + numInterpolationPoints*
157  (geoData->getNumLocalFineNodes() - geoData->getNumLocalCoarseNodes()) );
158  Array<size_t> rowPtr(geoData->getNumLocalFineNodes()+1);
159  rowPtr[0] = 0;
160  ArrayRCP<size_t> nnzOnRow(geoData->getNumLocalFineNodes());
161 
162  *out << "Compute prolongatorGraph data" << std::endl;
163  if(geoData->getInterpolationOrder() == 0) {
164  ComputeGraphDataConstant(graph, geoData, numInterpolationPoints, nnzOnRow, rowPtr, colIndex);
165  } else if(geoData->getInterpolationOrder() == 1) {
166  ComputeGraphDataLinear(graph, geoData, numInterpolationPoints, nnzOnRow, rowPtr, colIndex);
167  }
168 
169  // Compute graph's colMap and domainMap
170  RCP<Map> colMap, domainMap;
171  *out << "Compute domain and column maps of the CrsGraph" << std::endl;
172  if(coupled){
173  *out << "Extract data for ghosted nodes" << std::endl;
174  Array<LO> ghostedCoarseNodeCoarseLIDs;
175  Array<int> ghostedCoarseNodeCoarsePIDs;
176  Array<GO> ghostedCoarseNodeCoarseGIDs;
177  geoData->getGhostedNodesData(graph.GetDomainMap(), ghostedCoarseNodeCoarseLIDs,
178  ghostedCoarseNodeCoarsePIDs, ghostedCoarseNodeCoarseGIDs);
179 
180  // In this case we specify the global number of nodes on the coarse mesh
181  // as well as the GIDs needed on rank.
182  colMap = MapFactory::Build(graph.GetDomainMap()->lib(),
183  geoData->getNumGlobalCoarseNodes(),
184  ghostedCoarseNodeCoarseGIDs(),
185  graph.GetDomainMap()->getIndexBase(),
186  graph.GetDomainMap()->getComm(),
187  graph.GetDomainMap()->getNode());
188 
189  LO coarseNodeIdx = 0;
190  Array<GO> coarseNodeCoarseGIDs, coarseNodeFineGIDs;
191  geoData->getCoarseNodesData(graph.GetDomainMap(), coarseNodeCoarseGIDs, coarseNodeFineGIDs);
192  for(LO nodeIdx = 0; nodeIdx < ghostedCoarseNodeCoarseGIDs.size(); ++nodeIdx) {
193  if(ghostedCoarseNodeCoarsePIDs[nodeIdx] == colMap->getComm()->getRank()) {
194  coarseNodeCoarseGIDs[coarseNodeIdx] = ghostedCoarseNodeCoarseGIDs[nodeIdx];
195  ++coarseNodeIdx;
196  }
197  }
198  domainMap = MapFactory::Build(graph.GetDomainMap()->lib(),
199  geoData->getNumGlobalCoarseNodes(),
200  coarseNodeCoarseGIDs(),
201  graph.GetDomainMap()->getIndexBase(),
202  graph.GetDomainMap()->getComm(),
203  graph.GetDomainMap()->getNode());
204  coarseCoordinatesMap = MapFactory::Build(graph.GetDomainMap()->lib(),
205  geoData->getNumGlobalCoarseNodes(),
206  coarseNodeCoarseGIDs(),
207  graph.GetDomainMap()->getIndexBase(),
208  graph.GetDomainMap()->getComm(),
209  graph.GetDomainMap()->getNode());
210  coarseCoordinatesFineMap = MapFactory::Build(graph.GetDomainMap()->lib(),
211  geoData->getNumGlobalCoarseNodes(),
212  coarseNodeFineGIDs(),
213  graph.GetDomainMap()->getIndexBase(),
214  graph.GetDomainMap()->getComm(),
215  graph.GetDomainMap()->getNode());
216  } else {
217  // In this case the map will compute the global number of nodes on the coarse mesh
218  // since geoData->getNumGlobalCoarseNodes() == Teuchos::OrdinalTraits<GO>::invalid()
219  // and it will assign GIDs to the local coarse nodes.
220  colMap = MapFactory::Build(graph.GetDomainMap()->lib(),
221  geoData->getNumGlobalCoarseNodes(),
222  geoData->getNumLocalCoarseNodes(),
223  graph.GetDomainMap()->getIndexBase(),
224  graph.GetDomainMap()->getComm(),
225  graph.GetDomainMap()->getNode());
226  domainMap = colMap;
227 
228  Array<GO> coarseNodeCoarseGIDs(geoData->getNumLocalCoarseNodes());
229  Array<GO> coarseNodeFineGIDs(geoData->getNumLocalCoarseNodes());
230  geoData->getCoarseNodesData(graph.GetDomainMap(), coarseNodeCoarseGIDs, coarseNodeFineGIDs);
231  coarseCoordinatesMap = MapFactory::Build(graph.GetDomainMap()->lib(),
232  geoData->getNumGlobalCoarseNodes(),
233  geoData->getNumLocalCoarseNodes(),
234  graph.GetDomainMap()->getIndexBase(),
235  graph.GetDomainMap()->getComm(),
236  graph.GetDomainMap()->getNode());
237  coarseCoordinatesFineMap = MapFactory::Build(graph.GetDomainMap()->lib(),
238  geoData->getNumGlobalCoarseNodes(),
239  coarseNodeFineGIDs(),
240  graph.GetDomainMap()->getIndexBase(),
241  graph.GetDomainMap()->getComm(),
242  graph.GetDomainMap()->getNode());
243  }
244 
245  myGraph = CrsGraphFactory::Build(graph.GetDomainMap(),
246  colMap,
247  nnzOnRow,
248  Xpetra::DynamicProfile);
249  for(LO nodeIdx = 0; nodeIdx < geoData->getNumLocalFineNodes(); ++nodeIdx) {
250  myGraph->insertLocalIndices(nodeIdx, colIndex(rowPtr[nodeIdx], nnzOnRow[nodeIdx]) );
251  }
252  myGraph->fillComplete(domainMap, graph.GetDomainMap());
253 
254  } // BuildAggregates()
255 
256 
257  template <class LocalOrdinal, class GlobalOrdinal, class Node>
259  ComputeGraphDataConstant(const GraphBase& graph, RCP<IndexManager>& geoData,
260  const int numInterpolationPoints, ArrayRCP<size_t>& nnzOnRow,
261  Array<size_t>& rowPtr, Array<LO>& colIndex) const {
262 
263  RCP<Teuchos::FancyOStream> out;
264  if(const char* dbg = std::getenv("MUELU_STRUCTUREDALGORITHM_DEBUG")) {
265  out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
266  out->setShowAllFrontMatter(false).setShowProcRank(true);
267  } else {
268  out = Teuchos::getFancyOStream(rcp(new Teuchos::oblackholestream()));
269  }
270 
271  Array<LO> ghostedCoarseNodeCoarseLIDs;
272  Array<int> ghostedCoarseNodeCoarsePIDs;
273  Array<GO> ghostedCoarseNodeCoarseGIDs;
274  geoData->getGhostedNodesData(graph.GetDomainMap(), ghostedCoarseNodeCoarseLIDs,
275  ghostedCoarseNodeCoarsePIDs, ghostedCoarseNodeCoarseGIDs);
276 
277  LO ghostedCoarseNodeCoarseLID, rem, rate;
278  Array<LO> ghostedIdx(3), coarseIdx(3);
279  for(LO nodeIdx = 0; nodeIdx < geoData->getNumLocalFineNodes(); ++nodeIdx) {
280  // For piece-wise constant interpolation we only get one nnz per row
281  nnzOnRow[nodeIdx] = Teuchos::as<size_t>(1);
282  rowPtr[nodeIdx + 1] = rowPtr[nodeIdx] + 1; // These needs to change for kokkos: rowPtr[nodeIdx + 1] = nodeIdx + 1;
283 
284  // Compute coarse ID associated with fine LID
285  geoData->getFineNodeGhostedTuple(nodeIdx, ghostedIdx[0], ghostedIdx[1], ghostedIdx[2]);
286 
287  for(int dim = 0; dim < 3; ++dim) {
288  coarseIdx[dim] = ghostedIdx[dim] / geoData->getCoarseningRate(dim);
289  rem = ghostedIdx[dim] % geoData->getCoarseningRate(dim);
290  if(ghostedIdx[dim] - geoData->getOffset(dim)
291  < geoData->getLocalFineNodesInDir(dim) - geoData->getCoarseningEndRate(dim)) {
292  rate = geoData->getCoarseningRate(dim);
293  } else {
294  rate = geoData->getCoarseningEndRate(dim);
295  }
296  if(rem > (rate / 2)) {++coarseIdx[dim];}
297  if( (geoData->getStartGhostedCoarseNode(dim)*geoData->getCoarseningRate(dim)
298  > geoData->getStartIndex(dim)) && geoData->isAggregationCoupled() ) {--coarseIdx[dim];}
299  }
300 
301  geoData->getCoarseNodeGhostedLID(coarseIdx[0], coarseIdx[1], coarseIdx[2],
302  ghostedCoarseNodeCoarseLID);
303  colIndex[rowPtr[nodeIdx]] = ghostedCoarseNodeCoarseLIDs[ghostedCoarseNodeCoarseLID]; // Here too, substitute nodeIdx for rowPtr[nodeIdx]
304  } // Loop over fine points
305 
306  } // ComputeGraphDataConstant()
307 
308 
309  template <class LocalOrdinal, class GlobalOrdinal, class Node>
311  ComputeGraphDataLinear(const GraphBase& graph, RCP<IndexManager>& geoData,
312  const int numInterpolationPoints, ArrayRCP<size_t>& nnzOnRow,
313  Array<size_t>& rowPtr, Array<LO>& colIndex) const {
314 
315  RCP<Teuchos::FancyOStream> out;
316  if(const char* dbg = std::getenv("MUELU_STRUCTUREDALGORITHM_DEBUG")) {
317  out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
318  out->setShowAllFrontMatter(false).setShowProcRank(true);
319  } else {
320  out = Teuchos::getFancyOStream(rcp(new Teuchos::oblackholestream()));
321  }
322 
323  const bool coupled = geoData->isAggregationCoupled();
324  const int numDimensions = geoData->getNumDimensions();
325  Array<LO> ghostedIdx(3,0);
326  Array<LO> coarseIdx(3,0);
327  Array<LO> ijkRem(3,0);
328  int rate = 0;
329 
330  for(LO nodeIdx = 0; nodeIdx < geoData->getNumLocalFineNodes(); ++nodeIdx) {
331 
332  // Compute coarse ID associated with fine LID
333  geoData->getFineNodeGhostedTuple(nodeIdx, ghostedIdx[0], ghostedIdx[1], ghostedIdx[2]);
334  for(int dim=0; dim < numDimensions; dim++){
335  coarseIdx[dim] = ghostedIdx[dim] / geoData->getCoarseningRate(dim);
336  ijkRem[dim] = ghostedIdx[dim] % geoData->getCoarseningRate(dim);
337  if(ghostedIdx[dim] - geoData->getOffset(dim)
338  < geoData->getLocalFineNodesInDir(dim) - geoData->getCoarseningEndRate(dim)) {
339  rate = geoData->getCoarseningRate(dim);
340  } else {
341  rate = geoData->getCoarseningEndRate(dim);
342  }
343  if(ijkRem[dim] > (rate / 2)) {++coarseIdx[dim];}
344  if(coupled && (geoData->getStartGhostedCoarseNode(dim)*geoData->getCoarseningRate(dim)
345  > geoData->getStartIndex(dim))) {--coarseIdx[dim];}
346  }
347 
348  // Fill Graph
349  // Check if Fine node lies on Coarse Node
350  bool allCoarse = true;
351  Array<bool> isCoarse(numDimensions);
352  for(int dim = 0; dim < numDimensions; ++dim) {
353  isCoarse[dim] = false;
354  if(ijkRem[dim] == 0)
355  isCoarse[dim] = true;
356 
357  if(coupled){
358  if( ghostedIdx[dim]-geoData->getOffset(dim) == geoData->getLocalFineNodesInDir(dim)-1 &&
359  geoData->getMeshEdge(dim*2+1) )
360  isCoarse[dim] = true;
361  } else {
362  if( ghostedIdx[dim]-geoData->getOffset(dim) == geoData->getLocalFineNodesInDir(dim)-1)
363  isCoarse[dim] = true;
364  }
365 
366  if(!isCoarse[dim])
367  allCoarse = false;
368  }
369 
370  if(allCoarse) {
371  // Fine node lies on Coarse node, easy case, we only need the LID of the coarse node.
372  geoData->getCoarseNodeGhostedLID(coarseIdx[0], coarseIdx[1], coarseIdx[2],
373  colIndex[rowPtr[nodeIdx]]);
374  nnzOnRow[nodeIdx] = Teuchos::as<size_t>(1);
375  rowPtr[nodeIdx + 1] = rowPtr[nodeIdx] + 1;
376  } else {
377  // Harder case, we need the LIDs of all the coarse nodes contributing to the interpolation
378  // at the current node.
379  nnzOnRow[nodeIdx] = Teuchos::as<size_t>( numInterpolationPoints );
380  rowPtr[nodeIdx + 1] = rowPtr[nodeIdx] + Teuchos::as<LO>( numInterpolationPoints );
381 
382  for(int dim = 0; dim < numDimensions; ++dim) {
383  if(coarseIdx[dim] == geoData->getGhostedNodesInDir(dim) - 1)
384  --coarseIdx[dim];
385  }
386  // Compute Coarse Node LID
387  geoData->getCoarseNodeGhostedLID( coarseIdx[0], coarseIdx[1], coarseIdx[2], colIndex[ rowPtr[nodeIdx]+0]);
388  geoData->getCoarseNodeGhostedLID( coarseIdx[0]+1, coarseIdx[1], coarseIdx[2], colIndex[ rowPtr[nodeIdx]+1]);
389  if(numDimensions > 1) {
390  geoData->getCoarseNodeGhostedLID( coarseIdx[0], coarseIdx[1]+1, coarseIdx[2], colIndex[ rowPtr[nodeIdx]+2]);
391  geoData->getCoarseNodeGhostedLID( coarseIdx[0]+1, coarseIdx[1]+1, coarseIdx[2], colIndex[ rowPtr[nodeIdx]+3]);
392  if(numDimensions > 2) {
393  geoData->getCoarseNodeGhostedLID(coarseIdx[0], coarseIdx[1], coarseIdx[2]+1, colIndex[ rowPtr[nodeIdx]+4]);
394  geoData->getCoarseNodeGhostedLID(coarseIdx[0]+1, coarseIdx[1], coarseIdx[2]+1, colIndex[ rowPtr[nodeIdx]+5]);
395  geoData->getCoarseNodeGhostedLID(coarseIdx[0], coarseIdx[1]+1, coarseIdx[2]+1, colIndex[ rowPtr[nodeIdx]+6]);
396  geoData->getCoarseNodeGhostedLID(coarseIdx[0]+1, coarseIdx[1]+1, coarseIdx[2]+1, colIndex[ rowPtr[nodeIdx]+7]);
397  }
398  }
399  }
400  } // Loop over fine points
401  } // ComputeGraphDataLinear()
402 
403 } // end namespace
404 
405 
406 #endif /* MUELU_AGGREGATIONSTRUCTUREDALGORITHM_DEF_HPP_ */
Container class for aggregation information.
RCP< IndexManager > & GetIndexManager()
Get the index manager used by structured aggregation algorithms.
void ComputeGraphDataConstant(const GraphBase &graph, RCP< IndexManager > &geoData, const int numInterpolationPoints, ArrayRCP< size_t > &nnzOnRow, Array< size_t > &rowPtr, Array< LO > &colIndex) const
virtual const RCP< const Map > GetDomainMap() const =0
Namespace for MueLu classes and methods.
void BuildAggregates(const Teuchos::ParameterList &params, const GraphBase &graph, Aggregates &aggregates, std::vector< unsigned > &aggStat, LO &numNonAggregatedNodes) const
Local aggregation.
MueLu representation of a graph.
void ComputeGraphDataLinear(const GraphBase &graph, RCP< IndexManager > &geoData, const int numInterpolationPoints, ArrayRCP< size_t > &nnzOnRow, Array< size_t > &rowPtr, Array< LO > &colIndex) const
Timer to be used in non-factories.
const RCP< LOMultiVector > & GetVertex2AggId() const
Returns constant vector that maps local node IDs to local aggregates IDs.
const RCP< LOVector > & GetProcWinner() const
Returns constant vector that maps local node IDs to owning processor IDs.
void BuildGraph(const GraphBase &graph, RCP< IndexManager > &geoData, RCP< CrsGraph > &myGraph, RCP< const Map > &coarseCoordinatesFineMap, RCP< const Map > &coarseCoordinatesMap) const
Local aggregation.