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
23namespace Ifpack2 {
24
25template <class MatrixType>
27 DatabaseSchwarz(const Teuchos::RCP<const row_matrix_type>& A)
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
46template <class MatrixType>
48 DatabaseSchwarz(const Teuchos::RCP<const row_matrix_type>& A,
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
69template <class MatrixType>
72
73template <class MatrixType>
74void DatabaseSchwarz<MatrixType>::setMatrix(const Teuchos::RCP<const row_matrix_type>& A) {
75 // ASSERT NON-NULL INPUT
76 if (A.getRawPtr() != A_.getRawPtr()) {
77 IsInitialized_ = false;
78 IsComputed_ = false;
79 A_ = A;
80 }
81}
82
83template <class MatrixType>
84void DatabaseSchwarz<MatrixType>::setParameters(const Teuchos::ParameterList& params) {
85 // GH: Copied from CAG and others. Yes, const_cast bad.
86 this->setParametersImpl(const_cast<Teuchos::ParameterList&>(params));
87}
88
89template <class MatrixType>
90void DatabaseSchwarz<MatrixType>::setParametersImpl(Teuchos::ParameterList& params) {
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
101 TEUCHOS_TEST_FOR_EXCEPTION(
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
110 TEUCHOS_TEST_FOR_EXCEPTION(
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
123template <class MatrixType>
125 (void)zeroStartingSolution;
126}
127
128template <class MatrixType>
129Teuchos::RCP<const Teuchos::Comm<int> >
131 Teuchos::RCP<const row_matrix_type> A = getMatrix();
132 TEUCHOS_TEST_FOR_EXCEPTION(
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
140template <class MatrixType>
141Teuchos::RCP<const typename DatabaseSchwarz<MatrixType>::row_matrix_type>
143 return A_;
144}
145
146template <class MatrixType>
147Teuchos::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
159template <class MatrixType>
160Teuchos::RCP<const typename DatabaseSchwarz<MatrixType>::map_type>
162 getDomainMap() const {
163 Teuchos::RCP<const row_matrix_type> A = getMatrix();
164 TEUCHOS_TEST_FOR_EXCEPTION(
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
172template <class MatrixType>
173Teuchos::RCP<const typename DatabaseSchwarz<MatrixType>::map_type>
175 getRangeMap() const {
176 Teuchos::RCP<const row_matrix_type> A = getMatrix();
177 TEUCHOS_TEST_FOR_EXCEPTION(
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
185template <class MatrixType>
187 return false;
188}
189
190template <class MatrixType>
192 return NumInitialize_;
193}
194
195template <class MatrixType>
197 return NumCompute_;
198}
199
200template <class MatrixType>
202 return NumApply_;
203}
204
205template <class MatrixType>
207 return InitializeTime_;
208}
209
210template <class MatrixType>
212 return ComputeTime_;
213}
214
215template <class MatrixType>
217 return ApplyTime_;
218}
219
220template <class MatrixType>
222 return ComputeFlops_;
223}
224
225template <class MatrixType>
227 return ApplyFlops_;
228}
229
230template <class MatrixType>
232 Teuchos::RCP<const row_matrix_type> A = getMatrix();
233 TEUCHOS_TEST_FOR_EXCEPTION(
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
242template <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");
250 Teuchos::RCP<Teuchos::Time> timer = Teuchos::TimeMonitor::lookupCounter(timerName);
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().
263 TEUCHOS_TEST_FOR_EXCEPTION(
264 !isComputed(), std::runtime_error,
265 "Ifpack2::DatabaseSchwarz::apply(): You must call the compute() method before "
266 "you may call apply().");
267 TEUCHOS_TEST_FOR_EXCEPTION(
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
281 Teuchos::LAPACK<int, typename row_matrix_type::scalar_type> lapack;
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
287 Teuchos::Array<typename row_matrix_type::scalar_type> x_patch(PatchSize_);
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.
307 TEUCHOS_TEST_FOR_EXCEPTION(
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.
317 TEUCHOS_TEST_FOR_EXCEPTION(
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
338template <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 {
343 TEUCHOS_TEST_FOR_EXCEPTION(
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();
348 TEUCHOS_TEST_FOR_EXCEPTION(
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
357template <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");
363 Teuchos::RCP<Teuchos::Time> timer = Teuchos::TimeMonitor::lookupCounter(timerName);
364 if (timer.is_null()) {
365 timer = Teuchos::TimeMonitor::getNewCounter(timerName);
366 }
367 IsInitialized_ = true;
368 ++NumInitialize_;
369}
370
371template <class MatrixType>
373 const std::string timerName("Ifpack2::DatabaseSchwarz::compute");
374 Teuchos::RCP<Teuchos::Time> timer = Teuchos::TimeMonitor::lookupCounter(timerName);
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
427 typedef typename Teuchos::SerialDenseMatrix<typename row_matrix_type::local_ordinal_type, typename row_matrix_type::scalar_type> DenseMatType;
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
460 typename Teuchos::ScalarTraits<typename row_matrix_type::scalar_type>::magnitudeType abserror = 0.0;
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
467 if (abserror > Teuchos::as<typename Teuchos::ScalarTraits<typename row_matrix_type::scalar_type>::magnitudeType>(PatchTolerance_))
468 break;
469 }
470
471 // check if this error is acceptable; if so, mark the match and break
472 if (abserror < Teuchos::as<typename Teuchos::ScalarTraits<typename row_matrix_type::scalar_type>::magnitudeType>(PatchTolerance_)) {
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)
508 Teuchos::LAPACK<int, typename row_matrix_type::scalar_type> lapack;
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.
522 TEUCHOS_TEST_FOR_EXCEPTION(
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 }
535 TEUCHOS_TEST_FOR_EXCEPTION(
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
559template <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
587template <class MatrixType>
589 describe(Teuchos::FancyOStream& out,
590 const Teuchos::EVerbosityLevel verbLevel) const {
591 using std::endl;
592 using Teuchos::TypeNameTraits;
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
Overlapping Schwarz where redundant patches are not stored explicitly.
Definition Ifpack2_DatabaseSchwarz_decl.hpp:70
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 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
void setParameters(const Teuchos::ParameterList &params)
Set (or reset) parameters.
Definition Ifpack2_DatabaseSchwarz_def.hpp:84
bool hasTransposeApply() const
Whether it's possible to apply the transpose of this operator.
Definition Ifpack2_DatabaseSchwarz_def.hpp:186
double getComputeFlops() const
The total number of floating-point operations taken by all calls to compute().
Definition Ifpack2_DatabaseSchwarz_def.hpp:221
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 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
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
MatrixType::global_ordinal_type global_ordinal_type
The type of global indices in the input MatrixType.
Definition Ifpack2_DatabaseSchwarz_decl.hpp:85
DatabaseSchwarz(const Teuchos::RCP< const row_matrix_type > &A)
Constructor.
Definition Ifpack2_DatabaseSchwarz_def.hpp:27
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
void setZeroStartingSolution(bool zeroStartingSolution)
Set this preconditioner's parameters.
Definition Ifpack2_DatabaseSchwarz_def.hpp:124
MatrixType::local_ordinal_type local_ordinal_type
The type of local indices in the input MatrixType.
Definition Ifpack2_DatabaseSchwarz_decl.hpp:82
int getNumCompute() const
The total number of successful calls to compute().
Definition Ifpack2_DatabaseSchwarz_def.hpp:196
double getComputeTime() const
The total time spent in all calls to compute().
Definition Ifpack2_DatabaseSchwarz_def.hpp:211
double getApplyTime() const
The total time spent in all calls to apply().
Definition Ifpack2_DatabaseSchwarz_def.hpp:216
virtual void setMatrix(const Teuchos::RCP< const row_matrix_type > &A)
Change the matrix to be preconditioned.
Definition Ifpack2_DatabaseSchwarz_def.hpp:74
MatrixType::scalar_type scalar_type
The type of the entries of the input MatrixType.
Definition Ifpack2_DatabaseSchwarz_decl.hpp:79
double getInitializeTime() const
The total time spent in all calls to initialize().
Definition Ifpack2_DatabaseSchwarz_def.hpp:206
Teuchos::RCP< const map_type > getRangeMap() const
The Tpetra::Map representing the range of this operator.
Definition Ifpack2_DatabaseSchwarz_def.hpp:175
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::RCP< const Teuchos::Comm< int > > getComm() const
The communicator over which the matrix is distributed.
Definition Ifpack2_DatabaseSchwarz_def.hpp:130
int getNumInitialize() const
The total number of successful calls to initialize().
Definition Ifpack2_DatabaseSchwarz_def.hpp:191
double getApplyFlops() const
The total number of floating-point operations taken by all calls to apply().
Definition Ifpack2_DatabaseSchwarz_def.hpp:226
std::string description() const
A simple one-line description of this object.
Definition Ifpack2_DatabaseSchwarz_def.hpp:560
void initialize()
Initialize the preconditioner.
Definition Ifpack2_DatabaseSchwarz_def.hpp:358
Teuchos::RCP< const row_matrix_type > getMatrix() const
The matrix for which this is a preconditioner.
Definition Ifpack2_DatabaseSchwarz_def.hpp:142
Preconditioners and smoothers for Tpetra sparse matrices.
Definition Ifpack2_AdditiveSchwarz_decl.hpp:40