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");
124 #undef SET_VALID_ENTRY
129 validParamList->
set<
RCP<const FactoryBase> >(
"DofsPerNode", null,
"Generating factory for variable \'DofsPerNode\', usually the same as for \'Graph\'");
131 validParamList->
set<std::string> (
"OnePt aggregate map name",
"",
132 "Name of input map for single node aggregates. (default='')");
133 validParamList->
set<std::string> (
"OnePt aggregate map factory",
"",
134 "Generating factory of (DOF) map for single node aggregates.");
137 validParamList->
set< std::string > (
"Interface aggregate map name",
"",
138 "Name of input map for interface aggregates. (default='')");
139 validParamList->
set< std::string > (
"Interface aggregate map factory",
"",
140 "Generating factory of (DOF) map for interface aggregates.");
142 "Array specifying whether or not a node is on the interface (1 or 0).");
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: mode");
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();
285 std::vector<unsigned> aggStat(numRows,
READY);
288 std::string regionType;
289 if(currentLevel.GetLevelID() == 0) {
291 regionType = currentLevel.Get< std::string >(
"aggregationRegionType",
NoFactory::get());
294 regionType = Get< std::string >(currentLevel,
"aggregationRegionType");
296 *out<<
"p="<< myRank <<
" | "<<regionType<<
" | regionType determined" << std::endl;
299 if (regionType ==
"structured") {
305 const int numDimensions = pL.
get<
int>(
"aggregation: number of spatial dimensions");
306 const int interpolationOrder = pL.
get<
int>(
"aggregation: coarsening order");
307 std::string meshLayout = pL.
get<std::string>(
"aggregation: mesh layout");
308 std::string coupling = pL.
get<std::string>(
"aggregation: mode");
309 const bool coupled =
false;
312 if(currentLevel.GetLevelID() == 0) {
321 gFineNodesPerDir = Get<Array<GO> >(currentLevel,
"gNodesPerDim");
323 lFineNodesPerDir = Get<Array<LO> >(currentLevel,
"lNodesPerDim");
327 for(
int dim = numDimensions; dim < 3; ++dim) {
328 lFineNodesPerDir[dim] = 1;
332 std::string coarseningRate = pL.
get<std::string>(
"aggregation: coarsening rate");
335 coarseRate = Teuchos::fromStringToArray<LO>(coarseningRate);
337 GetOStream(
Errors,-1) <<
" *** \"aggregation: coarsening rate\" must be a string convertible into an array! *** "
343 "\"aggregation: coarsening rate\" must have at least as many"
344 " components as the number of spatial dimensions in the problem.");
360 "Coupled aggregation is not yet implemented in hybrid aggregation");
363 *out <<
"The index manager has now been built" << std::endl;
365 !=
static_cast<size_t>(geoData->getNumLocalFineNodes()),
367 "The local number of elements in the graph's map is not equal to "
368 "the number of nodes given by: lNodesPerDim!");
371 !=
static_cast<size_t>(geoData->getNumGlobalFineNodes()),
373 "The global number of elements in the graph's map is not equal to "
374 "the number of nodes given by: gNodesPerDim!");
377 *out <<
"Compute coarse mesh data" << std::endl;
378 std::vector<std::vector<GO> > coarseMeshData = geoData->getCoarseMeshData();
383 Set(currentLevel,
"gCoarseNodesPerDim", geoData->getGlobalCoarseNodesPerDir());
384 Set(currentLevel,
"lCoarseNodesPerDim", geoData->getLocalCoarseNodesPerDir());
388 if (regionType ==
"uncoupled"){
400 std::string mapInterfaceName = pL.
get<std::string>(
"Interface aggregate map name");
401 RCP<Map> InterfaceMap = Teuchos::null;
403 if (pL.
get<
bool>(
"aggregation: use interface aggregation") ==
true){
405 for (
LO i = 0; i < numRows; i++) {
406 if (nodeOnInterface[i])
413 if (dirichletBoundaryMap != Teuchos::null)
414 for (
LO i = 0; i < numRows; i++)
415 if (dirichletBoundaryMap[i] ==
true)
419 std::string mapOnePtName = pL.
get<std::string>(
"OnePt aggregate map name");
421 if (mapOnePtName.length()) {
422 std::string mapOnePtFactName = pL.
get<std::string>(
"OnePt aggregate map factory");
423 if (mapOnePtFactName ==
"" || mapOnePtFactName ==
"NoFactory") {
427 OnePtMap = currentLevel.Get<
RCP<Map> >(mapOnePtName, mapOnePtFact.
get());
430 LO nDofsPerNode = Get<LO>(currentLevel,
"DofsPerNode");
432 if (OnePtMap != Teuchos::null) {
433 for (
LO i = 0; i < numRows; i++) {
435 GO grid = (graph->
GetDomainMap()->getGlobalElement(i)-indexBase) * nDofsPerNode + indexBase;
436 for (
LO kr = 0; kr < nDofsPerNode; kr++)
437 if (OnePtMap->isNodeGlobalElement(grid + kr))
444 Set(currentLevel,
"lCoarseNodesPerDim", lCoarseNodesPerDir);
449 LO numNonAggregatedNodes = numRows;
450 for (
size_t a = 0; a < algos_.size(); a++) {
451 std::string phase = algos_[a]->description();
453 *out <<
"p=" << myRank <<
" | "<<regionType<<
" | Executing phase " << a << std::endl;
455 int oldRank = algos_[a]->SetProcRankVerbose(this->GetProcRankVerbose());
456 algos_[a]->BuildAggregates(pL, *graph, *aggregates, aggStat, numNonAggregatedNodes);
457 algos_[a]->SetProcRankVerbose(oldRank);
458 *out <<
"p=" << myRank <<
" | "<<regionType<<
" | Done Executing phase " << a << std::endl;
463 Set(currentLevel,
"Aggregates", aggregates);
465 Set(currentLevel,
"aggregationRegionTypeCoarse", regionType);
Algorithm for coarsening a graph with uncoupled aggregation. keep special marked nodes as singleton n...
Container class for aggregation information.
void setValidator(RCP< const ParameterEntryValidator > const &validator)
basic_FancyOStream & setShowProcRank(const bool showProcRank)
T & get(const std::string &name, T def_value)
virtual size_t GetNodeNumVertices() const =0
Return number of vertices owned by the calling node.
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
Timer to be used in factories. Similar to Monitor but with additional timers.
virtual const ArrayRCP< const bool > GetBoundaryNodeMap() const =0
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Algorithm for coarsening a graph with structured aggregation.
virtual const RCP< const Map > GetDomainMap() const =0
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
void SetIndexManager(RCP< IndexManager > &geoData)
Get the index manager used by structured aggregation algorithms.
Teuchos::ArrayRCP< LO > ComputeAggregateSizes(bool forceRecompute=false) const
Compute sizes of aggregates.
static const NoFactory * get()
Algorithm for coarsening a graph with uncoupled aggregation. creates aggregates along an interface us...
Builds one-to-one aggregates for all Dirichlet boundary nodes. For some applications this might be ne...
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Class that holds all level-specific information.
Timer to be used in factories. Similar to SubMonitor but adds a timer level by level.
virtual void setObjectLabel(const std::string &objectLabel)
basic_FancyOStream & setShowAllFrontMatter(const bool showAllFrontMatter)
void Build(Level ¤tLevel) const
Build aggregates.
Among unaggregated points, see if we can make a reasonable size aggregate out of it.IdeaAmong unaggregated points, see if we can make a reasonable size aggregate out of it. We do this by looking at neighbors and seeing how many are unaggregated and on my processor. Loosely, base the number of new aggregates created on the percentage of unaggregated nodes.
Add leftovers to existing aggregatesIdeaIn phase 2b non-aggregated nodes are added to existing aggreg...
void DeclareInput(Level ¤tLevel) const
Input.
Algorithm for coarsening a graph with uncoupled aggregation.
int GetLevelID() const
Return level number.
Exception throws to report errors in the internal logical of the program.
HybridAggregationFactory()
Constructor.
Handle leftover nodes. Try to avoid singleton nodesIdeaIn phase 3 we try to stick unaggregated nodes ...
#define SET_VALID_ENTRY(name)
ParameterEntry & getEntry(const std::string &name)
std::string description() const
Return a simple one-line description of this object.
void AggregatesCrossProcessors(const bool &flag)
Record whether aggregates include DOFs from other processes.
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()
bool IsAvailable(const std::string &ename, const FactoryBase *factory=NoFactory::get()) const
Test whether a need's value has been saved.
void SetNumAggregates(LO nAggregates)
Set number of local aggregates on current processor.