46 #ifndef MUELU_LOCALORDINALTRANSFER_FACTORY_DEF_HPP 47 #define MUELU_LOCALORDINALTRANSFER_FACTORY_DEF_HPP 49 #include "Xpetra_ImportFactory.hpp" 50 #include "Xpetra_VectorFactory.hpp" 51 #include "Xpetra_MapFactory.hpp" 52 #include "Xpetra_CrsGraph.hpp" 54 #include "Xpetra_IO.hpp" 56 #include "MueLu_CoarseMapFactory.hpp" 57 #include "MueLu_Aggregates.hpp" 65 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
67 RCP<ParameterList> validParamList = rcp(
new ParameterList());
69 validParamList->set<RCP<const FactoryBase> >(TransferVecName_, Teuchos::null,
"Factory for TransferVec generation");
70 validParamList->set<RCP<const FactoryBase> >(
"P Graph", Teuchos::null,
"Factory for P generation");
71 validParamList->set<RCP<const FactoryBase> >(
"Aggregates", Teuchos::null,
"Factory for aggregates generation");
72 validParamList->set<RCP<const FactoryBase> >(
"CoarseMap", Teuchos::null,
"Generating factory of the coarse map");
74 return validParamList;
77 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
79 static bool isAvailableXfer =
false;
81 isAvailableXfer = coarseLevel.
IsAvailable(TransferVecName_,
this);
82 if (isAvailableXfer ==
false) {
83 Input(fineLevel, TransferVecName_);
84 Input(fineLevel,
"CoarseMap");
86 if(useAggregatesMode_)
87 Input(fineLevel,
"Aggregates");
89 Input(coarseLevel,
"P Graph");
96 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
98 if(useAggregatesMode_) BuildAggregates(fineLevel,coarseLevel);
99 else BuildFC(fineLevel,coarseLevel);
102 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
106 GetOStream(
Runtime0) <<
"Transferring " <<TransferVecName_ << std::endl;
107 LO LO_INVALID = Teuchos::OrdinalTraits<LO>::invalid();
109 if (coarseLevel.
IsAvailable(TransferVecName_,
this)) {
110 GetOStream(
Runtime0) <<
"Reusing "<<TransferVecName_ << std::endl;
115 RCP<const CrsGraph> P = Get< RCP<const CrsGraph> >(coarseLevel,
"P Graph");
116 RCP<LocalOrdinalVector> fineTV = Get< RCP<LocalOrdinalVector> >(fineLevel, TransferVecName_);
117 RCP<const Map> coarseMap = Get< RCP<const Map> > (fineLevel,
"CoarseMap");
118 RCP<const Map> uniqueMap = fineTV->getMap();
119 ArrayRCP<const LO> fineData = fineTV->getData(0);
122 RCP<LocalOrdinalVector> coarseTV = LocalOrdinalVectorFactory::Build(coarseMap,1);
123 ArrayRCP<LO> coarseData = coarseTV->getDataNonConst(0);
126 for(LO i=0; i<coarseData.size(); i++)
127 coarseData[i] = LO_INVALID;
130 LO domMapNumElements = P->getDomainMap()->getNodeNumElements();
131 for (LO row=0; row<(LO)P->getNodeNumRows(); row++) {
132 LO fineNumber = fineData[row];
133 ArrayView<const LO> indices;
134 P->getLocalRowView(row,indices);
136 for(LO j=0; j<(LO)indices.size(); j++) {
138 if (col >= domMapNumElements) {
141 coarseData[col] = fineNumber;
146 #ifdef HAVE_MUELU_DEBUG 147 size_t error_count = 0;
149 RCP<LocalOrdinalVector> coarseTVghosted;
150 RCP<const Import> importer = P->getImporter();
151 if (!importer.is_null()) {
152 coarseTVghosted = LocalOrdinalVectorFactory::Build(P->getColMap(),1);
153 coarseTVghosted->doImport(*coarseTV, *importer, Xpetra::INSERT);
155 coarseTVghosted = coarseTV;
157 ArrayRCP<LO> coarseDataGhosted = coarseTVghosted->getDataNonConst(0);
158 for (LO col=0; col<(LO)P->getColMap()->getNodeNumElements(); col++) {
159 if (coarseDataGhosted[col] == LO_INVALID)
162 for (LO row=0; row<(LO)P->getNodeNumRows(); row++) {
163 LO fineNumber = fineData[row];
164 ArrayView<const LO> indices;
165 P->getLocalRowView(row,indices);
166 for(LO j=0; j<(LO)indices.size(); j++) {
167 if (coarseDataGhosted[indices[j]] != fineNumber)
174 if(error_count > 0) {
175 std::ostringstream ofs;
176 ofs <<
"LocalOrdinalTransferFactory("<<TransferVecName_<<
"): ERROR: Each coarse dof must have a unique LO value. We had "<<std::to_string(error_count)<<
" unknowns that did not match.";
177 throw std::runtime_error(ofs.str());
181 Set<RCP<LocalOrdinalVector> >(coarseLevel, TransferVecName_, coarseTV);
187 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
191 GetOStream(
Runtime0) <<
"Transferring " <<TransferVecName_ << std::endl;
192 RCP<LocalOrdinalVector> coarseTV;
193 RCP<LocalOrdinalVector> fineTV;
194 LO LO_INVALID = Teuchos::OrdinalTraits<LO>::invalid();
196 if (coarseLevel.
IsAvailable(TransferVecName_,
this)) {
197 GetOStream(
Runtime0) <<
"Reusing "<<TransferVecName_ << std::endl;
201 RCP<Aggregates> aggregates = Get< RCP<Aggregates> > (fineLevel,
"Aggregates");
202 fineTV = Get< RCP<LocalOrdinalVector> >(fineLevel, TransferVecName_);
203 RCP<const Map> coarseMap = Get< RCP<const Map> > (fineLevel,
"CoarseMap");
204 RCP<const Map> uniqueMap = fineTV->getMap();
206 ArrayView<const GO> elementAList = coarseMap->getNodeElementList();
208 coarseTV = LocalOrdinalVectorFactory::Build(coarseMap,1);
211 RCP<LocalOrdinalVector> ghostedTV = fineTV;
212 if (aggregates->AggregatesCrossProcessors()) {
214 RCP<const Map> nonUniqueMap = aggregates->GetMap();
215 RCP<const Import> importer = ImportFactory::Build(uniqueMap, nonUniqueMap);
217 ghostedTV = LocalOrdinalVectorFactory::Build(nonUniqueMap, 1);
218 ghostedTV->doImport(*fineTV, *importer, Xpetra::INSERT);
222 int myPID = uniqueMap->getComm()->getRank();
223 ArrayRCP<LO> aggSizes = aggregates->ComputeAggregateSizes();
224 const ArrayRCP<const LO> vertex2AggID = aggregates->GetVertex2AggId()->getData(0);
225 const ArrayRCP<const LO> procWinner = aggregates->GetProcWinner()->getData(0);
228 ArrayRCP<const LO> fineData = ghostedTV->getData(0);
229 ArrayRCP<LO> coarseData = coarseTV->getDataNonConst(0);
232 for(LO i=0; i<coarseData.size(); i++)
233 coarseData[i] = LO_INVALID;
236 size_t error_count = 0;
237 for (LO lnode = 0; lnode < vertex2AggID.size(); lnode++) {
238 if (procWinner[lnode] == myPID &&
240 lnode < fineData.size() &&
241 vertex2AggID[lnode] < coarseData.size()) {
242 if(coarseData[vertex2AggID[lnode]] == LO_INVALID)
243 coarseData[vertex2AggID[lnode]] = fineData[lnode];
244 if(coarseData[vertex2AggID[lnode]] != fineData[lnode])
250 if(error_count > 0) {
251 std::ostringstream ofs;
252 ofs <<
"LocalOrdinalTransferFactory: ERROR: Each aggregate must have a unique LO value. We had "<<std::to_string(error_count)<<
" unknowns that did not match.";
253 throw std::runtime_error(ofs.str());
256 Set<RCP<LocalOrdinalVector> >(coarseLevel, TransferVecName_, coarseTV);
262 #endif // MUELU_LOCALORDINALTRANSFER_FACTORY_DEF_HPP void Build(Level &fineLevel, Level &coarseLevel) const
Build an object with this factory.
RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
RequestMode GetRequestMode() const
Timer to be used in factories. Similar to Monitor but with additional timers.
One-liner description of what is happening.
Namespace for MueLu classes and methods.
void DeclareInput(Level &finelevel, Level &coarseLevel) const
Specifies the data that this class needs, and the factories that generate that data.
Class that holds all level-specific information.
void BuildFC(Level &fineLevel, Level &coarseLevel) const
bool IsAvailable(const std::string &ename, const FactoryBase *factory=NoFactory::get()) const
Test whether a need's value has been saved.
void BuildAggregates(Level &fineLevel, Level &coarseLevel) const