46 #ifndef MUELU_HYBRIDAGGREGATIONFACTORY_DEF_HPP_
47 #define MUELU_HYBRIDAGGREGATIONFACTORY_DEF_HPP_
58 #include "MueLu_InterfaceAggregationAlgorithm.hpp"
59 #include "MueLu_OnePtAggregationAlgorithm.hpp"
60 #include "MueLu_PreserveDirichletAggregationAlgorithm.hpp"
61 #include "MueLu_IsolatedNodeAggregationAlgorithm.hpp"
63 #include "MueLu_AggregationPhase1Algorithm.hpp"
64 #include "MueLu_AggregationPhase2aAlgorithm.hpp"
65 #include "MueLu_AggregationPhase2bAlgorithm.hpp"
66 #include "MueLu_AggregationPhase3Algorithm.hpp"
69 #include "MueLu_AggregationStructuredAlgorithm.hpp"
70 #include "MueLu_UncoupledIndexManager.hpp"
77 #include "MueLu_Aggregates.hpp"
80 #include "MueLu_Utilities.hpp"
81 #include "MueLu_AmalgamationInfo.hpp"
86 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
91 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
97 #define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name))
104 rcp(
new validatorType(Teuchos::tuple<std::string>(
"natural",
"graph",
"random"),
"aggregation: ordering")));
112 SET_VALID_ENTRY(
"aggregation: error on nodes with no on-rank neighbors");
114 #undef SET_VALID_ENTRY
119 validParamList->
set<
RCP<const FactoryBase> >(
"DofsPerNode",
null,
"Generating factory for variable \'DofsPerNode\', usually the same as for \'Graph\'");
121 validParamList->
set<std::string> (
"OnePt aggregate map name",
"",
122 "Name of input map for single node aggregates. (default='')");
123 validParamList->
set<std::string> (
"OnePt aggregate map factory",
"",
124 "Generating factory of (DOF) map for single node aggregates.");
127 validParamList->
set< std::string > (
"Interface aggregate map name",
"",
128 "Name of input map for interface aggregates. (default='')");
129 validParamList->
set< std::string > (
"Interface aggregate map factory",
"",
130 "Generating factory of (DOF) map for interface aggregates.");
132 "Array specifying whether or not a node is on the interface (1 or 0).");
136 validParamList->
set<std::string > (
"aggregation: mesh layout",
"Global Lexicographic",
137 "Type of mesh ordering");
138 validParamList->
set<std::string > (
"aggregation: coupling",
"uncoupled",
139 "aggregation coupling mode: coupled or uncoupled");
140 validParamList->
set<
int> (
"aggregation: number of spatial dimensions", 3,
141 "The number of spatial dimensions in the problem");
142 validParamList->
set<
int> (
"aggregation: coarsening order", 0,
143 "The interpolation order used to construct grid transfer operators based off these aggregates.");
144 validParamList->
set<std::string> (
"aggregation: coarsening rate",
"{3}",
145 "Coarsening rate per spatial dimensions");
147 "Mesh ordering associated data");
150 "Number of nodes per spatial dimmension provided by CoordinatesTransferFactory.");
152 "Number of nodes per spatial dimmension provided by CoordinatesTransferFactory.");
157 "Type of aggregation to use on the region (\"structured\" or \"uncoupled\")");
159 return validParamList;
162 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
165 Input(currentLevel,
"Graph");
176 "Aggregation region type was not provided by the user!");
179 Input(currentLevel,
"aggregationRegionType");
184 Input(currentLevel,
"DofsPerNode");
187 if (pL.
get<
bool>(
"aggregation: use interface aggregation") ==
true){
194 "nodeOnInterface was not provided by the user on level0!");
197 Input(currentLevel,
"nodeOnInterface");
202 std::string mapOnePtName = pL.
get<std::string>(
"OnePt aggregate map name");
203 if (mapOnePtName.length() > 0) {
204 std::string mapOnePtFactName = pL.
get<std::string>(
"OnePt aggregate map factory");
205 if (mapOnePtFactName ==
"" || mapOnePtFactName ==
"NoFactory") {
216 std::string coupling = pL.
get<std::string>(
"aggregation: coupling");
217 const bool coupled = (coupling ==
"coupled" ? true :
false);
226 "gNodesPerDim was not provided by the user on level0!");
229 Input(currentLevel,
"gNodesPerDim");
240 "lNodesPerDim was not provided by the user on level0!");
243 Input(currentLevel,
"lNodesPerDim");
249 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
255 if(
const char* dbg = std::getenv(
"MUELU_HYBRIDAGGREGATION_DEBUG")) {
256 out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
262 *out <<
"Entering hybrid aggregation" << std::endl;
265 bDefinitionPhase_ =
false;
267 if (pL.
get<
int>(
"aggregation: max agg size") == -1)
268 pL.
set(
"aggregation: max agg size", INT_MAX);
276 const int myRank = fineMap->getComm()->getRank();
277 const int numRanks = fineMap->getComm()->getSize();
278 const GO minGlobalIndex = fineMap->getMinGlobalIndex();
286 std::vector<unsigned> aggStat(numRows,
READY);
289 std::string regionType;
290 if(currentLevel.GetLevelID() == 0) {
292 regionType = currentLevel.Get< std::string >(
"aggregationRegionType",
NoFactory::get());
295 regionType = Get< std::string >(currentLevel,
"aggregationRegionType");
297 *out<<
"p="<< myRank <<
" | "<<regionType<<
" | regionType determined" << std::endl;
300 if (regionType ==
"structured") {
306 const int numDimensions = pL.
get<
int>(
"aggregation: number of spatial dimensions");
307 const int interpolationOrder = pL.
get<
int>(
"aggregation: coarsening order");
308 std::string meshLayout = pL.
get<std::string>(
"aggregation: mesh layout");
309 std::string coupling = pL.
get<std::string>(
"aggregation: coupling");
310 const bool coupled =
false;
313 if(currentLevel.GetLevelID() == 0) {
322 gFineNodesPerDir = Get<Array<GO> >(currentLevel,
"gNodesPerDim");
324 lFineNodesPerDir = Get<Array<LO> >(currentLevel,
"lNodesPerDim");
328 for(
int dim = numDimensions; dim < 3; ++dim) {
329 lFineNodesPerDir[dim] = 1;
333 std::string coarseningRate = pL.
get<std::string>(
"aggregation: coarsening rate");
336 coarseRate = Teuchos::fromStringToArray<LO>(coarseningRate);
338 GetOStream(
Errors,-1) <<
" *** \"aggregation: coarsening rate\" must be a string convertible into an array! *** "
344 "\"aggregation: coarsening rate\" must have at least as many"
345 " components as the number of spatial dimensions in the problem.");
361 "Coupled aggregation is not yet implemented in hybrid aggregation");
364 *out <<
"The index manager has now been built" << std::endl;
366 != static_cast<size_t>(geoData->getNumLocalFineNodes()),
368 "The local number of elements in the graph's map is not equal to "
369 "the number of nodes given by: lNodesPerDim!");
372 != static_cast<size_t>(geoData->getNumGlobalFineNodes()),
374 "The global number of elements in the graph's map is not equal to "
375 "the number of nodes given by: gNodesPerDim!");
378 *out <<
"Compute coarse mesh data" << std::endl;
379 std::vector<std::vector<GO> > coarseMeshData = geoData->getCoarseMeshData();
384 Set(currentLevel,
"gCoarseNodesPerDim", geoData->getGlobalCoarseNodesPerDir());
385 Set(currentLevel,
"lCoarseNodesPerDim", geoData->getLocalCoarseNodesPerDir());
389 if (regionType ==
"uncoupled"){
401 std::string mapInterfaceName = pL.
get<std::string>(
"Interface aggregate map name");
402 RCP<Map> InterfaceMap = Teuchos::null;
404 if (pL.
get<
bool>(
"aggregation: use interface aggregation") ==
true){
406 for (
LO i = 0; i < numRows; i++) {
407 if (nodeOnInterface[i])
414 if (dirichletBoundaryMap != Teuchos::null)
415 for (
LO i = 0; i < numRows; i++)
416 if (dirichletBoundaryMap[i] ==
true)
420 std::string mapOnePtName = pL.
get<std::string>(
"OnePt aggregate map name");
422 if (mapOnePtName.length()) {
423 std::string mapOnePtFactName = pL.
get<std::string>(
"OnePt aggregate map factory");
424 if (mapOnePtFactName ==
"" || mapOnePtFactName ==
"NoFactory") {
428 OnePtMap = currentLevel.Get<
RCP<Map> >(mapOnePtName, mapOnePtFact.
get());
431 LO nDofsPerNode = Get<LO>(currentLevel,
"DofsPerNode");
433 if (OnePtMap != Teuchos::null) {
434 for (
LO i = 0; i < numRows; i++) {
436 GO grid = (graph->
GetDomainMap()->getGlobalElement(i)-indexBase) * nDofsPerNode + indexBase;
437 for (
LO kr = 0; kr < nDofsPerNode; kr++)
438 if (OnePtMap->isNodeGlobalElement(grid + kr))
445 Set(currentLevel,
"lCoarseNodesPerDim", lCoarseNodesPerDir);
450 LO numNonAggregatedNodes = numRows;
451 for (
size_t a = 0; a < algos_.size(); a++) {
452 std::string phase = algos_[a]->description();
454 *out <<
"p=" << myRank <<
" | "<<regionType<<
" | Executing phase " << a << std::endl;
456 int oldRank = algos_[a]->SetProcRankVerbose(this->GetProcRankVerbose());
457 algos_[a]->BuildAggregates(pL, *graph, *aggregates, aggStat, numNonAggregatedNodes);
458 algos_[a]->SetProcRankVerbose(oldRank);
459 *out <<
"p=" << myRank <<
" | "<<regionType<<
" | Done Executing phase " << a << std::endl;
464 Set(currentLevel,
"Aggregates", aggregates);
466 Set(currentLevel,
"aggregationRegionTypeCoarse", regionType);