10 #ifndef IFPACK2_BLOCKRELAXATION_DEF_HPP
11 #define IFPACK2_BLOCKRELAXATION_DEF_HPP
14 #include "Ifpack2_LinearPartitioner.hpp"
15 #include "Ifpack2_LinePartitioner.hpp"
16 #include "Ifpack2_Zoltan2Partitioner_decl.hpp"
17 #include "Ifpack2_Zoltan2Partitioner_def.hpp"
19 #include "Ifpack2_Details_UserPartitioner_def.hpp"
20 #include "Ifpack2_LocalFilter.hpp"
21 #include "Ifpack2_Parameters.hpp"
23 #include "Tpetra_BlockCrsMatrix_Helpers_decl.hpp"
24 #include "Tpetra_Import_Util.hpp"
25 #include "Ifpack2_BlockHelper_Timers.hpp"
29 template<
class MatrixType,
class ContainerType>
34 IsInitialized_ =
false;
36 Partitioner_ = Teuchos::null;
40 IsParallel_ = (A->getRowMap ()->getComm ()->getSize () != 1);
42 Teuchos::rcp_dynamic_cast<
const block_crs_matrix_type> (A);
43 hasBlockCrsMatrix_ = !A_bcrs.
is_null();
45 if (! Container_.is_null ()) {
48 Container_->clearBlocks();
57 template<
class MatrixType,
class ContainerType>
61 Container_ (Teuchos::null),
62 Partitioner_ (Teuchos::null),
63 PartitionerType_ (
"linear"),
66 containerType_ (
"TriDi"),
67 PrecType_ (Ifpack2::Details::JACOBI),
68 ZeroStartingSolution_ (true),
69 hasBlockCrsMatrix_ (false),
70 DoBackwardGS_ (false),
73 schwarzCombineMode_(
"ZERO"),
74 DampingFactor_ (
STS::one ()),
75 IsInitialized_ (false),
81 InitializeTime_ (0.0),
85 NumGlobalNonzeros_ (0),
87 Importer_ (Teuchos::null)
92 template<
class MatrixType,
class ContainerType>
97 template<
class MatrixType,
class ContainerType>
104 validParams->
set(
"relaxation: container",
"TriDi");
105 validParams->
set(
"relaxation: backward mode",
false);
106 validParams->
set(
"relaxation: type",
"Jacobi");
107 validParams->
set(
"relaxation: sweeps", 1);
108 validParams->
set(
"relaxation: damping factor", STS::one());
109 validParams->
set(
"relaxation: zero starting solution",
true);
110 validParams->
set(
"block relaxation: decouple dofs",
false);
111 validParams->
set(
"schwarz: compute condest",
false);
112 validParams->
set(
"schwarz: combine mode",
"ZERO");
113 validParams->
set(
"schwarz: use reordering",
true);
114 validParams->
set(
"schwarz: filter singletons",
false);
115 validParams->
set(
"schwarz: overlap level", 0);
116 validParams->
set(
"partitioner: type",
"greedy");
117 validParams->
set(
"zoltan2: algorithm",
"phg");
118 validParams->
set(
"partitioner: local parts", 1);
119 validParams->
set(
"partitioner: overlap", 0);
120 validParams->
set(
"partitioner: combine mode",
"ZERO");
122 validParams->
set(
"partitioner: parts", tmp0);
124 validParams->
set(
"partitioner: global ID parts", tmp1);
125 validParams->
set(
"partitioner: nonsymmetric overlap combine",
false);
126 validParams->
set(
"partitioner: maintain sparsity",
false);
127 validParams->
set(
"fact: ilut level-of-fill", 1.0);
128 validParams->
set(
"fact: absolute threshold", 0.0);
129 validParams->
set(
"fact: relative threshold", 1.0);
130 validParams->
set(
"fact: relax value", 0.0);
133 validParams->
set(
"Amesos2",dummyList);
135 validParams->
set(
"Amesos2 solver name",
"KLU2");
138 validParams->
set(
"partitioner: map", tmp);
140 validParams->
set(
"partitioner: line detection threshold", 0.0);
141 validParams->
set(
"partitioner: PDE equations", 1);
143 typename MatrixType::local_ordinal_type,
144 typename MatrixType::global_ordinal_type,
145 typename MatrixType::node_type> > dummy;
146 validParams->
set(
"partitioner: coordinates",dummy);
147 validParams->
set(
"timer for apply",
true);
148 validParams->
set(
"partitioner: subparts per part", 1);
149 validParams->
set(
"partitioner: block size", -1);
150 validParams->
set(
"partitioner: print level",
false);
151 validParams->
set(
"partitioner: explicit convert to BlockCrs",
false);
152 validParams->
set(
"partitioner: checkBlockConsistency",
true);
153 validParams->
set(
"partitioner: use LIDs",
true);
158 template<
class MatrixType,
class ContainerType>
166 this->setParametersImpl(const_cast<Teuchos::ParameterList&>(pl));
169 template<
class MatrixType,
class ContainerType>
174 if (List.
isType<
double>(
"relaxation: damping factor")) {
177 scalar_type df = List.
get<
double>(
"relaxation: damping factor");
178 List.
remove(
"relaxation: damping factor");
179 List.
set(
"relaxation: damping factor",df);
193 containerType_ = List.
get<std::string> (
"relaxation: container");
195 if(containerType_ ==
"Tridiagonal") {
196 containerType_ =
"TriDi";
198 if(containerType_ ==
"Block Tridiagonal") {
199 containerType_ =
"BlockTriDi";
204 const std::string relaxType = List.
get<std::string> (
"relaxation: type");
206 if (relaxType ==
"Jacobi") {
207 PrecType_ = Ifpack2::Details::JACOBI;
209 else if (relaxType ==
"MT Split Jacobi") {
210 PrecType_ = Ifpack2::Details::MTSPLITJACOBI;
212 else if (relaxType ==
"Gauss-Seidel") {
213 PrecType_ = Ifpack2::Details::GS;
215 else if (relaxType ==
"Symmetric Gauss-Seidel") {
216 PrecType_ = Ifpack2::Details::SGS;
220 (
true, std::invalid_argument,
"Ifpack2::BlockRelaxation::"
221 "setParameters: Invalid parameter value \"" << relaxType
222 <<
"\" for parameter \"relaxation: type\".");
227 NumSweeps_ = List.
get<
int> (
"relaxation: sweeps");
233 if (List.
isParameter (
"relaxation: damping factor")) {
234 if (List.
isType<
double> (
"relaxation: damping factor")) {
235 const double dampingFactor =
236 List.
get<
double> (
"relaxation: damping factor");
237 DampingFactor_ =
static_cast<scalar_type
> (dampingFactor);
239 else if (List.
isType<scalar_type> (
"relaxation: damping factor")) {
240 DampingFactor_ = List.
get<scalar_type> (
"relaxation: damping factor");
242 else if (List.
isType<magnitude_type> (
"relaxation: damping factor")) {
243 const magnitude_type dampingFactor =
244 List.
get<magnitude_type> (
"relaxation: damping factor");
245 DampingFactor_ =
static_cast<scalar_type
> (dampingFactor);
249 (
true, std::invalid_argument,
"Ifpack2::BlockRelaxation::"
250 "setParameters: Parameter \"relaxation: damping factor\" "
251 "has the wrong type.");
255 if (List.
isParameter (
"relaxation: zero starting solution")) {
256 ZeroStartingSolution_ = List.
get<
bool> (
"relaxation: zero starting solution");
259 if (List.
isParameter (
"relaxation: backward mode")) {
260 DoBackwardGS_ = List.
get<
bool> (
"relaxation: backward mode");
264 PartitionerType_ = List.
get<std::string> (
"partitioner: type");
269 if (List.
isParameter (
"partitioner: local parts")) {
270 if (List.
isType<local_ordinal_type> (
"partitioner: local parts")) {
271 NumLocalBlocks_ = List.
get<local_ordinal_type> (
"partitioner: local parts");
273 else if (! std::is_same<int, local_ordinal_type>::value &&
274 List.
isType<
int> (
"partitioner: local parts")) {
275 NumLocalBlocks_ = List.
get<
int> (
"partitioner: local parts");
279 (
true, std::invalid_argument,
"Ifpack2::BlockRelaxation::"
280 "setParameters: Parameter \"partitioner: local parts\" "
281 "has the wrong type.");
285 if (List.
isParameter (
"partitioner: overlap level")) {
286 if (List.
isType<
int> (
"partitioner: overlap level")) {
287 OverlapLevel_ = List.
get<
int> (
"partitioner: overlap level");
289 else if (! std::is_same<int, local_ordinal_type>::value &&
290 List.
isType<local_ordinal_type> (
"partitioner: overlap level")) {
291 OverlapLevel_ = List.
get<local_ordinal_type> (
"partitioner: overlap level");
295 (
true, std::invalid_argument,
"Ifpack2::BlockRelaxation::"
296 "setParameters: Parameter \"partitioner: overlap level\" "
297 "has the wrong type.");
302 if ( ( List.
isParameter(
"partitioner: global ID parts")) && (OverlapLevel_ < 1)) OverlapLevel_ = 1;
304 if (List.
isParameter (
"partitioner: nonsymmetric overlap combine"))
305 nonsymCombine_ = List.
get<
bool> (
"partitioner: nonsymmetric overlap combine");
307 if (List.
isParameter (
"partitioner: combine mode"))
308 schwarzCombineMode_ = List.
get<std::string> (
"partitioner: combine mode");
310 std::string defaultContainer =
"TriDi";
311 if(std::is_same<ContainerType, Container<MatrixType> >::value)
317 if (PrecType_ != Ifpack2::Details::JACOBI) {
320 if (NumLocalBlocks_ < static_cast<local_ordinal_type> (0)) {
321 NumLocalBlocks_ = A_->getLocalNumRows() / (-NumLocalBlocks_);
325 if(List.
isParameter(
"block relaxation: decouple dofs"))
326 decouple_ = List.
get<
bool>(
"block relaxation: decouple dofs");
332 DoBackwardGS_, std::runtime_error,
333 "Ifpack2::BlockRelaxation:setParameters: Setting the \"relaxation: "
334 "backward mode\" parameter to true is not yet supported.");
337 TimerForApply_ = List.
get<
bool>(
"timer for apply");
344 template<
class MatrixType,
class ContainerType>
349 (A_.
is_null (), std::runtime_error,
"Ifpack2::BlockRelaxation::getComm: "
350 "The matrix is null. You must call setMatrix() with a nonnull matrix "
351 "before you may call this method.");
352 return A_->getComm ();
355 template<
class MatrixType,
class ContainerType>
356 Teuchos::RCP<
const Tpetra::RowMatrix<
typename MatrixType::scalar_type,
357 typename MatrixType::local_ordinal_type,
358 typename MatrixType::global_ordinal_type,
359 typename MatrixType::node_type> >
364 template<
class MatrixType,
class ContainerType>
365 Teuchos::RCP<
const Tpetra::Map<
typename MatrixType::local_ordinal_type,
366 typename MatrixType::global_ordinal_type,
367 typename MatrixType::node_type> >
372 (A_.
is_null (), std::runtime_error,
"Ifpack2::BlockRelaxation::"
373 "getDomainMap: The matrix is null. You must call setMatrix() with a "
374 "nonnull matrix before you may call this method.");
375 return A_->getDomainMap ();
378 template<
class MatrixType,
class ContainerType>
379 Teuchos::RCP<
const Tpetra::Map<
typename MatrixType::local_ordinal_type,
380 typename MatrixType::global_ordinal_type,
381 typename MatrixType::node_type> >
386 (A_.
is_null (), std::runtime_error,
"Ifpack2::BlockRelaxation::"
387 "getRangeMap: The matrix is null. You must call setMatrix() with a "
388 "nonnull matrix before you may call this method.");
389 return A_->getRangeMap ();
392 template<
class MatrixType,
class ContainerType>
399 template<
class MatrixType,
class ContainerType>
403 return NumInitialize_;
406 template<
class MatrixType,
class ContainerType>
414 template<
class MatrixType,
class ContainerType>
422 template<
class MatrixType,
class ContainerType>
427 return InitializeTime_;
430 template<
class MatrixType,
class ContainerType>
438 template<
class MatrixType,
class ContainerType>
447 template<
class MatrixType,
class ContainerType>
450 A_.
is_null (), std::runtime_error,
"Ifpack2::BlockRelaxation::getNodeSmootherComplexity: "
451 "The input matrix A is null. Please call setMatrix() with a nonnull "
452 "input matrix, then call compute(), before calling this method.");
455 size_t block_nnz = 0;
457 block_nnz += Partitioner_->numRowsInPart(i) *Partitioner_->numRowsInPart(i);
459 return block_nnz + A_->getLocalNumEntries();
462 template<
class MatrixType,
class ContainerType>
465 apply (
const Tpetra::MultiVector<
typename MatrixType::scalar_type,
466 typename MatrixType::local_ordinal_type,
467 typename MatrixType::global_ordinal_type,
468 typename MatrixType::node_type>& X,
469 Tpetra::MultiVector<
typename MatrixType::scalar_type,
470 typename MatrixType::local_ordinal_type,
471 typename MatrixType::global_ordinal_type,
472 typename MatrixType::node_type>& Y,
478 (A_.
is_null (), std::runtime_error,
"Ifpack2::BlockRelaxation::apply: "
479 "The matrix is null. You must call setMatrix() with a nonnull matrix, "
480 "then call initialize() and compute() (in that order), before you may "
481 "call this method.");
483 ! isComputed (), std::runtime_error,
"Ifpack2::BlockRelaxation::apply: "
484 "isComputed() must be true prior to calling apply.");
485 TEUCHOS_TEST_FOR_EXCEPTION(
486 X.getNumVectors () != Y.getNumVectors (), std::invalid_argument,
487 "Ifpack2::BlockRelaxation::apply: X.getNumVectors() = "
488 << X.getNumVectors () <<
" != Y.getNumVectors() = "
489 << Y.getNumVectors () <<
".");
490 TEUCHOS_TEST_FOR_EXCEPTION(
492 "apply: This method currently only implements the case mode == Teuchos::"
493 "NO_TRANS. Transposed modes are not currently supported.");
494 TEUCHOS_TEST_FOR_EXCEPTION(
496 "Ifpack2::BlockRelaxation::apply: This method currently only implements "
497 "the case alpha == 1. You specified alpha = " << alpha <<
".");
498 TEUCHOS_TEST_FOR_EXCEPTION(
500 "Ifpack2::BlockRelaxation::apply: This method currently only implements "
501 "the case beta == 0. You specified beta = " << beta <<
".");
503 const std::string timerName (
"Ifpack2::BlockRelaxation::apply");
505 if (TimerForApply_) {
527 X_copy = rcpFromRef (X);
531 if (ZeroStartingSolution_) {
532 Y.putScalar (STS::zero ());
537 case Ifpack2::Details::JACOBI:
538 ApplyInverseJacobi(*X_copy,Y);
540 case Ifpack2::Details::GS:
541 ApplyInverseGS(*X_copy,Y);
543 case Ifpack2::Details::SGS:
544 ApplyInverseSGS(*X_copy,Y);
546 case Ifpack2::Details::MTSPLITJACOBI:
548 Container_->applyInverseJacobi(*X_copy, Y, DampingFactor_, ZeroStartingSolution_, NumSweeps_);
551 TEUCHOS_TEST_FOR_EXCEPTION
552 (
true, std::logic_error,
"Ifpack2::BlockRelaxation::apply: Invalid "
553 "PrecType_ enum value " << PrecType_ <<
". Valid values are Ifpack2::"
554 "Details::JACOBI = " << Ifpack2::Details::JACOBI <<
", Ifpack2::Details"
555 "::GS = " << Ifpack2::Details::GS <<
", and Ifpack2::Details::SGS = "
556 << Ifpack2::Details::SGS <<
". Please report this bug to the Ifpack2 "
561 ApplyTime_ += (time.
wallTime() - startTime);
565 template<
class MatrixType,
class ContainerType>
568 applyMat (
const Tpetra::MultiVector<
typename MatrixType::scalar_type,
569 typename MatrixType::local_ordinal_type,
570 typename MatrixType::global_ordinal_type,
571 typename MatrixType::node_type>& X,
572 Tpetra::MultiVector<
typename MatrixType::scalar_type,
573 typename MatrixType::local_ordinal_type,
574 typename MatrixType::global_ordinal_type,
575 typename MatrixType::node_type>& Y,
578 A_->apply (X, Y, mode);
581 template<
class MatrixType,
class ContainerType>
587 typedef Tpetra::RowGraph<local_ordinal_type, global_ordinal_type, node_type>
591 (A_.
is_null (), std::runtime_error,
"Ifpack2::BlockRelaxation::initialize: "
592 "The matrix is null. You must call setMatrix() with a nonnull matrix "
593 "before you may call this method.");
597 double startTime = timer->wallTime();
601 IsInitialized_ =
false;
605 Teuchos::rcp_dynamic_cast<
const block_crs_matrix_type> (A_);
606 hasBlockCrsMatrix_ = !A_bcrs.
is_null();
610 if(!hasBlockCrsMatrix_ && List_.isParameter(
"relaxation: container") && List_.get<std::string>(
"relaxation: container") ==
"BlockTriDi" ) {
611 IFPACK2_BLOCKHELPER_TIMER(
"Ifpack2::BlockRelaxation::initialize::convertToBlockCrsMatrix", convertToBlockCrsMatrix);
612 int block_size = List_.get<
int>(
"partitioner: block size");
613 bool use_explicit_conversion = List_.isParameter(
"partitioner: explicit convert to BlockCrs") && List_.get<
bool>(
"partitioner: explicit convert to BlockCrs");
615 (use_explicit_conversion && block_size == -1,
"A pointwise matrix and block_size = -1 were given as inputs.");
616 bool use_LID = !List_.isParameter(
"partitioner: use LIDs") || List_.get<
bool>(
"partitioner: use LIDs");
617 bool check_block_consistency = !List_.isParameter(
"partitioner: checkBlockConsistency") || List_.get<
bool>(
"partitioner: checkBlockConsistency");
619 if ( (use_LID || !use_explicit_conversion) && check_block_consistency ) {
620 if ( !A_->getGraph ()->getImporter().
is_null()) {
621 TEUCHOS_TEST_FOR_EXCEPT_MSG
622 (!Tpetra::Import_Util::checkBlockConsistency(*(A_->getGraph ()->getColMap()), block_size),
623 "The pointwise graph of the input matrix A pointwise is not consistent with block_size.");
626 if(use_explicit_conversion) {
627 A_bcrs = Tpetra::convertToBlockCrsMatrix(*Teuchos::rcp_dynamic_cast<const crs_matrix_type>(A_), block_size, use_LID);
629 hasBlockCrsMatrix_ =
true;
630 graph = A_->getGraph ();
633 graph = Tpetra::getBlockCrsGraph(*Teuchos::rcp_dynamic_cast<const crs_matrix_type>(A_), block_size,
true);
635 IFPACK2_BLOCKHELPER_TIMER_DEFAULT_FENCE();
638 NumLocalRows_ = A_->getLocalNumRows ();
639 NumGlobalRows_ = A_->getGlobalNumRows ();
640 NumGlobalNonzeros_ = A_->getGlobalNumEntries ();
645 Partitioner_ = Teuchos::null;
647 if (PartitionerType_ ==
"linear") {
648 IFPACK2_BLOCKHELPER_TIMER(
"Ifpack2::BlockRelaxation::initialize::linear", linear);
651 IFPACK2_BLOCKHELPER_TIMER_DEFAULT_FENCE();
652 }
else if (PartitionerType_ ==
"line") {
653 IFPACK2_BLOCKHELPER_TIMER(
"Ifpack2::BlockRelaxation::initialize::line", line);
656 IFPACK2_BLOCKHELPER_TIMER_DEFAULT_FENCE();
657 }
else if (PartitionerType_ ==
"user") {
658 IFPACK2_BLOCKHELPER_TIMER(
"Ifpack2::BlockRelaxation::initialize::user", user);
661 IFPACK2_BLOCKHELPER_TIMER_DEFAULT_FENCE();
662 }
else if (PartitionerType_ ==
"zoltan2") {
663 IFPACK2_BLOCKHELPER_TIMER(
"Ifpack2::BlockRelaxation::initialize::zoltan2", zoltan2);
664 #if defined(HAVE_IFPACK2_ZOLTAN2)
665 if (graph->getComm ()->getSize () == 1) {
668 rcp (
new Ifpack2::Zoltan2Partitioner<row_graph_type> (graph) );
673 rcp (
new Ifpack2::Zoltan2Partitioner<row_graph_type> (A_local->getGraph ()) );
677 (
true, std::logic_error,
"Ifpack2::BlockRelaxation::initialize: Zoltan2 not enabled.");
679 IFPACK2_BLOCKHELPER_TIMER_DEFAULT_FENCE();
684 (
true, std::logic_error,
"Ifpack2::BlockRelaxation::initialize: Unknown "
685 "partitioner type " << PartitionerType_ <<
". Valid values are "
686 "\"linear\", \"line\", and \"user\".");
691 IFPACK2_BLOCKHELPER_TIMER(
"Ifpack2::BlockRelaxation::initialize::Partitioner",
Partitioner);
692 Partitioner_->setParameters (List_);
693 Partitioner_->compute ();
694 IFPACK2_BLOCKHELPER_TIMER_DEFAULT_FENCE();
698 NumLocalBlocks_ = Partitioner_->numLocalParts ();
703 if (A_->getComm()->getSize() != 1) {
712 (NumSweeps_ < 0, std::logic_error,
"Ifpack2::BlockRelaxation::initialize: "
713 "NumSweeps_ = " << NumSweeps_ <<
" < 0.");
717 IFPACK2_BLOCKHELPER_TIMER(
"Ifpack2::BlockRelaxation::initialize::ExtractSubmatricesStructure", ExtractSubmatricesStructure);
718 ExtractSubmatricesStructure ();
719 IFPACK2_BLOCKHELPER_TIMER_DEFAULT_FENCE();
725 if (PrecType_ == Ifpack2::Details::JACOBI && OverlapLevel_ > 0) {
727 (hasBlockCrsMatrix_, std::runtime_error,
728 "Ifpack2::BlockRelaxation::initialize: "
729 "We do not support overlapped Jacobi yet for Tpetra::BlockCrsMatrix. Sorry!");
732 W_ =
rcp (
new vector_type (A_->getRowMap ()));
733 W_->putScalar (STS::zero ());
738 for (
size_t j = 0 ; j < Partitioner_->numRowsInPart(i) ; ++j) {
740 w_ptr[LID] += STS::one();
748 if (schwarzCombineMode_ ==
"ADD") {
749 IFPACK2_BLOCKHELPER_TIMER(
"Ifpack2::BlockRelaxation::initialize::ADD", ADD);
750 typedef Tpetra::MultiVector< typename MatrixType::scalar_type, typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type,typename MatrixType::node_type> scMV;
753 scMV nonOverLapW(theImport->getSourceMap(), 1,
false);
756 nonOverLapW.putScalar(STS::zero ());
757 for (
int ii = 0; ii < (int) theImport->getSourceMap()->getLocalNumElements(); ii++) nonOverLapWArray[ii] = w_ptr[ii];
758 nonOverLapWArray = Teuchos::null;
759 w_ptr = Teuchos::null;
760 nonOverLapW.doExport (*W_, *theImport, Tpetra::ADD);
761 W_->doImport( nonOverLapW, *theImport, Tpetra::INSERT);
763 IFPACK2_BLOCKHELPER_TIMER_DEFAULT_FENCE();
765 W_->reciprocal (*W_);
769 InitializeTime_ += (timer->wallTime() - startTime);
771 IsInitialized_ =
true;
775 template<
class MatrixType,
class ContainerType>
783 (A_.
is_null (), std::runtime_error,
"Ifpack2::BlockRelaxation::compute: "
784 "The matrix is null. You must call setMatrix() with a nonnull matrix, "
785 "then call initialize(), before you may call this method.");
787 if (! isInitialized ()) {
794 double startTime = timer->
wallTime();
802 Container_->compute();
805 ComputeTime_ += (timer->
wallTime() - startTime);
810 template<
class MatrixType,
class ContainerType>
816 (Partitioner_.is_null (), std::runtime_error,
"Ifpack2::BlockRelaxation::"
817 "ExtractSubmatricesStructure: Partitioner object is null.");
819 std::string containerType = ContainerType::getName ();
820 if (containerType ==
"Generic") {
824 containerType = containerType_;
828 bool pointIndexed = decouple_ && hasBlockCrsMatrix_;
833 auto A_bcrs = Teuchos::rcp_dynamic_cast<
const block_crs_matrix_type>(A_);
834 local_ordinal_type dofs = hasBlockCrsMatrix_ ?
835 A_bcrs->getBlockSize() : List_.get<
int>(
"partitioner: PDE equations");
836 blockRows.
resize(NumLocalBlocks_ * dofs);
837 if(hasBlockCrsMatrix_)
839 for(local_ordinal_type i = 0; i < NumLocalBlocks_; i++)
841 size_t blockSize = Partitioner_->numRowsInPart(i);
844 for(local_ordinal_type j = 0; j < dofs; j++)
846 local_ordinal_type blockIndex = i * dofs + j;
847 blockRows[blockIndex].
resize(blockSize);
848 for(
size_t k = 0; k < blockSize; k++)
852 blockRows[blockIndex][k] = (*Partitioner_)(i, k) * dofs + j;
861 for(local_ordinal_type i = 0; i < NumLocalBlocks_; i++)
865 "Expected size of all blocks (partitions) to be divisible by MueLu dofs/node.");
866 size_t blockSize = Partitioner_->numRowsInPart(i) / dofs;
870 for(local_ordinal_type j = 0; j < dofs; j++)
872 local_ordinal_type blockIndex = i * dofs + j;
873 blockRows[blockIndex].
resize(blockSize);
874 for(
size_t k = 0; k < blockSize; k++)
876 blockRows[blockIndex][k] = (*Partitioner_)(i, k * dofs + j);
885 blockRows.
resize(NumLocalBlocks_);
886 for(local_ordinal_type i = 0; i < NumLocalBlocks_; ++i)
888 const size_t numRows = Partitioner_->numRowsInPart (i);
889 blockRows[i].
resize(numRows);
891 for (
size_t j = 0; j < numRows; ++j)
893 blockRows[i][j] = (*Partitioner_) (i,j);
899 Container_->setParameters(List_);
900 Container_->initialize();
903 template<
class MatrixType,
class ContainerType>
905 BlockRelaxation<MatrixType,ContainerType>::
906 ApplyInverseJacobi (
const MV& X, MV& Y)
const
908 const size_t NumVectors = X.getNumVectors ();
910 MV AY (Y.getMap (), NumVectors);
913 int starting_iteration = 0;
914 if (OverlapLevel_ > 0)
917 auto WView = W_->getLocalViewHost (Tpetra::Access::ReadOnly);
918 if(ZeroStartingSolution_) {
919 auto XView = X.getLocalViewHost (Tpetra::Access::ReadOnly);
920 auto YView = Y.getLocalViewHost (Tpetra::Access::ReadWrite);
921 Container_->DoOverlappingJacobi(XView, YView, WView, DampingFactor_, nonsymCombine_);
922 starting_iteration = 1;
924 const scalar_type ONE = STS::one();
925 for(
int j = starting_iteration; j < NumSweeps_; j++)
928 AY.update (ONE, X, -ONE);
930 auto AYView = AY.getLocalViewHost (Tpetra::Access::ReadOnly);
931 auto YView = Y.getLocalViewHost (Tpetra::Access::ReadWrite);
932 Container_->DoOverlappingJacobi (AYView, YView, WView, DampingFactor_, nonsymCombine_);
939 if(ZeroStartingSolution_)
941 auto XView = X.getLocalViewHost (Tpetra::Access::ReadOnly);
942 auto YView = Y.getLocalViewHost (Tpetra::Access::ReadWrite);
943 Container_->DoJacobi (XView, YView, DampingFactor_);
944 starting_iteration = 1;
946 const scalar_type ONE = STS::one();
947 for(
int j = starting_iteration; j < NumSweeps_; j++)
950 AY.update (ONE, X, -ONE);
952 auto AYView = AY.getLocalViewHost (Tpetra::Access::ReadOnly);
953 auto YView = Y.getLocalViewHost (Tpetra::Access::ReadWrite);
954 Container_->DoJacobi (AYView, YView, DampingFactor_);
960 template<
class MatrixType,
class ContainerType>
962 BlockRelaxation<MatrixType,ContainerType>::
963 ApplyInverseGS (
const MV& X, MV& Y)
const
967 size_t numVecs = X.getNumVectors();
969 auto XView = X.getLocalViewHost (Tpetra::Access::ReadOnly);
970 auto YView = Y.getLocalViewHost (Tpetra::Access::ReadWrite);
973 bool deleteY2 =
false;
976 Y2 = ptr(
new MV(Importer_->getTargetMap(), numVecs));
983 for(
int j = 0; j < NumSweeps_; ++j)
986 Y2->doImport(Y, *Importer_, Tpetra::INSERT);
987 auto Y2View = Y2->getLocalViewHost (Tpetra::Access::ReadWrite);
988 Container_->DoGaussSeidel(XView, YView, Y2View, DampingFactor_);
993 auto Y2View = Y2->getLocalViewHost (Tpetra::Access::ReadWrite);
994 for(
int j = 0; j < NumSweeps_; ++j)
996 Container_->DoGaussSeidel(XView, YView, Y2View, DampingFactor_);
1003 template<
class MatrixType,
class ContainerType>
1005 BlockRelaxation<MatrixType,ContainerType>::
1006 ApplyInverseSGS (
const MV& X, MV& Y)
const
1011 auto XView = X.getLocalViewHost (Tpetra::Access::ReadOnly);
1012 auto YView = Y.getLocalViewHost (Tpetra::Access::ReadWrite);
1015 bool deleteY2 =
false;
1018 Y2 = ptr(
new MV(Importer_->getTargetMap(), X.getNumVectors()));
1025 for(
int j = 0; j < NumSweeps_; ++j)
1028 Y2->doImport(Y, *Importer_, Tpetra::INSERT);
1029 auto Y2View = Y2->getLocalViewHost (Tpetra::Access::ReadWrite);
1030 Container_->DoSGS(XView, YView, Y2View, DampingFactor_);
1035 auto Y2View = Y2->getLocalViewHost (Tpetra::Access::ReadWrite);
1036 for(
int j = 0; j < NumSweeps_; ++j)
1038 Container_->DoSGS(XView, YView, Y2View, DampingFactor_);
1045 template<
class MatrixType,
class ContainerType>
1046 void BlockRelaxation<MatrixType,ContainerType>::computeImporter ()
const
1054 using Teuchos::rcp_dynamic_cast;
1057 if(hasBlockCrsMatrix_)
1059 const RCP<const block_crs_matrix_type> bcrs =
1060 rcp_dynamic_cast<
const block_crs_matrix_type>(A_);
1061 int bs_ = bcrs->getBlockSize();
1062 RCP<const map_type> oldDomainMap = A_->getDomainMap();
1063 RCP<const map_type> oldColMap = A_->getColMap();
1066 global_size_t numGlobalElements = oldColMap->getGlobalNumElements() * bs_;
1067 global_ordinal_type indexBase = oldColMap->getIndexBase();
1068 RCP<const Comm<int>> comm = oldColMap->getComm();
1069 ArrayView<const global_ordinal_type> oldColElements = oldColMap->getLocalElementList();
1070 Array<global_ordinal_type> newColElements(bs_ * oldColElements.size());
1071 for(
int i = 0; i < oldColElements.size(); i++)
1073 for(
int j = 0; j < bs_; j++)
1074 newColElements[i * bs_ + j] = oldColElements[i] * bs_ + j;
1076 RCP<map_type> colMap(
new map_type(numGlobalElements, newColElements, indexBase, comm));
1078 Importer_ =
rcp(
new import_type(oldDomainMap, colMap));
1082 Importer_ = A_->getGraph()->getImporter();
1083 if(Importer_.is_null())
1084 Importer_ =
rcp(
new import_type(A_->getDomainMap(), A_->getColMap()));
1090 template<
class MatrixType,
class ContainerType>
1095 std::ostringstream out;
1100 out <<
"\"Ifpack2::BlockRelaxation\": {";
1101 if (this->getObjectLabel () !=
"") {
1102 out <<
"Label: \"" << this->getObjectLabel () <<
"\", ";
1107 out <<
"Matrix: null, ";
1112 out <<
"Global matrix dimensions: ["
1113 << A_->getGlobalNumRows () <<
", " << A_->getGlobalNumCols () <<
"], ";
1118 out <<
"\"relaxation: type\": ";
1119 if (PrecType_ == Ifpack2::Details::JACOBI) {
1120 out <<
"Block Jacobi";
1121 }
else if (PrecType_ == Ifpack2::Details::GS) {
1122 out <<
"Block Gauss-Seidel";
1123 }
else if (PrecType_ == Ifpack2::Details::SGS) {
1124 out <<
"Block Symmetric Gauss-Seidel";
1125 }
else if (PrecType_ == Ifpack2::Details::MTSPLITJACOBI) {
1126 out <<
"MT Split Jacobi";
1132 if(hasBlockCrsMatrix_)
1136 int approx_rows_per_part = A_->getLocalNumRows()/Partitioner_->numLocalParts();
1137 out <<
", blocksize: "<<approx_rows_per_part;
1139 out <<
", overlap: " << OverlapLevel_;
1141 out <<
", " <<
"sweeps: " << NumSweeps_ <<
", "
1142 <<
"damping factor: " << DampingFactor_ <<
", ";
1144 std::string containerType = ContainerType::getName();
1145 out <<
"block container: " << ((containerType ==
"Generic") ? containerType_ : containerType);
1146 if(List_.isParameter(
"partitioner: PDE equations"))
1147 out <<
", dofs/node: "<<List_.get<
int>(
"partitioner: PDE equations");
1154 template<
class MatrixType,
class ContainerType>
1172 const int myImageID = A_->getComm()->getRank();
1182 if (vl !=
VERB_NONE && myImageID == 0) {
1183 out <<
"Ifpack2::BlockRelaxation<"
1184 << TypeNameTraits<MatrixType>::name () <<
", "
1185 << TypeNameTraits<ContainerType>::name () <<
" >:";
1188 if (this->getObjectLabel () !=
"") {
1189 out <<
"label: \"" << this->getObjectLabel () <<
"\"" << endl;
1191 out <<
"initialized: " << (isInitialized () ?
"true" :
"false") << endl
1192 <<
"computed: " << (isComputed () ?
"true" :
"false") << endl;
1194 std::string precType;
1195 if (PrecType_ == Ifpack2::Details::JACOBI) {
1196 precType =
"Block Jacobi";
1197 }
else if (PrecType_ == Ifpack2::Details::GS) {
1198 precType =
"Block Gauss-Seidel";
1199 }
else if (PrecType_ == Ifpack2::Details::SGS) {
1200 precType =
"Block Symmetric Gauss-Seidel";
1202 out <<
"type: " << precType << endl
1203 <<
"global number of rows: " << A_->getGlobalNumRows () << endl
1204 <<
"global number of columns: " << A_->getGlobalNumCols () << endl
1205 <<
"number of sweeps: " << NumSweeps_ << endl
1206 <<
"damping factor: " << DampingFactor_ << endl
1207 <<
"nonsymmetric overlap combine" << nonsymCombine_ << endl
1208 <<
"backwards mode: "
1209 << ((PrecType_ == Ifpack2::Details::GS && DoBackwardGS_) ?
"true" :
"false")
1211 <<
"zero starting solution: "
1212 << (ZeroStartingSolution_ ?
"true" :
"false") << endl;
1230 #ifdef HAVE_IFPACK2_EXPLICIT_INSTANTIATION
1232 #define IFPACK2_BLOCKRELAXATION_INSTANT(S,LO,GO,N) \
1234 class Ifpack2::BlockRelaxation< \
1235 Tpetra::RowMatrix<S, LO, GO, N>, \
1236 Ifpack2::Container<Tpetra::RowMatrix<S, LO, GO, N> > >;
1238 #endif // HAVE_IFPACK2_EXPLICIT_INSTANTIATION
1240 #endif // IFPACK2_BLOCKRELAXATION_DEF_HPP
Ifpack2::BlockRelaxation class declaration.
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
The communicator over which the input matrix is distributed.
Definition: Ifpack2_BlockRelaxation_def.hpp:346
ParameterList & disableRecursiveValidation()
std::string description() const
A one-line description of this object.
Definition: Ifpack2_BlockRelaxation_def.hpp:1093
double getApplyTime() const
Returns the time spent in apply().
Definition: Ifpack2_BlockRelaxation_def.hpp:441
T & get(const std::string &name, T def_value)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
int getNumApply() const
Returns the number of calls to apply().
Definition: Ifpack2_BlockRelaxation_def.hpp:417
void getParameter(const Teuchos::ParameterList ¶ms, const std::string &name, T &value)
Set a value from a ParameterList if a parameter with the specified name exists.
Definition: Ifpack2_Parameters.hpp:26
Teuchos::RCP< const map_type > getRangeMap() const
Returns the Tpetra::Map object associated with the range of this operator.
Definition: Ifpack2_BlockRelaxation_def.hpp:383
int getNumCompute() const
Returns the number of calls to compute().
Definition: Ifpack2_BlockRelaxation_def.hpp:409
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
void setParameters(const Teuchos::ParameterList ¶ms)
Sets all the parameters for the preconditioner.
Definition: Ifpack2_BlockRelaxation_def.hpp:161
void compute()
compute the preconditioner for the specified matrix, diagonal perturbation thresholds and relaxation ...
Definition: Ifpack2_BlockRelaxation_def.hpp:778
Block relaxation preconditioners (or smoothers) for Tpetra::RowMatrix and Tpetra::CrsMatrix sparse ma...
Definition: Ifpack2_BlockRelaxation_decl.hpp:49
double getInitializeTime() const
Returns the time spent in initialize().
Definition: Ifpack2_BlockRelaxation_def.hpp:425
Declaration of a user-defined partitioner in which the user can define a partition of the graph...
Ifpack2::Partitioner:
Definition: Ifpack2_Partitioner.hpp:146
bool isParameter(const std::string &name) const
bool remove(std::string const &name, bool throwIfNotExists=true)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
#define TEUCHOS_TEST_FOR_EXCEPT_MSG(throw_exception_test, msg)
double getComputeTime() const
Returns the time spent in compute().
Definition: Ifpack2_BlockRelaxation_def.hpp:433
size_t getNodeSmootherComplexity() const
Get a rough estimate of cost per iteration.
Definition: Ifpack2_BlockRelaxation_def.hpp:448
virtual void setMatrix(const Teuchos::RCP< const row_matrix_type > &A)
Change the matrix to be preconditioned.
Definition: Ifpack2_BlockRelaxation_def.hpp:31
virtual ~BlockRelaxation()
Destructor.
Definition: Ifpack2_BlockRelaxation_def.hpp:94
Teuchos::RCP< const map_type > getDomainMap() const
Returns the Tpetra::Map object associated with the domain of this operator.
Definition: Ifpack2_BlockRelaxation_def.hpp:369
Partition in which the user can define a nonoverlapping partition of the graph in any way they choose...
Definition: Ifpack2_Details_UserPartitioner_decl.hpp:36
void resize(size_type new_size, const value_type &x=value_type())
int getNumInitialize() const
Returns the number of calls to initialize().
Definition: Ifpack2_BlockRelaxation_def.hpp:402
void initialize()
Initialize.
Definition: Ifpack2_BlockRelaxation_def.hpp:584
void validateParameters(ParameterList const &validParamList, int const depth=1000, EValidateUsed const validateUsed=VALIDATE_USED_ENABLED, EValidateDefaults const validateDefaults=VALIDATE_DEFAULTS_ENABLED) const
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Print the object with some verbosity level to an FancyOStream object.
Definition: Ifpack2_BlockRelaxation_def.hpp:1157
MatrixType::local_ordinal_type local_ordinal_type
The type of local indices in the input MatrixType.
Definition: Ifpack2_BlockRelaxation_decl.hpp:67
void applyMat(const MV &X, MV &Y, Teuchos::ETransp mode=Teuchos::NO_TRANS) const
Applies the matrix to a Tpetra::MultiVector.
Definition: Ifpack2_BlockRelaxation_def.hpp:568
MatrixType::scalar_type scalar_type
The type of the entries of the input MatrixType.
Definition: Ifpack2_BlockRelaxation_decl.hpp:64
bool isType(const std::string &name) const
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
Access only local rows and columns of a sparse matrix.
Definition: Ifpack2_LocalFilter_decl.hpp:128
static Teuchos::RCP< BaseContainer > build(std::string containerType, const Teuchos::RCP< const MatrixType > &A, const Teuchos::Array< Teuchos::Array< local_ordinal_type >> &partitions, const Teuchos::RCP< const import_type > importer, bool pointIndexed)
Build a specialization of Ifpack2::Container given a key that has been registered.
Definition: Ifpack2_ContainerFactory_def.hpp:56
Teuchos::RCP< const row_matrix_type > getMatrix() const
The input matrix of this preconditioner's constructor.
Definition: Ifpack2_BlockRelaxation_def.hpp:360
void getValidParameters(Teuchos::ParameterList ¶ms)
Fills a list which contains all the parameters possibly used by Ifpack2.
Definition: Ifpack2_Parameters.cpp:18
Ifpack2::LinePartitioner: A class to define partitions into a set of lines.
Definition: Ifpack2_LinePartitioner_decl.hpp:45
A class to define linear partitions.
Definition: Ifpack2_LinearPartitioner_decl.hpp:27
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Return a list of all the parameters that this class accepts.
Definition: Ifpack2_BlockRelaxation_def.hpp:100
void apply(const MV &X, MV &Y, Teuchos::ETransp mode=Teuchos::NO_TRANS, scalar_type alpha=Teuchos::ScalarTraits< scalar_type >::one(), scalar_type beta=Teuchos::ScalarTraits< scalar_type >::zero()) const
Applies the preconditioner to X, returns the result in Y.
Definition: Ifpack2_BlockRelaxation_def.hpp:465
BlockRelaxation(const Teuchos::RCP< const row_matrix_type > &Matrix)
Constructor.
Definition: Ifpack2_BlockRelaxation_def.hpp:59