00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
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
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);
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
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 > ¶ms=null) = 0;
00284
00296 virtual void fillComplete(const RCP<const Map> &domainMap, const RCP<const Map> &rangeMap, const RCP<ParameterList> ¶ms = null) =0;
00297
00311
00312 virtual void fillComplete(const RCP<ParameterList> ¶ms=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
00457
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
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
00515
00516
00517
00518
00519
00520
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
00536
00538 virtual RCP<const CrsGraph> getCrsGraph() const =0;
00539
00540
00541
00542
00543 void SetFixedBlockSize(LocalOrdinal blksize) {
00544
00545 TEUCHOS_TEST_FOR_EXCEPTION(isFillComplete() == false, Exceptions::RuntimeError, "Xpetra::Matrix::SetFixedBlockSize(): operator is not filled and completed.");
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());
00576 } else
00577
00578 return 1;
00579 };
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_;
00599 viewLabel_t currentViewLabel_;
00600
00601 };
00602
00603 }
00604
00605 #define XPETRA_MATRIX_SHORT
00606 #endif //XPETRA_MATRIX_DECL_HPP