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