85 RCP<Teuchos::FancyOStream> out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
87 Teuchos::RCP<Matrix> originalTransferOp = Teuchos::null;
88 originalTransferOp = Get<RCP<Matrix> >(coarseLevel,
"R");
90 RCP<Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > bOriginalTransferOp =
91 Teuchos::rcp_dynamic_cast<Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(originalTransferOp);
92 TEUCHOS_TEST_FOR_EXCEPTION(bOriginalTransferOp == Teuchos::null,
Exceptions::BadCast,
"MueLu::RebalanceBlockTransferFactory::Build: input matrix P or R is not of type BlockedCrsMatrix! error.");
94 RCP<const MapExtractor> rangeMapExtractor = bOriginalTransferOp->getRangeMapExtractor();
95 RCP<const MapExtractor> domainMapExtractor = bOriginalTransferOp->getDomainMapExtractor();
98 bool bRestrictComm =
false;
99 const ParameterList &pL = GetParameterList();
100 if (pL.get<
bool>(
"repartition: use subcommunicators") ==
true)
101 bRestrictComm =
true;
110 bool bThyraRangeGIDs = rangeMapExtractor->getThyraMode();
111 bool bThyraDomainGIDs = domainMapExtractor->getThyraMode();
114 std::vector<GO> fullRangeMapVector;
115 std::vector<GO> fullDomainMapVector;
116 std::vector<RCP<const Map> > subBlockRRangeMaps;
117 std::vector<RCP<const Map> > subBlockRDomainMaps;
118 subBlockRRangeMaps.reserve(bOriginalTransferOp->Rows());
119 subBlockRDomainMaps.reserve(bOriginalTransferOp->Cols());
121 std::vector<Teuchos::RCP<Matrix> > subBlockRebR;
122 subBlockRebR.reserve(bOriginalTransferOp->Cols());
124 std::vector<RCP<const Import> > importers = std::vector<RCP<const Import> >(bOriginalTransferOp->Rows(), Teuchos::null);
125 if (UseSingleSourceImporters_) {
126 importers = Get<std::vector<RCP<const Import> > >(coarseLevel,
"SubImporters");
130 Teuchos::RCP<const Import> rebalanceImporter;
131 std::vector<Teuchos::RCP<const FactoryManagerBase> >::const_iterator it;
132 for (it = FactManager_.begin(); it != FactManager_.end(); ++it) {
137 if (UseSingleSourceImporters_)
138 rebalanceImporter = importers[curBlockId];
140 rebalanceImporter = coarseLevel.
Get<Teuchos::RCP<const Import> >(
"Importer", (*it)->GetFactory(
"Importer").get());
143 Teuchos::RCP<Matrix> Rii = bOriginalTransferOp->getMatrix(curBlockId, curBlockId);
146 TEUCHOS_TEST_FOR_EXCEPTION(bThyraRangeGIDs ==
true && Rii->getRowMap()->getMinAllGlobalIndex() != 0,
148 "MueLu::RebalanceBlockRestrictionFactory::Build: inconsistent Thyra GIDs. Thyra global ids for block range " << curBlockId <<
" start with " << Rii->getRowMap()->getMinAllGlobalIndex() <<
" but should start with 0");
149 TEUCHOS_TEST_FOR_EXCEPTION(bThyraDomainGIDs ==
true && Rii->getColMap()->getMinAllGlobalIndex() != 0,
151 "MueLu::RebalanceBlockRestrictionFactory::Build: inconsistent Thyra GIDs. Thyra global ids for block domain " << curBlockId <<
" start with " << Rii->getColMap()->getMinAllGlobalIndex() <<
" but should start with 0");
153 Teuchos::RCP<Matrix> rebRii;
154 if (rebalanceImporter != Teuchos::null) {
155 std::stringstream ss;
156 ss <<
"Rebalancing restriction block R(" << curBlockId <<
"," << curBlockId <<
")";
159 SubFactoryMonitor subM(*
this,
"Rebalancing restriction -- fusedImport", coarseLevel);
163 rebRii = MatrixFactory::Build(Rii, *rebalanceImporter, dummy, rebalanceImporter->getTargetMap());
166 RCP<ParameterList> params = rcp(
new ParameterList());
167 params->set(
"printLoadBalancingInfo",
true);
168 std::stringstream ss2;
169 ss2 <<
"R(" << curBlockId <<
"," << curBlockId <<
") rebalanced:";
173 RCP<ParameterList> params = rcp(
new ParameterList());
174 params->set(
"printLoadBalancingInfo",
true);
175 std::stringstream ss2;
176 ss2 <<
"R(" << curBlockId <<
"," << curBlockId <<
") not rebalanced:";
181 Teuchos::RCP<const StridedMap> orig_stridedRgMap = Teuchos::rcp_dynamic_cast<const StridedMap>(rangeMapExtractor->getMap(Teuchos::as<size_t>(curBlockId), rangeMapExtractor->getThyraMode()));
182 Teuchos::RCP<const Map> stridedRgMap = Teuchos::null;
183 if (orig_stridedRgMap != Teuchos::null) {
184 std::vector<size_t> stridingData = orig_stridedRgMap->getStridingData();
185 Teuchos::ArrayView<const GlobalOrdinal> nodeRangeMapii = rebRii->getRangeMap()->getLocalElementList();
186 stridedRgMap = StridedMapFactory::Build(
187 originalTransferOp->getRangeMap()->lib(),
188 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
190 rebRii->getRangeMap()->getIndexBase(),
192 originalTransferOp->getRangeMap()->getComm(),
193 orig_stridedRgMap->getStridedBlockId(),
194 orig_stridedRgMap->getOffset());
196 stridedRgMap = Rii->getRangeMap();
198 Teuchos::RCP<const StridedMap> orig_stridedDoMap = Teuchos::rcp_dynamic_cast<const StridedMap>(domainMapExtractor->getMap(Teuchos::as<size_t>(curBlockId), domainMapExtractor->getThyraMode()));
199 Teuchos::RCP<const Map> stridedDoMap = Teuchos::null;
200 if (orig_stridedDoMap != Teuchos::null) {
201 std::vector<size_t> stridingData = orig_stridedDoMap->getStridingData();
202 Teuchos::ArrayView<const GlobalOrdinal> nodeDomainMapii = rebRii->getDomainMap()->getLocalElementList();
203 stridedDoMap = StridedMapFactory::Build(
204 originalTransferOp->getDomainMap()->lib(),
205 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
207 rebRii->getDomainMap()->getIndexBase(),
209 originalTransferOp->getDomainMap()->getComm(),
210 orig_stridedDoMap->getStridedBlockId(),
211 orig_stridedDoMap->getOffset());
213 stridedDoMap = Rii->getDomainMap();
216 stridedRgMap->removeEmptyProcesses();
217 stridedDoMap->removeEmptyProcesses();
220 TEUCHOS_TEST_FOR_EXCEPTION(stridedRgMap == Teuchos::null,
Exceptions::RuntimeError,
"MueLu::RebalanceBlockRestrictionFactory::Build: failed to generate striding information. error.");
221 TEUCHOS_TEST_FOR_EXCEPTION(stridedDoMap == Teuchos::null,
Exceptions::RuntimeError,
"MueLu::RebalanceBlockRestrictionFactory::Build: failed to generate striding information. error.");
224 if (rebRii->IsView(
"stridedMaps")) rebRii->RemoveView(
"stridedMaps");
225 rebRii->CreateView(
"stridedMaps", stridedRgMap, stridedDoMap);
228 subBlockRebR.push_back(rebRii);
231 Teuchos::RCP<const Map> rangeMapii = rebRii->getRowMap(
"stridedMaps");
232 subBlockRRangeMaps.push_back(rangeMapii);
233 Teuchos::ArrayView<const GlobalOrdinal> nodeRangeMapii = rebRii->getRangeMap()->getLocalElementList();
235 fullRangeMapVector.insert(fullRangeMapVector.end(), nodeRangeMapii.begin(), nodeRangeMapii.end());
236 if (bThyraRangeGIDs ==
false)
237 sort(fullRangeMapVector.begin(), fullRangeMapVector.end());
240 Teuchos::RCP<const Map> domainMapii = rebRii->getColMap(
"stridedMaps");
241 subBlockRDomainMaps.push_back(domainMapii);
242 Teuchos::ArrayView<const GlobalOrdinal> nodeDomainMapii = rebRii->getDomainMap()->getLocalElementList();
244 fullDomainMapVector.insert(fullDomainMapVector.end(), nodeDomainMapii.begin(), nodeDomainMapii.end());
245 if (bThyraDomainGIDs ==
false)
246 sort(fullDomainMapVector.begin(), fullDomainMapVector.end());
253 if (rebalanceImporter != Teuchos::null) {
254 std::stringstream ss2;
255 ss2 <<
"Rebalancing nullspace block(" << curBlockId <<
"," << curBlockId <<
")";
258 RCP<MultiVector> nullspace = coarseLevel.
Get<RCP<MultiVector> >(
"Nullspace", (*it)->GetFactory(
"Nullspace").get());
259 RCP<MultiVector> permutedNullspace = MultiVectorFactory::Build(rebalanceImporter->getTargetMap(), nullspace->getNumVectors());
260 permutedNullspace->doImport(*nullspace, *rebalanceImporter, Xpetra::INSERT);
264 permutedNullspace->replaceMap(permutedNullspace->getMap()->removeEmptyProcesses());
266 coarseLevel.
Set<RCP<MultiVector> >(
"Nullspace", permutedNullspace, (*it)->GetFactory(
"Nullspace").get());
270 RCP<MultiVector> nullspace = coarseLevel.
Get<RCP<MultiVector> >(
"Nullspace", (*it)->GetFactory(
"Nullspace").get());
271 coarseLevel.
Set<RCP<MultiVector> >(
"Nullspace", nullspace, (*it)->GetFactory(
"Nullspace").get());
280 GO rangeIndexBase = originalTransferOp->getRangeMap()->getIndexBase();
281 GO domainIndexBase = originalTransferOp->getDomainMap()->getIndexBase();
284 Teuchos::ArrayView<GO> fullRangeMapGIDs(fullRangeMapVector.size() ? &fullRangeMapVector[0] : 0, fullRangeMapVector.size());
285 Teuchos::RCP<const StridedMap> stridedRgFullMap = Teuchos::rcp_dynamic_cast<const StridedMap>(rangeMapExtractor->getFullMap());
286 Teuchos::RCP<const Map> fullRangeMap = Teuchos::null;
287 if (stridedRgFullMap != Teuchos::null) {
288 std::vector<size_t> stridedData = stridedRgFullMap->getStridingData();
290 StridedMapFactory::Build(
291 originalTransferOp->getRangeMap()->lib(),
292 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
296 originalTransferOp->getRangeMap()->getComm(),
297 stridedRgFullMap->getStridedBlockId(),
298 stridedRgFullMap->getOffset());
302 originalTransferOp->getRangeMap()->lib(),
303 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
306 originalTransferOp->getRangeMap()->getComm());
309 Teuchos::ArrayView<GO> fullDomainMapGIDs(fullDomainMapVector.size() ? &fullDomainMapVector[0] : 0, fullDomainMapVector.size());
310 Teuchos::RCP<const StridedMap> stridedDoFullMap = Teuchos::rcp_dynamic_cast<const StridedMap>(domainMapExtractor->getFullMap());
311 Teuchos::RCP<const Map> fullDomainMap = Teuchos::null;
312 if (stridedDoFullMap != Teuchos::null) {
313 TEUCHOS_TEST_FOR_EXCEPTION(stridedDoFullMap == Teuchos::null,
Exceptions::BadCast,
"MueLu::BlockedPFactory::Build: full map in domain map extractor has no striding information! error.");
314 std::vector<size_t> stridedData2 = stridedDoFullMap->getStridingData();
316 StridedMapFactory::Build(
317 originalTransferOp->getDomainMap()->lib(),
318 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
322 originalTransferOp->getDomainMap()->getComm(),
323 stridedDoFullMap->getStridedBlockId(),
324 stridedDoFullMap->getOffset());
328 originalTransferOp->getDomainMap()->lib(),
329 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
332 originalTransferOp->getDomainMap()->getComm());
336 fullRangeMap->removeEmptyProcesses();
337 fullDomainMap->removeEmptyProcesses();
341 Teuchos::RCP<const MapExtractor> rebrangeMapExtractor =
342 MapExtractorFactory::Build(fullRangeMap, subBlockRRangeMaps, bThyraRangeGIDs);
343 Teuchos::RCP<const MapExtractor> rebdomainMapExtractor =
344 MapExtractorFactory::Build(fullDomainMap, subBlockRDomainMaps, bThyraDomainGIDs);
346 Teuchos::RCP<BlockedCrsMatrix> bRebR = Teuchos::rcp(
new BlockedCrsMatrix(rebrangeMapExtractor, rebdomainMapExtractor, 10));
347 for (
size_t i = 0; i < subBlockRRangeMaps.size(); i++) {
348 Teuchos::RCP<CrsMatrixWrap> crsOpii = Teuchos::rcp_dynamic_cast<CrsMatrixWrap>(subBlockRebR[i]);
349 bRebR->setMatrix(i, i, crsOpii);
352 bRebR->fillComplete();
354 Set(coarseLevel,
"R", Teuchos::rcp_dynamic_cast<Matrix>(bRebR));