Ifpack2 Templated Preconditioning Package  Version 1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Ifpack2_Details_TriDiSolver_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_DETAILS_TRIDISOLVER_DEF_HPP
11 #define IFPACK2_DETAILS_TRIDISOLVER_DEF_HPP
12 
13 #include "Ifpack2_LocalFilter.hpp"
14 #include "Teuchos_LAPACK.hpp"
15 #include "Tpetra_MultiVector.hpp"
16 #include "Tpetra_Map.hpp"
17 #include "Tpetra_Import.hpp"
18 #include "Tpetra_Export.hpp"
19 
20 #ifdef HAVE_MPI
21 #include <mpi.h>
23 #else
24 #include "Teuchos_DefaultSerialComm.hpp"
25 #endif // HAVE_MPI
26 
27 namespace Ifpack2 {
28 namespace Details {
29 
31 // Non-stub (full) implementation
33 
34 template <class MatrixType>
37  : A_(A)
38  , initializeTime_(0.0)
39  , computeTime_(0.0)
40  , applyTime_(0.0)
41  , numInitialize_(0)
42  , numCompute_(0)
43  , numApply_(0)
44  , isInitialized_(false)
45  , isComputed_(false) {}
46 
47 template <class MatrixType>
51  A_.is_null(), std::runtime_error,
52  "Ifpack2::Details::TriDiSolver::"
53  "getDomainMap: The input matrix A is null. Please call setMatrix() with a "
54  "nonnull input matrix before calling this method.");
55  // For an input matrix A, TriDiSolver solves Ax=b for x.
56  // Thus, its Maps are reversed from those of the input matrix.
57  return A_->getRangeMap();
58 }
59 
60 template <class MatrixType>
64  A_.is_null(), std::runtime_error,
65  "Ifpack2::Details::TriDiSolver::"
66  "getRangeMap: The input matrix A is null. Please call setMatrix() with a "
67  "nonnull input matrix before calling this method.");
68  // For an input matrix A, TriDiSolver solves Ax=b for x.
69  // Thus, its Maps are reversed from those of the input matrix.
70  return A_->getDomainMap();
71 }
72 
73 template <class MatrixType>
76  (void)params; // this preconditioner doesn't currently take any parameters
77 }
78 
79 template <class MatrixType>
81  return isInitialized_;
82 }
83 
84 template <class MatrixType>
86  return isComputed_;
87 }
88 
89 template <class MatrixType>
91  return numInitialize_;
92 }
93 
94 template <class MatrixType>
96  return numCompute_;
97 }
98 
99 template <class MatrixType>
101  return numApply_;
102 }
103 
104 template <class MatrixType>
105 double
107  return initializeTime_;
108 }
109 
110 template <class MatrixType>
111 double
113  return computeTime_;
114 }
115 
116 template <class MatrixType>
117 double
119  return applyTime_;
120 }
121 
122 template <class MatrixType>
125  return A_;
126 }
127 
128 template <class MatrixType>
130  reset() {
131  isInitialized_ = false;
132  isComputed_ = false;
133  A_local_ = Teuchos::null;
134  A_local_tridi_.reshape(0);
135  ipiv_.resize(0);
136 }
137 
138 template <class MatrixType>
141  // It's legitimate to call setMatrix() with a null input. This has
142  // the effect of resetting the preconditioner's internal state.
143  if (!A_.is_null()) {
144  const global_size_t numRows = A->getRangeMap()->getGlobalNumElements();
145  const global_size_t numCols = A->getDomainMap()->getGlobalNumElements();
147  numRows != numCols, std::invalid_argument,
148  "Ifpack2::Details::TriDiSolver::"
149  "setMatrix: Input matrix must be (globally) square. "
150  "The matrix you provided is "
151  << numRows << " by " << numCols << ".");
152  }
153  // Clear any previously computed objects.
154  reset();
155 
156  // Now that we've cleared the state, we can keep the matrix.
157  A_ = A;
158 }
159 
160 template <class MatrixType>
162  using Teuchos::Comm;
163  using Teuchos::null;
164  using Teuchos::RCP;
165  using Teuchos::rcp;
166  using Teuchos::Time;
167  using Teuchos::TimeMonitor;
168  const std::string timerName("Ifpack2::Details::TriDiSolver::initialize");
169 
170  RCP<Time> timer = TimeMonitor::lookupCounter(timerName);
171  if (timer.is_null()) {
172  timer = TimeMonitor::getNewCounter(timerName);
173  }
174 
175  double startTime = timer->wallTime();
176 
177  { // Begin timing here.
178  Teuchos::TimeMonitor timeMon(*timer);
179 
181  A_.is_null(), std::runtime_error,
182  "Ifpack2::Details::TriDiSolver::"
183  "initialize: The input matrix A is null. Please call setMatrix() "
184  "with a nonnull input before calling this method.");
185 
187  !A_->hasColMap(), std::invalid_argument,
188  "Ifpack2::Details::TriDiSolver: "
189  "The constructor's input matrix must have a column Map, "
190  "so that it has local indices.");
191 
192  // Clear any previously computed objects.
193  reset();
194 
195  // Make the local filter of the input matrix A.
196  if (A_->getComm()->getSize() > 1) {
197  A_local_ = rcp(new LocalFilter<row_matrix_type>(A_));
198  } else {
199  A_local_ = A_;
200  }
201 
203  A_local_.is_null(), std::logic_error,
204  "Ifpack2::Details::TriDiSolver::"
205  "initialize: A_local_ is null after it was supposed to have been "
206  "initialized. Please report this bug to the Ifpack2 developers.");
207 
208  // Allocate the TriDi local matrix and the pivot array.
209  const size_t numRows = A_local_->getLocalNumRows();
210  const size_t numCols = A_local_->getLocalNumCols();
212  numRows != numCols, std::logic_error,
213  "Ifpack2::Details::TriDiSolver::"
214  "initialize: Local filter matrix is not square. This should never happen. "
215  "Please report this bug to the Ifpack2 developers.");
216  A_local_tridi_.reshape(numRows);
217  ipiv_.resize(numRows);
218  std::fill(ipiv_.begin(), ipiv_.end(), 0);
219 
220  isInitialized_ = true;
221  ++numInitialize_;
222  }
223 
224  initializeTime_ += (timer->wallTime() - startTime);
225 }
226 
227 template <class MatrixType>
229 
230 template <class MatrixType>
232  using Teuchos::RCP;
233  const std::string timerName("Ifpack2::Details::TriDiSolver::compute");
234 
235  RCP<Teuchos::Time> timer = Teuchos::TimeMonitor::lookupCounter(timerName);
236  if (timer.is_null()) {
237  timer = Teuchos::TimeMonitor::getNewCounter(timerName);
238  }
239 
240  double startTime = timer->wallTime();
241 
242  // Begin timing here.
243  {
244  Teuchos::TimeMonitor timeMon(*timer);
246  A_.is_null(), std::runtime_error,
247  "Ifpack2::Details::TriDiSolver::"
248  "compute: The input matrix A is null. Please call setMatrix() with a "
249  "nonnull input, then call initialize(), before calling this method.");
250 
252  A_local_.is_null(), std::logic_error,
253  "Ifpack2::Details::TriDiSolver::"
254  "compute: A_local_ is null. Please report this bug to the Ifpack2 "
255  "developers.");
256 
257  isComputed_ = false;
258  if (!this->isInitialized()) {
259  this->initialize();
260  }
261  extract(A_local_tridi_, *A_local_); // extract the tridi local matrix
262 
263  factor(A_local_tridi_, ipiv_()); // factor the tridi local matrix
264 
265  isComputed_ = true;
266  ++numCompute_;
267  }
268  computeTime_ += (timer->wallTime() - startTime);
269 }
270 
271 template <class MatrixType>
273  const Teuchos::ArrayView<int>& ipiv) {
274  // Fill the LU permutation array with zeros.
275  std::fill(ipiv.begin(), ipiv.end(), 0);
276 
278  int INFO = 0;
279  lapack.GTTRF(A.numRowsCols(),
280  A.DL(),
281  A.D(),
282  A.DU(),
283  A.DU2(),
284  ipiv.getRawPtr(), &INFO);
285  // INFO < 0 is a bug.
287  INFO < 0, std::logic_error,
288  "Ifpack2::Details::TriDiSolver::factor: "
289  "LAPACK's _GTTRF (tridiagonal LU factorization with partial pivoting) "
290  "was called incorrectly. INFO = "
291  << INFO << " < 0. "
292  "Please report this bug to the Ifpack2 developers.");
293  // INFO > 0 means the matrix is singular. This is probably an issue
294  // either with the choice of rows the rows we extracted, or with the
295  // input matrix itself.
297  INFO > 0, std::runtime_error,
298  "Ifpack2::Details::TriDiSolver::factor: "
299  "LAPACK's _GTTRF (tridiagonal LU factorization with partial pivoting) "
300  "reports that the computed U factor is exactly singular. U("
301  << INFO << "," << INFO << ") (one-based index i) is exactly zero. This probably "
302  "means that the input matrix has a singular diagonal block.");
303 }
304 
305 template <class MatrixType>
306 void TriDiSolver<MatrixType, false>::
307  applyImpl(const MV& X,
308  MV& Y,
309  const Teuchos::ETransp mode,
310  const scalar_type alpha,
311  const scalar_type beta) const {
312  using Teuchos::ArrayRCP;
313  using Teuchos::CONJ_TRANS;
314  using Teuchos::RCP;
315  using Teuchos::rcp;
316  using Teuchos::rcpFromRef;
317  using Teuchos::TRANS;
318 
319  const int numVecs = static_cast<int>(X.getNumVectors());
320  if (alpha == STS::zero()) { // don't need to solve the linear system
321  if (beta == STS::zero()) {
322  // Use BLAS AXPY semantics for beta == 0: overwrite, clobbering
323  // any Inf or NaN values in Y (rather than multiplying them by
324  // zero, resulting in NaN values).
325  Y.putScalar(STS::zero());
326  } else { // beta != 0
327  Y.scale(STS::zero());
328  }
329  } else { // alpha != 0; must solve the linear system
331  // If beta is nonzero, Y is not constant stride, or alpha != 1, we
332  // have to use a temporary output multivector Y_tmp. It gets a
333  // copy of alpha*X, since GETRS overwrites its (multi)vector input
334  // with its output.
335  RCP<MV> Y_tmp;
336  if (beta == STS::zero() && Y.isConstantStride() && alpha == STS::one()) {
337  deep_copy(Y, X);
338  Y_tmp = rcpFromRef(Y);
339  } else {
340  Y_tmp = rcp(new MV(createCopy(X))); // constructor copies X
341  if (alpha != STS::one()) {
342  Y_tmp->scale(alpha);
343  }
344  }
345  const int Y_stride = static_cast<int>(Y_tmp->getStride());
346  ArrayRCP<scalar_type> Y_view = Y_tmp->get1dViewNonConst();
347  scalar_type* const Y_ptr = Y_view.getRawPtr();
348  int INFO = 0;
349  const char trans =
350  (mode == CONJ_TRANS ? 'C' : (mode == TRANS ? 'T' : 'N'));
351  lapack.GTTRS(trans, A_local_tridi_.numRowsCols(), numVecs,
352  A_local_tridi_.DL(),
353  A_local_tridi_.D(),
354  A_local_tridi_.DU(),
355  A_local_tridi_.DU2(),
356  ipiv_.getRawPtr(), Y_ptr, Y_stride, &INFO);
358  INFO != 0, std::runtime_error,
359  "Ifpack2::Details::TriDiSolver::"
360  "applyImpl: LAPACK's _GTTRS (tridiagonal solve using LU factorization "
361  "with partial pivoting) failed with INFO = "
362  << INFO << " != 0.");
363 
364  if (beta != STS::zero()) {
365  Y.update(alpha, *Y_tmp, beta);
366  } else if (!Y.isConstantStride()) {
367  deep_copy(Y, *Y_tmp);
368  }
369  }
370 }
371 
372 template <class MatrixType>
374  apply(const Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type>& X,
375  Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type>& Y,
376  Teuchos::ETransp mode,
377  scalar_type alpha,
378  scalar_type beta) const {
379  using Teuchos::ArrayView;
380  using Teuchos::as;
381  using Teuchos::RCP;
382  using Teuchos::rcp;
383  using Teuchos::rcpFromRef;
384 
385  const std::string timerName("Ifpack2::Details::TriDiSolver::apply");
386  RCP<Teuchos::Time> timer = Teuchos::TimeMonitor::lookupCounter(timerName);
387  if (timer.is_null()) {
388  timer = Teuchos::TimeMonitor::getNewCounter(timerName);
389  }
390 
391  double startTime = timer->wallTime();
392 
393  // Begin timing here.
394  {
395  Teuchos::TimeMonitor timeMon(*timer);
396 
398  !isComputed_, std::runtime_error,
399  "Ifpack2::Details::TriDiSolver::apply: "
400  "You must have called the compute() method before you may call apply(). "
401  "You may call the apply() method as many times as you want after calling "
402  "compute() once, but you must have called compute() at least once.");
403 
404  const size_t numVecs = X.getNumVectors();
405 
407  numVecs != Y.getNumVectors(), std::runtime_error,
408  "Ifpack2::Details::TriDiSolver::apply: X and Y have different numbers "
409  "of vectors. X has "
410  << X.getNumVectors() << ", but Y has "
411  << X.getNumVectors() << ".");
412 
413  if (numVecs == 0) {
414  return; // done! nothing to do
415  }
416 
417  // Set up "local" views of X and Y.
418  RCP<const MV> X_local;
419  RCP<MV> Y_local;
420  const bool multipleProcs = (A_->getRowMap()->getComm()->getSize() >= 1);
421  if (multipleProcs) {
422  // Interpret X and Y as "local" multivectors, that is, in the
423  // local filter's domain resp. range Maps. "Interpret" means that
424  // we create views with different Maps; we don't have to copy.
425  X_local = X.offsetView(A_local_->getDomainMap(), 0);
426  Y_local = Y.offsetViewNonConst(A_local_->getRangeMap(), 0);
427  } else { // only one process in A_'s communicator
428  // X and Y are already "local"; no need to set up local views.
429  X_local = rcpFromRef(X);
430  Y_local = rcpFromRef(Y);
431  }
432 
433  // Apply the local operator:
434  // Y_local := beta*Y_local + alpha*M^{-1}*X_local
435  this->applyImpl(*X_local, *Y_local, mode, alpha, beta);
436 
437  ++numApply_; // We've successfully finished the work of apply().
438  }
439 
440  applyTime_ += (timer->wallTime() - startTime);
441 }
442 
443 template <class MatrixType>
445  std::ostringstream out;
446 
447  // Output is a valid YAML dictionary in flow style. If you don't
448  // like everything on a single line, you should call describe()
449  // instead.
450  out << "\"Ifpack2::Details::TriDiSolver\": ";
451  out << "{";
452  if (this->getObjectLabel() != "") {
453  out << "Label: \"" << this->getObjectLabel() << "\", ";
454  }
455  out << "Initialized: " << (isInitialized() ? "true" : "false") << ", "
456  << "Computed: " << (isComputed() ? "true" : "false") << ", ";
457 
458  if (A_.is_null()) {
459  out << "Matrix: null";
460  } else {
461  out << "Matrix: not null"
462  << ", Global matrix dimensions: ["
463  << A_->getGlobalNumRows() << ", " << A_->getGlobalNumCols() << "]";
464  }
465 
466  out << "}";
467  return out.str();
468 }
469 
470 template <class MatrixType>
472  const Teuchos::EVerbosityLevel verbLevel) const {
473  using std::endl;
474  using Teuchos::FancyOStream;
475  using Teuchos::OSTab;
476  using Teuchos::RCP;
477  using Teuchos::rcpFromRef;
478 
479  if (verbLevel == Teuchos::VERB_NONE) {
480  return;
481  } else {
482  RCP<FancyOStream> ptrOut = rcpFromRef(out);
483  OSTab tab1(ptrOut);
484  if (this->getObjectLabel() != "") {
485  out << "label: " << this->getObjectLabel() << endl;
486  }
487  out << "initialized: " << (isInitialized_ ? "true" : "false") << endl
488  << "computed: " << (isComputed_ ? "true" : "false") << endl
489  << "number of initialize calls: " << numInitialize_ << endl
490  << "number of compute calls: " << numCompute_ << endl
491  << "number of apply calls: " << numApply_ << endl
492  << "total time in seconds in initialize: " << initializeTime_ << endl
493  << "total time in seconds in compute: " << computeTime_ << endl
494  << "total time in seconds in apply: " << applyTime_ << endl;
495  if (verbLevel >= Teuchos::VERB_EXTREME) {
496  out << "A_local_tridi_:" << endl;
497  A_local_tridi_.print(out);
498  }
499  out << "ipiv_: " << Teuchos::toString(ipiv_) << endl;
500  }
501 }
502 
503 template <class MatrixType>
505  const Teuchos::EVerbosityLevel verbLevel) const {
506  using std::endl;
507  using Teuchos::FancyOStream;
508  using Teuchos::OSTab;
509  using Teuchos::RCP;
510  using Teuchos::rcpFromRef;
511 
512  RCP<FancyOStream> ptrOut = rcpFromRef(out);
513  OSTab tab0(ptrOut);
514  if (A_.is_null()) {
515  // If A_ is null, we don't have a communicator, so we can't
516  // safely print local data on all processes. Just print the
517  // local data without arbitration between processes, and hope
518  // for the best.
519  if (verbLevel > Teuchos::VERB_NONE) {
520  out << "Ifpack2::Details::TriDiSolver:" << endl;
521  }
522  describeLocal(out, verbLevel);
523  } else {
524  // If A_ is not null, we have a communicator, so we can
525  // arbitrate among all processes to print local data.
526  const Teuchos::Comm<int>& comm = *(A_->getRowMap()->getComm());
527  const int myRank = comm.getRank();
528  const int numProcs = comm.getSize();
529  if (verbLevel > Teuchos::VERB_NONE && myRank == 0) {
530  out << "Ifpack2::Details::TriDiSolver:" << endl;
531  }
532  OSTab tab1(ptrOut);
533  for (int p = 0; p < numProcs; ++p) {
534  if (myRank == p) {
535  out << "Process " << myRank << ":" << endl;
536  describeLocal(out, verbLevel);
537  }
538  comm.barrier();
539  comm.barrier();
540  comm.barrier();
541  } // for p = 0 .. numProcs-1
542  }
543 }
544 
545 template <class MatrixType>
547  const row_matrix_type& A_local) {
548  using Teuchos::Array;
549  using Teuchos::ArrayView;
550  typedef local_ordinal_type LO;
551  typedef typename Teuchos::ArrayView<LO>::size_type size_type;
552 
553  // Fill the local tridi matrix with zeros.
554  A_local_tridi.putScalar(STS::zero());
555 
556  //
557  // Map both row and column indices to local indices. We can use the
558  // row Map's local indices for row indices, and the column Map's
559  // local indices for column indices. It doesn't really matter;
560  // either way is just a permutation of rows and columns.
561  //
562  const map_type& rowMap = *(A_local.getRowMap());
563 
564  // Temporary arrays to hold the indices and values of the entries in
565  // each row of A_local.
566  const size_type maxNumRowEntries =
567  static_cast<size_type>(A_local.getLocalMaxNumRowEntries());
568  nonconst_local_inds_host_view_type localIndices("localIndices", maxNumRowEntries);
569  nonconst_values_host_view_type values("values", maxNumRowEntries);
570 
571  const LO numLocalRows = static_cast<LO>(rowMap.getLocalNumElements());
572  const LO minLocalRow = rowMap.getMinLocalIndex();
573  // This slight complication of computing the upper loop bound avoids
574  // issues if the row Map has zero entries on the calling process.
575  const LO maxLocalRow = minLocalRow + numLocalRows; // exclusive bound
576  for (LO localRow = minLocalRow; localRow < maxLocalRow; ++localRow) {
577  // The LocalFilter automatically excludes "off-process" entries.
578  // That means all the column indices in this row belong to the
579  // domain Map. We can, therefore, just use the local row and
580  // column indices to put each entry directly in the tridi matrix.
581  // It's OK if the column Map puts the local indices in a different
582  // order; the Import will bring them into the correct order.
583  const size_type numEntriesInRow =
584  static_cast<size_type>(A_local.getNumEntriesInLocalRow(localRow));
585  size_t numEntriesOut = 0; // ignored
586  A_local.getLocalRowCopy(localRow,
587  localIndices,
588  values,
589  numEntriesOut);
590  for (LO k = 0; k < numEntriesInRow; ++k) {
591  const LO localCol = localIndices[k];
592  const scalar_type val = values[k];
593  // We use += instead of =, in case there are duplicate entries
594  // in the row. There should not be, but why not be general?
595  // NOTE: we only extract the TriDi part of the row matrix. Do not extract DU2
596  if (localCol >= localRow - 1 && localCol <= localRow + 1)
597  A_local_tridi(localRow, localCol) += val;
598  }
599  }
600 }
601 
603 // Stub implementation
605 
606 template <class MatrixType>
608  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
609 }
610 
611 template <class MatrixType>
614  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
615 }
616 
617 template <class MatrixType>
620  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
621 }
622 
623 template <class MatrixType>
625  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
626 }
627 
628 template <class MatrixType>
630  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
631 }
632 
633 template <class MatrixType>
635  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
636 }
637 
638 template <class MatrixType>
640  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
641 }
642 
643 template <class MatrixType>
645  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
646 }
647 
648 template <class MatrixType>
650  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
651 }
652 
653 template <class MatrixType>
654 double
656  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
657 }
658 
659 template <class MatrixType>
660 double
662  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
663 }
664 
665 template <class MatrixType>
666 double
668  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
669 }
670 
671 template <class MatrixType>
674  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
675 }
676 
677 template <class MatrixType>
679  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
680 }
681 
682 template <class MatrixType>
684  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
685 }
686 
687 template <class MatrixType>
689  // Destructors should never throw exceptions.
690 }
691 
692 template <class MatrixType>
694  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
695 }
696 
697 template <class MatrixType>
699  const Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type>& X,
700  Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type>& Y,
701  Teuchos::ETransp mode,
702  scalar_type alpha,
703  scalar_type beta) const {
704  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
705 }
706 
707 template <class MatrixType>
708 std::string
710  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
711 }
712 
713 template <class MatrixType>
715  const Teuchos::EVerbosityLevel verbLevel) const {
716  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
717 }
718 
719 } // namespace Details
720 } // namespace Ifpack2
721 
722 #define IFPACK2_DETAILS_TRIDISOLVER_INSTANT(S, LO, GO, N) \
723  template class Ifpack2::Details::TriDiSolver<Tpetra::RowMatrix<S, LO, GO, N> >;
724 
725 #endif // IFPACK2_DETAILS_TRIDISOLVER_HPP
virtual int getSize() const =0
OrdinalType numRowsCols() const
virtual int getRank() const =0
&quot;Preconditioner&quot; that uses LAPACK&#39;s tridi LU.
Definition: Ifpack2_Details_TriDiSolver_decl.hpp:43
basic_OSTab< char > OSTab
iterator begin() const
MatrixType::scalar_type scalar_type
The type of entries in the input (global) matrix.
Definition: Ifpack2_Details_TriDiSolver_decl.hpp:331
static RCP< Time > getNewCounter(const std::string &name)
static RCP< Time > lookupCounter(const std::string &name)
void GTTRS(const char &TRANS, const OrdinalType &n, const OrdinalType &nrhs, const ScalarType *dl, const ScalarType *d, const ScalarType *du, const ScalarType *du2, const OrdinalType *IPIV, ScalarType *B, const OrdinalType &ldb, OrdinalType *info) const
void GTTRF(const OrdinalType &n, ScalarType *dl, ScalarType *d, ScalarType *du, ScalarType *du2, OrdinalType *IPIV, OrdinalType *info) const
basic_FancyOStream< char > FancyOStream
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
MatrixType::scalar_type scalar_type
The type of entries in the input (global) matrix.
Definition: Ifpack2_Details_TriDiSolver_decl.hpp:72
virtual void barrier() const =0
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
virtual Teuchos::RCP< const Tpetra::Map< MatrixType::local_ordinal_type, MatrixType::global_ordinal_type, MatrixType::node_type > > getDomainMap() const =0
The domain Map of this operator.
TriDiSolver(const Teuchos::RCP< const row_matrix_type > &matrix)
Constructor.
Definition: Ifpack2_Details_TriDiSolver_def.hpp:36
T * getRawPtr() const
virtual Teuchos::RCP< const Tpetra::RowMatrix< MatrixType::scalar_type, MatrixType::local_ordinal_type, MatrixType::global_ordinal_type, MatrixType::node_type > > getMatrix() const =0
The input matrix given to the constructor.
virtual bool isComputed() const =0
True if the preconditioner has been successfully computed, else false.
virtual void setParameters(const Teuchos::ParameterList &List)=0
Set this preconditioner&#39;s parameters.
iterator end() const
TypeTo as(const TypeFrom &t)
virtual Teuchos::RCP< const Tpetra::Map< MatrixType::local_ordinal_type, MatrixType::global_ordinal_type, MatrixType::node_type > > getRangeMap() const =0
The range Map of this operator.
int putScalar(const ScalarType value=Teuchos::ScalarTraits< ScalarType >::zero())
Access only local rows and columns of a sparse matrix.
Definition: Ifpack2_LocalFilter_decl.hpp:127
virtual void apply(const Tpetra::MultiVector< MatrixType::scalar_type, MatrixType::local_ordinal_type, MatrixType::global_ordinal_type, MatrixType::node_type > &X, Tpetra::MultiVector< MatrixType::scalar_type, MatrixType::local_ordinal_type, MatrixType::global_ordinal_type, MatrixType::node_type > &Y, Teuchos::ETransp mode=Teuchos::NO_TRANS, MatrixType::scalar_typealpha=Teuchos::ScalarTraits< MatrixType::scalar_type >::one(), MatrixType::scalar_typebeta=Teuchos::ScalarTraits< MatrixType::scalar_type >::zero()) const =0
Apply the preconditioner to X, putting the result in Y.
virtual bool isInitialized() const =0
True if the preconditioner has been successfully initialized, else false.
std::string toString(const T &t)
virtual void setMatrix(const Teuchos::RCP< const Tpetra::RowMatrix< MatrixType::scalar_type, MatrixType::local_ordinal_type, MatrixType::global_ordinal_type, MatrixType::node_type > > &A)=0
Set the new matrix.
bool is_null() const