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>
37 precType1_(
"CHEBYSHEV")
38 , precType2_(
"CHEBYSHEV")
40 , ZeroStartingSolution_(true)
41 , ImplicitTranspose_(Pt.
is_null())
49 , InitializeTime_(0.0)
53 template <
class MatrixType>
62 precType1_(
"CHEBYSHEV")
63 , precType2_(
"CHEBYSHEV")
65 , ZeroStartingSolution_(true)
66 , ImplicitTranspose_(true)
74 , InitializeTime_(0.0)
78 template <
class MatrixType>
81 template <
class MatrixType>
89 ParameterList params = plist;
96 std::string precType1 = precType1_;
97 std::string precType2 = precType2_;
98 std::string preOrPost = preOrPost_;
101 bool zeroStartingSolution = ZeroStartingSolution_;
102 bool implicitTranspose = ImplicitTranspose_;
104 precType1 = params.
get(
"hiptmair: smoother type 1", precType1);
105 precType2 = params.get(
"hiptmair: smoother type 2", precType2);
106 precList1 = params.
get(
"hiptmair: smoother list 1", precList1);
107 precList2 = params.
get(
"hiptmair: smoother list 2", precList2);
108 preOrPost = params.get(
"hiptmair: pre or post", preOrPost);
109 zeroStartingSolution = params.get(
"hiptmair: zero starting solution",
110 zeroStartingSolution);
111 implicitTranspose = params.get(
"hiptmair: implicit transpose", implicitTranspose);
116 PtAP_ = params.get<RCP<row_matrix_type>>(
"PtAP");
118 P_ = params.get<RCP<row_matrix_type>>(
"P");
119 if (params.isType<RCP<row_matrix_type>>(
"Pt"))
120 Pt_ = params.get<RCP<row_matrix_type>>(
"Pt");
123 precType1_ = precType1;
124 precType2_ = precType2;
125 precList1_ = precList1;
126 precList2_ = precList2;
127 preOrPost_ = preOrPost;
128 ZeroStartingSolution_ = zeroStartingSolution;
129 ImplicitTranspose_ = implicitTranspose;
132 template <
class MatrixType>
136 A_.
is_null(), std::runtime_error,
137 "Ifpack2::Hiptmair::getComm: "
138 "The input matrix A is null. Please call setMatrix() with a nonnull "
139 "input matrix before calling this method.");
140 return A_->getComm();
143 template <
class MatrixType>
149 template <
class MatrixType>
153 A_.
is_null(), std::runtime_error,
154 "Ifpack2::Hiptmair::getDomainMap: "
155 "The input matrix A is null. Please call setMatrix() with a nonnull "
156 "input matrix before calling this method.");
157 return A_->getDomainMap();
160 template <
class MatrixType>
164 A_.
is_null(), std::runtime_error,
165 "Ifpack2::Hiptmair::getRangeMap: "
166 "The input matrix A is null. Please call setMatrix() with a nonnull "
167 "input matrix before calling this method.");
168 return A_->getRangeMap();
171 template <
class MatrixType>
178 template <
class MatrixType>
180 return NumInitialize_;
183 template <
class MatrixType>
188 template <
class MatrixType>
193 template <
class MatrixType>
195 return InitializeTime_;
198 template <
class MatrixType>
203 template <
class MatrixType>
208 template <
class MatrixType>
210 return ifpack2_prec1_;
213 template <
class MatrixType>
215 return ifpack2_prec2_;
218 template <
class MatrixType>
224 const char methodName[] =
"Ifpack2::Hiptmair::initialize";
227 A_.
is_null(), std::runtime_error,
228 "Ifpack2::Hiptmair::initialize: "
229 "The input matrix A is null. Please call setMatrix() with a nonnull "
230 "input matrix before calling this method.");
233 IsInitialized_ =
false;
239 double startTime = timer->
wallTime();
246 ifpack2_prec1_ = factory.
create(precType1_, A_);
247 ifpack2_prec1_->initialize();
248 ifpack2_prec1_->setParameters(precList1_);
250 ifpack2_prec2_ = factory.
create(precType2_, PtAP_);
251 ifpack2_prec2_->initialize();
252 ifpack2_prec2_->setParameters(precList2_);
254 IsInitialized_ =
true;
256 InitializeTime_ += (timer->
wallTime() - startTime);
259 template <
class MatrixType>
261 const char methodName[] =
"Ifpack2::Hiptmair::initialize";
264 A_.
is_null(), std::runtime_error,
265 "Ifpack2::Hiptmair::compute: "
266 "The input matrix A is null. Please call setMatrix() with a nonnull "
267 "input matrix before calling this method.");
270 if (!isInitialized()) {
277 double startTime = timer->
wallTime();
280 ifpack2_prec1_->compute();
281 ifpack2_prec2_->compute();
283 if (!ImplicitTranspose_ && Pt_.is_null()) {
284 using crs_type = Tpetra::CrsMatrix<typename MatrixType::scalar_type, typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type, typename MatrixType::node_type>;
287 using transposer_type = Tpetra::RowMatrixTransposer<typename MatrixType::scalar_type, typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type, typename MatrixType::node_type>;
288 Pt_ = transposer_type(crsP).createTranspose();
291 "Ifpack2::Hiptmair::compute: "
292 "ImplicitTranspose == false, but no Pt was provided and transposing P was not possible.");
298 ComputeTime_ += (timer->
wallTime() - startTime);
301 template <
class MatrixType>
303 apply(
const Tpetra::MultiVector<
typename MatrixType::scalar_type,
304 typename MatrixType::local_ordinal_type,
305 typename MatrixType::global_ordinal_type,
306 typename MatrixType::node_type>& X,
307 Tpetra::MultiVector<
typename MatrixType::scalar_type,
308 typename MatrixType::local_ordinal_type,
309 typename MatrixType::global_ordinal_type,
310 typename MatrixType::node_type>& Y,
312 typename MatrixType::scalar_type alpha,
313 typename MatrixType::scalar_type beta)
const {
316 using Teuchos::rcpFromRef;
321 !isComputed(), std::runtime_error,
322 "Ifpack2::Hiptmair::apply: You must call compute() before you may call apply().");
324 X.getNumVectors() != Y.getNumVectors(), std::invalid_argument,
325 "Ifpack2::Hiptmair::apply: The MultiVector inputs X and Y do not have the "
326 "same number of columns. X.getNumVectors() = "
328 <<
" != Y.getNumVectors() = " << Y.getNumVectors() <<
".");
332 alpha != STS::one(), std::logic_error,
333 "Ifpack2::Hiptmair::apply: alpha != 1 has not been implemented.");
334 TEUCHOS_TEST_FOR_EXCEPTION(
335 beta != STS::zero(), std::logic_error,
336 "Ifpack2::Hiptmair::apply: zero != 0 has not been implemented.");
337 TEUCHOS_TEST_FOR_EXCEPTION(
339 "Ifpack2::Hiptmair::apply: mode != Teuchos::NO_TRANS has not been implemented.");
341 const std::string timerName(
"Ifpack2::Hiptmair::apply");
346 double startTime = timer->
wallTime();
357 Xcopy = rcpFromRef(X);
361 RCP<MV> Ycopy = rcpFromRef(Y);
362 if (ZeroStartingSolution_) {
363 Ycopy->putScalar(STS::zero());
367 applyHiptmairSmoother(*Xcopy, *Ycopy);
370 ApplyTime_ += (timer->
wallTime() - startTime);
373 template <
class MatrixType>
376 const Teuchos::RCP<
const Tpetra::Map<local_ordinal_type, global_ordinal_type, node_type>>& map2,
377 size_t numVecs)
const {
382 if (cachedResidual1_.is_null() ||
383 map1.get() != cachedResidual1_->getMap().get() ||
384 cachedResidual1_->getNumVectors() != numVecs) {
385 cachedResidual1_ =
Teuchos::rcp(
new MV(map1, numVecs,
false));
386 cachedSolution1_ =
Teuchos::rcp(
new MV(map1, numVecs,
false));
388 if (cachedResidual2_.is_null() ||
389 map2.get() != cachedResidual2_->getMap().get() ||
390 cachedResidual2_->getNumVectors() != numVecs) {
391 cachedResidual2_ =
Teuchos::rcp(
new MV(map2, numVecs,
false));
392 cachedSolution2_ =
Teuchos::rcp(
new MV(map2, numVecs,
false));
396 template <
class MatrixType>
399 typename MatrixType::local_ordinal_type,
400 typename MatrixType::global_ordinal_type,
401 typename MatrixType::node_type>& X,
402 Tpetra::MultiVector<
typename MatrixType::scalar_type,
403 typename MatrixType::local_ordinal_type,
404 typename MatrixType::global_ordinal_type,
405 typename MatrixType::node_type>& Y)
const {
406 const scalar_type ZERO = STS::zero();
407 const scalar_type ONE = STS::one();
409 const std::string timerName1(
"Ifpack2::Hiptmair::apply 1");
410 const std::string timerName2(
"Ifpack2::Hiptmair::apply 2");
422 #ifdef IFPACK2_DEBUG_SMOOTHER
423 int mypid = X.getMap()->getComm()->getRank();
425 printf(
"\n--------------------------------\n");
426 printf(
"Coming into matrix Hiptmair\n");
428 if (!mypid) printf(
"\t||x|| = %15.10e\n", ttt[0]);
430 if (!mypid) printf(
"\t||rhs|| = %15.10e\n", ttt[0]);
432 double normA = A_->getFrobeniusNorm();
433 if (!mypid) printf(
"\t||A|| = %15.10e\n", normA);
434 Tpetra::Vector<
typename MatrixType::scalar_type,
435 typename MatrixType::local_ordinal_type,
436 typename MatrixType::global_ordinal_type,
437 typename MatrixType::node_type>
439 A_->getLocalDiagCopy(d);
441 if (!mypid) printf(
"\t||diag(A)|| = %15.10e\n", ttt[0]);
446 updateCachedMultiVectors(A_->getRowMap(),
450 if (preOrPost_ ==
"pre" || preOrPost_ ==
"both") {
453 Tpetra::Details::residual(*A_, Y, X, *cachedResidual1_);
454 cachedSolution1_->putScalar(ZERO);
455 ifpack2_prec1_->apply(*cachedResidual1_, *cachedSolution1_);
456 Y.update(ONE, *cachedSolution1_, ONE);
462 Tpetra::Details::residual(*A_, Y, X, *cachedResidual1_);
463 #ifdef IFPACK2_DEBUG_SMOOTHER
464 if (!mypid) printf(
" After smoothing on edges\n");
466 if (!mypid) printf(
"\t||x|| = %15.10e\n", ttt[0]);
467 cachedResidual1_->norm2(ttt());
468 if (!mypid) printf(
"\t||res|| = %15.10e\n", ttt[0]);
475 cachedSolution2_->putScalar(ZERO);
477 #ifdef IFPACK2_DEBUG_SMOOTHER
478 if (!mypid) printf(
" Before smoothing on nodes\n");
479 cachedSolution2_->norm2(ttt());
480 if (!mypid) printf(
"\t||x_nodal|| = %15.10e\n", ttt[0]);
481 cachedResidual2_->norm2(ttt());
482 if (!mypid) printf(
"\t||rhs_nodal|| = %15.10e\n", ttt[0]);
484 auto An = ifpack2_prec2_->getMatrix();
485 double normA = An->getFrobeniusNorm();
486 if (!mypid) printf(
"\t||An|| = %15.10e\n", normA);
487 Tpetra::Vector<
typename MatrixType::scalar_type,
488 typename MatrixType::local_ordinal_type,
489 typename MatrixType::global_ordinal_type,
490 typename MatrixType::node_type>
492 An->getLocalDiagCopy(d);
494 if (!mypid) printf(
"\t||diag(An)|| = %15.10e\n", ttt[0]);
499 ifpack2_prec2_->apply(*cachedResidual2_, *cachedSolution2_);
501 #ifdef IFPACK2_DEBUG_SMOOTHER
502 if (!mypid) printf(
" After smoothing on nodes\n");
503 cachedSolution2_->norm2(ttt());
504 if (!mypid) printf(
"\t||x_nodal|| = %15.10e\n", ttt[0]);
505 cachedResidual2_->norm2(ttt());
506 if (!mypid) printf(
"\t||rhs_nodal|| = %15.10e\n", ttt[0]);
512 if (preOrPost_ ==
"post" || preOrPost_ ==
"both") {
515 Tpetra::Details::residual(*A_, Y, X, *cachedResidual1_);
516 cachedSolution1_->putScalar(ZERO);
517 ifpack2_prec1_->apply(*cachedResidual1_, *cachedSolution1_);
518 Y.update(ONE, *cachedSolution1_, ONE);
521 #ifdef IFPACK2_DEBUG_SMOOTHER
522 if (!mypid) printf(
" After updating edge solution\n");
524 if (!mypid) printf(
"\t||x|| = %15.10e\n", ttt[0]);
525 if (!mypid) printf(
"--------------------------------\n");
529 template <
class MatrixType>
531 std::ostringstream os;
536 os <<
"\"Ifpack2::Hiptmair\": {";
537 if (this->getObjectLabel() !=
"") {
538 os <<
"Label: \"" << this->getObjectLabel() <<
"\", ";
540 os <<
"Initialized: " << (isInitialized() ?
"true" :
"false") <<
", "
541 <<
"Computed: " << (isComputed() ?
"true" :
"false") <<
", ";
544 os <<
"Matrix: null, ";
546 os <<
"Matrix: not null"
547 <<
", Global matrix dimensions: ["
548 << A_->getGlobalNumRows() <<
", " << A_->getGlobalNumCols() <<
"], ";
551 os <<
"Smoother 1: ";
552 os << ifpack2_prec1_->description() <<
", ";
553 os <<
"Smoother 2: ";
554 os << ifpack2_prec2_->description();
560 template <
class MatrixType>
579 out <<
"\"Ifpack2::Hiptmair\":";
582 if (this->getObjectLabel() !=
"") {
583 out <<
"Label: " << this->getObjectLabel() << endl;
585 out <<
"Initialized: " << (isInitialized() ?
"true" :
"false") << endl
586 <<
"Computed: " << (isComputed() ?
"true" :
"false") << endl
587 <<
"Global number of rows: " << A_->getGlobalNumRows() << endl
588 <<
"Global number of columns: " << A_->getGlobalNumCols() << endl
591 out <<
" null" << endl;
593 A_->describe(out, vl);
595 out <<
"Smoother 1: ";
596 ifpack2_prec1_->describe(out, vl);
597 out <<
"Smoother 2: ";
598 ifpack2_prec2_->describe(out, vl);
604 #define IFPACK2_HIPTMAIR_INSTANT(S, LO, GO, N) \
605 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:219
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:52
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:50
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:55
#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:47
double getComputeTime() const
Returns the time spent in Compute().
Definition: Ifpack2_Hiptmair_def.hpp:199
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Returns the operator's communicator.
Definition: Ifpack2_Hiptmair_def.hpp:134
bool hasTransposeApply() const
Whether this object's apply() method can apply the transpose (or conjugate transpose, if applicable).
Definition: Ifpack2_Hiptmair_def.hpp:172
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:562
double getApplyTime() const
Returns the time spent in apply().
Definition: Ifpack2_Hiptmair_def.hpp:204
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:209
void setParameters(const Teuchos::ParameterList ¶ms)
Set the preconditioner's parameters.
Definition: Ifpack2_Hiptmair_def.hpp:82
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:145
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:162
MatrixType::global_ordinal_type global_ordinal_type
The type of global indices in the input MatrixType.
Definition: Ifpack2_Hiptmair_decl.hpp:53
int getNumApply() const
Returns the number of calls to apply().
Definition: Ifpack2_Hiptmair_def.hpp:189
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:184
int getNumInitialize() const
Returns the number of calls to Initialize().
Definition: Ifpack2_Hiptmair_def.hpp:179
MatrixType::node_type node_type
The Node type used by the input MatrixType.
Definition: Ifpack2_Hiptmair_decl.hpp:56
void compute()
Do any initialization that depends on the input matrix's values.
Definition: Ifpack2_Hiptmair_def.hpp:260
virtual ~Hiptmair()
Destructor.
Definition: Ifpack2_Hiptmair_def.hpp:79
std::string description() const
Return a simple one-line description of this object.
Definition: Ifpack2_Hiptmair_def.hpp:530
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:151
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:375
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:214
double getInitializeTime() const
Returns the time spent in Initialize().
Definition: Ifpack2_Hiptmair_def.hpp:194
"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:303