All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
Xpetra_BlockedCrsOperator.hpp
Go to the documentation of this file.
00001 // @HEADER
00002 //
00003 // ***********************************************************************
00004 //
00005 //             Xpetra: A linear algebra interface package
00006 //                  Copyright 2012 Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact
00039 //                    Jeremie Gaidamour (jngaida@sandia.gov)
00040 //                    Jonathan Hu       (jhu@sandia.gov)
00041 //                    Ray Tuminaro      (rstumin@sandia.gov)
00042 //
00043 // ***********************************************************************
00044 //
00045 // @HEADER
00046 /*
00047  * Xpetra_BlockedCrsOperator.hpp
00048  *
00049  *  Created on: Aug 17, 2011
00050  *      Author: wiesner
00051  */
00052 
00053 // WARNING: This code is experimental. Backwards compatibility should not be expected.
00054 
00055 #ifndef XPETRA_BLOCKEDCRSOPERATOR_HPP_
00056 #define XPETRA_BLOCKEDCRSOPERATOR_HPP_
00057 
00058 #include <Kokkos_DefaultNode.hpp>
00059 #include <Kokkos_DefaultKernels.hpp>
00060 
00061 #include <Teuchos_SerialDenseMatrix.hpp>
00062 #include <Teuchos_Hashtable.hpp>
00063 
00064 #include "Xpetra_ConfigDefs.hpp"
00065 #include "Xpetra_Exceptions.hpp"
00066 
00067 #include "Xpetra_MapFactory.hpp"
00068 #include "Xpetra_MultiVector.hpp"
00069 #include "Xpetra_MultiVectorFactory.hpp"
00070 #include "Xpetra_CrsGraph.hpp"
00071 #include "Xpetra_CrsMatrix.hpp"
00072 #include "Xpetra_CrsMatrixFactory.hpp"
00073 
00074 #include "Xpetra_MapExtractor.hpp"
00075 
00076 #include "Xpetra_Operator.hpp"
00077 
00078 #define sumAll(rcpComm, in, out)                                        \
00079   Teuchos::reduceAll(*rcpComm, Teuchos::REDUCE_SUM, in, Teuchos::outArg(out));
00080 
00085 namespace Xpetra {
00086 
00087   typedef std::string viewLabel_t;
00088 
00089 template <class Scalar,
00090           class LocalOrdinal  = int,
00091           class GlobalOrdinal = LocalOrdinal,
00092           class Node          = Kokkos::DefaultNode::DefaultNodeType,
00093           class LocalMatOps   = typename Kokkos::DefaultKernels<Scalar,LocalOrdinal,Node>::SparseOps > //TODO: or BlockSparseOp ?
00094 class BlockedCrsOperator : public Operator<Scalar,LocalOrdinal,GlobalOrdinal,Node,LocalMatOps> {
00095 
00096   typedef Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node> MapClass;
00097   typedef Xpetra::MapExtractor<Scalar, LocalOrdinal, GlobalOrdinal, Node> MapExtractorClass;
00098   typedef Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalMatOps> CrsMatrixClass;
00099   typedef Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalMatOps> Operator;
00100   typedef Xpetra::CrsGraph<LocalOrdinal, GlobalOrdinal, Node, LocalMatOps> CrsGraph;
00101 #ifdef HAVE_CTHULHU_TPETRA
00102   typedef Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalMatOps> TpetraCrsMatrix;
00103 #endif
00104   typedef Xpetra::CrsMatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalMatOps> CrsMatrixFactory;
00105   typedef Xpetra::OperatorView<LocalOrdinal, GlobalOrdinal, Node> OperatorView;
00106 
00107 public:
00108 
00110 
00111 
00113 
00119   BlockedCrsOperator(Teuchos::RCP<const MapExtractorClass>& rangeMaps,
00120                      Teuchos::RCP<const MapExtractorClass>& domainMaps,
00121                      size_t npr,
00122                      Xpetra::ProfileType pftype = Xpetra::DynamicProfile)
00123   : domainmaps_(domainMaps),
00124     rangemaps_(rangeMaps)
00125   {
00126     // Set matrix data
00127     //matrixData_ = Teuchos::null; //CrsMatrixFactory::Build(rowMap, maxNumEntriesPerRow, pftype); // TODO remove me
00128 
00129     blocks_.reserve(Rows()*Cols());
00130 
00131     // add CrsMatrix objects in row,column order
00132     for (size_t r=0; r<Rows(); ++r)
00133     {
00134       for(size_t c=0; c<Cols(); ++c)
00135       {
00136         Teuchos::RCP<CrsMatrixClass> matblock = CrsMatrixFactory::Build(getRangeMap(r), npr, pftype);
00137         blocks_.push_back(matblock);
00138       }
00139     }
00140 
00141     // Default view
00142     CreateDefaultView();
00143   }
00144 
00146   virtual ~BlockedCrsOperator() {}
00147 
00149 
00150 
00152 
00153 
00155 
00166   void insertGlobalValues(GlobalOrdinal globalRow, const ArrayView<const GlobalOrdinal> &cols, const ArrayView<const Scalar> &vals)
00167   {
00168     TEUCHOS_TEST_FOR_EXCEPTION( true, Xpetra::Exceptions::RuntimeError,
00169         "insertGlobalValues not supported by BlockedCrsOperator!" );
00170   }
00171 
00173 
00180   void insertLocalValues(LocalOrdinal localRow, const ArrayView<const LocalOrdinal> &cols, const ArrayView<const Scalar> &vals) {
00181     TEUCHOS_TEST_FOR_EXCEPTION( true, Xpetra::Exceptions::RuntimeError,
00182         "insertLocalValues not supported by BlockedCrsOperator!" );
00183   }
00184 
00186 
00188 
00189 
00201   void fillComplete(const RCP<const MapClass> &domainMap, const RCP<const MapClass> &rangeMap, const RCP<ParameterList> &params=null)
00202   {
00203     TEUCHOS_TEST_FOR_EXCEPTION( true, Xpetra::Exceptions::RuntimeError,
00204         "fillComplete with arguments not supported for block matrices!" );
00205   }
00206 
00220   //TODO : Get ride of "Tpetra"::OptimizeOption
00221   void fillComplete(const RCP<ParameterList> &params=null)
00222   {
00223     for (size_t r=0; r<Rows(); ++r)
00224     {
00225       for (size_t c=0; c<Cols(); ++c)
00226       {
00227         if(getMatrix(r,c)->isFillComplete() == false)
00228           getMatrix(r,c)->fillComplete(getDomainMap(c),getRangeMap(r),params);
00229       }
00230     }
00231 
00232     // get full row map
00233     //fullrowmap_ = Xpetra::MapFactory<LocalOrdinal,GlobalOrdinal,Node>::Build(rangemaps_->getFullMap()->lib(), rangemaps_->getFullMap()->getNodeNumElements(), rangemaps_->getFullMap()->getNodeElementList(), rangemaps_->getFullMap()->getIndexBase(), rangemaps_->getFullMap()->getComm());//rangemaps_->FullMap(); //->Clone();
00234     fullrowmap_ = Xpetra::MapFactory<LocalOrdinal,GlobalOrdinal,Node>::Build(rangemaps_->getFullMap()->lib(), rangemaps_->getFullMap()->getGlobalNumElements(), rangemaps_->getFullMap()->getNodeElementList(), rangemaps_->getFullMap()->getIndexBase(), rangemaps_->getFullMap()->getComm());//rangemaps_->FullMap(); //->Clone();
00235 
00236     // TODO: check me, clean up, use only ArrayView instead of std::vector
00237     // build full col map
00238     if (fullcolmap_ == Teuchos::null)
00239     {
00240       std::vector<GlobalOrdinal> colmapentries;
00241       for (size_t c=0; c<Cols(); ++c)
00242       {
00243         std::set<GlobalOrdinal> colset;
00244         for (size_t r=0; r<Rows(); ++r)
00245         {
00246           if(getMatrix(r,c) != Teuchos::null) {
00247             Teuchos::RCP<const MapClass> colmap = getMatrix(r,c)->getColMap();
00248             copy(colmap->getNodeElementList().getRawPtr(),
00249           colmap->getNodeElementList().getRawPtr()+colmap->getNodeNumElements(),
00250           inserter(colset,colset.begin()));
00251           }
00252         }
00253         colmapentries.reserve(colmapentries.size()+colset.size());
00254         copy(colset.begin(), colset.end(), back_inserter(colmapentries));
00255         sort(colmapentries.begin(), colmapentries.end());
00256         typename std::vector<GlobalOrdinal>::iterator gendLocation;
00257         gendLocation = std::unique(colmapentries.begin(), colmapentries.end());
00258         colmapentries.erase(gendLocation,colmapentries.end());
00259       }
00260 
00261       // sum up number of local elements
00262       size_t numGlobalElements = 0;
00263       sumAll(rangemaps_->getFullMap()->getComm(), colmapentries.size(), numGlobalElements) 
00264 
00265       const Teuchos::ArrayView<const GlobalOrdinal> aView = Teuchos::ArrayView<const GlobalOrdinal>(colmapentries);
00266       fullcolmap_ = Xpetra::MapFactory<LocalOrdinal,GlobalOrdinal,Node>::Build(rangemaps_->getFullMap()->lib(), numGlobalElements, aView, 0,rangemaps_->getFullMap()->getComm());
00267       //fullcolmap_ = Xpetra::MapFactory<LocalOrdinal,GlobalOrdinal,Node>::Build(rangemaps_->getFullMap()->lib(), domainmaps_->getFullMap()->getGlobalNumElements(), aView, 0,domainmaps_->getFullMap()->getComm());
00268     }
00269 
00270 
00271   }
00272 
00274 
00276 
00278   global_size_t getGlobalNumRows() const
00279   {
00280     global_size_t globalNumRows= 0;
00281     for (size_t r=0; r<Rows(); ++r)
00282     {
00283       globalNumRows += getMatrix(r,0)->getGlobalNumRows();
00284     }
00285     return globalNumRows;
00286   }
00287 
00289 
00291   global_size_t getGlobalNumCols() const
00292   {
00293     global_size_t globalNumCols= 0;
00294     for (size_t c=0; c<Cols(); ++c)
00295     {
00296       globalNumCols += getMatrix(0,c)->getGlobalNumCols();
00297     }
00298     return globalNumCols;
00299   }
00300 
00302   size_t getNodeNumRows() const
00303   {
00304     global_size_t nodeNumRows= 0;
00305     for (size_t r=0; r<Rows(); ++r)
00306     {
00307       nodeNumRows += getMatrix(r,0)->getNodeNumRows();
00308     }
00309     return nodeNumRows;
00310   }
00311 
00313   global_size_t getGlobalNumEntries() const
00314   {
00315     global_size_t globalNumEntries= 0;
00316     for (size_t r=0; r<Rows(); ++r)
00317     {
00318       for(size_t c=0; c<Cols(); ++c)
00319       {
00320         globalNumEntries += getMatrix(r,c)->getGlobalNumEntries();
00321       }
00322     }
00323     return globalNumEntries;
00324   }
00325 
00327   size_t getNodeNumEntries() const
00328   {
00329     global_size_t nodeNumEntries= 0;
00330     for (size_t r=0; r<Rows(); ++r)
00331     {
00332       for(size_t c=0; c<Cols(); ++c)
00333       {
00334         nodeNumEntries += getMatrix(r,c)->getNodeNumEntries();
00335       }
00336     }
00337     return nodeNumEntries;
00338   }
00339 
00341 
00342   size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const
00343   {
00344     TEUCHOS_TEST_FOR_EXCEPTION( true, Xpetra::Exceptions::RuntimeError,
00345         "getNumEntriesInLocalRow not supported by BlockedCrsOperator!" );
00346     return 0;
00347   }
00348 
00350 
00352   global_size_t getGlobalNumDiags() const
00353   {
00354     TEUCHOS_TEST_FOR_EXCEPTION( true, Xpetra::Exceptions::RuntimeError,
00355         "getGlobalNumDiags() not supported by BlockedCrsOperator!" );
00356     return 0;
00357   }
00358 
00360 
00362   size_t getNodeNumDiags() const
00363   {
00364     TEUCHOS_TEST_FOR_EXCEPTION( true, Xpetra::Exceptions::RuntimeError,
00365         "getNodeNumDiags() not supported by BlockedCrsOperator!" );
00366     return 0;
00367   }
00368 
00370 
00372   size_t getGlobalMaxNumRowEntries() const
00373   {
00374     TEUCHOS_TEST_FOR_EXCEPTION( true, Xpetra::Exceptions::RuntimeError,
00375         "getGlobalMaxNumRowEntries() not supported by BlockedCrsOperator!" );
00376     return 0;
00377   }
00378 
00380 
00382   size_t getNodeMaxNumRowEntries() const
00383   {
00384     TEUCHOS_TEST_FOR_EXCEPTION( true, Xpetra::Exceptions::RuntimeError,
00385         "getNodeMaxNumRowEntries() not supported by BlockedCrsOperator!" );
00386     return 0;
00387   }
00388 
00390 
00393   bool isLocallyIndexed() const
00394   {
00395     for (size_t i=0; i<blocks_.size(); ++i)
00396       if (not blocks_[i]->isLocallyIndexed())
00397         return false;
00398     return true;
00399   }
00400 
00402 
00405   bool isGloballyIndexed() const
00406   {
00407     for (size_t i=0; i<blocks_.size(); ++i)
00408       if (not blocks_[i]->isGloballyIndexed())
00409         return false;
00410     return true;
00411   }
00412 
00414   bool isFillComplete() const
00415   {
00416     for (size_t i=0; i<blocks_.size(); ++i)
00417       if (not blocks_[i]->isFillComplete())
00418         return false;
00419     return true;
00420   }
00421 
00423 
00435     virtual void getLocalRowCopy(LocalOrdinal LocalRow,
00436                                  const ArrayView<LocalOrdinal> &Indices,
00437                                  const ArrayView<Scalar> &Values,
00438                                  size_t &NumEntries
00439                                  ) const
00440     {
00441       TEUCHOS_TEST_FOR_EXCEPTION( true, Xpetra::Exceptions::RuntimeError,
00442           "getLocalRowCopy not supported by BlockedCrsOperator!" );
00443     }
00444 
00446 
00455   void getGlobalRowView(GlobalOrdinal GlobalRow, ArrayView<const GlobalOrdinal> &indices, ArrayView<const Scalar> &values) const
00456   {
00457     TEUCHOS_TEST_FOR_EXCEPTION( true, Xpetra::Exceptions::RuntimeError,
00458         "getGlobalRowView not supported by BlockedCrsOperator!" );
00459   }
00460 
00462 
00471   void getLocalRowView(LocalOrdinal LocalRow, ArrayView<const LocalOrdinal> &indices, ArrayView<const Scalar> &values) const
00472   {
00473     TEUCHOS_TEST_FOR_EXCEPTION( true, Xpetra::Exceptions::RuntimeError,
00474         "getLocalRowView not supported by BlockedCrsOperator!" );
00475   }
00476 
00478 
00480   void getLocalDiagCopy(Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &diag) const
00481   {
00482     TEUCHOS_TEST_FOR_EXCEPTION( true, Xpetra::Exceptions::RuntimeError,
00483         "getLocalDiagCopy not supported by BlockedCrsOperator!" );
00484   }
00485 
00487   virtual typename ScalarTraits<Scalar>::magnitudeType getFrobeniusNorm() const
00488   {
00489     TEUCHOS_TEST_FOR_EXCEPTION( true, Xpetra::Exceptions::RuntimeError,
00490         "getFrobeniusNorm() not supported by BlockedCrsOperator, yet!" );
00491   }
00492 
00494 
00496 
00497 
00499 
00508   //TODO virtual=0 // TODO: Add default parameters ?
00509 //   void multiply(const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> & X, MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &Y, Teuchos::ETransp trans, Scalar alpha, Scalar beta) const {
00510 //      matrixData_->multiply(X, Y, trans, alpha, beta);
00511 //   }
00512 
00514 
00516 
00517 
00519 
00522   virtual void apply(const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> & X, MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &Y,
00523                      Teuchos::ETransp mode = Teuchos::NO_TRANS,
00524                      Scalar alpha = ScalarTraits<Scalar>::one(),
00525                      Scalar beta = ScalarTraits<Scalar>::zero()) const
00526   {
00527     // TODO: check maps
00528 
00529     Teuchos::RCP<const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > tX   = Teuchos::rcp(&X,false);
00530     Teuchos::RCP<      MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > tmpY = MultiVectorFactory<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Build(Y.getMap(), Y.getNumVectors());
00531 
00532     if (mode == Teuchos::NO_TRANS)
00533     {
00534       for(size_t rblock=0; rblock<Rows(); ++rblock)
00535       {
00536         Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > rowresult = rangemaps_->getVector(rblock,Y.getNumVectors()); // end result for block row
00537         Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > rowy      = rangemaps_->getVector(rblock,Y.getNumVectors()); // helper vector
00538         for (size_t cblock=0; cblock<Cols(); ++cblock)
00539         {
00540           Teuchos::RCP<const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > colx = domainmaps_->ExtractVector(tX,cblock);
00541           Teuchos::RCP<CrsMatrixClass> bmat = getMatrix(rblock,cblock);
00542           bmat->apply(*colx,*rowy);
00543           rowresult->update(ScalarTraits< Scalar >::one(),*rowy,ScalarTraits< Scalar >::one());
00544         }
00545         rangemaps_->InsertVector(rowresult,rblock,tmpY);
00546       }
00547       Y.update(alpha,*tmpY,beta);
00548     }
00549     else if (mode == Teuchos::TRANS)
00550     {
00551       // TODO: test me!
00552       for (size_t cblock = 0; cblock<Cols(); ++cblock)
00553       {
00554         Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > rowresult = domainmaps_->getVector(cblock,Y.getNumVectors()); // end result for block row
00555         Teuchos::RCP<MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > rowy      = domainmaps_->getVector(cblock,Y.getNumVectors()); // helper vector
00556         for (size_t rblock = 0; rblock<Rows(); ++rblock)
00557         {
00558           Teuchos::RCP<const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > colx = rangemaps_->ExtractVector(tX,rblock);
00559           Teuchos::RCP<CrsMatrixClass> bmat = getMatrix(rblock,cblock);
00560           bmat->apply(*colx,*rowy,Teuchos::TRANS);
00561           rowresult->update(ScalarTraits< Scalar >::one(),*rowy,ScalarTraits< Scalar >::one());
00562         }
00563         domainmaps_->InsertVector(rowresult,cblock,tmpY);
00564       }
00565       Y.update(alpha,*tmpY,beta);
00566     }
00567     else
00568       TEUCHOS_TEST_FOR_EXCEPTION( true, Xpetra::Exceptions::RuntimeError,
00569           "apply() only supports NO_TRANS and TRANS." );
00570 
00571   }
00572 
00575   const RCP<const MapClass > getDomainMap() const
00576   {
00577     return domainmaps_->getFullMap();
00578   }
00579 
00582   const RCP<const MapClass > getDomainMap(size_t i) const
00583   {
00584     return domainmaps_->getMap(i);
00585   }
00586 
00589   const RCP<const MapClass > getRangeMap() const
00590   {
00591     return rangemaps_->getFullMap();
00592   }
00593 
00596   const RCP<const MapClass > getRangeMap(size_t i) const
00597   {
00598     return rangemaps_->getMap(i);
00599   }
00600 
00602   const RCP<const MapExtractorClass> getRangeMapExtractor()
00603   {
00604     return rangemaps_;
00605   }
00606 
00608   const RCP<const MapExtractorClass> getDomainMapExtractor()
00609   {
00610     return domainmaps_;
00611   }
00612 
00614 
00616 
00617 
00619   std::string description() const {
00620     std::ostringstream oss;
00621     oss << "Xpetra_BlockedCrsOperator.description()" << std::endl;
00622     return oss.str();
00623   }
00624 
00626   void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const {
00627     //     Teuchos::EVerbosityLevel vl = verbLevel;
00628     //     if (vl == VERB_DEFAULT) vl = VERB_LOW;
00629     //     RCP<const Comm<int> > comm = this->getComm();
00630     //     const int myImageID = comm->getRank(),
00631     //       numImages = comm->getSize();
00632 
00633     //     if (myImageID == 0) out << this->description() << std::endl;
00634 
00635     out << "Xpetra::BlockedCrsOperator: " << Rows() << " x " << Cols() << std::endl;
00636 
00637     if(isFillComplete())
00638     {
00639       out << "BlockOperator is filled" << std::endl;
00640       out << "fullRowMap" << std::endl;
00641       fullrowmap_->describe(out,verbLevel);
00642       out << "fullColMap" << std::endl;
00643       fullcolmap_->describe(out,verbLevel);
00644     }
00645     else
00646       out << "BlockOperator is NOT filled" << std::endl;
00647 
00648     for (size_t r=0; r<Rows(); ++r)
00649     {
00650       for(size_t c=0; c<Cols(); ++c)
00651       {
00652         out << "Block(" << r << "," << c << ")" << std::endl;
00653         getMatrix(r,c)->describe(out,verbLevel);
00654       }
00655     }
00656 
00657 
00658     //matrixData_->describe(out,verbLevel);
00659 
00660     // Teuchos::OSTab tab(out);
00661   }
00662 
00663   // JG: Added:
00664 
00666   RCP<const CrsGraph> getCrsGraph() const
00667   {
00668     TEUCHOS_TEST_FOR_EXCEPTION( true, Xpetra::Exceptions::RuntimeError,
00669         "getCrsGraph() not supported by BlockedCrsOperator!" );
00670     return Teuchos::null;
00671   }
00672 
00674 
00676 
00677 
00679   virtual size_t Rows() const { return rangemaps_->NumMaps(); }
00680 
00682   virtual size_t Cols() const { return domainmaps_->NumMaps(); }
00683 
00685   Teuchos::RCP<CrsMatrixClass> getMatrix(size_t r, size_t c) const { return blocks_[r*Cols()+c]; }
00686 
00688   void setMatrix(size_t r, size_t c, Teuchos::RCP<CrsMatrixClass>& mat)
00689   {
00690     // TODO: if filled -> return error
00691 
00692     TEUCHOS_TEST_FOR_EXCEPTION( r > Rows(), std::out_of_range, "Error, r = " << Rows() << " is too big" );
00693     TEUCHOS_TEST_FOR_EXCEPTION( c > Cols(), std::out_of_range, "Error, c = " << Cols() << " is too big" );
00694 
00695     // check row map
00696     //if (!rangemaps_->Map(r)->isSameAs(mat->getRowMap()))
00697     //  TEUCHOS_TEST_FOR_EXCEPTION( true, Xpetra::Exceptions::RuntimeError, "Error. row maps do not fit." );
00698 
00699     // set matrix
00700     blocks_[r*Cols()+c] = mat;
00701   }
00702 
00704   /*
00705    * This is a rather expensive operation, since all blocks are copied into a new big CrsMatrix
00706    */
00707   Teuchos::RCP<CrsMatrixClass> Merge() const
00708   {
00709     Teuchos::RCP<CrsMatrixClass> sparse = Teuchos::rcp_dynamic_cast<CrsMatrixClass>(Xpetra::CrsMatrixFactory<Scalar,LocalOrdinal,GlobalOrdinal>::Build(fullrowmap_,33));// Teuchos::rcp(new CrsMatrixClass(*fullrowmap_,33));
00710     for (size_t i=0; i<blocks_.size(); ++i)
00711     {
00712       Teuchos::RCP<CrsMatrixClass> block = Teuchos::rcp_dynamic_cast<CrsMatrixClass>(blocks_[i]);
00713       this->Add(block,ScalarTraits< Scalar >::one(),sparse,ScalarTraits< Scalar >::one());
00714     }
00715     sparse->fillComplete(getDomainMap(),getRangeMap());
00716     return sparse;
00717   }
00719 
00720 
00721 private:
00722 
00725 
00727 
00737   void Add(Teuchos::RCP<CrsMatrixClass>& A, const Scalar scalarA, Teuchos::RCP<CrsMatrixClass>& B, const Scalar scalarB) const
00738   {
00739     TEUCHOS_TEST_FOR_EXCEPTION( !A->isFillComplete(), Xpetra::Exceptions::RuntimeError,
00740         "Matrix A is not completed" );
00741 
00742     B->scale(scalarB);
00743 
00744     size_t MaxNumEntries = std::max(A->getNodeMaxNumRowEntries(),B->getNodeMaxNumRowEntries());
00745     std::vector<GlobalOrdinal> vecIndices(MaxNumEntries);
00746     std::vector<Scalar>        vecValues (MaxNumEntries);
00747 
00748     const Teuchos::ArrayView<GlobalOrdinal> Indices(&vecIndices[0], vecIndices.size());
00749     const Teuchos::ArrayView<Scalar>        Values (&vecValues[0],  vecValues.size());
00750     size_t NumEntries;
00751 
00752     Teuchos::ArrayView<const GlobalOrdinal> MyGlobalRowIds = A->getRowMap()->getNodeElementList(); // global row ids
00753 
00754     if(scalarA)
00755     {
00756       for(size_t i=0; i<A->getNodeNumRows(); ++i)
00757       {
00758         GlobalOrdinal Row = MyGlobalRowIds[i];
00759 
00760         //A->getGlobalRowCopy(Row, Indices, Values, NumEntries);
00761         A->getLocalRowCopy(i, Indices, Values, NumEntries);
00762 
00763         if(scalarA != ScalarTraits< Scalar >::one())
00764           for (size_t j=0; j<NumEntries; ++j)
00765             Values[j] *= scalarA;
00766 
00767 
00768 #if 0
00769         for (size_t j=0; j<NumEntries; ++j)
00770         {
00771           std::vector<GlobalOrdinal> tempVec; tempVec.push_back(Indices[j]);
00772           std::vector<Scalar> tempVal; tempVal.push_back(Values[j]);
00773           Teuchos::ArrayView<GlobalOrdinal> tempIndex(&tempVec[0], 1);
00774           Teuchos::ArrayView<Scalar>        tempValue(&tempVal[0],  1);
00775           B->insertGlobalValues(Row, tempIndex, tempValue); // insert should be ok, since blocks in BlockedCrsOpeartor do not overlap!
00776         }
00777 #else
00778 
00779         std::vector<GlobalOrdinal> tempvecIndices(NumEntries);
00780         std::copy(Indices.getRawPtr(),
00781             Indices.getRawPtr()+NumEntries,
00782             std::inserter(tempvecIndices,tempvecIndices.begin()));
00783         std::vector<Scalar> tempvecValues(NumEntries);
00784         std::copy(Values.getRawPtr(),
00785             Values.getRawPtr()+NumEntries,
00786             std::inserter(tempvecValues,tempvecValues.begin()));
00787         Teuchos::ArrayView<GlobalOrdinal> tempIndex(&tempvecIndices[0], NumEntries);
00788         Teuchos::ArrayView<Scalar>        tempValue(&tempvecValues[0],  NumEntries);
00789         B->insertGlobalValues(Row, tempIndex, tempValue); // insert should be ok, since blocks in BlockedCrsOpeartor do not overlap!
00790 #endif
00791 
00792 
00793       }
00794     }
00795   }
00796 
00798 
00799   // Default view is created after fillComplete()
00800   // Because ColMap might not be available before fillComplete().
00801   void CreateDefaultView() {
00802 
00803     // Create default view
00804     this->defaultViewLabel_ = "point";
00805     this->CreateView(this->GetDefaultViewLabel(), getRangeMap(), getDomainMap());
00806 
00807     // Set current view
00808     this->currentViewLabel_ = this->GetDefaultViewLabel();
00809   }
00810 
00811 private:
00812   // Teuchos::RCP<CrsMatrixClass> matrixData_;
00813 
00815   Teuchos::RCP<const MapExtractorClass> domainmaps_;
00816 
00818   Teuchos::RCP<const MapExtractorClass> rangemaps_;
00819 
00821   std::vector<Teuchos::RCP<CrsMatrixClass> > blocks_;
00822 
00824   Teuchos::RCP<MapClass> fullrowmap_;
00825 
00827   Teuchos::RCP<MapClass> fullcolmap_;
00828 
00829 
00830 }; //class BlockedCrsOperator
00831 
00832 } //namespace Xpetra
00833 
00834 #define XPETRA_BLOCKEDCRSOPERATOR_SHORT
00835 #endif /* XPETRA_BLOCKEDCRSOPERATOR_HPP_ */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines