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