All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
Xpetra_CrsOperator.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 // WARNING: This code is experimental. Backwards compatibility should not be expected.
00048 
00049 #ifndef XPETRA_CRSOPERATOR_HPP
00050 #define XPETRA_CRSOPERATOR_HPP
00051 
00052 #include <Kokkos_DefaultNode.hpp>
00053 #include <Kokkos_DefaultKernels.hpp>
00054 
00055 #include "Xpetra_ConfigDefs.hpp"
00056 #include "Xpetra_Exceptions.hpp"
00057 
00058 #include "Xpetra_MultiVector.hpp"
00059 #include "Xpetra_CrsGraph.hpp"
00060 #include "Xpetra_CrsMatrix.hpp"
00061 #include "Xpetra_CrsMatrixFactory.hpp"
00062 
00063 #include "Xpetra_Operator.hpp"
00064 
00065 #include <Teuchos_SerialDenseMatrix.hpp>
00066 #include <Teuchos_Hashtable.hpp>
00067 
00072 namespace Xpetra {
00073 
00074   typedef std::string viewLabel_t;
00075 
00080 template <class Scalar, 
00081           class LocalOrdinal  = int, 
00082           class GlobalOrdinal = LocalOrdinal, 
00083           class Node          = Kokkos::DefaultNode::DefaultNodeType, 
00084           class LocalMatOps   = typename Kokkos::DefaultKernels<Scalar,LocalOrdinal,Node>::SparseOps > //TODO: or BlockSparseOp ?
00085 class CrsOperator : public Operator<Scalar,LocalOrdinal,GlobalOrdinal,Node,LocalMatOps> {
00086 
00087   typedef Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node> Map;
00088   typedef Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalMatOps> CrsMatrix;
00089   typedef Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalMatOps> Operator;
00090   typedef Xpetra::CrsGraph<LocalOrdinal, GlobalOrdinal, Node, LocalMatOps> CrsGraph;
00091 #ifdef HAVE_XPETRA_TPETRA
00092   typedef Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalMatOps> TpetraCrsMatrix;
00093 #endif
00094   typedef Xpetra::CrsMatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node, LocalMatOps> CrsMatrixFactory;
00095   typedef Xpetra::OperatorView<LocalOrdinal, GlobalOrdinal, Node> OperatorView;
00096 
00097 public:
00098   
00100 
00101 
00103   CrsOperator(const RCP<const Map> &rowMap, size_t maxNumEntriesPerRow, Xpetra::ProfileType pftype = Xpetra::DynamicProfile)
00104     : finalDefaultView_(false)
00105   {
00106     // Set matrix data
00107     matrixData_ = CrsMatrixFactory::Build(rowMap, maxNumEntriesPerRow, pftype);
00108 
00109     // Default view
00110     CreateDefaultView();
00111   }
00112 
00114   CrsOperator(const RCP<const Map> &rowMap, const ArrayRCP<const size_t> &NumEntriesPerRowToAlloc, ProfileType pftype = Xpetra::DynamicProfile)
00115     : finalDefaultView_(false)
00116   {
00117     // Set matrix data
00118     matrixData_ = CrsMatrixFactory::Build(rowMap, NumEntriesPerRowToAlloc, pftype);
00119     
00120     // Default view
00121     CreateDefaultView();
00122   }
00123   
00124   CrsOperator(RCP<CrsMatrix> &matrix)
00125     : finalDefaultView_(matrix->isFillComplete())
00126   {
00127     // Set matrix data
00128     matrixData_ = matrix;
00129 
00130     // Default view
00131     CreateDefaultView();
00132   }
00133   
00135   virtual ~CrsOperator() {}
00136 
00138 
00139 
00141 
00142 
00144 
00155   void insertGlobalValues(GlobalOrdinal globalRow, const ArrayView<const GlobalOrdinal> &cols, const ArrayView<const Scalar> &vals) { 
00156     matrixData_->insertGlobalValues(globalRow, cols, vals);
00157   }
00158 
00160 
00167   void insertLocalValues(LocalOrdinal localRow, const ArrayView<const LocalOrdinal> &cols, const ArrayView<const Scalar> &vals) {
00168     matrixData_->insertLocalValues(localRow, cols, vals);
00169   }
00170 
00172 
00174 
00175 
00187   void fillComplete(const RCP<const Map> &domainMap, const RCP<const Map> &rangeMap, const RCP<Teuchos::ParameterList> &params = null) {
00188     matrixData_->fillComplete(domainMap, rangeMap, params);
00189 
00190     // Update default view with the colMap because colMap can be <tt>null</tt> until fillComplete() is called.
00191     updateDefaultView();
00192   }
00193 
00207   //TODO : Get ride of "Tpetra"::OptimizeOption
00208   void fillComplete(const RCP<ParameterList> &params = null) {
00209     matrixData_->fillComplete(params);
00210 
00211     // Update default view with the colMap because colMap can be <tt>null</tt> until fillComplete() is called.
00212     updateDefaultView();
00213   }
00214 
00216 
00218 
00220   global_size_t getGlobalNumRows() const { 
00221     return matrixData_->getGlobalNumRows();
00222   }
00223 
00225 
00227   global_size_t getGlobalNumCols() const {
00228     return matrixData_->getGlobalNumCols();
00229   }
00230 
00232   size_t getNodeNumRows() const {
00233     return matrixData_->getNodeNumRows();
00234   }
00235 
00237   global_size_t getGlobalNumEntries() const {
00238     return matrixData_->getGlobalNumEntries();
00239   }
00240 
00242   size_t getNodeNumEntries() const {
00243     return matrixData_->getNodeNumEntries();
00244   }
00245 
00247 
00248   size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const {
00249     return matrixData_->getNumEntriesInLocalRow(localRow);
00250   }
00251 
00253 
00255   global_size_t getGlobalNumDiags() const {
00256     return matrixData_->getGlobalNumDiags();
00257   }
00258 
00260 
00262   size_t getNodeNumDiags() const {
00263     return matrixData_->getNodeNumDiags();
00264   }
00265 
00267 
00269   size_t getGlobalMaxNumRowEntries() const {
00270     return matrixData_->getGlobalMaxNumRowEntries();
00271   }
00272 
00274 
00276   size_t getNodeMaxNumRowEntries() const {
00277     return matrixData_->getNodeMaxNumRowEntries();
00278   }
00279 
00281   bool isLocallyIndexed() const {
00282     return matrixData_->isLocallyIndexed();
00283   }
00284 
00286   bool isGloballyIndexed() const {
00287     return matrixData_->isGloballyIndexed();
00288   }
00289 
00291   bool isFillComplete() const {
00292     return matrixData_->isFillComplete();
00293   }
00294 
00296 
00308   void getLocalRowCopy(LocalOrdinal LocalRow, 
00309                        const ArrayView<LocalOrdinal> &Indices, 
00310                        const ArrayView<Scalar> &Values,
00311                        size_t &NumEntries
00312                        ) const {
00313     matrixData_->getLocalRowCopy(LocalRow, Indices, Values, NumEntries);
00314   }
00315   
00317 
00326   void getGlobalRowView(GlobalOrdinal GlobalRow, ArrayView<const GlobalOrdinal> &indices, ArrayView<const Scalar> &values) const {
00327      matrixData_->getGlobalRowView(GlobalRow, indices, values);
00328   }
00329 
00331 
00340   void getLocalRowView(LocalOrdinal LocalRow, ArrayView<const LocalOrdinal> &indices, ArrayView<const Scalar> &values) const {
00341      matrixData_->getLocalRowView(LocalRow, indices, values);
00342   }
00343 
00345 
00347   void getLocalDiagCopy(Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &diag) const {
00348     matrixData_->getLocalDiagCopy(diag);
00349   }
00350 
00352   typename ScalarTraits<Scalar>::magnitudeType getFrobeniusNorm() const {
00353     return matrixData_->getFrobeniusNorm();
00354   }
00355 
00357 
00359 
00360 
00362 
00371   //TODO virtual=0 // TODO: Add default parameters ?
00372 //   void multiply(const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> & X, MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &Y, Teuchos::ETransp trans, Scalar alpha, Scalar beta) const {
00373 //      matrixData_->multiply(X, Y, trans, alpha, beta);
00374 //   }
00375 
00377 
00379 
00380 
00382 
00385   void apply(const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> & X, MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &Y, 
00386              Teuchos::ETransp mode = Teuchos::NO_TRANS,
00387              Scalar alpha = ScalarTraits<Scalar>::one(),
00388              Scalar beta = ScalarTraits<Scalar>::zero()) const {
00389 
00390     matrixData_->apply(X,Y,mode,alpha,beta);
00391   }
00392   
00395   const RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > getDomainMap() const {
00396     return matrixData_->getDomainMap();
00397   }
00398 
00401   const RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > getRangeMap() const {
00402     return matrixData_->getRangeMap();
00403   }
00404 
00407   const RCP<const Map> & getColMap() const { return getColMap(Operator::GetCurrentViewLabel()); }
00408   
00410   const RCP<const Map> & getColMap(viewLabel_t viewLabel) const { 
00411     TEUCHOS_TEST_FOR_EXCEPTION(Operator::operatorViewTable_.containsKey(viewLabel) == false, Xpetra::Exceptions::RuntimeError, "Xpetra::Operator.GetColMap(): view '" + viewLabel + "' does not exist.");
00412     updateDefaultView(); // If CrsMatrix::fillComplete() have been used instead of CrsOperator::fillComplete(), the default view is updated.
00413     return Operator::operatorViewTable_.get(viewLabel)->GetColMap(); 
00414   }
00415   
00417 
00419 
00420   
00422   std::string description() const {
00423     return "Xpetra_CrsOperator.description()";
00424   }
00425   
00427   void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const { 
00428     //     Teuchos::EVerbosityLevel vl = verbLevel;
00429     //     if (vl == VERB_DEFAULT) vl = VERB_LOW;
00430     //     RCP<const Comm<int> > comm = this->getComm();
00431     //     const int myImageID = comm->getRank(),
00432     //       numImages = comm->getSize();
00433     
00434     //     if (myImageID == 0) out << this->description() << std::endl; 
00435     
00436     matrixData_->describe(out,verbLevel);
00437 
00438     // Teuchos::OSTab tab(out);
00439   }
00440 
00441   // JG: Added:
00442 
00444   RCP<const CrsGraph> getCrsGraph() const { return matrixData_->getCrsGraph(); }
00445 
00446   RCP<CrsMatrix> getCrsMatrix() const {  return matrixData_; }
00447 
00449   
00450 
00451 private:
00452 
00453   // Default view is created after fillComplete()
00454   // Because ColMap might not be available before fillComplete(). 
00455   void CreateDefaultView() {
00456     
00457     // Create default view
00458     this->defaultViewLabel_ = "point";
00459     this->CreateView(this->GetDefaultViewLabel(), matrixData_->getRowMap(), matrixData_->getColMap());    
00460     
00461     // Set current view
00462     this->currentViewLabel_ = this->GetDefaultViewLabel();
00463   }
00464 
00465 private:
00466 
00467   // The colMap can be <tt>null</tt> until fillComplete() is called. The default view of the Operator have to be updated when fillComplete() is called. 
00468   // If CrsMatrix::fillComplete() have been used instead of CrsOperator::fillComplete(), the default view is updated when getColMap() is called.
00469   void updateDefaultView() const {
00470     if ((finalDefaultView_ == false) &&  matrixData_->isFillComplete() ) {
00471       // Update default view with the colMap
00472       Operator::operatorViewTable_.get(Operator::GetDefaultViewLabel())->SetColMap(matrixData_->getColMap());
00473       finalDefaultView_ = true;
00474     }
00475   }
00476   // The boolean finalDefaultView_ keep track of the status of the default view (= already updated or not)
00477   // See also CrsOperator::updateDefaultView()
00478   mutable bool finalDefaultView_;
00479 
00480 
00481   RCP<CrsMatrix> matrixData_;
00482 
00483 }; //class Operator
00484 
00485 } //namespace Xpetra
00486 
00487 #define XPETRA_CRSOPERATOR_SHORT
00488 #endif //XPETRA_CRSOPERATOR_DECL_HPP
00489 
00490 //NOTE: if CrsMatrix and VbrMatrix share a common interface for fillComplete() etc, I can move some stuff in Xpetra_Operator.hpp
00491 //TODO: getUnderlyingMatrix() method
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines