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")));
106 SET_VALID_ENTRY(
"aggregation: error on nodes with no on-rank neighbors");
109 #undef SET_VALID_ENTRY 112 validParamList->set< RCP<const FactoryBase> >(
"Graph", null,
"Generating factory of the graph");
113 validParamList->set< RCP<const FactoryBase> >(
"DofsPerNode", null,
"Generating factory for variable \'DofsPerNode\', usually the same as for \'Graph\'");
114 validParamList->set< RCP<const FactoryBase> >(
"AggregateQualities", null,
"Generating factory for variable \'AggregateQualities\'");
117 validParamList->set< std::string > (
"OnePt aggregate map name",
"",
"Name of input map for single node aggregates. (default='')");
118 validParamList->set< std::string > (
"OnePt aggregate map factory",
"",
"Generating factory of (DOF) map for single node aggregates.");
123 validParamList->set< std::string > (
"Interface aggregate map name",
"",
"Name of input map for interface aggregates. (default='')");
124 validParamList->set< std::string > (
"Interface aggregate map factory",
"",
"Generating factory of (DOF) map for interface aggregates.");
125 validParamList->set<RCP<const FactoryBase> > (
"nodeOnInterface", Teuchos::null,
"Array specifying whether or not a node is on the interface (1 or 0).");
127 return validParamList;
130 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
132 Input(currentLevel,
"Graph");
133 Input(currentLevel,
"DofsPerNode");
135 const ParameterList& pL = GetParameterList();
138 std::string mapOnePtName = pL.get<std::string>(
"OnePt aggregate map name");
139 if (mapOnePtName.length() > 0) {
140 std::string mapOnePtFactName = pL.get<std::string>(
"OnePt aggregate map factory");
141 if (mapOnePtFactName ==
"" || mapOnePtFactName ==
"NoFactory") {
144 RCP<const FactoryBase> mapOnePtFact = GetFactory(mapOnePtFactName);
145 currentLevel.
DeclareInput(mapOnePtName, mapOnePtFact.get());
150 if (pL.get<
bool>(
"aggregation: use interface aggregation") ==
true){
157 "nodeOnInterface was not provided by the user on level0!");
160 Input(currentLevel,
"nodeOnInterface");
164 if (pL.get<
bool>(
"aggregation: compute aggregate qualities")) {
165 Input(currentLevel,
"AggregateQualities");
169 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
173 ParameterList pL = GetParameterList();
174 bDefinitionPhase_ =
false;
176 if (pL.get<
int>(
"aggregation: max agg size") == -1)
177 pL.set(
"aggregation: max agg size", INT_MAX);
180 RCP<const FactoryBase> graphFact = GetFactory(
"Graph");
186 if (pL.get<
bool>(
"aggregation: allow user-specified singletons") ==
true) algos_.push_back(rcp(
new OnePtAggregationAlgorithm (graphFact)));
198 std::string mapOnePtName = pL.get<std::string>(
"OnePt aggregate map name");
199 RCP<Map> OnePtMap = Teuchos::null;
200 if (mapOnePtName.length()) {
201 std::string mapOnePtFactName = pL.get<std::string>(
"OnePt aggregate map factory");
202 if (mapOnePtFactName ==
"" || mapOnePtFactName ==
"NoFactory") {
205 RCP<const FactoryBase> mapOnePtFact = GetFactory(mapOnePtFactName);
206 OnePtMap = currentLevel.
Get<RCP<Map> >(mapOnePtName, mapOnePtFact.get());
211 std::string mapInterfaceName = pL.get<std::string>(
"Interface aggregate map name");
212 RCP<Map> InterfaceMap = Teuchos::null;
214 RCP<const GraphBase> graph = Get< RCP<GraphBase> >(currentLevel,
"Graph");
217 RCP<Aggregates> aggregates = rcp(
new Aggregates(*graph));
218 aggregates->setObjectLabel(
"UC");
220 const LO numRows = graph->GetNodeNumVertices();
223 std::vector<unsigned> aggStat(numRows,
READY);
226 if (pL.get<
bool>(
"aggregation: use interface aggregation") ==
true){
227 Teuchos::Array<LO> nodeOnInterface = Get<Array<LO>>(currentLevel,
"nodeOnInterface");
228 for (LO i = 0; i < numRows; i++) {
229 if (nodeOnInterface[i])
234 ArrayRCP<const bool> dirichletBoundaryMap = graph->GetBoundaryNodeMap();
235 if (dirichletBoundaryMap != Teuchos::null)
236 for (LO i = 0; i < numRows; i++)
237 if (dirichletBoundaryMap[i] ==
true)
240 LO nDofsPerNode = Get<LO>(currentLevel,
"DofsPerNode");
241 GO indexBase = graph->GetDomainMap()->getIndexBase();
242 if (OnePtMap != Teuchos::null) {
243 for (LO i = 0; i < numRows; i++) {
245 GO grid = (graph->GetDomainMap()->getGlobalElement(i)-indexBase) * nDofsPerNode + indexBase;
247 for (LO kr = 0; kr < nDofsPerNode; kr++)
248 if (OnePtMap->isNodeGlobalElement(grid + kr))
255 const RCP<const Teuchos::Comm<int> > comm = graph->GetComm();
256 GO numGlobalRows = 0;
260 LO numNonAggregatedNodes = numRows;
261 GO numGlobalAggregatedPrev = 0, numGlobalAggsPrev = 0;
262 for (
size_t a = 0; a < algos_.size(); a++) {
263 std::string phase = algos_[a]->description();
266 int oldRank = algos_[a]->SetProcRankVerbose(this->GetProcRankVerbose());
267 algos_[a]->BuildAggregates(pL, *graph, *aggregates, aggStat, numNonAggregatedNodes);
268 algos_[a]->SetProcRankVerbose(oldRank);
271 GO numLocalAggregated = numRows - numNonAggregatedNodes, numGlobalAggregated = 0;
272 GO numLocalAggs = aggregates->GetNumAggregates(), numGlobalAggs = 0;
273 MueLu_sumAll(comm, numLocalAggregated, numGlobalAggregated);
276 double aggPercent = 100*as<double>(numGlobalAggregated)/as<double>(numGlobalRows);
277 if (aggPercent > 99.99 && aggPercent < 100.00) {
284 GetOStream(
Statistics1) <<
" aggregated : " << (numGlobalAggregated - numGlobalAggregatedPrev) <<
" (phase), " << std::fixed
285 << std::setprecision(2) << numGlobalAggregated <<
"/" << numGlobalRows <<
" [" << aggPercent <<
"%] (total)\n" 286 <<
" remaining : " << numGlobalRows - numGlobalAggregated <<
"\n" 287 <<
" aggregates : " << numGlobalAggs-numGlobalAggsPrev <<
" (phase), " << numGlobalAggs <<
" (total)" << std::endl;
288 numGlobalAggregatedPrev = numGlobalAggregated;
289 numGlobalAggsPrev = numGlobalAggs;
293 TEUCHOS_TEST_FOR_EXCEPTION(numNonAggregatedNodes,
Exceptions::RuntimeError,
"MueLu::UncoupledAggregationFactory::Build: Leftover nodes found! Error!");
295 aggregates->AggregatesCrossProcessors(
false);
296 aggregates->ComputeAggregateSizes(
true);
298 Set(currentLevel,
"Aggregates", aggregates);
300 if (pL.get<
bool>(
"aggregation: compute aggregate qualities")) {
301 RCP<Xpetra::MultiVector<double,LO,GO,Node>> aggQualities = Get<RCP<Xpetra::MultiVector<double,LO,GO,Node>>>(currentLevel,
"AggregateQualities");
304 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()