Xpetra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Xpetra_Matrix_def.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Xpetra: A linear algebra interface package
4 //
5 // Copyright 2012 NTESS and the Xpetra contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 // WARNING: This code is experimental. Backwards compatibility should not be expected.
11 
12 #ifndef XPETRA_MATRIX_DEF_HPP
13 #define XPETRA_MATRIX_DEF_HPP
14 
15 #include <Tpetra_KokkosCompat_DefaultNode.hpp>
16 
17 #include "Xpetra_ConfigDefs.hpp"
18 #include "Xpetra_Exceptions.hpp"
19 #include "Xpetra_Matrix_decl.hpp"
20 #include "Xpetra_MultiVector.hpp"
21 #include "Xpetra_CrsGraph.hpp"
22 #include "Xpetra_CrsMatrix.hpp"
24 #include "Xpetra_MatrixView.hpp"
25 #include "Xpetra_Operator.hpp"
26 #include "Xpetra_StridedMap.hpp"
27 #include "Xpetra_StridedMapFactory.hpp"
28 
29 #include <Teuchos_SerialDenseMatrix.hpp>
30 #include <Teuchos_Hashtable.hpp>
31 
32 namespace Xpetra {
33 
34 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
36 
37 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
39 
40 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
41 void Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::CreateView(viewLabel_t viewLabel, const RCP<const Map> &rowMap, const RCP<const Map> &colMap) {
42  TEUCHOS_TEST_FOR_EXCEPTION(operatorViewTable_.containsKey(viewLabel) == true, Xpetra::Exceptions::RuntimeError, "Xpetra::Matrix.CreateView(): a view labeled '" + viewLabel + "' already exist.");
43  RCP<MatrixView> view = rcp(new MatrixView(rowMap, colMap));
44  operatorViewTable_.put(viewLabel, view);
45 }
46 
47 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
48 void Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::CreateView(const viewLabel_t viewLabel, const RCP<const Matrix> &A, bool transposeA, const RCP<const Matrix> &B, bool transposeB) {
49  RCP<const Map> domainMap = Teuchos::null;
50  RCP<const Map> rangeMap = Teuchos::null;
51 
52  const size_t blkSize = 1;
53  std::vector<size_t> stridingInfo(1, blkSize);
54  LocalOrdinal stridedBlockId = -1;
55 
56  if (A->IsView(viewLabel)) {
57  rangeMap = transposeA ? A->getColMap(viewLabel) : A->getRowMap(viewLabel);
58  domainMap = transposeA ? A->getRowMap(viewLabel) : A->getColMap(viewLabel); // will be overwritten if B != Teuchos::null
59 
60  } else {
61  rangeMap = transposeA ? A->getDomainMap() : A->getRangeMap();
62  domainMap = transposeA ? A->getRangeMap() : A->getDomainMap();
63 
64  if (viewLabel == "stridedMaps") {
65  rangeMap = Xpetra::StridedMapFactory<LocalOrdinal, GlobalOrdinal, Node>::Build(rangeMap, stridingInfo, stridedBlockId);
66  domainMap = Xpetra::StridedMapFactory<LocalOrdinal, GlobalOrdinal, Node>::Build(domainMap, stridingInfo, stridedBlockId);
67  }
68  }
69 
70  if (B != Teuchos::null) {
71  // B has strided Maps
72 
73  if (B->IsView(viewLabel)) {
74  domainMap = transposeB ? B->getRowMap(viewLabel) : B->getColMap(viewLabel);
75 
76  } else {
77  domainMap = transposeB ? B->getRangeMap() : B->getDomainMap();
78 
79  if (viewLabel == "stridedMaps")
80  domainMap = Xpetra::StridedMapFactory<LocalOrdinal, GlobalOrdinal, Node>::Build(domainMap, stridingInfo, stridedBlockId);
81  }
82  }
83 
84  if (IsView(viewLabel))
85  RemoveView(viewLabel);
86 
87  CreateView(viewLabel, rangeMap, domainMap);
88 }
89 
90 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
92  int last = out.getOutputToRootOnly();
93  Teuchos::OSTab tab(out);
94  out.setOutputToRootOnly(0);
95  Teuchos::Array<viewLabel_t> viewLabels;
96  Teuchos::Array<RCP<MatrixView>> viewList;
97  operatorViewTable_.arrayify(viewLabels, viewList);
98  out << "views associated with this operator" << std::endl;
99  for (int i = 0; i < viewLabels.size(); ++i)
100  out << viewLabels[i] << std::endl;
101  out.setOutputToRootOnly(last);
102 }
103 
104 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
106  TEUCHOS_TEST_FOR_EXCEPTION(operatorViewTable_.containsKey(viewLabel) == false, Xpetra::Exceptions::RuntimeError, "Xpetra::Matrix.RemoveView(): view '" + viewLabel + "' does not exist.");
107  TEUCHOS_TEST_FOR_EXCEPTION(viewLabel == GetDefaultViewLabel(), Xpetra::Exceptions::RuntimeError, "Xpetra::Matrix.RemoveView(): view '" + viewLabel + "' is the default view and cannot be removed.");
108  operatorViewTable_.remove(viewLabel);
109 }
110 
111 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
113  TEUCHOS_TEST_FOR_EXCEPTION(operatorViewTable_.containsKey(viewLabel) == false, Xpetra::Exceptions::RuntimeError, "Xpetra::Matrix.SwitchToView(): view '" + viewLabel + "' does not exist.");
114  viewLabel_t oldViewLabel = GetCurrentViewLabel();
115  currentViewLabel_ = viewLabel;
116  return oldViewLabel;
117 }
118 
119 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
121  return operatorViewTable_.containsKey(viewLabel);
122 }
123 
124 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
125 const std::string Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::SwitchToDefaultView() { return SwitchToView(GetDefaultViewLabel()); }
126 
127 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
128 const std::string &Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::GetDefaultViewLabel() const { return defaultViewLabel_; }
129 
130 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
131 const std::string &Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::GetCurrentViewLabel() const { return currentViewLabel_; }
132 
133 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
134 const RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> &Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::getRowMap() const { return getRowMap(GetCurrentViewLabel()); }
135 
136 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
137 const RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> &Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::getRowMap(viewLabel_t viewLabel) const {
138  TEUCHOS_TEST_FOR_EXCEPTION(operatorViewTable_.containsKey(viewLabel) == false, Xpetra::Exceptions::RuntimeError, "Xpetra::Matrix.GetRowMap(): view '" + viewLabel + "' does not exist.");
139  return operatorViewTable_.get(viewLabel)->GetRowMap();
140 }
141 
142 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
143 const RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> &Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::getColMap() const { return getColMap(GetCurrentViewLabel()); }
144 
145 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
146 const RCP<const Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node>> &Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>::getColMap(viewLabel_t viewLabel) const {
147  TEUCHOS_TEST_FOR_EXCEPTION(operatorViewTable_.containsKey(viewLabel) == false, Xpetra::Exceptions::RuntimeError, "Xpetra::Matrix.GetColMap(): view '" + viewLabel + "' does not exist.");
148  return operatorViewTable_.get(viewLabel)->GetColMap();
149 }
150 
151 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
153  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
154  std::vector<size_t> stridingInfo;
155  stridingInfo.push_back(Teuchos::as<size_t>(blksize));
156  LocalOrdinal stridedBlockId = -1;
157 
158  RCP<const Xpetra::StridedMap<LocalOrdinal, GlobalOrdinal, Node>> stridedRangeMap = Xpetra::StridedMapFactory<LocalOrdinal, GlobalOrdinal, Node>::Build(
159  this->getRangeMap(),
160  stridingInfo,
161  stridedBlockId,
162  offset);
164  this->getDomainMap(),
165  stridingInfo,
166  stridedBlockId,
167  offset);
168 
169  if (IsFixedBlockSizeSet()) RemoveView("stridedMaps");
170  CreateView("stridedMaps", stridedRangeMap, stridedDomainMap);
171 }
172 
173 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
175  if (IsFixedBlockSizeSet()) {
176  Teuchos::RCP<const StridedMap<LocalOrdinal, GlobalOrdinal, Node>> rangeMap = Teuchos::rcp_dynamic_cast<const StridedMap<LocalOrdinal, GlobalOrdinal, Node>>(getRowMap("stridedMaps"));
177  Teuchos::RCP<const StridedMap<LocalOrdinal, GlobalOrdinal, Node>> domainMap = Teuchos::rcp_dynamic_cast<const StridedMap<LocalOrdinal, GlobalOrdinal, Node>>(getColMap("stridedMaps"));
178  TEUCHOS_TEST_FOR_EXCEPTION(rangeMap == Teuchos::null, Exceptions::BadCast, "Xpetra::Matrix::GetFixedBlockSize(): rangeMap is not of type StridedMap");
179  TEUCHOS_TEST_FOR_EXCEPTION(domainMap == Teuchos::null, Exceptions::BadCast, "Xpetra::Matrix::GetFixedBlockSize(): domainMap is not of type StridedMap");
180  TEUCHOS_TEST_FOR_EXCEPTION(domainMap->getFixedBlockSize() != rangeMap->getFixedBlockSize(), Exceptions::RuntimeError, "Xpetra::Matrix::GetFixedBlockSize(): block size of rangeMap and domainMap are different.");
181  return Teuchos::as<LocalOrdinal>(domainMap->getFixedBlockSize()); // TODO: why LocalOrdinal?
182  } else
183  // TEUCHOS_TEST_FOR_EXCEPTION(false, Exceptions::RuntimeError, "Xpetra::Matrix::GetFixedBlockSize(): no strided maps available."); // TODO remove this
184  return 1;
185 } // TODO: why LocalOrdinal?
186 
187 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
189  return IsView("stridedMaps");
190 }
191 
192 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
194  operatorViewTable_.get(GetCurrentViewLabel())->SetMaxEigenvalueEstimate(sigma);
195 }
196 
197 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
199  return operatorViewTable_.get(GetCurrentViewLabel())->GetMaxEigenvalueEstimate();
200 }
201 
202 } // namespace Xpetra
203 
204 #define XPETRA_MATRIX_SHORT
205 #endif // XPETRA_MATRIX_DECL_HPP
const viewLabel_t & GetCurrentViewLabel() const
virtual const RCP< const Map > & getColMap() const
Returns the Map that describes the column distribution in this matrix. This might be null until fillC...
virtual ~Matrix()
Destructor.
void RemoveView(const viewLabel_t viewLabel)
virtual const RCP< const Map > & getRowMap() const
Returns the Map that describes the row distribution in this matrix.
Exception throws to report errors in the internal logical of the program.
const viewLabel_t & GetDefaultViewLabel() const
Exception indicating invalid cast attempted.
void SetFixedBlockSize(LocalOrdinal blksize, GlobalOrdinal offset=0)
bool IsView(const viewLabel_t viewLabel) const
void CreateView(viewLabel_t viewLabel, const RCP< const Map > &rowMap, const RCP< const Map > &colMap)
void PrintViews(Teuchos::FancyOStream &out) const
Print all of the views associated with the Matrix.
LocalOrdinal GetFixedBlockSize() const
virtual Scalar GetMaxEigenvalueEstimate() const
virtual void SetMaxEigenvalueEstimate(Scalar const &sigma)
bool IsFixedBlockSizeSet() const
Returns true, if SetFixedBlockSize has been called before.
const viewLabel_t SwitchToView(const viewLabel_t viewLabel)
static RCP< Xpetra::StridedMap< LocalOrdinal, GlobalOrdinal, Node > > Build(UnderlyingLib lib, global_size_t numGlobalElements, GlobalOrdinal indexBase, std::vector< size_t > &stridingInfo, const Teuchos::RCP< const Teuchos::Comm< int >> &comm, LocalOrdinal stridedBlockId=-1, GlobalOrdinal offset=0, LocalGlobal lg=Xpetra::GloballyDistributed)
Map constructor with Xpetra-defined contiguous uniform distribution.
const viewLabel_t SwitchToDefaultView()
Class that stores a strided map.