46 #ifndef MUELU_UNCOUPLEDAGGREGATIONFACTORY_KOKKOS_DEF_HPP_ 47 #define MUELU_UNCOUPLEDAGGREGATIONFACTORY_KOKKOS_DEF_HPP_ 49 #ifdef HAVE_MUELU_KOKKOS_REFACTOR 53 #include <Xpetra_Map.hpp> 54 #include <Xpetra_Vector.hpp> 55 #include <Xpetra_MultiVectorFactory.hpp> 56 #include <Xpetra_VectorFactory.hpp> 60 #include "MueLu_OnePtAggregationAlgorithm_kokkos.hpp" 61 #include "MueLu_PreserveDirichletAggregationAlgorithm_kokkos.hpp" 62 #include "MueLu_IsolatedNodeAggregationAlgorithm_kokkos.hpp" 64 #include "MueLu_AggregationPhase1Algorithm_kokkos.hpp" 65 #include "MueLu_AggregationPhase2aAlgorithm_kokkos.hpp" 66 #include "MueLu_AggregationPhase2bAlgorithm_kokkos.hpp" 67 #include "MueLu_AggregationPhase3Algorithm_kokkos.hpp" 70 #include "MueLu_LWGraph_kokkos.hpp" 71 #include "MueLu_Aggregates_kokkos.hpp" 74 #include "MueLu_AmalgamationInfo.hpp" 75 #include "MueLu_Utilities.hpp" 79 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
80 UncoupledAggregationFactory_kokkos<LocalOrdinal, GlobalOrdinal, Node>::UncoupledAggregationFactory_kokkos()
81 : bDefinitionPhase_(true)
84 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
85 RCP<const ParameterList> UncoupledAggregationFactory_kokkos<LocalOrdinal, GlobalOrdinal, Node>::GetValidParameterList()
const {
86 RCP<ParameterList> validParamList = rcp(
new ParameterList());
91 typedef Teuchos::StringToIntegralParameterEntryValidator<int> validatorType;
92 #define SET_VALID_ENTRY(name) validParamList->setEntry(name, MasterList::getEntry(name)) 97 validParamList->getEntry(
"aggregation: ordering").setValidator(
98 rcp(
new validatorType(Teuchos::tuple<std::string>(
"natural",
"graph",
"random"),
"aggregation: ordering")));
106 #undef SET_VALID_ENTRY 109 validParamList->set< RCP<const FactoryBase> >(
"Graph", null,
"Generating factory of the graph");
110 validParamList->set< RCP<const FactoryBase> >(
"DofsPerNode", null,
"Generating factory for variable \'DofsPerNode\', usually the same as for \'Graph\'");
113 validParamList->set< std::string > (
"OnePt aggregate map name",
"",
"Name of input map for single node aggregates. (default='')");
114 validParamList->set< std::string > (
"OnePt aggregate map factory",
"",
"Generating factory of (DOF) map for single node aggregates.");
117 return validParamList;
120 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
121 void UncoupledAggregationFactory_kokkos<LocalOrdinal, GlobalOrdinal, Node>::DeclareInput(Level& currentLevel)
const {
122 Input(currentLevel,
"Graph");
123 Input(currentLevel,
"DofsPerNode");
125 const ParameterList& pL = GetParameterList();
128 std::string mapOnePtName = pL.get<std::string>(
"OnePt aggregate map name");
129 if (mapOnePtName.length() > 0) {
130 std::string mapOnePtFactName = pL.get<std::string>(
"OnePt aggregate map factory");
131 if (mapOnePtFactName ==
"" || mapOnePtFactName ==
"NoFactory") {
132 currentLevel.DeclareInput(mapOnePtName, NoFactory::get());
134 RCP<const FactoryBase> mapOnePtFact = GetFactory(mapOnePtFactName);
135 currentLevel.DeclareInput(mapOnePtName, mapOnePtFact.get());
140 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
141 void UncoupledAggregationFactory_kokkos<LocalOrdinal, GlobalOrdinal, Node>::Build(Level ¤tLevel)
const {
142 FactoryMonitor m(*
this,
"Build", currentLevel);
144 ParameterList pL = GetParameterList();
145 bDefinitionPhase_ =
false;
147 if (pL.get<
int>(
"aggregation: max agg size") == -1)
148 pL.set(
"aggregation: max agg size", INT_MAX);
151 RCP<const FactoryBase> graphFact = GetFactory(
"Graph");
155 algos_.push_back(rcp(
new PreserveDirichletAggregationAlgorithm_kokkos(graphFact)));
156 if (pL.get<
bool>(
"aggregation: allow user-specified singletons") ==
true) algos_.push_back(rcp(
new OnePtAggregationAlgorithm_kokkos (graphFact)));
157 if (pL.get<
bool>(
"aggregation: enable phase 1" ) ==
true) algos_.push_back(rcp(
new AggregationPhase1Algorithm_kokkos (graphFact)));
158 if (pL.get<
bool>(
"aggregation: enable phase 2a") ==
true) algos_.push_back(rcp(
new AggregationPhase2aAlgorithm_kokkos (graphFact)));
159 if (pL.get<
bool>(
"aggregation: enable phase 2b") ==
true) algos_.push_back(rcp(
new AggregationPhase2bAlgorithm_kokkos (graphFact)));
160 if (pL.get<
bool>(
"aggregation: enable phase 3" ) ==
true) algos_.push_back(rcp(
new AggregationPhase3Algorithm_kokkos (graphFact)));
162 std::string mapOnePtName = pL.get<std::string>(
"OnePt aggregate map name");
163 RCP<Map> OnePtMap = Teuchos::null;
164 if (mapOnePtName.length()) {
165 std::string mapOnePtFactName = pL.get<std::string>(
"OnePt aggregate map factory");
166 if (mapOnePtFactName ==
"" || mapOnePtFactName ==
"NoFactory") {
167 OnePtMap = currentLevel.Get<RCP<Map> >(mapOnePtName, NoFactory::get());
169 RCP<const FactoryBase> mapOnePtFact = GetFactory(mapOnePtFactName);
170 OnePtMap = currentLevel.Get<RCP<Map> >(mapOnePtName, mapOnePtFact.get());
174 RCP<const LWGraph_kokkos> graph = Get< RCP<LWGraph_kokkos> >(currentLevel,
"Graph");
177 RCP<Aggregates_kokkos> aggregates = rcp(
new Aggregates_kokkos(*graph));
178 aggregates->setObjectLabel(
"UC");
180 const LO numRows = graph->GetNodeNumVertices();
183 std::vector<unsigned> aggStat(numRows,
READY);
187 ArrayRCP<const bool> dirichletBoundaryMap;
189 if (dirichletBoundaryMap != Teuchos::null)
190 for (LO i = 0; i < numRows; i++)
191 if (dirichletBoundaryMap[i] ==
true)
194 LO nDofsPerNode = Get<LO>(currentLevel,
"DofsPerNode");
195 GO indexBase = graph->GetDomainMap()->getIndexBase();
196 if (OnePtMap != Teuchos::null) {
197 for (LO i = 0; i < numRows; i++) {
199 GO grid = (graph->GetDomainMap()->getGlobalElement(i)-indexBase) * nDofsPerNode + indexBase;
201 for (LO kr = 0; kr < nDofsPerNode; kr++)
202 if (OnePtMap->isNodeGlobalElement(grid + kr))
208 const RCP<const Teuchos::Comm<int> > comm = graph->GetComm();
209 GO numGlobalRows = 0;
213 LO numNonAggregatedNodes = numRows;
214 GO numGlobalAggregatedPrev = 0, numGlobalAggsPrev = 0;
215 for (
size_t a = 0; a < algos_.size(); a++) {
216 std::string phase = algos_[a]->description();
217 SubFactoryMonitor sfm(*
this,
"Algo \"" + phase +
"\"", currentLevel);
219 int oldRank = algos_[a]->SetProcRankVerbose(this->GetProcRankVerbose());
220 algos_[a]->BuildAggregates(pL, *graph, *aggregates, aggStat, numNonAggregatedNodes);
221 algos_[a]->SetProcRankVerbose(oldRank);
224 GO numLocalAggregated = numRows - numNonAggregatedNodes, numGlobalAggregated = 0;
225 GO numLocalAggs = aggregates->GetNumAggregates(), numGlobalAggs = 0;
226 MueLu_sumAll(comm, numLocalAggregated, numGlobalAggregated);
229 double aggPercent = 100*as<double>(numGlobalAggregated)/as<double>(numGlobalRows);
230 if (aggPercent > 99.99 && aggPercent < 100.00) {
237 GetOStream(
Statistics1) <<
" aggregated : " << (numGlobalAggregated - numGlobalAggregatedPrev) <<
" (phase), " << std::fixed
238 << std::setprecision(2) << numGlobalAggregated <<
"/" << numGlobalRows <<
" [" << aggPercent <<
"%] (total)\n" 239 <<
" remaining : " << numGlobalRows - numGlobalAggregated <<
"\n" 240 <<
" aggregates : " << numGlobalAggs-numGlobalAggsPrev <<
" (phase), " << numGlobalAggs <<
" (total)" << std::endl;
241 numGlobalAggregatedPrev = numGlobalAggregated;
242 numGlobalAggsPrev = numGlobalAggs;
246 TEUCHOS_TEST_FOR_EXCEPTION(numNonAggregatedNodes, Exceptions::RuntimeError,
"MueLu::UncoupledAggregationFactory::Build: Leftover nodes found! Error!");
248 aggregates->AggregatesCrossProcessors(
false);
249 aggregates->ComputeAggregateSizes(
true);
251 Set(currentLevel,
"Aggregates", aggregates);
253 GetOStream(
Statistics1) << aggregates->description() << std::endl;
258 #endif // HAVE_MUELU_KOKKOS_REFACTOR #define MueLu_sumAll(rcpComm, in, out)
Namespace for MueLu classes and methods.
#define SET_VALID_ENTRY(name)