93 typedef Xpetra::MultiVector<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LO, GO, NO> xdMV;
94 typedef Xpetra::BlockedMultiVector<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LO, GO, NO> xdBV;
96 bool UseSingleSource = FactManager_.size() == 0;
99 Teuchos::RCP<Matrix> nonrebCoarseA = Get<RCP<Matrix> >(coarseLevel,
"A");
101 Teuchos::RCP<Matrix> originalTransferOp = Teuchos::null;
102 originalTransferOp = Get<RCP<Matrix> >(coarseLevel,
"P");
104 RCP<Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > bOriginalTransferOp =
105 Teuchos::rcp_dynamic_cast<Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(originalTransferOp);
106 TEUCHOS_TEST_FOR_EXCEPTION(bOriginalTransferOp == Teuchos::null,
Exceptions::BadCast,
"MueLu::RebalanceBlockTransferFactory::Build: input matrix P or R is not of type BlockedCrsMatrix! error.");
108 RCP<const MapExtractor> rangeMapExtractor = bOriginalTransferOp->getRangeMapExtractor();
109 RCP<const MapExtractor> domainMapExtractor = bOriginalTransferOp->getDomainMapExtractor();
118 bool bThyraRangeGIDs = rangeMapExtractor->getThyraMode();
119 bool bThyraDomainGIDs = domainMapExtractor->getThyraMode();
122 std::vector<GO> fullRangeMapVector;
123 std::vector<GO> fullDomainMapVector;
124 std::vector<RCP<const Map> > subBlockPRangeMaps;
125 std::vector<RCP<const Map> > subBlockPDomainMaps;
126 subBlockPRangeMaps.reserve(bOriginalTransferOp->Rows());
127 subBlockPDomainMaps.reserve(bOriginalTransferOp->Cols());
129 std::vector<Teuchos::RCP<Matrix> > subBlockRebP;
130 subBlockRebP.reserve(bOriginalTransferOp->Rows());
133 std::vector<RCP<const Import> > importers = std::vector<RCP<const Import> >(bOriginalTransferOp->Rows(), Teuchos::null);
134 std::vector<RCP<xdMV> > newCoordinates(bOriginalTransferOp->Rows());
135 RCP<xdBV> oldCoordinates;
136 if (UseSingleSource) {
137 importers = Get<std::vector<RCP<const Import> > >(coarseLevel,
"SubImporters");
138 oldCoordinates = Get<RCP<xdBV> >(coarseLevel,
"Coordinates");
142 Teuchos::RCP<const Import> rebalanceImporter = Teuchos::null;
143 std::vector<Teuchos::RCP<const FactoryManagerBase> >::const_iterator it;
144 for (it = FactManager_.begin(); it != FactManager_.end(); ++it) {
151 rebalanceImporter = importers[curBlockId];
153 rebalanceImporter = coarseLevel.
Get<Teuchos::RCP<const Import> >(
"Importer", (*it)->GetFactory(
"Importer").get());
156 Teuchos::RCP<Matrix> Pii = bOriginalTransferOp->getMatrix(curBlockId, curBlockId);
157 Teuchos::RCP<CrsMatrixWrap> Pwii = Teuchos::rcp_dynamic_cast<CrsMatrixWrap>(Pii);
158 TEUCHOS_TEST_FOR_EXCEPTION(Pwii == Teuchos::null, Xpetra::Exceptions::BadCast,
"MueLu::RebalanceBlockTransferFactory::Build: block " << curBlockId <<
" is not of type CrsMatrixWrap. We need an underlying CsrMatrix to replace domain map and importer!");
162 "MueLu::RebalanceBlockInterpolationFactory::Build: inconsistent Thyra GIDs. Thyra global ids for block range " << curBlockId <<
" start with " << Pii->getRowMap()->getMinAllGlobalIndex() <<
" but should start with 0");
165 "MueLu::RebalanceBlockInterpolationFactory::Build: inconsistent Thyra GIDs. Thyra global ids for block domain " << curBlockId <<
" start with " << Pii->getColMap()->getMinAllGlobalIndex() <<
" but should start with 0");
168 if (rebalanceImporter != Teuchos::null) {
169 std::stringstream ss;
170 ss <<
"Rebalancing prolongator block P(" << curBlockId <<
"," << curBlockId <<
")";
184 RCP<const Import> newImporter;
186 SubFactoryMonitor subM(*
this,
"Rebalancing prolongator -- fast map replacement", coarseLevel);
187 newImporter = ImportFactory::Build(rebalanceImporter->getTargetMap(), Pii->getColMap());
188 Pwii->getCrsMatrix()->replaceDomainMapAndImporter(rebalanceImporter->getTargetMap(), newImporter);
191 RCP<ParameterList> params = rcp(
new ParameterList());
192 params->set(
"printLoadBalancingInfo",
true);
193 std::stringstream ss2;
194 ss2 <<
"P(" << curBlockId <<
"," << curBlockId <<
") rebalanced:";
198 subBlockRebP.push_back(Pii);
203 if (UseSingleSource) {
204 RCP<xdMV> localCoords = oldCoordinates->getMultiVector(curBlockId);
207 RCP<const Import> coordImporter = rebalanceImporter;
209 RCP<xdMV> permutedLocalCoords = Xpetra::MultiVectorFactory<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LO, GO, NO>::Build(coordImporter->getTargetMap(), localCoords->getNumVectors());
210 permutedLocalCoords->doImport(*localCoords, *coordImporter, Xpetra::INSERT);
212 newCoordinates[curBlockId] = permutedLocalCoords;
213 }
else if ((*it)->hasFactory(
"Coordinates") ==
true && coarseLevel.
IsAvailable(
"Coordinates", (*it)->GetFactory(
"Coordinates").get()) ==
true) {
214 RCP<xdMV> coords = coarseLevel.
Get<RCP<xdMV> >(
"Coordinates", (*it)->GetFactory(
"Coordinates").get());
219 LO nodeNumElts = coords->getMap()->getLocalNumElements();
222 LO myBlkSize = 0, blkSize = 0;
224 if (nodeNumElts > 0) {
227 "MueLu::RebalanceBlockInterpolationFactory::Build: block size. " << rebalanceImporter->getSourceMap()->getLocalNumElements() <<
" not divisable by " << nodeNumElts);
228 myBlkSize = rebalanceImporter->getSourceMap()->getLocalNumElements() / nodeNumElts;
231 MueLu_maxAll(coords->getMap()->getComm(), myBlkSize, blkSize);
233 RCP<const Import> coordImporter = Teuchos::null;
235 coordImporter = rebalanceImporter;
240 RCP<const Map> origMap = coords->getMap();
241 GO indexBase = origMap->getIndexBase();
243 ArrayView<const GO> OEntries = rebalanceImporter->getTargetMap()->getLocalElementList();
244 LO numEntries = OEntries.size() / blkSize;
245 ArrayRCP<GO> Entries(numEntries);
246 for (LO i = 0; i < numEntries; i++)
247 Entries[i] = (OEntries[i * blkSize] - indexBase) / blkSize + indexBase;
249 RCP<const Map> targetMap = MapFactory::Build(origMap->lib(), origMap->getGlobalNumElements(), Entries(), indexBase, origMap->getComm());
250 coordImporter = ImportFactory::Build(origMap, targetMap);
253 RCP<xdMV> permutedCoords = Xpetra::MultiVectorFactory<typename Teuchos::ScalarTraits<Scalar>::magnitudeType, LO, GO, NO>::Build(coordImporter->getTargetMap(), coords->getNumVectors());
254 permutedCoords->doImport(*coords, *coordImporter, Xpetra::INSERT);
256 const ParameterList &pL = GetParameterList();
257 if (pL.isParameter(
"repartition: use subcommunicators") ==
true && pL.get<
bool>(
"repartition: use subcommunicators") ==
true)
258 permutedCoords->replaceMap(permutedCoords->getMap()->removeEmptyProcesses());
260 Set(coarseLevel,
"Coordinates", permutedCoords);
264 RCP<ParameterList> params = rcp(
new ParameterList());
265 params->set(
"printLoadBalancingInfo",
true);
266 std::stringstream ss;
267 ss <<
"P(" << curBlockId <<
"," << curBlockId <<
") not rebalanced:";
270 subBlockRebP.push_back(Pii);
275 if ((*it)->hasFactory(
"Coordinates") ==
true && coarseLevel.
IsAvailable(
"Coordinates", (*it)->GetFactory(
"Coordinates").get()) ==
true) {
276 coarseLevel.
Set(
"Coordinates", coarseLevel.
Get<RCP<xdMV> >(
"Coordinates", (*it)->GetFactory(
"Coordinates").get()),
this);
282 Teuchos::RCP<const StridedMap> orig_stridedRgMap = Teuchos::rcp_dynamic_cast<const StridedMap>(rangeMapExtractor->getMap(Teuchos::as<size_t>(curBlockId), rangeMapExtractor->getThyraMode()));
283 Teuchos::RCP<const Map> stridedRgMap = Teuchos::null;
284 if (orig_stridedRgMap != Teuchos::null) {
285 std::vector<size_t> stridingData = orig_stridedRgMap->getStridingData();
286 Teuchos::ArrayView<const GlobalOrdinal> nodeRangeMapii = Pii->getRangeMap()->getLocalElementList();
287 stridedRgMap = StridedMapFactory::Build(
288 originalTransferOp->getRangeMap()->lib(),
289 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
291 Pii->getRangeMap()->getIndexBase(),
293 originalTransferOp->getRangeMap()->getComm(),
294 orig_stridedRgMap->getStridedBlockId(),
295 orig_stridedRgMap->getOffset());
297 stridedRgMap = Pii->getRangeMap();
300 Teuchos::RCP<const StridedMap> orig_stridedDoMap = Teuchos::rcp_dynamic_cast<const StridedMap>(domainMapExtractor->getMap(Teuchos::as<size_t>(curBlockId), domainMapExtractor->getThyraMode()));
302 Teuchos::RCP<const Map> stridedDoMap = Teuchos::null;
303 if (orig_stridedDoMap != Teuchos::null) {
304 std::vector<size_t> stridingData = orig_stridedDoMap->getStridingData();
305 Teuchos::ArrayView<const GlobalOrdinal> nodeDomainMapii = Pii->getDomainMap()->getLocalElementList();
306 stridedDoMap = StridedMapFactory::Build(originalTransferOp->getDomainMap()->lib(),
307 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
309 Pii->getDomainMap()->getIndexBase(),
311 originalTransferOp->getDomainMap()->getComm(),
312 orig_stridedDoMap->getStridedBlockId(),
313 orig_stridedDoMap->getOffset());
315 stridedDoMap = Pii->getDomainMap();
317 TEUCHOS_TEST_FOR_EXCEPTION(stridedRgMap == Teuchos::null,
Exceptions::RuntimeError,
"MueLu::RebalanceBlockInterpolationFactory::Build: failed to generate striding information. error.");
318 TEUCHOS_TEST_FOR_EXCEPTION(stridedDoMap == Teuchos::null,
Exceptions::RuntimeError,
"MueLu::RebalanceBlockInterpolationFactory::Build: failed to generate striding information. error.");
321 if (Pii->IsView(
"stridedMaps")) Pii->RemoveView(
"stridedMaps");
322 Pii->CreateView(
"stridedMaps", stridedRgMap, stridedDoMap);
325 Teuchos::RCP<const Map> rangeMapii = Pii->getRowMap(
"stridedMaps");
326 subBlockPRangeMaps.push_back(rangeMapii);
327 Teuchos::ArrayView<const GlobalOrdinal> nodeRangeMapii = Pii->getRangeMap()->getLocalElementList();
329 fullRangeMapVector.insert(fullRangeMapVector.end(), nodeRangeMapii.begin(), nodeRangeMapii.end());
330 if (bThyraRangeGIDs ==
false)
331 sort(fullRangeMapVector.begin(), fullRangeMapVector.end());
334 Teuchos::RCP<const Map> domainMapii = Pii->getColMap(
"stridedMaps");
335 subBlockPDomainMaps.push_back(domainMapii);
336 Teuchos::ArrayView<const GlobalOrdinal> nodeDomainMapii = Pii->getDomainMap()->getLocalElementList();
338 fullDomainMapVector.insert(fullDomainMapVector.end(), nodeDomainMapii.begin(), nodeDomainMapii.end());
339 if (bThyraDomainGIDs ==
false)
340 sort(fullDomainMapVector.begin(), fullDomainMapVector.end());
347 GO rangeIndexBase = originalTransferOp->getRangeMap()->getIndexBase();
348 GO domainIndexBase = originalTransferOp->getDomainMap()->getIndexBase();
350 RCP<const Xpetra::MapExtractor<Scalar, LocalOrdinal, GlobalOrdinal, Node> > rangePMapExtractor = bOriginalTransferOp->getRangeMapExtractor();
351 Teuchos::ArrayView<GO> fullRangeMapGIDs(fullRangeMapVector.size() ? &fullRangeMapVector[0] : 0, fullRangeMapVector.size());
352 Teuchos::RCP<const StridedMap> stridedRgFullMap = Teuchos::rcp_dynamic_cast<const StridedMap>(rangePMapExtractor->getFullMap());
353 Teuchos::RCP<const Map> fullRangeMap = Teuchos::null;
354 if (stridedRgFullMap != Teuchos::null) {
355 std::vector<size_t> stridedData = stridedRgFullMap->getStridingData();
357 StridedMapFactory::Build(
358 originalTransferOp->getRangeMap()->lib(),
359 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
363 originalTransferOp->getRangeMap()->getComm(),
364 stridedRgFullMap->getStridedBlockId(),
365 stridedRgFullMap->getOffset());
369 originalTransferOp->getRangeMap()->lib(),
370 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
373 originalTransferOp->getRangeMap()->getComm());
376 RCP<const Xpetra::MapExtractor<Scalar, LocalOrdinal, GlobalOrdinal, Node> > domainAMapExtractor = bOriginalTransferOp->getDomainMapExtractor();
377 Teuchos::ArrayView<GO> fullDomainMapGIDs(fullDomainMapVector.size() ? &fullDomainMapVector[0] : 0, fullDomainMapVector.size());
378 Teuchos::RCP<const StridedMap> stridedDoFullMap = Teuchos::rcp_dynamic_cast<const StridedMap>(domainAMapExtractor->getFullMap());
379 Teuchos::RCP<const Map> fullDomainMap = Teuchos::null;
380 if (stridedDoFullMap != Teuchos::null) {
381 TEUCHOS_TEST_FOR_EXCEPTION(stridedDoFullMap == Teuchos::null,
Exceptions::BadCast,
"MueLu::BlockedPFactory::Build: full map in domain map extractor has no striding information! error.");
382 std::vector<size_t> stridedData2 = stridedDoFullMap->getStridingData();
384 StridedMapFactory::Build(
385 originalTransferOp->getDomainMap()->lib(),
386 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
390 originalTransferOp->getDomainMap()->getComm(),
391 stridedDoFullMap->getStridedBlockId(),
392 stridedDoFullMap->getOffset());
396 originalTransferOp->getDomainMap()->lib(),
397 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
400 originalTransferOp->getDomainMap()->getComm());
404 Teuchos::RCP<const MapExtractor> rebrangeMapExtractor =
405 MapExtractorFactory::Build(fullRangeMap, subBlockPRangeMaps, bThyraRangeGIDs);
406 Teuchos::RCP<const MapExtractor> rebdomainMapExtractor =
407 MapExtractorFactory::Build(fullDomainMap, subBlockPDomainMaps, bThyraDomainGIDs);
409 Teuchos::RCP<BlockedCrsMatrix> bRebP = Teuchos::rcp(
new BlockedCrsMatrix(rebrangeMapExtractor, rebdomainMapExtractor, 10));
410 for (
size_t i = 0; i < subBlockPRangeMaps.size(); i++) {
411 Teuchos::RCP<CrsMatrixWrap> crsOpii = Teuchos::rcp_dynamic_cast<CrsMatrixWrap>(subBlockRebP[i]);
412 TEUCHOS_TEST_FOR_EXCEPTION(crsOpii == Teuchos::null, Xpetra::Exceptions::BadCast,
"MueLu::RebalanceBlockTransferFactory::Build: block P" << i <<
" is not of type CrsMatrixWrap.");
413 bRebP->setMatrix(i, i, crsOpii);
415 bRebP->fillComplete();
417 Set(coarseLevel,
"P", Teuchos::rcp_dynamic_cast<Matrix>(bRebP));
420 if (UseSingleSource) {
421 RCP<xdBV> bcoarseCoords = rcp(
new xdBV(rebrangeMapExtractor->getBlockedMap(), newCoordinates));
422 Set(coarseLevel,
"Coordinates", bcoarseCoords);