MueLu  Version of the Day
Thyra_MueLuPreconditionerFactory_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 THYRA_MUELU_PRECONDITIONER_FACTORY_DEF_HPP
47 #define THYRA_MUELU_PRECONDITIONER_FACTORY_DEF_HPP
48 
50 
51 #ifdef HAVE_MUELU_STRATIMIKOS
52 
53 // Stratimikos needs Thyra, so we don't need special guards for Thyra here
54 #include "Thyra_DefaultPreconditioner.hpp"
55 #include "Thyra_TpetraLinearOp.hpp"
56 #include "Thyra_TpetraThyraWrappers.hpp"
57 
58 #include "Teuchos_Ptr.hpp"
59 #include "Teuchos_TestForException.hpp"
60 #include "Teuchos_Assert.hpp"
61 #include "Teuchos_Time.hpp"
62 
63 #include <Xpetra_CrsMatrixWrap.hpp>
64 #include <Xpetra_CrsMatrix.hpp>
65 #include <Xpetra_Matrix.hpp>
66 #include <Xpetra_ThyraUtils.hpp>
67 
68 #include <MueLu_Hierarchy.hpp>
70 #include <MueLu_HierarchyHelpers.hpp>
71 #include <MueLu_ParameterListInterpreter.hpp>
72 #include <MueLu_MLParameterListInterpreter.hpp>
73 #include <MueLu_MasterList.hpp>
74 #ifdef HAVE_MUELU_TPETRA
75 #include <MueLu_TpetraOperator.hpp>
76 #endif
77 #ifdef HAVE_MUELU_EPETRA
78 #include <MueLu_EpetraOperator.hpp>
79 #endif
80 
81 namespace Thyra {
82 
83  using Teuchos::RCP;
84  using Teuchos::rcp;
85  using Teuchos::ParameterList;
86 
87 
88  // Constructors/initializers/accessors
89 
90  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
92  paramList_(rcp(new ParameterList()))
93  {}
94 
95  // Overridden from PreconditionerFactoryBase
96 
97  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
98  bool MueLuPreconditionerFactory<Scalar,LocalOrdinal,GlobalOrdinal,Node>::isCompatible(const LinearOpSourceBase<Scalar>& fwdOpSrc) const {
99  const RCP<const LinearOpBase<Scalar> > fwdOp = fwdOpSrc.getOp();
100 
101 #ifdef HAVE_MUELU_TPETRA
102  if (Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::isTpetra(fwdOp)) return true;
103 #endif
104 
105 #ifdef HAVE_MUELU_EPETRA
106  if (Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node>::isEpetra(fwdOp)) return true;
107 #endif
108  return false;
109  }
110 
111 
112  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
114  return Teuchos::rcp(new DefaultPreconditioner<Scalar>);
115  }
116 
117  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
119  initializePrec(const RCP<const LinearOpSourceBase<Scalar> >& fwdOpSrc, PreconditionerBase<Scalar>* prec, const ESupportSolveUse supportSolveUse) const {
120  using Teuchos::rcp_dynamic_cast;
121 
122  // we are using typedefs here, since we are using objects from different packages (Xpetra, Thyra,...)
123  typedef Xpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node> XpOp;
124  typedef Xpetra::ThyraUtils<Scalar,LocalOrdinal,GlobalOrdinal,Node> XpThyUtils;
125  typedef Xpetra::CrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> XpCrsMat;
126  typedef Xpetra::Matrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> XpMat;
127  typedef Xpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> XpMultVec;
128  typedef Xpetra::MultiVector<double,LocalOrdinal,GlobalOrdinal,Node> XpMultVecDouble;
129  typedef Thyra::LinearOpBase<Scalar> ThyLinOpBase;
130 #ifdef HAVE_MUELU_TPETRA
132  typedef Tpetra::Operator<Scalar,LocalOrdinal,GlobalOrdinal,Node> TpOp;
133  typedef Thyra::TpetraLinearOp<Scalar,LocalOrdinal,GlobalOrdinal,Node> ThyTpLinOp;
134 #endif
135 #ifdef HAVE_MUELU_EPETRA
136  typedef MueLu::EpetraOperator MueEpOp;
137  typedef Thyra::EpetraLinearOp ThyEpLinOp;
138 #endif
139 
140 
141  // Check precondition
142  TEUCHOS_ASSERT(Teuchos::nonnull(fwdOpSrc));
143  TEUCHOS_ASSERT(this->isCompatible(*fwdOpSrc));
144  TEUCHOS_ASSERT(prec);
145 
146  // Create a copy, as we may remove some things from the list
147  ParameterList paramList = *paramList_;
148 
149  // Retrieve wrapped concrete Xpetra matrix from FwdOp
150  const RCP<const ThyLinOpBase> fwdOp = fwdOpSrc->getOp();
151  TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(fwdOp));
152 
153  // Check whether it is Epetra/Tpetra
154  bool bIsEpetra = XpThyUtils::isEpetra(fwdOp);
155  bool bIsTpetra = XpThyUtils::isTpetra(fwdOp);
156  TEUCHOS_TEST_FOR_EXCEPT(bIsEpetra == bIsTpetra);
157 
158  RCP<const XpCrsMat > xpetraFwdCrsMat = XpThyUtils::toXpetra(fwdOp);
159  TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(xpetraFwdCrsMat));
160 
161  // MueLu needs a non-const object as input
162  RCP<XpCrsMat> xpetraFwdCrsMatNonConst = Teuchos::rcp_const_cast<XpCrsMat>(xpetraFwdCrsMat);
163  TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(xpetraFwdCrsMatNonConst));
164 
165  // wrap the forward operator as an Xpetra::Matrix that MueLu can work with
166  RCP<XpMat> A = rcp(new Xpetra::CrsMatrixWrap<Scalar,LocalOrdinal,GlobalOrdinal,Node>(xpetraFwdCrsMatNonConst));
167  TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(A));
168 
169  // Retrieve concrete preconditioner object
170  const Teuchos::Ptr<DefaultPreconditioner<Scalar> > defaultPrec = Teuchos::ptr(dynamic_cast<DefaultPreconditioner<Scalar> *>(prec));
171  TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(defaultPrec));
172 
173  // extract preconditioner operator
174  RCP<ThyLinOpBase> thyra_precOp = Teuchos::null;
175  thyra_precOp = rcp_dynamic_cast<Thyra::LinearOpBase<Scalar> >(defaultPrec->getNonconstUnspecifiedPrecOp(), true);
176 
177  // Variable for multigrid hierarchy: either build a new one or reuse the existing hierarchy
178  RCP<MueLu::Hierarchy<Scalar,LocalOrdinal,GlobalOrdinal,Node> > H = Teuchos::null;
179 
180  // make a decision whether to (re)build the multigrid preconditioner or reuse the old one
181  // rebuild preconditioner if startingOver == true
182  // reuse preconditioner if startingOver == false
183  const bool startingOver = (thyra_precOp.is_null() || !paramList.isParameter("reuse: type") || paramList.get<std::string>("reuse: type") == "none");
184 
185  if (startingOver == true) {
186  // extract coordinates from parameter list
187  Teuchos::RCP<XpMultVecDouble> coordinates = Teuchos::null;
188 #ifdef HAVE_MUELU_TPETRA
189  if (bIsTpetra) {
190  // Tpetra does not instantiate on Scalar=float by default, so we must check for this
191  // FIXME This will still break if LO != int or GO != int
192  # if !defined(HAVE_TPETRA_EXPLICIT_INSTANTIATION) || defined(HAVE_MUELU_INST_FLOAT_INT_INT)
193  typedef Tpetra::MultiVector<float, LocalOrdinal, GlobalOrdinal, Node> tfMV;
194  RCP<tfMV> floatCoords = Teuchos::null;
195  # endif
196  typedef Tpetra::MultiVector<double, LocalOrdinal, GlobalOrdinal, Node> tdMV;
197  RCP<tdMV> doubleCoords = Teuchos::null;
198  if (paramList.isType<RCP<tdMV> >("Coordinates")) {
199  doubleCoords = paramList.get<RCP<tdMV> >("Coordinates");
200  paramList.remove("Coordinates");
201  }
202  # if !defined(HAVE_TPETRA_EXPLICIT_INSTANTIATION) || defined(HAVE_MUELU_INST_FLOAT_INT_INT)
203  else if (paramList.isType<RCP<tfMV> >("Coordinates")) {
204  floatCoords = paramList.get<RCP<tfMV> >("Coordinates");
205  paramList.remove("Coordinates");
206  doubleCoords = rcp(new tdMV(floatCoords->getMap(), floatCoords->getNumVectors()));
207  deep_copy(*doubleCoords, *floatCoords);
208  }
209  # endif
210  if(doubleCoords != Teuchos::null) {
211  coordinates = MueLu::TpetraMultiVector_To_XpetraMultiVector<double,LocalOrdinal,GlobalOrdinal,Node>(doubleCoords);
212  TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(coordinates));
213  TEUCHOS_TEST_FOR_EXCEPT(doubleCoords->getNumVectors() != coordinates->getNumVectors());
214  }
215  }
216 #endif // HAVE_MUELU_TPETRA
217 
218 #ifdef HAVE_MUELU_EPETRA
219  if (bIsEpetra) {
220  RCP<Epetra_MultiVector> doubleCoords;
221  if (paramList.isType<RCP<Epetra_MultiVector> >("Coordinates")) {
222  doubleCoords = paramList.get<RCP<Epetra_MultiVector> >("Coordinates");
223  paramList.remove("Coordinates");
224  RCP<Xpetra::EpetraMultiVector> epCoordinates = Teuchos::rcp(new Xpetra::EpetraMultiVector(doubleCoords));
225  RCP<Xpetra::MultiVector<double,int,int,Node> > epCoordinatesMult = rcp_dynamic_cast<Xpetra::MultiVector<double,int,int,Node> >(epCoordinates);
226  coordinates = rcp_dynamic_cast<Xpetra::MultiVector<double,LocalOrdinal,GlobalOrdinal,Node> >(epCoordinatesMult);
227  TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(coordinates));
228  TEUCHOS_TEST_FOR_EXCEPT(doubleCoords->NumVectors() != Teuchos::as<int>(coordinates->getNumVectors()));
229  }
230  }
231 #endif // HAVE_MUELU_EPETRA
232 
233  // TODO check for Xpetra or Thyra vectors?
234 
235  RCP<XpMultVec> nullspace = Teuchos::null;
236 #ifdef HAVE_MUELU_TPETRA
237  if (bIsTpetra) {
238  typedef Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> tMV;
239  RCP<tMV> tpetra_nullspace = Teuchos::null;
240  if (paramList.isType<Teuchos::RCP<tMV> >("Nullspace")) {
241  tpetra_nullspace = paramList.get<RCP<tMV> >("Nullspace");
242  paramList.remove("Nullspace");
243  nullspace = MueLu::TpetraMultiVector_To_XpetraMultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>(tpetra_nullspace);
244  TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(nullspace));
245  }
246  }
247 #endif
248 #ifdef HAVE_MUELU_EPETRA
249  if (bIsEpetra) {
250  RCP<Epetra_MultiVector> epetra_nullspace = Teuchos::null;
251  if (paramList.isType<RCP<Epetra_MultiVector> >("Nullspace")) {
252  epetra_nullspace = paramList.get<RCP<Epetra_MultiVector> >("Nullspace");
253  paramList.remove("Nullspace");
254  RCP<Xpetra::EpetraMultiVector> xpEpNullspace = Teuchos::rcp(new Xpetra::EpetraMultiVector(epetra_nullspace));
255  RCP<Xpetra::MultiVector<double,int,int,Node> > xpEpNullspaceMult = rcp_dynamic_cast<Xpetra::MultiVector<double,int,int,Node> >(xpEpNullspace);
256  nullspace = rcp_dynamic_cast<XpMultVec>(xpEpNullspaceMult);
257  TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(nullspace));
258  }
259  }
260 #endif
261 
262  // build a new MueLu hierarchy
263  H = CreateXpetraPreconditioner(A, paramList, coordinates, nullspace);
264 
265  } else {
266  // reuse old MueLu hierarchy stored in MueLu Tpetra/Epetra operator and put in new matrix
267 
268  // get old MueLu hierarchy
269 #ifdef HAVE_MUELU_TPETRA
270  if (bIsTpetra) {
271 
272  RCP<ThyTpLinOp> tpetr_precOp = rcp_dynamic_cast<ThyTpLinOp>(thyra_precOp);
273  RCP<MueTpOp> muelu_precOp = rcp_dynamic_cast<MueTpOp>(tpetr_precOp->getTpetraOperator(),true);
274 
275  H = muelu_precOp->GetHierarchy();
276  }
277 #endif
278 #ifdef HAVE_MUELU_TPETRA
279  if (bIsEpetra) {
280  RCP<ThyEpLinOp> epetr_precOp = rcp_dynamic_cast<ThyEpLinOp>(thyra_precOp);
281  RCP<MueEpOp> muelu_precOp = rcp_dynamic_cast<MueEpOp>(epetr_precOp->epetra_op(),true);
282 
283  H = rcp_dynamic_cast<MueLu::Hierarchy<Scalar,LocalOrdinal,GlobalOrdinal,Node> >(muelu_precOp->GetHierarchy());
284  }
285 #endif
286  TEUCHOS_TEST_FOR_EXCEPTION(!H->GetNumLevels(), MueLu::Exceptions::RuntimeError,
287  "MueLu::ThyraPreconditionerFactory: Hierarchy has no levels in it");
288  TEUCHOS_TEST_FOR_EXCEPTION(!H->GetLevel(0)->IsAvailable("A"), MueLu::Exceptions::RuntimeError,
289  "MueLu::ThyraPreconditionerFactory: Hierarchy has no fine level operator");
290  RCP<MueLu::Level> level0 = H->GetLevel(0);
291  RCP<XpOp> O0 = level0->Get<RCP<XpOp> >("A");
292  RCP<XpMat> A0 = rcp_dynamic_cast<XpMat>(O0);
293 
294  if (!A0.is_null()) {
295  // If a user provided a "number of equations" argument in a parameter list
296  // during the initial setup, we must honor that settings and reuse it for
297  // all consequent setups.
298  A->SetFixedBlockSize(A0->GetFixedBlockSize());
299  }
300 
301  // set new matrix
302  level0->Set("A", A);
303 
304  H->SetupRe();
305  }
306 
307  // wrap hierarchy H in thyraPrecOp
308  RCP<ThyLinOpBase > thyraPrecOp = Teuchos::null;
309 #ifdef HAVE_MUELU_TPETRA
310  if (bIsTpetra) {
311  RCP<MueTpOp> muelu_tpetraOp = rcp(new MueTpOp(H));
312  TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(muelu_tpetraOp));
313  thyraPrecOp = Thyra::createLinearOp(RCP<TpOp>(muelu_tpetraOp));
314  }
315 #endif
316 
317 #ifdef HAVE_MUELU_EPETRA
318  if (bIsEpetra) {
319  RCP<MueLu::Hierarchy<double,int,int> > epetraH =
320  rcp_dynamic_cast<MueLu::Hierarchy<double,int,int> >(H);
321  RCP<MueEpOp> muelu_epetraOp = rcp(new MueEpOp(epetraH));
322  TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(muelu_epetraOp));
323  // attach fwdOp to muelu_epetraOp to guarantee that it will not go away
324  set_extra_data(fwdOp,"IFPF::fwdOp", Teuchos::inOutArg(muelu_epetraOp), Teuchos::POST_DESTROY,false);
325  RCP<ThyEpLinOp> thyra_epetraOp = Thyra::nonconstEpetraLinearOp(muelu_epetraOp, NOTRANS, EPETRA_OP_APPLY_APPLY_INVERSE, EPETRA_OP_ADJOINT_UNSUPPORTED);
326  TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(thyra_epetraOp));
327  thyraPrecOp = rcp_dynamic_cast<ThyLinOpBase>(thyra_epetraOp);
328  }
329 #endif
330  TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(thyraPrecOp));
331 
332  defaultPrec->initializeUnspecified(thyraPrecOp);
333 
334  }
335 
336  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
337  Teuchos::RCP<MueLu::Hierarchy<Scalar,LocalOrdinal,GlobalOrdinal,Node> > MueLuPreconditionerFactory<Scalar,LocalOrdinal,GlobalOrdinal,Node>::
338  CreateXpetraPreconditioner(Teuchos::RCP<Xpetra::Matrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> > op, const Teuchos::ParameterList& inParamList, Teuchos::RCP<Xpetra::MultiVector<double, LocalOrdinal, GlobalOrdinal, Node> > coords, Teuchos::RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> > nullspace) const {
339 
342 
343  Teuchos::ParameterList paramList = inParamList;
344 
345  bool hasParamList = paramList.numParams();
346 
347  RCP<HierarchyManager> mueLuFactory;
348 
349  std::string syntaxStr = "parameterlist: syntax";
350  if (hasParamList && paramList.isParameter(syntaxStr) && paramList.get<std::string>(syntaxStr) == "ml") {
351  paramList.remove(syntaxStr);
353  } else {
354  mueLuFactory = rcp(new MueLu::ParameterListInterpreter <Scalar,LocalOrdinal,GlobalOrdinal,Node>(paramList,op->getDomainMap()->getComm()));
355  }
356 
357  RCP<Hierarchy> H = mueLuFactory->CreateHierarchy();
358  H->setlib(op->getDomainMap()->lib());
359 
360 
361  // Set fine level operator
362  H->GetLevel(0)->Set("A", op);
363 
364  // Set coordinates if available
365  if (coords != Teuchos::null) {
366  H->GetLevel(0)->Set("Coordinates", coords);
367  }
368 
369  // Wrap nullspace if available, otherwise use constants
370  if (nullspace == Teuchos::null) {
371  int nPDE = MueLu::MasterList::getDefault<int>("number of equations");
372  if (paramList.isSublist("Matrix")) {
373  // Factory style parameter list
374  const Teuchos::ParameterList& operatorList = paramList.sublist("Matrix");
375  if (operatorList.isParameter("PDE equations"))
376  nPDE = operatorList.get<int>("PDE equations");
377 
378  } else if (paramList.isParameter("number of equations")) {
379  // Easy style parameter list
380  nPDE = paramList.get<int>("number of equations");
381  }
382 
383  nullspace = Xpetra::MultiVectorFactory<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Build(op->getDomainMap(), nPDE);
384  if (nPDE == 1) {
385  nullspace->putScalar(Teuchos::ScalarTraits<Scalar>::one());
386 
387  } else {
388  for (int i = 0; i < nPDE; i++) {
389  Teuchos::ArrayRCP<Scalar> nsData = nullspace->getDataNonConst(i);
390  for (int j = 0; j < nsData.size(); j++) {
391  GlobalOrdinal GID = op->getDomainMap()->getGlobalElement(j) - op->getDomainMap()->getIndexBase();
392 
393  if ((GID-i) % nPDE == 0)
394  nsData[j] = Teuchos::ScalarTraits<Scalar>::one();
395  }
396  }
397  }
398  }
399  H->GetLevel(0)->Set("Nullspace", nullspace);
400 
401 
402  Teuchos::ParameterList nonSerialList,dummyList;
403  MueLu::ExtractNonSerializableData(paramList, dummyList, nonSerialList);
405 
406  mueLuFactory->SetupHierarchy(*H);
407 
408  return H;
409  }
410 
411  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
413  uninitializePrec(PreconditionerBase<Scalar>* prec, RCP<const LinearOpSourceBase<Scalar> >* fwdOp, ESupportSolveUse* supportSolveUse) const {
414  TEUCHOS_ASSERT(prec);
415 
416  // Retrieve concrete preconditioner object
417  const Teuchos::Ptr<DefaultPreconditioner<Scalar> > defaultPrec = Teuchos::ptr(dynamic_cast<DefaultPreconditioner<Scalar> *>(prec));
418  TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(defaultPrec));
419 
420  if (fwdOp) {
421  // TODO: Implement properly instead of returning default value
422  *fwdOp = Teuchos::null;
423  }
424 
425  if (supportSolveUse) {
426  // TODO: Implement properly instead of returning default value
427  *supportSolveUse = Thyra::SUPPORT_SOLVE_UNSPECIFIED;
428  }
429 
430  defaultPrec->uninitialize();
431  }
432 
433 
434  // Overridden from ParameterListAcceptor
435  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
437  TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(paramList));
438  paramList_ = paramList;
439  }
440 
441  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
443  return paramList_;
444  }
445 
446  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
448  RCP<ParameterList> savedParamList = paramList_;
449  paramList_ = Teuchos::null;
450  return savedParamList;
451  }
452 
453  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
455  return paramList_;
456  }
457 
458  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
460  static RCP<const ParameterList> validPL;
461 
462  if (Teuchos::is_null(validPL))
463  validPL = rcp(new ParameterList());
464 
465  return validPL;
466  }
467 
468 
469  // Public functions overridden from Teuchos::Describable
470  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
472  return "Thyra::MueLuPreconditionerFactory";
473  }
474 } // namespace Thyra
475 
476 #endif // HAVE_MUELU_STRATIMIKOS
477 
478 #endif // ifdef THYRA_MUELU_PRECONDITIONER_FACTORY_DEF_HPP
RCP< Level > & GetLevel(const int levelID=0)
Retrieve a certain level from hierarchy.
static void AddNonSerializableDataToHierarchy(HierarchyManager &HM, Hierarchy &H, const ParameterList &nonSerialList)
void initializePrec(const Teuchos::RCP< const LinearOpSourceBase< Scalar > > &fwdOp, PreconditionerBase< Scalar > *prec, const ESupportSolveUse supportSolveUse) const
void uninitializePrec(PreconditionerBase< Scalar > *prec, Teuchos::RCP< const LinearOpSourceBase< Scalar > > *fwdOp, ESupportSolveUse *supportSolveUse) const
Teuchos::RCP< Teuchos::ParameterList > paramList_
Turns a MueLu::Hierarchy into a Epetra_Operator. It allows MueLu to be used as a preconditioner for A...
bool isCompatible(const LinearOpSourceBase< Scalar > &fwdOp) const
Teuchos::RCP< const Teuchos::ParameterList > getParameterList() const
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &paramList)
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Class that accepts ML-style parameters and builds a MueLu preconditioner. This interpreter uses the s...
Teuchos::RCP< MueLu::Hierarchy< Scalar, LocalOrdinal, GlobalOrdinal, Node > > CreateXpetraPreconditioner(Teuchos::RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > op, const Teuchos::ParameterList &paramList, Teuchos::RCP< Xpetra::MultiVector< double, LocalOrdinal, GlobalOrdinal, Node > > coords, Teuchos::RCP< Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > nullspace) const
Teuchos::RCP< PreconditionerBase< Scalar > > createPrec() const
Wraps an existing MueLu::Hierarchy as a Tpetra::Operator.
Exception throws to report errors in the internal logical of the program.
Teuchos::RCP< Teuchos::ParameterList > getNonconstParameterList()
Teuchos::RCP< Teuchos::ParameterList > unsetParameterList()
Provides methods to build a multigrid hierarchy and apply multigrid cycles.
long ExtractNonSerializableData(const Teuchos::ParameterList &inList, Teuchos::ParameterList &serialList, Teuchos::ParameterList &nonSerialList)