115 RCP<Teuchos::FancyOStream> out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
119 RCP<Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > bA = Teuchos::rcp_dynamic_cast<Xpetra::BlockedCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >(originalAc);
120 TEUCHOS_TEST_FOR_EXCEPTION(bA==Teuchos::null,
Exceptions::BadCast,
"MueLu::RebalanceBlockAcFactory::Build: input matrix A is not of type BlockedCrsMatrix! error.");
121 TEUCHOS_TEST_FOR_EXCEPTION(bA->Rows() != bA->Cols(),
Exceptions::RuntimeError,
"MueLu::RebalanceBlockAcFactory::Build: Blocked operator has " << bA->Rows() <<
" and " << bA->Cols() <<
". We only support square matrices (with same number of blocks and columns).");
124 std::vector<GO> fullRangeMapVector;
125 std::vector<GO> fullDomainMapVector;
126 std::vector<RCP<const Map> > subBlockARangeMaps;
127 std::vector<RCP<const Map> > subBlockADomainMaps;
128 subBlockARangeMaps.reserve(bA->Rows());
129 subBlockADomainMaps.reserve(bA->Cols());
132 RCP<const MapExtractor> rangeMapExtractor = bA->getRangeMapExtractor();
133 RCP<const MapExtractor> domainMapExtractor = bA->getDomainMapExtractor();
142 bool bThyraRangeGIDs = rangeMapExtractor->getThyraMode();
143 bool bThyraDomainGIDs = domainMapExtractor->getThyraMode();
146 std::vector<RCP<Matrix> > subBlockRebA =
147 std::vector<RCP<Matrix> >(bA->Cols() * bA->Rows(), Teuchos::null);
151 std::vector<RCP<const Import> > importers = std::vector<RCP<const Import> >(bA->Rows(), Teuchos::null);
152 std::vector<Teuchos::RCP<const FactoryManagerBase> >::const_iterator it;
158 RCP<const Import> rebalanceImporter = coarseLevel.
Get<RCP<const Import> >(
"Importer", (*it)->GetFactory(
"Importer").get());
159 importers[idx] = rebalanceImporter;
168 bool bRestrictComm =
false;
170 if (pL.get<
bool>(
"repartition: use subcommunicators") ==
true)
171 bRestrictComm =
true;
173 RCP<ParameterList> XpetraList = Teuchos::rcp(
new ParameterList());
175 XpetraList->set(
"Restrict Communicator",
true);
177 XpetraList->set(
"Restrict Communicator",
false);
181 RCP<const Teuchos::Comm<int> > rebalancedComm = Teuchos::null;
186 for(
size_t i=0; i<bA->Rows(); i++) {
187 for(
size_t j=0; j<bA->Cols(); j++) {
189 RCP<Matrix> Aij = bA->getMatrix(i, j);
191 std::stringstream ss; ss <<
"Rebalancing matrix block A(" << i <<
"," << j <<
")";
194 RCP<Matrix> rebAij = Teuchos::null;
196 if( importers[i] != Teuchos::null &&
197 importers[j] != Teuchos::null &&
198 Aij != Teuchos::null) {
199 RCP<const Map> targetRangeMap = importers[i]->getTargetMap();
200 RCP<const Map> targetDomainMap = importers[j]->getTargetMap();
207 RCP<Matrix> cAij = Aij;
210 Teuchos::RCP<const Import> rebAijImport = ImportFactory::Build(importers[j]->getTargetMap(),cAij->getColMap());
211 TEUCHOS_TEST_FOR_EXCEPTION(rebAijImport.is_null() ==
true,
Exceptions::RuntimeError,
"MueLu::RebalanceBlockAcFactory::Build: Importer associated with block " << j <<
" is null.");
213 Teuchos::RCP<const CrsMatrixWrap> cAwij = Teuchos::rcp_dynamic_cast<const CrsMatrixWrap>(cAij);
214 TEUCHOS_TEST_FOR_EXCEPTION(cAwij.is_null() ==
true,
Exceptions::RuntimeError,
"MueLu::RebalanceBlockAcFactory::Build: Block (" << i <<
"," << j <<
") is not of type CrsMatrix. We cannot rebalanced (nested) operators.");
215 Teuchos::RCP<CrsMatrix> cAmij = cAwij->getCrsMatrix();
222 rebAij = MatrixFactory::Build(cAij, *(importers[i]), *(importers[j]), targetDomainMap, targetRangeMap, XpetraList);
229 subBlockRebA[i*bA->Cols() + j] = rebAij;
231 if (!rebAij.is_null()) {
233 if(rebalancedComm.is_null()) rebalancedComm = rebAij->getRowMap()->getComm();
236 RCP<ParameterList> params = rcp(
new ParameterList());
237 params->set(
"printLoadBalancingInfo",
true);
238 std::stringstream ss2; ss2 <<
"A(" << i <<
"," << j <<
") rebalanced:";
248 if ( subBlockRebA[i*bA->Cols() + i].is_null() ==
false ) {
249 RCP<Matrix> rebAii = subBlockRebA[i*bA->Cols() + i];
250 Teuchos::RCP<const StridedMap> orig_stridedRgMap = Teuchos::rcp_dynamic_cast<const StridedMap>(rangeMapExtractor->getMap(i,rangeMapExtractor->getThyraMode()));
251 Teuchos::RCP<const Map> stridedRgMap = Teuchos::null;
252 if(orig_stridedRgMap != Teuchos::null) {
253 std::vector<size_t> stridingData = orig_stridedRgMap->getStridingData();
254 Teuchos::ArrayView< const GlobalOrdinal > nodeRangeMapii = rebAii->getRangeMap()->getLocalElementList();
255 stridedRgMap = StridedMapFactory::Build(
256 bA->getRangeMap()->lib(),
257 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
259 rebAii->getRangeMap()->getIndexBase(),
262 orig_stridedRgMap->getStridedBlockId(),
263 orig_stridedRgMap->getOffset());
265 Teuchos::RCP<const StridedMap> orig_stridedDoMap = Teuchos::rcp_dynamic_cast<const StridedMap>(domainMapExtractor->getMap(i,domainMapExtractor->getThyraMode()));
266 Teuchos::RCP<const Map> stridedDoMap = Teuchos::null;
267 if(orig_stridedDoMap != Teuchos::null) {
268 std::vector<size_t> stridingData = orig_stridedDoMap->getStridingData();
269 Teuchos::ArrayView< const GlobalOrdinal > nodeDomainMapii = rebAii->getDomainMap()->getLocalElementList();
270 stridedDoMap = StridedMapFactory::Build(
271 bA->getDomainMap()->lib(),
272 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
274 rebAii->getDomainMap()->getIndexBase(),
277 orig_stridedDoMap->getStridedBlockId(),
278 orig_stridedDoMap->getOffset());
282 stridedRgMap->removeEmptyProcesses();
283 stridedDoMap->removeEmptyProcesses();
286 TEUCHOS_TEST_FOR_EXCEPTION(stridedRgMap == Teuchos::null,
Exceptions::RuntimeError,
"MueLu::RebalanceBlockAcFactory::Build: failed to generate striding information. error.");
287 TEUCHOS_TEST_FOR_EXCEPTION(stridedDoMap == Teuchos::null,
Exceptions::RuntimeError,
"MueLu::RebalanceBlockAcFactory::Build: failed to generate striding information. error.");
290 if(rebAii->IsView(
"stridedMaps")) rebAii->RemoveView(
"stridedMaps");
291 rebAii->CreateView(
"stridedMaps", stridedRgMap, stridedDoMap);
293 subBlockARangeMaps.push_back(rebAii->getRowMap(
"stridedMaps"));
294 Teuchos::ArrayView< const GlobalOrdinal > nodeRangeMap = rebAii->getRangeMap()->getLocalElementList();
296 fullRangeMapVector.insert(fullRangeMapVector.end(), nodeRangeMap.begin(), nodeRangeMap.end());
297 if(bThyraRangeGIDs ==
false)
298 sort(fullRangeMapVector.begin(), fullRangeMapVector.end());
300 subBlockADomainMaps.push_back(rebAii->getColMap(
"stridedMaps"));
301 Teuchos::ArrayView< const GlobalOrdinal > nodeDomainMap = rebAii->getDomainMap()->getLocalElementList();
303 fullDomainMapVector.insert(fullDomainMapVector.end(), nodeDomainMap.begin(), nodeDomainMap.end());
304 if(bThyraDomainGIDs ==
false)
305 sort(fullDomainMapVector.begin(), fullDomainMapVector.end());
312 if (rebalancedComm == Teuchos::null) {
313 GetOStream(
Debug,-1) <<
"RebalanceBlockedAc: deactivate proc " << originalAc->getRowMap()->getComm()->getRank() << std::endl;
315 Teuchos::RCP<BlockedCrsMatrix> reb_bA = Teuchos::null;
316 coarseLevel.
Set(
"A", Teuchos::rcp_dynamic_cast<Matrix>(reb_bA),
this);
322 GO rangeIndexBase = bA->getRangeMap()->getIndexBase();
323 GO domainIndexBase = bA->getDomainMap()->getIndexBase();
325 Teuchos::ArrayView<GO> fullRangeMapGIDs(fullRangeMapVector.size() ? &fullRangeMapVector[0] : 0,fullRangeMapVector.size());
326 Teuchos::RCP<const StridedMap> stridedRgFullMap = Teuchos::rcp_dynamic_cast<const StridedMap>(rangeMapExtractor->getFullMap());
327 Teuchos::RCP<const Map > fullRangeMap = Teuchos::null;
328 if(stridedRgFullMap != Teuchos::null) {
329 std::vector<size_t> stridedData = stridedRgFullMap->getStridingData();
331 StridedMapFactory::Build(
332 bA->getRangeMap()->lib(),
333 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
338 stridedRgFullMap->getStridedBlockId(),
339 stridedRgFullMap->getOffset());
343 bA->getRangeMap()->lib(),
344 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
349 Teuchos::ArrayView<GO> fullDomainMapGIDs(fullDomainMapVector.size() ? &fullDomainMapVector[0] : 0,fullDomainMapVector.size());
351 Teuchos::RCP<const StridedMap> stridedDoFullMap = Teuchos::rcp_dynamic_cast<const StridedMap>(domainMapExtractor->getFullMap());
352 Teuchos::RCP<const Map > fullDomainMap = Teuchos::null;
353 if(stridedDoFullMap != Teuchos::null) {
354 TEUCHOS_TEST_FOR_EXCEPTION(stridedDoFullMap==Teuchos::null,
Exceptions::BadCast,
"MueLu::RebalanceBlockedAc::Build: full map in domain map extractor has no striding information! error.");
355 std::vector<size_t> stridedData2 = stridedDoFullMap->getStridingData();
357 StridedMapFactory::Build(
358 bA->getDomainMap()->lib(),
359 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
364 stridedDoFullMap->getStridedBlockId(),
365 stridedDoFullMap->getOffset());
370 bA->getDomainMap()->lib(),
371 Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(),
378 fullRangeMap->removeEmptyProcesses();
379 fullDomainMap->removeEmptyProcesses();
383 RCP<const MapExtractor> rebRangeMapExtractor = MapExtractorFactory::Build(fullRangeMap, subBlockARangeMaps, bThyraRangeGIDs);
384 RCP<const MapExtractor> rebDomainMapExtractor = MapExtractorFactory::Build(fullDomainMap, subBlockADomainMaps, bThyraDomainGIDs);
386 TEUCHOS_TEST_FOR_EXCEPTION(rangeMapExtractor->NumMaps() != rebRangeMapExtractor->NumMaps(),
Exceptions::RuntimeError,
387 "MueLu::RebalanceBlockedAc::Build: Rebalanced RangeMapExtractor has " << rebRangeMapExtractor->NumMaps()
388 <<
" sub maps. Original RangeMapExtractor has " << rangeMapExtractor->NumMaps() <<
". They must match!");
389 TEUCHOS_TEST_FOR_EXCEPTION(domainMapExtractor->NumMaps() != rebDomainMapExtractor->NumMaps(),
Exceptions::RuntimeError,
390 "MueLu::RebalanceBlockedAc::Build: Rebalanced DomainMapExtractor has " << rebDomainMapExtractor->NumMaps()
391 <<
" sub maps. Original DomainMapExtractor has " << domainMapExtractor->NumMaps() <<
". They must match!");
393 Teuchos::RCP<BlockedCrsMatrix> reb_bA = Teuchos::rcp(
new BlockedCrsMatrix(rebRangeMapExtractor,rebDomainMapExtractor,10));
394 for(
size_t i=0; i<bA->Rows(); i++) {
395 for(
size_t j=0; j<bA->Cols(); j++) {
396 reb_bA->setMatrix(i,j,subBlockRebA[i*bA->Cols() + j]);
400 reb_bA->fillComplete();
402 coarseLevel.
Set(
"A", Teuchos::rcp_dynamic_cast<Matrix>(reb_bA),
this);
412 GetOStream(
Runtime0) <<
"RebalanceBlockedAc: call rebalance factory " << (*it2).get() <<
": " << (*it2)->description() << std::endl;
413 (*it2)->CallBuild(coarseLevel);