Ifpack2 Templated Preconditioning Package  Version 1.0
Ifpack2_BlockRelaxation_def.hpp
1 /*@HEADER
2 // ***********************************************************************
3 //
4 // Ifpack2: Tempated 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_BLOCKRELAXATION_DEF_HPP
44 #define IFPACK2_BLOCKRELAXATION_DEF_HPP
45 
47 #include "Ifpack2_LinearPartitioner.hpp"
48 #include "Ifpack2_LinePartitioner.hpp"
50 #include "Ifpack2_Details_UserPartitioner_def.hpp"
51 #include <Ifpack2_Parameters.hpp>
52 
53 namespace Ifpack2 {
54 
55 template<class MatrixType,class ContainerType>
57 setMatrix (const Teuchos::RCP<const row_matrix_type>& A)
58 {
59  if (A.getRawPtr () != A_.getRawPtr ()) { // it's a different matrix
60  IsInitialized_ = false;
61  IsComputed_ = false;
62  Partitioner_ = Teuchos::null;
63  Importer_ = Teuchos::null;
64  W_ = Teuchos::null;
65 
66  if (! A.is_null ()) {
67  IsParallel_ = (A->getRowMap ()->getComm ()->getSize () > 1);
68  }
69 
70  std::vector<Teuchos::RCP<ContainerType> > emptyVec;
71  std::swap (Containers_, emptyVec);
72  NumLocalBlocks_ = 0;
73 
74  A_ = A;
75  }
76 }
77 
78 template<class MatrixType,class ContainerType>
80 BlockRelaxation (const Teuchos::RCP<const row_matrix_type>& A)
81 : A_ (A),
82  Time_ (Teuchos::rcp (new Teuchos::Time ("Ifpack2::BlockRelaxation"))),
83  OverlapLevel_ (0),
84  PartitionerType_ ("linear"),
85  NumSweeps_ (1),
86  NumLocalBlocks_(0),
87  PrecType_ (Ifpack2::Details::JACOBI),
88  DampingFactor_ (STS::one ()),
89  IsParallel_ (false),
90  ZeroStartingSolution_ (true),
91  DoBackwardGS_ (false),
92  IsInitialized_ (false),
93  IsComputed_ (false),
94  NumInitialize_ (0),
95  NumCompute_ (0),
96  NumApply_ (0),
97  InitializeTime_ (0.0),
98  ComputeTime_ (0.0),
99  ApplyTime_ (0.0),
100  ComputeFlops_ (0.0),
101  ApplyFlops_ (0.0),
102  NumMyRows_ (0),
103  NumGlobalRows_ (0),
104  NumGlobalNonzeros_ (0)
105 {
106  TEUCHOS_TEST_FOR_EXCEPTION(
107  A_.is_null (), std::invalid_argument,
108  Teuchos::typeName(*this) << "::BlockRelaxation(): input matrix is null.");
109 }
110 
111 //==========================================================================
112 template<class MatrixType,class ContainerType>
114 
115 //==========================================================================
116 template<class MatrixType,class ContainerType>
117 void
119 setParameters (const Teuchos::ParameterList& List)
120 {
121  Teuchos::ParameterList validparams;
122  Ifpack2::getValidParameters (validparams);
123  List.validateParameters (validparams);
124 
125  std::string PT;
126  if (PrecType_ == Ifpack2::Details::JACOBI) {
127  PT = "Jacobi";
128  } else if (PrecType_ == Ifpack2::Details::GS) {
129  PT = "Gauss-Seidel";
130  } else if (PrecType_ == Ifpack2::Details::SGS) {
131  PT = "Symmetric Gauss-Seidel";
132  }
133 
134  Ifpack2::getParameter (List, "relaxation: type", PT);
135 
136  if (PT == "Jacobi") {
137  PrecType_ = Ifpack2::Details::JACOBI;
138  }
139  else if (PT == "Gauss-Seidel") {
140  PrecType_ = Ifpack2::Details::GS;
141  }
142  else if (PT == "Symmetric Gauss-Seidel") {
143  PrecType_ = Ifpack2::Details::SGS;
144  }
145  else {
146  TEUCHOS_TEST_FOR_EXCEPTION(
147  true, std::invalid_argument, "Ifpack2::BlockRelaxation::setParameters: "
148  "Invalid parameter value \"" << PT << "\" for parameter \"relaxation: type\".");
149  }
150 
151  Ifpack2::getParameter (List, "relaxation: sweeps",NumSweeps_);
152  Ifpack2::getParameter (List, "relaxation: damping factor", DampingFactor_);
153  Ifpack2::getParameter (List, "relaxation: zero starting solution", ZeroStartingSolution_);
154  Ifpack2::getParameter (List, "relaxation: backward mode",DoBackwardGS_);
155  Ifpack2::getParameter (List, "partitioner: type",PartitionerType_);
156  Ifpack2::getParameter (List, "partitioner: local parts",NumLocalBlocks_);
157  Ifpack2::getParameter (List, "partitioner: overlap",OverlapLevel_);
158 
159  // check parameters
160  if (PrecType_ != Ifpack2::Details::JACOBI) {
161  OverlapLevel_ = 0;
162  }
163  if (NumLocalBlocks_ < 0) {
164  NumLocalBlocks_ = A_->getNodeNumRows() / (-NumLocalBlocks_);
165  }
166  // other checks are performed in Partitioner_
167 
168  // NTS: Sanity check to be removed at a later date when Backward mode is enabled
169  TEUCHOS_TEST_FOR_EXCEPTION(
170  DoBackwardGS_, std::runtime_error,
171  "Ifpack2::BlockRelaxation:setParameters: \"relaxation: backward mode\" == "
172  "true is not supported yet.");
173 
174  // copy the list as each subblock's constructor will
175  // require it later
176  List_ = List;
177 }
178 
179 //==========================================================================
180 template<class MatrixType,class ContainerType>
181 Teuchos::RCP<const Teuchos::Comm<int> >
183  return A_->getComm();
184 }
185 
186 //==========================================================================
187 template<class MatrixType,class ContainerType>
188 Teuchos::RCP<const Tpetra::RowMatrix<typename MatrixType::scalar_type,
189  typename MatrixType::local_ordinal_type,
190  typename MatrixType::global_ordinal_type,
191  typename MatrixType::node_type> >
193  return(A_);
194 }
195 
196 //==========================================================================
197 template<class MatrixType,class ContainerType>
198 Teuchos::RCP<const Tpetra::Map<typename MatrixType::local_ordinal_type,
199  typename MatrixType::global_ordinal_type,
200  typename MatrixType::node_type> >
202  return A_->getDomainMap();
203 }
204 
205 //==========================================================================
206 template<class MatrixType,class ContainerType>
207 Teuchos::RCP<const Tpetra::Map<typename MatrixType::local_ordinal_type,
208  typename MatrixType::global_ordinal_type,
209  typename MatrixType::node_type> >
211  return A_->getRangeMap();
212 }
213 
214 //==========================================================================
215 template<class MatrixType,class ContainerType>
217  return true;
218 }
219 
220 //==========================================================================
221 template<class MatrixType,class ContainerType>
223  return(NumInitialize_);
224 }
225 
226 //==========================================================================
227 template<class MatrixType,class ContainerType>
229  return(NumCompute_);
230 }
231 
232 //==========================================================================
233 template<class MatrixType,class ContainerType>
235  return(NumApply_);
236 }
237 
238 //==========================================================================
239 template<class MatrixType,class ContainerType>
241  return(InitializeTime_);
242 }
243 
244 //==========================================================================
245 template<class MatrixType,class ContainerType>
247  return(ComputeTime_);
248 }
249 
250 //==========================================================================
251 template<class MatrixType,class ContainerType>
253  return(ApplyTime_);
254 }
255 
256 //==========================================================================
257 template<class MatrixType,class ContainerType>
259  return(ComputeFlops_);
260 }
261 
262 //==========================================================================
263 template<class MatrixType,class ContainerType>
265  return ApplyFlops_;
266 }
267 
268 //==========================================================================
269 template<class MatrixType,class ContainerType>
270 void
272 apply (const Tpetra::MultiVector<typename MatrixType::scalar_type,
273  typename MatrixType::local_ordinal_type,
274  typename MatrixType::global_ordinal_type,
275  typename MatrixType::node_type>& X,
276  Tpetra::MultiVector<typename MatrixType::scalar_type,
277  typename MatrixType::local_ordinal_type,
278  typename MatrixType::global_ordinal_type,
279  typename MatrixType::node_type>& Y,
280  Teuchos::ETransp mode,
281  scalar_type alpha,
282  scalar_type beta) const
283 {
284  TEUCHOS_TEST_FOR_EXCEPTION(
285  ! isComputed (), std::runtime_error, "Ifpack2::BlockRelaxation::apply: "
286  "isComputed() must be true prior to calling apply.");
287  TEUCHOS_TEST_FOR_EXCEPTION(
288  X.getNumVectors () != Y.getNumVectors (), std::invalid_argument,
289  "Ifpack2::BlockRelaxation::apply: X.getNumVectors() = "
290  << X.getNumVectors () << " != Y.getNumVectors() = "
291  << Y.getNumVectors () << ".");
292  TEUCHOS_TEST_FOR_EXCEPTION(
293  mode != Teuchos::NO_TRANS, std::logic_error, "Ifpack2::BlockRelaxation::"
294  "apply: This method currently only implements the case mode == Teuchos::"
295  "NO_TRANS. Transposed modes are not currently supported.");
296  TEUCHOS_TEST_FOR_EXCEPTION(
297  alpha != Teuchos::ScalarTraits<scalar_type>::one (), std::logic_error,
298  "Ifpack2::BlockRelaxation::apply: This method currently only implements "
299  "the case alpha == 1. You specified alpha = " << alpha << ".");
300  TEUCHOS_TEST_FOR_EXCEPTION(
301  beta != Teuchos::ScalarTraits<scalar_type>::zero (), std::logic_error,
302  "Ifpack2::BlockRelaxation::apply: This method currently only implements "
303  "the case beta == 0. You specified beta = " << beta << ".");
304 
305  Time_->start(true);
306 
307  // If X and Y are pointing to the same memory location,
308  // we need to create an auxiliary vector, Xcopy
309  Teuchos::RCP<const MV> X_copy;
310  {
311  auto X_lcl_host = X.template getLocalView<Kokkos::HostSpace> ();
312  auto Y_lcl_host = Y.template getLocalView<Kokkos::HostSpace> ();
313  if (X_lcl_host.ptr_on_device () == Y_lcl_host.ptr_on_device ()) {
314  X_copy = rcp (new MV (X, Teuchos::Copy));
315  } else {
316  X_copy = rcpFromRef (X);
317  }
318  }
319 
320  if (ZeroStartingSolution_) {
321  Y.putScalar (STS::zero ());
322  }
323 
324  // Flops are updated in each of the following.
325  switch (PrecType_) {
326  case Ifpack2::Details::JACOBI:
327  ApplyInverseJacobi(*X_copy,Y);
328  break;
329  case Ifpack2::Details::GS:
330  ApplyInverseGS(*X_copy,Y);
331  break;
332  case Ifpack2::Details::SGS:
333  ApplyInverseSGS(*X_copy,Y);
334  break;
335  default:
336  throw std::runtime_error("Ifpack2::BlockRelaxation::apply internal logic error.");
337  }
338 
339  ++NumApply_;
340  Time_->stop();
341  ApplyTime_ += Time_->totalElapsedTime();
342 }
343 
344 //==========================================================================
345 template<class MatrixType,class ContainerType>
347  const Tpetra::MultiVector<typename MatrixType::scalar_type,
348  typename MatrixType::local_ordinal_type,
349  typename MatrixType::global_ordinal_type,
350  typename MatrixType::node_type>& X,
351  Tpetra::MultiVector<typename MatrixType::scalar_type,
352  typename MatrixType::local_ordinal_type,
353  typename MatrixType::global_ordinal_type,
354  typename MatrixType::node_type>& Y,
355  Teuchos::ETransp mode) const
356 {
357  TEUCHOS_TEST_FOR_EXCEPTION(isComputed() == false, std::runtime_error,
358  "Ifpack2::BlockRelaxation::applyMat() ERROR: isComputed() must be true prior to calling applyMat().");
359  TEUCHOS_TEST_FOR_EXCEPTION(X.getNumVectors() != Y.getNumVectors(), std::runtime_error,
360  "Ifpack2::BlockRelaxation::applyMat() ERROR: X.getNumVectors() != Y.getNumVectors().");
361  A_->apply (X, Y, mode);
362 }
363 
364 //==========================================================================
365 template<class MatrixType,class ContainerType>
367  using Teuchos::rcp;
368  typedef Tpetra::RowGraph<local_ordinal_type, global_ordinal_type, node_type>
369  row_graph_type;
370 
371  IsInitialized_ = false;
372  Time_->start (true);
373 
374  NumMyRows_ = A_->getNodeNumRows ();
375  NumGlobalRows_ = A_->getGlobalNumRows ();
376  NumGlobalNonzeros_ = A_->getGlobalNumEntries ();
377 
378  // NTS: Will need to add support for Zoltan2 partitions later Also,
379  // will need a better way of handling the Graph typing issue.
380  // Especially with ordinal types w.r.t the container.
381 
382  if (PartitionerType_ == "linear") {
383  Partitioner_ =
384  rcp (new Ifpack2::LinearPartitioner<row_graph_type> (A_->getGraph ()));
385  } else if (PartitionerType_ == "line") {
386  Partitioner_ =
388  } else if (PartitionerType_ == "user") {
389  Partitioner_ =
390  rcp (new Ifpack2::Details::UserPartitioner<row_graph_type> (A_->getGraph () ) );
391  } else {
392  // We should have checked for this in setParameters(), so it's a
393  // logic_error, not an invalid_argument or runtime_error.
394  TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error,
395  "Ifpack2::BlockRelaxation::initialize, invalid partitioner type.");
396  }
397 
398  // need to partition the graph of A
399  Partitioner_->setParameters (List_);
400  Partitioner_->compute ();
401 
402  // get actual number of partitions
403  NumLocalBlocks_ = Partitioner_->numLocalParts ();
404 
405  // Note: Unlike Ifpack, we'll punt on computing W_ until compute(), which is where
406  // we assume that the type of relaxation has been chosen.
407 
408  if (A_->getComm()->getSize() != 1) {
409  IsParallel_ = true;
410  } else {
411  IsParallel_ = false;
412  }
413 
414  ++NumInitialize_;
415  Time_->stop ();
416  InitializeTime_ += Time_->totalElapsedTime ();
417  IsInitialized_ = true;
418 }
419 
420 //==========================================================================
421 template<class MatrixType,class ContainerType>
423 {
424  using Teuchos::rcp;
425  typedef Tpetra::Vector<scalar_type,
427  typedef Tpetra::Import<local_ordinal_type,
428  global_ordinal_type, node_type> import_type;
429 
430  // We should have checked for this in setParameters(), so it's a
431  // logic_error, not an invalid_argument or runtime_error.
432  TEUCHOS_TEST_FOR_EXCEPTION(NumSweeps_ < 0, std::logic_error,
433  "Ifpack2::BlockRelaxation::compute, NumSweeps_ must be >= 0");
434 
435  if (! isInitialized ()) {
436  initialize ();
437  }
438  Time_->start (true);
439 
440  // reset values
441  IsComputed_ = false;
442 
443  // Extract the submatrices
444  ExtractSubmatrices ();
445 
446  // Compute the weight vector if we're doing overlapped Jacobi (and
447  // only if we're doing overlapped Jacobi).
448  if (PrecType_ == Ifpack2::Details::JACOBI && OverlapLevel_ > 0) {
449  // weight of each vertex
450  W_ = rcp (new vector_type (A_->getRowMap ()));
451  W_->putScalar (STS::zero ());
452  Teuchos::ArrayRCP<scalar_type > w_ptr = W_->getDataNonConst(0);
453 
454  for (local_ordinal_type i = 0 ; i < NumLocalBlocks_ ; ++i) {
455  for (size_t j = 0 ; j < Partitioner_->numRowsInPart(i) ; ++j) {
456  // FIXME (mfh 12 Sep 2014) Should this really be int?
457  // Perhaps it should be local_ordinal_type instead.
458  int LID = (*Partitioner_)(i,j);
459  w_ptr[LID]+= STS::one();
460  }
461  }
462  W_->reciprocal (*W_);
463  }
464 
465  // We need to import data from external processors. Here I create a
466  // Tpetra::Import object if needed (stealing from A_ if possible)
467  // Marzio's comment:
468  // Note that I am doing some strange stuff to set the components of Y
469  // from Y2 (to save some time).
470  //
471  if (IsParallel_ && (PrecType_ == Ifpack2::Details::GS ||
472  PrecType_ == Ifpack2::Details::SGS)) {
473  Importer_ = A_->getGraph ()->getImporter ();
474  if (Importer_.is_null ()) {
475  Importer_ = rcp (new import_type (A_->getDomainMap (), A_->getColMap ()));
476  }
477  }
478 
479  ++NumCompute_;
480  Time_->stop ();
481  ComputeTime_ += Time_->totalElapsedTime();
482  IsComputed_ = true;
483 }
484 
485 //==============================================================================
486 template<class MatrixType,class ContainerType>
488 {
489  typedef Tpetra::Vector<scalar_type, local_ordinal_type,
490  global_ordinal_type, node_type> vec_type;
491  TEUCHOS_TEST_FOR_EXCEPTION(
492  Partitioner_.is_null (), std::runtime_error,
493  "Ifpack2::BlockRelaxation::ExtractSubmatrices: Partitioner object is null.");
494 
495  NumLocalBlocks_ = Partitioner_->numLocalParts ();
496  Containers_.resize (NumLocalBlocks_);
497  vec_type D (A_->getRowMap ());
498  A_->getLocalDiagCopy (D);
499  DiagRCP = D.getData ();
500 
501  for (local_ordinal_type i = 0; i < NumLocalBlocks_; ++i) {
502  const size_t numRows = Partitioner_->numRowsInPart (i);
503 
504  // Extract a list of the indices of each partitioner row.
505  Teuchos::Array<local_ordinal_type> localRows (numRows);
506  for (size_t j = 0; j < numRows; ++j) {
507  localRows[j] = (*Partitioner_) (i,j);
508  }
509  if(numRows>1) { // only do for non-singletons
510  Containers_[i] = Teuchos::rcp (new ContainerType (A_, localRows ()));
511  Containers_[i]->setParameters (List_);
512  Containers_[i]->initialize ();
513  Containers_[i]->compute ();
514  }
515  }
516 }
517 
518 
519 
520 //==========================================================================
521 template<class MatrixType,class ContainerType>
523 {
524  const size_t NumVectors = X.getNumVectors ();
525  MV AY (Y.getMap (), NumVectors);
526 
527  // Initial matvec not needed
528  int starting_iteration = 0;
529  if (ZeroStartingSolution_) {
530  DoJacobi (X, Y);
531  starting_iteration = 1;
532  }
533 
534  const scalar_type ONE = STS::one ();
535  for (int j = starting_iteration; j < NumSweeps_; ++j) {
536  applyMat (Y, AY);
537  AY.update (ONE, X, -ONE);
538  DoJacobi (AY, Y);
539 
540  // Flops for matrix apply & update
541  ApplyFlops_ += NumVectors * (2 * NumGlobalNonzeros_ + 2 * NumGlobalRows_);
542  }
543 
544 }
545 
546 
547 //==========================================================================
548 template<class MatrixType,class ContainerType>
549 void BlockRelaxation<MatrixType,ContainerType>::DoJacobi(const MV& X, MV& Y) const
550 {
551  const size_t NumVectors = X.getNumVectors ();
552  const scalar_type one = STS::one ();
553  // Note: Flop counts copied naively from Ifpack.
554 
555  if (OverlapLevel_ == 0) {
556  // Non-overlapping Jacobi
557  for (local_ordinal_type i = 0; i < NumLocalBlocks_; ++i) {
558  // may happen that a partition is empty
559  if( Partitioner_->numRowsInPart (i) != 1 ) {
560  if(Containers_[i]->getNumRows () == 0 ) continue;
561  Containers_[i]->apply (X, Y, Teuchos::NO_TRANS, DampingFactor_, one);
562  ApplyFlops_ += NumVectors * 2 * NumGlobalRows_;
563  }
564  else { // singleton, can't access Containers_[i] as it was never filled and may be null.
565  local_ordinal_type LRID = (*Partitioner_)(i,0); // by definition, a singleton 1 row in block.
566  Teuchos::ArrayView< const scalar_type > Diag = DiagRCP();
567  scalar_type d = Diag[LRID];
568  for(unsigned int nv = 0;nv < NumVectors ; ++nv ) {
569  Teuchos::ArrayRCP< const scalar_type > xRCP = X.getData(nv);
570  scalar_type x = xRCP[LRID];
571  Teuchos::ArrayRCP< scalar_type > yRCP = Y.getDataNonConst(nv);
572 
573  scalar_type newy= x/d;
574  yRCP[LRID]= newy;
575  }
576  }
577  }
578  }
579  else {
580  // Overlapping Jacobi
581  for (local_ordinal_type i = 0 ; i < NumLocalBlocks_ ; i++) {
582  // may happen that a partition is empty
583  if(Containers_[i]->getNumRows() == 0) continue;
584  if ( Partitioner_->numRowsInPart (i) != 1 ) {
585  try {
586  Containers_[i]->weightedApply(X,Y,*W_,Teuchos::NO_TRANS,DampingFactor_,one);
587  } catch (std::exception& e) {
588  std::cerr << "BlockRelaxation::DoJacobi: Containers_[" << i
589  << "]->weightedApply() threw an exception: " << e.what ()
590  << std::endl;
591  throw;
592  }
593  } // end Partitioner_->numRowsInPart (i) != 1
594 
595  // NOTE: do not count (for simplicity) the flops due to overlapping rows
596  ApplyFlops_ += NumVectors * 4 * NumGlobalRows_;
597  }
598  }
599 }
600 
601 //==========================================================================
602 template<class MatrixType,class ContainerType>
604 ApplyInverseGS (const MV& X, MV& Y) const
605 {
606  MV Xcopy (X, Teuchos::Copy);
607  for (int j = 0; j < NumSweeps_; ++j) {
608  DoGaussSeidel (Xcopy, Y);
609  if (j != NumSweeps_ - 1) {
610  Tpetra::deep_copy (Xcopy, X);
611  }
612  }
613 }
614 
615 
616 //==============================================================================
617 template<class MatrixType,class ContainerType>
619 DoGaussSeidel (MV& X, MV& Y) const
620 {
621  using Teuchos::Array;
622  using Teuchos::ArrayRCP;
623  using Teuchos::ArrayView;
624  using Teuchos::RCP;
625  using Teuchos::rcp;
626  using Teuchos::rcpFromRef;
627 
628  // Note: Flop counts copied naively from Ifpack.
629 
630  const scalar_type one = STS::one ();
631  const size_t Length = A_->getNodeMaxNumRowEntries();
632  const size_t NumVectors = X.getNumVectors();
633  Array<scalar_type> Values;
634  Array<local_ordinal_type> Indices;
635  Values.resize (Length);
636  Indices.resize (Length);
637 
638  // an additonal vector is needed by parallel computations
639  // (note that applications through Ifpack2_AdditiveSchwarz
640  // are always seen are serial)
641  RCP<MV> Y2;
642  if (IsParallel_) {
643  Y2 = rcp (new MV (Importer_->getTargetMap (), NumVectors));
644  } else {
645  Y2 = rcpFromRef (Y);
646  }
647 
648  // I think I decided I need two extra vectors:
649  // One to store the sum of the corrections (initialized to zero)
650  // One to store the temporary residual (doesn't matter if it is zeroed or not)
651  // My apologies for making the names clear and meaningful. (X=RHS, Y=guess?! Nice.)
652  MV Residual (X.getMap (), NumVectors, false);
653 
654  ArrayRCP<ArrayRCP<scalar_type> > x_ptr = X.get2dViewNonConst();
655  ArrayRCP<ArrayRCP<scalar_type> > y_ptr = Y.get2dViewNonConst();
656  ArrayRCP<ArrayRCP<scalar_type> > y2_ptr = Y2->get2dViewNonConst();
657  ArrayRCP<ArrayRCP<scalar_type> > residual_ptr = Residual.get2dViewNonConst();
658 
659  // data exchange is here, once per sweep
660  if (IsParallel_) Y2->doImport(Y,*Importer_,Tpetra::INSERT);
661 
662  for (local_ordinal_type i = 0; i < NumLocalBlocks_; ++i) {
663  if( Partitioner_->numRowsInPart (i) != 1 ) {
664  if (Containers_[i]->getNumRows () == 0) continue;
665  // update from previous block
666  ArrayView<const local_ordinal_type> localRows =
667  Containers_[i]->getLocalRows ();
668  const size_t localNumRows = Containers_[i]->getNumRows ();
669  for (size_t j = 0; j < localNumRows; ++j) {
670  const local_ordinal_type LID = localRows[j]; // Containers_[i]->ID (j);
671  size_t NumEntries;
672  A_->getLocalRowCopy (LID, Indices (), Values (), NumEntries);
673 
674  for (size_t m = 0; m < NumVectors; ++m) {
675  ArrayView<const scalar_type> x_local = (x_ptr())[m]();
676  ArrayView<scalar_type> y2_local = (y2_ptr())[m]();
677  ArrayView<scalar_type> r_local = (residual_ptr())[m]();
678 
679  r_local[LID] = x_local[LID];
680  for (size_t k = 0; k < NumEntries; ++k) {
681  const local_ordinal_type col = Indices[k];
682  r_local[LID] -= Values[k] * y2_local[col];
683  }
684  }
685  }
686  // solve with this block
687  //
688  // Note: I'm abusing the ordering information, knowing that X/Y
689  // and Y2 have the same ordering for on-proc unknowns.
690  //
691  // Note: Add flop counts for inverse apply
692  Containers_[i]->apply (Residual, *Y2, Teuchos::NO_TRANS,
693  DampingFactor_,one);
694 
695  // operations for all getrow's
696  ApplyFlops_ += NumVectors * (2 * NumGlobalNonzeros_ + 2 * NumGlobalRows_);
697  }
698  else { // singleton, can't access Containers_[i] as it was never filled and may be null.
699  // a singleton calculation is exact, all residuals should be zero.
700  local_ordinal_type LRID = (*Partitioner_)(i,0); // by definition, a singleton 1 row in block.
701  Teuchos::ArrayView< const scalar_type > Diag = DiagRCP();
702  scalar_type d = Diag[LRID];
703  ArrayRCP<ArrayRCP<scalar_type> > y2_ptr2 = Y2->get2dViewNonConst();
704  for(unsigned int nv = 0;nv < NumVectors ; ++nv ) {
705  Teuchos::ArrayRCP< const scalar_type > xRCP = X.getData(nv);
706  scalar_type x = xRCP[LRID];
707  ArrayView<scalar_type> y2_local = (y2_ptr2())[nv]();
708  scalar_type newy= x/d;
709  y2_local[LRID]= newy;
710  }
711  } // end else
712  } // end for NumLocalBlocks_
713  // Attention: this is delicate... Not all combinations
714  // of Y2 and Y will always work (tough for ML it should be ok)
715  if (IsParallel_) {
716  for (size_t m = 0; m < NumVectors; ++m) {
717  ArrayView<scalar_type> y2_local = (y2_ptr())[m]();
718  ArrayView<scalar_type> y_local = (y_ptr())[m]();
719  for (size_t i = 0; i < NumMyRows_; ++i) {
720  y_local[i] = y2_local[i];
721  }
722  }
723  }
724 }
725 
726 //==========================================================================
727 template<class MatrixType,class ContainerType>
728 void
730 ApplyInverseSGS (const MV& X, MV& Y) const
731 {
732  MV Xcopy (X, Teuchos::Copy);
733  for (int j = 0; j < NumSweeps_; ++j) {
734  DoSGS (Xcopy, Y);
735  if (j != NumSweeps_ - 1) {
736  Tpetra::deep_copy (Xcopy, X);
737  }
738  }
739 }
740 
741 //==========================================================================
742 template<class MatrixType,class ContainerType>
743 void
745 {
746  using Teuchos::Array;
747  using Teuchos::ArrayRCP;
748  using Teuchos::ArrayView;
749  using Teuchos::RCP;
750  using Teuchos::rcp;
751  using Teuchos::rcpFromRef;
752 
753  const scalar_type one = STS::one ();
754  const size_t Length = A_->getNodeMaxNumRowEntries();
755  const size_t NumVectors = X.getNumVectors();
756  Array<scalar_type> Values;
757  Array<local_ordinal_type> Indices;
758  Values.resize(Length);
759  Indices.resize(Length);
760 
761  // an additonal vector is needed by parallel computations
762  // (note that applications through Ifpack2_AdditiveSchwarz
763  // are always seen are serial)
764  RCP<MV> Y2;
765  if (IsParallel_) {
766  Y2 = rcp (new MV (Importer_->getTargetMap (), NumVectors));
767  } else {
768  Y2 = rcpFromRef (Y);
769  }
770 
771  // I think I decided I need two extra vectors:
772  // One to store the sum of the corrections (initialized to zero)
773  // One to store the temporary residual (doesn't matter if it is zeroed or not)
774  // My apologies for making the names clear and meaningful. (X=RHS, Y=guess?! Nice.)
775  MV Residual (X.getMap (), NumVectors, false);
776 
777  ArrayRCP<ArrayRCP<scalar_type> > x_ptr = X.get2dViewNonConst();
778  ArrayRCP<ArrayRCP<scalar_type> > y_ptr = Y.get2dViewNonConst();
779  ArrayRCP<ArrayRCP<scalar_type> > y2_ptr = Y2->get2dViewNonConst();
780  ArrayRCP<ArrayRCP<scalar_type> > residual_ptr = Residual.get2dViewNonConst();
781 
782  // data exchange is here, once per sweep
783  if (IsParallel_) {
784  Y2->doImport (Y, *Importer_, Tpetra::INSERT);
785  }
786 
787  // Forward Sweep
788  for (local_ordinal_type i = 0; i < NumLocalBlocks_; ++i) {
789  if( Partitioner_->numRowsInPart (i) != 1 ) {
790  if (Containers_[i]->getNumRows () == 0) {
791  continue; // Skip empty partitions
792  }
793  // update from previous block
794  ArrayView<const local_ordinal_type> localRows =
795  Containers_[i]->getLocalRows ();
796  for (size_t j = 0; j < Containers_[i]->getNumRows (); ++j) {
797  const local_ordinal_type LID = localRows[j]; // Containers_[i]->ID (j);
798  size_t NumEntries;
799  A_->getLocalRowCopy (LID, Indices (), Values (), NumEntries);
800 
801  //set tmpresid = initresid - A*correction
802  for (size_t m = 0; m < NumVectors; ++m) {
803  ArrayView<const scalar_type> x_local = (x_ptr())[m]();
804  ArrayView<scalar_type> y2_local = (y2_ptr())[m]();
805  ArrayView<scalar_type> r_local = (residual_ptr())[m]();
806 
807  r_local[LID] = x_local[LID];
808  for (size_t k = 0 ; k < NumEntries ; k++) {
809  local_ordinal_type col = Indices[k];
810  r_local[LID] -= Values[k] * y2_local[col];
811  }
812  }
813  }
814  // solve with this block
815  //
816  // Note: I'm abusing the ordering information, knowing that X/Y
817  // and Y2 have the same ordering for on-proc unknowns.
818  //
819  // Note: Add flop counts for inverse apply
820  Containers_[i]->apply (Residual, *Y2, Teuchos::NO_TRANS,
821  DampingFactor_, one);
822 
823  // operations for all getrow's
824  ApplyFlops_ += NumVectors * (2 * NumGlobalNonzeros_ + 2 * NumGlobalRows_);
825 
826  }
827  else { // singleton, can't access Containers_[i] as it was never filled and may be null.
828  local_ordinal_type LRID = (*Partitioner_)(i,0); // by definition, a singleton 1 row in block.
829  Teuchos::ArrayView< const scalar_type > Diag = DiagRCP();
830  scalar_type d = Diag[LRID];
831  for(unsigned int nv = 0;nv < NumVectors ; ++nv ) {
832  Teuchos::ArrayRCP< const scalar_type > xRCP = X.getData(nv);
833  scalar_type x = xRCP[LRID];
834  Teuchos::ArrayRCP< scalar_type > yRCP = Y.getDataNonConst(nv);
835 
836  scalar_type newy= x/d;
837  yRCP[LRID]= newy;
838  }
839  } // end else
840  } // end forward sweep over NumLocalBlocks
841 
842  // Reverse Sweep
843  //
844  // mfh 12 July 2013: The unusual iteration bounds, and the use of
845  // i-1 rather than i in the loop body, ensure correctness even if
846  // local_ordinal_type is unsigned. "i = NumLocalBlocks_-1; i >= 0;
847  // i--" will loop forever if local_ordinal_type is unsigned, because
848  // unsigned integers are (trivially) always nonnegative.
849  for (local_ordinal_type i = NumLocalBlocks_; i > 0; --i) {
850  if( Partitioner_->numRowsInPart (i) != 1 ) {
851  if (Containers_[i-1]->getNumRows () == 0) continue;
852 
853  // update from previous block
854  ArrayView<const local_ordinal_type> localRows =
855  Containers_[i-1]->getLocalRows ();
856  for (size_t j = 0; j < Containers_[i-1]->getNumRows (); ++j) {
857  const local_ordinal_type LID = localRows[j]; // Containers_[i-1]->ID (j);
858  size_t NumEntries;
859  A_->getLocalRowCopy (LID, Indices (), Values (), NumEntries);
860 
861  //set tmpresid = initresid - A*correction
862  for (size_t m = 0; m < NumVectors; ++m) {
863  ArrayView<const scalar_type> x_local = (x_ptr())[m]();
864  ArrayView<scalar_type> y2_local = (y2_ptr())[m]();
865  ArrayView<scalar_type> r_local = (residual_ptr())[m]();
866 
867  r_local [LID] = x_local[LID];
868  for (size_t k = 0; k < NumEntries; ++k) {
869  local_ordinal_type col = Indices[k];
870  r_local[LID] -= Values[k] * y2_local[col];
871  }
872  }
873  }
874 
875  // solve with this block
876  //
877  // Note: I'm abusing the ordering information, knowing that X/Y
878  // and Y2 have the same ordering for on-proc unknowns.
879  //
880  // Note: Add flop counts for inverse apply
881  Containers_[i-1]->apply (Residual, *Y2, Teuchos::NO_TRANS,
882  DampingFactor_, one);
883 
884  // operations for all getrow's
885  ApplyFlops_ += NumVectors * (2 * NumGlobalNonzeros_ + 2 * NumGlobalRows_);
886  } // end Partitioner_->numRowsInPart (i) != 1 ) {
887  // else do nothing, as by definition with a singleton, the residuals are zero.
888  } //end reverse sweep
889 
890  // Attention: this is delicate... Not all combinations
891  // of Y2 and Y will always work (though for ML it should be ok)
892  if (IsParallel_) {
893  for (size_t m = 0; m < NumVectors; ++m) {
894  ArrayView<scalar_type> y_local = (y_ptr())[m]();
895  ArrayView<scalar_type> y2_local = (y2_ptr())[m]();
896  for (size_t i = 0 ; i < NumMyRows_ ; ++i) {
897  y_local[i] = y2_local[i];
898  }
899  }
900  }
901 }
902 
903 template<class MatrixType, class ContainerType>
905 {
906  std::ostringstream out;
907 
908  // Output is a valid YAML dictionary in flow style. If you don't
909  // like everything on a single line, you should call describe()
910  // instead.
911  out << "\"Ifpack2::BlockRelaxation\": {";
912  if (this->getObjectLabel () != "") {
913  out << "Label: \"" << this->getObjectLabel () << "\", ";
914  }
915  out << "Initialized: " << (isInitialized () ? "true" : "false") << ", ";
916  out << "Computed: " << (isComputed () ? "true" : "false") << ", ";
917 
918  if (A_.is_null ()) {
919  out << "Matrix: null, ";
920  }
921  else {
922  out << "Matrix: not null"
923  << ", Global matrix dimensions: ["
924  << A_->getGlobalNumRows () << ", " << A_->getGlobalNumCols () << "], ";
925  }
926 
927  // It's useful to print this instance's relaxation method. If you
928  // want more info than that, call describe() instead.
929  out << "\"relaxation: type\": ";
930  if (PrecType_ == Ifpack2::Details::JACOBI) {
931  out << "Block Jacobi";
932  } else if (PrecType_ == Ifpack2::Details::GS) {
933  out << "Block Gauss-Seidel";
934  } else if (PrecType_ == Ifpack2::Details::SGS) {
935  out << "Block Symmetric Gauss-Seidel";
936  } else {
937  out << "INVALID";
938  }
939 
940  out << ", " << "sweeps: " << NumSweeps_ << ", "
941  << "damping factor: " << DampingFactor_ << ", ";
942 
943  out << "}";
944  return out.str();
945 }
946 
947 
948 template<class MatrixType,class ContainerType>
950 describe (Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
951 {
952  using std::endl;
953  using std::setw;
954  using Teuchos::TypeNameTraits;
955  using Teuchos::VERB_DEFAULT;
956  using Teuchos::VERB_NONE;
957  using Teuchos::VERB_LOW;
958  using Teuchos::VERB_MEDIUM;
959  using Teuchos::VERB_HIGH;
960  using Teuchos::VERB_EXTREME;
961 
962  Teuchos::EVerbosityLevel vl = verbLevel;
963  if (vl == VERB_DEFAULT) vl = VERB_LOW;
964  const int myImageID = A_->getComm()->getRank();
965 
966  // Convention requires that describe() begin with a tab.
967  Teuchos::OSTab tab (out);
968 
969  // none: print nothing
970  // low: print O(1) info from node 0
971  // medium:
972  // high:
973  // extreme:
974  if (vl != VERB_NONE && myImageID == 0) {
975  out << "Ifpack2::BlockRelaxation<"
976  << TypeNameTraits<MatrixType>::name () << ", "
977  << TypeNameTraits<ContainerType>::name () << " >:";
978  Teuchos::OSTab tab1 (out);
979 
980  if (this->getObjectLabel () != "") {
981  out << "label: \"" << this->getObjectLabel () << "\"" << endl;
982  }
983  out << "initialized: " << (isInitialized () ? "true" : "false") << endl
984  << "computed: " << (isComputed () ? "true" : "false") << endl;
985 
986  std::string precType;
987  if (PrecType_ == Ifpack2::Details::JACOBI) {
988  precType = "Block Jacobi";
989  } else if (PrecType_ == Ifpack2::Details::GS) {
990  precType = "Block Gauss-Seidel";
991  } else if (PrecType_ == Ifpack2::Details::SGS) {
992  precType = "Block Symmetric Gauss-Seidel";
993  }
994  out << "type: " << precType << endl
995  << "global number of rows: " << A_->getGlobalNumRows () << endl
996  << "global number of columns: " << A_->getGlobalNumCols () << endl
997  << "number of sweeps: " << NumSweeps_ << endl
998  << "damping factor: " << DampingFactor_ << endl
999  << "backwards mode: "
1000  << ((PrecType_ == Ifpack2::Details::GS && DoBackwardGS_) ? "true" : "false")
1001  << endl
1002  << "zero starting solution: "
1003  << (ZeroStartingSolution_ ? "true" : "false") << endl;
1004 
1005  out << "===============================================================================" << endl;
1006  out << "Phase # calls Total Time (s) Total MFlops MFlops/s " << endl;
1007  out << "------------ ------- --------------- --------------- ---------------" << endl;
1008  out << setw(12) << "initialize()" << setw(5) << getNumInitialize() << " " << setw(15) << getInitializeTime() << endl;
1009  out << setw(12) << "compute()" << setw(5) << getNumCompute() << " " << setw(15) << getComputeTime() << " "
1010  << setw(15) << getComputeFlops() << " "
1011  << setw(15) << (getComputeTime() != 0.0 ? getComputeFlops() / getComputeTime() * 1.0e-6 : 0.0) << endl;
1012  out << setw(12) << "apply()" << setw(5) << getNumApply() << " " << setw(15) << getApplyTime() << " "
1013  << setw(15) << getApplyFlops() << " "
1014  << setw(15) << (getApplyTime() != 0.0 ? getApplyFlops() / getApplyTime() * 1.0e-6 : 0.0) << endl;
1015  out << "===============================================================================" << endl;
1016  out << endl;
1017  }
1018 }
1019 
1020 }//namespace Ifpack2
1021 
1022 
1023 #ifdef HAVE_IFPACK2_EXPLICIT_INSTANTIATION
1024 
1025 // For ETI
1030 #include "Ifpack2_ILUT_decl.hpp"
1031 
1032 // There's no need to instantiate for CrsMatrix too. All Ifpack2
1033 // preconditioners can and should do dynamic casts if they need a type
1034 // more specific than RowMatrix.
1035 
1036 #define IFPACK2_BLOCKRELAXATION_INSTANT(S,LO,GO,N) \
1037  template \
1038  class Ifpack2::BlockRelaxation< \
1039  Tpetra::RowMatrix<S, LO, GO, N>, \
1040  Ifpack2::SparseContainer< \
1041  Tpetra::RowMatrix<S, LO, GO, N>, \
1042  Ifpack2::ILUT< ::Tpetra::RowMatrix<S,LO,GO,N> > > >; \
1043  template \
1044  class Ifpack2::BlockRelaxation< \
1045  Tpetra::RowMatrix<S, LO, GO, N>, \
1046  Ifpack2::DenseContainer< \
1047  Tpetra::RowMatrix<S, LO, GO, N>, \
1048  S > >; \
1049  template \
1050  class Ifpack2::BlockRelaxation< \
1051  Tpetra::RowMatrix<S, LO, GO, N>, \
1052  Ifpack2::TriDiContainer< \
1053  Tpetra::RowMatrix<S, LO, GO, N>, \
1054  S > >; \
1055  template \
1056  class Ifpack2::BlockRelaxation< \
1057  Tpetra::RowMatrix<S, LO, GO, N>, \
1058  Ifpack2::BandedContainer< \
1059  Tpetra::RowMatrix<S, LO, GO, N>, \
1060  S > >;
1061 
1062 #endif // HAVE_IFPACK2_EXPLICIT_INSTANTIATION
1063 
1064 #endif // IFPACK2_BLOCKRELAXATION_DEF_HPP
double getApplyFlops() const
Returns the number of flops for the application of the preconditioner.
Definition: Ifpack2_BlockRelaxation_def.hpp:264
void applyMat(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) const
Applies the matrix to a Tpetra::MultiVector.
Definition: Ifpack2_BlockRelaxation_def.hpp:346
Ifpack2::BlockRelaxation class declaration.
Ifpack2::TriDiContainer class declaration.
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
The communicator over which the input matrix is distributed.
Definition: Ifpack2_BlockRelaxation_def.hpp:182
MatrixType::global_ordinal_type global_ordinal_type
The type of global indices in the input MatrixType.
Definition: Ifpack2_BlockRelaxation_decl.hpp:101
std::string description() const
A one-line description of this object.
Definition: Ifpack2_BlockRelaxation_def.hpp:904
double getApplyTime() const
Returns the time spent in apply().
Definition: Ifpack2_BlockRelaxation_def.hpp:252
int getNumApply() const
Returns the number of calls to apply().
Definition: Ifpack2_BlockRelaxation_def.hpp:234
void getParameter(const Teuchos::ParameterList &params, const std::string &name, T &value)
Set a value from a ParameterList if a parameter with the specified name exists.
Definition: Ifpack2_Parameters.hpp:59
Teuchos::RCP< const Tpetra::Map< local_ordinal_type, global_ordinal_type, node_type > > getRangeMap() const
Returns the Tpetra::Map object associated with the range of this operator.
Definition: Ifpack2_BlockRelaxation_def.hpp:210
int getNumCompute() const
Returns the number of calls to compute().
Definition: Ifpack2_BlockRelaxation_def.hpp:228
void setParameters(const Teuchos::ParameterList &params)
Sets all the parameters for the preconditioner.
Definition: Ifpack2_BlockRelaxation_def.hpp:119
void compute()
compute the preconditioner for the specified matrix, diagonal perturbation thresholds and relaxation ...
Definition: Ifpack2_BlockRelaxation_def.hpp:422
Block relaxation preconditioners (or smoothers) for Tpetra::RowMatrix and Tpetra::CrsMatrix sparse ma...
Definition: Ifpack2_BlockRelaxation_decl.hpp:80
Ifpack2 implementation details.
double getInitializeTime() const
Returns the time spent in initialize().
Definition: Ifpack2_BlockRelaxation_def.hpp:240
Declaration of a user-defined partitioner in which the user can define a nonoverlapping partition of ...
double getComputeFlops() const
Returns the number of flops in the computation phase.
Definition: Ifpack2_BlockRelaxation_def.hpp:258
double getComputeTime() const
Returns the time spent in compute().
Definition: Ifpack2_BlockRelaxation_def.hpp:246
bool isComputed() const
Return true if compute() has been called.
Definition: Ifpack2_BlockRelaxation_decl.hpp:189
virtual void setMatrix(const Teuchos::RCP< const row_matrix_type > &A)
Change the matrix to be preconditioned.
Definition: Ifpack2_BlockRelaxation_def.hpp:57
virtual ~BlockRelaxation()
Destructor.
Definition: Ifpack2_BlockRelaxation_def.hpp:113
Teuchos::RCP< const Tpetra::Map< local_ordinal_type, global_ordinal_type, node_type > > getDomainMap() const
Returns the Tpetra::Map object associated with the domain of this operator.
Definition: Ifpack2_BlockRelaxation_def.hpp:201
Partition in which the user can define a nonoverlapping partition of the graph in any way they choose...
Definition: Ifpack2_Details_UserPartitioner_decl.hpp:66
bool isInitialized() const
Returns true if the preconditioner has been successfully initialized.
Definition: Ifpack2_BlockRelaxation_decl.hpp:181
int getNumInitialize() const
Returns the number of calls to initialize().
Definition: Ifpack2_BlockRelaxation_def.hpp:222
void initialize()
Initialize.
Definition: Ifpack2_BlockRelaxation_def.hpp:366
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_BlockRelaxation_def.hpp:950
Ifpack2::BandedContainer class declaration.
Ifpack2::DenseContainer class declaration.
MatrixType::node_type node_type
Node type of the input MatrixType.
Definition: Ifpack2_BlockRelaxation_decl.hpp:104
MatrixType::local_ordinal_type local_ordinal_type
The type of local indices in the input MatrixType.
Definition: Ifpack2_BlockRelaxation_decl.hpp:98
Definition: Ifpack2_Details_Amesos2Wrapper_decl.hpp:63
MatrixType::scalar_type scalar_type
The type of the entries of the input MatrixType.
Definition: Ifpack2_BlockRelaxation_decl.hpp:95
Preconditioners and smoothers for Tpetra sparse matrices.
Definition: Ifpack2_AdditiveSchwarz_decl.hpp:72
Declaration of ILUT preconditioner.
Teuchos::RCP< const Tpetra::RowMatrix< scalar_type, local_ordinal_type, global_ordinal_type, node_type > > getMatrix() const
The input matrix of this preconditioner&#39;s constructor.
Definition: Ifpack2_BlockRelaxation_def.hpp:192
void getValidParameters(Teuchos::ParameterList &params)
Fills a list which contains all the parameters possibly used by Ifpack2.
Definition: Ifpack2_Parameters.cpp:50
Ifpack2::SparseContainer class declaration.
Definition: Ifpack2_LinePartitioner_decl.hpp:75
A class to define linear partitions.
Definition: Ifpack2_LinearPartitioner_decl.hpp:54
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
Applies the preconditioner to X, returns the result in Y.
Definition: Ifpack2_BlockRelaxation_def.hpp:272
BlockRelaxation(const Teuchos::RCP< const row_matrix_type > &Matrix)
Constructor.
Definition: Ifpack2_BlockRelaxation_def.hpp:80