43 #ifndef IFPACK2_HIPTMAIR_DEF_HPP
44 #define IFPACK2_HIPTMAIR_DEF_HPP
46 #include "Ifpack2_Details_OneLevelFactory.hpp"
47 #include "Ifpack2_Parameters.hpp"
49 #include "Tpetra_MultiVector.hpp"
50 #include "Tpetra_Details_residual.hpp"
51 #include <Tpetra_RowMatrixTransposer.hpp>
58 template <
class MatrixType>
69 precType1_ (
"CHEBYSHEV"),
70 precType2_ (
"CHEBYSHEV"),
72 ZeroStartingSolution_ (true),
73 ImplicitTranspose_ (Pt.
is_null()),
75 IsInitialized_ (false),
80 InitializeTime_ (0.0),
88 template <
class MatrixType>
96 precType1_ (
"CHEBYSHEV"),
97 precType2_ (
"CHEBYSHEV"),
99 ZeroStartingSolution_ (true),
100 ImplicitTranspose_ (true),
102 IsInitialized_ (false),
107 InitializeTime_ (0.0),
113 template <
class MatrixType>
116 template <
class MatrixType>
125 ParameterList params = plist;
132 std::string precType1 = precType1_;
133 std::string precType2 = precType2_;
134 std::string preOrPost = preOrPost_;
137 bool zeroStartingSolution = ZeroStartingSolution_;
138 bool implicitTranspose = ImplicitTranspose_;
140 precType1 = params.
get(
"hiptmair: smoother type 1", precType1);
141 precType2 = params.get(
"hiptmair: smoother type 2", precType2);
142 precList1 = params.
get(
"hiptmair: smoother list 1", precList1);
143 precList2 = params.
get(
"hiptmair: smoother list 2", precList2);
144 preOrPost = params.get(
"hiptmair: pre or post", preOrPost);
145 zeroStartingSolution = params.get(
"hiptmair: zero starting solution",
146 zeroStartingSolution);
147 implicitTranspose = params.get(
"hiptmair: implicit transpose", implicitTranspose);
152 PtAP_ = params.get<RCP<row_matrix_type> >(
"PtAP");
154 P_ = params.get<RCP<row_matrix_type> >(
"P");
155 if (params.isType<RCP<row_matrix_type> >(
"Pt"))
156 Pt_ = params.get<RCP<row_matrix_type> >(
"Pt");
160 precType1_ = precType1;
161 precType2_ = precType2;
162 precList1_ = precList1;
163 precList2_ = precList2;
164 preOrPost_ = preOrPost;
165 ZeroStartingSolution_ = zeroStartingSolution;
166 ImplicitTranspose_ = implicitTranspose;
170 template <
class MatrixType>
174 A_.
is_null (), std::runtime_error,
"Ifpack2::Hiptmair::getComm: "
175 "The input matrix A is null. Please call setMatrix() with a nonnull "
176 "input matrix before calling this method.");
177 return A_->getComm ();
181 template <
class MatrixType>
188 template <
class MatrixType>
193 A_.
is_null (), std::runtime_error,
"Ifpack2::Hiptmair::getDomainMap: "
194 "The input matrix A is null. Please call setMatrix() with a nonnull "
195 "input matrix before calling this method.");
196 return A_->getDomainMap ();
200 template <
class MatrixType>
205 A_.
is_null (), std::runtime_error,
"Ifpack2::Hiptmair::getRangeMap: "
206 "The input matrix A is null. Please call setMatrix() with a nonnull "
207 "input matrix before calling this method.");
208 return A_->getRangeMap ();
212 template <
class MatrixType>
220 template <
class MatrixType>
222 return NumInitialize_;
226 template <
class MatrixType>
232 template <
class MatrixType>
238 template <
class MatrixType>
240 return InitializeTime_;
244 template <
class MatrixType>
250 template <
class MatrixType>
256 template <
class MatrixType>
258 return ifpack2_prec1_;
262 template <
class MatrixType>
264 return ifpack2_prec2_;
268 template <
class MatrixType>
275 const char methodName[] =
"Ifpack2::Hiptmair::initialize";
278 A_.
is_null (), std::runtime_error,
"Ifpack2::Hiptmair::initialize: "
279 "The input matrix A is null. Please call setMatrix() with a nonnull "
280 "input matrix before calling this method.");
283 IsInitialized_ =
false;
289 double startTime = timer->
wallTime();
296 ifpack2_prec1_=factory.
create(precType1_,A_);
297 ifpack2_prec1_->initialize();
298 ifpack2_prec1_->setParameters(precList1_);
300 ifpack2_prec2_=factory.
create(precType2_,PtAP_);
301 ifpack2_prec2_->initialize();
302 ifpack2_prec2_->setParameters(precList2_);
305 IsInitialized_ =
true;
307 InitializeTime_ += (timer->
wallTime() - startTime);
311 template <
class MatrixType>
314 const char methodName[] =
"Ifpack2::Hiptmair::initialize";
317 A_.
is_null (), std::runtime_error,
"Ifpack2::Hiptmair::compute: "
318 "The input matrix A is null. Please call setMatrix() with a nonnull "
319 "input matrix before calling this method.");
322 if (! isInitialized ()) {
329 double startTime = timer->
wallTime();
332 ifpack2_prec1_->compute();
333 ifpack2_prec2_->compute();
335 if (!ImplicitTranspose_ && Pt_.is_null()) {
336 using crs_type = Tpetra::CrsMatrix<typename MatrixType::scalar_type,typename MatrixType::local_ordinal_type,typename MatrixType::global_ordinal_type,typename MatrixType::node_type>;
339 using transposer_type = Tpetra::RowMatrixTransposer<typename MatrixType::scalar_type,typename MatrixType::local_ordinal_type,typename MatrixType::global_ordinal_type,typename MatrixType::node_type>;
340 Pt_ = transposer_type(crsP).createTranspose();
343 "ImplicitTranspose == false, but no Pt was provided and transposing P was not possible.");
349 ComputeTime_ += (timer->
wallTime() - startTime);
353 template <
class MatrixType>
355 apply (
const Tpetra::MultiVector<
typename MatrixType::scalar_type,
356 typename MatrixType::local_ordinal_type,
357 typename MatrixType::global_ordinal_type,
358 typename MatrixType::node_type>& X,
359 Tpetra::MultiVector<
typename MatrixType::scalar_type,
360 typename MatrixType::local_ordinal_type,
361 typename MatrixType::global_ordinal_type,
362 typename MatrixType::node_type>& Y,
364 typename MatrixType::scalar_type alpha,
365 typename MatrixType::scalar_type beta)
const
369 using Teuchos::rcpFromRef;
373 ! isComputed (), std::runtime_error,
374 "Ifpack2::Hiptmair::apply: You must call compute() before you may call apply().");
376 X.getNumVectors () != Y.getNumVectors (), std::invalid_argument,
377 "Ifpack2::Hiptmair::apply: The MultiVector inputs X and Y do not have the "
378 "same number of columns. X.getNumVectors() = " << X.getNumVectors ()
379 <<
" != Y.getNumVectors() = " << Y.getNumVectors () <<
".");
383 alpha != STS::one (), std::logic_error,
384 "Ifpack2::Hiptmair::apply: alpha != 1 has not been implemented.");
385 TEUCHOS_TEST_FOR_EXCEPTION(
386 beta != STS::zero (), std::logic_error,
387 "Ifpack2::Hiptmair::apply: zero != 0 has not been implemented.");
388 TEUCHOS_TEST_FOR_EXCEPTION(
390 "Ifpack2::Hiptmair::apply: mode != Teuchos::NO_TRANS has not been implemented.");
392 const std::string timerName (
"Ifpack2::Hiptmair::apply");
397 double startTime = timer->
wallTime();
408 Xcopy = rcpFromRef (X);
412 RCP<MV> Ycopy = rcpFromRef (Y);
413 if (ZeroStartingSolution_) {
414 Ycopy->putScalar (STS::zero ());
418 applyHiptmairSmoother (*Xcopy, *Ycopy);
422 ApplyTime_ += (timer->
wallTime() - startTime);
426 template<
class MatrixType>
430 const Teuchos::RCP<
const Tpetra::Map<local_ordinal_type, global_ordinal_type, node_type>>& map2,
431 size_t numVecs)
const
437 if (cachedResidual1_.is_null () ||
438 map1.get () != cachedResidual1_->getMap ().get () ||
439 cachedResidual1_->getNumVectors () != numVecs) {
441 cachedResidual1_ =
Teuchos::rcp (
new MV (map1, numVecs,
false));
442 cachedSolution1_ =
Teuchos::rcp (
new MV (map1, numVecs,
false));
444 if (cachedResidual2_.is_null () ||
445 map2.get () != cachedResidual2_->getMap ().get () ||
446 cachedResidual2_->getNumVectors () != numVecs) {
448 cachedResidual2_ =
Teuchos::rcp (
new MV (map2, numVecs,
false));
449 cachedSolution2_ =
Teuchos::rcp (
new MV (map2, numVecs,
false));
454 template <
class MatrixType>
457 typename MatrixType::local_ordinal_type,
458 typename MatrixType::global_ordinal_type,
459 typename MatrixType::node_type>& X,
460 Tpetra::MultiVector<
typename MatrixType::scalar_type,
461 typename MatrixType::local_ordinal_type,
462 typename MatrixType::global_ordinal_type,
463 typename MatrixType::node_type>& Y)
const
465 const scalar_type ZERO = STS::zero ();
466 const scalar_type ONE = STS::one ();
468 const std::string timerName1 (
"Ifpack2::Hiptmair::apply 1");
469 const std::string timerName2 (
"Ifpack2::Hiptmair::apply 2");
481 #ifdef IFPACK2_DEBUG_SMOOTHER
482 int mypid = X.getMap()->getComm()->getRank();
484 printf(
"\n--------------------------------\n");
485 printf(
"Coming into matrix Hiptmair\n");
487 if (!mypid) printf(
"\t||x|| = %15.10e\n", ttt[0]);
489 if (!mypid) printf(
"\t||rhs|| = %15.10e\n", ttt[0]);
491 double normA = A_->getFrobeniusNorm();
492 if (!mypid) printf(
"\t||A|| = %15.10e\n", normA);
493 Tpetra::Vector<
typename MatrixType::scalar_type,
494 typename MatrixType::local_ordinal_type,
495 typename MatrixType::global_ordinal_type,
496 typename MatrixType::node_type> d(A_->getRowMap());
497 A_->getLocalDiagCopy(d);
499 if (!mypid) printf(
"\t||diag(A)|| = %15.10e\n", ttt[0]);
505 updateCachedMultiVectors (A_->getRowMap (),
509 if (preOrPost_ ==
"pre" || preOrPost_ ==
"both") {
512 Tpetra::Details::residual(*A_,Y,X,*cachedResidual1_);
513 cachedSolution1_->putScalar (ZERO);
514 ifpack2_prec1_->apply (*cachedResidual1_, *cachedSolution1_);
515 Y.update (ONE, *cachedSolution1_, ONE);
523 Tpetra::Details::residual(*A_,Y,X,*cachedResidual1_);
524 #ifdef IFPACK2_DEBUG_SMOOTHER
525 if (!mypid) printf(
" After smoothing on edges\n");
527 if (!mypid) printf(
"\t||x|| = %15.10e\n", ttt[0]);
528 cachedResidual1_->norm2(ttt());
529 if (!mypid) printf(
"\t||res|| = %15.10e\n", ttt[0]);
538 cachedSolution2_->putScalar (ZERO);
540 #ifdef IFPACK2_DEBUG_SMOOTHER
541 if (!mypid)printf(
" Before smoothing on nodes\n");
542 cachedSolution2_->norm2(ttt());
543 if (!mypid)printf(
"\t||x_nodal|| = %15.10e\n",ttt[0]);
544 cachedResidual2_->norm2(ttt());
545 if (!mypid)printf(
"\t||rhs_nodal|| = %15.10e\n", ttt[0]);
547 auto An = ifpack2_prec2_->getMatrix();
548 double normA = An->getFrobeniusNorm();
549 if (!mypid) printf(
"\t||An|| = %15.10e\n", normA);
550 Tpetra::Vector<
typename MatrixType::scalar_type,
551 typename MatrixType::local_ordinal_type,
552 typename MatrixType::global_ordinal_type,
553 typename MatrixType::node_type> d(An->getRowMap());
554 An->getLocalDiagCopy(d);
556 if (!mypid) printf(
"\t||diag(An)|| = %15.10e\n", ttt[0]);
561 ifpack2_prec2_->apply (*cachedResidual2_, *cachedSolution2_);
563 #ifdef IFPACK2_DEBUG_SMOOTHER
564 if (!mypid)printf(
" After smoothing on nodes\n");
565 cachedSolution2_->norm2(ttt());
566 if (!mypid)printf(
"\t||x_nodal|| = %15.10e\n",ttt[0]);
567 cachedResidual2_->norm2(ttt());
568 if (!mypid)printf(
"\t||rhs_nodal|| = %15.10e\n", ttt[0]);
575 if (preOrPost_ ==
"post" || preOrPost_ ==
"both") {
578 Tpetra::Details::residual(*A_,Y,X,*cachedResidual1_);
579 cachedSolution1_->putScalar (ZERO);
580 ifpack2_prec1_->apply (*cachedResidual1_, *cachedSolution1_);
581 Y.update (ONE, *cachedSolution1_, ONE);
584 #ifdef IFPACK2_DEBUG_SMOOTHER
585 if (!mypid)printf(
" After updating edge solution\n");
587 if (!mypid)printf(
"\t||x|| = %15.10e\n",ttt[0]);
588 if (!mypid)printf(
"--------------------------------\n");
594 template <
class MatrixType>
597 std::ostringstream os;
602 os <<
"\"Ifpack2::Hiptmair\": {";
603 if (this->getObjectLabel () !=
"") {
604 os <<
"Label: \"" << this->getObjectLabel () <<
"\", ";
606 os <<
"Initialized: " << (isInitialized () ?
"true" :
"false") <<
", "
607 <<
"Computed: " << (isComputed () ?
"true" :
"false") <<
", ";
610 os <<
"Matrix: null, ";
613 os <<
"Matrix: not null"
614 <<
", Global matrix dimensions: ["
615 << A_->getGlobalNumRows () <<
", " << A_->getGlobalNumCols () <<
"], ";
618 os <<
"Smoother 1: ";
619 os << ifpack2_prec1_->description() <<
", ";
620 os <<
"Smoother 2: ";
621 os << ifpack2_prec2_->description();
628 template <
class MatrixType>
648 out <<
"\"Ifpack2::Hiptmair\":";
651 if (this->getObjectLabel () !=
"") {
652 out <<
"Label: " << this->getObjectLabel () << endl;
654 out <<
"Initialized: " << (isInitialized () ?
"true" :
"false") << endl
655 <<
"Computed: " << (isComputed () ?
"true" :
"false") << endl
656 <<
"Global number of rows: " << A_->getGlobalNumRows () << endl
657 <<
"Global number of columns: " << A_->getGlobalNumCols () << endl
660 out <<
" null" << endl;
662 A_->describe (out, vl);
664 out <<
"Smoother 1: ";
665 ifpack2_prec1_->describe(out, vl);
666 out <<
"Smoother 2: ";
667 ifpack2_prec2_->describe(out, vl);
673 #define IFPACK2_HIPTMAIR_INSTANT(S,LO,GO,N) \
674 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:269
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:86
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:429
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:85
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:90
#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:82
double getComputeTime() const
Returns the time spent in Compute().
Definition: Ifpack2_Hiptmair_def.hpp:245
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Returns the operator's communicator.
Definition: Ifpack2_Hiptmair_def.hpp:172
bool hasTransposeApply() const
Whether this object's apply() method can apply the transpose (or conjugate transpose, if applicable).
Definition: Ifpack2_Hiptmair_def.hpp:213
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:630
double getApplyTime() const
Returns the time spent in apply().
Definition: Ifpack2_Hiptmair_def.hpp:251
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:257
void setParameters(const Teuchos::ParameterList ¶ms)
Set the preconditioner's parameters.
Definition: Ifpack2_Hiptmair_def.hpp:117
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:183
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:202
MatrixType::global_ordinal_type global_ordinal_type
The type of global indices in the input MatrixType.
Definition: Ifpack2_Hiptmair_decl.hpp:88
int getNumApply() const
Returns the number of calls to apply().
Definition: Ifpack2_Hiptmair_def.hpp:233
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Wrapper for Hiptmair smoothers.
Definition: Ifpack2_Hiptmair_decl.hpp:71
int getNumCompute() const
Returns the number of calls to Compute().
Definition: Ifpack2_Hiptmair_def.hpp:227
int getNumInitialize() const
Returns the number of calls to Initialize().
Definition: Ifpack2_Hiptmair_def.hpp:221
MatrixType::node_type node_type
The Node type used by the input MatrixType.
Definition: Ifpack2_Hiptmair_decl.hpp:91
void compute()
Do any initialization that depends on the input matrix's values.
Definition: Ifpack2_Hiptmair_def.hpp:312
virtual ~Hiptmair()
Destructor.
Definition: Ifpack2_Hiptmair_def.hpp:114
std::string description() const
Return a simple one-line description of this object.
Definition: Ifpack2_Hiptmair_def.hpp:595
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:190
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:263
double getInitializeTime() const
Returns the time spent in Initialize().
Definition: Ifpack2_Hiptmair_def.hpp:239
"Factory" for creating single-level preconditioners.
Definition: Ifpack2_Details_OneLevelFactory_decl.hpp:125
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:355