MueLu Version of the Day
Loading...
Searching...
No Matches
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
16namespace MueLu {
17
18template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
19MergedSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::MergedSmoother(ArrayRCP<RCP<SmootherPrototype> >& smootherList, bool verbose)
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
28template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
30 : reverseOrder_(src.reverseOrder_)
31 , verbose_(src.verbose_) {
32 // Deep copy of src.smootherList_
34}
35
36template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
37void MergedSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::SetFactory(const std::string& varName, const RCP<const FactoryBase>& factory) {
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
43template <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
49template <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
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
68template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
69void 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
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
91template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
92void MergedSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::print(Teuchos::FancyOStream& /* out */, const VerbLevel /* verbLevel */) const {
93 throw Exceptions::NotImplemented("MueLu::MergedSmoother<>::Print() is not implemented");
94}
95
96template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
97void 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
158template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
159RCP<MueLu::SmootherPrototype<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
164
165template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
166ArrayRCP<RCP<MueLu::SmootherPrototype<Scalar, LocalOrdinal, GlobalOrdinal, 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
177template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
180 // FIXME: This is a placeholder
181 return Teuchos::OrdinalTraits<size_t>::invalid();
182}
183
184} // namespace MueLu
185
186#endif // MUELU_MERGEDSMOOTHER_DEF_HPP
Copy
Exception throws when you call an unimplemented method of MueLu.
Exception throws to report errors in the internal logical of the program.
Class that holds all level-specific information.
size_t getNodeSmootherComplexity() const
Get a rough estimate of cost per iteration.
RCP< SmootherPrototype > Copy() const
Copy method (performs a deep copy of input object)
void DeclareInput(Level &currentLevel) const
Input.
void print(Teuchos::FancyOStream &out, const VerbLevel verbLevel=Default) const
ArrayRCP< RCP< SmootherPrototype > > smootherList_
ArrayRCP< RCP< SmootherPrototype > > SmootherListDeepCopy(const ArrayRCP< const RCP< SmootherPrototype > > &srcSmootherList)
void Setup(Level &level)
Set up.
void SetFactory(const std::string &varName, const RCP< const FactoryBase > &factory)
Custom SetFactory.
void Apply(MultiVector &X, const MultiVector &B, bool InitialGuessIsZero=false) const
Apply.
MergedSmoother(ArrayRCP< RCP< SmootherPrototype > > &smootherList, bool verbose=false)
Constructor.
void CopyParameters(RCP< SmootherPrototype > src)
const ArrayRCP< const RCP< SmootherPrototype > > GetSmootherList() const
bool IsSetup() const
Get the state of a smoother prototype.
Namespace for MueLu classes and methods.
@ Warnings0
Important warning messages (one line)