46 #ifndef MUELU_STRUCTUREDAGGREGATIONFACTORY_DEF_HPP_
47 #define MUELU_STRUCTUREDAGGREGATIONFACTORY_DEF_HPP_
49 #include <Xpetra_Map.hpp>
50 #include <Xpetra_CrsGraph.hpp>
52 #include "MueLu_AggregationStructuredAlgorithm.hpp"
55 #include "MueLu_Aggregates.hpp"
58 #include "MueLu_Utilities.hpp"
59 #include "MueLu_UncoupledIndexManager.hpp"
60 #include "MueLu_LocalLexicographicIndexManager.hpp"
61 #include "MueLu_GlobalLexicographicIndexManager.hpp"
67 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
72 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
75 RCP<ParameterList> validParamList = rcp(
new ParameterList());
77 #define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name))
80 SET_VALID_ENTRY(
"aggregation: error on nodes with no on-rank neighbors");
89 #undef SET_VALID_ENTRY
90 validParamList->set<RCP<const FactoryBase> >(
"Graph", Teuchos::null,
91 "Graph of the matrix after amalgamation but without dropping.");
92 validParamList->set<RCP<const FactoryBase> >(
"numDimensions", Teuchos::null,
93 "Number of spatial dimension provided by CoordinatesTransferFactory.");
94 validParamList->set<RCP<const FactoryBase> >(
"gNodesPerDim", Teuchos::null,
95 "Global number of nodes per spatial dimension provided by CoordinatesTransferFactory.");
96 validParamList->set<RCP<const FactoryBase> >(
"lNodesPerDim", Teuchos::null,
97 "Local number of nodes per spatial dimension provided by CoordinatesTransferFactory.");
98 validParamList->set<RCP<const FactoryBase> >(
"DofsPerNode", Teuchos::null,
99 "Generating factory for variable \'DofsPerNode\', usually the same as the \'Graph\' factory");
101 return validParamList;
104 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
107 Input(currentLevel,
"Graph");
108 Input(currentLevel,
"DofsPerNode");
110 ParameterList pL = GetParameterList();
111 std::string coupling = pL.get<std::string>(
"aggregation: mode");
112 const bool coupled = (coupling ==
"coupled" ? true :
false);
121 "gNodesPerDim was not provided by the user on level0!");
124 Input(currentLevel,
"gNodesPerDim");
135 "numDimensions was not provided by the user on level0!");
142 "lNodesPerDim was not provided by the user on level0!");
145 Input(currentLevel,
"numDimensions");
146 Input(currentLevel,
"lNodesPerDim");
150 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
155 RCP<Teuchos::FancyOStream> out;
156 if(
const char* dbg = std::getenv(
"MUELU_STRUCTUREDAGGREGATION_DEBUG")) {
157 out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
158 out->setShowAllFrontMatter(
false).setShowProcRank(
true);
160 out = Teuchos::getFancyOStream(rcp(
new Teuchos::oblackholestream()));
163 *out <<
"Entering structured aggregation" << std::endl;
165 ParameterList pL = GetParameterList();
166 bDefinitionPhase_ =
false;
169 RCP<const GraphBase> graph = Get< RCP<GraphBase> >(currentLevel,
"Graph");
170 RCP<const Map> fineMap = graph->GetDomainMap();
171 const int myRank = fineMap->getComm()->getRank();
172 const int numRanks = fineMap->getComm()->getSize();
173 const GO minGlobalIndex = fineMap->getMinGlobalIndex();
174 const LO dofsPerNode = Get<LO>(currentLevel,
"DofsPerNode");
178 const int interpolationOrder = pL.get<
int>(
"aggregation: coarsening order");
179 std::string meshLayout = pL.get<std::string>(
"aggregation: mesh layout");
180 std::string coupling = pL.get<std::string>(
"aggregation: mode");
181 const bool coupled = (coupling ==
"coupled" ? true :
false);
182 std::string outputType = pL.get<std::string>(
"aggregation: output type");
183 const bool outputAggregates = (outputType ==
"Aggregates" ? true :
false);
185 Array<GO> gFineNodesPerDir(3);
186 Array<LO> lFineNodesPerDir(3);
190 lFineNodesPerDir = currentLevel.
Get<Array<LO> >(
"lNodesPerDim",
NoFactory::get());
192 gFineNodesPerDir = currentLevel.
Get<Array<GO> >(
"gNodesPerDim",
NoFactory::get());
196 numDimensions = Get<int>(currentLevel,
"numDimensions");
197 lFineNodesPerDir = Get<Array<LO> >(currentLevel,
"lNodesPerDim");
199 gFineNodesPerDir = Get<Array<GO> >(currentLevel,
"gNodesPerDim");
205 for(
int dim = 0; dim < 3; ++dim) {
206 if(dim >= numDimensions) {
207 gFineNodesPerDir[dim] = 1;
208 lFineNodesPerDir[dim] = 1;
213 std::string coarseningRate = pL.get<std::string>(
"aggregation: coarsening rate");
214 Teuchos::Array<LO> coarseRate;
216 coarseRate = Teuchos::fromStringToArray<LO>(coarseningRate);
217 }
catch(
const Teuchos::InvalidArrayStringRepresentation& e) {
218 GetOStream(
Errors,-1) <<
" *** \"aggregation: coarsening rate\" must be a string convertible into an array! *** "
222 TEUCHOS_TEST_FOR_EXCEPTION((coarseRate.size() > 1) && (coarseRate.size() < numDimensions),
224 "\"aggregation: coarsening rate\" must have at least as many"
225 " components as the number of spatial dimensions in the problem.");
228 RCP<IndexManager > geoData;
239 }
else if(meshLayout ==
"Local Lexicographic") {
243 meshData = currentLevel.
Get<Array<GO> >(
"aggregation: mesh data",
NoFactory::get());
245 "The meshData array is empty, somehow the input for structured"
246 " aggregation are not captured correctly.");
249 meshData = Get<Array<GO> >(currentLevel,
"aggregation: mesh data");
265 }
else if(meshLayout ==
"Global Lexicographic") {
281 *out <<
"The index manager has now been built" << std::endl;
282 *out <<
"graph num nodes: " << fineMap->getNodeNumElements()
283 <<
", structured aggregation num nodes: " << geoData->getNumLocalFineNodes() << std::endl;
284 TEUCHOS_TEST_FOR_EXCEPTION(fineMap->getNodeNumElements()
285 !=
static_cast<size_t>(geoData->getNumLocalFineNodes()),
287 "The local number of elements in the graph's map is not equal to "
288 "the number of nodes given by: lNodesPerDim!");
290 TEUCHOS_TEST_FOR_EXCEPTION(fineMap->getGlobalNumElements()
291 !=
static_cast<size_t>(geoData->getNumGlobalFineNodes()),
293 "The global number of elements in the graph's map is not equal to "
294 "the number of nodes given by: gNodesPerDim!");
297 *out <<
"Compute coarse mesh data" << std::endl;
298 std::vector<std::vector<GO> > coarseMeshData = geoData->getCoarseMeshData();
302 RCP<const FactoryBase> graphFact = GetFactory(
"Graph");
303 RCP<const Map> coarseCoordinatesFineMap, coarseCoordinatesMap;
304 RCP<MueLu::AggregationStructuredAlgorithm<LocalOrdinal, GlobalOrdinal, Node> >
307 if(interpolationOrder == 0 && outputAggregates){
309 RCP<Aggregates> aggregates = rcp(
new Aggregates(graph->GetDomainMap()));
310 aggregates->setObjectLabel(
"ST");
311 aggregates->SetIndexManager(geoData);
312 aggregates->AggregatesCrossProcessors(coupled);
313 aggregates->SetNumAggregates(geoData->getNumLocalCoarseNodes());
314 std::vector<unsigned> aggStat(geoData->getNumLocalFineNodes(),
READY);
315 LO numNonAggregatedNodes = geoData->getNumLocalFineNodes();
317 myStructuredAlgorithm->BuildAggregates(pL, *graph, *aggregates, aggStat,
318 numNonAggregatedNodes);
321 "MueLu::StructuredAggregationFactory::Build: Leftover nodes found! Error!");
322 aggregates->ComputeAggregateSizes(
true);
323 GetOStream(
Statistics1) << aggregates->description() << std::endl;
324 Set(currentLevel,
"Aggregates", aggregates);
328 RCP<CrsGraph> myGraph;
329 myStructuredAlgorithm->BuildGraph(*graph, geoData, dofsPerNode, myGraph,
330 coarseCoordinatesFineMap, coarseCoordinatesMap);
331 Set(currentLevel,
"prolongatorGraph", myGraph);
335 Set(currentLevel,
"gCoarseNodesPerDim", geoData->getGlobalCoarseNodesPerDir());
337 Set(currentLevel,
"lCoarseNodesPerDim", geoData->getLocalCoarseNodesPerDir());
338 Set(currentLevel,
"coarseCoordinatesFineMap", coarseCoordinatesFineMap);
339 Set(currentLevel,
"coarseCoordinatesMap", coarseCoordinatesMap);
340 Set(currentLevel,
"interpolationOrder", interpolationOrder);
341 Set(currentLevel,
"numDimensions", numDimensions);
#define SET_VALID_ENTRY(name)
Container class for aggregation information.
Algorithm for coarsening a graph with structured aggregation.
Exception throws to report errors in the internal logical of the program.
Timer to be used in factories. Similar to Monitor but with additional timers.
Class that holds all level-specific information.
bool IsAvailable(const std::string &ename, const FactoryBase *factory=NoFactory::get()) const
Test whether a need's value has been saved.
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()
int GetLevelID() const
Return level number.
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access)....
static const NoFactory * get()
void DeclareInput(Level ¤tLevel) const
Input.
void Build(Level ¤tLevel) const
Build aggregates.
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
StructuredAggregationFactory()
Constructor.
Namespace for MueLu classes and methods.
@ Statistics1
Print more statistics.