43 #ifndef IFPACK2_CHEBYSHEV_DEF_HPP
44 #define IFPACK2_CHEBYSHEV_DEF_HPP
46 #include "Ifpack2_Parameters.hpp"
47 #include "Teuchos_TimeMonitor.hpp"
48 #include "Tpetra_CrsMatrix.hpp"
49 #include "Teuchos_TypeNameTraits.hpp"
56 template<
class MatrixType>
57 Chebyshev<MatrixType>::
58 Chebyshev (
const Teuchos::RCP<const row_matrix_type>& A)
60 IsInitialized_ (false),
65 InitializeTime_ (0.0),
71 this->setObjectLabel (
"Ifpack2::Chebyshev");
75 template<
class MatrixType>
80 template<
class MatrixType>
83 if (A.getRawPtr () != impl_.getMatrix ().getRawPtr ()) {
84 IsInitialized_ =
false;
91 template<
class MatrixType>
96 impl_.setParameters (const_cast<Teuchos::ParameterList&> (List));
100 template<
class MatrixType>
101 Teuchos::RCP<const Teuchos::Comm<int> >
104 Teuchos::RCP<const row_matrix_type> A = impl_.getMatrix ();
105 TEUCHOS_TEST_FOR_EXCEPTION(
106 A.is_null (), std::runtime_error,
"Ifpack2::Chebyshev::getComm: The input "
107 "matrix A is null. Please call setMatrix() with a nonnull input matrix "
108 "before calling this method.");
109 return A->getRowMap ()->getComm ();
113 template<
class MatrixType>
114 Teuchos::RCP<const typename Chebyshev<MatrixType>::row_matrix_type>
117 return impl_.getMatrix ();
121 template<
class MatrixType>
122 Teuchos::RCP<
const Tpetra::CrsMatrix<
typename MatrixType::scalar_type,
123 typename MatrixType::local_ordinal_type,
124 typename MatrixType::global_ordinal_type,
125 typename MatrixType::node_type> >
130 return Teuchos::rcp_dynamic_cast<const crs_matrix_type> (impl_.getMatrix ());
134 template<
class MatrixType>
135 Teuchos::RCP<const typename Chebyshev<MatrixType>::map_type>
139 Teuchos::RCP<const row_matrix_type> A = impl_.getMatrix ();
140 TEUCHOS_TEST_FOR_EXCEPTION(
141 A.is_null (), std::runtime_error,
"Ifpack2::Chebyshev::getDomainMap: The "
142 "input matrix A is null. Please call setMatrix() with a nonnull input "
143 "matrix before calling this method.");
144 return A->getDomainMap ();
148 template<
class MatrixType>
149 Teuchos::RCP<const typename Chebyshev<MatrixType>::map_type>
153 Teuchos::RCP<const row_matrix_type> A = impl_.getMatrix ();
154 TEUCHOS_TEST_FOR_EXCEPTION(
155 A.is_null (), std::runtime_error,
"Ifpack2::Chebyshev::getRangeMap: The "
156 "input matrix A is null. Please call setMatrix() with a nonnull input "
157 "matrix before calling this method.");
158 return A->getRangeMap ();
162 template<
class MatrixType>
164 return impl_.hasTransposeApply ();
168 template<
class MatrixType>
170 return NumInitialize_;
174 template<
class MatrixType>
180 template<
class MatrixType>
186 template<
class MatrixType>
188 return InitializeTime_;
192 template<
class MatrixType>
198 template<
class MatrixType>
204 template<
class MatrixType>
206 return ComputeFlops_;
210 template<
class MatrixType>
215 template<
class MatrixType>
217 Teuchos::RCP<const row_matrix_type> A = impl_.getMatrix();
218 TEUCHOS_TEST_FOR_EXCEPTION(
219 A.is_null (), std::runtime_error,
"Ifpack2::Chevyshev::getNodeSmootherComplexity: "
220 "The input matrix A is null. Please call setMatrix() with a nonnull "
221 "input matrix, then call compute(), before calling this method.");
223 return A->getNodeNumRows() + A->getNodeNumEntries();
228 template<
class MatrixType>
231 apply (
const Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type>& X,
232 Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type>& Y,
233 Teuchos::ETransp mode,
237 const std::string timerName (
"Ifpack2::Chebyshev::apply");
238 Teuchos::RCP<Teuchos::Time> timer = Teuchos::TimeMonitor::lookupCounter (timerName);
239 if (timer.is_null ()) {
240 timer = Teuchos::TimeMonitor::getNewCounter (timerName);
245 Teuchos::TimeMonitor timeMon (*timer);
249 TEUCHOS_TEST_FOR_EXCEPTION(
250 ! isComputed (), std::runtime_error,
251 "Ifpack2::Chebyshev::apply(): You must call the compute() method before "
252 "you may call apply().");
253 TEUCHOS_TEST_FOR_EXCEPTION(
254 X.getNumVectors () != Y.getNumVectors (), std::runtime_error,
255 "Ifpack2::Chebyshev::apply(): X and Y must have the same number of "
256 "columns. X.getNumVectors() = " << X.getNumVectors() <<
" != "
257 <<
"Y.getNumVectors() = " << Y.getNumVectors() <<
".");
258 applyImpl (X, Y, mode, alpha, beta);
264 ApplyTime_ = timer->totalElapsedTime ();
268 template<
class MatrixType>
271 applyMat (
const Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type>& X,
272 Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type>& Y,
273 Teuchos::ETransp mode)
const
275 TEUCHOS_TEST_FOR_EXCEPTION(
276 X.getNumVectors () != Y.getNumVectors (), std::invalid_argument,
277 "Ifpack2::Chebyshev::applyMat: X.getNumVectors() != Y.getNumVectors().");
279 Teuchos::RCP<const row_matrix_type> A = impl_.getMatrix ();
280 TEUCHOS_TEST_FOR_EXCEPTION(
281 A.is_null (), std::runtime_error,
"Ifpack2::Chebyshev::applyMat: The input "
282 "matrix A is null. Please call setMatrix() with a nonnull input matrix "
283 "before calling this method.");
285 A->apply (X, Y, mode);
289 template<
class MatrixType>
294 const std::string timerName (
"Ifpack2::Chebyshev::initialize");
295 Teuchos::RCP<Teuchos::Time> timer = Teuchos::TimeMonitor::lookupCounter (timerName);
296 if (timer.is_null ()) {
297 timer = Teuchos::TimeMonitor::getNewCounter (timerName);
299 IsInitialized_ =
true;
304 template<
class MatrixType>
307 const std::string timerName (
"Ifpack2::Chebyshev::compute");
308 Teuchos::RCP<Teuchos::Time> timer = Teuchos::TimeMonitor::lookupCounter (timerName);
309 if (timer.is_null ()) {
310 timer = Teuchos::TimeMonitor::getNewCounter (timerName);
315 Teuchos::TimeMonitor timeMon (*timer);
316 if (! isInitialized ()) {
327 ComputeTime_ = timer->totalElapsedTime ();
331 template <
class MatrixType>
333 std::ostringstream out;
338 out <<
"\"Ifpack2::Chebyshev\": {";
339 out <<
"Initialized: " << (isInitialized () ?
"true" :
"false") <<
", "
340 <<
"Computed: " << (isComputed () ?
"true" :
"false") <<
", ";
342 out << impl_.description() <<
", ";
344 if (impl_.getMatrix ().is_null ()) {
345 out <<
"Matrix: null";
348 out <<
"Global matrix dimensions: ["
349 << impl_.getMatrix ()->getGlobalNumRows () <<
", "
350 << impl_.getMatrix ()->getGlobalNumCols () <<
"]"
351 <<
", Global nnz: " << impl_.getMatrix ()->getGlobalNumEntries();
359 template <
class MatrixType>
362 const Teuchos::EVerbosityLevel verbLevel)
const
364 using Teuchos::TypeNameTraits;
368 const Teuchos::EVerbosityLevel vl =
369 (verbLevel == Teuchos::VERB_DEFAULT) ? Teuchos::VERB_LOW : verbLevel;
371 if (vl == Teuchos::VERB_NONE) {
381 Teuchos::OSTab tab0 (out);
382 const int myRank = this->getComm ()->getRank ();
386 out <<
"\"Ifpack2::Chebyshev\":" << endl;
389 Teuchos::OSTab tab1 (out);
390 if (vl >= Teuchos::VERB_LOW && myRank == 0) {
391 out <<
"Template parameters:" << endl;
393 Teuchos::OSTab tab2 (out);
394 out <<
"Scalar: " << TypeNameTraits<scalar_type>::name () << endl
395 <<
"LocalOrdinal: " << TypeNameTraits<local_ordinal_type>::name () << endl
396 <<
"GlobalOrdinal: " << TypeNameTraits<global_ordinal_type>::name () << endl
397 <<
"Device: " << TypeNameTraits<device_type>::name () << endl;
399 out <<
"Initialized: " << (isInitialized () ?
"true" :
"false") << endl
400 <<
"Computed: " << (isComputed () ?
"true" :
"false") << endl;
401 impl_.describe (out, vl);
403 if (impl_.getMatrix ().is_null ()) {
404 out <<
"Matrix: null" << endl;
407 out <<
"Global matrix dimensions: ["
408 << impl_.getMatrix ()->getGlobalNumRows () <<
", "
409 << impl_.getMatrix ()->getGlobalNumCols () <<
"]" << endl
410 <<
"Global nnz: " << impl_.getMatrix ()->getGlobalNumEntries() << endl;
415 template<
class MatrixType>
422 scalar_type beta)
const
424 using Teuchos::ArrayRCP;
428 using Teuchos::rcp_const_cast;
429 using Teuchos::rcpFromRef;
431 const scalar_type zero = STS::zero();
432 const scalar_type one = STS::one();
453 Y_orig = rcp (
new MV (Y, Teuchos::Copy));
462 RCP<const MV> X_copy;
463 bool copiedInput =
false;
465 auto X_lcl_host = X.template getLocalView<Kokkos::HostSpace> ();
466 auto Y_lcl_host = Y.template getLocalView<Kokkos::HostSpace> ();
467 if (X_lcl_host.data () == Y_lcl_host.data ()) {
468 X_copy = rcp (
new MV (X, Teuchos::Copy));
471 X_copy = rcpFromRef (X);
481 RCP<MV> X_copy_nonConst = rcp_const_cast<MV> (X_copy);
483 X_copy_nonConst = rcp (
new MV (X, Teuchos::Copy));
486 X_copy_nonConst->scale (alpha);
487 X_copy = rcp_const_cast<const MV> (X_copy_nonConst);
490 impl_.apply (*X_copy, Y);
493 Y.update (beta, *Y_orig, one);
498 template<
class MatrixType>
500 return impl_.getLambdaMaxForApply ();
507 #define IFPACK2_CHEBYSHEV_INSTANT(S,LO,GO,N) \
508 template class Ifpack2::Chebyshev< Tpetra::RowMatrix<S, LO, GO, N> >;
510 #endif // IFPACK2_CHEBYSHEV_DEF_HPP