MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MueLu_MergedSmoother_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_MERGEDSMOOTHER_DEF_HPP
11 #define MUELU_MERGEDSMOOTHER_DEF_HPP
12 
14 #include "MueLu_Exceptions.hpp"
15 
16 namespace MueLu {
17 
18 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
20  : smootherList_(smootherList)
21  , reverseOrder_(false)
22  , verbose_(verbose) {
23  // TODO: check that on each method TEUCHOS_TEST_FOR_EXCEPTION(smootherList == Teuchos::null, MueLu::Exceptions::RuntimeError, "");
24 
26 }
27 
28 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
30  : reverseOrder_(src.reverseOrder_)
31  , verbose_(src.verbose_) {
32  // Deep copy of src.smootherList_
34 }
35 
36 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
38  // We need to propagate SetFactory to proper place
39  for (typename ArrayView<RCP<SmootherPrototype> >::iterator it = smootherList_.begin(); it != smootherList_.end(); it++)
40  (*it)->SetFactory(varName, factory);
41 }
42 
43 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
45  for (typename ArrayView<RCP<SmootherPrototype> >::iterator it = smootherList_.begin(); it != smootherList_.end(); ++it)
46  (*it)->DeclareInput(currentLevel);
47 }
48 
49 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
51  if (SmootherPrototype::IsSetup() == true)
52  this->GetOStream(Warnings0) << "MueLu::MergedSmoother::Setup(): Setup() has already been called";
53 
54  for (typename ArrayView<RCP<SmootherPrototype> >::iterator it = smootherList_.begin(); it != smootherList_.end(); ++it) {
55  try {
56  (*it)->Setup(level);
57 
58  } catch (MueLu::Exceptions::RuntimeError& e) {
59  std::string msg = "MueLu::MergedSmoother<>::Setup(): Runtime Error.\n One of the underlying smoother throwed the following exception: \n";
60  msg += e.what();
62  }
63  }
64 
66 }
67 
68 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
69 void MergedSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Apply(MultiVector& X, const MultiVector& B, bool InitialGuessIsZero) const {
70  TEUCHOS_TEST_FOR_EXCEPTION(SmootherPrototype::IsSetup() == false, MueLu::Exceptions::RuntimeError, "MueLu::MergedSmoother<>:Apply(): Setup() has not been called");
71 
72  typedef typename ArrayRCP<RCP<SmootherPrototype> >::size_type sz_t;
73  sz_t n = smootherList_.size(), c = (reverseOrder_ ? n - 1 : 0);
74  char d = (reverseOrder_ ? -1 : 1);
75 
76  for (sz_t i = 0; i < n; i++) // loop unifying both forward and reverse order
77  try {
78  // Be careful with nonnegative numbers
79  smootherList_[c + d * Teuchos::as<char>(i)]->Apply(X, B, InitialGuessIsZero);
80 
81  // For second and later iterations, initial guess = previous result
82  InitialGuessIsZero = false;
83 
84  } catch (MueLu::Exceptions::RuntimeError& e) {
85  std::string msg = "MueLu::MergedSmoother<>::Apply(): Runtime Error. One of the underlying smoothers throws the following exception: \n";
86  msg += e.what();
88  }
89 }
90 
91 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
93  throw Exceptions::NotImplemented("MueLu::MergedSmoother<>::Print() is not implemented");
94 }
95 
96 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
97 void MergedSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::CopyParameters(RCP<SmootherPrototype> src) { // TODO: wrong prototype. We do not need an RCP here.
98  RCP<MergedSmoother> srcMergedSmoother = rcp_dynamic_cast<MergedSmoother>(src); // TODO: check if dynamic cast fails
99 
100  reverseOrder_ = srcMergedSmoother->GetReverseOrder();
101 
102  {
103  const ArrayRCP<const RCP<SmootherPrototype> >& srcSmootherList = srcMergedSmoother->GetSmootherList();
104  const ArrayRCP<const RCP<SmootherPrototype> >& thisSmootherList = smootherList_;
105  TEUCHOS_TEST_FOR_EXCEPTION(srcSmootherList == Teuchos::null, MueLu::Exceptions::RuntimeError, // might be allowed later if useful
106  "MueLu::MergedSmoother<>:CopyParameters(): thisSmootherList == Teuchos::null");
107 
108  // If the smootherList of 'this' and 'src' contains the same type of smoothers,
109  // we can transfert parameters from src to 'this' in order to tentatively reuse
110  // the current setup information of each smoothers. Note that the reuse of the
111  // setup phase of the MergedSmoother 'src' can be implemented for a larger set
112  // of cases (and more complicated cases), but it does not seems useful for now.
113 
114  bool reuse = true; // true == can we transfert parameters of smoothers one by one or do we have to copy the whole list of src?
115 
116  // test 1: same list size
117  reuse = reuse && (thisSmootherList.size() == srcSmootherList.size());
118 
119  if (reuse) {
120  // test 2: one-by-one comparison of smoother types
121  for (typename ArrayRCP<RCP<SmootherPrototype> >::size_type i = 0; i < srcSmootherList.size(); i++) {
122  // The following test should never throw in our use cases because 'src' is a prototype and
123  // 'this' is a real smoother so they don't share any data. We may allow such case later if useful.
124  TEUCHOS_TEST_FOR_EXCEPTION((thisSmootherList[i] == srcSmootherList[i]) && (thisSmootherList[i] != Teuchos::null), MueLu::Exceptions::RuntimeError,
125  "MueLu::MergedSmoother<>:CopyParameters(): internal logic error");
126 
127  // TODO
128  // reuse = reuse && ((thisSmootherList[i] == Teuchos::null && srcSmootherList[i] == Teuchos::null) ||
129  // thisSmootherList[i]->GetType() == srcSmootherList[i]->GetType());
130  }
131  }
132 
133  reuse = false; // TODO: temporary disactivated.
134 
135  if (reuse) {
136  bool isSetup = true;
137 
138  // Call CopyParameters for each smoothers and update IsSetup status of the MergedSmoother
139  for (typename ArrayRCP<RCP<SmootherPrototype> >::size_type i = 0; i < srcSmootherList.size(); i++) {
140  if (srcSmootherList[i] != Teuchos::null) {
141  TEUCHOS_TEST_FOR_EXCEPTION(srcSmootherList[i] == Teuchos::null, MueLu::Exceptions::RuntimeError, "MueLu::MergedSmoother<>:CopyParameters(): internal logic error");
142 
143  // TODO thisSmootherList[i]->CopyParameters(srcSmootherList[i]);
144  isSetup = isSetup && thisSmootherList[i]->IsSetup();
145  }
147  }
148 
149  } else {
150  // No reuse: copy srcSmootherList.
151  smootherList_ = Teuchos::null;
152  smootherList_ = SmootherListDeepCopy(srcSmootherList);
154  }
155  }
156 }
157 
158 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
161  Copy() const {
162  return rcp(new MergedSmoother(*this));
163 }
164 
165 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
168  SmootherListDeepCopy(const ArrayRCP<const RCP<SmootherPrototype> >& srcSmootherList) {
169  ArrayRCP<RCP<SmootherPrototype> > newSmootherList(srcSmootherList.size());
170 
171  for (typename ArrayRCP<RCP<SmootherPrototype> >::size_type i = 0; i < srcSmootherList.size(); i++)
172  newSmootherList[i] = srcSmootherList[i]->Copy();
173 
174  return newSmootherList;
175 }
176 
177 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
180  // FIXME: This is a placeholder
182 }
183 
184 } // namespace MueLu
185 
186 #endif // MUELU_MERGEDSMOOTHER_DEF_HPP
Important warning messages (one line)
RCP< SmootherPrototype > Copy() const
Copy method (performs a deep copy of input object)
ArrayRCP< RCP< SmootherPrototype > > smootherList_
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
size_t getNodeSmootherComplexity() const
Get a rough estimate of cost per iteration.
size_type size() const
void Apply(MultiVector &X, const MultiVector &B, bool InitialGuessIsZero=false) const
Apply.
void DeclareInput(Level &currentLevel) const
Input.
void CopyParameters(RCP< SmootherPrototype > src)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Class that holds all level-specific information.
Definition: MueLu_Level.hpp:63
void print(Teuchos::FancyOStream &out, const VerbLevel verbLevel=Default) const
Exception throws when you call an unimplemented method of MueLu.
ArrayRCP< RCP< SmootherPrototype > > SmootherListDeepCopy(const ArrayRCP< const RCP< SmootherPrototype > > &srcSmootherList)
bool IsSetup() const
Get the state of a smoother prototype.
const ArrayRCP< const RCP< SmootherPrototype > > GetSmootherList() const
void SetFactory(const std::string &varName, const RCP< const FactoryBase > &factory)
Custom SetFactory.
MergedSmoother(ArrayRCP< RCP< SmootherPrototype > > &smootherList, bool verbose=false)
Constructor.
Exception throws to report errors in the internal logical of the program.
void Setup(Level &level)
Set up.