Ifpack2 Templated Preconditioning Package Version 1.0
Loading...
Searching...
No Matches
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
56namespace Ifpack2 {
57
58template <class MatrixType>
60Hiptmair (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
88template <class MatrixType>
90Hiptmair (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
113template <class MatrixType>
115
116template <class MatrixType>
117void 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
170template <class MatrixType>
171Teuchos::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
181template <class MatrixType>
182Teuchos::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
188template <class MatrixType>
189Teuchos::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
200template <class MatrixType>
201Teuchos::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
212template <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
220template <class MatrixType>
222 return NumInitialize_;
223}
224
225
226template <class MatrixType>
228 return NumCompute_;
229}
230
231
232template <class MatrixType>
234 return NumApply_;
235}
236
237
238template <class MatrixType>
240 return InitializeTime_;
241}
242
243
244template <class MatrixType>
246 return ComputeTime_;
247}
248
249
250template <class MatrixType>
252 return ApplyTime_;
253}
254
255
256template <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
299template <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
341template <class MatrixType>
343apply (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
414template<class MatrixType>
415void
417updateCachedMultiVectors (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
442template <class MatrixType>
444applyHiptmairSmoother(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
582template <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
616template <class MatrixType>
618describe (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 */
"Factory" for creating single-level preconditioners.
Definition: Ifpack2_Details_OneLevelFactory_decl.hpp:124
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
Wrapper for Hiptmair smoothers.
Definition: Ifpack2_Hiptmair_decl.hpp:76
void initialize()
Do any initialization that depends on the input matrix's structure.
Definition: Ifpack2_Hiptmair_def.hpp:257
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
int getNumCompute() const
Returns the number of calls to Compute().
Definition: Ifpack2_Hiptmair_def.hpp:227
void compute()
Do any initialization that depends on the input matrix's values.
Definition: Ifpack2_Hiptmair_def.hpp:300
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
MatrixType::local_ordinal_type local_ordinal_type
The type of local indices in the input MatrixType.
Definition: Ifpack2_Hiptmair_decl.hpp:85
std::string description() const
Return a simple one-line description of this object.
Definition: Ifpack2_Hiptmair_def.hpp:583
double getApplyTime() const
Returns the time spent in apply().
Definition: Ifpack2_Hiptmair_def.hpp:251
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
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
MatrixType::scalar_type scalar_type
The type of the entries of the input MatrixType.
Definition: Ifpack2_Hiptmair_decl.hpp:82
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
int getNumInitialize() const
Returns the number of calls to Initialize().
Definition: Ifpack2_Hiptmair_def.hpp:221
int getNumApply() const
Returns the number of calls to apply().
Definition: Ifpack2_Hiptmair_def.hpp:233
virtual ~Hiptmair()
Destructor.
Definition: Ifpack2_Hiptmair_def.hpp:114
void setParameters(const Teuchos::ParameterList &params)
Set the preconditioner's parameters.
Definition: Ifpack2_Hiptmair_def.hpp:117
MatrixType::node_type node_type
The Node type used by the input MatrixType.
Definition: Ifpack2_Hiptmair_decl.hpp:91
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
double getInitializeTime() const
Returns the time spent in Initialize().
Definition: Ifpack2_Hiptmair_def.hpp:239
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Returns the operator's communicator.
Definition: Ifpack2_Hiptmair_def.hpp:172
MatrixType::global_ordinal_type global_ordinal_type
The type of global indices in the input MatrixType.
Definition: Ifpack2_Hiptmair_decl.hpp:88
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
double getComputeTime() const
Returns the time spent in Compute().
Definition: Ifpack2_Hiptmair_def.hpp:245
bool hasTransposeApply() const
Whether this object's apply() method can apply the transpose (or conjugate transpose,...
Definition: Ifpack2_Hiptmair_def.hpp:213
Preconditioners and smoothers for Tpetra sparse matrices.
Definition: Ifpack2_AdditiveSchwarz_decl.hpp:74