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_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" 70 #include "MueLu_Aggregates.hpp" 73 #include "MueLu_AmalgamationInfo.hpp" 74 #include "MueLu_Utilities.hpp" 78 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
80 : bDefinitionPhase_(true)
83 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
85 RCP<ParameterList> validParamList = rcp(
new ParameterList());
90 typedef Teuchos::StringToIntegralParameterEntryValidator<int> validatorType;
91 #define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name)) 96 validParamList->getEntry(
"aggregation: ordering").setValidator(
97 rcp(
new validatorType(Teuchos::tuple<std::string>(
"natural",
"graph",
"random"),
"aggregation: ordering")));
107 SET_VALID_ENTRY(
"aggregation: error on nodes with no on-rank neighbors");
110 #undef SET_VALID_ENTRY 113 validParamList->set< RCP<const FactoryBase> >(
"Graph", null,
"Generating factory of the graph");
114 validParamList->set< RCP<const FactoryBase> >(
"DofsPerNode", null,
"Generating factory for variable \'DofsPerNode\', usually the same as for \'Graph\'");
115 validParamList->set< RCP<const FactoryBase> >(
"AggregateQualities", null,
"Generating factory for variable \'AggregateQualities\'");
118 validParamList->set< std::string > (
"OnePt aggregate map name",
"",
"Name of input map for single node aggregates. (default='')");
119 validParamList->set< std::string > (
"OnePt aggregate map factory",
"",
"Generating factory of (DOF) map for single node aggregates.");
124 validParamList->set< std::string > (
"Interface aggregate map name",
"",
"Name of input map for interface aggregates. (default='')");
125 validParamList->set< std::string > (
"Interface aggregate map factory",
"",
"Generating factory of (DOF) map for interface aggregates.");
126 validParamList->set<RCP<const FactoryBase> > (
"nodeOnInterface", Teuchos::null,
"Array specifying whether or not a node is on the interface (1 or 0).");
128 return validParamList;
131 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
133 Input(currentLevel,
"Graph");
134 Input(currentLevel,
"DofsPerNode");
136 const ParameterList& pL = GetParameterList();
139 std::string mapOnePtName = pL.get<std::string>(
"OnePt aggregate map name");
140 if (mapOnePtName.length() > 0) {
141 std::string mapOnePtFactName = pL.get<std::string>(
"OnePt aggregate map factory");
142 if (mapOnePtFactName ==
"" || mapOnePtFactName ==
"NoFactory") {
145 RCP<const FactoryBase> mapOnePtFact = GetFactory(mapOnePtFactName);
146 currentLevel.
DeclareInput(mapOnePtName, mapOnePtFact.get());
151 if (pL.get<
bool>(
"aggregation: use interface aggregation") ==
true){
158 "nodeOnInterface was not provided by the user on level0!");
161 Input(currentLevel,
"nodeOnInterface");
165 if (pL.get<
bool>(
"aggregation: compute aggregate qualities")) {
166 Input(currentLevel,
"AggregateQualities");
170 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
174 ParameterList pL = GetParameterList();
175 bDefinitionPhase_ =
false;
177 if (pL.get<
int>(
"aggregation: max agg size") == -1)
178 pL.set(
"aggregation: max agg size", INT_MAX);
181 RCP<const FactoryBase> graphFact = GetFactory(
"Graph");
187 if (pL.get<
bool>(
"aggregation: allow user-specified singletons") ==
true) algos_.push_back(rcp(
new OnePtAggregationAlgorithm (graphFact)));
199 std::string mapOnePtName = pL.get<std::string>(
"OnePt aggregate map name");
200 RCP<Map> OnePtMap = Teuchos::null;
201 if (mapOnePtName.length()) {
202 std::string mapOnePtFactName = pL.get<std::string>(
"OnePt aggregate map factory");
203 if (mapOnePtFactName ==
"" || mapOnePtFactName ==
"NoFactory") {
206 RCP<const FactoryBase> mapOnePtFact = GetFactory(mapOnePtFactName);
207 OnePtMap = currentLevel.
Get<RCP<Map> >(mapOnePtName, mapOnePtFact.get());
212 std::string mapInterfaceName = pL.get<std::string>(
"Interface aggregate map name");
213 RCP<Map> InterfaceMap = Teuchos::null;
215 RCP<const GraphBase> graph = Get< RCP<GraphBase> >(currentLevel,
"Graph");
218 RCP<Aggregates> aggregates = rcp(
new Aggregates(*graph));
219 aggregates->setObjectLabel(
"UC");
221 const LO numRows = graph->GetNodeNumVertices();
224 std::vector<unsigned> aggStat(numRows,
READY);
227 if (pL.get<
bool>(
"aggregation: use interface aggregation") ==
true){
228 Teuchos::Array<LO> nodeOnInterface = Get<Array<LO>>(currentLevel,
"nodeOnInterface");
229 for (LO i = 0; i < numRows; i++) {
230 if (nodeOnInterface[i])
235 ArrayRCP<const bool> dirichletBoundaryMap = graph->GetBoundaryNodeMap();
236 if (dirichletBoundaryMap != Teuchos::null)
237 for (LO i = 0; i < numRows; i++)
238 if (dirichletBoundaryMap[i] ==
true)
241 LO nDofsPerNode = Get<LO>(currentLevel,
"DofsPerNode");
242 GO indexBase = graph->GetDomainMap()->getIndexBase();
243 if (OnePtMap != Teuchos::null) {
244 for (LO i = 0; i < numRows; i++) {
246 GO grid = (graph->GetDomainMap()->getGlobalElement(i)-indexBase) * nDofsPerNode + indexBase;
248 for (LO kr = 0; kr < nDofsPerNode; kr++)
249 if (OnePtMap->isNodeGlobalElement(grid + kr))
256 const RCP<const Teuchos::Comm<int> > comm = graph->GetComm();
257 GO numGlobalRows = 0;
261 LO numNonAggregatedNodes = numRows;
262 GO numGlobalAggregatedPrev = 0, numGlobalAggsPrev = 0;
263 for (
size_t a = 0; a < algos_.size(); a++) {
264 std::string phase = algos_[a]->description();
267 int oldRank = algos_[a]->SetProcRankVerbose(this->GetProcRankVerbose());
268 algos_[a]->BuildAggregates(pL, *graph, *aggregates, aggStat, numNonAggregatedNodes);
269 algos_[a]->SetProcRankVerbose(oldRank);
272 GO numLocalAggregated = numRows - numNonAggregatedNodes, numGlobalAggregated = 0;
273 GO numLocalAggs = aggregates->GetNumAggregates(), numGlobalAggs = 0;
274 MueLu_sumAll(comm, numLocalAggregated, numGlobalAggregated);
277 double aggPercent = 100*as<double>(numGlobalAggregated)/as<double>(numGlobalRows);
278 if (aggPercent > 99.99 && aggPercent < 100.00) {
285 GetOStream(
Statistics1) <<
" aggregated : " << (numGlobalAggregated - numGlobalAggregatedPrev) <<
" (phase), " << std::fixed
286 << std::setprecision(2) << numGlobalAggregated <<
"/" << numGlobalRows <<
" [" << aggPercent <<
"%] (total)\n" 287 <<
" remaining : " << numGlobalRows - numGlobalAggregated <<
"\n" 288 <<
" aggregates : " << numGlobalAggs-numGlobalAggsPrev <<
" (phase), " << numGlobalAggs <<
" (total)" << std::endl;
289 numGlobalAggregatedPrev = numGlobalAggregated;
290 numGlobalAggsPrev = numGlobalAggs;
294 TEUCHOS_TEST_FOR_EXCEPTION(numNonAggregatedNodes,
Exceptions::RuntimeError,
"MueLu::UncoupledAggregationFactory::Build: Leftover nodes found! Error!");
296 aggregates->AggregatesCrossProcessors(
false);
297 aggregates->ComputeAggregateSizes(
true);
299 Set(currentLevel,
"Aggregates", aggregates);
301 if (pL.get<
bool>(
"aggregation: compute aggregate qualities")) {
302 RCP<Xpetra::MultiVector<double,LO,GO,Node>> aggQualities = Get<RCP<Xpetra::MultiVector<double,LO,GO,Node>>>(currentLevel,
"AggregateQualities");
306 GetOStream(
Statistics1) << aggregates->description() << std::endl;
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.
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.
static const NoFactory * get()
int GetLevelID() const
Return level number.
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...
Class that holds all level-specific information.
Timer to be used in factories. Similar to SubMonitor but adds a timer level by level.
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
#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...
Algorithm for coarsening a graph with uncoupled aggregation.
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.
Handle leftover nodes. Try to avoid singleton nodesIdeaIn phase 3 we try to stick unaggregated nodes ...
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()