All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Xpetra_BlockedCrsMatrix.hpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // Xpetra: A linear algebra interface package
6 // Copyright 2012 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact
39 // Jonathan Hu (jhu@sandia.gov)
40 // Andrey Prokopenko (aprokop@sandia.gov)
41 // Ray Tuminaro (rstumin@sandia.gov)
42 //
43 // ***********************************************************************
44 //
45 // @HEADER
46 #ifndef XPETRA_BLOCKEDCRSMATRIX_HPP
47 #define XPETRA_BLOCKEDCRSMATRIX_HPP
48 
49 #include <Kokkos_DefaultNode.hpp>
50 
52 #include <Teuchos_Hashtable.hpp>
53 
54 #include "Xpetra_ConfigDefs.hpp"
55 #include "Xpetra_Exceptions.hpp"
56 
57 #include "Xpetra_MapFactory.hpp"
58 #include "Xpetra_MultiVector.hpp"
59 #include "Xpetra_BlockedMultiVector.hpp"
60 #include "Xpetra_MultiVectorFactory.hpp"
61 #include "Xpetra_BlockedVector.hpp"
62 #include "Xpetra_CrsGraph.hpp"
63 #include "Xpetra_CrsMatrix.hpp"
65 
66 #include "Xpetra_MapExtractor.hpp"
67 
68 #include "Xpetra_Matrix.hpp"
69 #include "Xpetra_MatrixFactory.hpp"
70 #include "Xpetra_CrsMatrixWrap.hpp"
71 
72 #ifdef HAVE_XPETRA_THYRA
73 #include <Thyra_ProductVectorSpaceBase.hpp>
74 #include <Thyra_VectorSpaceBase.hpp>
75 #include <Thyra_LinearOpBase.hpp>
76 #include <Thyra_BlockedLinearOpBase.hpp>
77 #include <Thyra_PhysicallyBlockedLinearOpBase.hpp>
78 #include "Xpetra_ThyraUtils.hpp"
79 #endif
80 
81 #include "Xpetra_VectorFactory.hpp"
82 
83 
88 namespace Xpetra {
89 
90  typedef std::string viewLabel_t;
91 
92  template <class Scalar,
93  class LocalOrdinal,
94  class GlobalOrdinal,
97  public Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> {
98  public:
99  typedef Scalar scalar_type;
100  typedef LocalOrdinal local_ordinal_type;
101  typedef GlobalOrdinal global_ordinal_type;
102  typedef Node node_type;
103 
104  private:
105 #undef XPETRA_BLOCKEDCRSMATRIX_SHORT
106 #include "Xpetra_UseShortNames.hpp"
107 
108  public:
109 
111 
112 
114 
121  const Teuchos::RCP<const BlockedMap>& domainMaps,
122  size_t npr, Xpetra::ProfileType pftype = Xpetra::DynamicProfile) {
123  is_diagonal_ = true;
124  domainmaps_ = Teuchos::rcp(new MapExtractor(domainMaps));
125  rangemaps_ = Teuchos::rcp(new MapExtractor(rangeMaps));
126  bRangeThyraMode_ = rangeMaps->getThyraMode();
127  bDomainThyraMode_ = domainMaps->getThyraMode();
128 
129  blocks_.reserve(Rows()*Cols());
130 
131  // add CrsMatrix objects in row,column order
132  for (size_t r = 0; r < Rows(); ++r)
133  for (size_t c = 0; c < Cols(); ++c)
134  blocks_.push_back(MatrixFactory::Build(getRangeMap(r,bRangeThyraMode_), npr, pftype));
135 
136  // Default view
138  }
139 
141 
151  size_t npr, Xpetra::ProfileType pftype = Xpetra::DynamicProfile)
152  : is_diagonal_(true), domainmaps_(domainMaps), rangemaps_(rangeMaps)
153  {
154  bRangeThyraMode_ = rangeMaps->getThyraMode();
155  bDomainThyraMode_ = domainMaps->getThyraMode();
156 
157  blocks_.reserve(Rows()*Cols());
158 
159  // add CrsMatrix objects in row,column order
160  for (size_t r = 0; r < Rows(); ++r)
161  for (size_t c = 0; c < Cols(); ++c)
162  blocks_.push_back(MatrixFactory::Build(getRangeMap(r,bRangeThyraMode_), npr, pftype));
163 
164  // Default view
166  }
167 
168 #ifdef HAVE_XPETRA_THYRA
169 
176  BlockedCrsMatrix(const Teuchos::RCP<const Thyra::BlockedLinearOpBase<Scalar> >& thyraOp, const Teuchos::RCP<const Teuchos::Comm<int> >& /* comm */)
177  : is_diagonal_(true), thyraOp_(thyraOp)
178  {
179  // extract information from Thyra blocked operator and rebuilt information
180  const Teuchos::RCP<const Thyra::ProductVectorSpaceBase<Scalar> > productRangeSpace = thyraOp->productRange();
181  const Teuchos::RCP<const Thyra::ProductVectorSpaceBase<Scalar> > productDomainSpace = thyraOp->productDomain();
182 
183  int numRangeBlocks = productRangeSpace->numBlocks();
184  int numDomainBlocks = productDomainSpace->numBlocks();
185 
186  // build range map extractor from Thyra::BlockedLinearOpBase object
187  std::vector<Teuchos::RCP<const Map> > subRangeMaps(numRangeBlocks);
188  for (size_t r=0; r<Teuchos::as<size_t>(numRangeBlocks); ++r) {
189  for (size_t c=0; c<Teuchos::as<size_t>(numDomainBlocks); ++c) {
190  if (thyraOp->blockExists(r,c)) {
191  // we only need at least one block in each block row to extract the range map
192  Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > const_op = thyraOp->getBlock(r,c); // nonConst access is not allowed.
195  subRangeMaps[r] = xop->getRangeMap();
196  if(r!=c) is_diagonal_ = false;
197  break;
198  }
199  }
200  }
201  Teuchos::RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > fullRangeMap = mergeMaps(subRangeMaps);
202 
203  // check whether the underlying Thyra operator uses Thyra-style numbering (default for most applications) or
204  // Xpetra style numbering
205  bool bRangeUseThyraStyleNumbering = false;
206  size_t numAllElements = 0;
207  for(size_t v = 0; v < subRangeMaps.size(); ++v) {
208  numAllElements += subRangeMaps[v]->getGlobalNumElements();
209  }
210  if ( fullRangeMap->getGlobalNumElements() != numAllElements) bRangeUseThyraStyleNumbering = true;
211  rangemaps_ = Teuchos::rcp(new Xpetra::MapExtractor<Scalar,LocalOrdinal,GlobalOrdinal,Node>(fullRangeMap, subRangeMaps, bRangeUseThyraStyleNumbering));
212 
213  // build domain map extractor from Thyra::BlockedLinearOpBase object
214  std::vector<Teuchos::RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > > subDomainMaps(numDomainBlocks);
215  for (size_t c=0; c<Teuchos::as<size_t>(numDomainBlocks); ++c) {
216  for (size_t r=0; r<Teuchos::as<size_t>(numRangeBlocks); ++r) {
217  if (thyraOp->blockExists(r,c)) {
218  // we only need at least one block in each block row to extract the range map
219  Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > const_op = thyraOp->getBlock(r,c); // nonConst access is not allowed.
222  subDomainMaps[c] = xop->getDomainMap();
223  break;
224  }
225  }
226  }
227  Teuchos::RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > fullDomainMap = mergeMaps(subDomainMaps);
228  // plausibility check for numbering style (Xpetra or Thyra)
229  bool bDomainUseThyraStyleNumbering = false;
230  numAllElements = 0;
231  for(size_t v = 0; v < subDomainMaps.size(); ++v) {
232  numAllElements += subDomainMaps[v]->getGlobalNumElements();
233  }
234  if (fullDomainMap->getGlobalNumElements() != numAllElements) bDomainUseThyraStyleNumbering = true;
235  domainmaps_ = Teuchos::rcp(new Xpetra::MapExtractor<Scalar,LocalOrdinal,GlobalOrdinal,Node>(fullDomainMap, subDomainMaps, bDomainUseThyraStyleNumbering));
236 
237  // store numbering mode
238  bRangeThyraMode_ = bRangeUseThyraStyleNumbering;
239  bDomainThyraMode_ = bDomainUseThyraStyleNumbering;
240 
241  // add CrsMatrix objects in row,column order
242  blocks_.reserve(Rows()*Cols());
243  for (size_t r = 0; r < Rows(); ++r) {
244  for (size_t c = 0; c < Cols(); ++c) {
245  if(thyraOp->blockExists(r,c)) {
246  // TODO we do not support nested Thyra operators here!
247  Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > const_op = thyraOp->getBlock(r,c); // nonConst access is not allowed.
248  Teuchos::RCP<Thyra::LinearOpBase<Scalar> > op = Teuchos::rcp_const_cast<Thyra::LinearOpBase<Scalar> >(const_op); // cast away const
253  blocks_.push_back(xwrap);
254  } else {
255  // add empty block
257  }
258  }
259  }
260  // Default view
262  }
263 
264  private:
266 
273  Teuchos::RCP<const Map> mergeMaps(std::vector<Teuchos::RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > > & subMaps) {
274  // TODO merging for Thyra mode is missing (similar to what we do in constructor of MapExtractor
275 
276  // merge submaps to global map
277  std::vector<GlobalOrdinal> gids;
278  for(size_t tt = 0; tt<subMaps.size(); ++tt) {
280 #if 1
281  Teuchos::ArrayView< const GlobalOrdinal > subMapGids = subMap->getNodeElementList();
282  gids.insert(gids.end(), subMapGids.begin(), subMapGids.end());
283 #else
284  size_t myNumElements = subMap->getNodeNumElements();
285  for(LocalOrdinal l = 0; l < Teuchos::as<LocalOrdinal>(myNumElements); ++l) {
286  GlobalOrdinal gid = subMap->getGlobalElement(l);
287  gids.push_back(gid);
288  }
289 #endif
290  }
291 
292  // we have to sort the matrix entries and get rid of the double entries
293  // since we use this to detect Thyra-style numbering or Xpetra-style
294  // numbering. In Thyra-style numbering mode, the Xpetra::MapExtractor builds
295  // the correct row maps.
297  std::sort(gids.begin(), gids.end());
298  gids.erase(std::unique(gids.begin(), gids.end()), gids.end());
299  Teuchos::ArrayView<GO> gidsView(&gids[0], gids.size());
300  Teuchos::RCP<Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > fullMap = Xpetra::MapFactory<LocalOrdinal,GlobalOrdinal,Node>::Build(subMaps[0]->lib(), INVALID, gidsView, subMaps[0]->getIndexBase(), subMaps[0]->getComm());
301  return fullMap;
302  }
303 
304  public:
305 #endif
306 
308  virtual ~BlockedCrsMatrix() {}
309 
311 
312 
314 
315 
317 
342  void insertGlobalValues(GlobalOrdinal globalRow, const ArrayView<const GlobalOrdinal>& cols, const ArrayView<const Scalar>& vals) {
343  XPETRA_MONITOR("XpetraBlockedCrsMatrix::insertGlobalValues");
344  if (Rows() == 1 && Cols () == 1) {
345  getMatrix(0,0)->insertGlobalValues(globalRow, cols, vals);
346  return;
347  }
348  throw Xpetra::Exceptions::RuntimeError("insertGlobalValues not supported by BlockedCrsMatrix");
349  }
350 
352 
362  void insertLocalValues(LocalOrdinal localRow, const ArrayView<const LocalOrdinal>& cols, const ArrayView<const Scalar>& vals) {
363  XPETRA_MONITOR("XpetraBlockedCrsMatrix::insertLocalValues");
364  if (Rows() == 1 && Cols () == 1) {
365  getMatrix(0,0)->insertLocalValues(localRow, cols, vals);
366  return;
367  }
368  throw Xpetra::Exceptions::RuntimeError("insertLocalValues not supported by BlockedCrsMatrix");
369  }
370 
372  XPETRA_MONITOR("XpetraBlockedCrsMatrix::removeEmptyProcessesInPlace");
373  if (Rows() == 1 && Cols () == 1) {
374  getMatrix(0,0)->removeEmptyProcessesInPlace(newMap);
375  return;
376  }
377  throw Xpetra::Exceptions::RuntimeError("removeEmptyProcesses not supported by BlockedCrsMatrix");
378  }
379 
381 
389  void replaceGlobalValues(GlobalOrdinal globalRow,
390  const ArrayView<const GlobalOrdinal> &cols,
391  const ArrayView<const Scalar> &vals) {
392  XPETRA_MONITOR("XpetraBlockedCrsMatrix::replaceGlobalValues");
393  if (Rows() == 1 && Cols () == 1) {
394  getMatrix(0,0)->replaceGlobalValues(globalRow,cols,vals);
395  return;
396  }
397  throw Xpetra::Exceptions::RuntimeError("replaceGlobalValues not supported by BlockedCrsMatrix");
398  }
399 
401 
405  void replaceLocalValues(LocalOrdinal localRow,
406  const ArrayView<const LocalOrdinal> &cols,
407  const ArrayView<const Scalar> &vals) {
408  XPETRA_MONITOR("XpetraBlockedCrsMatrix::replaceLocalValues");
409  if (Rows() == 1 && Cols () == 1) {
410  getMatrix(0,0)->replaceLocalValues(localRow,cols,vals);
411  return;
412  }
413  throw Xpetra::Exceptions::RuntimeError("replaceLocalValues not supported by BlockedCrsMatrix");
414  }
415 
417  virtual void setAllToScalar(const Scalar& alpha) {
418  XPETRA_MONITOR("XpetraBlockedCrsMatrix::setAllToScalar");
419  for (size_t row = 0; row < Rows(); row++) {
420  for (size_t col = 0; col < Cols(); col++) {
421  if (!getMatrix(row,col).is_null()) {
422  getMatrix(row,col)->setAllToScalar(alpha);
423  }
424  }
425  }
426  }
427 
429  void scale(const Scalar& alpha) {
430  XPETRA_MONITOR("XpetraBlockedCrsMatrix::scale");
431  for (size_t row = 0; row < Rows(); row++) {
432  for (size_t col = 0; col < Cols(); col++) {
433  if (!getMatrix(row,col).is_null()) {
434  getMatrix(row,col)->scale(alpha);
435  }
436  }
437  }
438  }
439 
441 
443 
444 
452  void resumeFill(const RCP< ParameterList >& params = null) {
453  XPETRA_MONITOR("XpetraBlockedCrsMatrix::resumeFill");
454  for (size_t row = 0; row < Rows(); row++) {
455  for (size_t col = 0; col < Cols(); col++) {
456  if (!getMatrix(row,col).is_null()) {
457  getMatrix(row,col)->resumeFill(params);
458  }
459  }
460  }
461  }
462 
468  void fillComplete(const RCP<const Map>& domainMap, const RCP<const Map>& rangeMap, const RCP<ParameterList>& params = null) {
469  XPETRA_MONITOR("XpetraBlockedCrsMatrix::fillComplete");
470  if (Rows() == 1 && Cols () == 1) {
471  getMatrix(0,0)->fillComplete(domainMap, rangeMap, params);
472  return;
473  }
474  fillComplete(params);
475  }
476 
491  void fillComplete(const RCP<ParameterList>& params = null) {
492  XPETRA_MONITOR("XpetraBlockedCrsMatrix::fillComplete");
493  TEUCHOS_TEST_FOR_EXCEPTION(rangemaps_==Teuchos::null, Xpetra::Exceptions::RuntimeError,"BlockedCrsMatrix::fillComplete: rangemaps_ is not set. Error.");
494 
495  for (size_t r = 0; r < Rows(); ++r)
496  for (size_t c = 0; c < Cols(); ++c) {
497  if(getMatrix(r,c) != Teuchos::null) {
498  Teuchos::RCP<Matrix> Ablock = getMatrix(r,c);
499  if(r!=c) is_diagonal_ = false;
500  if (Ablock != Teuchos::null && !Ablock->isFillComplete())
501  Ablock->fillComplete(getDomainMap(c, bDomainThyraMode_), getRangeMap(r, bRangeThyraMode_), params);
502  }
503  }
504 
505 #if 0
506  // get full row map
507  RCP<const Map> rangeMap = rangemaps_->getFullMap();
508  fullrowmap_ = MapFactory::Build(rangeMap()->lib(), rangeMap()->getGlobalNumElements(), rangeMap()->getNodeElementList(), rangeMap()->getIndexBase(), rangeMap()->getComm());
509 
510  // build full col map
511  fullcolmap_ = Teuchos::null; // delete old full column map
512 
513  std::vector<GO> colmapentries;
514  for (size_t c = 0; c < Cols(); ++c) {
515  // copy all local column lids of all block rows to colset
516  std::set<GO> colset;
517  for (size_t r = 0; r < Rows(); ++r) {
518  Teuchos::RCP<CrsMatrix> Ablock = getMatrix(r,c);
519 
520  if (Ablock != Teuchos::null) {
521  Teuchos::ArrayView<const GO> colElements = Ablock->getColMap()->getNodeElementList();
522  Teuchos::RCP<const Map> colmap = Ablock->getColMap();
523  copy(colElements.getRawPtr(), colElements.getRawPtr() + colElements.size(), inserter(colset, colset.begin()));
524  }
525  }
526 
527  // remove duplicates (entries which are in column maps of more than one block row)
528  colmapentries.reserve(colmapentries.size() + colset.size());
529  copy(colset.begin(), colset.end(), back_inserter(colmapentries));
530  sort(colmapentries.begin(), colmapentries.end());
531  typename std::vector<GO>::iterator gendLocation;
532  gendLocation = std::unique(colmapentries.begin(), colmapentries.end());
533  colmapentries.erase(gendLocation,colmapentries.end());
534  }
535 
536  // sum up number of local elements
537  size_t numGlobalElements = 0;
538  Teuchos::reduceAll(*(rangeMap->getComm()), Teuchos::REDUCE_SUM, colmapentries.size(), Teuchos::outArg(numGlobalElements));
539 
540  // store global full column map
541  const Teuchos::ArrayView<const GO> aView = Teuchos::ArrayView<const GO>(colmapentries);
542  fullcolmap_ = MapFactory::Build(rangeMap->lib(), numGlobalElements, aView, 0, rangeMap->getComm());
543 #endif
544  }
545 
547 
549 
552  XPETRA_MONITOR("XpetraBlockedCrsMatrix::getGlobalNumRows");
553  global_size_t globalNumRows = 0;
554 
555  for (size_t row = 0; row < Rows(); row++)
556  for (size_t col = 0; col < Cols(); col++)
557  if (!getMatrix(row,col).is_null()) {
558  globalNumRows += getMatrix(row,col)->getGlobalNumRows();
559  break; // we need only one non-null matrix in a row
560  }
561 
562  return globalNumRows;
563  }
564 
566 
569  XPETRA_MONITOR("XpetraBlockedCrsMatrix::getGlobalNumCols");
570  global_size_t globalNumCols = 0;
571 
572  for (size_t col = 0; col < Cols(); col++)
573  for (size_t row = 0; row < Rows(); row++)
574  if (!getMatrix(row,col).is_null()) {
575  globalNumCols += getMatrix(row,col)->getGlobalNumCols();
576  break; // we need only one non-null matrix in a col
577  }
578 
579  return globalNumCols;
580  }
581 
583  size_t getNodeNumRows() const {
584  XPETRA_MONITOR("XpetraBlockedCrsMatrix::getNodeNumRows");
585  global_size_t nodeNumRows = 0;
586 
587  for (size_t row = 0; row < Rows(); ++row)
588  for (size_t col = 0; col < Cols(); col++)
589  if (!getMatrix(row,col).is_null()) {
590  nodeNumRows += getMatrix(row,col)->getNodeNumRows();
591  break; // we need only one non-null matrix in a row
592  }
593 
594  return nodeNumRows;
595  }
596 
599  XPETRA_MONITOR("XpetraBlockedCrsMatrix::getGlobalNumEntries");
600  global_size_t globalNumEntries = 0;
601 
602  for (size_t row = 0; row < Rows(); ++row)
603  for (size_t col = 0; col < Cols(); ++col)
604  if (!getMatrix(row,col).is_null())
605  globalNumEntries += getMatrix(row,col)->getGlobalNumEntries();
606 
607  return globalNumEntries;
608  }
609 
611  size_t getNodeNumEntries() const {
612  XPETRA_MONITOR("XpetraBlockedCrsMatrix::getNodeNumEntries");
613  global_size_t nodeNumEntries = 0;
614 
615  for (size_t row = 0; row < Rows(); ++row)
616  for (size_t col = 0; col < Cols(); ++col)
617  if (!getMatrix(row,col).is_null())
618  nodeNumEntries += getMatrix(row,col)->getNodeNumEntries();
619 
620  return nodeNumEntries;
621  }
622 
624 
625  size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const {
626  XPETRA_MONITOR("XpetraBlockedCrsMatrix::getNumEntriesInLocalRow");
627  if (Rows() == 1 && Cols () == 1) {
628  return getMatrix(0,0)->getNumEntriesInLocalRow(localRow);
629  }
630  else if(is_diagonal_){
631  GlobalOrdinal gid = this->getRowMap()->getGlobalElement(localRow);
632  size_t row = getBlockedRangeMap()->getMapIndexForGID(gid);
633  return getMatrix(row,row)->getNumEntriesInLocalRow(getMatrix(row,row)->getRowMap()->getLocalElement(gid));
634  }
635  throw Xpetra::Exceptions::RuntimeError("getNumEntriesInLocalRow() not supported by BlockedCrsMatrix");
636  }
637 
639 
640  size_t getNumEntriesInGlobalRow(GlobalOrdinal globalRow) const {
641  XPETRA_MONITOR("XpetraBlockedCrsMatrix::getNumEntriesInGlobalRow");
642  if (Rows() == 1 && Cols () == 1) {
643  return getMatrix(0,0)->getNumEntriesInGlobalRow(globalRow);
644  }
645  throw Xpetra::Exceptions::RuntimeError("getNumEntriesInGlobalRow not supported by this BlockedCrsMatrix");
646  }
647 
649 
651  size_t getGlobalMaxNumRowEntries() const {
652  XPETRA_MONITOR("XpetraBlockedCrsMatrix::getGlobalMaxNumRowEntries");
653  global_size_t globalMaxEntries = 0;
654 
655  for (size_t row = 0; row < Rows(); row++) {
656  global_size_t globalMaxEntriesBlockRows = 0;
657  for (size_t col = 0; col < Cols(); col++) {
658  if (!getMatrix(row,col).is_null()) {
659  globalMaxEntriesBlockRows += getMatrix(row,col)->getGlobalMaxNumRowEntries();
660  }
661  }
662  if(globalMaxEntriesBlockRows > globalMaxEntries)
663  globalMaxEntries = globalMaxEntriesBlockRows;
664  }
665  return globalMaxEntries;
666  }
667 
669 
671  size_t getNodeMaxNumRowEntries() const {
672  XPETRA_MONITOR("XpetraBlockedCrsMatrix::getNodeMaxNumRowEntries");
673  size_t localMaxEntries = 0;
674 
675  for (size_t row = 0; row < Rows(); row++) {
676  size_t localMaxEntriesBlockRows = 0;
677  for (size_t col = 0; col < Cols(); col++) {
678  if (!getMatrix(row,col).is_null()) {
679  localMaxEntriesBlockRows += getMatrix(row,col)->getNodeMaxNumRowEntries();
680  }
681  }
682  if(localMaxEntriesBlockRows > localMaxEntries)
683  localMaxEntries = localMaxEntriesBlockRows;
684  }
685  return localMaxEntries;
686  }
687 
689 
692  bool isLocallyIndexed() const {
693  XPETRA_MONITOR("XpetraBlockedCrsMatrix::isLocallyIndexed");
694  for (size_t i = 0; i < blocks_.size(); ++i)
695  if (blocks_[i] != Teuchos::null && !blocks_[i]->isLocallyIndexed())
696  return false;
697  return true;
698  }
699 
701 
704  bool isGloballyIndexed() const {
705  XPETRA_MONITOR("XpetraBlockedCrsMatrix::isGloballyIndexed");
706  for (size_t i = 0; i < blocks_.size(); i++)
707  if (blocks_[i] != Teuchos::null && !blocks_[i]->isGloballyIndexed())
708  return false;
709  return true;
710  }
711 
713  bool isFillComplete() const {
714  XPETRA_MONITOR("XpetraBlockedCrsMatrix::isFillComplete");
715  for (size_t i = 0; i < blocks_.size(); i++)
716  if (blocks_[i] != Teuchos::null && !blocks_[i]->isFillComplete())
717  return false;
718  return true;
719  }
720 
722 
736  virtual void getLocalRowCopy(LocalOrdinal LocalRow,
737  const ArrayView<LocalOrdinal>& Indices,
738  const ArrayView<Scalar>& Values,
739  size_t &NumEntries) const {
740  XPETRA_MONITOR("XpetraBlockedCrsMatrix::getLocalRowCopy");
741  if (Rows() == 1 && Cols () == 1) {
742  getMatrix(0,0)->getLocalRowCopy(LocalRow, Indices, Values, NumEntries);
743  return;
744  }
745  throw Xpetra::Exceptions::RuntimeError("getLocalRowCopy not supported by BlockedCrsMatrix" );
746  }
747 
749 
758  void getGlobalRowView(GlobalOrdinal GlobalRow, ArrayView<const GlobalOrdinal>& indices, ArrayView<const Scalar>& values) const {
759  XPETRA_MONITOR("XpetraBlockedCrsMatrix::getGlobalRowView");
760  if (Rows() == 1 && Cols () == 1) {
761  getMatrix(0,0)->getGlobalRowView(GlobalRow, indices, values);
762  return;
763  }
764  throw Xpetra::Exceptions::RuntimeError("getGlobalRowView not supported by BlockedCrsMatrix");
765  }
766 
768 
777  void getLocalRowView(LocalOrdinal LocalRow, ArrayView<const LocalOrdinal>& indices, ArrayView<const Scalar>& values) const {
778  XPETRA_MONITOR("XpetraBlockedCrsMatrix::getLocalRowView");
779  if (Rows() == 1 && Cols () == 1) {
780  getMatrix(0,0)->getLocalRowView(LocalRow, indices, values);
781  return;
782  }
783  else if(is_diagonal_) {
784  //CMS
785  GlobalOrdinal gid = this->getRowMap()->getGlobalElement(LocalRow);
786  size_t row = getBlockedRangeMap()->getMapIndexForGID(gid);
787  getMatrix(row,row)->getLocalRowView(getMatrix(row,row)->getRowMap()->getLocalElement(gid),indices,values);
788  return;
789  }
790  throw Xpetra::Exceptions::RuntimeError("getLocalRowView not supported by BlockedCrsMatrix");
791  }
792 
794 
797  void getLocalDiagCopy(Vector& diag) const {
798  XPETRA_MONITOR("XpetraBlockedCrsMatrix::getLocalDiagCopy");
799 
800  //RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
801 
802  Teuchos::RCP<Vector> rcpdiag = Teuchos::rcpFromRef(diag);
803  Teuchos::RCP<BlockedVector> bdiag = Teuchos::rcp_dynamic_cast<BlockedVector>(rcpdiag);
804 
805  // special treatment for 1x1 block matrices
806  // ReorderedBlockedCrsMatrix object encapsulate single blocks in ReorderedBlocks
807  // BlockedVectors have Vector objects as Leaf objects.
808  if(Rows() == 1 && Cols() == 1 && bdiag.is_null() == true) {
810  rm->getLocalDiagCopy(diag);
811  return;
812  }
813 
814  TEUCHOS_TEST_FOR_EXCEPTION(bdiag.is_null() == true, Xpetra::Exceptions::RuntimeError, "BlockedCrsMatrix::getLocalDiagCopy: diag must be a Blocked(Multi)Vector.");
815  TEUCHOS_TEST_FOR_EXCEPTION(bdiag->getNumVectors() != 1, Xpetra::Exceptions::RuntimeError, "BlockedCrsMatrix::getLocalDiagCopy: diag must be a Blocked(Multi)Vector with exactly one vector. However, the number of stored vectors is " << bdiag->getNumVectors());
816  TEUCHOS_TEST_FOR_EXCEPTION(bdiag->getBlockedMap()->getNumMaps() != this->Rows(), Xpetra::Exceptions::RuntimeError,
817  "BlockedCrsMatrix::getLocalDiagCopy(): the number of blocks in diag differ from the number of blocks in this operator." );
818  //XPETRA_TEST_FOR_EXCEPTION(bdiag->getMap()->isSameAs(*(getMap())) == false, Xpetra::Exceptions::RuntimeError,
819  // "BlockedCrsMatrix::getLocalDiagCopy(): the map of the vector diag is not compatible with the map of the blocked operator." );
820 
821  for (size_t row = 0; row < Rows(); row++) {
823  if (!rm.is_null()) {
824  Teuchos::RCP<Vector> rv = VectorFactory::Build(bdiag->getBlockedMap()->getMap(row,bdiag->getBlockedMap()->getThyraMode()));
825  rm->getLocalDiagCopy(*rv);
826  bdiag->setMultiVector(row,rv,bdiag->getBlockedMap()->getThyraMode());
827  }
828  }
829  }
830 
832  void leftScale (const Vector& x) {
833  XPETRA_MONITOR("XpetraBlockedCrsMatrix::leftScale");
834 
835  Teuchos::RCP<const Vector> rcpx = Teuchos::rcpFromRef(x);
836  Teuchos::RCP<const BlockedVector> bx = Teuchos::rcp_dynamic_cast<const BlockedVector>(rcpx);
837 
838  //RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
839 
840  // special treatment for 1xn block matrices
841  // ReorderedBlockedCrsMatrix object encapsulate single blocks in ReorderedBlocks
842  // BlockedVectors have Vector objects as Leaf objects.
843  if(Rows() == 1 && bx.is_null() == true) {
844  for (size_t col = 0; col < Cols(); ++col) {
845  Teuchos::RCP<Matrix> rm = getMatrix(0,col);
846  rm->leftScale(x);
847  }
848  return;
849  }
850 
851  TEUCHOS_TEST_FOR_EXCEPTION(bx.is_null() == true, Xpetra::Exceptions::RuntimeError, "BlockedCrsMatrix::leftScale: x must be a Blocked(Multi)Vector.");
852  TEUCHOS_TEST_FOR_EXCEPTION(bx->getNumVectors() != 1, Xpetra::Exceptions::RuntimeError, "BlockedCrsMatrix::leftScale: x must be a Blocked(Multi)Vector with exactly one vector. However, the number of stored vectors is " << bx->getNumVectors());
853  TEUCHOS_TEST_FOR_EXCEPTION(bx->getBlockedMap()->getNumMaps() != this->Rows(), Xpetra::Exceptions::RuntimeError,
854  "BlockedCrsMatrix::leftScale(): the number of blocks in diag differ from the number of blocks in this operator." );
855 
856  for (size_t row = 0; row < Rows(); row++) {
857  Teuchos::RCP<const MultiVector> rmv = bx->getMultiVector(row);
858  Teuchos::RCP<const Vector> rscale = rmv->getVector(0);
859  XPETRA_TEST_FOR_EXCEPTION(rscale.is_null()==true, Xpetra::Exceptions::RuntimeError, "BlockedCrsMatrix::leftScale: x must be a Vector.");
860  for (size_t col = 0; col < Cols(); ++col) {
861  Teuchos::RCP<Matrix> rm = getMatrix(row,col);
862  if (!rm.is_null()) {
863  rm->leftScale(*rscale);
864  }
865  }
866  }
867  }
868 
870  void rightScale (const Vector& x) {
871  XPETRA_MONITOR("XpetraBlockedCrsMatrix::rightScale");
872 
873  Teuchos::RCP<const Vector> rcpx = Teuchos::rcpFromRef(x);
874  Teuchos::RCP<const BlockedVector> bx = Teuchos::rcp_dynamic_cast<const BlockedVector>(rcpx);
875 
876  //RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
877 
878  // special treatment for nx1 block matrices
879  // ReorderedBlockedCrsMatrix object encapsulate single blocks in ReorderedBlocks
880  // BlockedVectors have Vector objects as Leaf objects.
881  if(Cols() == 1 && bx.is_null() == true) {
882  for (size_t row = 0; row < Rows(); ++row) {
883  Teuchos::RCP<Matrix> rm = getMatrix(row,0);
884  rm->rightScale(x);
885  }
886  return;
887  }
888 
889  TEUCHOS_TEST_FOR_EXCEPTION(bx.is_null() == true, Xpetra::Exceptions::RuntimeError, "BlockedCrsMatrix::rightScale: x must be a Blocked(Multi)Vector.");
890  TEUCHOS_TEST_FOR_EXCEPTION(bx->getNumVectors() != 1, Xpetra::Exceptions::RuntimeError, "BlockedCrsMatrix::rightScale: x must be a Blocked(Multi)Vector with exactly one vector. However, the number of stored vectors is " << bx->getNumVectors());
891  TEUCHOS_TEST_FOR_EXCEPTION(bx->getBlockedMap()->getNumMaps() != this->Cols(), Xpetra::Exceptions::RuntimeError,
892  "BlockedCrsMatrix::rightScale(): the number of blocks in diag differ from the number of blocks in this operator." );
893 
894  for (size_t col = 0; col < Cols(); ++col) {
895  Teuchos::RCP<const MultiVector> rmv = bx->getMultiVector(col);
896  Teuchos::RCP<const Vector> rscale = rmv->getVector(0);
897  XPETRA_TEST_FOR_EXCEPTION(rscale.is_null()==true, Xpetra::Exceptions::RuntimeError, "BlockedCrsMatrix::leftScale: x must be a Vector.");
898  for (size_t row = 0; row < Rows(); row++) {
899  Teuchos::RCP<Matrix> rm = getMatrix(row,col);
900  if (!rm.is_null()) {
901  rm->rightScale(*rscale);
902  }
903  }
904  }
905  }
906 
907 
910  XPETRA_MONITOR("XpetraBlockedCrsMatrix::getFrobeniusNorm");
912  for (size_t col = 0; col < Cols(); ++col) {
913  for (size_t row = 0; row < Rows(); ++row) {
914  if(getMatrix(row,col)!=Teuchos::null) {
915  typename ScalarTraits<Scalar>::magnitudeType n = getMatrix(row,col)->getFrobeniusNorm();
916  ret += n * n;
917  }
918  }
919  }
921  }
922 
923 
925  virtual bool haveGlobalConstants() const {return true;}
926 
927 
929 
931 
932 
934 
954 
956 
957 
959 
962  virtual void apply(const MultiVector& X, MultiVector& Y,
964  Scalar alpha = ScalarTraits<Scalar>::one(),
965  Scalar beta = ScalarTraits<Scalar>::zero()) const
966  {
967  XPETRA_MONITOR("XpetraBlockedCrsMatrix::apply");
968  //using Teuchos::RCP;
969 
971  "apply() only supports the following modes: NO_TRANS and TRANS." );
972 
973  // check whether input parameters are blocked or not
974  RCP<const MultiVector> refX = rcpFromRef(X);
975  RCP<const BlockedMultiVector> refbX = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(refX);
976  //RCP<MultiVector> tmpY = rcpFromRef(Y);
977  //RCP<BlockedMultiVector> tmpbY = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(tmpY);
978 
979  // TODO get rid of me: adapt MapExtractor
980  bool bBlockedX = (refbX != Teuchos::null) ? true : false;
981 
982  // create (temporary) vectors for output
983  // In the end we call Y.update(alpha, *tmpY, beta). Therefore we need a new vector storing the temporary results
985 
986  //RCP<Teuchos::FancyOStream> out = rcp(new Teuchos::FancyOStream(rcp(&std::cout,false)));
987 
988  SC one = ScalarTraits<SC>::one();
989 
990  if (mode == Teuchos::NO_TRANS) {
991 
992  for (size_t row = 0; row < Rows(); row++) {
993  RCP<MultiVector> Yblock = rangemaps_->getVector(row, Y.getNumVectors(), bRangeThyraMode_, true);
994  for (size_t col = 0; col < Cols(); col++) {
995 
996  // extract matrix block
997  RCP<Matrix> Ablock = getMatrix(row, col);
998 
999  if (Ablock.is_null())
1000  continue;
1001 
1002  // check whether Ablock is itself a blocked operator
1003  // If it is a blocked operator we have to provide Xpetra style GIDs, i.e. we have to transform GIDs
1004  bool bBlockedSubMatrix = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(Ablock) == Teuchos::null ? false : true;
1005 
1006  // input/output vectors for local block operation
1007  RCP<const MultiVector> Xblock = Teuchos::null; // subpart of X vector to be applied to subblock of A
1008 
1009  // extract sub part of X using Xpetra or Thyra GIDs
1010  // if submatrix is again blocked, we extract it using Xpetra style gids. If it is a single
1011  // block matrix we use the Thyra or Xpetra style GIDs that are used to store the matrix
1012  if(bBlockedX) Xblock = domainmaps_->ExtractVector(refbX, col, bDomainThyraMode_);
1013  else Xblock = domainmaps_->ExtractVector(refX, col, bBlockedSubMatrix == true ? false : bDomainThyraMode_);
1014 
1015  RCP<MultiVector> tmpYblock = rangemaps_->getVector(row, Y.getNumVectors(), bRangeThyraMode_, false); // subpart of Y vector containing part of solution of Xblock applied to Ablock
1016  Ablock->apply(*Xblock, *tmpYblock);
1017 
1018  Yblock->update(one, *tmpYblock, one);
1019  }
1020  rangemaps_->InsertVector(Yblock, row, tmpY, bRangeThyraMode_);
1021  }
1022 
1023  } else if (mode == Teuchos::TRANS) {
1024  // TODO: test me!
1025  for (size_t col = 0; col < Cols(); col++) {
1026  RCP<MultiVector> Yblock = domainmaps_->getVector(col, Y.getNumVectors(), bDomainThyraMode_, true);
1027 
1028  for (size_t row = 0; row<Rows(); row++) {
1029  RCP<Matrix> Ablock = getMatrix(row, col);
1030 
1031  if (Ablock.is_null())
1032  continue;
1033 
1034  // check whether Ablock is itself a blocked operator
1035  // If it is a blocked operator we have to provide Xpetra style GIDs, i.e. we have to transform GIDs
1036  bool bBlockedSubMatrix = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(Ablock) == Teuchos::null ? false : true;
1037 
1038  RCP<const MultiVector> Xblock = Teuchos::null;
1039 
1040  // extract sub part of X using Xpetra or Thyra GIDs
1041  if(bBlockedX) Xblock = rangemaps_->ExtractVector(refbX, row, bRangeThyraMode_);
1042  else Xblock = rangemaps_->ExtractVector(refX, row, bBlockedSubMatrix == true ? false : bRangeThyraMode_);
1043  RCP<MultiVector> tmpYblock = domainmaps_->getVector(col, Y.getNumVectors(), bDomainThyraMode_, false);
1044  Ablock->apply(*Xblock, *tmpYblock, Teuchos::TRANS);
1045 
1046  Yblock->update(one, *tmpYblock, one);
1047  }
1048  domainmaps_->InsertVector(Yblock, col, tmpY, bDomainThyraMode_);
1049  }
1050  }
1051  Y.update(alpha, *tmpY, beta);
1052  }
1053 
1055  RCP<const Map > getFullDomainMap() const { XPETRA_MONITOR("XpetraBlockedCrsMatrix::getFullDomainMap()"); return domainmaps_->getFullMap(); }
1056 
1058  RCP<const BlockedMap > getBlockedDomainMap() const { XPETRA_MONITOR("XpetraBlockedCrsMatrix::getBlockedDomainMap()"); return domainmaps_->getBlockedMap(); }
1059 
1061  RCP<const Map > getDomainMap() const { XPETRA_MONITOR("XpetraBlockedCrsMatrix::getDomainMap()"); return domainmaps_->getMap(); /*domainmaps_->getFullMap();*/ }
1062 
1064  RCP<const Map > getDomainMap(size_t i) const { XPETRA_MONITOR("XpetraBlockedCrsMatrix::getDomainMap(size_t)"); return domainmaps_->getMap(i, bDomainThyraMode_); }
1065 
1067  RCP<const Map > getDomainMap(size_t i, bool bThyraMode) const { XPETRA_MONITOR("XpetraBlockedCrsMatrix::getDomainMap(size_t,bool)"); return domainmaps_->getMap(i, bThyraMode); }
1068 
1070  RCP<const Map > getFullRangeMap() const { XPETRA_MONITOR("XpetraBlockedCrsMatrix::getRangeMap()"); return rangemaps_->getFullMap(); }
1071 
1073  RCP<const BlockedMap > getBlockedRangeMap() const { XPETRA_MONITOR("XpetraBlockedCrsMatrix::getBlockedRangeMap()"); return rangemaps_->getBlockedMap(); }
1074 
1076  RCP<const Map > getRangeMap() const { XPETRA_MONITOR("XpetraBlockedCrsMatrix::getRangeMap()"); return rangemaps_->getMap(); /*rangemaps_->getFullMap();*/ }
1077 
1079  RCP<const Map > getRangeMap(size_t i) const { XPETRA_MONITOR("XpetraBlockedCrsMatrix::getRangeMap(size_t)"); return rangemaps_->getMap(i, bRangeThyraMode_); }
1080 
1082  RCP<const Map > getRangeMap(size_t i, bool bThyraMode) const { XPETRA_MONITOR("XpetraBlockedCrsMatrix::getRangeMap(size_t,bool)"); return rangemaps_->getMap(i, bThyraMode); }
1083 
1085  RCP<const MapExtractor> getRangeMapExtractor() const { XPETRA_MONITOR("XpetraBlockedCrsMatrix::getRangeMapExtractor()"); return rangemaps_; }
1086 
1088  RCP<const MapExtractor> getDomainMapExtractor() const { XPETRA_MONITOR("XpetraBlockedCrsMatrix::getDomainMapExtractor()"); return domainmaps_; }
1089 
1091 
1093  //{@
1094 
1103  virtual void bgs_apply(
1104  const MultiVector& X,
1105  MultiVector& Y,
1106  size_t row,
1108  Scalar alpha = ScalarTraits<Scalar>::one(),
1109  Scalar beta = ScalarTraits<Scalar>::zero()
1110  ) const
1111  {
1112  XPETRA_MONITOR("XpetraBlockedCrsMatrix::bgs_apply");
1113  //using Teuchos::RCP;
1114 
1116  "apply() only supports the following modes: NO_TRANS and TRANS." );
1117 
1118  // check whether input parameters are blocked or not
1119  RCP<const MultiVector> refX = rcpFromRef(X);
1120  RCP<const BlockedMultiVector> refbX = Teuchos::rcp_dynamic_cast<const BlockedMultiVector>(refX);
1121  //RCP<MultiVector> tmpY = rcpFromRef(Y);
1122  //RCP<BlockedMultiVector> tmpbY = Teuchos::rcp_dynamic_cast<BlockedMultiVector>(tmpY);
1123 
1124  bool bBlockedX = (refbX != Teuchos::null) ? true : false;
1125 
1126  // create (temporary) vectors for output
1127  // In the end we call Y.update(alpha, *tmpY, beta). Therefore we need a new vector storing the temporary results
1129 
1130  SC one = ScalarTraits<SC>::one();
1131 
1132  if (mode == Teuchos::NO_TRANS) {
1133  RCP<MultiVector> Yblock = rangemaps_->getVector(row, Y.getNumVectors(), bRangeThyraMode_, true);
1134  for (size_t col = 0; col < Cols(); col++) {
1135 
1136  // extract matrix block
1137  RCP<Matrix> Ablock = getMatrix(row, col);
1138 
1139  if (Ablock.is_null())
1140  continue;
1141 
1142  // check whether Ablock is itself a blocked operator
1143  // If it is a blocked operator we have to provide Xpetra style GIDs, i.e. we have to transform GIDs
1144  bool bBlockedSubMatrix = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(Ablock) == Teuchos::null ? false : true;
1145 
1146  // input/output vectors for local block operation
1147  RCP<const MultiVector> Xblock = Teuchos::null; // subpart of X vector to be applied to subblock of A
1148 
1149  // extract sub part of X using Xpetra or Thyra GIDs
1150  // if submatrix is again blocked, we extract it using Xpetra style gids. If it is a single
1151  // block matrix we use the Thyra or Xpetra style GIDs that are used to store the matrix
1152  if(bBlockedX) Xblock = domainmaps_->ExtractVector(refbX, col, bDomainThyraMode_);
1153  else Xblock = domainmaps_->ExtractVector(refX, col, bBlockedSubMatrix == true ? false : bDomainThyraMode_);
1154 
1155  RCP<MultiVector> tmpYblock = rangemaps_->getVector(row, Y.getNumVectors(), bRangeThyraMode_, false); // subpart of Y vector containing part of solution of Xblock applied to Ablock
1156  Ablock->apply(*Xblock, *tmpYblock);
1157 
1158  Yblock->update(one, *tmpYblock, one);
1159  }
1160  rangemaps_->InsertVector(Yblock, row, tmpY, bRangeThyraMode_);
1161  } else {
1162  TEUCHOS_TEST_FOR_EXCEPTION(true,Xpetra::Exceptions::NotImplemented,"Xpetar::BlockedCrsMatrix::bgs_apply: not implemented for transpose case.");
1163  }
1164  Y.update(alpha, *tmpY, beta);
1165  }
1166 
1167 
1169 
1170 
1172  //{@
1173 
1176  XPETRA_MONITOR("XpetraBlockedCrsMatrix::getMap");
1177  if (Rows() == 1 && Cols () == 1) {
1178  return getMatrix(0,0)->getMap();
1179  }
1180  throw Xpetra::Exceptions::RuntimeError("BlockedCrsMatrix::getMap(): operation not supported.");
1181  }
1182 
1184  void doImport(const Matrix &source, const Import& importer, CombineMode CM) {
1185  XPETRA_MONITOR("XpetraBlockedCrsMatrix::doImport");
1186  if (Rows() == 1 && Cols () == 1) {
1187  getMatrix(0,0)->doImport(source, importer, CM);
1188  return;
1189  }
1190  throw Xpetra::Exceptions::RuntimeError("BlockedCrsMatrix::doImport(): operation not supported.");
1191  }
1192 
1194  void doExport(const Matrix& dest, const Import& importer, CombineMode CM) {
1195  XPETRA_MONITOR("XpetraBlockedCrsMatrix::doExport");
1196  if (Rows() == 1 && Cols () == 1) {
1197  getMatrix(0,0)->doExport(dest, importer, CM);
1198  return;
1199  }
1200  throw Xpetra::Exceptions::RuntimeError("BlockedCrsMatrix::doExport(): operation not supported.");
1201  }
1202 
1204  void doImport(const Matrix& source, const Export& exporter, CombineMode CM) {
1205  XPETRA_MONITOR("XpetraBlockedCrsMatrix::doImport");
1206  if (Rows() == 1 && Cols () == 1) {
1207  getMatrix(0,0)->doImport(source, exporter, CM);
1208  return;
1209  }
1210  throw Xpetra::Exceptions::RuntimeError("BlockedCrsMatrix::doImport(): operation not supported.");
1211  }
1212 
1214  void doExport(const Matrix& dest, const Export& exporter, CombineMode CM) {
1215  XPETRA_MONITOR("XpetraBlockedCrsMatrix::doExport");
1216  if (Rows() == 1 && Cols () == 1) {
1217  getMatrix(0,0)->doExport(dest, exporter, CM);
1218  return;
1219  }
1220  throw Xpetra::Exceptions::RuntimeError("BlockedCrsMatrix::doExport(): operation not supported.");
1221  }
1222 
1223  // @}
1224 
1226 
1227 
1229  std::string description() const { return "Xpetra_BlockedCrsMatrix.description()"; }
1230 
1233  out << "Xpetra::BlockedCrsMatrix: " << Rows() << " x " << Cols() << std::endl;
1234 
1235  if (isFillComplete()) {
1236  out << "BlockMatrix is fillComplete" << std::endl;
1237 
1238  /*if(fullrowmap_ != Teuchos::null) {
1239  out << "fullRowMap" << std::endl;
1240  fullrowmap_->describe(out,verbLevel);
1241  } else {
1242  out << "fullRowMap not set. Check whether block matrix is properly fillCompleted!" << std::endl;
1243  }*/
1244 
1245  //out << "fullColMap" << std::endl;
1246  //fullcolmap_->describe(out,verbLevel);
1247 
1248  } else {
1249  out << "BlockMatrix is NOT fillComplete" << std::endl;
1250  }
1251 
1252  for (size_t r = 0; r < Rows(); ++r)
1253  for (size_t c = 0; c < Cols(); ++c) {
1254  if(getMatrix(r,c)!=Teuchos::null) {
1255  out << "Block(" << r << "," << c << ")" << std::endl;
1256  getMatrix(r,c)->describe(out,verbLevel);
1257  } else out << "Block(" << r << "," << c << ") = null" << std::endl;
1258  }
1259  }
1260 
1262 
1263  void setObjectLabel( const std::string &objectLabel ) {
1264  XPETRA_MONITOR("TpetraBlockedCrsMatrix::setObjectLabel");
1265  for (size_t r = 0; r < Rows(); ++r)
1266  for (size_t c = 0; c < Cols(); ++c) {
1267  if(getMatrix(r,c)!=Teuchos::null) {
1268  std::ostringstream oss; oss<< objectLabel << "(" << r << "," << c << ")";
1269  getMatrix(r,c)->setObjectLabel(oss.str());
1270  }
1271  }
1272  }
1274 
1275 
1277  bool hasCrsGraph() const {
1278  if (Rows() == 1 && Cols () == 1) return true;
1279  else return false;
1280  }
1281 
1284  XPETRA_MONITOR("XpetraBlockedCrsMatrix::getCrsGraph");
1285  if (Rows() == 1 && Cols () == 1) {
1286  return getMatrix(0,0)->getCrsGraph();
1287  }
1288  throw Xpetra::Exceptions::RuntimeError("getCrsGraph() not supported by BlockedCrsMatrix");
1289  }
1290 
1292 
1294 
1295 
1296  virtual bool isDiagonal() const {return is_diagonal_;}
1297 
1299  virtual size_t Rows() const { XPETRA_MONITOR("XpetraBlockedCrsMatrix::Rows"); return rangemaps_->NumMaps(); }
1300 
1302  virtual size_t Cols() const { XPETRA_MONITOR("XpetraBlockedCrsMatrix::Cols"); return domainmaps_->NumMaps(); }
1303 
1306  XPETRA_MONITOR("XpetraBlockedCrsMatrix::getCrsMatrix");
1307  TEUCHOS_TEST_FOR_EXCEPTION(Rows()!=1, std::out_of_range, "Can only unwrap a 1x1 blocked matrix. The matrix has " << Rows() << " block rows, though.");
1308  TEUCHOS_TEST_FOR_EXCEPTION(Cols()!=1, std::out_of_range, "Can only unwrap a 1x1 blocked matrix. The matrix has " << Cols() << " block columns, though.");
1309 
1310  RCP<Matrix> mat = getMatrix(0,0);
1311  RCP<BlockedCrsMatrix> bmat = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(mat);
1312  if (bmat == Teuchos::null) return mat;
1313  return bmat->getCrsMatrix();
1314  }
1315 
1318  XPETRA_MONITOR("XpetraBlockedCrsMatrix::getInnermostCrsMatrix");
1319  size_t row = Rows()+1, col = Cols()+1;
1320  for (size_t r = 0; r < Rows(); ++r)
1321  for(size_t c = 0; c < Cols(); ++c)
1322  if (getMatrix(r,c) != Teuchos::null) {
1323  row = r;
1324  col = c;
1325  break;
1326  }
1327  TEUCHOS_TEST_FOR_EXCEPTION(row == Rows()+1 || col == Cols()+1, Xpetra::Exceptions::Incompatible, "Xpetra::BlockedCrsMatrix::getInnermostCrsMatrix: Could not find a non-zero sub-block in blocked operator.")
1328  RCP<Matrix> mm = getMatrix(row,col);
1329  RCP<BlockedCrsMatrix> bmat = Teuchos::rcp_dynamic_cast<BlockedCrsMatrix>(mm);
1330  if (bmat == Teuchos::null) return mm;
1331  return bmat->getInnermostCrsMatrix();
1332  }
1333 
1335  Teuchos::RCP<Matrix> getMatrix(size_t r, size_t c) const {
1336  XPETRA_MONITOR("XpetraBlockedCrsMatrix::getMatrix");
1337  TEUCHOS_TEST_FOR_EXCEPTION(r > Rows(), std::out_of_range, "Error, r = " << Rows() << " is too big");
1338  TEUCHOS_TEST_FOR_EXCEPTION(c > Cols(), std::out_of_range, "Error, c = " << Cols() << " is too big");
1339 
1340  // transfer strided/blocked map information
1341  /* if (blocks_[r*Cols()+c] != Teuchos::null &&
1342  blocks_[r*Cols()+c]->IsView("stridedMaps") == false)
1343  blocks_[r*Cols()+c]->CreateView("stridedMaps", getRangeMap(r,bRangeThyraMode_), getDomainMap(c,bDomainThyraMode_));*/
1344  return blocks_[r*Cols()+c];
1345  }
1346 
1348  //void setMatrix(size_t r, size_t c, Teuchos::RCP<CrsMatrix> mat) {
1349  void setMatrix(size_t r, size_t c, Teuchos::RCP<Matrix> mat) {
1350  XPETRA_MONITOR("XpetraBlockedCrsMatrix::setMatrix");
1351  // TODO: if filled -> return error
1352 
1353  TEUCHOS_TEST_FOR_EXCEPTION(r > Rows(), std::out_of_range, "Error, r = " << Rows() << " is too big");
1354  TEUCHOS_TEST_FOR_EXCEPTION(c > Cols(), std::out_of_range, "Error, c = " << Cols() << " is too big");
1355  if(!mat.is_null() && r!=c) is_diagonal_ = false;
1356  // set matrix
1357  blocks_[r*Cols() + c] = mat;
1358  }
1359 
1361  // NOTE: This is a rather expensive operation, since all blocks are copied
1362  // into a new big CrsMatrix
1364  XPETRA_MONITOR("XpetraBlockedCrsMatrix::Merge");
1365  using Teuchos::RCP;
1366  using Teuchos::rcp_dynamic_cast;
1367  Scalar one = ScalarTraits<SC>::one();
1368 
1370  "BlockedCrsMatrix::Merge: only implemented for Xpetra-style or Thyra-style numbering. No mixup allowed!" );
1371 
1373  "BlockedCrsMatrix::Merge: BlockMatrix must be fill-completed." );
1374 
1375  RCP<Matrix> sparse = MatrixFactory::Build(getRangeMapExtractor()->getFullMap(), 33);
1376 
1377  if(bRangeThyraMode_ == false) {
1378  // Xpetra mode
1379  for (size_t i = 0; i < Rows(); i++) {
1380  for (size_t j = 0; j < Cols(); j++) {
1381  if (getMatrix(i,j) != Teuchos::null) {
1382  RCP<const Matrix> mat = getMatrix(i,j);
1383 
1384  // recursively call Merge routine
1385  RCP<const BlockedCrsMatrix> bMat = Teuchos::rcp_dynamic_cast<const BlockedCrsMatrix>(mat);
1386  if (bMat != Teuchos::null) mat = bMat->Merge();
1387 
1388  bMat = Teuchos::rcp_dynamic_cast<const BlockedCrsMatrix>(mat);
1390  "BlockedCrsMatrix::Merge: Merging of blocked sub-operators failed?!" );
1391 
1392  // jump over empty blocks
1393  if(mat->getNodeNumEntries() == 0) continue;
1394 
1395  this->Add(*mat, one, *sparse, one);
1396  }
1397  }
1398  }
1399  } else {
1400  // Thyra mode
1401  for (size_t i = 0; i < Rows(); i++) {
1402  for (size_t j = 0; j < Cols(); j++) {
1403  if (getMatrix(i,j) != Teuchos::null) {
1404  RCP<const Matrix> mat = getMatrix(i,j);
1405  // recursively call Merge routine
1406  RCP<const BlockedCrsMatrix> bMat = Teuchos::rcp_dynamic_cast<const BlockedCrsMatrix>(mat);
1407  if (bMat != Teuchos::null) mat = bMat->Merge();
1408 
1409  bMat = Teuchos::rcp_dynamic_cast<const BlockedCrsMatrix>(mat);
1411  "BlockedCrsMatrix::Merge: Merging of blocked sub-operators failed?!" );
1412 
1413  // check whether we have a CrsMatrix block (no blocked operator)
1414  RCP<const CrsMatrixWrap> crsMat = Teuchos::rcp_dynamic_cast<const CrsMatrixWrap>(mat);
1415  TEUCHOS_ASSERT(crsMat != Teuchos::null);
1416 
1417  // these are the thyra style maps of the matrix
1418  RCP<const Map> trowMap = mat->getRowMap();
1419  RCP<const Map> tcolMap = mat->getColMap();
1420  RCP<const Map> tdomMap = mat->getDomainMap();
1421 
1422  // get Xpetra maps
1423  RCP<const Map> xrowMap = getRangeMapExtractor()->getMap(i,false);
1424  RCP<const Map> xdomMap = getDomainMapExtractor()->getMap(j,false);
1425 
1426  // generate column map with Xpetra GIDs
1427  // We have to do this separately for each block since the column
1428  // map of each block might be different in the same block column
1430  *tcolMap,
1431  *tdomMap,
1432  *xdomMap);
1433 
1434  // jump over empty blocks
1435  if(mat->getNodeNumEntries() == 0) continue;
1436 
1437  size_t maxNumEntries = mat->getNodeMaxNumRowEntries();
1438 
1439  size_t numEntries;
1440  Array<GO> inds (maxNumEntries);
1441  Array<GO> inds2(maxNumEntries);
1442  Array<SC> vals (maxNumEntries);
1443 
1444  // loop over all rows and add entries
1445  for (size_t k = 0; k < mat->getNodeNumRows(); k++) {
1446  GlobalOrdinal rowTGID = trowMap->getGlobalElement(k);
1447  crsMat->getCrsMatrix()->getGlobalRowCopy(rowTGID, inds(), vals(), numEntries);
1448 
1449  // create new indices array
1450  for (size_t l = 0; l < numEntries; ++l) {
1451  LocalOrdinal lid = tcolMap->getLocalElement(inds[l]);
1452  inds2[l] = xcolMap->getGlobalElement(lid);
1453  }
1454 
1455  GlobalOrdinal rowXGID = xrowMap->getGlobalElement(k);
1456  sparse->insertGlobalValues(
1457  rowXGID, inds2(0, numEntries),
1458  vals(0, numEntries));
1459  }
1460  }
1461  }
1462  }
1463  }
1464 
1465  sparse->fillComplete(getDomainMap(), getRangeMap());
1466 
1468  "BlockedCrsMatrix::Merge: Local number of entries of merged matrix does not coincide with local number of entries of blocked operator." );
1469 
1471  "BlockedCrsMatrix::Merge: Global number of entries of merged matrix does not coincide with global number of entries of blocked operator." );
1472 
1473  return sparse;
1474  }
1476 
1477 #ifdef HAVE_XPETRA_KOKKOS_REFACTOR
1478  typedef typename CrsMatrix::local_matrix_type local_matrix_type;
1479 
1481  local_matrix_type getLocalMatrix () const {
1482  if (Rows() == 1 && Cols () == 1) {
1483  return getMatrix(0,0)->getLocalMatrix();
1484  }
1485  throw Xpetra::Exceptions::RuntimeError("BlockedCrsMatrix::getLocalMatrix(): operation not supported.");
1486  }
1487 #endif
1488 
1489 #ifdef HAVE_XPETRA_THYRA
1492  Xpetra::ThyraUtils<Scalar,LO,GO,Node>::toThyra(Teuchos::rcpFromRef(*this));
1494 
1496  Teuchos::rcp_dynamic_cast<Thyra::BlockedLinearOpBase<Scalar> >(thOp);
1498  return thbOp;
1499  }
1500 #endif
1501 
1502  private:
1503 
1506 
1508 
1518  void Add(const Matrix& A, const Scalar scalarA, Matrix& B, const Scalar scalarB) const {
1519  XPETRA_MONITOR("XpetraBlockedCrsMatrix::Add");
1521  "Matrix A is not completed");
1522  using Teuchos::Array;
1523  using Teuchos::ArrayView;
1524 
1525  B.scale(scalarB);
1526 
1527  Scalar one = ScalarTraits<SC>::one();
1528  Scalar zero = ScalarTraits<SC>::zero();
1529 
1530  if (scalarA == zero)
1531  return;
1532 
1533  Teuchos::RCP<const Matrix> rcpA = Teuchos::rcpFromRef(A);
1534  Teuchos::RCP<const CrsMatrixWrap> rcpAwrap = Teuchos::rcp_dynamic_cast<const CrsMatrixWrap>(rcpA);
1535  TEUCHOS_TEST_FOR_EXCEPTION(rcpAwrap == Teuchos::null, Xpetra::Exceptions::BadCast,
1536  "BlockedCrsMatrix::Add: matrix A must be of type CrsMatrixWrap.");
1537  Teuchos::RCP<const CrsMatrix> crsA = rcpAwrap->getCrsMatrix();
1538 
1539  size_t maxNumEntries = crsA->getNodeMaxNumRowEntries();
1540 
1541  size_t numEntries;
1542  Array<GO> inds(maxNumEntries);
1543  Array<SC> vals(maxNumEntries);
1544 
1545  RCP<const Map> rowMap = crsA->getRowMap();
1546  RCP<const Map> colMap = crsA->getColMap();
1547 
1548  ArrayView<const GO> rowGIDs = crsA->getRowMap()->getNodeElementList();
1549  for (size_t i = 0; i < crsA->getNodeNumRows(); i++) {
1550  GO row = rowGIDs[i];
1551  crsA->getGlobalRowCopy(row, inds(), vals(), numEntries);
1552 
1553  if (scalarA != one)
1554  for (size_t j = 0; j < numEntries; ++j)
1555  vals[j] *= scalarA;
1556 
1557  B.insertGlobalValues(row, inds(0, numEntries), vals(0, numEntries)); // insert should be ok, since blocks in BlockedCrsOpeartor do not overlap!
1558  }
1559  }
1560 
1562 
1563  // Default view is created after fillComplete()
1564  // Because ColMap might not be available before fillComplete().
1566  XPETRA_MONITOR("XpetraBlockedCrsMatrix::CreateDefaultView");
1567 
1568  // Create default view
1569  this->defaultViewLabel_ = "point";
1571 
1572  // Set current view
1573  this->currentViewLabel_ = this->GetDefaultViewLabel();
1574  }
1575 
1576 
1577  private:
1578  bool is_diagonal_; // If we're diagonal a bunch of the extraction stuff should work
1579  Teuchos::RCP<const MapExtractor> domainmaps_; // full domain map together with all partial domain maps
1580  Teuchos::RCP<const MapExtractor> rangemaps_; // full range map together with all partial domain maps
1581 
1582  std::vector<Teuchos::RCP<Matrix> > blocks_; // row major matrix block storage
1583 #ifdef HAVE_XPETRA_THYRA
1585 #endif
1588 
1589 };
1590 
1591 } //namespace Xpetra
1592 
1593 #define XPETRA_BLOCKEDCRSMATRIX_SHORT
1594 #endif /* XPETRA_BLOCKEDCRSMATRIX_HPP */
virtual void getLocalRowCopy(LocalOrdinal LocalRow, const ArrayView< LocalOrdinal > &Indices, const ArrayView< Scalar > &Values, size_t &NumEntries) const
Extract a list of entries in a specified local row of the matrix. Put into storage allocated by calli...
RCP< const Map > getDomainMap(size_t i, bool bThyraMode) const
Returns the Map associated with the i&#39;th block domain of this operator.
virtual size_t getNodeMaxNumRowEntries() const =0
Returns the maximum number of entries across all rows/columns on this node.
virtual Teuchos::RCP< const Teuchos::Comm< int > > getComm() const =0
Get this Map&#39;s Comm object.
RCP< const Map > getFullDomainMap() const
Returns the Map associated with the full domain of this operator.
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.
virtual const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > getColMap() const =0
Returns the Map that describes the column distribution in this matrix.
bool isFillComplete() const
Returns true if fillComplete() has been called and the matrix is in compute mode. ...
void replaceGlobalValues(GlobalOrdinal globalRow, const ArrayView< const GlobalOrdinal > &cols, const ArrayView< const Scalar > &vals)
Replace matrix entries, using global IDs.
void fillComplete(const RCP< const Map > &domainMap, const RCP< const Map > &rangeMap, const RCP< ParameterList > &params=null)
Signal that data entry is complete.
virtual void setAllToScalar(const Scalar &alpha)
Set all matrix entries equal to scalar.
GlobalOrdinal GO
iterator begin() const
bool is_null(const std::shared_ptr< T > &p)
RCP< const Map > getRangeMap() const
Returns the Map associated with the range of this operator.
RCP< const Map > getRangeMap(size_t i, bool bThyraMode) const
Returns the Map associated with the i&#39;th block range of this operator.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Teuchos::RCP< const MapExtractor > rangemaps_
virtual const RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > getRowMap() const =0
Returns the Map that describes the row distribution in this matrix.
void doImport(const Matrix &source, const Import &importer, CombineMode CM)
Import.
void getLocalRowView(LocalOrdinal LocalRow, ArrayView< const LocalOrdinal > &indices, ArrayView< const Scalar > &values) const
Extract a const, non-persisting view of local indices in a specified row of the matrix.
size_type size() const
virtual void bgs_apply(const MultiVector &X, MultiVector &Y, size_t row, Teuchos::ETransp mode=Teuchos::NO_TRANS, Scalar alpha=ScalarTraits< Scalar >::one(), Scalar beta=ScalarTraits< Scalar >::zero()) const
Special multiplication routine (for BGS/Jacobi smoother)
Exception throws to report errors in the internal logical of the program.
size_t getNodeNumEntries() const
Returns the local number of entries in this matrix.
virtual LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const =0
The local index corresponding to the given global index.
virtual ~BlockedCrsMatrix()
Destructor.
RCP< const Map > getRangeMap(size_t i) const
Returns the Map associated with the i&#39;th block range of this operator.
Teuchos::RCP< Matrix > getCrsMatrix() const
return unwrap 1x1 blocked operators
void doExport(const Matrix &dest, const Import &importer, CombineMode CM)
Export.
size_t getGlobalMaxNumRowEntries() const
Returns the maximum number of entries across all rows/columns on all nodes.
void Add(const Matrix &A, const Scalar scalarA, Matrix &B, const Scalar scalarB) const
Add a Xpetra::CrsMatrix to another: B = B*scalarB + A*scalarA.
void resumeFill(const RCP< ParameterList > &params=null)
BlockedCrsMatrix(const Teuchos::RCP< const BlockedMap > &rangeMaps, const Teuchos::RCP< const BlockedMap > &domainMaps, size_t npr, Xpetra::ProfileType pftype=Xpetra::DynamicProfile)
Constructor.
global_size_t getGlobalNumCols() const
Returns the number of global columns in the matrix.
virtual void update(const Scalar &alpha, const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &A, const Scalar &beta)=0
Update multi-vector values with scaled values of A, this = beta*this + alpha*A.
void rightScale(const Vector &x)
Right scale matrix using the given vector entries.
virtual void getGlobalRowCopy(GlobalOrdinal GlobalRow, const ArrayView< GlobalOrdinal > &indices, const ArrayView< Scalar > &values, size_t &numEntries) const =0
Extract a list of entries in a specified global row of this matrix. Put into pre-allocated storage...
global_size_t getGlobalNumEntries() const
Returns the global number of entries in this matrix.
size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const
Returns the current number of entries on this node in the specified local row.
RCP< const CrsGraph > getCrsGraph() const
Returns the CrsGraph associated with this matrix.
Exception indicating invalid cast attempted.
virtual bool haveGlobalConstants() const
Returns true if globalConstants have been computed; false otherwise.
void insertGlobalValues(GlobalOrdinal globalRow, const ArrayView< const GlobalOrdinal > &cols, const ArrayView< const Scalar > &vals)
Insert matrix entries, using global IDs.
void getLocalDiagCopy(Vector &diag) const
Get a copy of the diagonal entries owned by this node, with local row indices.
viewLabel_t defaultViewLabel_
virtual void insertGlobalValues(GlobalOrdinal globalRow, const ArrayView< const GlobalOrdinal > &cols, const ArrayView< const Scalar > &vals)=0
Insert matrix entries, using global IDs.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
void doExport(const Matrix &dest, const Export &exporter, CombineMode CM)
Export (using an Importer).
void leftScale(const Vector &x)
Left scale matrix using the given vector entries.
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.
void setObjectLabel(const std::string &objectLabel)
RCP< const BlockedMap > getBlockedDomainMap() const
Returns the BlockedMap associated with the domain of this operator.
Teuchos::RCP< Matrix > getInnermostCrsMatrix()
helper routine recursively returns the first inner-most non-null matrix block from a (nested) blocked...
void insertLocalValues(LocalOrdinal localRow, const ArrayView< const LocalOrdinal > &cols, const ArrayView< const Scalar > &vals)
Insert matrix entries, using local IDs.
Teuchos::RCP< Matrix > getMatrix(size_t r, size_t c) const
return block (r,c)
virtual bool isFillComplete() const =0
Returns true if fillComplete() has been called and the matrix is in compute mode. ...
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Print the object with some verbosity level to an FancyOStream object.
virtual size_t Cols() const
number of column blocks
static Teuchos::RCP< Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > transformThyra2XpetraGIDs(const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > &input, const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > &nonOvlInput, const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > &nonOvlReferenceInput)
replace set of global ids by new global ids
RCP< const Map > getFullRangeMap() const
Returns the Map associated with the full range of this operator.
const Teuchos::RCP< const Map > getMap() const
Implements DistObject interface.
void scale(const Scalar &alpha)
Scale the current values of a matrix, this = alpha*this.
void CreateView(viewLabel_t viewLabel, const RCP< const Map > &rowMap, const RCP< const Map > &colMap)
virtual Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > getMap() const =0
The Map describing the parallel distribution of this object.
viewLabel_t currentViewLabel_
TEUCHOS_DEPRECATED void reduceAll(const Comm< Ordinal > &comm, const EReductionType reductType, const Packet &send, Packet *globalReduct)
void doImport(const Matrix &source, const Export &exporter, CombineMode CM)
Import (using an Exporter).
void getGlobalRowView(GlobalOrdinal GlobalRow, ArrayView< const GlobalOrdinal > &indices, ArrayView< const Scalar > &values) const
Extract a const, non-persisting view of global indices in a specified row of the matrix.
virtual GlobalOrdinal getGlobalElement(LocalOrdinal localIndex) const =0
The global index corresponding to the given local index.
Exception throws when you call an unimplemented method of Xpetra.
T * getRawPtr() const
bool hasCrsGraph() const
Supports the getCrsGraph() call.
std::string viewLabel_t
size_t global_size_t
Global size_t object.
static RCP< Vector > Build(const Teuchos::RCP< const Map > &map, bool zeroOut=true)
Constructor specifying the number of non-zeros for all rows.
size_t getNodeMaxNumRowEntries() const
Returns the maximum number of entries across all rows/columns on this node.
static const EVerbosityLevel verbLevel_default
std::vector< Teuchos::RCP< Matrix > > blocks_
Teuchos::RCP< Matrix > Merge() const
merge BlockedCrsMatrix blocks in a CrsMatrix
static magnitudeType magnitude(T a)
RCP< const MapExtractor > getDomainMapExtractor() const
Returns map extractor for domain map.
global_size_t getGlobalNumRows() const
Returns the number of global rows.
RCP< const CrsGraph< int, GlobalOrdinal, Node > > toXpetra(const Epetra_CrsGraph &g)
#define XPETRA_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
size_t getNumEntriesInGlobalRow(GlobalOrdinal globalRow) const
Returns the current number of entries in the specified (locally owned) global row.
void setMatrix(size_t r, size_t c, Teuchos::RCP< Matrix > mat)
set matrix block
iterator end() const
std::string description() const
Return a simple one-line description of this object.
bool bDomainThyraMode_
boolean flag, which is true, if BlockedCrsMatrix has been created using Thyra-style numbering for sub...
BlockedCrsMatrix(Teuchos::RCP< const MapExtractor > &rangeMaps, Teuchos::RCP< const MapExtractor > &domainMaps, size_t npr, Xpetra::ProfileType pftype=Xpetra::DynamicProfile)
Constructor.
bool isGloballyIndexed() const
If matrix indices are in the global range, this function returns true. Otherwise, this function retur...
Exception throws to report incompatible objects (like maps).
RCP< const Map > getDomainMap() const
Returns the Map associated with the domain of this operator.
Concrete implementation of Xpetra::Matrix.
virtual size_t Rows() const
number of row blocks
CombineMode
Xpetra::Combine Mode enumerable type.
#define XPETRA_MONITOR(funcName)
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.
virtual void scale(const Scalar &alpha)=0
Scale the current values of a matrix, this = alpha*this.
void fillComplete(const RCP< ParameterList > &params=null)
Signal that data entry is complete.
#define TEUCHOS_ASSERT(assertion_test)
const viewLabel_t & GetDefaultViewLabel() const
RCP< const BlockedMap > getBlockedRangeMap() const
Returns the BlockedMap associated with the range of this operator.
RCP< const Map > getDomainMap(size_t i) const
Returns the Map associated with the i&#39;th block domain of this operator.
virtual size_t getNumVectors() const =0
Number of columns in the multivector.
virtual size_t getNodeNumRows() const =0
Returns the number of matrix rows owned on the calling node.
size_t getNodeNumRows() const
Returns the number of matrix rows owned on the calling node.
virtual UnderlyingLib lib() const =0
Get the library used by this object (Tpetra or Epetra?)
virtual ScalarTraits< Scalar >::magnitudeType getFrobeniusNorm() const
Get Frobenius norm of the matrix.
void removeEmptyProcessesInPlace(const Teuchos::RCP< const Map > &newMap)
virtual Teuchos::RCP< const Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > getVector(size_t j) const =0
Return a Vector which is a const view of column j.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
bool isLocallyIndexed() const
If matrix indices of all matrix blocks are in the local range, this function returns true...
void replaceLocalValues(LocalOrdinal localRow, const ArrayView< const LocalOrdinal > &cols, const ArrayView< const Scalar > &vals)
Replace matrix entries, using local IDs.
Xpetra-specific matrix class.
Teuchos::RCP< const MapExtractor > domainmaps_
virtual void apply(const MultiVector &X, MultiVector &Y, Teuchos::ETransp mode=Teuchos::NO_TRANS, Scalar alpha=ScalarTraits< Scalar >::one(), Scalar beta=ScalarTraits< Scalar >::zero()) const
Computes the sparse matrix-multivector multiplication.
bool bRangeThyraMode_
boolean flag, which is true, if BlockedCrsMatrix has been created using Thyra-style numbering for sub...
RCP< const MapExtractor > getRangeMapExtractor() const
Returns map extractor class for range map.
bool is_null() const