10#ifndef IFPACK2_DETAILS_DENSESOLVER_DEF_HPP
11#define IFPACK2_DETAILS_DENSESOLVER_DEF_HPP
13#include "Ifpack2_LocalFilter.hpp"
14#include "Teuchos_LAPACK.hpp"
15#include "Ifpack2_Details_DenseSolver.hpp"
16#include "Tpetra_Map.hpp"
20# include "Teuchos_DefaultMpiComm.hpp"
22# include "Teuchos_DefaultSerialComm.hpp"
33template<
class MatrixType>
35DenseSolver (
const Teuchos::RCP<const row_matrix_type>& A) :
37 initializeTime_ (0.0),
43 isInitialized_ (false),
48template<
class MatrixType>
49Teuchos::RCP<const typename DenseSolver<MatrixType, false>::map_type>
51 TEUCHOS_TEST_FOR_EXCEPTION(
52 A_.is_null (), std::runtime_error,
"Ifpack2::Details::DenseSolver::"
53 "getDomainMap: The input matrix A is null. Please call setMatrix() with a "
54 "nonnull input matrix before calling this method.");
57 return A_->getRangeMap ();
61template<
class MatrixType>
62Teuchos::RCP<const typename DenseSolver<MatrixType, false>::map_type>
64 TEUCHOS_TEST_FOR_EXCEPTION(
65 A_.is_null (), std::runtime_error,
"Ifpack2::Details::DenseSolver::"
66 "getRangeMap: The input matrix A is null. Please call setMatrix() with a "
67 "nonnull input matrix before calling this method.");
70 return A_->getDomainMap ();
74template<
class MatrixType>
82template<
class MatrixType>
85 return isInitialized_;
89template<
class MatrixType>
96template<
class MatrixType>
99 return numInitialize_;
103template<
class MatrixType>
110template<
class MatrixType>
117template<
class MatrixType>
120 return initializeTime_;
124template<
class MatrixType>
131template<
class MatrixType>
138template<
class MatrixType>
139Teuchos::RCP<const typename DenseSolver<MatrixType, false>::row_matrix_type>
145template<
class MatrixType>
149 isInitialized_ =
false;
151 A_local_ = Teuchos::null;
152 A_local_dense_.reshape (0, 0);
157template<
class MatrixType>
159setMatrix (
const Teuchos::RCP<const row_matrix_type>& A)
163 if (! A_.is_null ()) {
164 const global_size_t numRows = A->getRangeMap ()->getGlobalNumElements ();
165 const global_size_t numCols = A->getDomainMap ()->getGlobalNumElements ();
166 TEUCHOS_TEST_FOR_EXCEPTION(
167 numRows != numCols, std::invalid_argument,
"Ifpack2::Details::DenseSolver::"
168 "setMatrix: Input matrix must be (globally) square. "
169 "The matrix you provided is " << numRows <<
" by " << numCols <<
".");
179template<
class MatrixType>
187 using Teuchos::TimeMonitor;
188 const std::string timerName (
"Ifpack2::Details::DenseSolver::initialize");
190 RCP<Time> timer = TimeMonitor::lookupCounter (timerName);
191 if (timer.is_null ()) {
192 timer = TimeMonitor::getNewCounter (timerName);
195 double startTime = timer->wallTime();
198 Teuchos::TimeMonitor timeMon (*timer);
200 TEUCHOS_TEST_FOR_EXCEPTION(
201 A_.is_null (), std::runtime_error,
"Ifpack2::Details::DenseSolver::"
202 "initialize: The input matrix A is null. Please call setMatrix() "
203 "with a nonnull input before calling this method.");
205 TEUCHOS_TEST_FOR_EXCEPTION(
206 ! A_->hasColMap (), std::invalid_argument,
"Ifpack2::Details::DenseSolver: "
207 "The constructor's input matrix must have a column Map, "
208 "so that it has local indices.");
214 if (A_->getComm ()->getSize () > 1) {
220 TEUCHOS_TEST_FOR_EXCEPTION(
221 A_local_.is_null (), std::logic_error,
"Ifpack2::Details::DenseSolver::"
222 "initialize: A_local_ is null after it was supposed to have been "
223 "initialized. Please report this bug to the Ifpack2 developers.");
226 const size_t numRows = A_local_->getLocalNumRows ();
227 const size_t numCols = A_local_->getLocalNumCols ();
228 TEUCHOS_TEST_FOR_EXCEPTION(
229 numRows != numCols, std::logic_error,
"Ifpack2::Details::DenseSolver::"
230 "initialize: Local filter matrix is not square. This should never happen. "
231 "Please report this bug to the Ifpack2 developers.");
232 A_local_dense_.reshape (numRows, numCols);
233 ipiv_.resize (std::min (numRows, numCols));
234 std::fill (ipiv_.begin (), ipiv_.end (), 0);
236 isInitialized_ =
true;
240 initializeTime_ += (timer->wallTime() - startTime);
244template<
class MatrixType>
249template<
class MatrixType>
253 const std::string timerName (
"Ifpack2::Details::DenseSolver::compute");
255 RCP<Teuchos::Time> timer = Teuchos::TimeMonitor::lookupCounter (timerName);
256 if (timer.is_null ()) {
257 timer = Teuchos::TimeMonitor::getNewCounter (timerName);
260 double startTime = timer->wallTime();
264 Teuchos::TimeMonitor timeMon (*timer);
265 TEUCHOS_TEST_FOR_EXCEPTION(
266 A_.is_null (), std::runtime_error,
"Ifpack2::Details::DenseSolver::"
267 "compute: The input matrix A is null. Please call setMatrix() with a "
268 "nonnull input, then call initialize(), before calling this method.");
270 TEUCHOS_TEST_FOR_EXCEPTION(
271 A_local_.is_null (), std::logic_error,
"Ifpack2::Details::DenseSolver::"
272 "compute: A_local_ is null. Please report this bug to the Ifpack2 "
279 extract (A_local_dense_, *A_local_);
280 factor (A_local_dense_, ipiv_ ());
285 computeTime_ += (timer->wallTime() - startTime);
288template<
class MatrixType>
290factor (Teuchos::SerialDenseMatrix<int, scalar_type>& A,
291 const Teuchos::ArrayView<int>& ipiv)
294 std::fill (ipiv.begin (), ipiv.end (), 0);
296 Teuchos::LAPACK<int, scalar_type> lapack;
298 lapack.GETRF (A.numRows (), A.numCols (), A.values (), A.stride (),
299 ipiv.getRawPtr (), &INFO);
301 TEUCHOS_TEST_FOR_EXCEPTION(
302 INFO < 0, std::logic_error,
"Ifpack2::Details::DenseSolver::factor: "
303 "LAPACK's _GETRF (LU factorization with partial pivoting) was called "
304 "incorrectly. INFO = " << INFO <<
" < 0. "
305 "Please report this bug to the Ifpack2 developers.");
309 TEUCHOS_TEST_FOR_EXCEPTION(
310 INFO > 0, std::runtime_error,
"Ifpack2::Details::DenseSolver::factor: "
311 "LAPACK's _GETRF (LU factorization with partial pivoting) reports that the "
312 "computed U factor is exactly singular. U(" << INFO <<
"," << INFO <<
") "
313 "(one-based index i) is exactly zero. This probably means that the input "
314 "matrix has a singular diagonal block.");
318template<
class MatrixType>
319void DenseSolver<MatrixType, false>::
320applyImpl (
const MV& X,
322 const Teuchos::ETransp mode,
323 const scalar_type alpha,
324 const scalar_type beta)
const
326 using Teuchos::ArrayRCP;
329 using Teuchos::rcpFromRef;
330 using Teuchos::CONJ_TRANS;
331 using Teuchos::TRANS;
333 const int numVecs =
static_cast<int> (X.getNumVectors ());
334 if (alpha == STS::zero ()) {
335 if (beta == STS::zero ()) {
339 Y.putScalar (STS::zero ());
342 Y.scale (STS::zero ());
346 Teuchos::LAPACK<int, scalar_type> lapack;
352 if (beta == STS::zero () && Y.isConstantStride () && alpha == STS::one ()) {
354 Y_tmp = rcpFromRef (Y);
357 Y_tmp = rcp (
new MV (X, Teuchos::Copy));
358 if (alpha != STS::one ()) {
359 Y_tmp->scale (alpha);
362 const int Y_stride =
static_cast<int> (Y_tmp->getStride ());
363 ArrayRCP<scalar_type> Y_view = Y_tmp->get1dViewNonConst ();
364 scalar_type*
const Y_ptr = Y_view.getRawPtr ();
367 (mode == CONJ_TRANS ?
'C' : (mode ==
TRANS ?
'T' :
'N'));
368 lapack.GETRS (trans, A_local_dense_.numRows (), numVecs,
369 A_local_dense_.values (), A_local_dense_.stride (),
370 ipiv_.getRawPtr (), Y_ptr, Y_stride, &INFO);
371 TEUCHOS_TEST_FOR_EXCEPTION(
372 INFO != 0, std::runtime_error,
"Ifpack2::Details::DenseSolver::"
373 "applyImpl: LAPACK's _GETRS (solve using LU factorization with "
374 "partial pivoting) failed with INFO = " << INFO <<
" != 0.");
376 if (beta != STS::zero ()) {
377 Y.update (alpha, *Y_tmp, beta);
379 else if (! Y.isConstantStride ()) {
380 deep_copy (Y, *Y_tmp);
386template<
class MatrixType>
388apply (
const Tpetra::MultiVector<scalar_type,local_ordinal_type,global_ordinal_type,node_type>& X,
389 Tpetra::MultiVector<scalar_type,local_ordinal_type,global_ordinal_type,node_type>& Y,
390 Teuchos::ETransp mode,
394 using Teuchos::ArrayView;
398 using Teuchos::rcpFromRef;
400 const std::string timerName (
"Ifpack2::Details::DenseSolver::apply");
401 RCP<Teuchos::Time> timer = Teuchos::TimeMonitor::lookupCounter (timerName);
402 if (timer.is_null ()) {
403 timer = Teuchos::TimeMonitor::getNewCounter (timerName);
406 double startTime = timer->wallTime();
410 Teuchos::TimeMonitor timeMon (*timer);
412 TEUCHOS_TEST_FOR_EXCEPTION(
413 ! isComputed_, std::runtime_error,
"Ifpack2::Details::DenseSolver::apply: "
414 "You must have called the compute() method before you may call apply(). "
415 "You may call the apply() method as many times as you want after calling "
416 "compute() once, but you must have called compute() at least once.");
418 const size_t numVecs = X.getNumVectors ();
420 TEUCHOS_TEST_FOR_EXCEPTION(
421 numVecs != Y.getNumVectors (), std::runtime_error,
422 "Ifpack2::Details::DenseSolver::apply: X and Y have different numbers "
423 "of vectors. X has " << X.getNumVectors () <<
", but Y has "
424 << X.getNumVectors () <<
".");
431 RCP<const MV> X_local;
433 const bool multipleProcs = (A_->getRowMap ()->getComm ()->getSize () >= 1);
438 X_local = X.offsetView (A_local_->getDomainMap (), 0);
439 Y_local = Y.offsetViewNonConst (A_local_->getRangeMap (), 0);
443 X_local = rcpFromRef (X);
444 Y_local = rcpFromRef (Y);
449 this->applyImpl (*X_local, *Y_local, mode, alpha, beta);
454 applyTime_ += (timer->wallTime() - startTime);
458template<
class MatrixType>
462 std::ostringstream out;
467 out <<
"\"Ifpack2::Details::DenseSolver\": ";
469 if (this->getObjectLabel () !=
"") {
470 out <<
"Label: \"" << this->getObjectLabel () <<
"\", ";
472 out <<
"Initialized: " << (
isInitialized () ?
"true" :
"false") <<
", "
473 <<
"Computed: " << (
isComputed () ?
"true" :
"false") <<
", ";
476 out <<
"Matrix: null";
479 out <<
"Matrix: not null"
480 <<
", Global matrix dimensions: ["
481 << A_->getGlobalNumRows () <<
", " << A_->getGlobalNumCols () <<
"]";
489template<
class MatrixType>
492 const Teuchos::EVerbosityLevel verbLevel)
const
494 using Teuchos::FancyOStream;
495 using Teuchos::OSTab;
497 using Teuchos::rcpFromRef;
500 if (verbLevel == Teuchos::VERB_NONE) {
504 RCP<FancyOStream> ptrOut = rcpFromRef (out);
506 if (this->getObjectLabel () !=
"") {
507 out <<
"label: " << this->getObjectLabel () << endl;
509 out <<
"initialized: " << (isInitialized_ ?
"true" :
"false") << endl
510 <<
"computed: " << (isComputed_ ?
"true" :
"false") << endl
511 <<
"number of initialize calls: " << numInitialize_ << endl
512 <<
"number of compute calls: " << numCompute_ << endl
513 <<
"number of apply calls: " << numApply_ << endl
514 <<
"total time in seconds in initialize: " << initializeTime_ << endl
515 <<
"total time in seconds in compute: " << computeTime_ << endl
516 <<
"total time in seconds in apply: " << applyTime_ << endl;
517 if (verbLevel >= Teuchos::VERB_EXTREME) {
518 out <<
"A_local_dense_:" << endl;
522 for (
int i = 0; i < A_local_dense_.numRows (); ++i) {
523 for (
int j = 0; j < A_local_dense_.numCols (); ++j) {
524 out << A_local_dense_(i,j);
525 if (j + 1 < A_local_dense_.numCols ()) {
529 if (i + 1 < A_local_dense_.numRows ()) {
535 out <<
"ipiv_: " << Teuchos::toString (ipiv_) << endl;
541template<
class MatrixType>
543describe (Teuchos::FancyOStream& out,
544 const Teuchos::EVerbosityLevel verbLevel)
const
546 using Teuchos::FancyOStream;
547 using Teuchos::OSTab;
549 using Teuchos::rcpFromRef;
552 RCP<FancyOStream> ptrOut = rcpFromRef (out);
559 if (verbLevel > Teuchos::VERB_NONE) {
560 out <<
"Ifpack2::Details::DenseSolver:" << endl;
562 describeLocal (out, verbLevel);
567 const Teuchos::Comm<int>& comm = * (A_->getRowMap ()->getComm ());
568 const int myRank = comm.getRank ();
569 const int numProcs = comm.getSize ();
570 if (verbLevel > Teuchos::VERB_NONE && myRank == 0) {
571 out <<
"Ifpack2::Details::DenseSolver:" << endl;
574 for (
int p = 0; p < numProcs; ++p) {
576 out <<
"Process " << myRank <<
":" << endl;
577 describeLocal (out, verbLevel);
587template<
class MatrixType>
589extract (Teuchos::SerialDenseMatrix<int, scalar_type>& A_local_dense,
592 using Teuchos::Array;
593 using Teuchos::ArrayView;
595 typedef typename Teuchos::ArrayView<LO>::size_type size_type;
598 A_local_dense.putScalar (STS::zero ());
606 const map_type& rowMap = * (A_local.getRowMap ());
610 const size_type maxNumRowEntries =
611 static_cast<size_type
> (A_local.getLocalMaxNumRowEntries ());
612 nonconst_local_inds_host_view_type localIndices (
"localIndices",maxNumRowEntries);
613 nonconst_values_host_view_type values (
"values",maxNumRowEntries);
615 const LO numLocalRows =
static_cast<LO
> (rowMap.getLocalNumElements ());
616 const LO minLocalRow = rowMap.getMinLocalIndex ();
619 const LO maxLocalRow = minLocalRow + numLocalRows;
620 for (LO localRow = minLocalRow; localRow < maxLocalRow; ++localRow) {
627 const size_type numEntriesInRow =
628 static_cast<size_type
> (A_local.getNumEntriesInLocalRow (localRow));
629 size_t numEntriesOut = 0;
630 A_local.getLocalRowCopy (localRow,
634 for (LO k = 0; k < numEntriesInRow; ++k) {
635 const LO localCol = localIndices[k];
636 const scalar_type val = values[k];
639 A_local_dense(localRow, localCol) += val;
648template<
class MatrixType>
650DenseSolver (
const Teuchos::RCP<const row_matrix_type>& A) {
651 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Not implemented");
655template<
class MatrixType>
656Teuchos::RCP<const typename DenseSolver<MatrixType, true>::map_type>
658 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Not implemented");
662template<
class MatrixType>
663Teuchos::RCP<const typename DenseSolver<MatrixType, true>::map_type>
665 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Not implemented");
669template<
class MatrixType>
673 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Not implemented");
677template<
class MatrixType>
680 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Not implemented");
684template<
class MatrixType>
687 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Not implemented");
691template<
class MatrixType>
694 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Not implemented");
698template<
class MatrixType>
701 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Not implemented");
705template<
class MatrixType>
708 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Not implemented");
712template<
class MatrixType>
715 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Not implemented");
719template<
class MatrixType>
722 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Not implemented");
726template<
class MatrixType>
729 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Not implemented");
733template<
class MatrixType>
734Teuchos::RCP<const typename DenseSolver<MatrixType, true>::row_matrix_type>
736 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Not implemented");
740template<
class MatrixType>
742setMatrix (
const Teuchos::RCP<const row_matrix_type>& A)
744 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Not implemented");
748template<
class MatrixType>
751 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Not implemented");
755template<
class MatrixType>
762template<
class MatrixType>
765 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Not implemented");
769template<
class MatrixType>
771apply (
const Tpetra::MultiVector<scalar_type,local_ordinal_type,global_ordinal_type,node_type>& X,
772 Tpetra::MultiVector<scalar_type,local_ordinal_type,global_ordinal_type,node_type>& Y,
773 Teuchos::ETransp mode,
777 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Not implemented");
781template<
class MatrixType>
785 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Not implemented");
789template<
class MatrixType>
791describe (Teuchos::FancyOStream& out,
792 const Teuchos::EVerbosityLevel verbLevel)
const
794 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Not implemented");
801#define IFPACK2_DETAILS_DENSESOLVER_INSTANT(S,LO,GO,N) \
802 template class Ifpack2::Details::DenseSolver< Tpetra::RowMatrix<S, LO, GO, N> >;
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
DenseSolver(const Teuchos::RCP< const row_matrix_type > &matrix)
Constructor.
Definition Ifpack2_Details_DenseSolver_def.hpp:35
void initialize()
Set up the graph structure of this preconditioner.
Definition Ifpack2_Details_DenseSolver_def.hpp:180
MatrixType::scalar_type scalar_type
The type of entries in the input (global) matrix.
Definition Ifpack2_Details_DenseSolver_decl.hpp:75
bool isComputed() const
True if the preconditioner has been successfully computed, else false.
Definition Ifpack2_Details_DenseSolver_def.hpp:91
bool isInitialized() const
True if the preconditioner has been successfully initialized, else false.
Definition Ifpack2_Details_DenseSolver_def.hpp:84
DenseSolver(const Teuchos::RCP< const row_matrix_type > &matrix)
Constructor.
Definition Ifpack2_Details_DenseSolver_def.hpp:650
MatrixType::scalar_type scalar_type
The type of entries in the input (global) matrix.
Definition Ifpack2_Details_DenseSolver_decl.hpp:340
"Preconditioner" that uses LAPACK's dense LU.
Definition Ifpack2_Details_DenseSolver_decl.hpp:51
Access only local rows and columns of a sparse matrix.
Definition Ifpack2_LocalFilter_decl.hpp:131
virtual double getComputeTime() const=0
virtual bool isInitialized() const=0
virtual int getNumCompute() 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
virtual int getNumApply() const=0
virtual double getApplyTime() const=0
virtual void setParameters(const Teuchos::ParameterList &List)=0
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
virtual Teuchos::RCP< const Tpetra::Map< MatrixType::local_ordinal_type, MatrixType::global_ordinal_type, MatrixType::node_type > > getRangeMap() const=0
virtual Teuchos::RCP< const Tpetra::Map< MatrixType::local_ordinal_type, MatrixType::global_ordinal_type, MatrixType::node_type > > getDomainMap() const=0
virtual bool isComputed() const=0
virtual void initialize()=0
virtual double getInitializeTime() const=0
virtual int getNumInitialize() const=0
Preconditioners and smoothers for Tpetra sparse matrices.
Definition Ifpack2_AdditiveSchwarz_decl.hpp:41