51 const ParameterList& pL = GetParameterList();
52 size_t row = Teuchos::as<size_t>(pL.get<
int>(
"block row"));
53 size_t col = Teuchos::as<size_t>(pL.get<
int>(
"block col"));
55 RCP<Matrix> Ain = currentLevel.
Get<RCP<Matrix>>(
"A", this->GetFactory(
"A").get());
56 RCP<BlockedCrsMatrix> A = rcp_dynamic_cast<BlockedCrsMatrix>(Ain);
58 TEUCHOS_TEST_FOR_EXCEPTION(A.is_null(),
Exceptions::BadCast,
"Input matrix A is not a BlockedCrsMatrix.");
59 TEUCHOS_TEST_FOR_EXCEPTION(row > A->Rows(),
Exceptions::RuntimeError,
"row [" << row <<
"] > A.Rows() [" << A->Rows() <<
"].");
60 TEUCHOS_TEST_FOR_EXCEPTION(col > A->Cols(),
Exceptions::RuntimeError,
"col [" << col <<
"] > A.Cols() [" << A->Cols() <<
"].");
63 RCP<Matrix> Op = A->getMatrix(row, col);
70 RCP<BlockedCrsMatrix> bOp = rcp_dynamic_cast<BlockedCrsMatrix>(Op);
71 if (bOp != Teuchos::null) {
73 if (bOp->Rows() == 1 && bOp->Cols() == 1) {
75 Op = bOp->getCrsMatrix();
76 TEUCHOS_TEST_FOR_EXCEPTION(rcp_dynamic_cast<CrsMatrixWrap>(Op) == Teuchos::null,
Exceptions::BadCast,
77 "SubBlockAFactory::Build: sub block A[" << row <<
"," << col <<
"] must be a single block CrsMatrixWrap object!");
82 GetOStream(
Statistics1) <<
"A(" << row <<
"," << col <<
") is a " << bOp->Rows() <<
"x" << bOp->Cols() <<
" block matrix" << std::endl;
83 GetOStream(
Statistics2) <<
"with altogether " << bOp->getGlobalNumRows() <<
"x" << bOp->getGlobalNumCols() <<
" rows and columns." << std::endl;
84 currentLevel.
Set(
"A", Op,
this);
100 TEUCHOS_TEST_FOR_EXCEPTION(rcp_dynamic_cast<CrsMatrixWrap>(Op) == Teuchos::null,
Exceptions::BadCast,
101 "SubBlockAFactory::Build: sub block A[" << row <<
"," << col <<
"] is NOT a BlockedCrsMatrix, but also NOT a CrsMatrixWrap object. This cannot be.");
104 RCP<const StridedMap> stridedRangeMap = Teuchos::null;
105 RCP<const StridedMap> stridedDomainMap = Teuchos::null;
108 std::vector<size_t> rangeStridingInfo;
109 std::vector<size_t> domainStridingInfo;
112 bool bRangeUserSpecified = CheckForUserSpecifiedBlockInfo(
true, rangeStridingInfo, rangeStridedBlockId);
113 bool bDomainUserSpecified = CheckForUserSpecifiedBlockInfo(
false, domainStridingInfo, domainStridedBlockId);
115 "MueLu::SubBlockAFactory[" << row <<
"," << col <<
"]: the user has to specify either both domain and range map or none.");
118 RCP<const MapExtractor> rangeMapExtractor = A->getRangeMapExtractor();
119 RCP<const MapExtractor> domainMapExtractor = A->getDomainMapExtractor();
121 bool thyraMode = rangeMapExtractor->getThyraMode();
123 RCP<const Map> rangeMap = rangeMapExtractor->getMap(row, thyraMode);
124 RCP<const Map> domainMap = domainMapExtractor->getMap(col, thyraMode);
127 if (bRangeUserSpecified)
128 stridedRangeMap = rcp(
new StridedMap(rangeMap, rangeStridingInfo, rangeMap->getIndexBase(), rangeStridedBlockId, 0));
130 stridedRangeMap = rcp_dynamic_cast<const StridedMap>(rangeMap);
132 if (bDomainUserSpecified)
133 stridedDomainMap = rcp(
new StridedMap(domainMap, domainStridingInfo, domainMap->getIndexBase(), domainStridedBlockId, 0));
135 stridedDomainMap = rcp_dynamic_cast<const StridedMap>(domainMap);
140 if (stridedRangeMap.is_null()) {
141 RCP<const Map> fullRangeMap = rangeMapExtractor->getFullMap();
142 RCP<const StridedMap> stridedFullRangeMap = rcp_dynamic_cast<const StridedMap>(fullRangeMap);
143 TEUCHOS_TEST_FOR_EXCEPTION(stridedFullRangeMap.is_null(),
Exceptions::BadCast,
"Full rangeMap is not a strided map.");
145 std::vector<size_t> stridedData = stridedFullRangeMap->getStridingData();
146 if (stridedData.size() == 1 && row > 0) {
148 stridedRangeMap = StridedMapFactory::Build(rangeMap, stridedData, 0, stridedFullRangeMap->getOffset());
152 stridedRangeMap = StridedMapFactory::Build(rangeMap, stridedData, row, stridedFullRangeMap->getOffset());
156 if (stridedDomainMap.is_null()) {
157 RCP<const Map> fullDomainMap = domainMapExtractor->getFullMap();
158 RCP<const StridedMap> stridedFullDomainMap = rcp_dynamic_cast<const StridedMap>(fullDomainMap);
159 TEUCHOS_TEST_FOR_EXCEPTION(stridedFullDomainMap.is_null(),
Exceptions::BadCast,
"Full domainMap is not a strided map");
161 std::vector<size_t> stridedData = stridedFullDomainMap->getStridingData();
162 if (stridedData.size() == 1 && col > 0) {
164 stridedDomainMap = StridedMapFactory::Build(domainMap, stridedData, 0, stridedFullDomainMap->getOffset());
168 stridedDomainMap = StridedMapFactory::Build(domainMap, stridedData, col, stridedFullDomainMap->getOffset());
172 TEUCHOS_TEST_FOR_EXCEPTION(stridedRangeMap.is_null(),
Exceptions::BadCast,
"rangeMap " << row <<
" is not a strided map.");
173 TEUCHOS_TEST_FOR_EXCEPTION(stridedDomainMap.is_null(),
Exceptions::BadCast,
"domainMap " << col <<
" is not a strided map.");
175 GetOStream(
Statistics1) <<
"A(" << row <<
"," << col <<
") is a single block and has strided maps:"
176 <<
"\n range map fixed block size = " << stridedRangeMap->getFixedBlockSize() <<
", strided block id = " << stridedRangeMap->getStridedBlockId()
177 <<
"\n domain map fixed block size = " << stridedDomainMap->getFixedBlockSize() <<
", strided block id = " << stridedDomainMap->getStridedBlockId() << std::endl;
178 GetOStream(
Statistics2) <<
"A(" << row <<
"," << col <<
") has " << Op->getGlobalNumRows() <<
"x" << Op->getGlobalNumCols() <<
" rows and columns." << std::endl;
181 if (Op->IsView(
"stridedMaps") ==
true)
182 Op->RemoveView(
"stridedMaps");
183 Op->CreateView(
"stridedMaps", stridedRangeMap, stridedDomainMap);
185 TEUCHOS_TEST_FOR_EXCEPTION(Op->IsView(
"stridedMaps") ==
false,
Exceptions::RuntimeError,
"Failed to set \"stridedMaps\" view.");
187 currentLevel.
Set(
"A", Op,
this);