MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MueLu_ProjectorSmoother_def.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // MueLu: A package for multigrid based preconditioning
4 //
5 // Copyright 2012 NTESS and the MueLu contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef MUELU_PROJECTORSMOOTHER_DEF_HPP
11 #define MUELU_PROJECTORSMOOTHER_DEF_HPP
12 
13 #include <Xpetra_Matrix.hpp>
14 #include <Xpetra_MultiVectorFactory.hpp>
15 
16 #include "MueLu_ConfigDefs.hpp"
17 
19 #include "MueLu_Level.hpp"
20 #include "MueLu_Utilities.hpp"
21 #include "MueLu_Monitor.hpp"
22 
23 namespace MueLu {
24 
25 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
27  : coarseSolver_(coarseSolver) {}
28 
29 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
31 
32 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
34  Factory::Input(currentLevel, "A");
35  Factory::Input(currentLevel, "Nullspace");
36 
37  coarseSolver_->DeclareInput(currentLevel);
38 }
39 
40 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
42  FactoryMonitor monitor(*this, "Projector Smoother", currentLevel);
43 
44  coarseSolver_->Setup(currentLevel);
45 
46  if (SmootherPrototype::IsSetup() == true)
47  this->GetOStream(Warnings0) << "MueLu::ProjectorSmoother::Setup(): Setup() has already been called" << std::endl;
48 
49  RCP<Matrix> A = Factory::Get<RCP<Matrix> >(currentLevel, "A");
50  RCP<MultiVector> B = Factory::Get<RCP<MultiVector> >(currentLevel, "Nullspace");
51 
52  int m = B->getNumVectors();
53 
54  // Find which vectors we want to keep
55  Array<Scalar> br(m), bb(m);
56  RCP<MultiVector> R = MultiVectorFactory::Build(B->getMap(), m);
57  A->apply(*B, *R);
58  B->dot(*R, br);
59  B->dot(*B, bb);
60 
61  Array<size_t> selectedIndices;
62  for (int i = 0; i < m; i++) {
63  Scalar rayleigh = br[i] / bb[i];
64 
65  if (Teuchos::ScalarTraits<Scalar>::magnitude(rayleigh) < 1e-12)
66  selectedIndices.push_back(i);
67  }
68  this->GetOStream(Runtime0) << "Coarse level orth indices: " << selectedIndices << std::endl;
69 
70 #if defined(HAVE_XPETRA_TPETRA)
71 #ifdef HAVE_MUELU_TPETRA_INST_INT_INT
72  // Orthonormalize
74  // TAW: Oct 16 2015: subCopy is not part of Xpetra. One should either add it to Xpetra (with an emulator for Epetra)
75  // or replace this call by a local loop. I'm not motivated to do this now...
76  RCP<Tpetra::MultiVector<SC, LO, GO, NO> > Borth = B_->subCopy(selectedIndices); // copy
77  for (int i = 0; i < selectedIndices.size(); i++) {
78  RCP<Tpetra::Vector<SC, LO, GO, NO> > Bi = Borth->getVectorNonConst(i);
79 
80  Scalar dot;
82  for (int k = 0; k < i; k++) { // orthogonalize
83  RCP<const Tpetra::Vector<SC, LO, GO, NO> > Bk = Borth->getVector(k);
84 
85  dot = Bi->dot(*Bk);
86  Bi->update(-dot, *Bk, Teuchos::ScalarTraits<Scalar>::one());
87  }
88 
89  norm = Bi->norm2();
90  Bi->scale(Teuchos::ScalarTraits<Scalar>::one() / norm); // normalize
91  }
92 
93  Borth_ = rcp(static_cast<MultiVector *>(new TpetraMultiVector(Borth)));
94 #else
95  TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, "Tpetra with GO=int not available. The code in ProjectorSmoother should be rewritten!");
96 #endif
97 #endif
98 
100 }
101 
102 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
103 void ProjectorSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Apply(MultiVector &X, const MultiVector &B, bool InitialGuessIsZero) const {
104  coarseSolver_->Apply(X, B, InitialGuessIsZero);
105 
106  int m = Borth_->getNumVectors();
107  int n = X.getNumVectors();
108 
109  RCP<Xpetra::MultiVector<SC, LO, GO, NO> > X_ = Teuchos::rcpFromRef(X);
110  for (int i = 0; i < n; i++) {
111  RCP<Xpetra::Vector<SC, LO, GO, NO> > Xi = X_->getVectorNonConst(i);
112 
113  Array<Scalar> dot(1);
114  for (int k = 0; k < m; k++) { // orthogonalize
115  RCP<const Xpetra::Vector<SC, LO, GO, NO> > Bk = Borth_->getVector(k);
116 
117  Xi->dot(*Bk, dot());
118  Xi->update(-dot[0], *Bk, Teuchos::ScalarTraits<Scalar>::one());
119  }
120  }
121 }
122 
123 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
125  return rcp(new ProjectorSmoother(*this));
126 }
127 
128 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
130  std::ostringstream out;
132  return out.str();
133 }
134 
135 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
138  out0 << "";
139 }
140 
141 } // namespace MueLu
142 
143 #endif // MUELU_PROJECTORSMOOTHER_DEF_HPP
Important warning messages (one line)
void print(Teuchos::FancyOStream &out, const VerbLevel verbLevel=Default) const
Print the object with some verbosity level to an FancyOStream object.
std::string description() const
Return a simple one-line description of this object.
static RCP< const Tpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > MV2TpetraMV(RCP< Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node >> const vec)
Helper utility to pull out the underlying Tpetra objects from an Xpetra object.
Timer to be used in factories. Similar to Monitor but with additional timers.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
One-liner description of what is happening.
virtual ~ProjectorSmoother()
Destructor.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
MueLu::DefaultScalar Scalar
Class that holds all level-specific information.
Definition: MueLu_Level.hpp:63
RCP< SmootherPrototype > Copy() const
bool IsSetup() const
Get the state of a smoother prototype.
void Setup(Level &currentLevel)
Set up the direct solver.
#define MUELU_DESCRIBE
Helper macro for implementing Describable::describe() for BaseClass objects.
This class enables the elimination of the nullspace component of the solution through the use of proj...
void push_back(const value_type &x)
size_type size() const
void Apply(MultiVector &X, const MultiVector &B, bool InitialGuessIsZero=false) const
Apply the direct solver. Solves the linear system AX=B using the constructed solver.
Exception throws to report errors in the internal logical of the program.
ProjectorSmoother(RCP< SmootherPrototype > coarseSolver)
Constructor.
void Input(Level &level, const std::string &varName) const
void DeclareInput(Level &currentLevel) const
Input.
virtual std::string description() const
Return a simple one-line description of this object.