46 #ifndef MUELU_AGGREGATIONSTRUCTUREDALGORITHM_DEF_HPP_
47 #define MUELU_AGGREGATIONSTRUCTUREDALGORITHM_DEF_HPP_
50 #include <Teuchos_Comm.hpp>
51 #include <Teuchos_CommHelpers.hpp>
53 #include <Xpetra_MapFactory.hpp>
54 #include <Xpetra_Map.hpp>
55 #include <Xpetra_CrsGraphFactory.hpp>
56 #include <Xpetra_CrsGraph.hpp>
61 #include "MueLu_Aggregates.hpp"
62 #include "MueLu_IndexManager.hpp"
68 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
71 Aggregates& aggregates, std::vector<unsigned>& aggStat,
72 LO& numNonAggregatedNodes)
const {
73 Monitor m(*
this,
"BuildAggregates");
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);
80 out = Teuchos::getFancyOStream(rcp(
new Teuchos::oblackholestream()));
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;
91 *out <<
"Extract data for ghosted nodes" << std::endl;
92 geoData->getGhostedNodesData(graph.
GetDomainMap(), ghostedCoarseNodeCoarseLIDs,
93 ghostedCoarseNodeCoarsePIDs, ghostedCoarseNodeCoarseGIDs);
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) {
101 geoData->getFineNodeGhostedTuple(nodeIdx, ghostedIdx[0], ghostedIdx[1], ghostedIdx[2]);
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);
110 rate = geoData->getCoarseningEndRate(dim);
112 if(rem > (rate / 2)) {++coarseIdx[dim];}
113 if(coupled && (geoData->getStartGhostedCoarseNode(dim)*geoData->getCoarseningRate(dim)
114 > geoData->getStartIndex(dim))) {--coarseIdx[dim];}
117 geoData->getCoarseNodeGhostedLID(coarseIdx[0], coarseIdx[1], coarseIdx[2],
118 ghostedCoarseNodeCoarseLID);
120 aggId = ghostedCoarseNodeCoarseLIDs[ghostedCoarseNodeCoarseLID];
121 vertex2AggId[nodeIdx] = aggId;
122 procWinner[nodeIdx] = ghostedCoarseNodeCoarsePIDs[ghostedCoarseNodeCoarseLID];
124 --numNonAggregatedNodes;
130 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
133 RCP<CrsGraph>& myGraph, RCP<const Map>& coarseCoordinatesFineMap,
134 RCP<const Map>& coarseCoordinatesMap)
const {
135 Monitor m(*
this,
"BuildGraphP");
137 RCP<Teuchos::FancyOStream> out;
138 if(
const char* dbg = std::getenv(
"MUELU_STRUCTUREDALGORITHM_DEBUG")) {
139 out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
140 out->setShowAllFrontMatter(
false).setShowProcRank(
true);
142 out = Teuchos::getFancyOStream(rcp(
new Teuchos::oblackholestream()));
145 const bool coupled = geoData->isAggregationCoupled();
148 int numInterpolationPoints = 0;
149 if(geoData->getInterpolationOrder() == 0) {
150 numInterpolationPoints = 1;
151 }
else if(geoData->getInterpolationOrder() == 1) {
153 numInterpolationPoints = 1 << geoData->getNumDimensions();
155 *out <<
"numInterpolationPoints=" << numInterpolationPoints << std::endl;
157 Array<LO> colIndex((geoData->getNumLocalCoarseNodes() + numInterpolationPoints*
158 (geoData->getNumLocalFineNodes() - geoData->getNumLocalCoarseNodes()))*dofsPerNode);
159 Array<size_t> rowPtr(geoData->getNumLocalFineNodes()*dofsPerNode + 1);
161 ArrayRCP<size_t> nnzOnRow(geoData->getNumLocalFineNodes()*dofsPerNode);
163 *out <<
"Compute prolongatorGraph data" << std::endl;
164 if(geoData->getInterpolationOrder() == 0) {
165 ComputeGraphDataConstant(graph, geoData, dofsPerNode, numInterpolationPoints,
166 nnzOnRow, rowPtr, colIndex);
167 }
else if(geoData->getInterpolationOrder() == 1) {
168 ComputeGraphDataLinear(graph, geoData, dofsPerNode, numInterpolationPoints,
169 nnzOnRow, rowPtr, colIndex);
173 RCP<Map> rowMap = MapFactory::Build(graph.
GetDomainMap(), dofsPerNode);
174 RCP<Map> colMap, domainMap;
175 *out <<
"Compute domain and column maps of the CrsGraph" << std::endl;
177 *out <<
"Extract data for ghosted nodes" << std::endl;
178 Array<LO> ghostedCoarseNodeCoarseLIDs;
179 Array<int> ghostedCoarseNodeCoarsePIDs;
180 Array<GO> ghostedCoarseNodeCoarseGIDs;
181 geoData->getGhostedNodesData(graph.
GetDomainMap(), ghostedCoarseNodeCoarseLIDs,
182 ghostedCoarseNodeCoarsePIDs, ghostedCoarseNodeCoarseGIDs);
187 geoData->getNumGlobalCoarseNodes(),
188 ghostedCoarseNodeCoarseGIDs(),
192 LO coarseNodeIdx = 0;
193 Array<GO> coarseNodeCoarseGIDs, coarseNodeFineGIDs;
194 geoData->getCoarseNodesData(graph.
GetDomainMap(), coarseNodeCoarseGIDs, coarseNodeFineGIDs);
195 for(LO nodeIdx = 0; nodeIdx < ghostedCoarseNodeCoarseGIDs.size(); ++nodeIdx) {
196 if(ghostedCoarseNodeCoarsePIDs[nodeIdx] == colMap->getComm()->getRank()) {
197 coarseNodeCoarseGIDs[coarseNodeIdx] = ghostedCoarseNodeCoarseGIDs[nodeIdx];
201 domainMap = MapFactory::Build(graph.
GetDomainMap()->lib(),
202 geoData->getNumGlobalCoarseNodes(),
203 coarseNodeCoarseGIDs(),
206 coarseCoordinatesMap = MapFactory::Build(graph.
GetDomainMap()->lib(),
207 geoData->getNumGlobalCoarseNodes(),
208 coarseNodeCoarseGIDs(),
211 coarseCoordinatesFineMap = MapFactory::Build(graph.
GetDomainMap()->lib(),
212 geoData->getNumGlobalCoarseNodes(),
213 coarseNodeFineGIDs(),
220 Teuchos::OrdinalTraits<GO>::invalid(),
221 geoData->getNumLocalCoarseNodes()*dofsPerNode,
226 Array<GO> coarseNodeCoarseGIDs(geoData->getNumLocalCoarseNodes());
227 Array<GO> coarseNodeFineGIDs(geoData->getNumLocalCoarseNodes());
228 geoData->getCoarseNodesData(graph.
GetDomainMap(), coarseNodeCoarseGIDs, coarseNodeFineGIDs);
229 coarseCoordinatesMap = MapFactory::Build(graph.
GetDomainMap()->lib(),
230 Teuchos::OrdinalTraits<GO>::invalid(),
231 geoData->getNumLocalCoarseNodes(),
234 coarseCoordinatesFineMap = MapFactory::Build(graph.
GetDomainMap()->lib(),
235 Teuchos::OrdinalTraits<GO>::invalid(),
236 coarseNodeFineGIDs(),
241 *out <<
"Call constructor of CrsGraph" << std::endl;
242 myGraph = CrsGraphFactory::Build(rowMap,
245 Xpetra::StaticProfile);
247 *out <<
"Fill CrsGraph" << std::endl;
249 for(LO nodeIdx = 0; nodeIdx < geoData->getNumLocalFineNodes(); ++nodeIdx) {
250 for(LO dof = 0; dof < dofsPerNode; ++dof) {
251 rowIdx = nodeIdx*dofsPerNode + dof;
252 myGraph->insertLocalIndices(rowIdx, colIndex(rowPtr[rowIdx], nnzOnRow[rowIdx]) );
256 *out <<
"Call fillComplete on CrsGraph" << std::endl;
257 myGraph->fillComplete(domainMap, rowMap);
258 *out <<
"Prolongator CrsGraph computed" << std::endl;
263 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
266 const LO dofsPerNode,
const int ,
267 ArrayRCP<size_t>& nnzOnRow, Array<size_t>& rowPtr,
268 Array<LO>& colIndex)
const {
270 RCP<Teuchos::FancyOStream> out;
271 if(
const char* dbg = std::getenv(
"MUELU_STRUCTUREDALGORITHM_DEBUG")) {
272 out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
273 out->setShowAllFrontMatter(
false).setShowProcRank(
true);
275 out = Teuchos::getFancyOStream(rcp(
new Teuchos::oblackholestream()));
278 Array<LO> ghostedCoarseNodeCoarseLIDs;
279 Array<int> ghostedCoarseNodeCoarsePIDs;
280 Array<GO> ghostedCoarseNodeCoarseGIDs;
281 geoData->getGhostedNodesData(graph.
GetDomainMap(), ghostedCoarseNodeCoarseLIDs,
282 ghostedCoarseNodeCoarsePIDs, ghostedCoarseNodeCoarseGIDs);
284 LO ghostedCoarseNodeCoarseLID, rem, rate;
285 Array<LO> ghostedIdx(3), coarseIdx(3);
286 for(LO nodeIdx = 0; nodeIdx < geoData->getNumLocalFineNodes(); ++nodeIdx) {
289 geoData->getFineNodeGhostedTuple(nodeIdx, ghostedIdx[0], ghostedIdx[1], ghostedIdx[2]);
291 for(
int dim = 0; dim < 3; ++dim) {
292 coarseIdx[dim] = ghostedIdx[dim] / geoData->getCoarseningRate(dim);
293 rem = ghostedIdx[dim] % geoData->getCoarseningRate(dim);
294 if(ghostedIdx[dim] - geoData->getOffset(dim)
295 < geoData->getLocalFineNodesInDir(dim) - geoData->getCoarseningEndRate(dim)) {
296 rate = geoData->getCoarseningRate(dim);
298 rate = geoData->getCoarseningEndRate(dim);
300 if(rem > (rate / 2)) {++coarseIdx[dim];}
301 if( (geoData->getStartGhostedCoarseNode(dim)*geoData->getCoarseningRate(dim)
302 > geoData->getStartIndex(dim)) && geoData->isAggregationCoupled() ) {--coarseIdx[dim];}
305 geoData->getCoarseNodeGhostedLID(coarseIdx[0], coarseIdx[1], coarseIdx[2],
306 ghostedCoarseNodeCoarseLID);
308 for(LO dof = 0; dof < dofsPerNode; ++dof) {
309 nnzOnRow[nodeIdx*dofsPerNode + dof] = 1;
310 rowPtr[nodeIdx*dofsPerNode + dof + 1] = rowPtr[nodeIdx*dofsPerNode + dof] + 1;
311 colIndex[rowPtr[nodeIdx*dofsPerNode + dof]] =
312 ghostedCoarseNodeCoarseLIDs[ghostedCoarseNodeCoarseLID]*dofsPerNode + dof;
319 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
322 const LO dofsPerNode,
const int numInterpolationPoints,
323 ArrayRCP<size_t>& nnzOnRow, Array<size_t>& rowPtr,
324 Array<LO>& colIndex)
const {
326 RCP<Teuchos::FancyOStream> out;
327 if(
const char* dbg = std::getenv(
"MUELU_STRUCTUREDALGORITHM_DEBUG")) {
328 out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
329 out->setShowAllFrontMatter(
false).setShowProcRank(
true);
331 out = Teuchos::getFancyOStream(rcp(
new Teuchos::oblackholestream()));
334 const bool coupled = geoData->isAggregationCoupled();
335 const int numDimensions = geoData->getNumDimensions();
336 Array<LO> ghostedIdx(3,0);
337 Array<LO> coarseIdx(3,0);
338 Array<LO> ijkRem(3,0);
339 const LO coarsePointOffset[8][3] = {{0, 0, 0}, {1, 0, 0}, {0, 1, 0}, {1, 1, 0},
340 {0, 0, 1}, {1, 0, 1}, {0, 1, 1}, {1, 1, 1}};
342 for(LO nodeIdx = 0; nodeIdx < geoData->getNumLocalFineNodes(); ++nodeIdx) {
345 geoData->getFineNodeGhostedTuple(nodeIdx, ghostedIdx[0], ghostedIdx[1], ghostedIdx[2]);
346 for(
int dim=0; dim < numDimensions; dim++){
347 coarseIdx[dim] = ghostedIdx[dim] / geoData->getCoarseningRate(dim);
348 ijkRem[dim] = ghostedIdx[dim] % geoData->getCoarseningRate(dim);
350 if (geoData->getStartGhostedCoarseNode(dim)*geoData->getCoarseningRate(dim)
351 > geoData->getStartIndex(dim)) {
355 if(ghostedIdx[dim] == geoData->getLocalFineNodesInDir(dim) - 1) {
356 coarseIdx[dim] = geoData->getLocalCoarseNodesInDir(dim) - 1;
363 bool allCoarse =
true;
364 Array<bool> isCoarse(numDimensions);
365 for(
int dim = 0; dim < numDimensions; ++dim) {
366 isCoarse[dim] =
false;
368 isCoarse[dim] =
true;
371 if( ghostedIdx[dim]-geoData->getOffset(dim) == geoData->getLocalFineNodesInDir(dim)-1 &&
372 geoData->getMeshEdge(dim*2+1) )
373 isCoarse[dim] =
true;
375 if( ghostedIdx[dim]-geoData->getOffset(dim) == geoData->getLocalFineNodesInDir(dim)-1)
376 isCoarse[dim] =
true;
383 LO rowIdx = 0, colIdx = 0;
385 for(LO dof = 0; dof < dofsPerNode; ++dof) {
386 rowIdx = nodeIdx*dofsPerNode + dof;
387 nnzOnRow[rowIdx] = 1;
388 rowPtr[rowIdx + 1] = rowPtr[rowIdx] + 1;
391 geoData->getCoarseNodeGhostedLID(coarseIdx[0], coarseIdx[1], coarseIdx[2], colIdx);
392 colIndex[rowPtr[rowIdx]] = colIdx*dofsPerNode + dof;
396 for(
int dim = 0; dim < numDimensions; ++dim) {
397 if(coarseIdx[dim] == geoData->getGhostedNodesInDir(dim) - 1)
401 for(LO dof = 0; dof < dofsPerNode; ++dof) {
403 rowIdx = nodeIdx*dofsPerNode + dof;
404 nnzOnRow[rowIdx] = Teuchos::as<size_t>( numInterpolationPoints );
405 rowPtr[rowIdx + 1] = rowPtr[rowIdx] + Teuchos::as<LO>(numInterpolationPoints);
407 for(LO interpIdx = 0; interpIdx < numInterpolationPoints; ++interpIdx) {
408 geoData->getCoarseNodeGhostedLID(coarseIdx[0] + coarsePointOffset[interpIdx][0],
409 coarseIdx[1] + coarsePointOffset[interpIdx][1],
410 coarseIdx[2] + coarsePointOffset[interpIdx][2],
412 colIndex[rowPtr[rowIdx] + interpIdx] = colIdx*dofsPerNode + dof;
Container class for aggregation information.
RCP< IndexManager > & GetIndexManager()
Get the index manager used by structured aggregation algorithms.
const RCP< LOVector > & GetProcWinner() const
Returns constant vector that maps local node IDs to owning processor IDs.
const RCP< LOMultiVector > & GetVertex2AggId() const
Returns constant vector that maps local node IDs to local aggregates IDs.
void BuildGraph(const GraphBase &graph, RCP< IndexManager > &geoData, const LO dofsPerNode, RCP< CrsGraph > &myGraph, RCP< const Map > &coarseCoordinatesFineMap, RCP< const Map > &coarseCoordinatesMap) const
Local aggregation.
void ComputeGraphDataConstant(const GraphBase &graph, RCP< IndexManager > &geoData, const LO dofsPerNode, const int numInterpolationPoints, ArrayRCP< size_t > &nnzOnRow, Array< size_t > &rowPtr, Array< LO > &colIndex) const
void BuildAggregates(const Teuchos::ParameterList ¶ms, const GraphBase &graph, Aggregates &aggregates, std::vector< unsigned > &aggStat, LO &numNonAggregatedNodes) const
Local aggregation.
void ComputeGraphDataLinear(const GraphBase &graph, RCP< IndexManager > &geoData, const LO dofsPerNode, const int numInterpolationPoints, ArrayRCP< size_t > &nnzOnRow, Array< size_t > &rowPtr, Array< LO > &colIndex) const
MueLu representation of a graph.
virtual const RCP< const Map > GetDomainMap() const =0
Timer to be used in non-factories.
Namespace for MueLu classes and methods.