47 #ifndef PACKAGES_XPETRA_SUP_MATRIX_UTILS_HPP_
48 #define PACKAGES_XPETRA_SUP_MATRIX_UTILS_HPP_
75 template <
class Scalar,
80 #undef XPETRA_MATRIXUTILS_SHORT
95 ret->replaceLocalValue(Teuchos::as<LocalOrdinal>(r), c, data[r]);
113 for(
size_t i = 0; i<input.
getColMap()->getNodeNumElements(); i++) {
114 GlobalOrdinal gcid = input.
getColMap()->getGlobalElement(i);
122 std::vector<int> myUnknownDofGIDs(comm->getSize(),0);
123 std::vector<int> numUnknownDofGIDs(comm->getSize(),0);
124 myUnknownDofGIDs[comm->getRank()] = ovlUnknownStatusGids.
size();
125 Teuchos::reduceAll(*comm,Teuchos::REDUCE_MAX,comm->getSize(),&myUnknownDofGIDs[0],&numUnknownDofGIDs[0]);
128 size_t cntUnknownDofGIDs = 0;
129 for(
int p = 0; p < comm->getSize(); p++) cntUnknownDofGIDs += numUnknownDofGIDs[p];
130 std::vector<GlobalOrdinal> lUnknownDofGIDs(cntUnknownDofGIDs,-1);
131 std::vector<GlobalOrdinal> gUnknownDofGIDs(cntUnknownDofGIDs,-1);
133 size_t cntUnknownOffset = 0;
134 for(
int p = 0; p < comm->getRank(); p++) cntUnknownOffset += numUnknownDofGIDs[p];
135 for(
size_t k=0; k < Teuchos::as<size_t>(ovlUnknownStatusGids.
size()); k++) {
136 lUnknownDofGIDs[k+cntUnknownOffset] = ovlUnknownStatusGids[k];
138 if(cntUnknownDofGIDs > 0)
139 Teuchos::reduceAll(*comm,Teuchos::REDUCE_MAX,Teuchos::as<int>(cntUnknownDofGIDs),&lUnknownDofGIDs[0],&gUnknownDofGIDs[0]);
140 std::sort(gUnknownDofGIDs.begin(), gUnknownDofGIDs.end());
141 gUnknownDofGIDs.erase(std::unique(gUnknownDofGIDs.begin(), gUnknownDofGIDs.end()), gUnknownDofGIDs.end());
144 for(
size_t k=0; k < gUnknownDofGIDs.size(); k++) {
145 GlobalOrdinal curgid = gUnknownDofGIDs[k];
151 std::vector<int> myFoundDofGIDs(comm->getSize(),0);
152 std::vector<int> numFoundDofGIDs(comm->getSize(),0);
153 myFoundDofGIDs[comm->getRank()] = ovlFoundStatusGids.
size();
154 Teuchos::reduceAll(*comm,Teuchos::REDUCE_MAX,comm->getSize(),&myFoundDofGIDs[0],&numFoundDofGIDs[0]);
157 size_t cntFoundDofGIDs = 0;
158 for(
int p = 0; p < comm->getSize(); p++) cntFoundDofGIDs += numFoundDofGIDs[p];
159 std::vector<GlobalOrdinal> lFoundDofGIDs(cntFoundDofGIDs,-1);
160 std::vector<GlobalOrdinal> gFoundDofGIDs(cntFoundDofGIDs,-1);
162 size_t cntFoundOffset = 0;
163 for(
int p = 0; p < comm->getRank(); p++) cntFoundOffset += numFoundDofGIDs[p];
164 for(
size_t k=0; k < Teuchos::as<size_t>(ovlFoundStatusGids.
size()); k++) {
165 lFoundDofGIDs[k+cntFoundOffset] = ovlFoundStatusGids[k];
167 if(cntFoundDofGIDs > 0)
168 Teuchos::reduceAll(*comm,Teuchos::REDUCE_MAX,Teuchos::as<int>(cntFoundDofGIDs),&lFoundDofGIDs[0],&gFoundDofGIDs[0]);
171 for(
size_t i = 0; i<input.
getColMap()->getNodeNumElements(); i++) {
172 GlobalOrdinal gcid = input.
getColMap()->getGlobalElement(i);
174 std::find(gFoundDofGIDs.begin(), gFoundDofGIDs.end(), gcid) != gFoundDofGIDs.end()) {
195 bool bThyraMode =
false) {
201 size_t numRows = rangeMapExtractor->NumMaps();
202 size_t numCols = domainMapExtractor->NumMaps();
204 TEUCHOS_TEST_FOR_EXCEPTION(rangeMapExtractor->getThyraMode() ==
true,
Xpetra::Exceptions::Incompatible,
"Xpetra::MatrixUtils::Split: RangeMapExtractor must not use Thyra style numbering of GIDs. The MapExtractor must contain all GIDs of the full range map in order to define a proper splitting.")
205 TEUCHOS_TEST_FOR_EXCEPTION(domainMapExtractor->getThyraMode() ==
true,
Xpetra::Exceptions::Incompatible,
"Xpetra::MatrixUtils::Split: DomainMapExtractor must not use Thyra style numbering of GIDs. The MapExtractor must contain all GIDs of the full domain map in order to define a proper splitting.")
217 TEUCHOS_TEST_FOR_EXCEPTION(fullDomainMap->getMaxAllGlobalIndex() != input.
getColMap()->getMaxAllGlobalIndex(),
Xpetra::Exceptions::Incompatible,
"Xpetra::MatrixUtils::Split: DomainMapExtractor incompatible to domain map of input matrix. fullDomainMap->getMaxAllGlobalIndex() = " << fullDomainMap->getMaxAllGlobalIndex() <<
" vs. input.getColMap()->getMaxAllGlobalIndex() = " << input.
getColMap()->getMaxAllGlobalIndex())
224 if(columnMapExtractor == Teuchos::null) {
227 std::vector<Teuchos::RCP<const Map> > ovlxmaps(numCols, Teuchos::null);
228 for(
size_t c = 0; c < numCols; c++) {
231 ovlxmaps[c] = colMap;
237 myColumnMapExtractor = columnMapExtractor;
244 if(bThyraMode ==
true) {
246 std::vector<Teuchos::RCP<const Map> > thyRgMapExtractorMaps(numRows, Teuchos::null);
247 for (
size_t r = 0; r < numRows; r++) {
251 if(strRangeMap != Teuchos::null) {
252 std::vector<size_t> strInfo = strRangeMap->getStridingData();
253 GlobalOrdinal offset = strRangeMap->getOffset();
254 LocalOrdinal stridedBlockId = strRangeMap->getStridedBlockId();
256 thyRgMapExtractorMaps[r] = strShrinkedMap;
258 thyRgMapExtractorMaps[r] = shrinkedMap;
264 std::vector<Teuchos::RCP<const Map> > thyDoMapExtractorMaps (numCols, Teuchos::null);
265 std::vector<Teuchos::RCP<const Map> > thyColMapExtractorMaps(numCols, Teuchos::null);
266 for (
size_t c = 0; c < numCols; c++) {
271 if(strDomainMap != Teuchos::null) {
272 std::vector<size_t> strInfo = strDomainMap->getStridingData();
273 GlobalOrdinal offset = strDomainMap->getOffset();
274 LocalOrdinal stridedBlockId = strDomainMap->getStridedBlockId();
276 thyDoMapExtractorMaps[c] = strShrinkedDomainMap;
278 thyDoMapExtractorMaps[c] = shrinkedDomainMap;
283 if(strColMap != Teuchos::null) {
284 std::vector<size_t> strInfo = strColMap->getStridingData();
285 GlobalOrdinal offset = strColMap->getOffset();
286 LocalOrdinal stridedBlockId = strColMap->getStridedBlockId();
288 thyColMapExtractorMaps[c] = strShrinkedColMap;
290 thyColMapExtractorMaps[c] = shrinkedColMap;
302 std::vector<Teuchos::RCP<Matrix> > subMatrices(numRows*numCols, Teuchos::null);
303 for (
size_t r = 0; r < numRows; r++) {
304 for (
size_t c = 0; c < numCols; c++) {
308 if(bThyraMode ==
true)
321 #if 0 // TAW needs to be fixed (does not compile for Scalar=complex)
328 doCheck->putScalar(1.0);
334 doCheck->putScalar(-1.0);
335 coCheck->putScalar(-1.0);
338 for (
size_t rrr = 0; rrr < input.
getDomainMap()->getNodeNumElements(); rrr++) {
340 GlobalOrdinal
id = input.
getDomainMap()->getGlobalElement(rrr);
343 size_t BlockId = domainMapExtractor->getMapIndexForGID(
id);
345 doCheckData[rrr] = Teuchos::as<Scalar>(BlockId);
353 for (
size_t rr = 0; rr < input.
getRowMap()->getNodeNumElements(); rr++) {
356 GlobalOrdinal growid = input.
getRowMap()->getGlobalElement(rr);
365 size_t rowBlockId = rangeMapExtractor->getMapIndexForGID(growid);
368 GlobalOrdinal subblock_growid = growid;
369 if(bThyraMode ==
true) {
371 LocalOrdinal lrowid = rangeMapExtractor->getMap(rowBlockId)->getLocalElement(growid);
373 subblock_growid = thyRangeMapExtractor->getMap(rowBlockId,
true)->getGlobalElement(lrowid);
386 for(
size_t i=0; i<(size_t)indices.
size(); i++) {
388 GlobalOrdinal gcolid = input.
getColMap()->getGlobalElement(indices[i]);
390 size_t colBlockId = myColumnMapExtractor->getMapIndexForGID(gcolid);
394 GlobalOrdinal subblock_gcolid = gcolid;
395 if(bThyraMode ==
true) {
397 LocalOrdinal lcolid = myColumnMapExtractor->getMap(colBlockId)->getLocalElement(gcolid);
399 subblock_gcolid = thyColMapExtractor->getMap(colBlockId,
true)->getGlobalElement(lcolid);
401 blockColIdx [colBlockId].push_back(subblock_gcolid);
402 blockColVals[colBlockId].push_back(vals[i]);
405 for (
size_t c = 0; c < numCols; c++) {
406 subMatrices[rowBlockId*numCols+c]->insertGlobalValues(subblock_growid,blockColIdx[c].view(0,blockColIdx[c].size()),blockColVals[c].view(0,blockColVals[c].size()));
413 if(bThyraMode ==
true) {
414 for (
size_t r = 0; r < numRows; r++) {
415 for (
size_t c = 0; c < numCols; c++) {
416 subMatrices[r*numCols+c]->fillComplete(thyDomainMapExtractor->getMap(c,
true), thyRangeMapExtractor->getMap(r,
true));
421 for (
size_t r = 0; r < numRows; r++) {
422 for (
size_t c = 0; c < numCols; c++) {
423 subMatrices[r*numCols+c]->fillComplete(domainMapExtractor->getMap(c), rangeMapExtractor->getMap(r));
429 for (
size_t r = 0; r < numRows; r++) {
430 for (
size_t c = 0; c < numCols; c++) {
431 bA->setMatrix(r,c,subMatrices[r*numCols+c]);
446 p->
set(
"DoOptimizeStorage",
true);
450 Ac->getLocalDiagCopy(*diagVec);
452 LocalOrdinal lZeroDiags = 0;
455 for (
size_t i = 0; i < rowMap->getNodeNumElements(); i++) {
456 if (diagVal[i] == zero) {
460 GlobalOrdinal gZeroDiags;
461 Teuchos::reduceAll(*(rowMap->getComm()), Teuchos::REDUCE_SUM, Teuchos::as<GlobalOrdinal>(lZeroDiags),
462 Teuchos::outArg(gZeroDiags));
464 if (repairZeroDiagonals && gZeroDiags > 0) {
482 for (
size_t r = 0; r < rowMap->getNodeNumElements(); r++) {
483 if (diagVal[r] == zero) {
484 GlobalOrdinal grid = rowMap->getGlobalElement(r);
487 fixDiagMatrix->insertGlobalValues(grid,indout(), valout());
492 fixDiagMatrix->fillComplete(Ac->getDomainMap(),Ac->getRangeMap());
496 Xpetra::MatrixMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>::TwoMatrixAdd(*Ac,
false, 1.0, *fixDiagMatrix,
false, 1.0, newAc, fos);
497 if (Ac->IsView(
"stridedMaps"))
498 newAc->CreateView(
"stridedMaps", Ac);
501 fixDiagMatrix = Teuchos::null;
515 fos <<
"CheckRepairMainDiagonal: " << (repairZeroDiagonals ?
"repaired " :
"found ")
516 << gZeroDiags <<
" zeros on main diagonal of Ac." << std::endl;
518 #ifdef HAVE_XPETRA_DEBUG // only for debugging
520 Ac->getLocalDiagCopy(*diagVec);
522 for (
size_t r = 0; r < Ac->getRowMap()->getNodeNumElements(); r++) {
523 if (diagVal2[r] == zero) {
524 fos <<
"Error: there are zeros left on diagonal after repair..." << std::endl;
535 #define XPETRA_MATRIXUTILS_SHORT
537 #endif // PACKAGES_XPETRA_SUP_MATRIX_UTILS_HPP_