Ifpack2 Templated Preconditioning Package  Version 1.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Ifpack2_DatabaseSchwarz_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_DATABASESCHWARZ_DEF_HPP
11 #define IFPACK2_DATABASESCHWARZ_DEF_HPP
12 
13 #include "Ifpack2_Parameters.hpp"
14 #include "Teuchos_TimeMonitor.hpp"
15 #include "Tpetra_CrsMatrix.hpp"
16 #include "Teuchos_FancyOStream.hpp"
17 #include "Teuchos_oblackholestream.hpp"
19 #include "Teuchos_LAPACK.hpp"
20 #include <iostream>
21 #include <sstream>
22 
23 
24 namespace Ifpack2 {
25 
26 template<class MatrixType>
29  : A_(A),
30  IsInitialized_(false),
31  IsComputed_(false),
32  NumInitialize_(0),
33  NumCompute_(0),
34  NumApply_(0),
35  InitializeTime_(0.0),
36  ComputeTime_(0.0),
37  ApplyTime_(0.0),
38  ComputeFlops_(0.0),
39  ApplyFlops_(0.0),
40  PatchSize_(9),
41  PatchTolerance_(1e-3),
42  SkipDatabase_(false),
43  Verbose_(false)
44 {
45  this->setObjectLabel("Ifpack2::DatabaseSchwarz");
46 }
47 
48 
49 template<class MatrixType>
52  Teuchos::ParameterList& params)
53  : A_(A),
54  IsInitialized_(false),
55  IsComputed_(false),
56  NumInitialize_(0),
57  NumCompute_(0),
58  NumApply_(0),
59  InitializeTime_(0.0),
60  ComputeTime_(0.0),
61  ApplyTime_(0.0),
62  ComputeFlops_(0.0),
63  ApplyFlops_(0.0),
64  PatchSize_(9),
65  PatchTolerance_(1e-3),
66  SkipDatabase_(false),
67  Verbose_(false)
68 {
69  this->setObjectLabel("Ifpack2::DatabaseSchwarz");
70  this->setParameters(params);
71 }
72 
73 
74 template<class MatrixType>
76 }
77 
78 
79 template<class MatrixType>
81 {
82  // ASSERT NON-NULL INPUT
83  if (A.getRawPtr() != A_.getRawPtr()) {
84  IsInitialized_ = false;
85  IsComputed_ = false;
86  A_ = A;
87  }
88 }
89 
90 
91 template<class MatrixType>
92 void
94 {
95  // GH: Copied from CAG and others. Yes, const_cast bad.
96  this->setParametersImpl(const_cast<Teuchos::ParameterList&>(params));
97 }
98 
99 
100 template<class MatrixType>
101 void
103 {
104  // GH: since patch size varies dramatically, it doesn't make sense to force a default size
105  // but I don't know if it's any better to throw if the user doesn't provide a patch size
106  const int defaultPatchSize = 9;
107  const double defaultPatchTolerance = 1e-3;
108  const bool defaultSkipDatabase = false;
109  const bool defaultVerbose = false;
110 
111  // the size of patch to search for
112  PatchSize_ = params.get<int>("database schwarz: patch size",defaultPatchSize);
113 
115  PatchSize_ < 0, std::invalid_argument,
116  "Ifpack2::DatabaseSchwarz::setParameters: \"database schwarz: patch size\" parameter "
117  "must be a nonnegative integer. You gave a value of " << PatchSize_ << ".");
118 
119  // the tolerance at which two patch matrices are considered "equal"
120  PatchTolerance_ = params.get("database schwarz: patch tolerance", defaultPatchTolerance);
121 
123  PatchTolerance_ <= 0, std::invalid_argument,
124  "Ifpack2::DatabaseSchwarz::setParameters: \"database schwarz: patch tolerance\" parameter "
125  "must be a positive double. You gave a value of " << PatchTolerance_ << ".");
126 
127  // whether to skip the database computation and invert all patches or not
128  SkipDatabase_ = params.get<bool>("database schwarz: skip database",defaultSkipDatabase);
129 
130  // verbosity: controls whether to print a database summary at the end of the compute phase
131  Verbose_ = params.get<bool>("database schwarz: print database summary",defaultVerbose);
132 }
133 
134 
135 template<class MatrixType>
136 void
138 {
139  (void) zeroStartingSolution;
140 }
141 
142 template<class MatrixType>
145 {
146  Teuchos::RCP<const row_matrix_type> A = getMatrix();
148  A.is_null(), std::runtime_error, "Ifpack2::DatabaseSchwarz::getComm: The input "
149  "matrix A is null. Please call setMatrix() with a nonnull input matrix "
150  "before calling this method.");
151  return A->getRowMap()->getComm();
152 }
153 
154 
155 template<class MatrixType>
158 {
159  return A_;
160 }
161 
162 
163 template<class MatrixType>
164 Teuchos::RCP<const Tpetra::CrsMatrix<typename MatrixType::scalar_type,
165  typename MatrixType::local_ordinal_type,
166  typename MatrixType::global_ordinal_type,
167  typename MatrixType::node_type> >
169 getCrsMatrix() const {
170  typedef Tpetra::CrsMatrix<scalar_type, local_ordinal_type,
171  global_ordinal_type, node_type> crs_matrix_type;
172  return Teuchos::rcp_dynamic_cast<const crs_matrix_type> (getMatrix());
173 }
174 
175 
176 template<class MatrixType>
180 {
181  Teuchos::RCP<const row_matrix_type> A = getMatrix();
183  A.is_null(), std::runtime_error, "Ifpack2::DatabaseSchwarz::getDomainMap: The "
184  "input matrix A is null. Please call setMatrix() with a nonnull input "
185  "matrix before calling this method.");
186  return A->getDomainMap();
187 }
188 
189 
190 template<class MatrixType>
193 getRangeMap() const
194 {
195  Teuchos::RCP<const row_matrix_type> A = getMatrix();
197  A.is_null(), std::runtime_error, "Ifpack2::DatabaseSchwarz::getRangeMap: The "
198  "input matrix A is null. Please call setMatrix() with a nonnull input "
199  "matrix before calling this method.");
200  return A->getRangeMap();
201 }
202 
203 
204 template<class MatrixType>
206  return false;
207 }
208 
209 
210 template<class MatrixType>
212  return NumInitialize_;
213 }
214 
215 
216 template<class MatrixType>
218  return NumCompute_;
219 }
220 
221 
222 template<class MatrixType>
224  return NumApply_;
225 }
226 
227 
228 template<class MatrixType>
230  return InitializeTime_;
231 }
232 
233 
234 template<class MatrixType>
236  return ComputeTime_;
237 }
238 
239 
240 template<class MatrixType>
242  return ApplyTime_;
243 }
244 
245 
246 template<class MatrixType>
248  return ComputeFlops_;
249 }
250 
251 
252 template<class MatrixType>
254  return ApplyFlops_;
255 }
256 
257 template<class MatrixType>
259  Teuchos::RCP<const row_matrix_type> A = getMatrix();
261  A.is_null(), std::runtime_error, "Ifpack2::DatabaseSchwarz::getNodeSmootherComplexity: "
262  "The input matrix A is null. Please call setMatrix() with a nonnull "
263  "input matrix, then call compute(), before calling this method.");
264  // DatabaseSchwarz costs roughly one apply + one diagonal inverse per iteration
265  return A->getLocalNumRows() + A->getLocalNumEntries();
266 }
267 
268 
269 
270 template<class MatrixType>
271 void
273 apply(const Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type>& X,
274  Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type>& Y,
275  Teuchos::ETransp mode,
276  scalar_type alpha,
277  scalar_type beta) const
278 {
279  const std::string timerName ("Ifpack2::DatabaseSchwarz::apply");
281  if (timer.is_null()) {
282  timer = Teuchos::TimeMonitor::getNewCounter (timerName);
283  }
284 
285  double startTime = timer->wallTime();
286 
287  // Start timing here.
288  {
289  Teuchos::TimeMonitor timeMon (*timer);
290 
291  // compute() calls initialize() if it hasn't already been called.
292  // Thus, we only need to check isComputed().
294  ! isComputed(), std::runtime_error,
295  "Ifpack2::DatabaseSchwarz::apply(): You must call the compute() method before "
296  "you may call apply().");
298  X.getNumVectors() != Y.getNumVectors(), std::runtime_error,
299  "Ifpack2::DatabaseSchwarz::apply(): X and Y must have the same number of "
300  "columns. X.getNumVectors() = " << X.getNumVectors() << " != "
301  << "Y.getNumVectors() = " << Y.getNumVectors() << ".");
302 
303  // 1. Compute beta*Y
304  Y.scale(beta);
305 
306  // 2. Solve prec on X
307  auto X_view = X.getLocalViewHost(Tpetra::Access::ReadOnly);
308  auto Y_view = Y.getLocalViewHost(Tpetra::Access::ReadWrite);
309 
311  int INFO = 0;
312  for(unsigned int ipatch=0; ipatch<NumPatches_; ipatch++) {
313  int idatabase = DatabaseIndices_[ipatch];
314 
315  // 2a. Split X into Xk on each local patch
317  for(unsigned int c=0; c<X_view.extent(1); ++c) {
318  for(unsigned int i=0; i<x_patch.size(); ++i) {
319  x_patch[i] = X_view(PatchIndices_[ipatch][i],c);
320  }
321  }
322 
323  // 2b. Solve each using Lapack::GETRS
324  // GH: TODO: can improve this by grouping all patches such that DatabaseIndices_[ipatch] is equal
325  // in the compute phase and then utilizing the multiple RHS capability here.
326  int numRhs = 1;
327 
328  int* ipiv = &ipiv_[idatabase*PatchSize_];
329 
330  lapack.GETRS('N', DatabaseMatrices_[idatabase]->numRows(), numRhs,
331  DatabaseMatrices_[idatabase]->values(), DatabaseMatrices_[idatabase]->numRows(),
332  ipiv, x_patch.getRawPtr(),
333  DatabaseMatrices_[idatabase]->numRows(), &INFO);
334 
335  // INFO < 0 is a bug.
337  INFO < 0, std::logic_error, "Ifpack2::DatabaseSchwarz::compute: "
338  "LAPACK's _GETRF (LU factorization with partial pivoting) was called "
339  "incorrectly. INFO = " << INFO << " < 0. "
340  "Please report this bug to the Ifpack2 developers.");
341  // INFO > 0 means the matrix is singular. This is probably an issue
342  // either with the choice of rows the rows we extracted, or with the
343  // input matrix itself.
345  INFO > 0, std::runtime_error, "Ifpack2::DatabaseSchwarz::compute: "
346  "LAPACK's _GETRF (LU factorization with partial pivoting) reports that the "
347  "computed U factor is exactly singular. U(" << INFO << "," << INFO << ") "
348  "(one-based index i) is exactly zero. This probably means that the input "
349  "patch is singular.");
350 
351  // 2c. Add alpha*weights*Xk into Y for each Xk
352  for(unsigned int c=0; c<Y_view.extent(1); ++c) {
353  for(unsigned int i=0; i<x_patch.size(); ++i) {
354  Y_view(PatchIndices_[ipatch][i],c) += alpha*Weights_[PatchIndices_[ipatch][i]]*x_patch[i];
355  }
356  }
357  }
358  }
359  ++NumApply_;
360  ApplyTime_ += (timer->wallTime() - startTime);
361 }
362 
363 
364 template<class MatrixType>
365 void
367 applyMat (const Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type>& X,
368  Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type>& Y,
369  Teuchos::ETransp mode) const
370 {
372  X.getNumVectors() != Y.getNumVectors(), std::invalid_argument,
373  "Ifpack2::DatabaseSchwarz::applyMat: X.getNumVectors() != Y.getNumVectors().");
374 
375  Teuchos::RCP<const row_matrix_type> A = getMatrix();
377  A.is_null(), std::runtime_error, "Ifpack2::DatabaseSchwarz::applyMat: The input "
378  "matrix A is null. Please call setMatrix() with a nonnull input matrix "
379  "before calling this method.");
380 
381  A->apply (X, Y, mode);
382 }
383 
384 
385 template<class MatrixType>
387  // We create the timer, but this method doesn't do anything, so
388  // there is no need to start the timer. The resulting total time
389  // will always be zero.
390  const std::string timerName ("Ifpack2::DatabaseSchwarz::initialize");
392  if (timer.is_null()) {
393  timer = Teuchos::TimeMonitor::getNewCounter (timerName);
394  }
395  IsInitialized_ = true;
396  ++NumInitialize_;
397 }
398 
399 
400 template<class MatrixType>
402 {
403  const std::string timerName ("Ifpack2::DatabaseSchwarz::compute");
405  if (timer.is_null()) {
406  timer = Teuchos::TimeMonitor::getNewCounter (timerName);
407  }
408 
409  double startTime = timer->wallTime();
410 
411  // Start timing here.
412  {
413  Teuchos::TimeMonitor timeMon(*timer);
414  if (!isInitialized()) {
415  initialize();
416  }
417  IsComputed_ = false;
418  const int maxNnzPerRow = A_->getGlobalMaxNumRowEntries();
419 
420  // Phase 1: Loop over rows of A_, construct patch indices, and construct patch matrices
421  PatchIndices_.resize(0);
422  NumPatches_ = 0;
423  // loop over potential candidates by checking rows of A_
424  for(local_ordinal_type irow=0; irow < (local_ordinal_type) A_->getLocalNumRows(); ++irow) {
425  size_t num_entries = A_->getNumEntriesInLocalRow(irow);
426 
427  // if irow is a potential patch candidate
428  if((local_ordinal_type) num_entries == PatchSize_) {
429  // grab row irow of A_
430  typename row_matrix_type::nonconst_local_inds_host_view_type row_inds("row indices", maxNnzPerRow);
431  typename row_matrix_type::nonconst_values_host_view_type row_vals("row values", maxNnzPerRow);
432  A_->getLocalRowCopy(irow, row_inds, row_vals, num_entries);
433 
434  // check if we've added DOF irow before
435  bool is_new_patch = true;
436  for(size_t ipatch=0; ipatch<PatchIndices_.size(); ++ipatch) {
437  for(size_t i=0; i<PatchIndices_[ipatch].size(); ++i) {
438  if(PatchIndices_[ipatch][i] == irow) {
439  is_new_patch = false;
440  ipatch=PatchIndices_.size(); // likely the ugliest way to break out other than using goto TheEnd:
441  break;
442  }
443  }
444  }
445 
446  // if this patch is new, append the indices
447  if(is_new_patch) {
448  Teuchos::ArrayView<typename row_matrix_type::local_ordinal_type> indices_array_view(row_inds.data(),num_entries);
449  std::vector<typename row_matrix_type::local_ordinal_type> indices_vector = Teuchos::createVector(indices_array_view);
450  PatchIndices_.push_back(indices_vector);
451  NumPatches_++;
452  }
453  }
454  }
455 
456  // Phase 2: construct the list of local patch matrices
458  typedef Teuchos::RCP<DenseMatType> DenseMatRCP;
459  DatabaseIndices_.resize(NumPatches_,-1);
460  Weights_.resize(A_->getLocalNumRows(),0);
461  std::vector<double> index_count(A_->getLocalNumRows(),0);
462  // compute the local patch matrix A_k by grabbing values from the rows of A_
463  for(unsigned int ipatch=0; ipatch< NumPatches_; ++ipatch) {
464  // form a local patch matrix and grab the indices for its rows/columns
465  DenseMatRCP patch_matrix = Teuchos::rcp(new DenseMatType(PatchSize_, PatchSize_));
466  auto indices_vector = PatchIndices_[ipatch];
467 
468  for(local_ordinal_type i=0; i<PatchSize_; ++i) {
469  index_count[indices_vector[i]]++;
470  // grab each row from A_ and throw them into patch_matrix
471  typename row_matrix_type::nonconst_local_inds_host_view_type row_inds("row indices", maxNnzPerRow);
472  typename row_matrix_type::nonconst_values_host_view_type row_vals("row values", maxNnzPerRow);
473  size_t num_entries;
474  A_->getLocalRowCopy(indices_vector[i], row_inds, row_vals, num_entries);
475  for(local_ordinal_type j=0; j<PatchSize_; ++j) {
476  for(size_t k=0; k<num_entries; ++k) {
477  if(row_inds(k) == indices_vector[j]) {
478  (*patch_matrix)(i,j) = row_vals(k);
479  }
480  }
481  }
482  }
483 
484  // check if the local patch matrix has been seen before
485  // this is skipped and the patch is stored anyway if SkipDatabase_ is true
486  bool found_match = false;
487  if(!SkipDatabase_) {
488  for(size_t idatabase=0; idatabase<DatabaseMatrices_.size(); ++idatabase) {
489 
490  // sum errors
492  for(local_ordinal_type irow=0; irow<PatchSize_; irow++) {
493  for(local_ordinal_type icol=0; icol<PatchSize_; ++icol) {
494  DenseMatRCP database_candidate = DatabaseMatrices_[idatabase];
495  abserror += Teuchos::ScalarTraits<typename row_matrix_type::scalar_type>::magnitude((*patch_matrix)(irow,icol)-(*database_candidate)(irow,icol));
496  }
497  // break out early if we finish a row and the error is already too high
499  break;
500  }
501 
502  // check if this error is acceptable; if so, mark the match and break
504  DatabaseIndices_[ipatch] = idatabase;
505  found_match = true;
506  break;
507  }
508  }
509  }
510 
511  // if no match was found, append patch_matrix to the database
512  if(!found_match) {
513  DatabaseMatrices_.push_back(patch_matrix);
514  DatabaseIndices_[ipatch] = DatabaseMatrices_.size()-1;
515  TEUCHOS_TEST_FOR_EXCEPTION(DatabaseMatrices_[DatabaseMatrices_.size()-1].is_null(), std::logic_error,
516  "Ifpack2::DatabaseSchwarz::compute: A matrix was added to the database, but appears to be null!"
517  "Please report this bug to the Ifpack2 developers.");
518  }
519  }
520 
521  // compute proc-local overlap weights
522  for(unsigned int i=0; i<index_count.size(); ++i) {
523  TEUCHOS_TEST_FOR_EXCEPTION(index_count[i] == 0.0, std::logic_error,
524  "Ifpack2::DatabaseSchwarz::compute: DOF " << i << " has no corresponding patch! "
525  "All DOFs must be able to locate in a patch to use this method! "
526  "Have you considered adjusting the patch size? Currently it is " << PatchSize_ << ".");
527  Weights_[i] = 1./index_count[i];
528  }
529  DatabaseSize_ = DatabaseMatrices_.size();
530 
531  // compute how many patches refer to a given database entry
532  std::vector<int> database_counts(DatabaseSize_,0);
533  for(unsigned int ipatch=0; ipatch<NumPatches_; ++ipatch) {
534  database_counts[DatabaseIndices_[ipatch]]++;
535  }
536 
537  // Phase 3: factor the patches using LAPACK (GETRF for factorization)
539  int INFO = 0;
540  ipiv_.resize(DatabaseSize_*PatchSize_);
541  std::fill(ipiv_.begin (), ipiv_.end (), 0);
542  for(unsigned int idatabase=0; idatabase<DatabaseSize_; idatabase++) {
543  int* ipiv = &ipiv_[idatabase*PatchSize_];
544 
545  lapack.GETRF(DatabaseMatrices_[idatabase]->numRows(),
546  DatabaseMatrices_[idatabase]->numCols(),
547  DatabaseMatrices_[idatabase]->values(),
548  DatabaseMatrices_[idatabase]->stride(),
549  ipiv, &INFO);
550 
551  // INFO < 0 is a bug.
553  INFO < 0, std::logic_error, "Ifpack2::DatabaseSchwarz::compute: "
554  "LAPACK's _GETRF (LU factorization with partial pivoting) was called "
555  "incorrectly. INFO = " << INFO << " < 0. "
556  "Please report this bug to the Ifpack2 developers.");
557  // INFO > 0 means the matrix is singular. This is probably an issue
558  // either with the choice of rows the rows we extracted, or with the
559  // input matrix itself.
560  if(INFO > 0) {
561  std::cout << "SINGULAR LOCAL MATRIX, COUNT=" << database_counts[idatabase] << std::endl;
562  }
564  INFO > 0, std::runtime_error, "Ifpack2::DatabaseSchwarz::compute: "
565  "LAPACK's _GETRF (LU factorization with partial pivoting) reports that the "
566  "computed U factor is exactly singular. U(" << INFO << "," << INFO << ") "
567  "(one-based index i) is exactly zero. This probably means that the input "
568  "patch is singular.");
569  }
570  }
571  IsComputed_ = true;
572  ++NumCompute_;
573 
574  ComputeTime_ += (timer->wallTime() - startTime);
575 
576  // print a summary after compute finishes if Verbose_ is true (TODO: fancyostream)
577  if(Verbose_) {
578  std::cout << "Ifpack2::DatabaseSchwarz()::Compute() summary\n";
579  std::cout << "Found " << NumPatches_ << " patches of size " << PatchSize_ << " in matrix A\n";
580  std::cout << "Database tol = " << PatchTolerance_ << "\n";
581  std::cout << "Database size = " << DatabaseSize_ << " patches\n";
582  }
583 }
584 
585 
586 template <class MatrixType>
588  std::ostringstream out;
589 
590  // Output is a valid YAML dictionary in flow style. If you don't
591  // like everything on a single line, you should call describe()
592  // instead.
593  out << "\"Ifpack2::DatabaseSchwarz\": {";
594  out << "Initialized: " << (isInitialized() ? "true" : "false")
595  << ", Computed: " << (isComputed() ? "true" : "false")
596  << ", patch size: " << PatchSize_
597  << ", patch tolerance: " << PatchTolerance_
598  << ", skip database: " << (SkipDatabase_ ? "true" : "false")
599  << ", print database summary: " << (Verbose_ ? "true" : "false");
600 
601  if (getMatrix().is_null()) {
602  out << "Matrix: null";
603  }
604  else {
605  out << "Global matrix dimensions: ["
606  << getMatrix()->getGlobalNumRows() << ", "
607  << getMatrix()->getGlobalNumCols() << "]"
608  << ", Global nnz: " << getMatrix()->getGlobalNumEntries();
609  }
610 
611  out << "}";
612  return out.str();
613 }
614 
615 
616 template <class MatrixType>
619  const Teuchos::EVerbosityLevel verbLevel) const
620 {
622  using std::endl;
623 
624  // Default verbosity level is VERB_LOW
625  const Teuchos::EVerbosityLevel vl =
626  (verbLevel == Teuchos::VERB_DEFAULT) ? Teuchos::VERB_LOW : verbLevel;
627 
628  if (vl == Teuchos::VERB_NONE) {
629  return; // print NOTHING, not even the class name
630  }
631 
632  // By convention, describe() starts with a tab.
633  //
634  // This does affect all processes on which it's valid to print to
635  // 'out'. However, it does not actually print spaces to 'out'
636  // unless operator<< gets called, so it's safe to use on all
637  // processes.
638  Teuchos::OSTab tab0 (out);
639  const int myRank = this->getComm()->getRank();
640  if (myRank == 0) {
641  // Output is a valid YAML dictionary.
642  // In particular, we quote keys with colons in them.
643  out << "\"Ifpack2::DatabaseSchwarz\":" << endl;
644  }
645 
646  Teuchos::OSTab tab1 (out);
647  if (vl >= Teuchos::VERB_LOW && myRank == 0) {
648  out << "Template parameters:" << endl;
649  {
650  Teuchos::OSTab tab2 (out);
651  out << "Scalar: " << TypeNameTraits<scalar_type>::name() << endl
652  << "LocalOrdinal: " << TypeNameTraits<local_ordinal_type>::name() << endl
653  << "GlobalOrdinal: " << TypeNameTraits<global_ordinal_type>::name() << endl
654  << "Device: " << TypeNameTraits<device_type>::name() << endl;
655  }
656  out << "Initialized: " << (isInitialized() ? "true" : "false") << endl
657  << "Computed: " << (isComputed() ? "true" : "false") << endl;
658 
659  if (getMatrix().is_null()) {
660  out << "Matrix: null" << endl;
661  }
662  else {
663  out << "Global matrix dimensions: ["
664  << getMatrix()->getGlobalNumRows() << ", "
665  << getMatrix()->getGlobalNumCols() << "]" << endl
666  << "Global nnz: " << getMatrix()->getGlobalNumEntries() << endl;
667  }
668  }
669 }
670 
671 
672 
673 }//namespace Ifpack2
674 
675 #define IFPACK2_DATABASESCHWARZ_INSTANT(S,LO,GO,N) \
676  template class Ifpack2::DatabaseSchwarz< Tpetra::RowMatrix<S, LO, GO, N> >;
677 
678 #endif // IFPACK2_DATABASESCHWARZ_DEF_HPP
Teuchos::RCP< const row_matrix_type > getMatrix() const
The matrix for which this is a preconditioner.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:157
MatrixType::local_ordinal_type local_ordinal_type
The type of local indices in the input MatrixType.
Definition: Ifpack2_DatabaseSchwarz_decl.hpp:84
void apply(const Tpetra::MultiVector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > &X, Tpetra::MultiVector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > &Y, Teuchos::ETransp mode=Teuchos::NO_TRANS, scalar_type alpha=Teuchos::ScalarTraits< scalar_type >::one(), scalar_type beta=Teuchos::ScalarTraits< scalar_type >::zero()) const
Apply the preconditioner to X, returning the result in Y. Y = alpha*Op(A)*X + beta*Y.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:273
Teuchos::RCP< const map_type > getRangeMap() const
The Tpetra::Map representing the range of this operator.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:193
double getApplyTime() const
The total time spent in all calls to apply().
Definition: Ifpack2_DatabaseSchwarz_def.hpp:241
size_t getNodeSmootherComplexity() const
Get a rough estimate of cost per iteration.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:258
int getNumApply() const
The total number of successful calls to apply().
Definition: Ifpack2_DatabaseSchwarz_def.hpp:223
void initialize()
Initialize the preconditioner.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:386
bool hasTransposeApply() const
Whether it&#39;s possible to apply the transpose of this operator.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:205
T & get(const std::string &name, T def_value)
static RCP< Time > getNewCounter(const std::string &name)
static RCP< Time > lookupCounter(const std::string &name)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
double getInitializeTime() const
The total time spent in all calls to initialize().
Definition: Ifpack2_DatabaseSchwarz_def.hpp:229
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Print the object with some verbosity level to a Teuchos::FancyOStream.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:618
void setParameters(const Teuchos::ParameterList &params)
Set (or reset) parameters.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:93
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
The communicator over which the matrix is distributed.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:144
Teuchos::RCP< const map_type > getDomainMap() const
The Tpetra::Map representing the domain of this operator.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:179
virtual ~DatabaseSchwarz()
Destructor.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:75
double getComputeTime() const
The total time spent in all calls to compute().
Definition: Ifpack2_DatabaseSchwarz_def.hpp:235
double getApplyFlops() const
The total number of floating-point operations taken by all calls to apply().
Definition: Ifpack2_DatabaseSchwarz_def.hpp:253
void GETRF(const OrdinalType &m, const OrdinalType &n, ScalarType *A, const OrdinalType &lda, OrdinalType *IPIV, OrdinalType *info) const
T * getRawPtr() const
void compute()
(Re)compute the left scaling, and (if applicable) estimate max and min eigenvalues of D_inv * A...
Definition: Ifpack2_DatabaseSchwarz_def.hpp:401
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
DatabaseSchwarz(const Teuchos::RCP< const row_matrix_type > &A)
Constructor.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:28
Teuchos::RCP< const Tpetra::CrsMatrix< scalar_type, local_ordinal_type, global_ordinal_type, node_type > > getCrsMatrix() const
Attempt to return the matrix A as a Tpetra::CrsMatrix.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:169
MatrixType::node_type node_type
The Node type used by the input MatrixType.
Definition: Ifpack2_DatabaseSchwarz_decl.hpp:93
virtual void setMatrix(const Teuchos::RCP< const row_matrix_type > &A)
Change the matrix to be preconditioned.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:80
void setZeroStartingSolution(bool zeroStartingSolution)
Set this preconditioner&#39;s parameters.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:137
double getComputeFlops() const
The total number of floating-point operations taken by all calls to compute().
Definition: Ifpack2_DatabaseSchwarz_def.hpp:247
std::string description() const
A simple one-line description of this object.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:587
int getNumInitialize() const
The total number of successful calls to initialize().
Definition: Ifpack2_DatabaseSchwarz_def.hpp:211
static magnitudeType magnitude(T a)
Overlapping Schwarz where redundant patches are not stored explicitly.
Definition: Ifpack2_DatabaseSchwarz_decl.hpp:63
void applyMat(const Tpetra::MultiVector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > &X, Tpetra::MultiVector< scalar_type, local_ordinal_type, global_ordinal_type, node_type > &Y, Teuchos::ETransp mode=Teuchos::NO_TRANS) const
Compute Y = Op(A)*X, where Op(A) is either A, , or .
Definition: Ifpack2_DatabaseSchwarz_def.hpp:367
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
size_type size() const
TypeTo as(const TypeFrom &t)
MatrixType::scalar_type scalar_type
The type of the entries of the input MatrixType.
Definition: Ifpack2_DatabaseSchwarz_decl.hpp:81
static double wallTime()
MatrixType::global_ordinal_type global_ordinal_type
The type of global indices in the input MatrixType.
Definition: Ifpack2_DatabaseSchwarz_decl.hpp:87
int getNumCompute() const
The total number of successful calls to compute().
Definition: Ifpack2_DatabaseSchwarz_def.hpp:217
bool is_null() const