Ifpack2 Templated Preconditioning Package Version 1.0
Loading...
Searching...
No Matches
Ifpack2_SparsityFilter_def.hpp
1// @HEADER
2// *****************************************************************************
3// Ifpack2: Templated Object-Oriented Algebraic Preconditioner Package
4//
5// Copyright 2009 NTESS and the Ifpack2 contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef IFPACK2_SPARSITYFILTER_DEF_HPP
11#define IFPACK2_SPARSITYFILTER_DEF_HPP
12
13#include "Tpetra_Map.hpp"
14#include "Tpetra_MultiVector.hpp"
15#include "Tpetra_Vector.hpp"
16
17#include <algorithm>
18#include <vector>
19
20namespace Ifpack2 {
21
22//==========================================================================
23template<class MatrixType>
24SparsityFilter<MatrixType>::SparsityFilter(const Teuchos::RCP<const Tpetra::RowMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> >& Matrix,
25 size_t AllowedNumEntries,
26 LocalOrdinal AllowedBandwidth):
27 A_(Matrix),
28 AllowedNumEntries_(AllowedNumEntries),
29 AllowedBandwidth_(AllowedBandwidth),
30 NumRows_(0),
31 NumNonzeros_(0),
32 MaxNumEntries_(0),
33 MaxNumEntriesA_(0)
34{
35
36 // use this filter only on serial matrices
37 TEUCHOS_TEST_FOR_EXCEPTION(
38 A_->getComm()->getSize() != 1 || A_->getLocalNumRows() != A_->getGlobalNumRows(),
39 std::runtime_error, "Ifpack2::SparsityFilter: "
40 "This class may only be used when A.getComm()->getSize() == 1.");
41
42 // localized matrix has all the local rows of Matrix
43 NumRows_ = A_->getLocalNumRows();
44
45 // NodeNumEntries_ will contain the actual number of nonzeros
46 // for each localized row (that is, without external nodes,
47 // and always with the diagonal entry)
48 NumEntries_.resize(NumRows_);
49
50 // tentative value for MaxNumEntries. This is the number of
51 // nonzeros in the local matrix
52 MaxNumEntries_ = A_->getLocalMaxNumRowEntries();
53 MaxNumEntriesA_ = A_->getLocalMaxNumRowEntries();
54
55 // ExtractMyRowCopy() will use these vectors
56 Kokkos::resize(Indices_,MaxNumEntries_);
57 Kokkos::resize(Values_,MaxNumEntries_);
58
59 size_t ActualMaxNumEntries = 0;
60 for (size_t i = 0 ; i < NumRows_ ; ++i) {
61 NumEntries_[i] = MaxNumEntriesA_;
62 size_t Nnz;
63 A_->getLocalRowCopy(i,Indices_,Values_,Nnz);
64
65 NumNonzeros_ += Nnz;
66 NumEntries_[i] = Nnz;
67 if (Nnz > ActualMaxNumEntries)
68 ActualMaxNumEntries = Nnz;
69 }
70
71 MaxNumEntries_ = ActualMaxNumEntries;
72}
73
74//=========================================================================
75template<class MatrixType>
77
78//==========================================================================
79template<class MatrixType>
80Teuchos::RCP<const Teuchos::Comm<int> > SparsityFilter<MatrixType>::getComm() const
81{
82 return A_->getComm();
83}
84
85
86//==========================================================================
87template<class MatrixType>
88Teuchos::RCP<const Tpetra::Map<typename MatrixType::local_ordinal_type,
89 typename MatrixType::global_ordinal_type,
90 typename MatrixType::node_type> >
92{
93 return A_->getRowMap();
94}
95
96//==========================================================================
97template<class MatrixType>
98Teuchos::RCP<const Tpetra::Map<typename MatrixType::local_ordinal_type,
99 typename MatrixType::global_ordinal_type,
100 typename MatrixType::node_type> >
102{
103 return A_->getColMap();
104}
105
106//==========================================================================
107template<class MatrixType>
108Teuchos::RCP<const Tpetra::Map<typename MatrixType::local_ordinal_type,
109 typename MatrixType::global_ordinal_type,
110 typename MatrixType::node_type> >
112{
113 return A_->getDomainMap();
114}
115
116//==========================================================================
117template<class MatrixType>
118Teuchos::RCP<const Tpetra::Map<typename MatrixType::local_ordinal_type,
119 typename MatrixType::global_ordinal_type,
120 typename MatrixType::node_type> >
122{
123 return A_->getRangeMap();
124}
125
126//==========================================================================
127template<class MatrixType>
128Teuchos::RCP<const Tpetra::RowGraph<typename MatrixType::local_ordinal_type,
129 typename MatrixType::global_ordinal_type,
130 typename MatrixType::node_type> >
132{
133 throw std::runtime_error("Ifpack2::SparsityFilter: does not support getGraph.");
134}
135
136//==========================================================================
137template<class MatrixType>
139{
140 return NumRows_;
141}
142
143//==========================================================================
144template<class MatrixType>
146{
147 return NumRows_;
148}
149
150//==========================================================================
151template<class MatrixType>
153{
154 return NumRows_;
155}
156
157//==========================================================================
158
159template<class MatrixType>
161{
162 return NumRows_;
163}
164
165//==========================================================================
166template<class MatrixType>
167typename MatrixType::global_ordinal_type SparsityFilter<MatrixType>::getIndexBase() const
168{
169 return A_->getIndexBase();
170}
171
172//==========================================================================
173template<class MatrixType>
175{
176 return NumNonzeros_;
177}
178
179//==========================================================================
180template<class MatrixType>
182{
183 return NumNonzeros_;
184}
185
186//==========================================================================
187template<class MatrixType>
188size_t SparsityFilter<MatrixType>::getNumEntriesInGlobalRow(GlobalOrdinal /* globalRow */) const
189{
190 throw std::runtime_error("Ifpack2::SparsityFilter does not implement getNumEntriesInGlobalRow.");
191}
192
193//==========================================================================
194template<class MatrixType>
196{
197 return NumEntries_[localRow];
198}
199
200//==========================================================================
201template<class MatrixType>
203{
204 return MaxNumEntries_;
205}
206
207//==========================================================================
208template<class MatrixType>
210{
211 return MaxNumEntries_;
212}
213
214//==========================================================================
215template<class MatrixType>
216typename MatrixType::local_ordinal_type SparsityFilter<MatrixType>::getBlockSize() const
217{
218 return A_->getBlockSize();
219}
220
221//==========================================================================
222template<class MatrixType>
224{
225 return true;
226}
227
228//==========================================================================
229template<class MatrixType>
231{
232 return A_->isLocallyIndexed();
233}
234
235//==========================================================================
236template<class MatrixType>
238{
239 return A_->isGloballyIndexed();
240}
241
242//==========================================================================
243template<class MatrixType>
245{
246 return A_->isFillComplete();
247}
248
249//==========================================================================
250template<class MatrixType>
252getGlobalRowCopy (GlobalOrdinal /*GlobalRow*/,
253 nonconst_global_inds_host_view_type &/*Indices*/,
254 nonconst_values_host_view_type &/*Values*/,
255 size_t& /*NumEntries*/) const {
256 throw std::runtime_error("Ifpack2::SparsityFilter does not implement getGlobalRowCopy.");
257}
258
259//==========================================================================
260template<class MatrixType>
262 getLocalRowCopy (LocalOrdinal LocalRow,
263 nonconst_local_inds_host_view_type &Indices,
264 nonconst_values_host_view_type &Values,
265 size_t& NumEntries) const
266{
267TEUCHOS_TEST_FOR_EXCEPTION((LocalRow < 0 || (size_t) LocalRow >= NumRows_ || (size_t) Indices.size() < NumEntries_[LocalRow]), std::runtime_error, "Ifpack2::SparsityFilter::getLocalRowCopy invalid row or array size.");
268
269 // Note: This function will work correctly if called by apply, say, with Indices_ and Values_ as
270 // parameters. The structure of the loop below should make that obvious.
271
272 // always extract using the object Values_ and Indices_.
273 // This is because I need more space than that given by
274 // the user (for the external nodes)
275 size_t A_NumEntries=0;
276 A_->getLocalRowCopy(LocalRow,Indices_,Values_,A_NumEntries);
277 magnitudeType Threshold = Teuchos::ScalarTraits<magnitudeType>::zero();
278 std::vector<magnitudeType> Values2(A_NumEntries,Teuchos::ScalarTraits<magnitudeType>::zero());
279
280 if (A_NumEntries > AllowedNumEntries_) {
281 size_t count = 0;
282 for (size_t i = 0 ; i < A_NumEntries ; ++i) {
283 // skip diagonal entry (which is always inserted)
284 if (Indices_[i] == LocalRow)
285 continue;
286 // put magnitude
287 Values2[count] = Teuchos::ScalarTraits<Scalar>::magnitude(Values_[i]);
288 count++;
289 }
290
291 // sort in descending order
292 std::sort(Values2.rbegin(),Values2.rend());
293 // get the cut-off value
294 Threshold = Values2[AllowedNumEntries_ - 1];
295 }
296
297
298 // loop over all nonzero elements of row MyRow,
299 // and drop elements below specified threshold.
300 // Also, add value to zero diagonal
301 NumEntries = 0;
302 for (size_t i = 0 ; i < A_NumEntries ; ++i) {
303 if (std::abs(Indices_[i] - LocalRow) > AllowedBandwidth_)
304 continue;
305
306 if ((Indices_[i] != LocalRow) && (Teuchos::ScalarTraits<Scalar>::magnitude(Values_[i]) < Threshold))
307 continue;
308
309 Values[NumEntries] = Values_[i];
310 Indices[NumEntries] = Indices_[i];
311
312 NumEntries++;
313 if (NumEntries > AllowedNumEntries_)
314 break;
315 }
316
317
318}
319
320//==========================================================================
321template<class MatrixType>
322void SparsityFilter<MatrixType>::getGlobalRowView(GlobalOrdinal /* GlobalRow */,
323 global_inds_host_view_type &/*indices*/,
324 values_host_view_type &/*values*/) const
325{
326 throw std::runtime_error("Ifpack2::SparsityFilter: does not support getGlobalRowView.");
327}
328
329//==========================================================================
330template<class MatrixType>
331void SparsityFilter<MatrixType>::getLocalRowView(LocalOrdinal /* LocalRow */,
332 local_inds_host_view_type & /*indices*/,
333 values_host_view_type & /*values*/) const
334{
335 throw std::runtime_error("Ifpack2::SparsityFilter: does not support getLocalRowView.");
336}
337
338//==========================================================================
339template<class MatrixType>
340void SparsityFilter<MatrixType>::getLocalDiagCopy(Tpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &diag) const
341{
342 // This is somewhat dubious as to how the maps match.
343 return A_->getLocalDiagCopy(diag);
344}
345
346//==========================================================================
347template<class MatrixType>
348void SparsityFilter<MatrixType>::leftScale(const Tpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& /* x */)
349{
350 throw std::runtime_error("Ifpack2::SparsityFilter does not support leftScale.");
351}
352
353//==========================================================================
354template<class MatrixType>
355void SparsityFilter<MatrixType>::rightScale(const Tpetra::Vector<Scalar, LocalOrdinal, GlobalOrdinal, Node>& /* x */)
356{
357 throw std::runtime_error("Ifpack2::SparsityFilter does not support rightScale.");
358}
359
360//==========================================================================
361template<class MatrixType>
362void SparsityFilter<MatrixType>::apply(const Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &X,
363 Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &Y,
364 Teuchos::ETransp mode,
365 Scalar /* alpha */,
366 Scalar /* beta */) const
367{
368 // Note: This isn't AztecOO compliant. But neither was Ifpack's version.
369 // Note: The localized maps mean the matvec is trivial (and has no import)
370 TEUCHOS_TEST_FOR_EXCEPTION(X.getNumVectors() != Y.getNumVectors(), std::runtime_error,
371 "Ifpack2::SparsityFilter::apply ERROR: X.getNumVectors() != Y.getNumVectors().");
372
373 Scalar zero = Teuchos::ScalarTraits<Scalar>::zero();
374 Teuchos::ArrayRCP<Teuchos::ArrayRCP<const Scalar> > x_ptr = X.get2dView();
375 Teuchos::ArrayRCP<Teuchos::ArrayRCP<Scalar> > y_ptr = Y.get2dViewNonConst();
376
377 Y.putScalar(zero);
378 size_t NumVectors = Y.getNumVectors();
379
380 for (size_t i = 0 ; i < NumRows_ ; ++i) {
381 size_t Nnz;
382 // Use this class's getrow to make the below code simpler
383 getLocalRowCopy(i,Indices_,Values_,Nnz);
384 Scalar* Values = reinterpret_cast<Scalar*>(Values_.data());
385 if (mode==Teuchos::NO_TRANS){
386 for (size_t j = 0 ; j < Nnz ; ++j)
387 for (size_t k = 0 ; k < NumVectors ; ++k)
388 y_ptr[k][i] += Values[j] * x_ptr[k][Indices_[j]];
389 }
390 else if (mode==Teuchos::TRANS){
391 for (size_t j = 0 ; j < Nnz ; ++j)
392 for (size_t k = 0 ; k < NumVectors ; ++k)
393 y_ptr[k][Indices_[j]] += Values[j] * x_ptr[k][i];
394 }
395 else { //mode==Teuchos::CONJ_TRANS
396 for (size_t j = 0 ; j < Nnz ; ++j)
397 for (size_t k = 0 ; k < NumVectors ; ++k)
398 y_ptr[k][Indices_[j]] += Teuchos::ScalarTraits<Scalar>::conjugate(Values[j]) * x_ptr[k][i];
399 }
400 }
401}
402
403
404//==========================================================================
405template<class MatrixType>
407{
408 return true;
409}
410
411//==========================================================================
412template<class MatrixType>
414{
415 return false;
416}
417
418//==========================================================================
419template<class MatrixType>
420typename SparsityFilter<MatrixType>::mag_type SparsityFilter<MatrixType>::getFrobeniusNorm() const
421{
422 throw std::runtime_error("Ifpack2::SparsityFilter does not implement getFrobeniusNorm.");
423}
424
425} // namespace Ifpack2
426
427#define IFPACK2_SPARSITYFILTER_INSTANT(S,LO,GO,N) \
428 template class Ifpack2::SparsityFilter< Tpetra::RowMatrix<S, LO, GO, N> >;
429
430#endif
virtual global_size_t getGlobalNumRows() const
Returns the number of global rows in this matrix.
Definition Ifpack2_SparsityFilter_def.hpp:138
virtual size_t getNumEntriesInLocalRow(LocalOrdinal localRow) const
Returns the current number of entries on this node in the specified local row.
Definition Ifpack2_SparsityFilter_def.hpp:195
virtual void getLocalRowView(LocalOrdinal 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_SparsityFilter_def.hpp:331
virtual bool hasTransposeApply() const
Indicates whether this operator supports applying the adjoint operator.
Definition Ifpack2_SparsityFilter_def.hpp:406
virtual Teuchos::RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > getDomainMap() const
Returns the Map that describes the domain distribution in this matrix.
Definition Ifpack2_SparsityFilter_def.hpp:111
virtual GlobalOrdinal getIndexBase() const
Returns the index base for global indices for this matrix.
Definition Ifpack2_SparsityFilter_def.hpp:167
virtual mag_type getFrobeniusNorm() const
Returns the Frobenius norm of the matrix.
Definition Ifpack2_SparsityFilter_def.hpp:420
virtual global_size_t getGlobalNumEntries() const
Returns the global number of entries in this matrix.
Definition Ifpack2_SparsityFilter_def.hpp:174
virtual Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Returns the communicator.
Definition Ifpack2_SparsityFilter_def.hpp:80
virtual Teuchos::RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > getRowMap() const
Returns the Map that describes the row distribution in this matrix.
Definition Ifpack2_SparsityFilter_def.hpp:91
virtual size_t getLocalNumCols() const
Returns the number of columns needed to apply the forward operator on this node, i....
Definition Ifpack2_SparsityFilter_def.hpp:160
virtual LocalOrdinal getBlockSize() const
The number of degrees of freedom per mesh point.
Definition Ifpack2_SparsityFilter_def.hpp:216
virtual size_t getNumEntriesInGlobalRow(GlobalOrdinal globalRow) const
Returns the current number of entries on this node in the specified global row.
Definition Ifpack2_SparsityFilter_def.hpp:188
virtual size_t getLocalMaxNumRowEntries() const
Returns the maximum number of entries across all rows/columns on this node.
Definition Ifpack2_SparsityFilter_def.hpp:209
virtual ~SparsityFilter()
Destructor.
Definition Ifpack2_SparsityFilter_def.hpp:76
virtual void getGlobalRowView(GlobalOrdinal 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_SparsityFilter_def.hpp:322
virtual void getLocalDiagCopy(Tpetra::Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &diag) const
Get a copy of the diagonal entries owned by this node, with local row indices.
Definition Ifpack2_SparsityFilter_def.hpp:340
virtual void getGlobalRowCopy(GlobalOrdinal 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_SparsityFilter_def.hpp:252
virtual bool isLocallyIndexed() const
If matrix indices are in the local range, this function returns true. Otherwise, this function return...
Definition Ifpack2_SparsityFilter_def.hpp:230
virtual global_size_t getGlobalNumCols() const
Returns the number of global columns in this matrix.
Definition Ifpack2_SparsityFilter_def.hpp:145
virtual Teuchos::RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > getRangeMap() const
Returns the Map that describes the range distribution in this matrix.
Definition Ifpack2_SparsityFilter_def.hpp:121
virtual bool hasColMap() const
Indicates whether this matrix has a well-defined column map.
Definition Ifpack2_SparsityFilter_def.hpp:223
virtual void rightScale(const Tpetra::Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &x)
Scales the RowMatrix on the right with the Vector x.
Definition Ifpack2_SparsityFilter_def.hpp:355
virtual void apply(const Tpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &X, Tpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &Y, Teuchos::ETransp mode=Teuchos::NO_TRANS, Scalar alpha=Teuchos::ScalarTraits< Scalar >::one(), Scalar beta=Teuchos::ScalarTraits< Scalar >::zero()) const
Computes the operator-multivector application.
Definition Ifpack2_SparsityFilter_def.hpp:362
virtual Teuchos::RCP< const Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > > getColMap() const
Returns the Map that describes the column distribution in this matrix.
Definition Ifpack2_SparsityFilter_def.hpp:101
virtual bool supportsRowViews() const
Returns true if RowViews are supported.
Definition Ifpack2_SparsityFilter_def.hpp:413
virtual bool isFillComplete() const
Returns true if fillComplete() has been called.
Definition Ifpack2_SparsityFilter_def.hpp:244
virtual void leftScale(const Tpetra::Vector< Scalar, LocalOrdinal, GlobalOrdinal, Node > &x)
Scales the RowMatrix on the left with the Vector x.
Definition Ifpack2_SparsityFilter_def.hpp:348
virtual Teuchos::RCP< const Tpetra::RowGraph< LocalOrdinal, GlobalOrdinal, Node > > getGraph() const
Returns the RowGraph associated with this matrix.
Definition Ifpack2_SparsityFilter_def.hpp:131
virtual size_t getLocalNumRows() const
Returns the number of rows owned on the calling node.
Definition Ifpack2_SparsityFilter_def.hpp:152
SparsityFilter(const Teuchos::RCP< const row_matrix_type > &Matrix, size_t AllowedNumEntries, LocalOrdinal AllowedBandwidth=-Teuchos::ScalarTraits< LocalOrdinal >::one())
Constructor.
Definition Ifpack2_SparsityFilter_def.hpp:24
virtual void getLocalRowCopy(LocalOrdinal 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_SparsityFilter_def.hpp:262
virtual size_t getGlobalMaxNumRowEntries() const
Returns the maximum number of entries across all rows/columns on all nodes.
Definition Ifpack2_SparsityFilter_def.hpp:202
virtual size_t getLocalNumEntries() const
Returns the local number of entries in this matrix.
Definition Ifpack2_SparsityFilter_def.hpp:181
virtual bool isGloballyIndexed() const
If matrix indices are in the global range, this function returns true. Otherwise, this function retur...
Definition Ifpack2_SparsityFilter_def.hpp:237
Preconditioners and smoothers for Tpetra sparse matrices.
Definition Ifpack2_AdditiveSchwarz_decl.hpp:41