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");
111 #undef SET_VALID_ENTRY 114 validParamList->set< RCP<const FactoryBase> >(
"Graph", null,
"Generating factory of the graph");
115 validParamList->set< RCP<const FactoryBase> >(
"DofsPerNode", null,
"Generating factory for variable \'DofsPerNode\', usually the same as for \'Graph\'");
116 validParamList->set< RCP<const FactoryBase> >(
"AggregateQualities", null,
"Generating factory for variable \'AggregateQualities\'");
119 validParamList->set< std::string > (
"OnePt aggregate map name",
"",
"Name of input map for single node aggregates. (default='')");
120 validParamList->set< std::string > (
"OnePt aggregate map factory",
"",
"Generating factory of (DOF) map for single node aggregates.");
125 validParamList->set< std::string > (
"Interface aggregate map name",
"",
"Name of input map for interface aggregates. (default='')");
126 validParamList->set< std::string > (
"Interface aggregate map factory",
"",
"Generating factory of (DOF) map for interface aggregates.");
127 validParamList->set<RCP<const FactoryBase> > (
"nodeOnInterface", Teuchos::null,
"Array specifying whether or not a node is on the interface (1 or 0).");
129 return validParamList;
132 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
134 Input(currentLevel,
"Graph");
135 Input(currentLevel,
"DofsPerNode");
137 const ParameterList& pL = GetParameterList();
140 std::string mapOnePtName = pL.get<std::string>(
"OnePt aggregate map name");
141 if (mapOnePtName.length() > 0) {
142 std::string mapOnePtFactName = pL.get<std::string>(
"OnePt aggregate map factory");
143 if (mapOnePtFactName ==
"" || mapOnePtFactName ==
"NoFactory") {
146 RCP<const FactoryBase> mapOnePtFact = GetFactory(mapOnePtFactName);
147 currentLevel.
DeclareInput(mapOnePtName, mapOnePtFact.get());
152 if (pL.get<
bool>(
"aggregation: use interface aggregation") ==
true){
159 "nodeOnInterface was not provided by the user on level0!");
162 Input(currentLevel,
"nodeOnInterface");
166 if (pL.get<
bool>(
"aggregation: compute aggregate qualities")) {
167 Input(currentLevel,
"AggregateQualities");
171 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
175 ParameterList pL = GetParameterList();
176 bDefinitionPhase_ =
false;
178 if (pL.get<
int>(
"aggregation: max agg size") == -1)
179 pL.set(
"aggregation: max agg size", INT_MAX);
182 RCP<const FactoryBase> graphFact = GetFactory(
"Graph");
188 if (pL.get<
bool>(
"aggregation: allow user-specified singletons") ==
true) algos_.push_back(rcp(
new OnePtAggregationAlgorithm (graphFact)));
200 std::string mapOnePtName = pL.get<std::string>(
"OnePt aggregate map name");
201 RCP<Map> OnePtMap = Teuchos::null;
202 if (mapOnePtName.length()) {
203 std::string mapOnePtFactName = pL.get<std::string>(
"OnePt aggregate map factory");
204 if (mapOnePtFactName ==
"" || mapOnePtFactName ==
"NoFactory") {
207 RCP<const FactoryBase> mapOnePtFact = GetFactory(mapOnePtFactName);
208 OnePtMap = currentLevel.
Get<RCP<Map> >(mapOnePtName, mapOnePtFact.get());
213 std::string mapInterfaceName = pL.get<std::string>(
"Interface aggregate map name");
214 RCP<Map> InterfaceMap = Teuchos::null;
216 RCP<const GraphBase> graph = Get< RCP<GraphBase> >(currentLevel,
"Graph");
219 RCP<Aggregates> aggregates = rcp(
new Aggregates(*graph));
220 aggregates->setObjectLabel(
"UC");
222 const LO numRows = graph->GetNodeNumVertices();
225 std::vector<unsigned> aggStat(numRows,
READY);
228 if (pL.get<
bool>(
"aggregation: use interface aggregation") ==
true){
229 Teuchos::Array<LO> nodeOnInterface = Get<Array<LO>>(currentLevel,
"nodeOnInterface");
230 for (LO i = 0; i < numRows; i++) {
231 if (nodeOnInterface[i])
236 ArrayRCP<const bool> dirichletBoundaryMap = graph->GetBoundaryNodeMap();
237 if (dirichletBoundaryMap != Teuchos::null)
238 for (LO i = 0; i < numRows; i++)
239 if (dirichletBoundaryMap[i] ==
true)
242 LO nDofsPerNode = Get<LO>(currentLevel,
"DofsPerNode");
243 GO indexBase = graph->GetDomainMap()->getIndexBase();
244 if (OnePtMap != Teuchos::null) {
245 for (LO i = 0; i < numRows; i++) {
247 GO grid = (graph->GetDomainMap()->getGlobalElement(i)-indexBase) * nDofsPerNode + indexBase;
249 for (LO kr = 0; kr < nDofsPerNode; kr++)
250 if (OnePtMap->isNodeGlobalElement(grid + kr))
257 const RCP<const Teuchos::Comm<int> > comm = graph->GetComm();
258 GO numGlobalRows = 0;
262 LO numNonAggregatedNodes = numRows;
263 GO numGlobalAggregatedPrev = 0, numGlobalAggsPrev = 0;
264 for (
size_t a = 0; a < algos_.size(); a++) {
265 std::string phase = algos_[a]->description();
268 int oldRank = algos_[a]->SetProcRankVerbose(this->GetProcRankVerbose());
269 algos_[a]->BuildAggregates(pL, *graph, *aggregates, aggStat, numNonAggregatedNodes);
270 algos_[a]->SetProcRankVerbose(oldRank);
273 GO numLocalAggregated = numRows - numNonAggregatedNodes, numGlobalAggregated = 0;
274 GO numLocalAggs = aggregates->GetNumAggregates(), numGlobalAggs = 0;
275 MueLu_sumAll(comm, numLocalAggregated, numGlobalAggregated);
278 double aggPercent = 100*as<double>(numGlobalAggregated)/as<double>(numGlobalRows);
279 if (aggPercent > 99.99 && aggPercent < 100.00) {
286 GetOStream(
Statistics1) <<
" aggregated : " << (numGlobalAggregated - numGlobalAggregatedPrev) <<
" (phase), " << std::fixed
287 << std::setprecision(2) << numGlobalAggregated <<
"/" << numGlobalRows <<
" [" << aggPercent <<
"%] (total)\n" 288 <<
" remaining : " << numGlobalRows - numGlobalAggregated <<
"\n" 289 <<
" aggregates : " << numGlobalAggs-numGlobalAggsPrev <<
" (phase), " << numGlobalAggs <<
" (total)" << std::endl;
290 numGlobalAggregatedPrev = numGlobalAggregated;
291 numGlobalAggsPrev = numGlobalAggs;
295 TEUCHOS_TEST_FOR_EXCEPTION(numNonAggregatedNodes,
Exceptions::RuntimeError,
"MueLu::UncoupledAggregationFactory::Build: Leftover nodes found! Error!");
297 aggregates->AggregatesCrossProcessors(
false);
298 aggregates->ComputeAggregateSizes(
true);
300 Set(currentLevel,
"Aggregates", aggregates);
302 if (pL.get<
bool>(
"aggregation: compute aggregate qualities")) {
303 RCP<Xpetra::MultiVector<DefaultScalar,LO,GO,Node>> aggQualities = Get<RCP<Xpetra::MultiVector<DefaultScalar,LO,GO,Node>>>(currentLevel,
"AggregateQualities");
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()