Ifpack2 Templated Preconditioning Package Version 1.0
Loading...
Searching...
No Matches
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>
20#include "Teuchos_DefaultMpiComm.hpp"
21#else
22#include "Teuchos_DefaultSerialComm.hpp"
23#endif // HAVE_MPI
24
25namespace Ifpack2 {
26namespace Details {
27
29// Non-stub (full) implementation
31
32template <class MatrixType>
34 DenseSolver(const Teuchos::RCP<const row_matrix_type>& A)
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
45template <class MatrixType>
46Teuchos::RCP<const typename DenseSolver<MatrixType, false>::map_type>
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
58template <class MatrixType>
59Teuchos::RCP<const typename DenseSolver<MatrixType, false>::map_type>
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
71template <class MatrixType>
73 setParameters(const Teuchos::ParameterList& params) {
74 (void)params; // this preconditioner doesn't currently take any parameters
75}
76
77template <class MatrixType>
79 return isInitialized_;
80}
81
82template <class MatrixType>
84 return isComputed_;
85}
86
87template <class MatrixType>
89 return numInitialize_;
90}
91
92template <class MatrixType>
94 return numCompute_;
95}
96
97template <class MatrixType>
99 return numApply_;
100}
101
102template <class MatrixType>
103double
105 return initializeTime_;
106}
107
108template <class MatrixType>
109double
111 return computeTime_;
112}
113
114template <class MatrixType>
115double
117 return applyTime_;
118}
119
120template <class MatrixType>
121Teuchos::RCP<const typename DenseSolver<MatrixType, false>::row_matrix_type>
123 return A_;
124}
125
126template <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
136template <class MatrixType>
138 setMatrix(const Teuchos::RCP<const row_matrix_type>& A) {
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
158template <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
225template <class MatrixType>
227
228template <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
268template <class MatrixType>
270 factor(Teuchos::SerialDenseMatrix<int, scalar_type>& A,
271 const Teuchos::ArrayView<int>& ipiv) {
272 // Fill the LU permutation array with zeros.
273 std::fill(ipiv.begin(), ipiv.end(), 0);
274
275 Teuchos::LAPACK<int, scalar_type> lapack;
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
300template <class MatrixType>
301void 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
325 Teuchos::LAPACK<int, scalar_type> lapack;
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);
349 TEUCHOS_TEST_FOR_EXCEPTION(
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
364template <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.
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
435template <class MatrixType>
436std::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
463template <class MatrixType>
465 describeLocal(Teuchos::FancyOStream& out,
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
512template <class MatrixType>
514 describe(Teuchos::FancyOStream& out,
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
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 }
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
555template <class MatrixType>
557 extract(Teuchos::SerialDenseMatrix<int, scalar_type>& A_local_dense,
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
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,
599 values,
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?
607 }
608 }
609}
610
612// Stub implementation
614
615template <class MatrixType>
617 DenseSolver(const Teuchos::RCP<const row_matrix_type>& A) {
618 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
619}
620
621template <class MatrixType>
622Teuchos::RCP<const typename DenseSolver<MatrixType, true>::map_type>
624 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
625}
626
627template <class MatrixType>
628Teuchos::RCP<const typename DenseSolver<MatrixType, true>::map_type>
630 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
631}
632
633template <class MatrixType>
635 setParameters(const Teuchos::ParameterList& params) {
636 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
637}
638
639template <class MatrixType>
641 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
642}
643
644template <class MatrixType>
646 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
647}
648
649template <class MatrixType>
651 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
652}
653
654template <class MatrixType>
656 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
657}
658
659template <class MatrixType>
661 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
662}
663
664template <class MatrixType>
665double
667 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
668}
669
670template <class MatrixType>
671double
673 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
674}
675
676template <class MatrixType>
677double
679 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
680}
681
682template <class MatrixType>
683Teuchos::RCP<const typename DenseSolver<MatrixType, true>::row_matrix_type>
685 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
686}
687
688template <class MatrixType>
690 setMatrix(const Teuchos::RCP<const row_matrix_type>& A) {
691 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
692}
693
694template <class MatrixType>
696 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
697}
698
699template <class MatrixType>
701 // Destructors should never throw exceptions.
702}
703
704template <class MatrixType>
706 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
707}
708
709template <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
719template <class MatrixType>
720std::string
722 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
723}
724
725template <class MatrixType>
727 describe(Teuchos::FancyOStream& out,
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
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.
MatrixType::scalar_type scalar_type
The type of entries in the input (global) matrix.
Definition Ifpack2_Details_DenseSolver_decl.hpp:71
MatrixType::scalar_type scalar_type
The type of entries in the input (global) matrix.
Definition Ifpack2_Details_DenseSolver_decl.hpp:332
"Preconditioner" that uses LAPACK's dense LU.
Definition Ifpack2_Details_DenseSolver_decl.hpp:49
Ifpack2's implementation of Trilinos::Details::LinearSolver interface.
Definition Ifpack2_Details_LinearSolver_decl.hpp:75
virtual bool isInitialized() const=0
True if the preconditioner has been successfully initialized, else false.
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 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_type alpha=Teuchos::ScalarTraits< MatrixType::scalar_type >::one(), MatrixType::scalar_type beta=Teuchos::ScalarTraits< MatrixType::scalar_type >::zero()) const=0
Apply the preconditioner to X, putting the result in Y.
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 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 bool isComputed() const=0
True if the preconditioner has been successfully computed, else false.
TRANS
Ifpack2 implementation details.
Preconditioners and smoothers for Tpetra sparse matrices.
Definition Ifpack2_AdditiveSchwarz_decl.hpp:40