Ifpack2 Templated Preconditioning Package  Version 1.0
Ifpack2_Hiptmair_def.hpp
1 /*@HEADER
2 // ***********************************************************************
3 //
4 // Ifpack2: Templated Object-Oriented Algebraic Preconditioner Package
5 // Copyright (2009) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 //@HEADER
41 */
42 
43 #ifndef IFPACK2_HIPTMAIR_DEF_HPP
44 #define IFPACK2_HIPTMAIR_DEF_HPP
45 
46 #include "Ifpack2_Details_OneLevelFactory.hpp"
47 #include "Ifpack2_Parameters.hpp"
48 #include "Teuchos_TimeMonitor.hpp"
49 #include "Tpetra_MultiVector.hpp"
50 #include "Tpetra_Details_residual.hpp"
51 #include <Tpetra_RowMatrixTransposer.hpp>
52 #include <cmath>
53 #include <iostream>
54 #include <sstream>
55 
56 namespace Ifpack2 {
57 
58 template <class MatrixType>
60 Hiptmair (const Teuchos::RCP<const row_matrix_type>& A,
61  const Teuchos::RCP<const row_matrix_type>& PtAP,
62  const Teuchos::RCP<const row_matrix_type>& P,
63  const Teuchos::RCP<const row_matrix_type>& Pt) :
64  A_ (A),
65  PtAP_ (PtAP),
66  P_ (P),
67  Pt_ (Pt),
68  // Default values
69  precType1_ ("CHEBYSHEV"),
70  precType2_ ("CHEBYSHEV"),
71  preOrPost_ ("both"),
72  ZeroStartingSolution_ (true),
73  ImplicitTranspose_ (Pt.is_null()),
74  // General
75  IsInitialized_ (false),
76  IsComputed_ (false),
77  NumInitialize_ (0),
78  NumCompute_ (0),
79  NumApply_ (0),
80  InitializeTime_ (0.0),
81  ComputeTime_ (0.0),
82  ApplyTime_ (0.0)
83 {}
84 
85 
86 
87 
88 template <class MatrixType>
90 Hiptmair (const Teuchos::RCP<const row_matrix_type>& A):
91  A_ (A),
92  PtAP_ (),
93  P_ (),
94  Pt_ (),
95  // Default values
96  precType1_ ("CHEBYSHEV"),
97  precType2_ ("CHEBYSHEV"),
98  preOrPost_ ("both"),
99  ZeroStartingSolution_ (true),
100  ImplicitTranspose_ (true),
101  // General
102  IsInitialized_ (false),
103  IsComputed_ (false),
104  NumInitialize_ (0),
105  NumCompute_ (0),
106  NumApply_ (0),
107  InitializeTime_ (0.0),
108  ComputeTime_ (0.0),
109  ApplyTime_ (0.0)
110 {}
111 
112 
113 template <class MatrixType>
115 
116 template <class MatrixType>
117 void Hiptmair<MatrixType>::setParameters (const Teuchos::ParameterList& plist)
118 {
119  using Teuchos::as;
120  using Teuchos::RCP;
121  using Teuchos::ParameterList;
122  using Teuchos::Exceptions::InvalidParameterName;
123  using Teuchos::Exceptions::InvalidParameterType;
124 
125  ParameterList params = plist;
126 
127  // Get the current parameters' values. We don't assign to the
128  // instance data directly until we've gotten all the parameters.
129  // This ensures "transactional" semantics, so that if attempting to
130  // get some parameter throws an exception, the class' state doesn't
131  // change.
132  std::string precType1 = precType1_;
133  std::string precType2 = precType2_;
134  std::string preOrPost = preOrPost_;
135  Teuchos::ParameterList precList1 = precList1_;
136  Teuchos::ParameterList precList2 = precList2_;
137  bool zeroStartingSolution = ZeroStartingSolution_;
138  bool implicitTranspose = ImplicitTranspose_;
139 
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);
148 
149  // Grab the matrices off of the parameter list if we need them
150  // This will intentionally throw if they're not there and we need them
151  if(PtAP_.is_null())
152  PtAP_ = params.get<RCP<row_matrix_type> >("PtAP");
153  if(P_.is_null())
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");
157 
158 
159  // "Commit" the new values to the instance data.
160  precType1_ = precType1;
161  precType2_ = precType2;
162  precList1_ = precList1;
163  precList2_ = precList2;
164  preOrPost_ = preOrPost;
165  ZeroStartingSolution_ = zeroStartingSolution;
166  ImplicitTranspose_ = implicitTranspose;
167 }
168 
169 
170 template <class MatrixType>
171 Teuchos::RCP<const Teuchos::Comm<int> >
173  TEUCHOS_TEST_FOR_EXCEPTION(
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 ();
178 }
179 
180 
181 template <class MatrixType>
182 Teuchos::RCP<const Tpetra::RowMatrix<typename MatrixType::scalar_type,typename MatrixType::local_ordinal_type,typename MatrixType::global_ordinal_type,typename MatrixType::node_type> >
184  return A_;
185 }
186 
187 
188 template <class MatrixType>
189 Teuchos::RCP<const Tpetra::Map<typename MatrixType::local_ordinal_type,typename MatrixType::global_ordinal_type,typename MatrixType::node_type> >
191 {
192  TEUCHOS_TEST_FOR_EXCEPTION(
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 ();
197 }
198 
199 
200 template <class MatrixType>
201 Teuchos::RCP<const Tpetra::Map<typename MatrixType::local_ordinal_type,typename MatrixType::global_ordinal_type,typename MatrixType::node_type> >
203 {
204  TEUCHOS_TEST_FOR_EXCEPTION(
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 ();
209 }
210 
211 
212 template <class MatrixType>
214  // FIXME (mfh 17 Jan 2014) apply() does not currently work with mode
215  // != NO_TRANS, so it's correct to return false here.
216  return false;
217 }
218 
219 
220 template <class MatrixType>
222  return NumInitialize_;
223 }
224 
225 
226 template <class MatrixType>
228  return NumCompute_;
229 }
230 
231 
232 template <class MatrixType>
234  return NumApply_;
235 }
236 
237 
238 template <class MatrixType>
240  return InitializeTime_;
241 }
242 
243 
244 template <class MatrixType>
246  return ComputeTime_;
247 }
248 
249 
250 template <class MatrixType>
252  return ApplyTime_;
253 }
254 
255 
256 template <class MatrixType>
258 {
259  using Teuchos::ParameterList;
260  using Teuchos::RCP;
261  using Teuchos::rcp;
262 
263  const char methodName[] = "Ifpack2::Hiptmair::initialize";
264 
265  TEUCHOS_TEST_FOR_EXCEPTION(
266  A_.is_null (), std::runtime_error, "Ifpack2::Hiptmair::initialize: "
267  "The input matrix A is null. Please call setMatrix() with a nonnull "
268  "input matrix before calling this method.");
269 
270  // clear any previous allocation
271  IsInitialized_ = false;
272  IsComputed_ = false;
273 
274  Teuchos::RCP<Teuchos::Time> timer =
275  Teuchos::TimeMonitor::getNewCounter (methodName);
276 
277  double startTime = timer->wallTime();
278 
279  { // The body of code to time
280  Teuchos::TimeMonitor timeMon (*timer);
281 
283 
284  ifpack2_prec1_=factory.create(precType1_,A_);
285  ifpack2_prec1_->initialize();
286  ifpack2_prec1_->setParameters(precList1_);
287 
288  ifpack2_prec2_=factory.create(precType2_,PtAP_);
289  ifpack2_prec2_->initialize();
290  ifpack2_prec2_->setParameters(precList2_);
291 
292  }
293  IsInitialized_ = true;
294  ++NumInitialize_;
295  InitializeTime_ += (timer->wallTime() - startTime);
296 }
297 
298 
299 template <class MatrixType>
301 {
302  const char methodName[] = "Ifpack2::Hiptmair::initialize";
303 
304  TEUCHOS_TEST_FOR_EXCEPTION(
305  A_.is_null (), std::runtime_error, "Ifpack2::Hiptmair::compute: "
306  "The input matrix A is null. Please call setMatrix() with a nonnull "
307  "input matrix before calling this method.");
308 
309  // Don't time the initialize(); that gets timed separately.
310  if (! isInitialized ()) {
311  initialize ();
312  }
313 
314  Teuchos::RCP<Teuchos::Time> timer =
315  Teuchos::TimeMonitor::getNewCounter (methodName);
316 
317  double startTime = timer->wallTime();
318  { // The body of code to time
319  Teuchos::TimeMonitor timeMon (*timer);
320  ifpack2_prec1_->compute();
321  ifpack2_prec2_->compute();
322 
323  if (!ImplicitTranspose_ && Pt_.is_null()) {
324  using crs_type = Tpetra::CrsMatrix<typename MatrixType::scalar_type,typename MatrixType::local_ordinal_type,typename MatrixType::global_ordinal_type,typename MatrixType::node_type>;
325  Teuchos::RCP<const crs_type> crsP = Teuchos::rcp_dynamic_cast<const crs_type>(P_);
326  if (!crsP.is_null()) {
327  using transposer_type = Tpetra::RowMatrixTransposer<typename MatrixType::scalar_type,typename MatrixType::local_ordinal_type,typename MatrixType::global_ordinal_type,typename MatrixType::node_type>;
328  Pt_ = transposer_type(crsP).createTranspose();
329  } else {
330  TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error, "Ifpack2::Hiptmair::compute: "
331  "ImplicitTranspose == false, but no Pt was provided and transposing P was not possible.");
332  }
333  }
334  }
335  IsComputed_ = true;
336  ++NumCompute_;
337  ComputeTime_ += (timer->wallTime() - startTime);
338 }
339 
340 
341 template <class MatrixType>
343 apply (const Tpetra::MultiVector<typename MatrixType::scalar_type,
344  typename MatrixType::local_ordinal_type,
345  typename MatrixType::global_ordinal_type,
346  typename MatrixType::node_type>& X,
347  Tpetra::MultiVector<typename MatrixType::scalar_type,
348  typename MatrixType::local_ordinal_type,
349  typename MatrixType::global_ordinal_type,
350  typename MatrixType::node_type>& Y,
351  Teuchos::ETransp mode,
352  typename MatrixType::scalar_type alpha,
353  typename MatrixType::scalar_type beta) const
354 {
355  using Teuchos::RCP;
356  using Teuchos::rcp;
357  using Teuchos::rcpFromRef;
358  typedef Tpetra::MultiVector<scalar_type, local_ordinal_type,
360  TEUCHOS_TEST_FOR_EXCEPTION(
361  ! isComputed (), std::runtime_error,
362  "Ifpack2::Hiptmair::apply: You must call compute() before you may call apply().");
363  TEUCHOS_TEST_FOR_EXCEPTION(
364  X.getNumVectors () != Y.getNumVectors (), std::invalid_argument,
365  "Ifpack2::Hiptmair::apply: The MultiVector inputs X and Y do not have the "
366  "same number of columns. X.getNumVectors() = " << X.getNumVectors ()
367  << " != Y.getNumVectors() = " << Y.getNumVectors () << ".");
368 
369  // Catch unimplemented cases: alpha != 1, beta != 0, mode != NO_TRANS.
370  TEUCHOS_TEST_FOR_EXCEPTION(
371  alpha != STS::one (), std::logic_error,
372  "Ifpack2::Hiptmair::apply: alpha != 1 has not been implemented.");
373  TEUCHOS_TEST_FOR_EXCEPTION(
374  beta != STS::zero (), std::logic_error,
375  "Ifpack2::Hiptmair::apply: zero != 0 has not been implemented.");
376  TEUCHOS_TEST_FOR_EXCEPTION(
377  mode != Teuchos::NO_TRANS, std::logic_error,
378  "Ifpack2::Hiptmair::apply: mode != Teuchos::NO_TRANS has not been implemented.");
379 
380  const std::string timerName ("Ifpack2::Hiptmair::apply");
381  Teuchos::RCP<Teuchos::Time> timer = Teuchos::TimeMonitor::lookupCounter (timerName);
382  if (timer.is_null ()) {
383  timer = Teuchos::TimeMonitor::getNewCounter (timerName);
384  }
385  double startTime = timer->wallTime();
386  { // The body of code to time
387  Teuchos::TimeMonitor timeMon (*timer);
388 
389  // If X and Y are pointing to the same memory location,
390  // we need to create an auxiliary vector, Xcopy
391  RCP<const MV> Xcopy;
392  {
393  if (X.aliases(Y)) {
394  Xcopy = rcp (new MV (X, Teuchos::Copy));
395  } else {
396  Xcopy = rcpFromRef (X);
397  }
398  }
399 
400  RCP<MV> Ycopy = rcpFromRef (Y);
401  if (ZeroStartingSolution_) {
402  Ycopy->putScalar (STS::zero ());
403  }
404 
405  // apply Hiptmair Smoothing
406  applyHiptmairSmoother (*Xcopy, *Ycopy);
407 
408  }
409  ++NumApply_;
410  ApplyTime_ += (timer->wallTime() - startTime);
411 }
412 
413 
414 template<class MatrixType>
415 void
417 updateCachedMultiVectors (const Teuchos::RCP<const Tpetra::Map<local_ordinal_type, global_ordinal_type, node_type>>& map1,
418  const Teuchos::RCP<const Tpetra::Map<local_ordinal_type, global_ordinal_type, node_type>>& map2,
419  size_t numVecs) const
420 {
421  // Allocate a multivector if the cached one isn't perfect. Checking
422  // for map pointer equality is much cheaper than Map::isSameAs.
423  using MV = Tpetra::MultiVector<scalar_type, local_ordinal_type,
425  if (cachedResidual1_.is_null () ||
426  map1.get () != cachedResidual1_->getMap ().get () ||
427  cachedResidual1_->getNumVectors () != numVecs) {
428 
429  cachedResidual1_ = Teuchos::rcp (new MV (map1, numVecs, false));
430  cachedSolution1_ = Teuchos::rcp (new MV (map1, numVecs, false));
431  }
432  if (cachedResidual2_.is_null () ||
433  map2.get () != cachedResidual2_->getMap ().get () ||
434  cachedResidual2_->getNumVectors () != numVecs) {
435 
436  cachedResidual2_ = Teuchos::rcp (new MV (map2, numVecs, false));
437  cachedSolution2_ = Teuchos::rcp (new MV (map2, numVecs, false));
438  }
439 }
440 
441 
442 template <class MatrixType>
444 applyHiptmairSmoother(const Tpetra::MultiVector<typename MatrixType::scalar_type,
445  typename MatrixType::local_ordinal_type,
446  typename MatrixType::global_ordinal_type,
447  typename MatrixType::node_type>& X,
448  Tpetra::MultiVector<typename MatrixType::scalar_type,
449  typename MatrixType::local_ordinal_type,
450  typename MatrixType::global_ordinal_type,
451  typename MatrixType::node_type>& Y) const
452 {
453  const scalar_type ZERO = STS::zero ();
454  const scalar_type ONE = STS::one ();
455 
456  const std::string timerName1 ("Ifpack2::Hiptmair::apply 1");
457  const std::string timerName2 ("Ifpack2::Hiptmair::apply 2");
458 
459  Teuchos::RCP<Teuchos::Time> timer1 = Teuchos::TimeMonitor::lookupCounter (timerName1);
460  if (timer1.is_null ()) {
461  timer1 = Teuchos::TimeMonitor::getNewCounter (timerName1);
462  }
463  Teuchos::RCP<Teuchos::Time> timer2 = Teuchos::TimeMonitor::lookupCounter (timerName2);
464  if (timer2.is_null ()) {
465  timer2 = Teuchos::TimeMonitor::getNewCounter (timerName2);
466  }
467 
468  //#define IFPACK2_DEBUG_SMOOTHER
469 #ifdef IFPACK2_DEBUG_SMOOTHER
470  int mypid = X.getMap()->getComm()->getRank();
471  Teuchos::Array<double> ttt(1);
472  printf("\n--------------------------------\n");
473  printf("Coming into matrix Hiptmair\n");
474  Y.norm2(ttt());
475  if (!mypid) printf("\t||x|| = %15.10e\n", ttt[0]);
476  X.norm2(ttt());
477  if (!mypid) printf("\t||rhs|| = %15.10e\n", ttt[0]);
478  {
479  double normA = A_->getFrobeniusNorm();
480  if (!mypid) printf("\t||A|| = %15.10e\n", normA);
481  Tpetra::Vector<typename MatrixType::scalar_type,
482  typename MatrixType::local_ordinal_type,
483  typename MatrixType::global_ordinal_type,
484  typename MatrixType::node_type> d(A_->getRowMap());
485  A_->getLocalDiagCopy(d);
486  d.norm2(ttt);
487  if (!mypid) printf("\t||diag(A)|| = %15.10e\n", ttt[0]);
488  }
489  fflush(stdout);
490 #endif
491 
492 
493  updateCachedMultiVectors (A_->getRowMap (),
494  PtAP_->getRowMap (),
495  X.getNumVectors ());
496 
497  if (preOrPost_ == "pre" || preOrPost_ == "both") {
498  // apply initial relaxation to primary space
499  Teuchos::TimeMonitor timeMon (*timer1);
500  Tpetra::Details::residual(*A_,Y,X,*cachedResidual1_);
501  cachedSolution1_->putScalar (ZERO);
502  ifpack2_prec1_->apply (*cachedResidual1_, *cachedSolution1_);
503  Y.update (ONE, *cachedSolution1_, ONE);
504  }
505 
506 
507 
508  {
509  // project to auxiliary space and smooth
510  Teuchos::TimeMonitor timeMon (*timer2);
511  Tpetra::Details::residual(*A_,Y,X,*cachedResidual1_);
512 #ifdef IFPACK2_DEBUG_SMOOTHER
513  if (!mypid) printf(" After smoothing on edges\n");
514  Y.norm2(ttt());
515  if (!mypid) printf("\t||x|| = %15.10e\n", ttt[0]);
516  cachedResidual1_->norm2(ttt());
517  if (!mypid) printf("\t||res|| = %15.10e\n", ttt[0]);
518 #endif
519 
520 
521 
522  if (!Pt_.is_null())
523  Pt_->apply (*cachedResidual1_, *cachedResidual2_, Teuchos::NO_TRANS);
524  else
525  P_->apply (*cachedResidual1_, *cachedResidual2_, Teuchos::TRANS);
526  cachedSolution2_->putScalar (ZERO);
527 
528 #ifdef IFPACK2_DEBUG_SMOOTHER
529  if (!mypid)printf(" Before smoothing on nodes\n");
530  cachedSolution2_->norm2(ttt());
531  if (!mypid)printf("\t||x_nodal|| = %15.10e\n",ttt[0]);
532  cachedResidual2_->norm2(ttt());
533  if (!mypid)printf("\t||rhs_nodal|| = %15.10e\n", ttt[0]);
534  {
535  auto An = ifpack2_prec2_->getMatrix();
536  double normA = An->getFrobeniusNorm();
537  if (!mypid) printf("\t||An|| = %15.10e\n", normA);
538  Tpetra::Vector<typename MatrixType::scalar_type,
539  typename MatrixType::local_ordinal_type,
540  typename MatrixType::global_ordinal_type,
541  typename MatrixType::node_type> d(An->getRowMap());
542  An->getLocalDiagCopy(d);
543  d.norm2(ttt);
544  if (!mypid) printf("\t||diag(An)|| = %15.10e\n", ttt[0]);
545  }
546 
547 #endif
548 
549  ifpack2_prec2_->apply (*cachedResidual2_, *cachedSolution2_);
550 
551 #ifdef IFPACK2_DEBUG_SMOOTHER
552  if (!mypid)printf(" After smoothing on nodes\n");
553  cachedSolution2_->norm2(ttt());
554  if (!mypid)printf("\t||x_nodal|| = %15.10e\n",ttt[0]);
555  cachedResidual2_->norm2(ttt());
556  if (!mypid)printf("\t||rhs_nodal|| = %15.10e\n", ttt[0]);
557 #endif
558 
559 
560  P_->apply (*cachedSolution2_, Y, Teuchos::NO_TRANS, ONE, ONE);
561  }
562 
563  if (preOrPost_ == "post" || preOrPost_ == "both") {
564  // smooth again on primary space
565  Teuchos::TimeMonitor timeMon (*timer1);
566  Tpetra::Details::residual(*A_,Y,X,*cachedResidual1_);
567  cachedSolution1_->putScalar (ZERO);
568  ifpack2_prec1_->apply (*cachedResidual1_, *cachedSolution1_);
569  Y.update (ONE, *cachedSolution1_, ONE);
570  }
571 
572 #ifdef IFPACK2_DEBUG_SMOOTHER
573  if (!mypid)printf(" After updating edge solution\n");
574  Y.norm2(ttt());
575  if (!mypid)printf("\t||x|| = %15.10e\n",ttt[0]);
576  if (!mypid)printf("--------------------------------\n");
577 #endif
578 
579 
580 }
581 
582 template <class MatrixType>
584 {
585  std::ostringstream os;
586 
587  // Output is a valid YAML dictionary in flow style. If you don't
588  // like everything on a single line, you should call describe()
589  // instead.
590  os << "\"Ifpack2::Hiptmair\": {";
591  if (this->getObjectLabel () != "") {
592  os << "Label: \"" << this->getObjectLabel () << "\", ";
593  }
594  os << "Initialized: " << (isInitialized () ? "true" : "false") << ", "
595  << "Computed: " << (isComputed () ? "true" : "false") << ", ";
596 
597  if (A_.is_null ()) {
598  os << "Matrix: null, ";
599  }
600  else {
601  os << "Matrix: not null"
602  << ", Global matrix dimensions: ["
603  << A_->getGlobalNumRows () << ", " << A_->getGlobalNumCols () << "], ";
604  }
605 
606  os << "Smoother 1: ";
607  os << ifpack2_prec1_->description() << ", ";
608  os << "Smoother 2: ";
609  os << ifpack2_prec2_->description();
610 
611  os << "}";
612  return os.str ();
613 }
614 
615 
616 template <class MatrixType>
618 describe (Teuchos::FancyOStream &out,
619  const Teuchos::EVerbosityLevel verbLevel) const
620 {
621  using std::endl;
622  using std::setw;
623  using Teuchos::VERB_DEFAULT;
624  using Teuchos::VERB_NONE;
625  using Teuchos::VERB_LOW;
626  using Teuchos::VERB_MEDIUM;
627  using Teuchos::VERB_HIGH;
628  using Teuchos::VERB_EXTREME;
629 
630  const Teuchos::EVerbosityLevel vl =
631  (verbLevel == VERB_DEFAULT) ? VERB_LOW : verbLevel;
632 
633  if (vl != VERB_NONE) {
634  // describe() always starts with a tab by convention.
635  Teuchos::OSTab tab0 (out);
636  out << "\"Ifpack2::Hiptmair\":";
637 
638  Teuchos::OSTab tab1 (out);
639  if (this->getObjectLabel () != "") {
640  out << "Label: " << this->getObjectLabel () << endl;
641  }
642  out << "Initialized: " << (isInitialized () ? "true" : "false") << endl
643  << "Computed: " << (isComputed () ? "true" : "false") << endl
644  << "Global number of rows: " << A_->getGlobalNumRows () << endl
645  << "Global number of columns: " << A_->getGlobalNumCols () << endl
646  << "Matrix:";
647  if (A_.is_null ()) {
648  out << " null" << endl;
649  } else {
650  A_->describe (out, vl);
651  }
652  out << "Smoother 1: ";
653  ifpack2_prec1_->describe(out, vl);
654  out << "Smoother 2: ";
655  ifpack2_prec2_->describe(out, vl);
656  }
657 }
658 
659 } // namespace Ifpack2
660 
661 #define IFPACK2_HIPTMAIR_INSTANT(S,LO,GO,N) \
662  template class Ifpack2::Hiptmair< Tpetra::RowMatrix<S, LO, GO, N> >;
663 
664 #endif /* IFPACK2_HIPTMAIR_DEF_HPP */
void initialize()
Do any initialization that depends on the input matrix&#39;s structure.
Definition: Ifpack2_Hiptmair_def.hpp:257
int getNumInitialize() const
Returns the number of calls to Initialize().
Definition: Ifpack2_Hiptmair_def.hpp:221
double getComputeTime() const
Returns the time spent in Compute().
Definition: Ifpack2_Hiptmair_def.hpp:245
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&#39;ll get the rest off the parameter list) ...
Definition: Ifpack2_Hiptmair_def.hpp:90
double getApplyTime() const
Returns the time spent in apply().
Definition: Ifpack2_Hiptmair_def.hpp:251
MatrixType::scalar_type scalar_type
The type of the entries of the input MatrixType.
Definition: Ifpack2_Hiptmair_decl.hpp:82
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
int getNumCompute() const
Returns the number of calls to Compute().
Definition: Ifpack2_Hiptmair_def.hpp:227
void setParameters(const Teuchos::ParameterList &params)
Set the preconditioner&#39;s parameters.
Definition: Ifpack2_Hiptmair_def.hpp:117
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
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:417
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
MatrixType::global_ordinal_type global_ordinal_type
The type of global indices in the input MatrixType.
Definition: Ifpack2_Hiptmair_decl.hpp:88
Wrapper for Hiptmair smoothers.
Definition: Ifpack2_Hiptmair_decl.hpp:71
MatrixType::node_type node_type
The Node type used by the input MatrixType.
Definition: Ifpack2_Hiptmair_decl.hpp:91
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:618
void compute()
Do any initialization that depends on the input matrix&#39;s values.
Definition: Ifpack2_Hiptmair_def.hpp:300
virtual ~Hiptmair()
Destructor.
Definition: Ifpack2_Hiptmair_def.hpp:114
double getInitializeTime() const
Returns the time spent in Initialize().
Definition: Ifpack2_Hiptmair_def.hpp:239
std::string description() const
Return a simple one-line description of this object.
Definition: Ifpack2_Hiptmair_def.hpp:583
bool hasTransposeApply() const
Whether this object&#39;s apply() method can apply the transpose (or conjugate transpose, if applicable).
Definition: Ifpack2_Hiptmair_def.hpp:213
int getNumApply() const
Returns the number of calls to apply().
Definition: Ifpack2_Hiptmair_def.hpp:233
"Factory" for creating single-level preconditioners.
Definition: Ifpack2_Details_OneLevelFactory_decl.hpp:124
Preconditioners and smoothers for Tpetra sparse matrices.
Definition: Ifpack2_AdditiveSchwarz_decl.hpp:74
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:84
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Returns the operator&#39;s communicator.
Definition: Ifpack2_Hiptmair_def.hpp:172
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:343