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");
81 #undef SET_VALID_ENTRY 84 validParamList->set<std::string> (
"aggregation: mesh layout",
"Global Lexicographic",
85 "Type of mesh ordering");
86 validParamList->set<std::string> (
"aggregation: coupling",
"coupled",
87 "aggregation coupling mode: coupled or uncoupled");
88 validParamList->set<std::string> (
"aggregation: output type",
"Aggregates",
89 "Type of object holding the aggregation data: Aggregtes or CrsGraph");
90 validParamList->set<std::string> (
"aggregation: coarsening rate",
"{3}",
91 "Coarsening rate per spatial dimensions");
92 validParamList->set<
int> (
"aggregation: number of spatial dimensions", 3,
93 "The number of spatial dimensions in the problem");
94 validParamList->set<
int> (
"aggregation: coarsening order", 0,
95 "The interpolation order used to construct grid transfer operators based off these aggregates.");
97 validParamList->set<RCP<const FactoryBase> >(
"aggregation: mesh data", Teuchos::null,
98 "Mesh ordering associated data");
100 validParamList->set<RCP<const FactoryBase> >(
"Graph", Teuchos::null,
101 "Graph of the matrix after amalgamation but without dropping.");
102 validParamList->set<RCP<const FactoryBase> >(
"gNodesPerDim", Teuchos::null,
103 "Number of nodes per spatial dimmension provided by CoordinatesTransferFactory.");
104 validParamList->set<RCP<const FactoryBase> >(
"lNodesPerDim", Teuchos::null,
105 "Number of nodes per spatial dimmension provided by CoordinatesTransferFactory.");
107 return validParamList;
110 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
113 Input(currentLevel,
"Graph");
116 std::string coupling = pL.get<std::string>(
"aggregation: coupling");
117 const bool coupled = (coupling ==
"coupled" ? true :
false);
126 "gNodesPerDim was not provided by the user on level0!");
129 Input(currentLevel,
"gNodesPerDim");
140 "lNodesPerDim was not provided by the user on level0!");
143 Input(currentLevel,
"lNodesPerDim");
147 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
152 RCP<Teuchos::FancyOStream> out;
153 if(
const char* dbg = std::getenv(
"MUELU_STRUCTUREDAGGREGATION_DEBUG")) {
154 out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
155 out->setShowAllFrontMatter(
false).setShowProcRank(
true);
157 out = Teuchos::getFancyOStream(rcp(
new Teuchos::oblackholestream()));
160 *out <<
"Entering structured aggregation" << std::endl;
166 RCP<const GraphBase> graph = Get< RCP<GraphBase> >(currentLevel,
"Graph");
167 RCP<const Map> fineMap = graph->GetDomainMap();
168 const int myRank = fineMap->getComm()->getRank();
169 const int numRanks = fineMap->getComm()->getSize();
170 const GO minGlobalIndex = fineMap->getMinGlobalIndex();
174 const int numDimensions = pL.get<
int>(
"aggregation: number of spatial dimensions");
175 const int interpolationOrder = pL.get<
int>(
"aggregation: coarsening order");
176 std::string meshLayout = pL.get<std::string>(
"aggregation: mesh layout");
177 std::string coupling = pL.get<std::string>(
"aggregation: coupling");
178 const bool coupled = (coupling ==
"coupled" ? true :
false);
179 std::string outputType = pL.get<std::string>(
"aggregation: output type");
180 const bool outputAggregates = (outputType ==
"Aggregates" ? true :
false);
181 Array<GO> gFineNodesPerDir(3);
182 Array<LO> lFineNodesPerDir(3);
183 if(currentLevel.GetLevelID() == 0) {
186 gFineNodesPerDir = currentLevel.Get<Array<GO> >(
"gNodesPerDim",
NoFactory::get());
188 lFineNodesPerDir = currentLevel.Get<Array<LO> >(
"lNodesPerDim",
NoFactory::get());
192 gFineNodesPerDir = Get<Array<GO> >(currentLevel,
"gNodesPerDim");
194 lFineNodesPerDir = Get<Array<LO> >(currentLevel,
"lNodesPerDim");
199 for(
int dim = 0; dim < 3; ++dim) {
200 if(dim >= numDimensions) {
201 gFineNodesPerDir[dim] = 1;
202 lFineNodesPerDir[dim] = 1;
207 std::string coarseningRate = pL.get<std::string>(
"aggregation: coarsening rate");
208 Teuchos::Array<LO> coarseRate;
210 coarseRate = Teuchos::fromStringToArray<LO>(coarseningRate);
211 }
catch(
const Teuchos::InvalidArrayStringRepresentation e) {
212 GetOStream(
Errors,-1) <<
" *** \"aggregation: coarsening rate\" must be a string convertible into an array! *** " 216 TEUCHOS_TEST_FOR_EXCEPTION((coarseRate.size() > 1) && (coarseRate.size() < numDimensions),
218 "\"aggregation: coarsening rate\" must have at least as many" 219 " components as the number of spatial dimensions in the problem.");
222 RCP<IndexManager > geoData;
233 }
else if(meshLayout ==
"Local Lexicographic") {
235 if(currentLevel.GetLevelID() == 0) {
237 meshData = currentLevel.Get<Array<GO> >(
"aggregation: mesh data",
NoFactory::get());
239 "The meshData array is empty, somehow the input for structured" 240 " aggregation are not captured correctly.");
243 meshData = Get<Array<GO> >(currentLevel,
"aggregation: mesh data");
259 }
else if(meshLayout ==
"Global Lexicographic") {
275 *out <<
"The index manager has now been built" << std::endl;
276 TEUCHOS_TEST_FOR_EXCEPTION(fineMap->getNodeNumElements()
277 !=
static_cast<size_t>(geoData->getNumLocalFineNodes()),
279 "The local number of elements in the graph's map is not equal to " 280 "the number of nodes given by: lNodesPerDim!");
282 TEUCHOS_TEST_FOR_EXCEPTION(fineMap->getGlobalNumElements()
283 !=
static_cast<size_t>(geoData->getNumGlobalFineNodes()),
285 "The global number of elements in the graph's map is not equal to " 286 "the number of nodes given by: gNodesPerDim!");
289 *out <<
"Compute coarse mesh data" << std::endl;
290 std::vector<std::vector<GO> > coarseMeshData = geoData->getCoarseMeshData();
294 RCP<const FactoryBase> graphFact =
GetFactory(
"Graph");
295 RCP<const Map> coarseCoordinatesFineMap, coarseCoordinatesMap;
296 RCP<MueLu::AggregationStructuredAlgorithm<LocalOrdinal, GlobalOrdinal, Node> >
299 if(interpolationOrder == 0 && outputAggregates){
300 RCP<Aggregates> aggregates = rcp(
new Aggregates(graph->GetDomainMap()));
301 aggregates->setObjectLabel(
"ST");
302 aggregates->SetIndexManager(geoData);
303 aggregates->AggregatesCrossProcessors(coupled);
304 aggregates->SetNumAggregates(geoData->getNumLocalCoarseNodes());
305 std::vector<unsigned> aggStat(geoData->getNumLocalFineNodes(),
READY);
306 LO numNonAggregatedNodes = geoData->getNumLocalFineNodes();
308 myStructuredAlgorithm->BuildAggregates(pL, *graph, *aggregates, aggStat,
309 numNonAggregatedNodes);
312 "MueLu::StructuredAggregationFactory::Build: Leftover nodes found! Error!");
313 aggregates->ComputeAggregateSizes(
true);
315 Set(currentLevel,
"Aggregates", aggregates);
319 RCP<CrsGraph> myGraph;
320 myStructuredAlgorithm->BuildGraph(*graph, geoData, myGraph, coarseCoordinatesFineMap,
321 coarseCoordinatesMap);
322 Set(currentLevel,
"prolongatorGraph", myGraph);
326 Set(currentLevel,
"gCoarseNodesPerDim", geoData->getGlobalCoarseNodesPerDir());
328 Set(currentLevel,
"lCoarseNodesPerDim", geoData->getLocalCoarseNodesPerDir());
329 Set(currentLevel,
"coarseCoordinatesFineMap", coarseCoordinatesFineMap);
330 Set(currentLevel,
"coarseCoordinatesMap", coarseCoordinatesMap);
331 Set(currentLevel,
"interpolationOrder", interpolationOrder);
332 Set(currentLevel,
"numDimensions", numDimensions);
void Build(Level ¤tLevel) const
Build aggregates.
Teuchos::FancyOStream & GetOStream(MsgType type, int thisProcRankOnly=0) const
Get an output stream for outputting the input message type.
Container class for aggregation information.
Timer to be used in factories. Similar to Monitor but with additional timers.
Algorithm for coarsening a graph with structured aggregation.
void DeclareInput(Level ¤tLevel) const
Input.
Namespace for MueLu classes and methods.
StructuredAggregationFactory()
Constructor.
static const NoFactory * get()
int GetLevelID() const
Return level number.
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
Class that holds all level-specific information.
virtual const Teuchos::ParameterList & GetParameterList() const
void Input(Level &level, const std::string &varName) const
const RCP< const FactoryBase > GetFactory(const std::string &varName) const
Default implementation of FactoryAcceptor::GetFactory()
bool IsAvailable(const std::string &ename, const FactoryBase *factory=NoFactory::get()) const
Test whether a need's value has been saved.
Exception throws to report errors in the internal logical of the program.
void Set(Level &level, const std::string &varName, const T &data) const
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()
#define SET_VALID_ENTRY(name)