All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
Xpetra_Matrix.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 //                    Jonathan Hu       (jhu@sandia.gov)
00040 //                    Andrey Prokopenko (aprokop@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_MATRIX_HPP
00050 #define XPETRA_MATRIX_HPP
00051 
00052 #include <Kokkos_DefaultNode.hpp>
00053 
00054 #include "Xpetra_ConfigDefs.hpp"
00055 #include "Xpetra_Exceptions.hpp"
00056 
00057 #include "Xpetra_MultiVector.hpp"
00058 #include "Xpetra_CrsGraph.hpp"
00059 #include "Xpetra_CrsMatrix.hpp"
00060 #include "Xpetra_CrsMatrixFactory.hpp"
00061 #include "Xpetra_MatrixView.hpp"
00062 #include "Xpetra_StridedMap.hpp"
00063 #include "Xpetra_StridedMapFactory.hpp"
00064 
00065 #include <Teuchos_SerialDenseMatrix.hpp>
00066 #include <Teuchos_Hashtable.hpp>
00067 
00072 namespace Xpetra {
00073 
00090   typedef std::string viewLabel_t;
00091 
00092   template <class Scalar = MultiVector<>::scalar_type,
00093             class LocalOrdinal = Map<>::local_ordinal_type,
00094             class GlobalOrdinal =
00095               typename Map<LocalOrdinal>::global_ordinal_type,
00096             class Node =
00097               typename Map<LocalOrdinal, GlobalOrdinal>::node_type>
00098   class Matrix : virtual public Teuchos::Describable {
00099     typedef Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node> Map;
00100     typedef Xpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> CrsMatrix;
00101     typedef Xpetra::CrsGraph<LocalOrdinal, GlobalOrdinal, Node> CrsGraph;
00102 #ifdef HAVE_XPETRA_TPETRA
00103     typedef Xpetra::TpetraCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> TpetraCrsMatrix;
00104 #endif
00105     typedef Xpetra::CrsMatrixFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node> CrsMatrixFactory;
00106     typedef Xpetra::MatrixView<Scalar, LocalOrdinal, GlobalOrdinal, Node> MatrixView;
00107 
00108   public:
00109     typedef Scalar scalar_type;
00110     typedef LocalOrdinal local_ordinal_type;
00111     typedef GlobalOrdinal global_ordinal_type;
00112     typedef Node node_type;
00113 
00115 
00116 
00117     Matrix() { }
00118 
00120     virtual ~Matrix() { }
00121 
00123 
00125 
00126     void CreateView(viewLabel_t viewLabel, const RCP<const Map> & rowMap, const RCP<const Map> & colMap) {
00127       TEUCHOS_TEST_FOR_EXCEPTION(operatorViewTable_.containsKey(viewLabel) == true, Xpetra::Exceptions::RuntimeError, "Xpetra::Matrix.CreateView(): a view labeled '" + viewLabel + "' already exist.");
00128       RCP<MatrixView> view = rcp(new MatrixView(rowMap, colMap));
00129       operatorViewTable_.put(viewLabel, view);
00130     }
00131 
00132     // JG TODO: why this is a member function??
00133     void CreateView(const viewLabel_t viewLabel, const RCP<const Matrix>& A, bool transposeA = false, const RCP<const Matrix>& B = Teuchos::null, bool transposeB = false) {
00134       RCP<const Map> domainMap = Teuchos::null;
00135       RCP<const Map> rangeMap  = Teuchos::null;
00136 
00137       typedef Xpetra::StridedMapFactory<LocalOrdinal, GlobalOrdinal, Node> StridedMapFactory;
00138 
00139       const size_t        blkSize = 1;
00140       std::vector<size_t> stridingInfo(1, blkSize);
00141       LocalOrdinal        stridedBlockId = -1;
00142 
00143 
00144       if (A->IsView(viewLabel)) {
00145         rangeMap  = transposeA ? A->getColMap(viewLabel) : A->getRowMap(viewLabel);
00146         domainMap = transposeA ? A->getRowMap(viewLabel) : A->getColMap(viewLabel); // will be overwritten if B != Teuchos::null
00147 
00148       } else {
00149         rangeMap  = transposeA ? A->getDomainMap()       : A->getRangeMap();
00150         domainMap = transposeA ? A->getRangeMap()        : A->getDomainMap();
00151 
00152         if (viewLabel == "stridedMaps") {
00153           rangeMap  = StridedMapFactory::Build(rangeMap,  stridingInfo, stridedBlockId);
00154           domainMap = StridedMapFactory::Build(domainMap, stridingInfo, stridedBlockId);
00155         }
00156       }
00157 
00158       if (B != Teuchos::null ) {
00159         // B has strided Maps
00160 
00161         if (B->IsView(viewLabel)) {
00162           domainMap = transposeB ? B->getRowMap(viewLabel) : B->getColMap(viewLabel);
00163 
00164         } else {
00165           domainMap = transposeB ? B->getRangeMap()        : B->getDomainMap();
00166 
00167           if (viewLabel == "stridedMaps")
00168             domainMap = StridedMapFactory::Build(domainMap, stridingInfo, stridedBlockId);
00169         }
00170       }
00171 
00172 
00173       if (IsView(viewLabel))
00174         RemoveView(viewLabel);
00175 
00176       CreateView(viewLabel, rangeMap, domainMap);
00177     }
00178 
00180     void PrintViews(Teuchos::FancyOStream &out) const {
00181       int last = out.getOutputToRootOnly();
00182       Teuchos::OSTab tab(out);
00183       out.setOutputToRootOnly(0);
00184       Teuchos::Array<viewLabel_t> viewLabels;
00185       Teuchos::Array<RCP<MatrixView> > viewList;
00186       operatorViewTable_.arrayify(viewLabels,viewList);
00187       out << "views associated with this operator" << std::endl;
00188       for (int i=0; i<viewLabels.size(); ++i)
00189         out << viewLabels[i] << std::endl;
00190       out.setOutputToRootOnly(last);
00191     }
00192 
00193 
00194     void RemoveView(const viewLabel_t viewLabel) {
00195       TEUCHOS_TEST_FOR_EXCEPTION(operatorViewTable_.containsKey(viewLabel) == false, Xpetra::Exceptions::RuntimeError, "Xpetra::Matrix.RemoveView(): view '" + viewLabel + "' does not exist.");
00196       TEUCHOS_TEST_FOR_EXCEPTION(viewLabel == GetDefaultViewLabel(), Xpetra::Exceptions::RuntimeError, "Xpetra::Matrix.RemoveView(): view '" + viewLabel + "' is the default view and cannot be removed.");
00197       operatorViewTable_.remove(viewLabel);
00198     }
00199 
00200     const viewLabel_t SwitchToView(const viewLabel_t viewLabel) {
00201       TEUCHOS_TEST_FOR_EXCEPTION(operatorViewTable_.containsKey(viewLabel) == false, Xpetra::Exceptions::RuntimeError, "Xpetra::Matrix.SwitchToView(): view '" + viewLabel + "' does not exist.");
00202       viewLabel_t oldViewLabel = GetCurrentViewLabel();
00203       currentViewLabel_ = viewLabel;
00204       return oldViewLabel;
00205     }
00206 
00207     bool IsView(const viewLabel_t viewLabel) const {
00208       return operatorViewTable_.containsKey(viewLabel);
00209     }
00210 
00211     const viewLabel_t SwitchToDefaultView() { return SwitchToView(GetDefaultViewLabel()); }
00212 
00213     const viewLabel_t & GetDefaultViewLabel() const { return defaultViewLabel_; }
00214 
00215     const viewLabel_t & GetCurrentViewLabel() const { return currentViewLabel_; }
00216 
00218 
00220 
00221 
00223 
00234     virtual void insertGlobalValues(GlobalOrdinal globalRow, const ArrayView<const GlobalOrdinal> &cols, const ArrayView<const Scalar> &vals) = 0;
00235 
00237 
00244     virtual void insertLocalValues(LocalOrdinal localRow, const ArrayView<const LocalOrdinal> &cols, const ArrayView<const Scalar> &vals) = 0;
00245 
00247 
00252     virtual void replaceGlobalValues(GlobalOrdinal globalRow,
00253                                      const ArrayView<const GlobalOrdinal> &cols,
00254                                      const ArrayView<const Scalar>        &vals) = 0;
00255 
00257 
00260     virtual void replaceLocalValues(LocalOrdinal localRow,
00261                                     const ArrayView<const LocalOrdinal> &cols,
00262                                     const ArrayView<const Scalar>       &vals) = 0;
00263 
00265     virtual void setAllToScalar(const Scalar &alpha)= 0;
00266 
00268     virtual void scale(const Scalar &alpha)= 0;
00269 
00271 
00273 
00274 
00283     virtual void resumeFill(const RCP< ParameterList > &params=null) = 0;
00284 
00296     virtual void fillComplete(const RCP<const Map> &domainMap, const RCP<const Map> &rangeMap, const RCP<ParameterList> &params = null) =0;
00297 
00311     //TODO : Get ride of "Tpetra"::OptimizeOption
00312     virtual void fillComplete(const RCP<ParameterList> &params=null) =0;
00313 
00315 
00317 
00318 
00320     virtual const RCP<const Map> & getRowMap() const { return getRowMap(GetCurrentViewLabel()); }
00321 
00323     virtual const RCP<const Map> & getRowMap(viewLabel_t viewLabel) const {
00324       TEUCHOS_TEST_FOR_EXCEPTION(operatorViewTable_.containsKey(viewLabel) == false, Xpetra::Exceptions::RuntimeError, "Xpetra::Matrix.GetRowMap(): view '" + viewLabel + "' does not exist.");
00325       return operatorViewTable_.get(viewLabel)->GetRowMap();
00326     }
00327 
00330     virtual const RCP<const Map> & getColMap() const { return getColMap(GetCurrentViewLabel()); }
00331 
00333     virtual const RCP<const Map> & getColMap(viewLabel_t viewLabel) const {
00334       TEUCHOS_TEST_FOR_EXCEPTION(operatorViewTable_.containsKey(viewLabel) == false, Xpetra::Exceptions::RuntimeError, "Xpetra::Matrix.GetColMap(): view '" + viewLabel + "' does not exist.");
00335       return operatorViewTable_.get(viewLabel)->GetColMap();
00336     }
00337 
00339 
00341     virtual global_size_t getGlobalNumRows() const =0;
00342 
00344 
00346     virtual global_size_t getGlobalNumCols() const =0;
00347 
00349     virtual size_t getNodeNumRows() const =0;
00350 
00352     virtual global_size_t getGlobalNumEntries() const =0;
00353 
00355     virtual size_t getNodeNumEntries() const =0;
00356 
00358 
00359     virtual size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const =0;
00360 
00362 
00364     virtual global_size_t getGlobalNumDiags() const =0;
00365 
00367 
00369     virtual size_t getNodeNumDiags() const =0;
00370 
00372 
00374     virtual size_t getGlobalMaxNumRowEntries() const =0;
00375 
00377 
00379     virtual size_t getNodeMaxNumRowEntries() const =0;
00380 
00382     virtual bool isLocallyIndexed() const =0;
00383 
00385     virtual bool isGloballyIndexed() const =0;
00386 
00388     virtual bool isFillComplete() const =0;
00389 
00391 
00403     virtual void getLocalRowCopy(LocalOrdinal LocalRow,
00404                                  const ArrayView<LocalOrdinal> &Indices,
00405                                  const ArrayView<Scalar> &Values,
00406                                  size_t &NumEntries
00407                                  ) const =0;
00408 
00410 
00419     virtual void getGlobalRowView(GlobalOrdinal GlobalRow, ArrayView<const GlobalOrdinal> &indices, ArrayView<const Scalar> &values) const =0;
00420 
00422 
00431     virtual void getLocalRowView(LocalOrdinal LocalRow, ArrayView<const LocalOrdinal> &indices, ArrayView<const Scalar> &values) const =0;
00432 
00434 
00436     virtual void getLocalDiagCopy(Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &diag) const =0;
00437 
00439     virtual typename ScalarTraits<Scalar>::magnitudeType getFrobeniusNorm() const = 0;
00440 
00442 
00444 
00445 
00447 
00456     //TODO virtual=0 // TODO: Add default parameters ?
00457 //     virtual void multiply(const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> & X, MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &Y, Teuchos::ETransp trans, Scalar alpha, Scalar beta) const=0;
00458 
00460 
00462 
00463 
00465 
00468     virtual void apply(const MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> & X, MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &Y,
00469                        Teuchos::ETransp mode = Teuchos::NO_TRANS,
00470                        Scalar alpha = ScalarTraits<Scalar>::one(),
00471                        Scalar beta = ScalarTraits<Scalar>::zero()) const =0;
00472 
00475     virtual const RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > getDomainMap() const =0;
00476 
00479     virtual const RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal,Node> > getRangeMap() const =0;
00480 
00481     virtual void removeEmptyProcessesInPlace(const RCP<const Xpetra::Map<LocalOrdinal,GlobalOrdinal, Node> >& newMap) = 0;
00482 
00484 
00486     //{@
00487 
00489     virtual const Teuchos::RCP< const Xpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > getMap() const =0;
00490 
00491     // TODO: first argument of doImport/doExport should be a Xpetra::DistObject
00492 
00494     virtual void doImport(const Matrix &source,
00495                           const Import< LocalOrdinal, GlobalOrdinal, Node > &importer, CombineMode CM) =0;
00496 
00498     virtual void doExport(const Matrix &dest,
00499                           const Import< LocalOrdinal, GlobalOrdinal, Node >& importer, CombineMode CM) =0;
00500 
00502     virtual void doImport(const Matrix &source,
00503                           const Export< LocalOrdinal, GlobalOrdinal, Node >& exporter, CombineMode CM) =0;
00504 
00506     virtual void doExport(const Matrix &dest,
00507                           const Export< LocalOrdinal, GlobalOrdinal, Node >& exporter, CombineMode CM) =0;
00508 
00509     // @}
00510 
00512 
00513 
00514     // TODO: describe of views can be done here
00515 
00516     //   /** \brief Return a simple one-line description of this object. */
00517     //   virtual std::string description() const =0;
00518 
00519     //   /** \brief Print the object with some verbosity level to an FancyOStream object. */
00520     //   virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const =0;
00521 
00523 
00524 
00526 
00527 
00529     virtual std::string description() const =0;
00530 
00532     virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const =0;
00534 
00535     // JG: Added:
00536 
00538     virtual RCP<const CrsGraph> getCrsGraph() const =0;
00539 
00540     // ----------------------------------------------------------------------------------
00541     // "TEMPORARY" VIEW MECHANISM
00542     // TODO: the view mechanism should be implemented as in MueMat.
00543     void SetFixedBlockSize(LocalOrdinal blksize) {
00544 
00545       TEUCHOS_TEST_FOR_EXCEPTION(isFillComplete() == false, Exceptions::RuntimeError, "Xpetra::Matrix::SetFixedBlockSize(): operator is not filled and completed."); // TODO: do we need this? we just wanna "copy" the domain and range map
00546 
00547       std::vector<size_t> stridingInfo;
00548       stridingInfo.push_back(Teuchos::as<size_t>(blksize));
00549       LocalOrdinal stridedBlockId = -1;
00550 
00551       RCP<const Xpetra::StridedMap<LocalOrdinal, GlobalOrdinal, Node> > stridedRangeMap = Xpetra::StridedMapFactory<LocalOrdinal, GlobalOrdinal, Node>::Build(
00552                                                     getRangeMap(),
00553                                                     stridingInfo,
00554                                                     stridedBlockId
00555                                                     );
00556       RCP<const Map> stridedDomainMap = Xpetra::StridedMapFactory<LocalOrdinal, GlobalOrdinal, Node>::Build(
00557                                               getDomainMap(),
00558                                               stridingInfo,
00559                                               stridedBlockId
00560                                               );
00561 
00562       if(IsView("stridedMaps") == true) RemoveView("stridedMaps");
00563       CreateView("stridedMaps", stridedRangeMap, stridedDomainMap);
00564     }
00565 
00566     //==========================================================================
00567 
00568     LocalOrdinal GetFixedBlockSize() const {
00569       if(IsView("stridedMaps")==true) {
00570         Teuchos::RCP<const StridedMap<LocalOrdinal, GlobalOrdinal, Node> > rangeMap = Teuchos::rcp_dynamic_cast<const StridedMap<LocalOrdinal, GlobalOrdinal, Node> >(getRowMap("stridedMaps"));
00571         Teuchos::RCP<const StridedMap<LocalOrdinal, GlobalOrdinal, Node> > domainMap = Teuchos::rcp_dynamic_cast<const StridedMap<LocalOrdinal, GlobalOrdinal, Node> >(getColMap("stridedMaps"));
00572         TEUCHOS_TEST_FOR_EXCEPTION(rangeMap  == Teuchos::null, Exceptions::BadCast, "Xpetra::Matrix::GetFixedBlockSize(): rangeMap is not of type StridedMap");
00573         TEUCHOS_TEST_FOR_EXCEPTION(domainMap == Teuchos::null, Exceptions::BadCast, "Xpetra::Matrix::GetFixedBlockSize(): domainMap is not of type StridedMap");
00574         TEUCHOS_TEST_FOR_EXCEPTION(domainMap->getFixedBlockSize() != rangeMap->getFixedBlockSize(), Exceptions::RuntimeError, "Xpetra::Matrix::GetFixedBlockSize(): block size of rangeMap and domainMap are different.");
00575         return Teuchos::as<LocalOrdinal>(domainMap->getFixedBlockSize()); // TODO: why LocalOrdinal?
00576       } else
00577         //TEUCHOS_TEST_FOR_EXCEPTION(false, Exceptions::RuntimeError, "Xpetra::Matrix::GetFixedBlockSize(): no strided maps available."); // TODO remove this
00578         return 1;
00579     }; //TODO: why LocalOrdinal?
00580 
00581     // ----------------------------------------------------------------------------------
00582 
00583     virtual void SetMaxEigenvalueEstimate(Scalar const &sigma) {
00584       operatorViewTable_.get(GetCurrentViewLabel())->SetMaxEigenvalueEstimate(sigma);
00585     }
00586 
00587     // ----------------------------------------------------------------------------------
00588 
00589     virtual Scalar GetMaxEigenvalueEstimate() const {
00590       return operatorViewTable_.get(GetCurrentViewLabel())->GetMaxEigenvalueEstimate();
00591     }
00592 
00593     // ----------------------------------------------------------------------------------
00594 
00595     protected:
00596       Teuchos::Hashtable<viewLabel_t, RCP<MatrixView> > operatorViewTable_; // hashtable storing the operator views (keys = view names, values = views).
00597 
00598       viewLabel_t defaultViewLabel_;  // label of the view associated with inital Matrix construction
00599       viewLabel_t currentViewLabel_;  // label of the current view
00600 
00601   }; //class Matrix
00602 
00603 } //namespace Xpetra
00604 
00605 #define XPETRA_MATRIX_SHORT
00606 #endif //XPETRA_MATRIX_DECL_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines