Ifpack2 Templated Preconditioning Package Version 1.0
Loading...
Searching...
No Matches
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>
22#include "Teuchos_DefaultMpiComm.hpp"
23#else
24#include "Teuchos_DefaultSerialComm.hpp"
25#endif // HAVE_MPI
26
27namespace Ifpack2 {
28namespace Details {
29
31// Non-stub (full) implementation
33
34template <class MatrixType>
36 TriDiSolver(const Teuchos::RCP<const row_matrix_type>& A)
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
47template <class MatrixType>
48Teuchos::RCP<const typename TriDiSolver<MatrixType, false>::map_type>
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
60template <class MatrixType>
61Teuchos::RCP<const typename TriDiSolver<MatrixType, false>::map_type>
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
73template <class MatrixType>
75 setParameters(const Teuchos::ParameterList& params) {
76 (void)params; // this preconditioner doesn't currently take any parameters
77}
78
79template <class MatrixType>
81 return isInitialized_;
82}
83
84template <class MatrixType>
86 return isComputed_;
87}
88
89template <class MatrixType>
91 return numInitialize_;
92}
93
94template <class MatrixType>
96 return numCompute_;
97}
98
99template <class MatrixType>
101 return numApply_;
102}
103
104template <class MatrixType>
105double
107 return initializeTime_;
108}
109
110template <class MatrixType>
111double
113 return computeTime_;
114}
115
116template <class MatrixType>
117double
119 return applyTime_;
120}
121
122template <class MatrixType>
123Teuchos::RCP<const typename TriDiSolver<MatrixType, false>::row_matrix_type>
125 return A_;
126}
127
128template <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
138template <class MatrixType>
140 setMatrix(const Teuchos::RCP<const row_matrix_type>& A) {
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
160template <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
227template <class MatrixType>
229
230template <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
271template <class MatrixType>
272void TriDiSolver<MatrixType, false>::factor(Teuchos::SerialTriDiMatrix<int, scalar_type>& A,
273 const Teuchos::ArrayView<int>& ipiv) {
274 // Fill the LU permutation array with zeros.
275 std::fill(ipiv.begin(), ipiv.end(), 0);
276
277 Teuchos::LAPACK<int, scalar_type> lapack;
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
305template <class MatrixType>
306void 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
330 Teuchos::LAPACK<int, scalar_type> lapack;
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);
357 TEUCHOS_TEST_FOR_EXCEPTION(
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
372template <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.
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
443template <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
470template <class MatrixType>
471void TriDiSolver<MatrixType, false>::describeLocal(Teuchos::FancyOStream& out,
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
503template <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
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 }
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
545template <class MatrixType>
546void TriDiSolver<MatrixType, false>::extract(Teuchos::SerialTriDiMatrix<int, scalar_type>& A_local_tridi,
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
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,
588 values,
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)
598 }
599 }
600}
601
603// Stub implementation
605
606template <class MatrixType>
607TriDiSolver<MatrixType, true>::TriDiSolver(const Teuchos::RCP<const row_matrix_type>& A) {
608 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
609}
610
611template <class MatrixType>
612Teuchos::RCP<const typename TriDiSolver<MatrixType, true>::map_type>
614 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
615}
616
617template <class MatrixType>
618Teuchos::RCP<const typename TriDiSolver<MatrixType, true>::map_type>
620 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
621}
622
623template <class MatrixType>
624void TriDiSolver<MatrixType, true>::setParameters(const Teuchos::ParameterList& params) {
625 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
626}
627
628template <class MatrixType>
630 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
631}
632
633template <class MatrixType>
635 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
636}
637
638template <class MatrixType>
640 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
641}
642
643template <class MatrixType>
645 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
646}
647
648template <class MatrixType>
650 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
651}
652
653template <class MatrixType>
654double
656 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
657}
658
659template <class MatrixType>
660double
662 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
663}
664
665template <class MatrixType>
666double
668 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
669}
670
671template <class MatrixType>
672Teuchos::RCP<const typename TriDiSolver<MatrixType, true>::row_matrix_type>
674 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
675}
676
677template <class MatrixType>
678void TriDiSolver<MatrixType, true>::setMatrix(const Teuchos::RCP<const row_matrix_type>& A) {
679 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
680}
681
682template <class MatrixType>
684 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
685}
686
687template <class MatrixType>
689 // Destructors should never throw exceptions.
690}
691
692template <class MatrixType>
694 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
695}
696
697template <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
707template <class MatrixType>
708std::string
710 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Not implemented");
711}
712
713template <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 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.
Ifpack2's implementation of Trilinos::Details::LinearSolver interface.
Definition Ifpack2_Details_LinearSolver_decl.hpp:75
MatrixType::scalar_type scalar_type
The type of entries in the input (global) matrix.
Definition Ifpack2_Details_TriDiSolver_decl.hpp:72
MatrixType::scalar_type scalar_type
The type of entries in the input (global) matrix.
Definition Ifpack2_Details_TriDiSolver_decl.hpp:331
"Preconditioner" that uses LAPACK's tridi LU.
Definition Ifpack2_Details_TriDiSolver_decl.hpp:50
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