46 #ifndef MUELU_UNCOUPLEDAGGREGATIONFACTORY_DEF_HPP_ 47 #define MUELU_UNCOUPLEDAGGREGATIONFACTORY_DEF_HPP_ 51 #include <Xpetra_Map.hpp> 52 #include <Xpetra_Vector.hpp> 53 #include <Xpetra_MultiVectorFactory.hpp> 54 #include <Xpetra_VectorFactory.hpp> 58 #include "MueLu_OnePtAggregationAlgorithm.hpp" 59 #include "MueLu_PreserveDirichletAggregationAlgorithm.hpp" 60 #include "MueLu_IsolatedNodeAggregationAlgorithm.hpp" 62 #include "MueLu_AggregationPhase1Algorithm.hpp" 63 #include "MueLu_AggregationPhase2aAlgorithm.hpp" 64 #include "MueLu_AggregationPhase2bAlgorithm.hpp" 65 #include "MueLu_AggregationPhase3Algorithm.hpp" 69 #include "MueLu_Aggregates.hpp" 72 #include "MueLu_AmalgamationInfo.hpp" 73 #include "MueLu_Utilities.hpp" 77 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
79 : bDefinitionPhase_(true)
82 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
84 RCP<ParameterList> validParamList = rcp(
new ParameterList());
89 typedef Teuchos::StringToIntegralParameterEntryValidator<int> validatorType;
90 #define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name)) 95 validParamList->getEntry(
"aggregation: ordering").setValidator(
96 rcp(
new validatorType(Teuchos::tuple<std::string>(
"natural",
"graph",
"random"),
"aggregation: ordering")));
103 SET_VALID_ENTRY(
"aggregation: error on nodes with no on-rank neighbors");
104 #undef SET_VALID_ENTRY 107 validParamList->set< RCP<const FactoryBase> >(
"Graph", null,
"Generating factory of the graph");
108 validParamList->set< RCP<const FactoryBase> >(
"DofsPerNode", null,
"Generating factory for variable \'DofsPerNode\', usually the same as for \'Graph\'");
111 validParamList->set< std::string > (
"OnePt aggregate map name",
"",
"Name of input map for single node aggregates. (default='')");
112 validParamList->set< std::string > (
"OnePt aggregate map factory",
"",
"Generating factory of (DOF) map for single node aggregates.");
115 return validParamList;
118 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
120 Input(currentLevel,
"Graph");
121 Input(currentLevel,
"DofsPerNode");
126 std::string mapOnePtName = pL.get<std::string>(
"OnePt aggregate map name");
127 if (mapOnePtName.length() > 0) {
128 std::string mapOnePtFactName = pL.get<std::string>(
"OnePt aggregate map factory");
129 if (mapOnePtFactName ==
"" || mapOnePtFactName ==
"NoFactory") {
132 RCP<const FactoryBase> mapOnePtFact =
GetFactory(mapOnePtFactName);
133 currentLevel.
DeclareInput(mapOnePtName, mapOnePtFact.get());
138 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
145 if (pL.get<
int>(
"aggregation: max agg size") == -1)
146 pL.set(
"aggregation: max agg size", INT_MAX);
149 RCP<const FactoryBase> graphFact =
GetFactory(
"Graph");
166 std::string mapOnePtName = pL.get<std::string>(
"OnePt aggregate map name");
167 RCP<Map> OnePtMap = Teuchos::null;
168 if (mapOnePtName.length()) {
169 std::string mapOnePtFactName = pL.get<std::string>(
"OnePt aggregate map factory");
170 if (mapOnePtFactName ==
"" || mapOnePtFactName ==
"NoFactory") {
173 RCP<const FactoryBase> mapOnePtFact =
GetFactory(mapOnePtFactName);
174 OnePtMap = currentLevel.
Get<RCP<Map> >(mapOnePtName, mapOnePtFact.get());
178 RCP<const GraphBase> graph = Get< RCP<GraphBase> >(currentLevel,
"Graph");
181 RCP<Aggregates> aggregates = rcp(
new Aggregates(*graph));
182 aggregates->setObjectLabel(
"UC");
184 const LO numRows = graph->GetNodeNumVertices();
187 std::vector<unsigned> aggStat(numRows,
READY);
189 ArrayRCP<const bool> dirichletBoundaryMap = graph->GetBoundaryNodeMap();
190 if (dirichletBoundaryMap != Teuchos::null)
191 for (LO i = 0; i < numRows; i++)
192 if (dirichletBoundaryMap[i] ==
true)
195 LO nDofsPerNode = Get<LO>(currentLevel,
"DofsPerNode");
196 GO indexBase = graph->GetDomainMap()->getIndexBase();
197 if (OnePtMap != Teuchos::null) {
198 for (LO i = 0; i < numRows; i++) {
200 GO grid = (graph->GetDomainMap()->getGlobalElement(i)-indexBase) * nDofsPerNode + indexBase;
202 for (LO kr = 0; kr < nDofsPerNode; kr++)
203 if (OnePtMap->isNodeGlobalElement(grid + kr))
209 const RCP<const Teuchos::Comm<int> > comm = graph->GetComm();
210 GO numGlobalRows = 0;
214 LO numNonAggregatedNodes = numRows;
215 GO numGlobalAggregatedPrev = 0, numGlobalAggsPrev = 0;
216 for (
size_t a = 0; a <
algos_.size(); a++) {
217 std::string phase =
algos_[a]->description();
221 algos_[a]->BuildAggregates(pL, *graph, *aggregates, aggStat, numNonAggregatedNodes);
222 algos_[a]->SetProcRankVerbose(oldRank);
225 GO numLocalAggregated = numRows - numNonAggregatedNodes, numGlobalAggregated = 0;
226 GO numLocalAggs = aggregates->GetNumAggregates(), numGlobalAggs = 0;
227 MueLu_sumAll(comm, numLocalAggregated, numGlobalAggregated);
230 double aggPercent = 100*as<double>(numGlobalAggregated)/as<double>(numGlobalRows);
231 if (aggPercent > 99.99 && aggPercent < 100.00) {
238 GetOStream(
Statistics1) <<
" aggregated : " << (numGlobalAggregated - numGlobalAggregatedPrev) <<
" (phase), " << std::fixed
239 << std::setprecision(2) << numGlobalAggregated <<
"/" << numGlobalRows <<
" [" << aggPercent <<
"%] (total)\n" 240 <<
" remaining : " << numGlobalRows - numGlobalAggregated <<
"\n" 241 <<
" aggregates : " << numGlobalAggs-numGlobalAggsPrev <<
" (phase), " << numGlobalAggs <<
" (total)" << std::endl;
242 numGlobalAggregatedPrev = numGlobalAggregated;
243 numGlobalAggsPrev = numGlobalAggs;
247 TEUCHOS_TEST_FOR_EXCEPTION(numNonAggregatedNodes,
Exceptions::RuntimeError,
"MueLu::UncoupledAggregationFactory::Build: Leftover nodes found! Error!");
249 aggregates->AggregatesCrossProcessors(
false);
251 Set(currentLevel,
"Aggregates", aggregates);
std::vector< RCP< MueLu::AggregationAlgorithmBase< LocalOrdinal, GlobalOrdinal, Node > > > algos_
Append a new aggregation algorithm to list of aggregation algorithms.
Algorithm for coarsening a graph with uncoupled aggregation. keep special marked nodes as singleton n...
#define MueLu_sumAll(rcpComm, in, out)
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access). Usage: Level->Get< RCP<Matrix> >("A", factory) if factory == NULL => use default factory.
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.
void DeclareInput(Level ¤tLevel) const
Input.
Namespace for MueLu classes and methods.
void Build(Level ¤tLevel) const
Build aggregates.
bool IsPrint(MsgType type, int thisProcRankOnly=-1) const
Find out whether we need to print out information for a specific message type.
static const NoFactory * get()
Builds one-to-one aggregates for all Dirichlet boundary nodes. For some applications this might be ne...
Class that holds all level-specific information.
Timer to be used in factories. Similar to SubMonitor but adds a timer level by level.
int GetProcRankVerbose() const
Get proc rank used for printing. Do not use this information for any other purpose.
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
virtual const Teuchos::ParameterList & GetParameterList() const
#define SET_VALID_ENTRY(name)
UncoupledAggregationFactory()
Constructor.
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 Input(Level &level, const std::string &varName) const
const RCP< const FactoryBase > GetFactory(const std::string &varName) const
Default implementation of FactoryAcceptor::GetFactory()
Algorithm for coarsening a graph with uncoupled aggregation.
Exception throws to report errors in the internal logical of the program.
Handle leftover nodes. Try to avoid singleton nodesIdeaIn phase 3 we try to stick unaggregated nodes ...
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()