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