10 #ifndef IFPACK2_HIPTMAIR_DEF_HPP
11 #define IFPACK2_HIPTMAIR_DEF_HPP
13 #include "Ifpack2_Details_OneLevelFactory.hpp"
14 #include "Ifpack2_Parameters.hpp"
16 #include "Tpetra_MultiVector.hpp"
17 #include "Tpetra_Details_residual.hpp"
18 #include <Tpetra_RowMatrixTransposer.hpp>
25 template <
class MatrixType>
36 precType1_ (
"CHEBYSHEV"),
37 precType2_ (
"CHEBYSHEV"),
39 ZeroStartingSolution_ (true),
40 ImplicitTranspose_ (Pt.
is_null()),
42 IsInitialized_ (false),
47 InitializeTime_ (0.0),
55 template <
class MatrixType>
63 precType1_ (
"CHEBYSHEV"),
64 precType2_ (
"CHEBYSHEV"),
66 ZeroStartingSolution_ (true),
67 ImplicitTranspose_ (true),
69 IsInitialized_ (false),
74 InitializeTime_ (0.0),
80 template <
class MatrixType>
83 template <
class MatrixType>
92 ParameterList params = plist;
99 std::string precType1 = precType1_;
100 std::string precType2 = precType2_;
101 std::string preOrPost = preOrPost_;
104 bool zeroStartingSolution = ZeroStartingSolution_;
105 bool implicitTranspose = ImplicitTranspose_;
107 precType1 = params.
get(
"hiptmair: smoother type 1", precType1);
108 precType2 = params.get(
"hiptmair: smoother type 2", precType2);
109 precList1 = params.
get(
"hiptmair: smoother list 1", precList1);
110 precList2 = params.
get(
"hiptmair: smoother list 2", precList2);
111 preOrPost = params.get(
"hiptmair: pre or post", preOrPost);
112 zeroStartingSolution = params.get(
"hiptmair: zero starting solution",
113 zeroStartingSolution);
114 implicitTranspose = params.get(
"hiptmair: implicit transpose", implicitTranspose);
119 PtAP_ = params.get<RCP<row_matrix_type> >(
"PtAP");
121 P_ = params.get<RCP<row_matrix_type> >(
"P");
122 if (params.isType<RCP<row_matrix_type> >(
"Pt"))
123 Pt_ = params.get<RCP<row_matrix_type> >(
"Pt");
127 precType1_ = precType1;
128 precType2_ = precType2;
129 precList1_ = precList1;
130 precList2_ = precList2;
131 preOrPost_ = preOrPost;
132 ZeroStartingSolution_ = zeroStartingSolution;
133 ImplicitTranspose_ = implicitTranspose;
137 template <
class MatrixType>
141 A_.
is_null (), std::runtime_error,
"Ifpack2::Hiptmair::getComm: "
142 "The input matrix A is null. Please call setMatrix() with a nonnull "
143 "input matrix before calling this method.");
144 return A_->getComm ();
148 template <
class MatrixType>
155 template <
class MatrixType>
160 A_.
is_null (), std::runtime_error,
"Ifpack2::Hiptmair::getDomainMap: "
161 "The input matrix A is null. Please call setMatrix() with a nonnull "
162 "input matrix before calling this method.");
163 return A_->getDomainMap ();
167 template <
class MatrixType>
172 A_.
is_null (), std::runtime_error,
"Ifpack2::Hiptmair::getRangeMap: "
173 "The input matrix A is null. Please call setMatrix() with a nonnull "
174 "input matrix before calling this method.");
175 return A_->getRangeMap ();
179 template <
class MatrixType>
187 template <
class MatrixType>
189 return NumInitialize_;
193 template <
class MatrixType>
199 template <
class MatrixType>
205 template <
class MatrixType>
207 return InitializeTime_;
211 template <
class MatrixType>
217 template <
class MatrixType>
223 template <
class MatrixType>
225 return ifpack2_prec1_;
229 template <
class MatrixType>
231 return ifpack2_prec2_;
235 template <
class MatrixType>
242 const char methodName[] =
"Ifpack2::Hiptmair::initialize";
245 A_.
is_null (), std::runtime_error,
"Ifpack2::Hiptmair::initialize: "
246 "The input matrix A is null. Please call setMatrix() with a nonnull "
247 "input matrix before calling this method.");
250 IsInitialized_ =
false;
256 double startTime = timer->
wallTime();
263 ifpack2_prec1_=factory.
create(precType1_,A_);
264 ifpack2_prec1_->initialize();
265 ifpack2_prec1_->setParameters(precList1_);
267 ifpack2_prec2_=factory.
create(precType2_,PtAP_);
268 ifpack2_prec2_->initialize();
269 ifpack2_prec2_->setParameters(precList2_);
272 IsInitialized_ =
true;
274 InitializeTime_ += (timer->
wallTime() - startTime);
278 template <
class MatrixType>
281 const char methodName[] =
"Ifpack2::Hiptmair::initialize";
284 A_.
is_null (), std::runtime_error,
"Ifpack2::Hiptmair::compute: "
285 "The input matrix A is null. Please call setMatrix() with a nonnull "
286 "input matrix before calling this method.");
289 if (! isInitialized ()) {
296 double startTime = timer->
wallTime();
299 ifpack2_prec1_->compute();
300 ifpack2_prec2_->compute();
302 if (!ImplicitTranspose_ && Pt_.is_null()) {
303 using crs_type = Tpetra::CrsMatrix<typename MatrixType::scalar_type,typename MatrixType::local_ordinal_type,typename MatrixType::global_ordinal_type,typename MatrixType::node_type>;
306 using transposer_type = Tpetra::RowMatrixTransposer<typename MatrixType::scalar_type,typename MatrixType::local_ordinal_type,typename MatrixType::global_ordinal_type,typename MatrixType::node_type>;
307 Pt_ = transposer_type(crsP).createTranspose();
310 "ImplicitTranspose == false, but no Pt was provided and transposing P was not possible.");
316 ComputeTime_ += (timer->
wallTime() - startTime);
320 template <
class MatrixType>
322 apply (
const Tpetra::MultiVector<
typename MatrixType::scalar_type,
323 typename MatrixType::local_ordinal_type,
324 typename MatrixType::global_ordinal_type,
325 typename MatrixType::node_type>& X,
326 Tpetra::MultiVector<
typename MatrixType::scalar_type,
327 typename MatrixType::local_ordinal_type,
328 typename MatrixType::global_ordinal_type,
329 typename MatrixType::node_type>& Y,
331 typename MatrixType::scalar_type alpha,
332 typename MatrixType::scalar_type beta)
const
336 using Teuchos::rcpFromRef;
340 ! isComputed (), std::runtime_error,
341 "Ifpack2::Hiptmair::apply: You must call compute() before you may call apply().");
343 X.getNumVectors () != Y.getNumVectors (), std::invalid_argument,
344 "Ifpack2::Hiptmair::apply: The MultiVector inputs X and Y do not have the "
345 "same number of columns. X.getNumVectors() = " << X.getNumVectors ()
346 <<
" != Y.getNumVectors() = " << Y.getNumVectors () <<
".");
350 alpha != STS::one (), std::logic_error,
351 "Ifpack2::Hiptmair::apply: alpha != 1 has not been implemented.");
352 TEUCHOS_TEST_FOR_EXCEPTION(
353 beta != STS::zero (), std::logic_error,
354 "Ifpack2::Hiptmair::apply: zero != 0 has not been implemented.");
355 TEUCHOS_TEST_FOR_EXCEPTION(
357 "Ifpack2::Hiptmair::apply: mode != Teuchos::NO_TRANS has not been implemented.");
359 const std::string timerName (
"Ifpack2::Hiptmair::apply");
364 double startTime = timer->
wallTime();
375 Xcopy = rcpFromRef (X);
379 RCP<MV> Ycopy = rcpFromRef (Y);
380 if (ZeroStartingSolution_) {
381 Ycopy->putScalar (STS::zero ());
385 applyHiptmairSmoother (*Xcopy, *Ycopy);
389 ApplyTime_ += (timer->
wallTime() - startTime);
393 template<
class MatrixType>
397 const Teuchos::RCP<
const Tpetra::Map<local_ordinal_type, global_ordinal_type, node_type>>& map2,
398 size_t numVecs)
const
404 if (cachedResidual1_.is_null () ||
405 map1.get () != cachedResidual1_->getMap ().get () ||
406 cachedResidual1_->getNumVectors () != numVecs) {
408 cachedResidual1_ =
Teuchos::rcp (
new MV (map1, numVecs,
false));
409 cachedSolution1_ =
Teuchos::rcp (
new MV (map1, numVecs,
false));
411 if (cachedResidual2_.is_null () ||
412 map2.get () != cachedResidual2_->getMap ().get () ||
413 cachedResidual2_->getNumVectors () != numVecs) {
415 cachedResidual2_ =
Teuchos::rcp (
new MV (map2, numVecs,
false));
416 cachedSolution2_ =
Teuchos::rcp (
new MV (map2, numVecs,
false));
421 template <
class MatrixType>
424 typename MatrixType::local_ordinal_type,
425 typename MatrixType::global_ordinal_type,
426 typename MatrixType::node_type>& X,
427 Tpetra::MultiVector<
typename MatrixType::scalar_type,
428 typename MatrixType::local_ordinal_type,
429 typename MatrixType::global_ordinal_type,
430 typename MatrixType::node_type>& Y)
const
432 const scalar_type ZERO = STS::zero ();
433 const scalar_type ONE = STS::one ();
435 const std::string timerName1 (
"Ifpack2::Hiptmair::apply 1");
436 const std::string timerName2 (
"Ifpack2::Hiptmair::apply 2");
448 #ifdef IFPACK2_DEBUG_SMOOTHER
449 int mypid = X.getMap()->getComm()->getRank();
451 printf(
"\n--------------------------------\n");
452 printf(
"Coming into matrix Hiptmair\n");
454 if (!mypid) printf(
"\t||x|| = %15.10e\n", ttt[0]);
456 if (!mypid) printf(
"\t||rhs|| = %15.10e\n", ttt[0]);
458 double normA = A_->getFrobeniusNorm();
459 if (!mypid) printf(
"\t||A|| = %15.10e\n", normA);
460 Tpetra::Vector<
typename MatrixType::scalar_type,
461 typename MatrixType::local_ordinal_type,
462 typename MatrixType::global_ordinal_type,
463 typename MatrixType::node_type> d(A_->getRowMap());
464 A_->getLocalDiagCopy(d);
466 if (!mypid) printf(
"\t||diag(A)|| = %15.10e\n", ttt[0]);
472 updateCachedMultiVectors (A_->getRowMap (),
476 if (preOrPost_ ==
"pre" || preOrPost_ ==
"both") {
479 Tpetra::Details::residual(*A_,Y,X,*cachedResidual1_);
480 cachedSolution1_->putScalar (ZERO);
481 ifpack2_prec1_->apply (*cachedResidual1_, *cachedSolution1_);
482 Y.update (ONE, *cachedSolution1_, ONE);
490 Tpetra::Details::residual(*A_,Y,X,*cachedResidual1_);
491 #ifdef IFPACK2_DEBUG_SMOOTHER
492 if (!mypid) printf(
" After smoothing on edges\n");
494 if (!mypid) printf(
"\t||x|| = %15.10e\n", ttt[0]);
495 cachedResidual1_->norm2(ttt());
496 if (!mypid) printf(
"\t||res|| = %15.10e\n", ttt[0]);
505 cachedSolution2_->putScalar (ZERO);
507 #ifdef IFPACK2_DEBUG_SMOOTHER
508 if (!mypid)printf(
" Before smoothing on nodes\n");
509 cachedSolution2_->norm2(ttt());
510 if (!mypid)printf(
"\t||x_nodal|| = %15.10e\n",ttt[0]);
511 cachedResidual2_->norm2(ttt());
512 if (!mypid)printf(
"\t||rhs_nodal|| = %15.10e\n", ttt[0]);
514 auto An = ifpack2_prec2_->getMatrix();
515 double normA = An->getFrobeniusNorm();
516 if (!mypid) printf(
"\t||An|| = %15.10e\n", normA);
517 Tpetra::Vector<
typename MatrixType::scalar_type,
518 typename MatrixType::local_ordinal_type,
519 typename MatrixType::global_ordinal_type,
520 typename MatrixType::node_type> d(An->getRowMap());
521 An->getLocalDiagCopy(d);
523 if (!mypid) printf(
"\t||diag(An)|| = %15.10e\n", ttt[0]);
528 ifpack2_prec2_->apply (*cachedResidual2_, *cachedSolution2_);
530 #ifdef IFPACK2_DEBUG_SMOOTHER
531 if (!mypid)printf(
" After smoothing on nodes\n");
532 cachedSolution2_->norm2(ttt());
533 if (!mypid)printf(
"\t||x_nodal|| = %15.10e\n",ttt[0]);
534 cachedResidual2_->norm2(ttt());
535 if (!mypid)printf(
"\t||rhs_nodal|| = %15.10e\n", ttt[0]);
542 if (preOrPost_ ==
"post" || preOrPost_ ==
"both") {
545 Tpetra::Details::residual(*A_,Y,X,*cachedResidual1_);
546 cachedSolution1_->putScalar (ZERO);
547 ifpack2_prec1_->apply (*cachedResidual1_, *cachedSolution1_);
548 Y.update (ONE, *cachedSolution1_, ONE);
551 #ifdef IFPACK2_DEBUG_SMOOTHER
552 if (!mypid)printf(
" After updating edge solution\n");
554 if (!mypid)printf(
"\t||x|| = %15.10e\n",ttt[0]);
555 if (!mypid)printf(
"--------------------------------\n");
561 template <
class MatrixType>
564 std::ostringstream os;
569 os <<
"\"Ifpack2::Hiptmair\": {";
570 if (this->getObjectLabel () !=
"") {
571 os <<
"Label: \"" << this->getObjectLabel () <<
"\", ";
573 os <<
"Initialized: " << (isInitialized () ?
"true" :
"false") <<
", "
574 <<
"Computed: " << (isComputed () ?
"true" :
"false") <<
", ";
577 os <<
"Matrix: null, ";
580 os <<
"Matrix: not null"
581 <<
", Global matrix dimensions: ["
582 << A_->getGlobalNumRows () <<
", " << A_->getGlobalNumCols () <<
"], ";
585 os <<
"Smoother 1: ";
586 os << ifpack2_prec1_->description() <<
", ";
587 os <<
"Smoother 2: ";
588 os << ifpack2_prec2_->description();
595 template <
class MatrixType>
615 out <<
"\"Ifpack2::Hiptmair\":";
618 if (this->getObjectLabel () !=
"") {
619 out <<
"Label: " << this->getObjectLabel () << endl;
621 out <<
"Initialized: " << (isInitialized () ?
"true" :
"false") << endl
622 <<
"Computed: " << (isComputed () ?
"true" :
"false") << endl
623 <<
"Global number of rows: " << A_->getGlobalNumRows () << endl
624 <<
"Global number of columns: " << A_->getGlobalNumCols () << endl
627 out <<
" null" << endl;
629 A_->describe (out, vl);
631 out <<
"Smoother 1: ";
632 ifpack2_prec1_->describe(out, vl);
633 out <<
"Smoother 2: ";
634 ifpack2_prec2_->describe(out, vl);
640 #define IFPACK2_HIPTMAIR_INSTANT(S,LO,GO,N) \
641 template class Ifpack2::Hiptmair< Tpetra::RowMatrix<S, LO, GO, N> >;
void initialize()
Do any initialization that depends on the input matrix's structure.
Definition: Ifpack2_Hiptmair_def.hpp:236
bool is_null(const boost::shared_ptr< T > &p)
Teuchos::RCP< prec_type > create(const std::string &precType, const Teuchos::RCP< const row_matrix_type > &matrix) const
Create an instance of Preconditioner given the string name of the preconditioner type.
Definition: Ifpack2_Details_OneLevelFactory_def.hpp:53
void updateCachedMultiVectors(const Teuchos::RCP< const Tpetra::Map< local_ordinal_type, global_ordinal_type, node_type > > &map1, const Teuchos::RCP< const Tpetra::Map< local_ordinal_type, global_ordinal_type, node_type >> &map2, size_t numVecs) const
A service routine for updating the cached MultiVectors.
Definition: Ifpack2_Hiptmair_def.hpp:396
T & get(const std::string &name, T def_value)
MatrixType::local_ordinal_type local_ordinal_type
The type of local indices in the input MatrixType.
Definition: Ifpack2_Hiptmair_decl.hpp:52
Hiptmair(const Teuchos::RCP< const row_matrix_type > &A)
Constructor that takes 1 Tpetra matrix (assumes we'll get the rest off the parameter list) ...
Definition: Ifpack2_Hiptmair_def.hpp:57
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
MatrixType::scalar_type scalar_type
The type of the entries of the input MatrixType.
Definition: Ifpack2_Hiptmair_decl.hpp:49
double getComputeTime() const
Returns the time spent in Compute().
Definition: Ifpack2_Hiptmair_def.hpp:212
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Returns the operator's communicator.
Definition: Ifpack2_Hiptmair_def.hpp:139
bool hasTransposeApply() const
Whether this object's apply() method can apply the transpose (or conjugate transpose, if applicable).
Definition: Ifpack2_Hiptmair_def.hpp:180
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_Hiptmair_def.hpp:597
double getApplyTime() const
Returns the time spent in apply().
Definition: Ifpack2_Hiptmair_def.hpp:218
Teuchos::RCP< Ifpack2::Preconditioner< typename MatrixType::scalar_type, typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type, typename MatrixType::node_type > > getPrec1()
Returns prec 1.
Definition: Ifpack2_Hiptmair_def.hpp:224
void setParameters(const Teuchos::ParameterList ¶ms)
Set the preconditioner's parameters.
Definition: Ifpack2_Hiptmair_def.hpp:84
Teuchos::RCP< const Tpetra::RowMatrix< scalar_type, local_ordinal_type, global_ordinal_type, node_type > > getMatrix() const
Returns a reference to the matrix to be preconditioned.
Definition: Ifpack2_Hiptmair_def.hpp:150
Teuchos::RCP< const Tpetra::Map< local_ordinal_type, global_ordinal_type, node_type > > getRangeMap() const
Tpetra::Map representing the range of this operator.
Definition: Ifpack2_Hiptmair_def.hpp:169
MatrixType::global_ordinal_type global_ordinal_type
The type of global indices in the input MatrixType.
Definition: Ifpack2_Hiptmair_decl.hpp:55
int getNumApply() const
Returns the number of calls to apply().
Definition: Ifpack2_Hiptmair_def.hpp:200
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Wrapper for Hiptmair smoothers.
Definition: Ifpack2_Hiptmair_decl.hpp:38
int getNumCompute() const
Returns the number of calls to Compute().
Definition: Ifpack2_Hiptmair_def.hpp:194
int getNumInitialize() const
Returns the number of calls to Initialize().
Definition: Ifpack2_Hiptmair_def.hpp:188
MatrixType::node_type node_type
The Node type used by the input MatrixType.
Definition: Ifpack2_Hiptmair_decl.hpp:58
void compute()
Do any initialization that depends on the input matrix's values.
Definition: Ifpack2_Hiptmair_def.hpp:279
virtual ~Hiptmair()
Destructor.
Definition: Ifpack2_Hiptmair_def.hpp:81
std::string description() const
Return a simple one-line description of this object.
Definition: Ifpack2_Hiptmair_def.hpp:562
Teuchos::RCP< const Tpetra::Map< local_ordinal_type, global_ordinal_type, node_type > > getDomainMap() const
Tpetra::Map representing the domain of this operator.
Definition: Ifpack2_Hiptmair_def.hpp:157
TypeTo as(const TypeFrom &t)
Teuchos::RCP< Ifpack2::Preconditioner< typename MatrixType::scalar_type, typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type, typename MatrixType::node_type > > getPrec2()
Returns prec 2.
Definition: Ifpack2_Hiptmair_def.hpp:230
double getInitializeTime() const
Returns the time spent in Initialize().
Definition: Ifpack2_Hiptmair_def.hpp:206
"Factory" for creating single-level preconditioners.
Definition: Ifpack2_Details_OneLevelFactory_decl.hpp:92
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, putting the result in Y.
Definition: Ifpack2_Hiptmair_def.hpp:322