47 #ifndef PACKAGES_XPETRA_SUP_MATRIX_UTILS_HPP_
48 #define PACKAGES_XPETRA_SUP_MATRIX_UTILS_HPP_
64 #ifdef HAVE_XPETRA_TPETRA
65 #include <Tpetra_RowMatrixTransposer.hpp>
79 template <
class Scalar,
84 #undef XPETRA_MATRIXUTILS_SHORT
99 ret->replaceLocalValue(Teuchos::as<LocalOrdinal>(r), c, data[r]);
117 for(
size_t i = 0; i<input.
getColMap()->getNodeNumElements(); i++) {
118 GlobalOrdinal gcid = input.
getColMap()->getGlobalElement(i);
126 std::vector<int> myUnknownDofGIDs(comm->getSize(),0);
127 std::vector<int> numUnknownDofGIDs(comm->getSize(),0);
128 myUnknownDofGIDs[comm->getRank()] = ovlUnknownStatusGids.
size();
132 size_t cntUnknownDofGIDs = 0;
133 for(
int p = 0; p < comm->getSize(); p++) cntUnknownDofGIDs += numUnknownDofGIDs[p];
134 std::vector<GlobalOrdinal> lUnknownDofGIDs(cntUnknownDofGIDs,-1);
135 std::vector<GlobalOrdinal> gUnknownDofGIDs(cntUnknownDofGIDs,-1);
137 size_t cntUnknownOffset = 0;
138 for(
int p = 0; p < comm->getRank(); p++) cntUnknownOffset += numUnknownDofGIDs[p];
139 for(
size_t k=0; k < Teuchos::as<size_t>(ovlUnknownStatusGids.
size()); k++) {
140 lUnknownDofGIDs[k+cntUnknownOffset] = ovlUnknownStatusGids[k];
142 if(cntUnknownDofGIDs > 0)
144 std::sort(gUnknownDofGIDs.begin(), gUnknownDofGIDs.end());
145 gUnknownDofGIDs.erase(std::unique(gUnknownDofGIDs.begin(), gUnknownDofGIDs.end()), gUnknownDofGIDs.end());
148 for(
size_t k=0; k < gUnknownDofGIDs.size(); k++) {
149 GlobalOrdinal curgid = gUnknownDofGIDs[k];
155 std::vector<int> myFoundDofGIDs(comm->getSize(),0);
156 std::vector<int> numFoundDofGIDs(comm->getSize(),0);
157 myFoundDofGIDs[comm->getRank()] = ovlFoundStatusGids.
size();
161 size_t cntFoundDofGIDs = 0;
162 for(
int p = 0; p < comm->getSize(); p++) cntFoundDofGIDs += numFoundDofGIDs[p];
163 std::vector<GlobalOrdinal> lFoundDofGIDs(cntFoundDofGIDs,-1);
164 std::vector<GlobalOrdinal> gFoundDofGIDs(cntFoundDofGIDs,-1);
166 size_t cntFoundOffset = 0;
167 for(
int p = 0; p < comm->getRank(); p++) cntFoundOffset += numFoundDofGIDs[p];
168 for(
size_t k=0; k < Teuchos::as<size_t>(ovlFoundStatusGids.
size()); k++) {
169 lFoundDofGIDs[k+cntFoundOffset] = ovlFoundStatusGids[k];
171 if(cntFoundDofGIDs > 0)
175 for(
size_t i = 0; i<input.
getColMap()->getNodeNumElements(); i++) {
176 GlobalOrdinal gcid = input.
getColMap()->getGlobalElement(i);
178 std::find(gFoundDofGIDs.begin(), gFoundDofGIDs.end(), gcid) != gFoundDofGIDs.end()) {
199 bool bThyraMode =
false) {
205 size_t numRows = rangeMapExtractor->NumMaps();
206 size_t numCols = domainMapExtractor->NumMaps();
208 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.")
209 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.")
221 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())
228 if(columnMapExtractor == Teuchos::null) {
231 std::vector<Teuchos::RCP<const Map> > ovlxmaps(numCols, Teuchos::null);
232 for(
size_t c = 0; c < numCols; c++) {
235 ovlxmaps[c] = colMap;
241 myColumnMapExtractor = columnMapExtractor;
248 if(bThyraMode ==
true) {
250 std::vector<Teuchos::RCP<const Map> > thyRgMapExtractorMaps(numRows, Teuchos::null);
251 for (
size_t r = 0; r < numRows; r++) {
255 if(strRangeMap != Teuchos::null) {
256 std::vector<size_t> strInfo = strRangeMap->getStridingData();
257 GlobalOrdinal offset = strRangeMap->getOffset();
258 LocalOrdinal stridedBlockId = strRangeMap->getStridedBlockId();
260 thyRgMapExtractorMaps[r] = strShrinkedMap;
262 thyRgMapExtractorMaps[r] = shrinkedMap;
268 std::vector<Teuchos::RCP<const Map> > thyDoMapExtractorMaps (numCols, Teuchos::null);
269 std::vector<Teuchos::RCP<const Map> > thyColMapExtractorMaps(numCols, Teuchos::null);
270 for (
size_t c = 0; c < numCols; c++) {
275 if(strDomainMap != Teuchos::null) {
276 std::vector<size_t> strInfo = strDomainMap->getStridingData();
277 GlobalOrdinal offset = strDomainMap->getOffset();
278 LocalOrdinal stridedBlockId = strDomainMap->getStridedBlockId();
280 thyDoMapExtractorMaps[c] = strShrinkedDomainMap;
282 thyDoMapExtractorMaps[c] = shrinkedDomainMap;
287 if(strColMap != Teuchos::null) {
288 std::vector<size_t> strInfo = strColMap->getStridingData();
289 GlobalOrdinal offset = strColMap->getOffset();
290 LocalOrdinal stridedBlockId = strColMap->getStridedBlockId();
292 thyColMapExtractorMaps[c] = strShrinkedColMap;
294 thyColMapExtractorMaps[c] = shrinkedColMap;
306 std::vector<Teuchos::RCP<Matrix> > subMatrices(numRows*numCols, Teuchos::null);
307 for (
size_t r = 0; r < numRows; r++) {
308 for (
size_t c = 0; c < numCols; c++) {
312 if(bThyraMode ==
true)
325 #if 0 // TAW needs to be fixed (does not compile for Scalar=complex)
332 doCheck->putScalar(1.0);
338 doCheck->putScalar(-1.0);
339 coCheck->putScalar(-1.0);
342 for (
size_t rrr = 0; rrr < input.
getDomainMap()->getNodeNumElements(); rrr++) {
344 GlobalOrdinal
id = input.
getDomainMap()->getGlobalElement(rrr);
347 size_t BlockId = domainMapExtractor->getMapIndexForGID(
id);
349 doCheckData[rrr] = Teuchos::as<Scalar>(BlockId);
357 for (
size_t rr = 0; rr < input.
getRowMap()->getNodeNumElements(); rr++) {
360 GlobalOrdinal growid = input.
getRowMap()->getGlobalElement(rr);
369 size_t rowBlockId = rangeMapExtractor->getMapIndexForGID(growid);
372 GlobalOrdinal subblock_growid = growid;
373 if(bThyraMode ==
true) {
375 LocalOrdinal lrowid = rangeMapExtractor->getMap(rowBlockId)->getLocalElement(growid);
377 subblock_growid = thyRangeMapExtractor->getMap(rowBlockId,
true)->getGlobalElement(lrowid);
390 for(
size_t i=0; i<(size_t)indices.
size(); i++) {
392 GlobalOrdinal gcolid = input.
getColMap()->getGlobalElement(indices[i]);
394 size_t colBlockId = myColumnMapExtractor->getMapIndexForGID(gcolid);
398 GlobalOrdinal subblock_gcolid = gcolid;
399 if(bThyraMode ==
true) {
401 LocalOrdinal lcolid = myColumnMapExtractor->getMap(colBlockId)->getLocalElement(gcolid);
403 subblock_gcolid = thyColMapExtractor->getMap(colBlockId,
true)->getGlobalElement(lcolid);
405 blockColIdx [colBlockId].push_back(subblock_gcolid);
406 blockColVals[colBlockId].push_back(vals[i]);
409 for (
size_t c = 0; c < numCols; c++) {
410 subMatrices[rowBlockId*numCols+c]->insertGlobalValues(subblock_growid,blockColIdx[c].view(0,blockColIdx[c].size()),blockColVals[c].view(0,blockColVals[c].size()));
417 if(bThyraMode ==
true) {
418 for (
size_t r = 0; r < numRows; r++) {
419 for (
size_t c = 0; c < numCols; c++) {
420 subMatrices[r*numCols+c]->fillComplete(thyDomainMapExtractor->getMap(c,
true), thyRangeMapExtractor->getMap(r,
true));
425 for (
size_t r = 0; r < numRows; r++) {
426 for (
size_t c = 0; c < numCols; c++) {
427 subMatrices[r*numCols+c]->fillComplete(domainMapExtractor->getMap(c), rangeMapExtractor->getMap(r));
433 for (
size_t r = 0; r < numRows; r++) {
434 for (
size_t c = 0; c < numCols; c++) {
435 bA->setMatrix(r,c,subMatrices[r*numCols+c]);
448 Scalar one = TST::one();
451 p->
set(
"DoOptimizeStorage",
true);
455 Ac->getLocalDiagCopy(*diagVec);
457 LocalOrdinal lZeroDiags = 0;
460 for (
size_t i = 0; i < rowMap->getNodeNumElements(); i++) {
461 if (TST::magnitude(diagVal[i]) <= threshold) {
465 GlobalOrdinal gZeroDiags;
467 Teuchos::outArg(gZeroDiags));
469 if (repairZeroDiagonals && gZeroDiags > 0) {
487 for (
size_t r = 0; r < rowMap->getNodeNumElements(); r++) {
488 if (TST::magnitude(diagVal[r]) <= threshold) {
489 GlobalOrdinal grid = rowMap->getGlobalElement(r);
492 fixDiagMatrix->insertGlobalValues(grid,indout(), valout());
497 fixDiagMatrix->fillComplete(Ac->getDomainMap(),Ac->getRangeMap());
501 Xpetra::MatrixMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node>::TwoMatrixAdd(*Ac,
false, 1.0, *fixDiagMatrix,
false, 1.0, newAc, fos);
502 if (Ac->IsView(
"stridedMaps"))
503 newAc->CreateView(
"stridedMaps", Ac);
506 fixDiagMatrix = Teuchos::null;
520 fos <<
"CheckRepairMainDiagonal: " << (repairZeroDiagonals ?
"repaired " :
"found ")
521 << gZeroDiags <<
" too small entries on main diagonal of Ac." << std::endl;
523 #ifdef HAVE_XPETRA_DEBUG // only for debugging
525 Ac->getLocalDiagCopy(*diagVec);
527 for (
size_t r = 0; r < Ac->getRowMap()->getNodeNumElements(); r++) {
528 if (TST::magnitude(diagVal[r]) <= threshold) {
529 fos <<
"Error: there are too small entries left on diagonal after repair..." << std::endl;
540 #define XPETRA_MATRIXUTILS_SHORT
542 #endif // PACKAGES_XPETRA_SUP_MATRIX_UTILS_HPP_
virtual size_t getNodeMaxNumRowEntries() const =0
Returns the maximum number of entries across all rows/columns on this node.
static Teuchos::RCP< Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > findColumnSubMap(const Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &input, const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > &domainMap)
static RCP< Import< LocalOrdinal, GlobalOrdinal, Node > > Build(const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &source, const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &target)
Constructor specifying the number of non-zeros for all rows.
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Exception throws to report errors in the internal logical of the program.
Xpetra utility class for common map-related routines.
static void CheckRepairMainDiagonal(RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node >> &Ac, bool const &repairZeroDiagonals, Teuchos::FancyOStream &fos, const typename Teuchos::ScalarTraits< Scalar >::magnitudeType threshold=Teuchos::ScalarTraits< typename Teuchos::ScalarTraits< Scalar >::magnitudeType >::zero())
static Teuchos::RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > concatenateMaps(const std::vector< Teuchos::RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > > &subMaps)
Helper function to concatenate several maps.
static Teuchos::RCP< Xpetra::BlockedCrsMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > SplitMatrix(const Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > &input, Teuchos::RCP< const Xpetra::MapExtractor< Scalar, LocalOrdinal, GlobalOrdinal, Node > > rangeMapExtractor, Teuchos::RCP< const Xpetra::MapExtractor< Scalar, LocalOrdinal, GlobalOrdinal, Node > > domainMapExtractor, Teuchos::RCP< const Xpetra::MapExtractor< Scalar, LocalOrdinal, GlobalOrdinal, Node > > columnMapExtractor=Teuchos::null, bool bThyraMode=false)
static RCP< Time > getNewTimer(const std::string &name)
virtual const RCP< const Map > & getColMap() const
Returns the Map that describes the column distribution in this matrix. This might be null until fillC...
virtual bool isNodeGlobalElement(GlobalOrdinal globalIndex) const =0
Whether the given global index is valid for this Map on this process.
virtual void getLocalRowView(LocalOrdinal LocalRow, ArrayView< const LocalOrdinal > &indices, ArrayView< const Scalar > &values) const =0
Extract a const, non-persisting view of local indices in a specified row of the matrix.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
virtual Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > getMap() const =0
The Map describing the parallel distribution of this object.
TEUCHOS_DEPRECATED void reduceAll(const Comm< Ordinal > &comm, const EReductionType reductType, const Packet &send, Packet *globalReduct)
virtual size_t getLocalLength() const =0
Local number of rows on the calling process.
static Teuchos::RCP< Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > shrinkMapGIDs(const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > &input, const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > &nonOvlInput)
Helper function to shrink the GIDs and generate a standard map whith GIDs starting at 0...
static RCP< Vector > Build(const Teuchos::RCP< const Map > &map, bool zeroOut=true)
Constructor specifying the number of non-zeros for all rows.
static void TwoMatrixAdd(const Matrix &A, bool transposeA, SC alpha, Matrix &B, SC beta)
Helper function to calculate B = alpha*A + beta*B.
static Teuchos::RCP< Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > xpetraGidNumbering2ThyraGidNumbering(const Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &input)
static magnitudeType magnitude(T a)
void push_back(const value_type &x)
Exception throws to report incompatible objects (like maps).
virtual Teuchos::RCP< const Map > getRangeMap() const =0
The Map associated with the range of this operator, which must be compatible with Y...
static Teuchos::RCP< MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > Build(const Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > &map, size_t NumVectors, bool zeroOut=true)
Constructor specifying the number of non-zeros for all rows.
static RCP< Matrix > Build(const RCP< const Map > &rowMap, size_t maxNumEntriesPerRow, Xpetra::ProfileType pftype=Xpetra::DynamicProfile)
Constructor specifying the number of non-zeros for all rows.
virtual const RCP< const Map > & getRowMap() const
Returns the Map that describes the row distribution in this matrix.
static Teuchos::RCP< Map< LocalOrdinal, GlobalOrdinal, Node > > Build(UnderlyingLib lib, global_size_t numGlobalElements, GlobalOrdinal indexBase, const Teuchos::RCP< const Teuchos::Comm< int > > &comm, LocalGlobal lg=Xpetra::GloballyDistributed)
Map constructor with Xpetra-defined contiguous uniform distribution.
virtual size_t getNumVectors() const =0
Number of columns in the multivector.
virtual UnderlyingLib lib() const =0
Get the library used by this object (Tpetra or Epetra?)
virtual Teuchos::ArrayRCP< const Scalar > getData(size_t j) const =0
Const view of the local values in a particular vector of this multivector.
Xpetra utility class for common matrix-related routines.
virtual Teuchos::RCP< const Map > getDomainMap() const =0
The Map associated with the domain of this operator, which must be compatible with X...
Xpetra-specific matrix class.
Class that stores a strided map.