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 */
Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, KokkosClassic::DefaultNode::DefaultNodeType >::CreateView
void CreateView(viewLabel_t viewLabel, const RCP< const Map > &rowMap, const RCP< const Map > &colMap)
Definition: Xpetra_Matrix.hpp:128
Xpetra::BlockedCrsMatrix::getGlobalNumCols
global_size_t getGlobalNumCols() const
Returns the number of global columns in the matrix.
Definition: Xpetra_BlockedCrsMatrix.hpp:568
Xpetra::MatrixFactory::Build
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.
Definition: Xpetra_MatrixFactory.hpp:229
Xpetra_MultiVector.hpp
Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, KokkosClassic::DefaultNode::DefaultNodeType >::currentViewLabel_
viewLabel_t currentViewLabel_
Definition: Xpetra_Matrix.hpp:606
Kokkos::Compat::KokkosSerialWrapperNode
Definition: Kokkos_SerialNode.hpp:57
Xpetra::BlockedCrsMatrix::leftScale
void leftScale(const Vector &x)
Left scale matrix using the given vector entries.
Definition: Xpetra_BlockedCrsMatrix.hpp:832
Xpetra
Xpetra namespace
Definition: Xpetra_BlockedCrsMatrix.hpp:88
TEUCHOS_TEST_FOR_EXCEPT
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, KokkosClassic::DefaultNode::DefaultNodeType >::defaultViewLabel_
viewLabel_t defaultViewLabel_
Definition: Xpetra_Matrix.hpp:605
Xpetra::viewLabel_t
std::string viewLabel_t
Definition: Xpetra_BlockedCrsMatrix.hpp:90
Xpetra::global_size_t
size_t global_size_t
Global size_t object.
Definition: Xpetra_ConfigDefs.hpp:174
Xpetra_CrsGraph.hpp
Xpetra::Matrix::scale
virtual void scale(const Scalar &alpha)=0
Scale the current values of a matrix, this = alpha*this.
Xpetra::BlockedCrsMatrix::getNumEntriesInGlobalRow
size_t getNumEntriesInGlobalRow(GlobalOrdinal globalRow) const
Returns the current number of entries in the specified (locally owned) global row.
Definition: Xpetra_BlockedCrsMatrix.hpp:640
Xpetra::BlockedCrsMatrix::getGlobalMaxNumRowEntries
size_t getGlobalMaxNumRowEntries() const
Returns the maximum number of entries across all rows/columns on all nodes.
Definition: Xpetra_BlockedCrsMatrix.hpp:651
Xpetra::Exceptions::BadCast
Exception indicating invalid cast attempted.
Definition: Xpetra_Exceptions.hpp:87
Xpetra::BlockedCrsMatrix::scale
void scale(const Scalar &alpha)
Scale the current values of a matrix, this = alpha*this.
Definition: Xpetra_BlockedCrsMatrix.hpp:429
Xpetra::BlockedCrsMatrix::getNumEntriesInLocalRow
size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const
Returns the current number of entries on this node in the specified local row.
Definition: Xpetra_BlockedCrsMatrix.hpp:625
Xpetra::MultiVector
Definition: Xpetra_MultiVector.hpp:78
Teuchos_SerialDenseMatrix.hpp
Teuchos::ScalarTraits::magnitude
static magnitudeType magnitude(T a)
Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, KokkosClassic::DefaultNode::DefaultNodeType >::GetDefaultViewLabel
const viewLabel_t & GetDefaultViewLabel() const
Definition: Xpetra_Matrix.hpp:213
Xpetra::BlockedCrsMatrix::apply
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.
Definition: Xpetra_BlockedCrsMatrix.hpp:962
Xpetra::BlockedCrsMatrix::getDomainMapExtractor
RCP< const MapExtractor > getDomainMapExtractor() const
Returns map extractor for domain map.
Definition: Xpetra_BlockedCrsMatrix.hpp:1088
Xpetra::DynamicProfile
@ DynamicProfile
Definition: Xpetra_ConfigDefs.hpp:191
Teuchos::ScalarTraits::zero
static T zero()
XPETRA_TEST_FOR_EXCEPTION
#define XPETRA_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Definition: Xpetra_ConfigDefs.hpp:143
Xpetra::BlockedCrsMatrix::haveGlobalConstants
virtual bool haveGlobalConstants() const
Returns true if globalConstants have been computed; false otherwise.
Definition: Xpetra_BlockedCrsMatrix.hpp:925
Xpetra::BlockedCrsMatrix::doImport
void doImport(const Matrix &source, const Export &exporter, CombineMode CM)
Import (using an Exporter).
Definition: Xpetra_BlockedCrsMatrix.hpp:1204
Xpetra::BlockedCrsMatrix::resumeFill
void resumeFill(const RCP< ParameterList > &params=null)
Definition: Xpetra_BlockedCrsMatrix.hpp:452
Xpetra::BlockedCrsMatrix::setObjectLabel
void setObjectLabel(const std::string &objectLabel)
Definition: Xpetra_BlockedCrsMatrix.hpp:1263
Xpetra::BlockedCrsMatrix::removeEmptyProcessesInPlace
void removeEmptyProcessesInPlace(const Teuchos::RCP< const Map > &newMap)
Definition: Xpetra_BlockedCrsMatrix.hpp:371
Xpetra::BlockedCrsMatrix::hasCrsGraph
bool hasCrsGraph() const
Supports the getCrsGraph() call.
Definition: Xpetra_BlockedCrsMatrix.hpp:1277
Xpetra::Export
Definition: Xpetra_Export.hpp:64
Xpetra_CrsMatrixFactory.hpp
Xpetra::BlockedCrsMatrix::rightScale
void rightScale(const Vector &x)
Right scale matrix using the given vector entries.
Definition: Xpetra_BlockedCrsMatrix.hpp:870
Teuchos::NO_TRANS
NO_TRANS
Xpetra::Matrix::isFillComplete
virtual bool isFillComplete() const =0
Returns true if fillComplete() has been called and the matrix is in compute mode.
Xpetra::BlockedCrsMatrix::bgs_apply
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)
Definition: Xpetra_BlockedCrsMatrix.hpp:1103
Xpetra::toXpetra
RCP< const CrsGraph< int, GlobalOrdinal, Node > > toXpetra(const Epetra_CrsGraph &g)
Definition: Xpetra_EpetraCrsGraph.cpp:168
TEUCHOS_ASSERT
#define TEUCHOS_ASSERT(assertion_test)
Xpetra::Matrix::insertGlobalValues
virtual void insertGlobalValues(GlobalOrdinal globalRow, const ArrayView< const GlobalOrdinal > &cols, const ArrayView< const Scalar > &vals)=0
Insert matrix entries, using global IDs.
Xpetra_UseShortNames.hpp
Xpetra::BlockedCrsMatrix::getBlockedRangeMap
RCP< const BlockedMap > getBlockedRangeMap() const
Returns the BlockedMap associated with the range of this operator.
Definition: Xpetra_BlockedCrsMatrix.hpp:1073
Xpetra::BlockedCrsMatrix::bRangeThyraMode_
bool bRangeThyraMode_
boolean flag, which is true, if BlockedCrsMatrix has been created using Thyra-style numbering for sub...
Definition: Xpetra_BlockedCrsMatrix.hpp:1586
Xpetra::BlockedCrsMatrix::getFullRangeMap
RCP< const Map > getFullRangeMap() const
Returns the Map associated with the full range of this operator.
Definition: Xpetra_BlockedCrsMatrix.hpp:1070
Teuchos::rcp
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Xpetra::BlockedCrsMatrix::is_diagonal_
bool is_diagonal_
Definition: Xpetra_BlockedCrsMatrix.hpp:1578
Teuchos::EVerbosityLevel
EVerbosityLevel
Xpetra::MultiVector::getNumVectors
virtual size_t getNumVectors() const =0
Number of columns in the multivector.
Xpetra::BlockedCrsMatrix::CreateDefaultView
void CreateDefaultView()
Definition: Xpetra_BlockedCrsMatrix.hpp:1565
Xpetra::BlockedCrsMatrix::getDomainMap
RCP< const Map > getDomainMap() const
Returns the Map associated with the domain of this operator.
Definition: Xpetra_BlockedCrsMatrix.hpp:1061
Xpetra::BlockedCrsMatrix::Cols
virtual size_t Cols() const
number of column blocks
Definition: Xpetra_BlockedCrsMatrix.hpp:1302
SC
Scalar SC
Definition: Xpetra_UseShortNamesScalar.hpp:178
Xpetra::BlockedCrsMatrix::getGlobalNumRows
global_size_t getGlobalNumRows() const
Returns the number of global rows.
Definition: Xpetra_BlockedCrsMatrix.hpp:551
Xpetra::BlockedCrsMatrix::setAllToScalar
virtual void setAllToScalar(const Scalar &alpha)
Set all matrix entries equal to scalar.
Definition: Xpetra_BlockedCrsMatrix.hpp:417
Xpetra::BlockedCrsMatrix::global_ordinal_type
GlobalOrdinal global_ordinal_type
Definition: Xpetra_BlockedCrsMatrix.hpp:101
Xpetra::BlockedCrsMatrix::getRangeMapExtractor
RCP< const MapExtractor > getRangeMapExtractor() const
Returns map extractor class for range map.
Definition: Xpetra_BlockedCrsMatrix.hpp:1085
Teuchos::ArrayView
Xpetra::Map
Definition: Xpetra_Map_decl.hpp:91
Xpetra::Import
Definition: Xpetra_Import.hpp:64
Xpetra::BlockedCrsMatrix::replaceLocalValues
void replaceLocalValues(LocalOrdinal localRow, const ArrayView< const LocalOrdinal > &cols, const ArrayView< const Scalar > &vals)
Replace matrix entries, using local IDs.
Definition: Xpetra_BlockedCrsMatrix.hpp:405
Xpetra::BlockedCrsMatrix::getMatrix
Teuchos::RCP< Matrix > getMatrix(size_t r, size_t c) const
return block (r,c)
Definition: Xpetra_BlockedCrsMatrix.hpp:1335
Xpetra::CombineMode
CombineMode
Xpetra::Combine Mode enumerable type.
Definition: Xpetra_ConfigDefs.hpp:218
Xpetra::BlockedCrsMatrix::Rows
virtual size_t Rows() const
number of row blocks
Definition: Xpetra_BlockedCrsMatrix.hpp:1299
Xpetra::BlockedCrsMatrix::doExport
void doExport(const Matrix &dest, const Import &importer, CombineMode CM)
Export.
Definition: Xpetra_BlockedCrsMatrix.hpp:1194
Teuchos::RCP
Xpetra::BlockedCrsMatrix::bDomainThyraMode_
bool bDomainThyraMode_
boolean flag, which is true, if BlockedCrsMatrix has been created using Thyra-style numbering for sub...
Definition: Xpetra_BlockedCrsMatrix.hpp:1587
Xpetra::BlockedCrsMatrix::getRangeMap
RCP< const Map > getRangeMap(size_t i) const
Returns the Map associated with the i'th block range of this operator.
Definition: Xpetra_BlockedCrsMatrix.hpp:1079
Teuchos::Array
Xpetra::BlockedCrsMatrix::getNodeNumRows
size_t getNodeNumRows() const
Returns the number of matrix rows owned on the calling node.
Definition: Xpetra_BlockedCrsMatrix.hpp:583
Teuchos::ArrayView::begin
iterator begin() const
Xpetra::BlockedCrsMatrix::getLocalRowCopy
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...
Definition: Xpetra_BlockedCrsMatrix.hpp:736
Xpetra::BlockedCrsMatrix::getGlobalNumEntries
global_size_t getGlobalNumEntries() const
Returns the global number of entries in this matrix.
Definition: Xpetra_BlockedCrsMatrix.hpp:598
Xpetra::BlockedCrsMatrix::getCrsGraph
RCP< const CrsGraph > getCrsGraph() const
Returns the CrsGraph associated with this matrix.
Definition: Xpetra_BlockedCrsMatrix.hpp:1283
Xpetra::Matrix
Xpetra-specific matrix class.
Definition: Xpetra_Matrix.hpp:97
Xpetra::BlockedCrsMatrix::getNodeNumEntries
size_t getNodeNumEntries() const
Returns the local number of entries in this matrix.
Definition: Xpetra_BlockedCrsMatrix.hpp:611
Teuchos::TRANS
TRANS
Xpetra::MapUtils::transformThyra2XpetraGIDs
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
Definition: Xpetra_MapUtils.hpp:232
Xpetra::Vector
Definition: Xpetra_Vector.hpp:62
Xpetra::BlockedCrsMatrix::blocks_
std::vector< Teuchos::RCP< Matrix > > blocks_
Definition: Xpetra_BlockedCrsMatrix.hpp:1582
Xpetra::BlockedCrsMatrix::getInnermostCrsMatrix
Teuchos::RCP< Matrix > getInnermostCrsMatrix()
helper routine recursively returns the first inner-most non-null matrix block from a (nested) blocked...
Definition: Xpetra_BlockedCrsMatrix.hpp:1317
Xpetra::BlockedCrsMatrix::replaceGlobalValues
void replaceGlobalValues(GlobalOrdinal globalRow, const ArrayView< const GlobalOrdinal > &cols, const ArrayView< const Scalar > &vals)
Replace matrix entries, using global IDs.
Definition: Xpetra_BlockedCrsMatrix.hpp:389
Xpetra::BlockedCrsMatrix::getDomainMap
RCP< const Map > getDomainMap(size_t i, bool bThyraMode) const
Returns the Map associated with the i'th block domain of this operator.
Definition: Xpetra_BlockedCrsMatrix.hpp:1067
Xpetra::BlockedCrsMatrix::~BlockedCrsMatrix
virtual ~BlockedCrsMatrix()
Destructor.
Definition: Xpetra_BlockedCrsMatrix.hpp:308
Xpetra::BlockedCrsMatrix::getGlobalRowView
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.
Definition: Xpetra_BlockedCrsMatrix.hpp:758
Xpetra::MultiVector::update
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.
Xpetra::BlockedCrsMatrix::getMap
const Teuchos::RCP< const Map > getMap() const
Implements DistObject interface.
Definition: Xpetra_BlockedCrsMatrix.hpp:1175
Xpetra::Exceptions::RuntimeError
Exception throws to report errors in the internal logical of the program.
Definition: Xpetra_Exceptions.hpp:102
Teuchos::basic_FancyOStream
Teuchos::ScalarTraits::one
static T one()
Teuchos::ArrayView::size
size_type size() const
Xpetra::BlockedCrsMatrix::insertLocalValues
void insertLocalValues(LocalOrdinal localRow, const ArrayView< const LocalOrdinal > &cols, const ArrayView< const Scalar > &vals)
Insert matrix entries, using local IDs.
Definition: Xpetra_BlockedCrsMatrix.hpp:362
Kokkos_DefaultNode.hpp
Xpetra::BlockedCrsMatrix::description
std::string description() const
Return a simple one-line description of this object.
Definition: Xpetra_BlockedCrsMatrix.hpp:1229
Xpetra::BlockedCrsMatrix::describe
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.
Definition: Xpetra_BlockedCrsMatrix.hpp:1232
Xpetra::BlockedCrsMatrix::getLocalDiagCopy
void getLocalDiagCopy(Vector &diag) const
Get a copy of the diagonal entries owned by this node, with local row indices.
Definition: Xpetra_BlockedCrsMatrix.hpp:797
Teuchos::ScalarTraits
Xpetra::BlockedCrsMatrix::doImport
void doImport(const Matrix &source, const Import &importer, CombineMode CM)
Import.
Definition: Xpetra_BlockedCrsMatrix.hpp:1184
Xpetra::Exceptions::NotImplemented
Exception throws when you call an unimplemented method of Xpetra.
Definition: Xpetra_Exceptions.hpp:95
Xpetra::BlockedCrsMatrix
Definition: Xpetra_BlockedCrsMatrix.hpp:97
Xpetra::BlockedCrsMatrix::getRangeMap
RCP< const Map > getRangeMap() const
Returns the Map associated with the range of this operator.
Definition: Xpetra_BlockedCrsMatrix.hpp:1076
Xpetra::BlockedCrsMatrix::BlockedCrsMatrix
BlockedCrsMatrix(Teuchos::RCP< const MapExtractor > &rangeMaps, Teuchos::RCP< const MapExtractor > &domainMaps, size_t npr, Xpetra::ProfileType pftype=Xpetra::DynamicProfile)
Constructor.
Definition: Xpetra_BlockedCrsMatrix.hpp:149
Teuchos::ArrayView::getRawPtr
T * getRawPtr() const
Xpetra::DistObject::getMap
virtual Teuchos::RCP< const Map< LocalOrdinal, GlobalOrdinal, Node > > getMap() const =0
The Map describing the parallel distribution of this object.
Xpetra_ThyraUtils.hpp
Xpetra::BlockedCrsMatrix::isGloballyIndexed
bool isGloballyIndexed() const
If matrix indices are in the global range, this function returns true. Otherwise, this function retur...
Definition: Xpetra_BlockedCrsMatrix.hpp:704
Xpetra::BlockedCrsMatrix::isFillComplete
bool isFillComplete() const
Returns true if fillComplete() has been called and the matrix is in compute mode.
Definition: Xpetra_BlockedCrsMatrix.hpp:713
Teuchos::reduceAll
TEUCHOS_DEPRECATED void reduceAll(const Comm< Ordinal > &comm, const EReductionType reductType, const Packet &send, Packet *globalReduct)
Xpetra::BlockedCrsMatrix::getRangeMap
RCP< const Map > getRangeMap(size_t i, bool bThyraMode) const
Returns the Map associated with the i'th block range of this operator.
Definition: Xpetra_BlockedCrsMatrix.hpp:1082
Xpetra::BlockedCrsMatrix::getFullDomainMap
RCP< const Map > getFullDomainMap() const
Returns the Map associated with the full domain of this operator.
Definition: Xpetra_BlockedCrsMatrix.hpp:1055
Xpetra_ConfigDefs.hpp
Xpetra_MatrixFactory.hpp
Teuchos::RCP::is_null
bool is_null() const
Xpetra::MultiVectorFactory::Build
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.
Definition: Xpetra_MultiVectorFactory_def.hpp:62
Xpetra::Exceptions::Incompatible
Exception throws to report incompatible objects (like maps).
Definition: Xpetra_Exceptions.hpp:108
Xpetra::BlockedCrsMatrix::Merge
Teuchos::RCP< Matrix > Merge() const
merge BlockedCrsMatrix blocks in a CrsMatrix
Definition: Xpetra_BlockedCrsMatrix.hpp:1363
Xpetra::BlockedCrsMatrix::fillComplete
void fillComplete(const RCP< ParameterList > &params=null)
Signal that data entry is complete.
Definition: Xpetra_BlockedCrsMatrix.hpp:491
Xpetra::CrsMatrixWrap
Concrete implementation of Xpetra::Matrix.
Definition: Xpetra_CrsMatrixWrap_decl.hpp:85
Xpetra::BlockedCrsMatrix::BlockedCrsMatrix
BlockedCrsMatrix(const Teuchos::RCP< const BlockedMap > &rangeMaps, const Teuchos::RCP< const BlockedMap > &domainMaps, size_t npr, Xpetra::ProfileType pftype=Xpetra::DynamicProfile)
Constructor.
Definition: Xpetra_BlockedCrsMatrix.hpp:120
Xpetra::BlockedCrsMatrix::getNodeMaxNumRowEntries
size_t getNodeMaxNumRowEntries() const
Returns the maximum number of entries across all rows/columns on this node.
Definition: Xpetra_BlockedCrsMatrix.hpp:671
Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, KokkosClassic::DefaultNode::DefaultNodeType >::getRowMap
virtual const RCP< const Map > & getRowMap() const
Returns the Map that describes the row distribution in this matrix.
Definition: Xpetra_Matrix.hpp:320
Teuchos::ArrayView::end
iterator end() const
Xpetra::BlockedCrsMatrix::local_ordinal_type
LocalOrdinal local_ordinal_type
Definition: Xpetra_BlockedCrsMatrix.hpp:100
Xpetra::BlockedCrsMatrix::getCrsMatrix
Teuchos::RCP< Matrix > getCrsMatrix() const
return unwrap 1x1 blocked operators
Definition: Xpetra_BlockedCrsMatrix.hpp:1305
Xpetra::BlockedCrsMatrix::getBlockedDomainMap
RCP< const BlockedMap > getBlockedDomainMap() const
Returns the BlockedMap associated with the domain of this operator.
Definition: Xpetra_BlockedCrsMatrix.hpp:1058
Xpetra::BlockedCrsMatrix::domainmaps_
Teuchos::RCP< const MapExtractor > domainmaps_
Definition: Xpetra_BlockedCrsMatrix.hpp:1579
Xpetra_Exceptions.hpp
Xpetra::BlockedCrsMatrix::getDomainMap
RCP< const Map > getDomainMap(size_t i) const
Returns the Map associated with the i'th block domain of this operator.
Definition: Xpetra_BlockedCrsMatrix.hpp:1064
Xpetra_VectorFactory.hpp
Xpetra::BlockedCrsMatrix::getFrobeniusNorm
virtual ScalarTraits< Scalar >::magnitudeType getFrobeniusNorm() const
Get Frobenius norm of the matrix.
Definition: Xpetra_BlockedCrsMatrix.hpp:909
GO
GlobalOrdinal GO
Definition: Xpetra_UseShortNamesOrdinal.hpp:139
Xpetra::VectorFactory::Build
static RCP< Vector > Build(const Teuchos::RCP< const Map > &map, bool zeroOut=true)
Constructor specifying the number of non-zeros for all rows.
Definition: Xpetra_VectorFactory.hpp:83
Teuchos::OrdinalTraits::invalid
static T invalid()
Xpetra::MapExtractor
Definition: Xpetra_MapExtractor_decl.hpp:83
Xpetra::BlockedCrsMatrix::getLocalRowView
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.
Definition: Xpetra_BlockedCrsMatrix.hpp:777
Xpetra::BlockedCrsMatrix::isLocallyIndexed
bool isLocallyIndexed() const
If matrix indices of all matrix blocks are in the local range, this function returns true....
Definition: Xpetra_BlockedCrsMatrix.hpp:692
Xpetra::BlockedCrsMatrix::Add
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.
Definition: Xpetra_BlockedCrsMatrix.hpp:1518
Xpetra::BlockedCrsMatrix::scalar_type
Scalar scalar_type
Definition: Xpetra_BlockedCrsMatrix.hpp:99
Teuchos::ScalarTraits::magnitudeType
T magnitudeType
Teuchos::Comm
Xpetra::MapFactory::Build
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.
Definition: Xpetra_MapFactory_def.hpp:93
Xpetra::BlockedCrsMatrix::node_type
Node node_type
Definition: Xpetra_BlockedCrsMatrix.hpp:102
Xpetra::BlockedCrsMatrix::fillComplete
void fillComplete(const RCP< const Map > &domainMap, const RCP< const Map > &rangeMap, const RCP< ParameterList > &params=null)
Signal that data entry is complete.
Definition: Xpetra_BlockedCrsMatrix.hpp:468
Xpetra::BlockedCrsMatrix::isDiagonal
virtual bool isDiagonal() const
Definition: Xpetra_BlockedCrsMatrix.hpp:1296
Xpetra::BlockedCrsMatrix::rangemaps_
Teuchos::RCP< const MapExtractor > rangemaps_
Definition: Xpetra_BlockedCrsMatrix.hpp:1580
Teuchos_Hashtable.hpp
Teuchos::Describable::verbLevel_default
static const EVerbosityLevel verbLevel_default
Xpetra::BlockedCrsMatrix::insertGlobalValues
void insertGlobalValues(GlobalOrdinal globalRow, const ArrayView< const GlobalOrdinal > &cols, const ArrayView< const Scalar > &vals)
Insert matrix entries, using global IDs.
Definition: Xpetra_BlockedCrsMatrix.hpp:342
TEUCHOS_TEST_FOR_EXCEPTION
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
XPETRA_MONITOR
#define XPETRA_MONITOR(funcName)
Definition: Xpetra_ConfigDefs.hpp:132
Xpetra_Matrix.hpp
Teuchos::is_null
bool is_null(const std::shared_ptr< T > &p)
Xpetra::BlockedCrsMatrix::setMatrix
void setMatrix(size_t r, size_t c, Teuchos::RCP< Matrix > mat)
set matrix block
Definition: Xpetra_BlockedCrsMatrix.hpp:1349
Teuchos::ETransp
ETransp
Xpetra_CrsMatrix.hpp
Xpetra::BlockedCrsMatrix::doExport
void doExport(const Matrix &dest, const Export &exporter, CombineMode CM)
Export (using an Importer).
Definition: Xpetra_BlockedCrsMatrix.hpp:1214
Xpetra::ProfileType
ProfileType
Definition: Xpetra_ConfigDefs.hpp:189