Ifpack2 Templated Preconditioning Package Version 1.0
Loading...
Searching...
No Matches
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"
18#include "Teuchos_TypeNameTraits.hpp"
19#include "Teuchos_LAPACK.hpp"
20#include <iostream>
21#include <sstream>
22
23
24namespace Ifpack2 {
25
26template<class MatrixType>
28DatabaseSchwarz (const Teuchos::RCP<const row_matrix_type>& A)
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
49template<class MatrixType>
51DatabaseSchwarz (const Teuchos::RCP<const row_matrix_type>& A,
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
74template<class MatrixType>
77
78
79template<class MatrixType>
80void DatabaseSchwarz<MatrixType>::setMatrix(const Teuchos::RCP<const row_matrix_type>& A)
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
91template<class MatrixType>
92void
93DatabaseSchwarz<MatrixType>::setParameters(const Teuchos::ParameterList& params)
94{
95 // GH: Copied from CAG and others. Yes, const_cast bad.
96 this->setParametersImpl(const_cast<Teuchos::ParameterList&>(params));
97}
98
99
100template<class MatrixType>
101void
102DatabaseSchwarz<MatrixType>::setParametersImpl(Teuchos::ParameterList& params)
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
114 TEUCHOS_TEST_FOR_EXCEPTION(
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
122 TEUCHOS_TEST_FOR_EXCEPTION(
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
135template<class MatrixType>
136void
138{
139 (void) zeroStartingSolution;
140}
141
142template<class MatrixType>
143Teuchos::RCP<const Teuchos::Comm<int> >
145{
146 Teuchos::RCP<const row_matrix_type> A = getMatrix();
147 TEUCHOS_TEST_FOR_EXCEPTION(
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
155template<class MatrixType>
156Teuchos::RCP<const typename DatabaseSchwarz<MatrixType>::row_matrix_type>
158{
159 return A_;
160}
161
162
163template<class MatrixType>
164Teuchos::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> >
169getCrsMatrix() 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
176template<class MatrixType>
177Teuchos::RCP<const typename DatabaseSchwarz<MatrixType>::map_type>
179getDomainMap() const
180{
181 Teuchos::RCP<const row_matrix_type> A = getMatrix();
182 TEUCHOS_TEST_FOR_EXCEPTION(
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
190template<class MatrixType>
191Teuchos::RCP<const typename DatabaseSchwarz<MatrixType>::map_type>
193getRangeMap() const
194{
195 Teuchos::RCP<const row_matrix_type> A = getMatrix();
196 TEUCHOS_TEST_FOR_EXCEPTION(
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
204template<class MatrixType>
206 return false;
207}
208
209
210template<class MatrixType>
212 return NumInitialize_;
213}
214
215
216template<class MatrixType>
218 return NumCompute_;
219}
220
221
222template<class MatrixType>
224 return NumApply_;
225}
226
227
228template<class MatrixType>
230 return InitializeTime_;
231}
232
233
234template<class MatrixType>
236 return ComputeTime_;
237}
238
239
240template<class MatrixType>
242 return ApplyTime_;
243}
244
245
246template<class MatrixType>
248 return ComputeFlops_;
249}
250
251
252template<class MatrixType>
254 return ApplyFlops_;
255}
256
257template<class MatrixType>
259 Teuchos::RCP<const row_matrix_type> A = getMatrix();
260 TEUCHOS_TEST_FOR_EXCEPTION(
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
270template<class MatrixType>
271void
273apply(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");
280 Teuchos::RCP<Teuchos::Time> timer = Teuchos::TimeMonitor::lookupCounter (timerName);
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().
293 TEUCHOS_TEST_FOR_EXCEPTION(
294 ! isComputed(), std::runtime_error,
295 "Ifpack2::DatabaseSchwarz::apply(): You must call the compute() method before "
296 "you may call apply().");
297 TEUCHOS_TEST_FOR_EXCEPTION(
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
310 Teuchos::LAPACK<int, typename row_matrix_type::scalar_type> lapack;
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
316 Teuchos::Array<typename row_matrix_type::scalar_type> x_patch(PatchSize_);
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.
336 TEUCHOS_TEST_FOR_EXCEPTION(
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.
344 TEUCHOS_TEST_FOR_EXCEPTION(
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
364template<class MatrixType>
365void
367applyMat (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{
371 TEUCHOS_TEST_FOR_EXCEPTION(
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();
376 TEUCHOS_TEST_FOR_EXCEPTION(
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
385template<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");
391 Teuchos::RCP<Teuchos::Time> timer = Teuchos::TimeMonitor::lookupCounter (timerName);
392 if (timer.is_null()) {
393 timer = Teuchos::TimeMonitor::getNewCounter (timerName);
394 }
395 IsInitialized_ = true;
396 ++NumInitialize_;
397}
398
399
400template<class MatrixType>
402{
403 const std::string timerName ("Ifpack2::DatabaseSchwarz::compute");
404 Teuchos::RCP<Teuchos::Time> timer = Teuchos::TimeMonitor::lookupCounter (timerName);
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
457 typedef typename Teuchos::SerialDenseMatrix<typename row_matrix_type::local_ordinal_type,typename row_matrix_type::scalar_type> DenseMatType;
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
491 typename Teuchos::ScalarTraits<typename row_matrix_type::scalar_type>::magnitudeType abserror = 0.0;
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
498 if(abserror > Teuchos::as<typename Teuchos::ScalarTraits<typename row_matrix_type::scalar_type>::magnitudeType>(PatchTolerance_))
499 break;
500 }
501
502 // check if this error is acceptable; if so, mark the match and break
503 if(abserror < Teuchos::as<typename Teuchos::ScalarTraits<typename row_matrix_type::scalar_type>::magnitudeType>(PatchTolerance_)) {
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)
538 Teuchos::LAPACK<int, typename row_matrix_type::scalar_type> lapack;
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.
552 TEUCHOS_TEST_FOR_EXCEPTION(
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 }
563 TEUCHOS_TEST_FOR_EXCEPTION(
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
586template <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
616template <class MatrixType>
618describe (Teuchos::FancyOStream& out,
619 const Teuchos::EVerbosityLevel verbLevel) const
620{
621 using Teuchos::TypeNameTraits;
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
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 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
void setParameters(const Teuchos::ParameterList &params)
Set (or reset) parameters.
Definition Ifpack2_DatabaseSchwarz_def.hpp:93
bool isInitialized() const
Definition Ifpack2_DatabaseSchwarz_decl.hpp:171
bool hasTransposeApply() const
Whether it's possible to apply the transpose of this operator.
Definition Ifpack2_DatabaseSchwarz_def.hpp:205
double getComputeFlops() const
The total number of floating-point operations taken by all calls to compute().
Definition Ifpack2_DatabaseSchwarz_def.hpp:247
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 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
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
MatrixType::global_ordinal_type global_ordinal_type
The type of global indices in the input MatrixType.
Definition Ifpack2_DatabaseSchwarz_decl.hpp:87
DatabaseSchwarz(const Teuchos::RCP< const row_matrix_type > &A)
Constructor.
Definition Ifpack2_DatabaseSchwarz_def.hpp:28
bool isComputed() const
Whether compute() has been called at least once.
Definition Ifpack2_DatabaseSchwarz_decl.hpp:180
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
void setZeroStartingSolution(bool zeroStartingSolution)
Set this preconditioner's parameters.
Definition Ifpack2_DatabaseSchwarz_def.hpp:137
MatrixType::local_ordinal_type local_ordinal_type
The type of local indices in the input MatrixType.
Definition Ifpack2_DatabaseSchwarz_decl.hpp:84
int getNumCompute() const
The total number of successful calls to compute().
Definition Ifpack2_DatabaseSchwarz_def.hpp:217
double getComputeTime() const
The total time spent in all calls to compute().
Definition Ifpack2_DatabaseSchwarz_def.hpp:235
double getApplyTime() const
The total time spent in all calls to apply().
Definition Ifpack2_DatabaseSchwarz_def.hpp:241
virtual void setMatrix(const Teuchos::RCP< const row_matrix_type > &A)
Change the matrix to be preconditioned.
Definition Ifpack2_DatabaseSchwarz_def.hpp:80
MatrixType::scalar_type scalar_type
The type of the entries of the input MatrixType.
Definition Ifpack2_DatabaseSchwarz_decl.hpp:81
Teuchos::RCP< const row_matrix_type > A_
The matrix for which this is a preconditioner.
Definition Ifpack2_DatabaseSchwarz_decl.hpp:231
double getInitializeTime() const
The total time spent in all calls to initialize().
Definition Ifpack2_DatabaseSchwarz_def.hpp:229
Teuchos::RCP< const map_type > getRangeMap() const
The Tpetra::Map representing the range of this operator.
Definition Ifpack2_DatabaseSchwarz_def.hpp:193
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::RCP< const Teuchos::Comm< int > > getComm() const
The communicator over which the matrix is distributed.
Definition Ifpack2_DatabaseSchwarz_def.hpp:144
int getNumInitialize() const
The total number of successful calls to initialize().
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:253
std::string description() const
A simple one-line description of this object.
Definition Ifpack2_DatabaseSchwarz_def.hpp:587
void initialize()
Initialize the preconditioner.
Definition Ifpack2_DatabaseSchwarz_def.hpp:386
Teuchos::RCP< const row_matrix_type > getMatrix() const
The matrix for which this is a preconditioner.
Definition Ifpack2_DatabaseSchwarz_def.hpp:157
Preconditioners and smoothers for Tpetra sparse matrices.
Definition Ifpack2_AdditiveSchwarz_decl.hpp:41