10#ifndef IFPACK2_REORDERFILTER_DEF_HPP
11#define IFPACK2_REORDERFILTER_DEF_HPP
12#include "Ifpack2_ReorderFilter_decl.hpp"
15#include "Tpetra_ConfigDefs.hpp"
16#include "Tpetra_RowMatrix.hpp"
17#include "Tpetra_Map.hpp"
18#include "Tpetra_MultiVector.hpp"
19#include "Tpetra_Vector.hpp"
23template <
class MatrixType>
26 const Teuchos::ArrayRCP<local_ordinal_type> &perm,
27 const Teuchos::ArrayRCP<local_ordinal_type> &reverseperm)
30 , reverseperm_(reverseperm) {
31 TEUCHOS_TEST_FOR_EXCEPTION(
32 A_.is_null(), std::invalid_argument,
33 "Ifpack2::ReorderFilter: The input matrix is null.");
36 TEUCHOS_TEST_FOR_EXCEPTION(
37 A_->getComm()->getSize() != 1, std::invalid_argument,
38 "Ifpack2::ReorderFilter: This class may only be used if the input matrix's "
39 "communicator has one process. This class is an implementation detail of "
40 "Ifpack2::AdditiveSchwarz, and it is not meant to be used otherwise.");
42 TEUCHOS_TEST_FOR_EXCEPTION(
43 A_->getLocalNumRows() != A_->getGlobalNumRows(),
44 std::invalid_argument,
45 "Ifpack2::ReorderFilter: The input matrix is not square.");
48 Kokkos::resize(Indices_, A_->getLocalMaxNumRowEntries());
49 Kokkos::resize(Values_, A_->getLocalMaxNumRowEntries());
52template <
class MatrixType>
55template <
class MatrixType>
60template <
class MatrixType>
61Teuchos::RCP<const typename ReorderFilter<MatrixType>::map_type>
63 TEUCHOS_TEST_FOR_EXCEPTION(
64 A_.is_null(), std::runtime_error,
65 "Ifpack2::ReorderFilter::"
66 "getRowMap: The matrix A is null, so there is no row Map.");
68 return A_->getRowMap();
71template <
class MatrixType>
72Teuchos::RCP<const typename ReorderFilter<MatrixType>::map_type>
74 TEUCHOS_TEST_FOR_EXCEPTION(
75 A_.is_null(), std::runtime_error,
76 "Ifpack2::ReorderFilter::"
77 "getColMap: The matrix A is null, so there is no column Map.");
79 return A_->getColMap();
82template <
class MatrixType>
83Teuchos::RCP<const typename ReorderFilter<MatrixType>::map_type>
85 TEUCHOS_TEST_FOR_EXCEPTION(
86 A_.is_null(), std::runtime_error,
87 "Ifpack2::ReorderFilter::"
88 "getDomainMap: The matrix A is null, so there is no domain Map.");
90 return A_->getDomainMap();
93template <
class MatrixType>
94Teuchos::RCP<const typename ReorderFilter<MatrixType>::map_type>
96 TEUCHOS_TEST_FOR_EXCEPTION(
97 A_.is_null(), std::runtime_error,
98 "Ifpack2::ReorderFilter::"
99 "getRangeMap: The matrix A is null, so there is no range Map.");
101 return A_->getRangeMap();
104template <
class MatrixType>
105Teuchos::RCP<
const Tpetra::RowGraph<
typename MatrixType::local_ordinal_type,
106 typename MatrixType::global_ordinal_type,
107 typename MatrixType::node_type> >
109 throw std::runtime_error(
"Ifpack2::ReorderFilter: does not support getGraph.");
112template <
class MatrixType>
114 return A_->getGlobalNumRows();
117template <
class MatrixType>
119 return A_->getGlobalNumCols();
122template <
class MatrixType>
124 return A_->getLocalNumRows();
127template <
class MatrixType>
129 return A_->getLocalNumCols();
132template <
class MatrixType>
134 return A_->getIndexBase();
137template <
class MatrixType>
139 return A_->getGlobalNumEntries();
142template <
class MatrixType>
144 return A_->getLocalNumEntries();
147template <
class MatrixType>
149 return A_->getBlockSize();
152template <
class MatrixType>
155 if (A_.is_null() || A_->getRowMap().is_null()) {
156 return Teuchos::OrdinalTraits<size_t>::invalid();
158 const local_ordinal_type lclRow =
159 A_->getRowMap()->getLocalElement(globalRow);
160 if (lclRow == Teuchos::OrdinalTraits<local_ordinal_type>::invalid()) {
162 return static_cast<size_t>(0);
164 const local_ordinal_type origLclRow = reverseperm_[lclRow];
165 return A_->getNumEntriesInLocalRow(origLclRow);
170template <
class MatrixType>
175 if (A_->getRowMap()->isNodeLocalElement(localRow)) {
177 const local_ordinal_type localReorderedRow = reverseperm_[localRow];
178 return A_->getNumEntriesInLocalRow(localReorderedRow);
181 return static_cast<size_t>(0);
185template <
class MatrixType>
187 return A_->getGlobalMaxNumRowEntries();
190template <
class MatrixType>
192 return A_->getLocalMaxNumRowEntries();
195template <
class MatrixType>
200template <
class MatrixType>
202 return A_->isLocallyIndexed();
205template <
class MatrixType>
207 return A_->isGloballyIndexed();
210template <
class MatrixType>
212 return A_->isFillComplete();
215template <
class MatrixType>
218 nonconst_global_inds_host_view_type &globalInd,
219 nonconst_values_host_view_type &val,
220 size_t &numEntries)
const {
221 using Teuchos::Array;
222 using Teuchos::ArrayView;
223 using Teuchos::av_reinterpret_cast;
224 typedef local_ordinal_type LO;
225 typedef Teuchos::OrdinalTraits<LO> OTLO;
227 const map_type &rowMap = *(A_->getRowMap());
228 const local_ordinal_type localRow = rowMap.getLocalElement(globalRow);
229 TEUCHOS_TEST_FOR_EXCEPTION(
230 localRow == OTLO::invalid(), std::invalid_argument,
232 "Filter::getGlobalRowCopy: The given global row index "
234 <<
" is not owned by the calling process with rank "
235 << rowMap.getComm()->getRank() <<
".");
238 numEntries = this->getNumEntriesInLocalRow(localRow);
239 this->getLocalRowCopy(localRow, Indices_, val, numEntries);
242 for (
size_t k = 0; k < numEntries; ++k) {
243 globalInd[k] = rowMap.getGlobalElement(Indices_[k]);
247template <
class MatrixType>
250 nonconst_local_inds_host_view_type &Indices,
251 nonconst_values_host_view_type &Values,
252 size_t &NumEntries)
const
255 TEUCHOS_TEST_FOR_EXCEPTION(
256 !A_->getRowMap()->isNodeLocalElement(LocalRow),
257 std::invalid_argument,
258 "Ifpack2::ReorderFilter::getLocalRowCopy: The given local row index "
259 << LocalRow <<
" is not a valid local row index on the calling process "
261 << A_->getRowMap()->getComm()->getRank() <<
".");
265 const local_ordinal_type origLclRow = reverseperm_[LocalRow];
266 const size_t numEntries = A_->getNumEntriesInLocalRow(origLclRow);
268 TEUCHOS_TEST_FOR_EXCEPTION(
269 static_cast<size_t>(Indices.size()) < numEntries ||
270 static_cast<size_t>(Values.size()) < numEntries,
271 std::invalid_argument,
272 "Ifpack2::ReorderFilter::getLocalRowCopy: The given array views are not "
273 "long enough to store all the data in the given row "
275 <<
". Indices.size() = " << Indices.size() <<
", Values.size() = "
276 << Values.size() <<
", but the (original) row has " << numEntries
279 A_->getLocalRowCopy(origLclRow, Indices, Values, NumEntries);
284 for (
size_t i = 0; i < NumEntries; ++i) {
285 Indices[i] = perm_[Indices[i]];
289template <
class MatrixType>
291 global_inds_host_view_type & ,
292 values_host_view_type & )
const {
293 throw std::runtime_error(
"Ifpack2::ReorderFilter: does not support getGlobalRowView.");
296template <
class MatrixType>
298 local_inds_host_view_type & ,
299 values_host_view_type & )
const {
300 throw std::runtime_error(
"Ifpack2::ReorderFilter: does not support getLocalRowView.");
303template <
class MatrixType>
305 getLocalDiagCopy(Tpetra::Vector<scalar_type, local_ordinal_type, global_ordinal_type, node_type> &diag)
const {
307 return A_->getLocalDiagCopy(diag);
310template <
class MatrixType>
312 throw std::runtime_error(
"Ifpack2::ReorderFilter does not support leftScale.");
315template <
class MatrixType>
317 throw std::runtime_error(
"Ifpack2::ReorderFilter does not support rightScale.");
320template <
class MatrixType>
322 apply(
const Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type> &X,
323 Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type> &Y,
324 Teuchos::ETransp mode,
326 scalar_type beta)
const {
327 typedef Teuchos::ScalarTraits<scalar_type> STS;
329 TEUCHOS_TEST_FOR_EXCEPTION(
330 alpha != STS::one() || beta != STS::zero(), std::logic_error,
331 "Ifpack2::ReorderFilter::apply is only implemented for alpha = 1 and "
332 "beta = 0. You set alpha = "
333 << alpha <<
" and beta = " << beta <<
".");
337 TEUCHOS_TEST_FOR_EXCEPTION(
338 X.getNumVectors() != Y.getNumVectors(), std::runtime_error,
339 "Ifpack2::ReorderFilter::apply: X.getNumVectors() != Y.getNumVectors().");
341 const scalar_type zero = STS::zero();
342 Teuchos::ArrayRCP<Teuchos::ArrayRCP<const scalar_type> > x_ptr = X.get2dView();
343 Teuchos::ArrayRCP<Teuchos::ArrayRCP<scalar_type> > y_ptr = Y.get2dViewNonConst();
346 const size_t NumVectors = Y.getNumVectors();
348 for (
size_t i = 0; i < A_->getLocalNumRows(); ++i) {
351 getLocalRowCopy(i, Indices_, Values_, Nnz);
352 scalar_type *Values =
reinterpret_cast<scalar_type *
>(Values_.data());
353 if (mode == Teuchos::NO_TRANS) {
354 for (
size_t j = 0; j < Nnz; ++j) {
355 for (
size_t k = 0; k < NumVectors; ++k) {
356 y_ptr[k][i] += Values[j] * x_ptr[k][Indices_[j]];
359 }
else if (mode == Teuchos::TRANS) {
360 for (
size_t j = 0; j < Nnz; ++j) {
361 for (
size_t k = 0; k < NumVectors; ++k) {
362 y_ptr[k][Indices_[j]] += Values[j] * x_ptr[k][i];
366 for (
size_t j = 0; j < Nnz; ++j) {
367 for (
size_t k = 0; k < NumVectors; ++k) {
368 y_ptr[k][Indices_[j]] += STS::conjugate(Values[j]) * x_ptr[k][i];
375template <
class MatrixType>
380template <
class MatrixType>
385template <
class MatrixType>
388 return A_->getFrobeniusNorm();
391template <
class MatrixType>
393 permuteOriginalToReordered(
const Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type> &originalX,
394 Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type> &reorderedY)
const {
395 this->
template permuteOriginalToReorderedTempl<scalar_type, scalar_type>(originalX, reorderedY);
398template <
class MatrixType>
399template <
class DomainScalar,
class RangeScalar>
401 Tpetra::MultiVector<RangeScalar, local_ordinal_type, global_ordinal_type, node_type> &reorderedY)
const {
402 TEUCHOS_TEST_FOR_EXCEPTION(originalX.getNumVectors() != reorderedY.getNumVectors(), std::runtime_error,
403 "Ifpack2::ReorderFilter::permuteOriginalToReordered ERROR: X.getNumVectors() != Y.getNumVectors().");
405 Teuchos::ArrayRCP<Teuchos::ArrayRCP<const DomainScalar> > x_ptr = originalX.get2dView();
406 Teuchos::ArrayRCP<Teuchos::ArrayRCP<RangeScalar> > y_ptr = reorderedY.get2dViewNonConst();
408 const local_ordinal_type blockSize = getBlockSize();
409 const local_ordinal_type numRows = originalX.getLocalLength() / blockSize;
410 for (
size_t k = 0; k < originalX.getNumVectors(); k++)
411 for (local_ordinal_type i = 0; i < numRows; i++)
412 for (local_ordinal_type j = 0; j < blockSize; ++j)
413 y_ptr[k][perm_[i] * blockSize + j] = (RangeScalar)x_ptr[k][i * blockSize + j];
416template <
class MatrixType>
418 Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type> &originalY)
const {
419 this->
template permuteReorderedToOriginalTempl<scalar_type, scalar_type>(reorderedX, originalY);
422template <
class MatrixType>
423template <
class DomainScalar,
class RangeScalar>
426 Tpetra::MultiVector<RangeScalar, local_ordinal_type, global_ordinal_type, node_type> &originalY)
const {
427 TEUCHOS_TEST_FOR_EXCEPTION(
428 reorderedX.getNumVectors() != originalY.getNumVectors(),
430 "Ifpack2::ReorderFilter::permuteReorderedToOriginal: "
431 "X.getNumVectors() != Y.getNumVectors().");
433#ifdef HAVE_IFPACK2_DEBUG
435 typedef Teuchos::ScalarTraits<magnitude_type> STM;
436 Teuchos::Array<magnitude_type> norms(reorderedX.getNumVectors());
437 reorderedX.norm2(norms());
440 j < reorderedX.getNumVectors(); ++j) {
441 if (STM::isnaninf(norms[j])) {
446 TEUCHOS_TEST_FOR_EXCEPTION(
447 !good, std::runtime_error,
448 "Ifpack2::ReorderFilter::"
449 "permuteReorderedToOriginalTempl: The 2-norm of the input reorderedX is "
454 Teuchos::ArrayRCP<Teuchos::ArrayRCP<const DomainScalar> > x_ptr = reorderedX.get2dView();
455 Teuchos::ArrayRCP<Teuchos::ArrayRCP<RangeScalar> > y_ptr = originalY.get2dViewNonConst();
457 const local_ordinal_type blockSize = getBlockSize();
458 const local_ordinal_type numRows = reorderedX.getLocalLength() / blockSize;
459 for (
size_t k = 0; k < reorderedX.getNumVectors(); ++k) {
460 for (local_ordinal_type i = 0; i < numRows; ++i) {
461 for (local_ordinal_type j = 0; j < blockSize; ++j) {
462 y_ptr[k][reverseperm_[i] * blockSize + j] = (RangeScalar)x_ptr[k][i * blockSize + j];
467#ifdef HAVE_IFPACK2_DEBUG
469 typedef Teuchos::ScalarTraits<magnitude_type> STM;
470 Teuchos::Array<magnitude_type> norms(originalY.getNumVectors());
471 originalY.norm2(norms());
474 j < originalY.getNumVectors(); ++j) {
475 if (STM::isnaninf(norms[j])) {
480 TEUCHOS_TEST_FOR_EXCEPTION(
481 !good, std::runtime_error,
482 "Ifpack2::ReorderFilter::"
483 "permuteReorderedToOriginalTempl: The 2-norm of the output originalY is "
491#define IFPACK2_REORDERFILTER_INSTANT(S, LO, GO, N) \
492 template class Ifpack2::ReorderFilter<Tpetra::RowMatrix<S, LO, GO, N> >;
Wraps a Tpetra::RowMatrix in a filter that reorders local rows and columns.
Definition Ifpack2_ReorderFilter_decl.hpp:36
virtual local_ordinal_type getBlockSize() const
The number of degrees of freedom per mesh point.
Definition Ifpack2_ReorderFilter_def.hpp:148
virtual size_t getLocalNumCols() const
Returns the number of columns needed to apply the forward operator on this node, i....
Definition Ifpack2_ReorderFilter_def.hpp:128
virtual size_t getNumEntriesInGlobalRow(global_ordinal_type globalRow) const
The current number of entries in this matrix, stored on the calling process, in the row whose global ...
Definition Ifpack2_ReorderFilter_def.hpp:154
virtual mag_type getFrobeniusNorm() const
Returns the Frobenius norm of the matrix.
Definition Ifpack2_ReorderFilter_def.hpp:386
virtual size_t getGlobalMaxNumRowEntries() const
Returns the maximum number of entries across all rows/columns on all nodes.
Definition Ifpack2_ReorderFilter_def.hpp:186
virtual Teuchos::RCP< const map_type > getColMap() const
Returns the Map that describes the column distribution in this matrix.
Definition Ifpack2_ReorderFilter_def.hpp:73
virtual void rightScale(const Tpetra::Vector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > &x)
Scales the RowMatrix on the right with the Vector x.
Definition Ifpack2_ReorderFilter_def.hpp:316
virtual bool hasColMap() const
Indicates whether this matrix has a well-defined column map.
Definition Ifpack2_ReorderFilter_def.hpp:196
virtual size_t getLocalMaxNumRowEntries() const
Returns the maximum number of entries across all rows/columns on this node.
Definition Ifpack2_ReorderFilter_def.hpp:191
virtual void permuteReorderedToOriginal(const Tpetra::MultiVector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > &reorderedX, Tpetra::MultiVector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > &originalY) const
Permute multivector: reordered-to-original.
Definition Ifpack2_ReorderFilter_def.hpp:417
virtual void permuteOriginalToReordered(const Tpetra::MultiVector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > &originalX, Tpetra::MultiVector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > &reorderedY) const
Permute multivector: original-to-reordered.
Definition Ifpack2_ReorderFilter_def.hpp:393
virtual Teuchos::RCP< const map_type > getDomainMap() const
Returns the Map that describes the domain distribution in this matrix.
Definition Ifpack2_ReorderFilter_def.hpp:84
virtual bool supportsRowViews() const
Returns true if RowViews are supported.
Definition Ifpack2_ReorderFilter_def.hpp:381
virtual global_ordinal_type getIndexBase() const
Returns the index base for global indices for this matrix.
Definition Ifpack2_ReorderFilter_def.hpp:133
virtual void getLocalDiagCopy(Tpetra::Vector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > &diag) const
Get a copy of the diagonal entries owned by this node, with local row indices.
Definition Ifpack2_ReorderFilter_def.hpp:305
virtual bool isGloballyIndexed() const
If matrix indices are in the global range, this function returns true. Otherwise, this function retur...
Definition Ifpack2_ReorderFilter_def.hpp:206
virtual Teuchos::RCP< const map_type > getRowMap() const
Returns the Map that describes the row distribution in this matrix.
Definition Ifpack2_ReorderFilter_def.hpp:62
virtual size_t getLocalNumRows() const
Returns the number of rows owned on the calling node.
Definition Ifpack2_ReorderFilter_def.hpp:123
virtual Teuchos::RCP< const map_type > getRangeMap() const
Returns the Map that describes the range distribution in this matrix.
Definition Ifpack2_ReorderFilter_def.hpp:95
virtual Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
The matrix's communicator.
Definition Ifpack2_ReorderFilter_def.hpp:56
ReorderFilter(const Teuchos::RCP< const row_matrix_type > &A, const Teuchos::ArrayRCP< local_ordinal_type > &perm, const Teuchos::ArrayRCP< local_ordinal_type > &reverseperm)
Constructor.
Definition Ifpack2_ReorderFilter_def.hpp:25
virtual bool isFillComplete() const
Returns true if fillComplete() has been called.
Definition Ifpack2_ReorderFilter_def.hpp:211
virtual bool isLocallyIndexed() const
If matrix indices are in the local range, this function returns true. Otherwise, this function return...
Definition Ifpack2_ReorderFilter_def.hpp:201
virtual size_t getLocalNumEntries() const
Returns the local number of entries in this matrix.
Definition Ifpack2_ReorderFilter_def.hpp:143
virtual ~ReorderFilter()
Destructor.
Definition Ifpack2_ReorderFilter_def.hpp:53
virtual void getGlobalRowCopy(global_ordinal_type GlobalRow, nonconst_global_inds_host_view_type &Indices, nonconst_values_host_view_type &Values, size_t &NumEntries) const
Extract a list of entries in a specified global row of this matrix. Put into pre-allocated storage.
Definition Ifpack2_ReorderFilter_def.hpp:217
virtual void getLocalRowView(local_ordinal_type LocalRow, local_inds_host_view_type &indices, values_host_view_type &values) const
Extract a const, non-persisting view of local indices in a specified row of the matrix.
Definition Ifpack2_ReorderFilter_def.hpp:297
virtual size_t getNumEntriesInLocalRow(local_ordinal_type localRow) const
The current number of entries in this matrix, stored on the calling process, in the row whose local i...
Definition Ifpack2_ReorderFilter_def.hpp:172
virtual void getLocalRowCopy(local_ordinal_type LocalRow, nonconst_local_inds_host_view_type &Indices, nonconst_values_host_view_type &Values, size_t &NumEntries) const
Extract a list of entries in a specified local row of the graph. Put into storage allocated by callin...
Definition Ifpack2_ReorderFilter_def.hpp:249
virtual Teuchos::RCP< const Tpetra::RowGraph< local_ordinal_type, global_ordinal_type, node_type > > getGraph() const
Returns the RowGraph associated with this matrix.
Definition Ifpack2_ReorderFilter_def.hpp:108
virtual void apply(const Tpetra::MultiVector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > &X, Tpetra::MultiVector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > &Y, Teuchos::ETransp mode=Teuchos::NO_TRANS, scalar_type alpha=Teuchos::ScalarTraits< scalar_type >::one(), scalar_type beta=Teuchos::ScalarTraits< scalar_type >::zero()) const
, where Op(A) is either A, , or .
Definition Ifpack2_ReorderFilter_def.hpp:322
virtual global_size_t getGlobalNumRows() const
Returns the number of global rows in this matrix.
Definition Ifpack2_ReorderFilter_def.hpp:113
virtual bool hasTransposeApply() const
Whether apply() can apply the transpose or conjugate transpose.
Definition Ifpack2_ReorderFilter_def.hpp:376
virtual global_size_t getGlobalNumCols() const
Returns the number of global columns in this matrix.
Definition Ifpack2_ReorderFilter_def.hpp:118
virtual global_size_t getGlobalNumEntries() const
Returns the global number of entries in this matrix.
Definition Ifpack2_ReorderFilter_def.hpp:138
virtual void leftScale(const Tpetra::Vector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > &x)
Scales the RowMatrix on the left with the Vector x.
Definition Ifpack2_ReorderFilter_def.hpp:311
virtual void getGlobalRowView(global_ordinal_type GlobalRow, global_inds_host_view_type &indices, values_host_view_type &values) const
Extract a const, non-persisting view of global indices in a specified row of the matrix.
Definition Ifpack2_ReorderFilter_def.hpp:290
Preconditioners and smoothers for Tpetra sparse matrices.
Definition Ifpack2_AdditiveSchwarz_decl.hpp:40