Ifpack2 Templated Preconditioning Package  Version 1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
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>
21 #else
22 #include "Teuchos_DefaultSerialComm.hpp"
23 #endif // HAVE_MPI
24 
25 namespace Ifpack2 {
26 
27 template <class MatrixType, class LocalScalarType>
30  const Teuchos::Array<Teuchos::Array<LO> >& partitions,
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_) {
39  !matrix->hasColMap(), std::invalid_argument,
40  "Ifpack2::BandedContainer: "
41  "The constructor's input matrix must have a column Map.");
42 }
43 
44 template <class MatrixType, class LocalScalarType>
47 
48 template <class MatrixType, class LocalScalarType>
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 
63 template <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 
154 template <class MatrixType, class LocalScalarType>
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 
184 template <class MatrixType, class LocalScalarType>
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 
203 template <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 
294 template <class MatrixType, class LocalScalarType>
295 void BandedContainer<MatrixType, LocalScalarType>::
296  clearBlocks() {
297  diagBlocks_.clear();
298  scalars_.clear();
299  ContainerImpl<MatrixType, LocalScalarType>::clearBlocks();
300 }
301 
302 template <class MatrixType, class LocalScalarType>
303 void BandedContainer<MatrixType, LocalScalarType>::
304  factor() {
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.
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.
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 
346 template <class MatrixType, class LocalScalarType>
347 void 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
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.");
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.");
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 
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
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 
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 
452 template <class MatrixType, class LocalScalarType>
453 std::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 
462 template <class MatrixType, class LocalScalarType>
463 std::string
465  description() const {
466  std::ostringstream oss;
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 
481 template <class MatrixType, class LocalScalarType>
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 
499 template <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
virtual void initialize() override
Do all set-up operations that only require matrix structure.
Definition: Ifpack2_BandedContainer_def.hpp:156
T & get(const std::string &name, T def_value)
The implementation of the numerical features of Container (Jacobi, Gauss-Seidel, SGS). This class allows a custom scalar type (LocalScalarType) to be used for storing blocks and solving the block systems. Hiding this template parameter from the Container interface simplifies the BlockRelaxation and ContainerFactory classes.
Definition: Ifpack2_Container_decl.hpp:307
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void GBTRF(const OrdinalType &m, const OrdinalType &n, const OrdinalType &kl, const OrdinalType &ku, ScalarType *A, const OrdinalType &lda, OrdinalType *IPIV, OrdinalType *info) const
virtual void compute() override
Initialize and compute each block.
Definition: Ifpack2_BandedContainer_def.hpp:186
bool isParameter(const std::string &name) const
virtual std::string description() const
static std::string getName()
Get the name of this container type for Details::constructContainer()
Definition: Ifpack2_BandedContainer_def.hpp:500
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
basic_FancyOStream & setOutputToRootOnly(const int rootRank)
virtual ~BandedContainer()
Destructor (declared virtual for memory safety of derived classes).
Definition: Ifpack2_BandedContainer_def.hpp:46
void computeBandwidth()
Definition: Ifpack2_BandedContainer_def.hpp:65
void GBTRS(const char &TRANS, const OrdinalType &n, const OrdinalType &kl, const OrdinalType &ku, const OrdinalType &nrhs, const ScalarType *A, const OrdinalType &lda, const OrdinalType *IPIV, ScalarType *B, const OrdinalType &ldb, OrdinalType *info) const
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 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
virtual void setParameters(const Teuchos::ParameterList &List) override
Set all necessary parameters (super- and sub-diagonal bandwidth)
Definition: Ifpack2_BandedContainer_def.hpp:50
Store and solve a local Banded linear problem.
Definition: Ifpack2_BandedContainer_decl.hpp:69
virtual std::string description() const override
A one-line description of this object.
Definition: Ifpack2_BandedContainer_def.hpp:465