MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_MergedSmoother_def.hpp
Go to the documentation of this file.
1// @HEADER
2//
3// ***********************************************************************
4//
5// MueLu: A package for multigrid based preconditioning
6// Copyright 2012 Sandia Corporation
7//
8// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9// the U.S. Government retains certain rights in this software.
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17//
18// 2. Redistributions in binary form must reproduce the above copyright
19// notice, this list of conditions and the following disclaimer in the
20// documentation and/or other materials provided with the distribution.
21//
22// 3. Neither the name of the Corporation nor the names of the
23// contributors may be used to endorse or promote products derived from
24// this software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// Questions? Contact
39// Jonathan Hu (jhu@sandia.gov)
40// Andrey Prokopenko (aprokop@sandia.gov)
41// Ray Tuminaro (rstumin@sandia.gov)
42//
43// ***********************************************************************
44//
45// @HEADER
46#ifndef MUELU_MERGEDSMOOTHER_DEF_HPP
47#define MUELU_MERGEDSMOOTHER_DEF_HPP
48
50#include "MueLu_Exceptions.hpp"
51
52namespace MueLu {
53
54 template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
55 MergedSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::MergedSmoother(ArrayRCP<RCP<SmootherPrototype> > & smootherList, bool verbose)
56 : smootherList_(smootherList), reverseOrder_(false), verbose_(verbose) {
57 // TODO: check that on each method TEUCHOS_TEST_FOR_EXCEPTION(smootherList == Teuchos::null, MueLu::Exceptions::RuntimeError, "");
58
60 }
61
62 template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
64 : reverseOrder_(src.reverseOrder_), verbose_(src.verbose_) {
65 // Deep copy of src.smootherList_
67 }
68
69 template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
70 void MergedSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::SetFactory(const std::string& varName, const RCP<const FactoryBase>& factory) {
71 // We need to propagate SetFactory to proper place
72 for (typename ArrayView<RCP<SmootherPrototype> >::iterator it = smootherList_.begin(); it != smootherList_.end(); it++)
73 (*it)->SetFactory(varName, factory);
74 }
75
76
77 template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
79 for (typename ArrayView<RCP<SmootherPrototype> >::iterator it = smootherList_.begin(); it != smootherList_.end(); ++it)
80 (*it)->DeclareInput(currentLevel);
81 }
82
83 template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
85 if (SmootherPrototype::IsSetup() == true)
86 this->GetOStream(Warnings0) << "MueLu::MergedSmoother::Setup(): Setup() has already been called";
87
88 for (typename ArrayView<RCP<SmootherPrototype> >::iterator it = smootherList_.begin(); it != smootherList_.end(); ++it) {
89 try {
90 (*it)->Setup(level);
91
93 std::string msg = "MueLu::MergedSmoother<>::Setup(): Runtime Error.\n One of the underlying smoother throwed the following exception: \n";
94 msg += e.what();
96 }
97 }
98
100 }
101
102 template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
103 void MergedSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Apply(MultiVector& X, const MultiVector& B, bool InitialGuessIsZero) const {
104 TEUCHOS_TEST_FOR_EXCEPTION(SmootherPrototype::IsSetup() == false, MueLu::Exceptions::RuntimeError, "MueLu::MergedSmoother<>:Apply(): Setup() has not been called");
105
106 typedef typename ArrayRCP<RCP<SmootherPrototype> >::size_type sz_t;
107 sz_t n = smootherList_.size(), c = (reverseOrder_ ? n-1 : 0);
108 char d = (reverseOrder_ ? -1 : 1);
109
110 for (sz_t i = 0; i < n; i++) // loop unifying both forward and reverse order
111 try {
112 // Be careful with nonnegative numbers
113 smootherList_[c + d*Teuchos::as<char>(i)]->Apply(X, B, InitialGuessIsZero);
114
115 // For second and later iterations, initial guess = previous result
116 InitialGuessIsZero = false;
117
119 std::string msg = "MueLu::MergedSmoother<>::Apply(): Runtime Error. One of the underlying smoothers throws the following exception: \n";
120 msg += e.what();
122 }
123 }
124
125 template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
126 void MergedSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::print(Teuchos::FancyOStream& /* out */, const VerbLevel /* verbLevel */) const {
127 throw Exceptions::NotImplemented("MueLu::MergedSmoother<>::Print() is not implemented");
128 }
129
130 template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
131 void MergedSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>::CopyParameters(RCP<SmootherPrototype> src) { // TODO: wrong prototype. We do not need an RCP here.
132 RCP<MergedSmoother> srcMergedSmoother = rcp_dynamic_cast<MergedSmoother>(src); // TODO: check if dynamic cast fails
133
134 reverseOrder_ = srcMergedSmoother->GetReverseOrder();
135
136 {
137 const ArrayRCP<const RCP<SmootherPrototype> >& srcSmootherList = srcMergedSmoother->GetSmootherList();
138 const ArrayRCP<const RCP<SmootherPrototype> >& thisSmootherList = smootherList_;
139 TEUCHOS_TEST_FOR_EXCEPTION(srcSmootherList == Teuchos::null, MueLu::Exceptions::RuntimeError, // might be allowed later if useful
140 "MueLu::MergedSmoother<>:CopyParameters(): thisSmootherList == Teuchos::null");
141
142 // If the smootherList of 'this' and 'src' contains the same type of smoothers,
143 // we can transfert parameters from src to 'this' in order to tentatively reuse
144 // the current setup information of each smoothers. Note that the reuse of the
145 // setup phase of the MergedSmoother 'src' can be implemented for a larger set
146 // of cases (and more complicated cases), but it does not seems useful for now.
147
148 bool reuse = true; // true == can we transfert parameters of smoothers one by one or do we have to copy the whole list of src?
149
150 // test 1: same list size
151 reuse = reuse && (thisSmootherList.size() == srcSmootherList.size());
152
153 if (reuse) {
154 // test 2: one-by-one comparison of smoother types
155 for (typename ArrayRCP<RCP<SmootherPrototype> >::size_type i = 0; i < srcSmootherList.size(); i++) {
156 // The following test should never throw in our use cases because 'src' is a prototype and
157 // 'this' is a real smoother so they don't share any data. We may allow such case later if useful.
158 TEUCHOS_TEST_FOR_EXCEPTION((thisSmootherList[i] == srcSmootherList[i]) && (thisSmootherList[i] != Teuchos::null), MueLu::Exceptions::RuntimeError,
159 "MueLu::MergedSmoother<>:CopyParameters(): internal logic error");
160
161 //TODO
162 // reuse = reuse && ((thisSmootherList[i] == Teuchos::null && srcSmootherList[i] == Teuchos::null) ||
163 // thisSmootherList[i]->GetType() == srcSmootherList[i]->GetType());
164 }
165 }
166
167 reuse = false; //TODO: temporary disactivated.
168
169 if (reuse) {
170 bool isSetup = true;
171
172 // Call CopyParameters for each smoothers and update IsSetup status of the MergedSmoother
173 for (typename ArrayRCP<RCP<SmootherPrototype> >::size_type i = 0; i < srcSmootherList.size(); i++) {
174 if (srcSmootherList[i] != Teuchos::null) {
175 TEUCHOS_TEST_FOR_EXCEPTION(srcSmootherList[i] == Teuchos::null, MueLu::Exceptions::RuntimeError, "MueLu::MergedSmoother<>:CopyParameters(): internal logic error");
176
177 //TODO thisSmootherList[i]->CopyParameters(srcSmootherList[i]);
178 isSetup = isSetup && thisSmootherList[i]->IsSetup();
179 }
181 }
182
183 } else {
184 // No reuse: copy srcSmootherList.
185 smootherList_ = Teuchos::null;
186 smootherList_ = SmootherListDeepCopy(srcSmootherList);
188 }
189
190 }
191 }
192
193 template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
194 RCP<MueLu::SmootherPrototype<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
196 Copy () const
197 {
198 return rcp(new MergedSmoother(*this));
199 }
200
201 template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
202 ArrayRCP<RCP<MueLu::SmootherPrototype<Scalar, LocalOrdinal, GlobalOrdinal, Node> > >
204 SmootherListDeepCopy (const ArrayRCP<const RCP<SmootherPrototype> >& srcSmootherList)
205 {
206 ArrayRCP<RCP<SmootherPrototype> > newSmootherList(srcSmootherList.size());
207
208 for (typename ArrayRCP<RCP<SmootherPrototype> >::size_type i = 0; i < srcSmootherList.size(); i++)
209 newSmootherList[i] = srcSmootherList[i]->Copy();
210
211 return newSmootherList;
212 }
213
214
215 template <class Scalar,class LocalOrdinal, class GlobalOrdinal, class Node>
218 {
219 // FIXME: This is a placeholder
220 return Teuchos::OrdinalTraits<size_t>::invalid();
221 }
222
223} //namespace MueLu
224
225#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)