MueLu  Version of the Day
MueLu_CreateTpetraPreconditioner.hpp
Go to the documentation of this file.
1 #ifndef MUELU_CREATE_TPETRA_PRECONDITIONER_HPP
2 #define MUELU_CREATE_TPETRA_PRECONDITIONER_HPP
3 
6 
7 #include <Teuchos_XMLParameterListHelpers.hpp>
8 #include <Tpetra_Operator.hpp>
9 #include <Tpetra_RowMatrix.hpp>
10 #include <Xpetra_TpetraBlockCrsMatrix.hpp>
11 #include <Tpetra_Experimental_BlockCrsMatrix.hpp>
12 #include <Xpetra_CrsMatrix.hpp>
13 #include <Xpetra_MultiVector.hpp>
14 #include <Xpetra_MultiVectorFactory.hpp>
15 
16 #include <MueLu.hpp>
17 
18 #include <MueLu_Exceptions.hpp>
19 #include <MueLu_Hierarchy.hpp>
20 #include <MueLu_MasterList.hpp>
21 #include <MueLu_MLParameterListInterpreter.hpp>
22 #include <MueLu_ParameterListInterpreter.hpp>
23 #include <MueLu_TpetraOperator.hpp>
25 #include <MueLu_Utilities.hpp>
26 #include <MueLu_HierarchyUtils.hpp>
27 
28 
29 #if defined(HAVE_MUELU_EXPERIMENTAL) and defined(HAVE_MUELU_AMGX)
30 #include <MueLu_AMGXOperator.hpp>
31 #include <amgx_c.h>
32 #include "cuda_runtime.h"
33 #endif
34 
35 namespace MueLu {
36 
37 
46  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
47  Teuchos::RCP<MueLu::TpetraOperator<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
48  CreateTpetraPreconditioner(const Teuchos::RCP<Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node> > &inA,
49  Teuchos::ParameterList& inParamList,
50  Teuchos::ParameterList& dummyList)
51  {
52  typedef Scalar SC;
53  typedef LocalOrdinal LO;
54  typedef GlobalOrdinal GO;
55  typedef Node NO;
56 
57  using Teuchos::ParameterList;
58 
59  typedef Xpetra::MultiVector<SC,LO,GO,NO> MultiVector;
60  typedef Xpetra::Matrix<SC,LO,GO,NO> Matrix;
62  typedef Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> crs_matrix_type;
63  typedef Tpetra::Experimental::BlockCrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> block_crs_matrix_type;
64 
65 #if defined(HAVE_MUELU_EXPERIMENTAL) and defined(HAVE_MUELU_AMGX)
66  std::string externalMG = "use external multigrid package";
67  if (hasParamList && paramList.isParameter(externalMG) && paramList.get<std::string>(externalMG) == "amgx"){
68  constCrsA = rcp_dynamic_cast<const crs_matrix_type>(inA);
69  TEUCHOS_TEST_FOR_EXCEPTION(constCrsA == Teuchos::null, Exceptions::RuntimeError, "CreateTpetraPreconditioner: failed to dynamic cast to Tpetra::CrsMatrix, which is required to be able to use AmgX.");
70  return rcp(new AMGXOperator<SC,LO,GO,NO>(inA,inParamList));
71  }
72 #endif
73 
74  // Wrap A
75  RCP<Matrix> A;
76  RCP<block_crs_matrix_type> bcrsA = rcp_dynamic_cast<block_crs_matrix_type>(inA);
77  RCP<crs_matrix_type> crsA = rcp_dynamic_cast<crs_matrix_type>(inA);
78  if (crsA != Teuchos::null)
79  A = TpetraCrs_To_XpetraMatrix<SC,LO,GO,NO>(crsA);
80  else if (bcrsA != Teuchos::null) {
81  RCP<Xpetra::CrsMatrix<SC,LO,GO,NO> > temp = rcp(new Xpetra::TpetraBlockCrsMatrix<SC,LO,GO,NO>(bcrsA));
82  TEUCHOS_TEST_FOR_EXCEPTION(temp==Teuchos::null, Exceptions::RuntimeError, "CreateTpetraPreconditioner: cast from Tpetra::Experimental::BlockCrsMatrix to Xpetra::TpetraBlockCrsMatrix failed.");
83  A = rcp(new Xpetra::CrsMatrixWrap<SC,LO,GO,NO>(temp));
84  }
85  else {
86  TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, "CreateTpetraPreconditioner: only Tpetra CrsMatrix and BlockCrsMatrix types are supported.");
87  }
88 
89  Teuchos::ParameterList& userList = inParamList.sublist("user data");
90  if (userList.isParameter("Coordinates")) {
91  RCP<Xpetra::MultiVector<double,LO,GO,NO> > coordinates = Teuchos::null;
92  try {
93  coordinates = TpetraMultiVector_To_XpetraMultiVector<double,LO,GO,NO>(userList.get<RCP<Tpetra::MultiVector<double, LocalOrdinal, GlobalOrdinal, Node> > >("Coordinates"));
94  } catch(Teuchos::Exceptions::InvalidParameterType) {
95  coordinates = userList.get<RCP<Xpetra::MultiVector<double, LocalOrdinal, GlobalOrdinal, Node> > >("Coordinates");
96  }
97  userList.set<RCP<Xpetra::MultiVector<double,LO,GO,NO> > >("Coordinates", coordinates);
98  }
99  RCP<MultiVector> nullspace = Teuchos::null;
100  if (userList.isParameter("Nullspace")) {
101  try {
102  nullspace = TpetraMultiVector_To_XpetraMultiVector<SC,LO,GO,NO>(userList.get<RCP<Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> > >("Nullspace"));
103  } catch(Teuchos::Exceptions::InvalidParameterType) {
104  nullspace = userList.get<RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> > >("Nullspace");
105  }
106  }
107  if(nullspace == Teuchos::null) {
108  int nPDE = MueLu::MasterList::getDefault<int>("number of equations");
109  if (inParamList.isSublist("Matrix")) {
110  // Factory style parameter list
111  const Teuchos::ParameterList& operatorList = inParamList.sublist("Matrix");
112  if (operatorList.isParameter("PDE equations"))
113  nPDE = operatorList.get<int>("PDE equations");
114 
115  } else if (inParamList.isParameter("number of equations")) {
116  // Easy style parameter list
117  nPDE = inParamList.get<int>("number of equations");
118  }
119 
120  nullspace = Xpetra::MultiVectorFactory<SC,LO,GO,NO>::Build(A->getDomainMap(), nPDE);
121  if (nPDE == 1) {
122  nullspace->putScalar(Teuchos::ScalarTraits<Scalar>::one());
123 
124  } else {
125  for (int i = 0; i < nPDE; i++) {
126  Teuchos::ArrayRCP<Scalar> nsData = nullspace->getDataNonConst(i);
127  for (int j = 0; j < nsData.size(); j++) {
128  GlobalOrdinal GID = A->getDomainMap()->getGlobalElement(j) - A->getDomainMap()->getIndexBase();
129  if ((GID-i) % nPDE == 0)
130  nsData[j] = Teuchos::ScalarTraits<Scalar>::one();
131  }
132  }
133  }
134  }
135  if(nullspace == Teuchos::null) {std::cout << "The nullspace is still Teuchos::null as it is added to the Hierarchy!" << std::endl;}
136  userList.set<RCP<MultiVector> >("Nullspace", nullspace);
137 
138  RCP<Hierarchy> H = MueLu::CreateXpetraPreconditioner<SC,LO,GO,NO>(A,inParamList,inParamList);
139  return rcp(new TpetraOperator<SC,LO,GO,NO>(H));
140  }
141 
142 
152  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
153  Teuchos::RCP<MueLu::TpetraOperator<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
154  CreateTpetraPreconditioner(const Teuchos::RCP<Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node> > &inA,
155  Teuchos::ParameterList& inParamList,
156  const Teuchos::RCP<Tpetra::MultiVector<double, LocalOrdinal, GlobalOrdinal, Node>>& inCoords = Teuchos::null,
157  const Teuchos::RCP<Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& inNullspace = Teuchos::null)
158  {
159  typedef Scalar SC;
160  typedef LocalOrdinal LO;
161  typedef GlobalOrdinal GO;
162  typedef Node NO;
163 
164  using Teuchos::ParameterList;
165 
166  // Here the assumption is that the nullspace and coordinates passed
167  // as multivectors will overwrite data on the parameter list.
168  // If you want the data on the parameter list to prevail, then call the
169  // specialization that only accept an operator and a parameterList
170  Teuchos::ParameterList& userList = inParamList.sublist("user data");
171  if (inCoords != Teuchos::null) {
172  userList.set<RCP<Tpetra::MultiVector<double,LO,GO,NO> > >("Coordinates", inCoords);
173  }
174  if (inNullspace != Teuchos::null) {
175  userList.set<RCP<Tpetra::MultiVector<SC,LO,GO,NO> > >("Nullspace", inNullspace);
176  }
177 
178  return CreateTpetraPreconditioner<SC,LO,GO,NO>(inA,inParamList,inParamList);
179  }
180 
181 
194  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
195  MUELU_DEPRECATED
196  Teuchos::RCP<MueLu::TpetraOperator<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
197  CreateTpetraPreconditioner(const Teuchos::RCP<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> > &inA,
198  Teuchos::ParameterList& inParamList,
199  const Teuchos::RCP<Tpetra::MultiVector<double, LocalOrdinal, GlobalOrdinal, Node>>& inCoords = Teuchos::null,
200  const Teuchos::RCP<Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& inNullspace = Teuchos::null)
201  {
202  RCP<Tpetra::Operator<Scalar,LocalOrdinal,GlobalOrdinal,Node>> opMat(inA);
203  return CreateTpetraPreconditioner<Scalar, LocalOrdinal, GlobalOrdinal, Node>(opMat, inParamList, inCoords, inNullspace);
204  }
205 
206 
218  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
219  MUELU_DEPRECATED
220  Teuchos::RCP<MueLu::TpetraOperator<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
221  CreateTpetraPreconditioner(const Teuchos::RCP<Tpetra::CrsMatrix <Scalar, LocalOrdinal, GlobalOrdinal, Node> >& inA,
222  const Teuchos::RCP<Tpetra::MultiVector<double, LocalOrdinal, GlobalOrdinal, Node>>& inCoords = Teuchos::null,
223  const Teuchos::RCP<Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& inNullspace = Teuchos::null)
224  {
225  Teuchos::ParameterList paramList;
226  RCP<Tpetra::Operator<Scalar,LocalOrdinal,GlobalOrdinal,Node>> opMat(inA);
227  return CreateTpetraPreconditioner<Scalar, LocalOrdinal, GlobalOrdinal, Node>(opMat, paramList, inCoords, inNullspace);
228  }
229 
230 
243  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
244  MUELU_DEPRECATED
245  Teuchos::RCP<MueLu::TpetraOperator<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
246  CreateTpetraPreconditioner(const Teuchos::RCP<Tpetra::CrsMatrix <Scalar, LocalOrdinal, GlobalOrdinal, Node> >& inA,
247  const std::string& xmlFileName,
248  const Teuchos::RCP<Tpetra::MultiVector<double, LocalOrdinal, GlobalOrdinal, Node>>& inCoords = Teuchos::null,
249  const Teuchos::RCP<Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& inNullspace = Teuchos::null)
250  {
251  Teuchos::ParameterList paramList;
252  Teuchos::updateParametersFromXmlFileAndBroadcast(xmlFileName, Teuchos::Ptr<Teuchos::ParameterList>(&paramList), *inA->getComm());
253 
254  RCP<Tpetra::Operator<Scalar,LocalOrdinal,GlobalOrdinal,Node>> opMat(inA);
255  return CreateTpetraPreconditioner<Scalar, LocalOrdinal, GlobalOrdinal, Node>(opMat, paramList, inCoords, inNullspace);
256  }
257 
258 
269  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
270  Teuchos::RCP<MueLu::TpetraOperator<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
271  CreateTpetraPreconditioner(const Teuchos::RCP<Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node> >& inA,
272  const Teuchos::RCP<Tpetra::MultiVector<double, LocalOrdinal, GlobalOrdinal, Node>>& inCoords = Teuchos::null,
273  const Teuchos::RCP<Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& inNullspace = Teuchos::null)
274  {
275  Teuchos::ParameterList paramList;
276  return CreateTpetraPreconditioner<Scalar, LocalOrdinal, GlobalOrdinal, Node>(inA, paramList, inCoords, inNullspace);
277  }
278 
279 
291  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
292  Teuchos::RCP<MueLu::TpetraOperator<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
293  CreateTpetraPreconditioner(const Teuchos::RCP<Tpetra::Operator<Scalar, LocalOrdinal, GlobalOrdinal, Node> >& inA,
294  const std::string& xmlFileName,
295  const Teuchos::RCP<Tpetra::MultiVector<double, LocalOrdinal, GlobalOrdinal, Node>>& inCoords = Teuchos::null,
296  const Teuchos::RCP<Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node>>& inNullspace = Teuchos::null)
297  {
298  Teuchos::ParameterList paramList;
299  Teuchos::updateParametersFromXmlFileAndBroadcast(xmlFileName, Teuchos::Ptr<Teuchos::ParameterList>(&paramList), *inA->getDomainMap()->getComm());
300  return CreateTpetraPreconditioner<Scalar, LocalOrdinal, GlobalOrdinal, Node>(inA, paramList, inCoords, inNullspace);
301  }
302 
303 
311  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
312  void ReuseTpetraPreconditioner(const Teuchos::RCP<Tpetra::CrsMatrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >& inA,
314  typedef Scalar SC;
315  typedef LocalOrdinal LO;
316  typedef GlobalOrdinal GO;
317  typedef Node NO;
318 
319  typedef Xpetra::Matrix<SC,LO,GO,NO> Matrix;
320  typedef MueLu ::Hierarchy<SC,LO,GO,NO> Hierarchy;
321 
322  RCP<Hierarchy> H = Op.GetHierarchy();
323  RCP<Matrix> A = TpetraCrs_To_XpetraMatrix<SC,LO,GO,NO>(inA);
324 
325  MueLu::ReuseXpetraPreconditioner<SC,LO,GO,NO>(A, H);
326  }
327 
328 } //namespace
329 
330 #endif //ifndef MUELU_CREATE_TPETRA_PRECONDITIONER_HPP
331 
Various adapters that will create a MueLu preconditioner that is an Xpetra::Matrix.
Namespace for MueLu classes and methods.
RCP< MueLu::Hierarchy< Scalar, LocalOrdinal, GlobalOrdinal, Node > > GetHierarchy() const
Direct access to the underlying MueLu::Hierarchy.
Teuchos::RCP< MueLu::TpetraOperator< Scalar, LocalOrdinal, GlobalOrdinal, Node > > CreateTpetraPreconditioner(const Teuchos::RCP< Tpetra::Operator< Scalar, LocalOrdinal, GlobalOrdinal, Node > > &inA, Teuchos::ParameterList &inParamList, Teuchos::ParameterList &dummyList)
Helper function to create a MueLu or AMGX preconditioner that can be used by Tpetra.Given a Tpetra::Operator, this function returns a constructed MueLu preconditioner.
Wraps an existing MueLu::Hierarchy as a Tpetra::Operator.
void ReuseTpetraPreconditioner(const Teuchos::RCP< Tpetra::CrsMatrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > &inA, MueLu::TpetraOperator< Scalar, LocalOrdinal, GlobalOrdinal, Node > &Op)
Helper function to reuse an existing MueLu preconditioner.
Exception throws to report errors in the internal logical of the program.
Provides methods to build a multigrid hierarchy and apply multigrid cycles.
Adapter for AmgX library from Nvidia.