MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MueLu_StratimikosSmoother_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_STRATIMIKOSSMOOTHER_DEF_HPP
47 #define MUELU_STRATIMIKOSSMOOTHER_DEF_HPP
48 
49 #include "MueLu_ConfigDefs.hpp"
50 
51 #if defined(HAVE_MUELU_STRATIMIKOS) && defined(HAVE_MUELU_TPETRA) && defined(HAVE_MUELU_THYRA)
52 
54 
55 #include <Xpetra_CrsMatrix.hpp>
56 #include <Xpetra_CrsMatrixWrap.hpp>
57 #include <Xpetra_Matrix.hpp>
58 
60 #include "MueLu_Level.hpp"
62 #include "MueLu_Utilities.hpp"
63 #include "MueLu_Monitor.hpp"
64 
65 #include <Stratimikos_DefaultLinearSolverBuilder.hpp>
66 #include "Teuchos_AbstractFactoryStd.hpp"
67 #if defined(HAVE_MUELU_THYRATPETRAADAPTERS) && defined(HAVE_MUELU_IFPACK2)
68 #include <Thyra_Ifpack2PreconditionerFactory.hpp>
69 #endif
70 
71 
72 namespace MueLu {
73 
74  template <class LocalOrdinal, class GlobalOrdinal, class Node>
75  StratimikosSmoother<double, LocalOrdinal, GlobalOrdinal, Node>::StratimikosSmoother(const std::string type, const Teuchos::ParameterList& paramList)
76  : type_(type)
77  {
78  bool isSupported = type == "STRATIMIKOS";
79  this->declareConstructionOutcome(!isSupported, "Stratimikos does not provide the smoother '" + type_ + "'.");
80  if (isSupported)
81  SetParameterList(paramList);
82  }
83 
84  template <class LocalOrdinal, class GlobalOrdinal, class Node>
85  void StratimikosSmoother<double, LocalOrdinal, GlobalOrdinal, Node>::SetParameterList(const Teuchos::ParameterList& paramList) {
86  Factory::SetParameterList(paramList);
87  }
88 
89  template <class LocalOrdinal, class GlobalOrdinal, class Node>
90  void StratimikosSmoother<double, LocalOrdinal, GlobalOrdinal, Node>::DeclareInput(Level& currentLevel) const {
91  this->Input(currentLevel, "A");
92  }
93 
94  template <class LocalOrdinal, class GlobalOrdinal, class Node>
95  void StratimikosSmoother<double, LocalOrdinal, GlobalOrdinal, Node>::Setup(Level& currentLevel) {
96  FactoryMonitor m(*this, "Setup Smoother", currentLevel);
97 
98  A_ = Factory::Get< RCP<Matrix> >(currentLevel, "A");
99  SetupStratimikos(currentLevel);
100  SmootherPrototype::IsSetup(true);
101  this->GetOStream(Statistics1) << description() << std::endl;
102  }
103 
104  template <class LocalOrdinal, class GlobalOrdinal, class Node>
105  void StratimikosSmoother<double, LocalOrdinal, GlobalOrdinal, Node>::SetupStratimikos(Level& /* currentLevel */) {
106 
107  RCP<const Thyra::LinearOpBase<Scalar> > thyraA = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyra(Teuchos::rcp_dynamic_cast<CrsMatrixWrap>(A_)->getCrsMatrix());
108 
109  // Build Stratimikos solver
110  Stratimikos::DefaultLinearSolverBuilder linearSolverBuilder;
111  typedef Thyra::PreconditionerFactoryBase<Scalar> Base;
112 #if defined(HAVE_MUELU_THYRATPETRAADAPTERS) && defined(HAVE_MUELU_IFPACK2)
113  typedef Thyra::Ifpack2PreconditionerFactory<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > Impl;
114  linearSolverBuilder.setPreconditioningStrategyFactory(Teuchos::abstractFactoryStd<Base, Impl>(), "Ifpack2");
115 #endif
116  linearSolverBuilder.setParameterList(rcpFromRef(const_cast<ParameterList&>(this->GetParameterList())));
117 
118 
119  // Build a new "solver factory" according to the previously specified parameter list.
120  RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > solverFactory = Thyra::createLinearSolveStrategy(linearSolverBuilder);
121  solver_ = Thyra::linearOpWithSolve(*solverFactory, thyraA);
122  }
123 
124  template <class LocalOrdinal, class GlobalOrdinal, class Node>
125  void StratimikosSmoother<double, LocalOrdinal, GlobalOrdinal, Node>::Apply(MultiVector& X, const MultiVector& B, bool InitialGuessIsZero) const {
126  TEUCHOS_TEST_FOR_EXCEPTION(SmootherPrototype::IsSetup() == false, Exceptions::RuntimeError, "MueLu::StratimikosSmoother::Apply(): Setup() has not been called");
127 
128  // Apply
129  if (InitialGuessIsZero) {
130  X.putScalar(0.0);
131  RCP< Thyra::VectorBase<Scalar> >thyraX = Teuchos::rcp_const_cast<Thyra::VectorBase<Scalar> >(Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyraVector(X.getVectorNonConst(0)));
132  RCP<const Thyra::VectorBase<Scalar> >thyraB = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyraVector(B.getVector(0));
133  Thyra::SolveStatus<Scalar> status = Thyra::solve<Scalar>(*solver_, Thyra::NOTRANS, *thyraB, thyraX.ptr());
134 
135  } else {
136  typedef Teuchos::ScalarTraits<Scalar> TST;
137  RCP<MultiVector> Residual = Utilities::Residual(*A_, X, B);
138  RCP<MultiVector> Correction = MultiVectorFactory::Build(A_->getDomainMap(), X.getNumVectors());
139 
140  RCP< Thyra::VectorBase<Scalar> >thyraX = Teuchos::rcp_const_cast<Thyra::VectorBase<Scalar> >(Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyraVector(Correction->getVectorNonConst(0)));
141  RCP<const Thyra::VectorBase<Scalar> >thyraB = Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::toThyraVector(Residual->getVector(0));
142  Thyra::SolveStatus<Scalar> status = Thyra::solve<Scalar>(*solver_, Thyra::NOTRANS, *thyraB, thyraX.ptr());
143 
144  X.update(TST::one(), *Correction, TST::one());
145  }
146 
147  }
148 
149  template <class LocalOrdinal, class GlobalOrdinal, class Node>
150  RCP<MueLu::SmootherPrototype<double, LocalOrdinal, GlobalOrdinal, Node> > StratimikosSmoother<double, LocalOrdinal, GlobalOrdinal, Node>::Copy() const {
151  RCP<StratimikosSmoother> smoother = rcp(new StratimikosSmoother(*this) );
152  smoother->SetParameterList(this->GetParameterList());
153  return smoother;
154  }
155 
156  template <class LocalOrdinal, class GlobalOrdinal, class Node>
157  std::string StratimikosSmoother<double, LocalOrdinal, GlobalOrdinal, Node>::description() const {
158  std::ostringstream out;
159  if (SmootherPrototype::IsSetup()) {
160  out << solver_->description();
161  } else {
162  out << "STRATIMIKOS {type = " << type_ << "}";
163  }
164  return out.str();
165  }
166 
167  template <class LocalOrdinal, class GlobalOrdinal, class Node>
168  void StratimikosSmoother<double, LocalOrdinal, GlobalOrdinal, Node>::print(Teuchos::FancyOStream &out, const VerbLevel verbLevel) const {
170 
171  if (verbLevel & Parameters1) {
172  out0 << "Parameter list: " << std::endl;
173  Teuchos::OSTab tab2(out);
174  out << this->GetParameterList();
175  }
176 
177  if (verbLevel & External)
178  if (solver_ != Teuchos::null) {
179  Teuchos::OSTab tab2(out);
180  out << *solver_ << std::endl;
181  }
182 
183  if (verbLevel & Debug) {
184  out0 << "IsSetup: " << Teuchos::toString(SmootherPrototype::IsSetup()) << std::endl
185  << "-" << std::endl
186  << "RCP<solver_>: " << solver_ << std::endl;
187  }
188  }
189 
190  template <class LocalOrdinal, class GlobalOrdinal, class Node>
191  size_t StratimikosSmoother<double, LocalOrdinal, GlobalOrdinal, Node>::getNodeSmootherComplexity() const {
193  }
194 
195 
196 } // namespace MueLu
197 
198 #endif // HAVE_MUELU_STRATIMIKOS
199 #endif // MUELU_STRATIMIKOSSMOOTHER_DEF_HPP
Print external lib objects.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Print more statistics.
Print additional debugging information.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
#define MUELU_DESCRIBE
Helper macro for implementing Describable::describe() for BaseClass objects.
Print class parameters (more parameters, more verbose)
std::string toString(const T &t)