Ifpack2 Templated Preconditioning Package Version 1.0
Loading...
Searching...
No Matches
Ifpack2_BandedContainer_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_BANDEDCONTAINER_DEF_HPP
11#define IFPACK2_BANDEDCONTAINER_DEF_HPP
12
13#include "Teuchos_LAPACK.hpp"
14#include "Tpetra_CrsMatrix.hpp"
15#include <iostream>
16#include <sstream>
17
18#ifdef HAVE_MPI
19#include <mpi.h>
20#include "Teuchos_DefaultMpiComm.hpp"
21#else
22#include "Teuchos_DefaultSerialComm.hpp"
23#endif // HAVE_MPI
24
25namespace Ifpack2 {
26
27template <class MatrixType, class LocalScalarType>
29 BandedContainer(const Teuchos::RCP<const row_matrix_type>& matrix,
30 const Teuchos::Array<Teuchos::Array<LO> >& partitions,
31 const Teuchos::RCP<const import_type>&,
32 bool pointIndexed)
33 : ContainerImpl<MatrixType, LocalScalarType>(matrix, partitions, pointIndexed)
34 , ipiv_(this->blockRows_.size() * this->scalarsPerRow_)
35 , kl_(this->numBlocks_, -1)
36 , ku_(this->numBlocks_, -1)
37 , scalarOffsets_(this->numBlocks_) {
38 TEUCHOS_TEST_FOR_EXCEPTION(
39 !matrix->hasColMap(), std::invalid_argument,
40 "Ifpack2::BandedContainer: "
41 "The constructor's input matrix must have a column Map.");
42}
43
44template <class MatrixType, class LocalScalarType>
47
48template <class MatrixType, class LocalScalarType>
50 setParameters(const Teuchos::ParameterList& List) {
51 if (List.isParameter("relaxation: banded container superdiagonals")) {
52 int ku = List.get<int>("relaxation: banded container superdiagonals");
53 for (LO b = 0; b < this->numBlocks_; b++)
54 ku_[b] = ku;
55 }
56 if (List.isParameter("relaxation: banded container subdiagonals")) {
57 int kl = List.get<int>("relaxation: banded container subdiagonals");
58 for (LO b = 0; b < this->numBlocks_; b++)
59 kl_[b] = kl;
60 }
61}
62
63template <class MatrixType, class LocalScalarType>
66 using Teuchos::Array;
67 using Teuchos::ArrayView;
68 // now, for any block where kl_ or ku_ has not already been set, compute the actual bandwidth
69 const LO INVALID = Teuchos::OrdinalTraits<LO>::invalid();
70 size_t colToOffsetSize = this->inputMatrix_->getLocalNumCols();
71 if (this->pointIndexed_)
72 colToOffsetSize *= this->bcrsBlockSize_;
73 Array<LO> colToBlockOffset(colToOffsetSize, INVALID);
74 // Same logic as extract() to find entries in blocks efficiently
75 //(but here, just to find bandwidth, no scalars used)
76 for (int i = 0; i < this->numBlocks_; i++) {
77 // maxSub, maxSuper are the maximum lower and upper bandwidth
78 LO maxSub = 0;
79 LO maxSuper = 0;
80 if (this->scalarsPerRow_ > 1) {
81 // Get the interval where block i is defined in blockRows_
82 LO blockStart = this->blockOffsets_[i];
83 LO blockEnd = (i == this->numBlocks_ - 1) ? this->blockRows_.size() : this->blockOffsets_[i + 1];
84 ArrayView<const LO> blockRows = this->getBlockRows(i);
85 // Set the lookup table entries for the columns appearing in block i.
86 // If OverlapLevel_ > 0, then this may overwrite values for previous blocks, but
87 // this is OK. The values updated here are only needed to process block i's entries.
88 for (size_t j = 0; j < size_t(blockRows.size()); j++) {
89 LO localCol = this->translateRowToCol(blockRows[j]);
90 colToBlockOffset[localCol] = blockStart + j;
91 }
92
93 using h_inds_type = typename block_crs_matrix_type::local_inds_host_view_type;
94 using h_vals_type = typename block_crs_matrix_type::values_host_view_type;
95 for (LO blockRow = 0; blockRow < LO(blockRows.size()); blockRow++) {
96 // get a raw view of the whole block row
97 h_inds_type indices;
98 h_vals_type values;
99 LO inputRow = this->blockRows_[blockStart + blockRow];
100 this->inputBlockMatrix_->getLocalRowView(inputRow, indices, values);
101 LO numEntries = (LO)indices.size();
102 for (LO k = 0; k < numEntries; k++) {
103 LO colOffset = colToBlockOffset[indices[k]];
104 if (blockStart <= colOffset && colOffset < blockEnd) {
105 // This entry does appear in the diagonal block.
106 //(br, bc) identifies the scalar's position in the BlockCrs block.
107 // Convert this to (r, c) which is its position in the container block.
108 LO blockCol = colOffset - blockStart;
109 for (LO bc = 0; bc < this->bcrsBlockSize_; bc++) {
110 for (LO br = 0; br < this->bcrsBlockSize_; br++) {
111 LO r = this->bcrsBlockSize_ * blockRow + br;
112 LO c = this->bcrsBlockSize_ * blockCol + bc;
113 if (r - c > maxSub)
114 maxSub = r - c;
115 if (c - r > maxSuper)
116 maxSuper = c - r;
117 }
118 }
119 }
120 }
121 }
122 } else {
123 // Get the interval where block i is defined in blockRows_
124 LO blockStart = this->blockOffsets_[i];
125 LO blockEnd = (i == this->numBlocks_ - 1) ? this->blockRows_.size() : this->blockOffsets_[i + 1];
126 ArrayView<const LO> blockRows = this->getBlockRows(i);
127 // Set the lookup table entries for the columns appearing in block i.
128 // If OverlapLevel_ > 0, then this may overwrite values for previous blocks, but
129 // this is OK. The values updated here are only needed to process block i's entries.
130 for (size_t j = 0; j < size_t(blockRows.size()); j++) {
131 // translateRowToCol will return the corresponding split column
132 LO localCol = this->translateRowToCol(blockRows[j]);
133 colToBlockOffset[localCol] = blockStart + j;
134 }
135 for (LO blockRow = 0; blockRow < LO(blockRows.size()); blockRow++) {
136 // get a view of the general row
137 LO inputSplitRow = this->blockRows_[blockStart + blockRow];
138 auto rowView = this->getInputRowView(inputSplitRow);
139 for (size_t k = 0; k < rowView.size(); k++) {
140 LO colOffset = colToBlockOffset[rowView.ind(k)];
141 if (blockStart <= colOffset && colOffset < blockEnd) {
142 LO blockCol = colOffset - blockStart;
143 maxSub = std::max(maxSub, blockRow - blockCol);
144 maxSuper = std::max(maxSuper, blockCol - blockRow);
145 }
146 }
147 }
148 }
149 kl_[i] = maxSub;
150 ku_[i] = maxSuper;
151 }
152}
153
154template <class MatrixType, class LocalScalarType>
156 initialize() {
157 // note: in BlockRelaxation, Container_->setParameters() immediately
158 // precedes Container_->initialize(). So no matter what, either all
159 // the block bandwidths were set (in setParameters()) or none of them were.
160 // If none were they must be computed individually.
161 if (kl_[0] == -1)
162 computeBandwidth();
163 GO totalScalars = 0;
164 for (LO b = 0; b < this->numBlocks_; b++) {
165 LO stride = 2 * kl_[b] + ku_[b] + 1;
166 scalarOffsets_[b] = totalScalars;
167 totalScalars += stride * this->blockSizes_[b] * this->scalarsPerRow_;
168 }
169 scalars_.resize(totalScalars);
170 for (int b = 0; b < this->numBlocks_; b++) {
171 // NOTE: the stride and upper bandwidth used to construct the SerialBandDenseMatrix looks
172 // too large, but the extra kl_ in upper band space is needed by the LAPACK factorization routine.
173 LO nrows = this->blockSizes_[b] * this->scalarsPerRow_;
174 diagBlocks_.emplace_back(Teuchos::View, scalars_.data() + scalarOffsets_[b], 2 * kl_[b] + ku_[b] + 1, nrows, nrows, kl_[b], kl_[b] + ku_[b]);
175 diagBlocks_[b].putScalar(Teuchos::ScalarTraits<LSC>::zero());
176 }
177 std::fill(ipiv_.begin(), ipiv_.end(), 0);
178 // We assume that if you called this method, you intend to recompute
179 // everything.
180 this->IsComputed_ = false;
181 this->IsInitialized_ = true;
182}
183
184template <class MatrixType, class LocalScalarType>
186 compute() {
187 TEUCHOS_TEST_FOR_EXCEPTION(
188 ipiv_.size() != this->blockRows_.size() * this->scalarsPerRow_, std::logic_error,
189 "Ifpack2::BandedContainer::compute: ipiv_ array has the wrong size. "
190 "Please report this bug to the Ifpack2 developers.");
191
192 this->IsComputed_ = false;
193 if (!this->isInitialized()) {
194 this->initialize();
195 }
196
197 extract(); // Extract the submatrices
198 factor(); // Factor them
199
200 this->IsComputed_ = true;
201}
202
203template <class MatrixType, class LocalScalarType>
205 using Teuchos::Array;
206 using Teuchos::ArrayView;
207 using STS = Teuchos::ScalarTraits<SC>;
208 SC zero = STS::zero();
209 const LO INVALID = Teuchos::OrdinalTraits<LO>::invalid();
210 // To extract diagonal blocks, need to translate local rows to local columns.
211 // Strategy: make a lookup table that translates local cols in the matrix to offsets in blockRows_:
212 // blockOffsets_[b] <= offset < blockOffsets_[b+1]: tests whether the column is in block b.
213 // offset - blockOffsets_[b]: gives the column within block b.
214 //
215 // This provides the block and col within a block in O(1).
216 if (this->scalarsPerRow_ > 1) {
217 Array<LO> colToBlockOffset(this->inputBlockMatrix_->getLocalNumCols(), INVALID);
218 for (int i = 0; i < this->numBlocks_; i++) {
219 // Get the interval where block i is defined in blockRows_
220 LO blockStart = this->blockOffsets_[i];
221 LO blockEnd = blockStart + this->blockSizes_[i];
222 ArrayView<const LO> blockRows = this->getBlockRows(i);
223 // Set the lookup table entries for the columns appearing in block i.
224 // If OverlapLevel_ > 0, then this may overwrite values for previous blocks, but
225 // this is OK. The values updated here are only needed to process block i's entries.
226 for (size_t j = 0; j < size_t(blockRows.size()); j++) {
227 LO localCol = this->translateRowToCol(blockRows[j]);
228 colToBlockOffset[localCol] = blockStart + j;
229 }
230 using h_inds_type = typename block_crs_matrix_type::local_inds_host_view_type;
231 using h_vals_type = typename block_crs_matrix_type::values_host_view_type;
232 for (LO blockRow = 0; blockRow < LO(blockRows.size()); blockRow++) {
233 // get a raw view of the whole block row
234 h_inds_type indices;
235 h_vals_type values;
236 LO inputRow = this->blockRows_[blockStart + blockRow];
237 this->inputBlockMatrix_->getLocalRowView(inputRow, indices, values);
238 LO numEntries = (LO)indices.size();
239 for (LO k = 0; k < numEntries; k++) {
240 LO colOffset = colToBlockOffset[indices[k]];
241 if (blockStart <= colOffset && colOffset < blockEnd) {
242 // This entry does appear in the diagonal block.
243 //(br, bc) identifies the scalar's position in the BlockCrs block.
244 // Convert this to (r, c) which is its position in the container block.
245 LO blockCol = colOffset - blockStart;
246 for (LO bc = 0; bc < this->bcrsBlockSize_; bc++) {
247 for (LO br = 0; br < this->bcrsBlockSize_; br++) {
248 LO r = this->bcrsBlockSize_ * blockRow + br;
249 LO c = this->bcrsBlockSize_ * blockCol + bc;
250 auto val = values[k * (this->bcrsBlockSize_ * this->bcrsBlockSize_) + (br + this->bcrsBlockSize_ * bc)];
251 if (val != zero)
252 diagBlocks_[i](r, c) = val;
253 }
254 }
255 }
256 }
257 }
258 }
259 } else {
260 // get the mapping from point-indexed matrix columns to offsets in blockRows_
261 //(this includes regular CrsMatrix columns, in which case bcrsBlockSize_ == 1)
262 Array<LO> colToBlockOffset(this->inputMatrix_->getLocalNumCols() * this->bcrsBlockSize_, INVALID);
263 for (int i = 0; i < this->numBlocks_; i++) {
264 // Get the interval where block i is defined in blockRows_
265 LO blockStart = this->blockOffsets_[i];
266 LO blockEnd = blockStart + this->blockSizes_[i];
267 ArrayView<const LO> blockRows = this->getBlockRows(i);
268 // Set the lookup table entries for the columns appearing in block i.
269 // If OverlapLevel_ > 0, then this may overwrite values for previous blocks, but
270 // this is OK. The values updated here are only needed to process block i's entries.
271 for (size_t j = 0; j < size_t(blockRows.size()); j++) {
272 // translateRowToCol will return the corresponding split column
273 LO localCol = this->translateRowToCol(blockRows[j]);
274 colToBlockOffset[localCol] = blockStart + j;
275 }
276 for (size_t blockRow = 0; blockRow < size_t(blockRows.size()); blockRow++) {
277 // get a view of the split row
278 LO inputPointRow = this->blockRows_[blockStart + blockRow];
279 auto rowView = this->getInputRowView(inputPointRow);
280 for (size_t k = 0; k < rowView.size(); k++) {
281 LO colOffset = colToBlockOffset[rowView.ind(k)];
282 if (blockStart <= colOffset && colOffset < blockEnd) {
283 LO blockCol = colOffset - blockStart;
284 auto val = rowView.val(k);
285 if (val != zero)
286 diagBlocks_[i](blockRow, blockCol) = rowView.val(k);
287 }
288 }
289 }
290 }
291 }
292}
293
294template <class MatrixType, class LocalScalarType>
295void BandedContainer<MatrixType, LocalScalarType>::
296 clearBlocks() {
297 diagBlocks_.clear();
298 scalars_.clear();
299 ContainerImpl<MatrixType, LocalScalarType>::clearBlocks();
300}
301
302template <class MatrixType, class LocalScalarType>
303void BandedContainer<MatrixType, LocalScalarType>::
304 factor() {
305 Teuchos::LAPACK<int, LSC> lapack;
306 int INFO = 0;
307
308 for (int i = 0; i < this->numBlocks_; i++) {
309 // Plausibility checks for matrix
310 TEUCHOS_TEST_FOR_EXCEPTION(diagBlocks_[i].values() == 0, std::invalid_argument,
311 "BandedContainer<T>::factor: Diagonal block is an empty SerialBandDenseMatrix<T>!");
312 TEUCHOS_TEST_FOR_EXCEPTION(diagBlocks_[i].upperBandwidth() < diagBlocks_[i].lowerBandwidth(), std::invalid_argument,
313 "BandedContainer<T>::factor: Diagonal block needs kl additional superdiagonals for factorization! However, the number of superdiagonals is smaller than the number of subdiagonals!");
314 int* blockIpiv = &ipiv_[this->blockOffsets_[i] * this->scalarsPerRow_];
315 lapack.GBTRF(diagBlocks_[i].numRows(),
316 diagBlocks_[i].numCols(),
317 diagBlocks_[i].lowerBandwidth(),
318 diagBlocks_[i].upperBandwidth() - diagBlocks_[i].lowerBandwidth(), /* enter the real number of superdiagonals (see Teuchos_SerialBandDenseSolver)*/
319 diagBlocks_[i].values(),
320 diagBlocks_[i].stride(),
321 blockIpiv,
322 &INFO);
323
324 // INFO < 0 is a bug.
325 TEUCHOS_TEST_FOR_EXCEPTION(
326 INFO < 0, std::logic_error,
327 "Ifpack2::BandedContainer::factor: "
328 "LAPACK's _GBTRF (LU factorization with partial pivoting) was called "
329 "incorrectly. INFO = "
330 << INFO << " < 0. "
331 "Please report this bug to the Ifpack2 developers.");
332 // INFO > 0 means the matrix is singular. This is probably an issue
333 // either with the choice of rows the rows we extracted, or with the
334 // input matrix itself.
335 TEUCHOS_TEST_FOR_EXCEPTION(
336 INFO > 0, std::runtime_error,
337 "Ifpack2::BandedContainer::factor: "
338 "LAPACK's _GBTRF (LU factorization with partial pivoting) reports that the "
339 "computed U factor is exactly singular. U("
340 << INFO << "," << INFO << ") "
341 "(one-based index i) is exactly zero. This probably means that the input "
342 "matrix has a singular diagonal block.");
343 }
344}
345
346template <class MatrixType, class LocalScalarType>
347void BandedContainer<MatrixType, LocalScalarType>::
348 solveBlock(ConstHostSubviewLocal X,
349 HostSubviewLocal Y,
350 int blockIndex,
351 Teuchos::ETransp mode,
352 const LSC alpha,
353 const LSC beta) const {
354#ifdef HAVE_IFPACK2_DEBUG
355 TEUCHOS_TEST_FOR_EXCEPTION(
356 X.extent(0) != Y.extent(0),
357 std::logic_error,
358 "Ifpack2::BandedContainer::solveBlock: X and Y have "
359 "incompatible dimensions ("
360 << X.extent(0) << " resp. "
361 << Y.extent(0) << "). Please report this bug to "
362 "the Ifpack2 developers.");
363 TEUCHOS_TEST_FOR_EXCEPTION(
364 X.extent(0) != static_cast<size_t>(mode == Teuchos::NO_TRANS ? diagBlocks_[blockIndex].numCols() : diagBlocks_[blockIndex].numRows()),
365 std::logic_error,
366 "Ifpack2::BandedContainer::solveBlock: The input "
367 "multivector X has incompatible dimensions from those of the "
368 "inverse operator ("
369 << X.extent(0) << " vs. "
370 << (mode == Teuchos::NO_TRANS ? diagBlocks_[blockIndex].numCols() : diagBlocks_[blockIndex].numRows())
371 << "). Please report this bug to the Ifpack2 developers.");
372 TEUCHOS_TEST_FOR_EXCEPTION(
373 Y.extent(0) != static_cast<size_t>(mode == Teuchos::NO_TRANS ? diagBlocks_[blockIndex].numRows() : diagBlocks_[blockIndex].numCols()),
374 std::logic_error,
375 "Ifpack2::BandedContainer::solveBlock: The output "
376 "multivector Y has incompatible dimensions from those of the "
377 "inverse operator ("
378 << Y.extent(0) << " vs. "
379 << (mode == Teuchos::NO_TRANS ? diagBlocks_[blockIndex].numRows() : diagBlocks_[blockIndex].numCols())
380 << "). Please report this bug to the Ifpack2 developers.");
381#endif
382
383 size_t numRows = X.extent(0);
384 size_t numVecs = X.extent(1);
385
386 LSC zero = Teuchos::ScalarTraits<LSC>::zero();
387 if (alpha == zero) { // don't need to solve the linear system
388 if (beta == zero) {
389 // Use BLAS AXPY semantics for beta == 0: overwrite, clobbering
390 // any Inf or NaN values in Y (rather than multiplying them by
391 // zero, resulting in NaN values).
392 for (size_t j = 0; j < numVecs; j++)
393 for (size_t i = 0; i < numRows; i++)
394 Y(i, j) = zero;
395 } else { // beta != 0
396 for (size_t j = 0; j < numVecs; j++)
397 for (size_t i = 0; i < numRows; i++)
398 Y(i, j) = beta * Y(i, j);
399 }
400 } else { // alpha != 0; must solve the linear system
401 Teuchos::LAPACK<int, LSC> lapack;
402 // If beta is nonzero or Y is not constant stride, we have to use
403 // a temporary output multivector. It gets a copy of X, since
404 // GBTRS overwrites its (multi)vector input with its output.
405 std::vector<LSC> yTemp(numVecs * numRows);
406 for (size_t j = 0; j < numVecs; j++) {
407 for (size_t i = 0; i < numRows; i++)
408 yTemp[j * numRows + i] = X(i, j);
409 }
410
411 int INFO = 0;
412 const char trans = (mode == Teuchos::CONJ_TRANS ? 'C' : (mode == Teuchos::TRANS ? 'T' : 'N'));
413
414 const int* blockIpiv = &ipiv_[this->blockOffsets_[blockIndex] * this->scalarsPerRow_];
415
416 lapack.GBTRS(trans,
417 diagBlocks_[blockIndex].numCols(),
418 diagBlocks_[blockIndex].lowerBandwidth(),
419 /* enter the real number of superdiagonals (see Teuchos_SerialBandDenseSolver)*/
420 diagBlocks_[blockIndex].upperBandwidth() - diagBlocks_[blockIndex].lowerBandwidth(),
421 numVecs,
422 diagBlocks_[blockIndex].values(),
423 diagBlocks_[blockIndex].stride(),
424 blockIpiv,
425 yTemp.data(),
426 numRows,
427 &INFO);
428
429 if (beta != zero) {
430 for (size_t j = 0; j < numVecs; j++) {
431 for (size_t i = 0; i < numRows; i++) {
432 Y(i, j) *= ISC(beta);
433 Y(i, j) += ISC(alpha * yTemp[j * numRows + i]);
434 }
435 }
436 } else {
437 for (size_t j = 0; j < numVecs; j++) {
438 for (size_t i = 0; i < numRows; i++)
439 Y(i, j) = ISC(yTemp[j * numRows + i]);
440 }
441 }
442
443 TEUCHOS_TEST_FOR_EXCEPTION(
444 INFO != 0, std::runtime_error,
445 "Ifpack2::BandedContainer::solveBlock: "
446 "LAPACK's _GBTRS (solve using LU factorization with partial pivoting) "
447 "failed with INFO = "
448 << INFO << " != 0.");
449 }
450}
451
452template <class MatrixType, class LocalScalarType>
453std::ostream&
455 print(std::ostream& os) const {
456 Teuchos::FancyOStream fos(Teuchos::rcpFromRef(os));
457 fos.setOutputToRootOnly(0);
458 describe(fos);
459 return os;
460}
461
462template <class MatrixType, class LocalScalarType>
463std::string
465 description() const {
466 std::ostringstream oss;
467 oss << Teuchos::Describable::description();
468 if (this->isInitialized()) {
469 if (this->isComputed()) {
470 oss << "{status = initialized, computed";
471 } else {
472 oss << "{status = initialized, not computed";
473 }
474 } else {
475 oss << "{status = not initialized, not computed";
476 }
477 oss << "}";
478 return oss.str();
479}
480
481template <class MatrixType, class LocalScalarType>
483 describe(Teuchos::FancyOStream& os,
484 const Teuchos::EVerbosityLevel verbLevel) const {
485 if (verbLevel == Teuchos::VERB_NONE) return;
486 os << "================================================================================" << std::endl;
487 os << "Ifpack2::BandedContainer" << std::endl;
488 for (int i = 0; i < this->numBlocks_; i++) {
489 os << "Block " << i << ": Number of rows = " << this->blockSizes_[i] << std::endl;
490 os << "Block " << i << ": Number of subdiagonals = " << diagBlocks_[i].lowerBandwidth() << std::endl;
491 os << "Block " << i << ": Number of superdiagonals = " << diagBlocks_[i].upperBandwidth() << std::endl;
492 }
493 os << "isInitialized() = " << this->IsInitialized_ << std::endl;
494 os << "isComputed() = " << this->IsComputed_ << std::endl;
495 os << "================================================================================" << std::endl;
496 os << std::endl;
497}
498
499template <class MatrixType, class LocalScalarType>
501 return "Banded";
502}
503
504} // namespace Ifpack2
505
506#define IFPACK2_BANDEDCONTAINER_INSTANT(S, LO, GO, N) \
507 template class Ifpack2::BandedContainer<Tpetra::RowMatrix<S, LO, GO, N>, S>;
508
509#endif // IFPACK2_BANDEDCONTAINER_HPP
Store and solve a local Banded linear problem.
Definition Ifpack2_BandedContainer_decl.hpp:70
BandedContainer(const Teuchos::RCP< const row_matrix_type > &matrix, const Teuchos::Array< Teuchos::Array< LO > > &partitions, const Teuchos::RCP< const import_type > &, bool pointIndexed)
Constructor.
Definition Ifpack2_BandedContainer_def.hpp:29
virtual void compute() override
Initialize and compute each block.
Definition Ifpack2_BandedContainer_def.hpp:186
virtual void initialize() override
Do all set-up operations that only require matrix structure.
Definition Ifpack2_BandedContainer_def.hpp:156
virtual std::ostream & print(std::ostream &os) const override
Print information about this object to the given output stream.
Definition Ifpack2_BandedContainer_def.hpp:455
virtual ~BandedContainer()
Destructor (declared virtual for memory safety of derived classes).
Definition Ifpack2_BandedContainer_def.hpp:46
virtual void setParameters(const Teuchos::ParameterList &List) override
Set all necessary parameters (super- and sub-diagonal bandwidth)
Definition Ifpack2_BandedContainer_def.hpp:50
static std::string getName()
Get the name of this container type for Details::constructContainer()
Definition Ifpack2_BandedContainer_def.hpp:500
virtual std::string description() const override
A one-line description of this object.
Definition Ifpack2_BandedContainer_def.hpp:465
void computeBandwidth()
Definition Ifpack2_BandedContainer_def.hpp:65
virtual void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const override
Print the object with some verbosity level to the given FancyOStream.
Definition Ifpack2_BandedContainer_def.hpp:483
The implementation of the numerical features of Container (Jacobi, Gauss-Seidel, SGS)....
Definition Ifpack2_Container_decl.hpp:311
Preconditioners and smoothers for Tpetra sparse matrices.
Definition Ifpack2_AdditiveSchwarz_decl.hpp:40