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");
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");
100 validParamList->set<
const bool>(
"aggregation: single coarse point",
false,
101 "Allows the aggreagtion process to reduce spacial dimensions to a single layer");
103 return validParamList;
106 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
109 Input(currentLevel,
"Graph");
110 Input(currentLevel,
"DofsPerNode");
112 ParameterList pL = GetParameterList();
113 std::string coupling = pL.get<std::string>(
"aggregation: mode");
114 const bool coupled = (coupling ==
"coupled" ? true :
false);
123 "gNodesPerDim was not provided by the user on level0!");
126 Input(currentLevel,
"gNodesPerDim");
137 "numDimensions was not provided by the user on level0!");
144 "lNodesPerDim was not provided by the user on level0!");
147 Input(currentLevel,
"numDimensions");
148 Input(currentLevel,
"lNodesPerDim");
152 template <
class Scalar,
class LocalOrdinal,
class GlobalOrdinal,
class Node>
157 RCP<Teuchos::FancyOStream> out;
158 if(
const char* dbg = std::getenv(
"MUELU_STRUCTUREDAGGREGATION_DEBUG")) {
159 out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
160 out->setShowAllFrontMatter(
false).setShowProcRank(
true);
162 out = Teuchos::getFancyOStream(rcp(
new Teuchos::oblackholestream()));
165 *out <<
"Entering structured aggregation" << std::endl;
167 ParameterList pL = GetParameterList();
168 bDefinitionPhase_ =
false;
171 RCP<const GraphBase> graph = Get< RCP<GraphBase> >(currentLevel,
"Graph");
172 RCP<const Map> fineMap = graph->GetDomainMap();
173 const int myRank = fineMap->getComm()->getRank();
174 const int numRanks = fineMap->getComm()->getSize();
175 const GO minGlobalIndex = fineMap->getMinGlobalIndex();
176 const LO dofsPerNode = Get<LO>(currentLevel,
"DofsPerNode");
180 const int interpolationOrder = pL.get<
int>(
"aggregation: coarsening order");
181 std::string meshLayout = pL.get<std::string>(
"aggregation: mesh layout");
182 std::string coupling = pL.get<std::string>(
"aggregation: mode");
183 const bool coupled = (coupling ==
"coupled" ? true :
false);
184 std::string outputType = pL.get<std::string>(
"aggregation: output type");
185 const bool outputAggregates = (outputType ==
"Aggregates" ? true :
false);
186 const bool singleCoarsePoint = pL.get<
bool>(
"aggregation: single coarse point");
188 Array<GO> gFineNodesPerDir(3);
189 Array<LO> lFineNodesPerDir(3);
193 lFineNodesPerDir = currentLevel.
Get<Array<LO> >(
"lNodesPerDim",
NoFactory::get());
195 gFineNodesPerDir = currentLevel.
Get<Array<GO> >(
"gNodesPerDim",
NoFactory::get());
199 numDimensions = Get<int>(currentLevel,
"numDimensions");
200 lFineNodesPerDir = Get<Array<LO> >(currentLevel,
"lNodesPerDim");
202 gFineNodesPerDir = Get<Array<GO> >(currentLevel,
"gNodesPerDim");
208 for(
int dim = 0; dim < 3; ++dim) {
209 if(dim >= numDimensions) {
210 gFineNodesPerDir[dim] = 1;
211 lFineNodesPerDir[dim] = 1;
216 std::string coarseningRate = pL.get<std::string>(
"aggregation: coarsening rate");
217 Teuchos::Array<LO> coarseRate;
219 coarseRate = Teuchos::fromStringToArray<LO>(coarseningRate);
220 }
catch(
const Teuchos::InvalidArrayStringRepresentation& e) {
221 GetOStream(
Errors,-1) <<
" *** \"aggregation: coarsening rate\" must be a string convertible into an array! *** "
225 TEUCHOS_TEST_FOR_EXCEPTION((coarseRate.size() > 1) && (coarseRate.size() < numDimensions),
227 "\"aggregation: coarsening rate\" must have at least as many"
228 " components as the number of spatial dimensions in the problem.");
231 RCP<IndexManager > geoData;
243 }
else if(meshLayout ==
"Local Lexicographic") {
247 meshData = currentLevel.
Get<Array<GO> >(
"aggregation: mesh data",
NoFactory::get());
249 "The meshData array is empty, somehow the input for structured"
250 " aggregation are not captured correctly.");
253 meshData = Get<Array<GO> >(currentLevel,
"aggregation: mesh data");
269 }
else if(meshLayout ==
"Global Lexicographic") {
285 *out <<
"The index manager has now been built" << std::endl;
286 *out <<
"graph num nodes: " << fineMap->getLocalNumElements()
287 <<
", structured aggregation num nodes: " << geoData->getNumLocalFineNodes() << std::endl;
288 TEUCHOS_TEST_FOR_EXCEPTION(fineMap->getLocalNumElements()
289 !=
static_cast<size_t>(geoData->getNumLocalFineNodes()),
291 "The local number of elements in the graph's map is not equal to "
292 "the number of nodes given by: lNodesPerDim!");
294 TEUCHOS_TEST_FOR_EXCEPTION(fineMap->getGlobalNumElements()
295 !=
static_cast<size_t>(geoData->getNumGlobalFineNodes()),
297 "The global number of elements in the graph's map is not equal to "
298 "the number of nodes given by: gNodesPerDim!");
301 *out <<
"Compute coarse mesh data" << std::endl;
302 std::vector<std::vector<GO> > coarseMeshData = geoData->getCoarseMeshData();
306 RCP<const FactoryBase> graphFact = GetFactory(
"Graph");
307 RCP<const Map> coarseCoordinatesFineMap, coarseCoordinatesMap;
308 RCP<MueLu::AggregationStructuredAlgorithm<LocalOrdinal, GlobalOrdinal, Node> >
311 if(interpolationOrder == 0 && outputAggregates){
313 *out <<
"Compute Aggregates" << std::endl;
314 RCP<Aggregates> aggregates = rcp(
new Aggregates(graph->GetDomainMap()));
315 aggregates->setObjectLabel(
"ST");
316 aggregates->SetIndexManager(geoData);
317 aggregates->AggregatesCrossProcessors(coupled);
318 aggregates->SetNumAggregates(geoData->getNumLocalCoarseNodes());
319 std::vector<unsigned> aggStat(geoData->getNumLocalFineNodes(),
READY);
320 LO numNonAggregatedNodes = geoData->getNumLocalFineNodes();
322 myStructuredAlgorithm->BuildAggregates(pL, *graph, *aggregates, aggStat,
323 numNonAggregatedNodes);
326 "MueLu::StructuredAggregationFactory::Build: Leftover nodes found! Error!");
327 aggregates->ComputeAggregateSizes(
true);
328 GetOStream(
Statistics1) << aggregates->description() << std::endl;
329 Set(currentLevel,
"Aggregates", aggregates);
333 *out <<
"Compute CrsGraph" << std::endl;
334 RCP<CrsGraph> myGraph;
335 myStructuredAlgorithm->BuildGraph(*graph, geoData, dofsPerNode, myGraph,
336 coarseCoordinatesFineMap, coarseCoordinatesMap);
337 Set(currentLevel,
"prolongatorGraph", myGraph);
341 Set(currentLevel,
"gCoarseNodesPerDim", geoData->getGlobalCoarseNodesPerDir());
343 Set(currentLevel,
"lCoarseNodesPerDim", geoData->getLocalCoarseNodesPerDir());
344 Set(currentLevel,
"coarseCoordinatesFineMap", coarseCoordinatesFineMap);
345 Set(currentLevel,
"coarseCoordinatesMap", coarseCoordinatesMap);
346 Set(currentLevel,
"structuredInterpolationOrder", interpolationOrder);
347 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.