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 //
4 // Ifpack2: Templated Object-Oriented Algebraic Preconditioner Package
5 // Copyright (2009) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 //@HEADER
41 */
42 
43 #ifndef IFPACK2_DATABASESCHWARZ_DEF_HPP
44 #define IFPACK2_DATABASESCHWARZ_DEF_HPP
45 
46 #include "Ifpack2_Parameters.hpp"
47 #include "Teuchos_TimeMonitor.hpp"
48 #include "Tpetra_CrsMatrix.hpp"
49 #include "Teuchos_FancyOStream.hpp"
50 #include "Teuchos_oblackholestream.hpp"
52 #include "Teuchos_LAPACK.hpp"
53 #include <iostream>
54 #include <sstream>
55 
56 
57 namespace Ifpack2 {
58 
59 template<class MatrixType>
62  : A_(A),
63  IsInitialized_(false),
64  IsComputed_(false),
65  NumInitialize_(0),
66  NumCompute_(0),
67  NumApply_(0),
68  InitializeTime_(0.0),
69  ComputeTime_(0.0),
70  ApplyTime_(0.0),
71  ComputeFlops_(0.0),
72  ApplyFlops_(0.0),
73  PatchSize_(9),
74  PatchTolerance_(1e-3),
75  SkipDatabase_(false),
76  Verbose_(false)
77 {
78  this->setObjectLabel("Ifpack2::DatabaseSchwarz");
79 }
80 
81 
82 template<class MatrixType>
85  Teuchos::ParameterList& params)
86  : A_(A),
87  IsInitialized_(false),
88  IsComputed_(false),
89  NumInitialize_(0),
90  NumCompute_(0),
91  NumApply_(0),
92  InitializeTime_(0.0),
93  ComputeTime_(0.0),
94  ApplyTime_(0.0),
95  ComputeFlops_(0.0),
96  ApplyFlops_(0.0),
97  PatchSize_(9),
98  PatchTolerance_(1e-3),
99  SkipDatabase_(false),
100  Verbose_(false)
101 {
102  this->setObjectLabel("Ifpack2::DatabaseSchwarz");
103  this->setParameters(params);
104 }
105 
106 
107 template<class MatrixType>
109 }
110 
111 
112 template<class MatrixType>
114 {
115  // ASSERT NON-NULL INPUT
116  if (A.getRawPtr() != A_.getRawPtr()) {
117  IsInitialized_ = false;
118  IsComputed_ = false;
119  A_ = A;
120  }
121 }
122 
123 
124 template<class MatrixType>
125 void
127 {
128  // GH: Copied from CAG and others. Yes, const_cast bad.
129  this->setParametersImpl(const_cast<Teuchos::ParameterList&>(params));
130 }
131 
132 
133 template<class MatrixType>
134 void
136 {
137  // GH: since patch size varies dramatically, it doesn't make sense to force a default size
138  // but I don't know if it's any better to throw if the user doesn't provide a patch size
139  const int defaultPatchSize = 9;
140  const double defaultPatchTolerance = 1e-3;
141  const bool defaultSkipDatabase = false;
142  const bool defaultVerbose = false;
143 
144  // the size of patch to search for
145  PatchSize_ = params.get<int>("database schwarz: patch size",defaultPatchSize);
146 
148  PatchSize_ < 0, std::invalid_argument,
149  "Ifpack2::DatabaseSchwarz::setParameters: \"database schwarz: patch size\" parameter "
150  "must be a nonnegative integer. You gave a value of " << PatchSize_ << ".");
151 
152  // the tolerance at which two patch matrices are considered "equal"
153  PatchTolerance_ = params.get("database schwarz: patch tolerance", defaultPatchTolerance);
154 
156  PatchTolerance_ <= 0, std::invalid_argument,
157  "Ifpack2::DatabaseSchwarz::setParameters: \"database schwarz: patch tolerance\" parameter "
158  "must be a positive double. You gave a value of " << PatchTolerance_ << ".");
159 
160  // whether to skip the database computation and invert all patches or not
161  SkipDatabase_ = params.get<bool>("database schwarz: skip database",defaultSkipDatabase);
162 
163  // verbosity: controls whether to print a database summary at the end of the compute phase
164  Verbose_ = params.get<bool>("database schwarz: print database summary",defaultVerbose);
165 }
166 
167 
168 template<class MatrixType>
169 void
171 {
172  (void) zeroStartingSolution;
173 }
174 
175 template<class MatrixType>
178 {
179  Teuchos::RCP<const row_matrix_type> A = getMatrix();
181  A.is_null(), std::runtime_error, "Ifpack2::DatabaseSchwarz::getComm: The input "
182  "matrix A is null. Please call setMatrix() with a nonnull input matrix "
183  "before calling this method.");
184  return A->getRowMap()->getComm();
185 }
186 
187 
188 template<class MatrixType>
191 {
192  return A_;
193 }
194 
195 
196 template<class MatrixType>
197 Teuchos::RCP<const Tpetra::CrsMatrix<typename MatrixType::scalar_type,
198  typename MatrixType::local_ordinal_type,
199  typename MatrixType::global_ordinal_type,
200  typename MatrixType::node_type> >
202 getCrsMatrix() const {
203  typedef Tpetra::CrsMatrix<scalar_type, local_ordinal_type,
204  global_ordinal_type, node_type> crs_matrix_type;
205  return Teuchos::rcp_dynamic_cast<const crs_matrix_type> (getMatrix());
206 }
207 
208 
209 template<class MatrixType>
213 {
214  Teuchos::RCP<const row_matrix_type> A = getMatrix();
216  A.is_null(), std::runtime_error, "Ifpack2::DatabaseSchwarz::getDomainMap: The "
217  "input matrix A is null. Please call setMatrix() with a nonnull input "
218  "matrix before calling this method.");
219  return A->getDomainMap();
220 }
221 
222 
223 template<class MatrixType>
226 getRangeMap() const
227 {
228  Teuchos::RCP<const row_matrix_type> A = getMatrix();
230  A.is_null(), std::runtime_error, "Ifpack2::DatabaseSchwarz::getRangeMap: The "
231  "input matrix A is null. Please call setMatrix() with a nonnull input "
232  "matrix before calling this method.");
233  return A->getRangeMap();
234 }
235 
236 
237 template<class MatrixType>
239  return false;
240 }
241 
242 
243 template<class MatrixType>
245  return NumInitialize_;
246 }
247 
248 
249 template<class MatrixType>
251  return NumCompute_;
252 }
253 
254 
255 template<class MatrixType>
257  return NumApply_;
258 }
259 
260 
261 template<class MatrixType>
263  return InitializeTime_;
264 }
265 
266 
267 template<class MatrixType>
269  return ComputeTime_;
270 }
271 
272 
273 template<class MatrixType>
275  return ApplyTime_;
276 }
277 
278 
279 template<class MatrixType>
281  return ComputeFlops_;
282 }
283 
284 
285 template<class MatrixType>
287  return ApplyFlops_;
288 }
289 
290 template<class MatrixType>
292  Teuchos::RCP<const row_matrix_type> A = getMatrix();
294  A.is_null(), std::runtime_error, "Ifpack2::DatabaseSchwarz::getNodeSmootherComplexity: "
295  "The input matrix A is null. Please call setMatrix() with a nonnull "
296  "input matrix, then call compute(), before calling this method.");
297  // DatabaseSchwarz costs roughly one apply + one diagonal inverse per iteration
298  return A->getLocalNumRows() + A->getLocalNumEntries();
299 }
300 
301 
302 
303 template<class MatrixType>
304 void
306 apply(const Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type>& X,
307  Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type>& Y,
308  Teuchos::ETransp mode,
309  scalar_type alpha,
310  scalar_type beta) const
311 {
312  const std::string timerName ("Ifpack2::DatabaseSchwarz::apply");
314  if (timer.is_null()) {
315  timer = Teuchos::TimeMonitor::getNewCounter (timerName);
316  }
317 
318  double startTime = timer->wallTime();
319 
320  // Start timing here.
321  {
322  Teuchos::TimeMonitor timeMon (*timer);
323 
324  // compute() calls initialize() if it hasn't already been called.
325  // Thus, we only need to check isComputed().
327  ! isComputed(), std::runtime_error,
328  "Ifpack2::DatabaseSchwarz::apply(): You must call the compute() method before "
329  "you may call apply().");
331  X.getNumVectors() != Y.getNumVectors(), std::runtime_error,
332  "Ifpack2::DatabaseSchwarz::apply(): X and Y must have the same number of "
333  "columns. X.getNumVectors() = " << X.getNumVectors() << " != "
334  << "Y.getNumVectors() = " << Y.getNumVectors() << ".");
335 
336  // 1. Compute beta*Y
337  Y.scale(beta);
338 
339  // 2. Solve prec on X
340  auto X_view = X.getLocalViewHost(Tpetra::Access::ReadOnly);
341  auto Y_view = Y.getLocalViewHost(Tpetra::Access::ReadWrite);
342 
344  int INFO = 0;
345  for(unsigned int ipatch=0; ipatch<NumPatches_; ipatch++) {
346  int idatabase = DatabaseIndices_[ipatch];
347 
348  // 2a. Split X into Xk on each local patch
350  for(unsigned int c=0; c<X_view.extent(1); ++c) {
351  for(unsigned int i=0; i<x_patch.size(); ++i) {
352  x_patch[i] = X_view(PatchIndices_[ipatch][i],c);
353  }
354  }
355 
356  // 2b. Solve each using Lapack::GETRS
357  // GH: TODO: can improve this by grouping all patches such that DatabaseIndices_[ipatch] is equal
358  // in the compute phase and then utilizing the multiple RHS capability here.
359  int numRhs = 1;
360 
361  int* ipiv = &ipiv_[idatabase*PatchSize_];
362 
363  lapack.GETRS('N', DatabaseMatrices_[idatabase]->numRows(), numRhs,
364  DatabaseMatrices_[idatabase]->values(), DatabaseMatrices_[idatabase]->numRows(),
365  ipiv, x_patch.getRawPtr(),
366  DatabaseMatrices_[idatabase]->numRows(), &INFO);
367 
368  // INFO < 0 is a bug.
370  INFO < 0, std::logic_error, "Ifpack2::DatabaseSchwarz::compute: "
371  "LAPACK's _GETRF (LU factorization with partial pivoting) was called "
372  "incorrectly. INFO = " << INFO << " < 0. "
373  "Please report this bug to the Ifpack2 developers.");
374  // INFO > 0 means the matrix is singular. This is probably an issue
375  // either with the choice of rows the rows we extracted, or with the
376  // input matrix itself.
378  INFO > 0, std::runtime_error, "Ifpack2::DatabaseSchwarz::compute: "
379  "LAPACK's _GETRF (LU factorization with partial pivoting) reports that the "
380  "computed U factor is exactly singular. U(" << INFO << "," << INFO << ") "
381  "(one-based index i) is exactly zero. This probably means that the input "
382  "patch is singular.");
383 
384  // 2c. Add alpha*weights*Xk into Y for each Xk
385  for(unsigned int c=0; c<Y_view.extent(1); ++c) {
386  for(unsigned int i=0; i<x_patch.size(); ++i) {
387  Y_view(PatchIndices_[ipatch][i],c) += alpha*Weights_[PatchIndices_[ipatch][i]]*x_patch[i];
388  }
389  }
390  }
391  }
392  ++NumApply_;
393  ApplyTime_ += (timer->wallTime() - startTime);
394 }
395 
396 
397 template<class MatrixType>
398 void
400 applyMat (const Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type>& X,
401  Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type>& Y,
402  Teuchos::ETransp mode) const
403 {
405  X.getNumVectors() != Y.getNumVectors(), std::invalid_argument,
406  "Ifpack2::DatabaseSchwarz::applyMat: X.getNumVectors() != Y.getNumVectors().");
407 
408  Teuchos::RCP<const row_matrix_type> A = getMatrix();
410  A.is_null(), std::runtime_error, "Ifpack2::DatabaseSchwarz::applyMat: The input "
411  "matrix A is null. Please call setMatrix() with a nonnull input matrix "
412  "before calling this method.");
413 
414  A->apply (X, Y, mode);
415 }
416 
417 
418 template<class MatrixType>
420  // We create the timer, but this method doesn't do anything, so
421  // there is no need to start the timer. The resulting total time
422  // will always be zero.
423  const std::string timerName ("Ifpack2::DatabaseSchwarz::initialize");
425  if (timer.is_null()) {
426  timer = Teuchos::TimeMonitor::getNewCounter (timerName);
427  }
428  IsInitialized_ = true;
429  ++NumInitialize_;
430 }
431 
432 
433 template<class MatrixType>
435 {
436  const std::string timerName ("Ifpack2::DatabaseSchwarz::compute");
438  if (timer.is_null()) {
439  timer = Teuchos::TimeMonitor::getNewCounter (timerName);
440  }
441 
442  double startTime = timer->wallTime();
443 
444  // Start timing here.
445  {
446  Teuchos::TimeMonitor timeMon(*timer);
447  if (!isInitialized()) {
448  initialize();
449  }
450  IsComputed_ = false;
451  const int maxNnzPerRow = A_->getGlobalMaxNumRowEntries();
452 
453  // Phase 1: Loop over rows of A_, construct patch indices, and construct patch matrices
454  PatchIndices_.resize(0);
455  NumPatches_ = 0;
456  // loop over potential candidates by checking rows of A_
457  for(local_ordinal_type irow=0; irow < (local_ordinal_type) A_->getLocalNumRows(); ++irow) {
458  size_t num_entries = A_->getNumEntriesInLocalRow(irow);
459 
460  // if irow is a potential patch candidate
461  if((local_ordinal_type) num_entries == PatchSize_) {
462  // grab row irow of A_
463  typename row_matrix_type::nonconst_local_inds_host_view_type row_inds("row indices", maxNnzPerRow);
464  typename row_matrix_type::nonconst_values_host_view_type row_vals("row values", maxNnzPerRow);
465  A_->getLocalRowCopy(irow, row_inds, row_vals, num_entries);
466 
467  // check if we've added DOF irow before
468  bool is_new_patch = true;
469  for(size_t ipatch=0; ipatch<PatchIndices_.size(); ++ipatch) {
470  for(size_t i=0; i<PatchIndices_[ipatch].size(); ++i) {
471  if(PatchIndices_[ipatch][i] == irow) {
472  is_new_patch = false;
473  ipatch=PatchIndices_.size(); // likely the ugliest way to break out other than using goto TheEnd:
474  break;
475  }
476  }
477  }
478 
479  // if this patch is new, append the indices
480  if(is_new_patch) {
481  Teuchos::ArrayView<typename row_matrix_type::local_ordinal_type> indices_array_view(row_inds.data(),num_entries);
482  std::vector<typename row_matrix_type::local_ordinal_type> indices_vector = Teuchos::createVector(indices_array_view);
483  PatchIndices_.push_back(indices_vector);
484  NumPatches_++;
485  }
486  }
487  }
488 
489  // Phase 2: construct the list of local patch matrices
491  typedef Teuchos::RCP<DenseMatType> DenseMatRCP;
492  DatabaseIndices_.resize(NumPatches_,-1);
493  Weights_.resize(A_->getLocalNumRows(),0);
494  std::vector<double> index_count(A_->getLocalNumRows(),0);
495  // compute the local patch matrix A_k by grabbing values from the rows of A_
496  for(unsigned int ipatch=0; ipatch< NumPatches_; ++ipatch) {
497  // form a local patch matrix and grab the indices for its rows/columns
498  DenseMatRCP patch_matrix = Teuchos::rcp(new DenseMatType(PatchSize_, PatchSize_));
499  auto indices_vector = PatchIndices_[ipatch];
500 
501  for(local_ordinal_type i=0; i<PatchSize_; ++i) {
502  index_count[indices_vector[i]]++;
503  // grab each row from A_ and throw them into patch_matrix
504  typename row_matrix_type::nonconst_local_inds_host_view_type row_inds("row indices", maxNnzPerRow);
505  typename row_matrix_type::nonconst_values_host_view_type row_vals("row values", maxNnzPerRow);
506  size_t num_entries;
507  A_->getLocalRowCopy(indices_vector[i], row_inds, row_vals, num_entries);
508  for(local_ordinal_type j=0; j<PatchSize_; ++j) {
509  for(size_t k=0; k<num_entries; ++k) {
510  if(row_inds(k) == indices_vector[j]) {
511  (*patch_matrix)(i,j) = row_vals(k);
512  }
513  }
514  }
515  }
516 
517  // check if the local patch matrix has been seen before
518  // this is skipped and the patch is stored anyway if SkipDatabase_ is true
519  bool found_match = false;
520  if(!SkipDatabase_) {
521  for(size_t idatabase=0; idatabase<DatabaseMatrices_.size(); ++idatabase) {
522 
523  // sum errors
525  for(local_ordinal_type irow=0; irow<PatchSize_; irow++) {
526  for(local_ordinal_type icol=0; icol<PatchSize_; ++icol) {
527  DenseMatRCP database_candidate = DatabaseMatrices_[idatabase];
528  abserror += Teuchos::ScalarTraits<typename row_matrix_type::scalar_type>::magnitude((*patch_matrix)(irow,icol)-(*database_candidate)(irow,icol));
529  }
530  // break out early if we finish a row and the error is already too high
532  break;
533  }
534 
535  // check if this error is acceptable; if so, mark the match and break
537  DatabaseIndices_[ipatch] = idatabase;
538  found_match = true;
539  break;
540  }
541  }
542  }
543 
544  // if no match was found, append patch_matrix to the database
545  if(!found_match) {
546  DatabaseMatrices_.push_back(patch_matrix);
547  DatabaseIndices_[ipatch] = DatabaseMatrices_.size()-1;
548  TEUCHOS_TEST_FOR_EXCEPTION(DatabaseMatrices_[DatabaseMatrices_.size()-1].is_null(), std::logic_error,
549  "Ifpack2::DatabaseSchwarz::compute: A matrix was added to the database, but appears to be null!"
550  "Please report this bug to the Ifpack2 developers.");
551  }
552  }
553 
554  // compute proc-local overlap weights
555  for(unsigned int i=0; i<index_count.size(); ++i) {
556  TEUCHOS_TEST_FOR_EXCEPTION(index_count[i] == 0.0, std::logic_error,
557  "Ifpack2::DatabaseSchwarz::compute: DOF " << i << " has no corresponding patch! "
558  "All DOFs must be able to locate in a patch to use this method! "
559  "Have you considered adjusting the patch size? Currently it is " << PatchSize_ << ".");
560  Weights_[i] = 1./index_count[i];
561  }
562  DatabaseSize_ = DatabaseMatrices_.size();
563 
564  // compute how many patches refer to a given database entry
565  std::vector<int> database_counts(DatabaseSize_,0);
566  for(unsigned int ipatch=0; ipatch<NumPatches_; ++ipatch) {
567  database_counts[DatabaseIndices_[ipatch]]++;
568  }
569 
570  // Phase 3: factor the patches using LAPACK (GETRF for factorization)
572  int INFO = 0;
573  ipiv_.resize(DatabaseSize_*PatchSize_);
574  std::fill(ipiv_.begin (), ipiv_.end (), 0);
575  for(unsigned int idatabase=0; idatabase<DatabaseSize_; idatabase++) {
576  int* ipiv = &ipiv_[idatabase*PatchSize_];
577 
578  lapack.GETRF(DatabaseMatrices_[idatabase]->numRows(),
579  DatabaseMatrices_[idatabase]->numCols(),
580  DatabaseMatrices_[idatabase]->values(),
581  DatabaseMatrices_[idatabase]->stride(),
582  ipiv, &INFO);
583 
584  // INFO < 0 is a bug.
586  INFO < 0, std::logic_error, "Ifpack2::DatabaseSchwarz::compute: "
587  "LAPACK's _GETRF (LU factorization with partial pivoting) was called "
588  "incorrectly. INFO = " << INFO << " < 0. "
589  "Please report this bug to the Ifpack2 developers.");
590  // INFO > 0 means the matrix is singular. This is probably an issue
591  // either with the choice of rows the rows we extracted, or with the
592  // input matrix itself.
593  if(INFO > 0) {
594  std::cout << "SINGULAR LOCAL MATRIX, COUNT=" << database_counts[idatabase] << std::endl;
595  }
597  INFO > 0, std::runtime_error, "Ifpack2::DatabaseSchwarz::compute: "
598  "LAPACK's _GETRF (LU factorization with partial pivoting) reports that the "
599  "computed U factor is exactly singular. U(" << INFO << "," << INFO << ") "
600  "(one-based index i) is exactly zero. This probably means that the input "
601  "patch is singular.");
602  }
603  }
604  IsComputed_ = true;
605  ++NumCompute_;
606 
607  ComputeTime_ += (timer->wallTime() - startTime);
608 
609  // print a summary after compute finishes if Verbose_ is true (TODO: fancyostream)
610  if(Verbose_) {
611  std::cout << "Ifpack2::DatabaseSchwarz()::Compute() summary\n";
612  std::cout << "Found " << NumPatches_ << " patches of size " << PatchSize_ << " in matrix A\n";
613  std::cout << "Database tol = " << PatchTolerance_ << "\n";
614  std::cout << "Database size = " << DatabaseSize_ << " patches\n";
615  }
616 }
617 
618 
619 template <class MatrixType>
621  std::ostringstream out;
622 
623  // Output is a valid YAML dictionary in flow style. If you don't
624  // like everything on a single line, you should call describe()
625  // instead.
626  out << "\"Ifpack2::DatabaseSchwarz\": {";
627  out << "Initialized: " << (isInitialized() ? "true" : "false")
628  << ", Computed: " << (isComputed() ? "true" : "false")
629  << ", patch size: " << PatchSize_
630  << ", patch tolerance: " << PatchTolerance_
631  << ", skip database: " << (SkipDatabase_ ? "true" : "false")
632  << ", print database summary: " << (Verbose_ ? "true" : "false");
633 
634  if (getMatrix().is_null()) {
635  out << "Matrix: null";
636  }
637  else {
638  out << "Global matrix dimensions: ["
639  << getMatrix()->getGlobalNumRows() << ", "
640  << getMatrix()->getGlobalNumCols() << "]"
641  << ", Global nnz: " << getMatrix()->getGlobalNumEntries();
642  }
643 
644  out << "}";
645  return out.str();
646 }
647 
648 
649 template <class MatrixType>
652  const Teuchos::EVerbosityLevel verbLevel) const
653 {
655  using std::endl;
656 
657  // Default verbosity level is VERB_LOW
658  const Teuchos::EVerbosityLevel vl =
659  (verbLevel == Teuchos::VERB_DEFAULT) ? Teuchos::VERB_LOW : verbLevel;
660 
661  if (vl == Teuchos::VERB_NONE) {
662  return; // print NOTHING, not even the class name
663  }
664 
665  // By convention, describe() starts with a tab.
666  //
667  // This does affect all processes on which it's valid to print to
668  // 'out'. However, it does not actually print spaces to 'out'
669  // unless operator<< gets called, so it's safe to use on all
670  // processes.
671  Teuchos::OSTab tab0 (out);
672  const int myRank = this->getComm()->getRank();
673  if (myRank == 0) {
674  // Output is a valid YAML dictionary.
675  // In particular, we quote keys with colons in them.
676  out << "\"Ifpack2::DatabaseSchwarz\":" << endl;
677  }
678 
679  Teuchos::OSTab tab1 (out);
680  if (vl >= Teuchos::VERB_LOW && myRank == 0) {
681  out << "Template parameters:" << endl;
682  {
683  Teuchos::OSTab tab2 (out);
684  out << "Scalar: " << TypeNameTraits<scalar_type>::name() << endl
685  << "LocalOrdinal: " << TypeNameTraits<local_ordinal_type>::name() << endl
686  << "GlobalOrdinal: " << TypeNameTraits<global_ordinal_type>::name() << endl
687  << "Device: " << TypeNameTraits<device_type>::name() << endl;
688  }
689  out << "Initialized: " << (isInitialized() ? "true" : "false") << endl
690  << "Computed: " << (isComputed() ? "true" : "false") << endl;
691 
692  if (getMatrix().is_null()) {
693  out << "Matrix: null" << endl;
694  }
695  else {
696  out << "Global matrix dimensions: ["
697  << getMatrix()->getGlobalNumRows() << ", "
698  << getMatrix()->getGlobalNumCols() << "]" << endl
699  << "Global nnz: " << getMatrix()->getGlobalNumEntries() << endl;
700  }
701  }
702 }
703 
704 
705 
706 }//namespace Ifpack2
707 
708 #define IFPACK2_DATABASESCHWARZ_INSTANT(S,LO,GO,N) \
709  template class Ifpack2::DatabaseSchwarz< Tpetra::RowMatrix<S, LO, GO, N> >;
710 
711 #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:190
MatrixType::local_ordinal_type local_ordinal_type
The type of local indices in the input MatrixType.
Definition: Ifpack2_DatabaseSchwarz_decl.hpp:118
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:306
Teuchos::RCP< const map_type > getRangeMap() const
The Tpetra::Map representing the range of this operator.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:226
double getApplyTime() const
The total time spent in all calls to apply().
Definition: Ifpack2_DatabaseSchwarz_def.hpp:274
size_t getNodeSmootherComplexity() const
Get a rough estimate of cost per iteration.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:291
int getNumApply() const
The total number of successful calls to apply().
Definition: Ifpack2_DatabaseSchwarz_def.hpp:256
void initialize()
Initialize the preconditioner.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:419
bool hasTransposeApply() const
Whether it&#39;s possible to apply the transpose of this operator.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:238
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:262
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:651
void setParameters(const Teuchos::ParameterList &params)
Set (or reset) parameters.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:126
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
The communicator over which the matrix is distributed.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:177
Teuchos::RCP< const map_type > getDomainMap() const
The Tpetra::Map representing the domain of this operator.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:212
virtual ~DatabaseSchwarz()
Destructor.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:108
double getComputeTime() const
The total time spent in all calls to compute().
Definition: Ifpack2_DatabaseSchwarz_def.hpp:268
double getApplyFlops() const
The total number of floating-point operations taken by all calls to apply().
Definition: Ifpack2_DatabaseSchwarz_def.hpp:286
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:434
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:61
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:202
MatrixType::node_type node_type
The Node type used by the input MatrixType.
Definition: Ifpack2_DatabaseSchwarz_decl.hpp:127
virtual void setMatrix(const Teuchos::RCP< const row_matrix_type > &A)
Change the matrix to be preconditioned.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:113
void setZeroStartingSolution(bool zeroStartingSolution)
Set this preconditioner&#39;s parameters.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:170
double getComputeFlops() const
The total number of floating-point operations taken by all calls to compute().
Definition: Ifpack2_DatabaseSchwarz_def.hpp:280
std::string description() const
A simple one-line description of this object.
Definition: Ifpack2_DatabaseSchwarz_def.hpp:620
int getNumInitialize() const
The total number of successful calls to initialize().
Definition: Ifpack2_DatabaseSchwarz_def.hpp:244
static magnitudeType magnitude(T a)
Overlapping Schwarz where redundant patches are not stored explicitly.
Definition: Ifpack2_DatabaseSchwarz_decl.hpp:97
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:400
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:115
static double wallTime()
MatrixType::global_ordinal_type global_ordinal_type
The type of global indices in the input MatrixType.
Definition: Ifpack2_DatabaseSchwarz_decl.hpp:121
int getNumCompute() const
The total number of successful calls to compute().
Definition: Ifpack2_DatabaseSchwarz_def.hpp:250
bool is_null() const