MueLu  Version of the Day
MueLu_CreateXpetraPreconditioner.hpp
Go to the documentation of this file.
1 /*
2  * MueLu_CreateXpetraPreconditioner.hpp
3  *
4  * Created on: Feb 5, 2016
5  * Author: tawiesn
6  */
7 
8 #ifndef PACKAGES_MUELU_ADAPTERS_XPETRA_MUELU_CREATEXPETRAPRECONDITIONER_HPP_
9 #define PACKAGES_MUELU_ADAPTERS_XPETRA_MUELU_CREATEXPETRAPRECONDITIONER_HPP_
10 
13 
14 #include <Teuchos_XMLParameterListHelpers.hpp>
15 #include <Xpetra_CrsMatrix.hpp>
16 #include <Xpetra_MultiVector.hpp>
17 #include <Xpetra_MultiVectorFactory.hpp>
18 
19 #include <MueLu.hpp>
20 
21 #include <MueLu_Exceptions.hpp>
22 #include <MueLu_Hierarchy.hpp>
23 #include <MueLu_MasterList.hpp>
24 #include <MueLu_MLParameterListInterpreter.hpp>
25 #include <MueLu_ParameterListInterpreter.hpp>
26 #include <MueLu_Utilities.hpp>
27 #include <MueLu_HierarchyUtils.hpp>
28 
29 #include <stdlib.h>
30 
31 namespace MueLu {
42  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
43  Teuchos::RCP<MueLu::Hierarchy<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
44  CreateXpetraPreconditioner(Teuchos::RCP<Xpetra::Matrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> > op,
45  const Teuchos::ParameterList& inParamList,
46  Teuchos::RCP<Xpetra::MultiVector<double, LocalOrdinal, GlobalOrdinal, Node> > coords = Teuchos::null,
47  Teuchos::RCP<Xpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> > nullspace = Teuchos::null) {
53  typedef Xpetra::MultiVectorFactory<Scalar,LocalOrdinal,GlobalOrdinal,Node> MultiVectorFactory;
54 
55  std::string timerName = "MueLu setup time";
56  RCP<Teuchos::Time> tm = Teuchos::TimeMonitor::getNewTimer(timerName);
57  tm->start();
58 
59  bool hasParamList = inParamList.numParams();
60 
61  RCP<HierarchyManager> mueLuFactory;
62 
63  // Rip off non-serializable data before validation
64  Teuchos::ParameterList nonSerialList,paramList;
65  MueLu::ExtractNonSerializableData(inParamList, paramList, nonSerialList);
66 
67  std::string syntaxStr = "parameterlist: syntax";
68  if (hasParamList && paramList.isParameter(syntaxStr) && paramList.get<std::string>(syntaxStr) == "ml") {
69  paramList.remove(syntaxStr);
70  mueLuFactory = rcp(new MLParameterListInterpreter(paramList));
71  } else {
72  mueLuFactory = rcp(new ParameterListInterpreter(paramList,op->getDomainMap()->getComm()));
73  }
74 
75  // Create Hierarchy
76  RCP<Hierarchy> H = mueLuFactory->CreateHierarchy();
77  H->setlib(op->getDomainMap()->lib());
78 
79  // Stick the non-serializible data on the hierarchy.
80  HierarchyUtils::AddNonSerializableDataToHierarchy(*mueLuFactory,*H, nonSerialList);
81 
82  // Set fine level operator
83  H->GetLevel(0)->Set("A", op);
84 
85  // Set coordinates if available
86  if (coords != Teuchos::null) {
87  H->GetLevel(0)->Set("Coordinates", coords);
88  }
89 
90  // Wrap nullspace if available, otherwise use constants
91  if (nullspace == Teuchos::null) {
92  int nPDE = MueLu::MasterList::getDefault<int>("number of equations");
93  if (paramList.isSublist("Matrix")) {
94  // Factory style parameter list
95  const Teuchos::ParameterList& operatorList = paramList.sublist("Matrix");
96  if (operatorList.isParameter("PDE equations"))
97  nPDE = operatorList.get<int>("PDE equations");
98 
99  } else if (paramList.isParameter("number of equations")) {
100  // Easy style parameter list
101  nPDE = paramList.get<int>("number of equations");
102  }
103 
104  nullspace = MultiVectorFactory::Build(op->getDomainMap(), nPDE);
105  if (nPDE == 1) {
106  nullspace->putScalar(Teuchos::ScalarTraits<Scalar>::one());
107 
108  } else {
109  for (int i = 0; i < nPDE; i++) {
110  Teuchos::ArrayRCP<Scalar> nsData = nullspace->getDataNonConst(i);
111  for (int j = 0; j < nsData.size(); j++) {
112  GlobalOrdinal GID = op->getDomainMap()->getGlobalElement(j) - op->getDomainMap()->getIndexBase();
113 
114  if ((GID-i) % nPDE == 0)
115  nsData[j] = Teuchos::ScalarTraits<Scalar>::one();
116  }
117  }
118  }
119  }
120  H->GetLevel(0)->Set("Nullspace", nullspace);
121 
122 
123  mueLuFactory->SetupHierarchy(*H);
124 
125  tm->stop();
126  tm->incrementNumCalls();
127 
128  if (H->GetVerbLevel() & Statistics0) {
129  const bool alwaysWriteLocal = true;
130  const bool writeGlobalStats = true;
131  const bool writeZeroTimers = false;
132  const bool ignoreZeroTimers = true;
133  const std::string filter = timerName;
134  Teuchos::TimeMonitor::summarize(op->getRowMap()->getComm().ptr(), std::cout, alwaysWriteLocal, writeGlobalStats,
135  writeZeroTimers, Teuchos::Union, filter, ignoreZeroTimers);
136  }
137 
138  tm->reset();
139 
140  return H;
141  }
142 
143  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
144  Teuchos::RCP<MueLu::Hierarchy<Scalar,LocalOrdinal,GlobalOrdinal,Node> >
145  CreateXpetraPreconditioner(Teuchos::RCP<Xpetra::Matrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> > op,
146  const Teuchos::ParameterList& inParamList,
147  const Teuchos::ParameterList& dummy) {
153 
154  std::string timerName = "MueLu setup time";
155  RCP<Teuchos::Time> tm = Teuchos::TimeMonitor::getNewTimer(timerName);
156  tm->start();
157 
158  bool hasParamList = inParamList.numParams();
159 
160  RCP<HierarchyManager> mueLuFactory;
161 
162  // Rip off non-serializable data before validation
163  Teuchos::ParameterList nonSerialList,paramList;
164  MueLu::ExtractNonSerializableData(inParamList, paramList, nonSerialList);
165 
166  std::string syntaxStr = "parameterlist: syntax";
167  if (hasParamList && paramList.isParameter(syntaxStr) && paramList.get<std::string>(syntaxStr) == "ml") {
168  paramList.remove(syntaxStr);
169  mueLuFactory = rcp(new MLParameterListInterpreter(paramList));
170  } else {
171  mueLuFactory = rcp(new ParameterListInterpreter(paramList,op->getDomainMap()->getComm()));
172  }
173 
174  // Create Hierarchy
175  RCP<Hierarchy> H = mueLuFactory->CreateHierarchy();
176  H->setlib(op->getDomainMap()->lib());
177 
178  // Stick the non-serializible data on the hierarchy.
179  HierarchyUtils::AddNonSerializableDataToHierarchy(*mueLuFactory,*H, nonSerialList);
180 
181  // Set fine level operator
182  H->GetLevel(0)->Set("A", op);
183 
184  mueLuFactory->SetupHierarchy(*H);
185 
186  tm->stop();
187  tm->incrementNumCalls();
188 
189  if (H->GetVerbLevel() & Statistics0) {
190  const bool alwaysWriteLocal = true;
191  const bool writeGlobalStats = true;
192  const bool writeZeroTimers = false;
193  const bool ignoreZeroTimers = true;
194  const std::string filter = timerName;
195  Teuchos::TimeMonitor::summarize(op->getRowMap()->getComm().ptr(), std::cout, alwaysWriteLocal, writeGlobalStats,
196  writeZeroTimers, Teuchos::Union, filter, ignoreZeroTimers);
197  }
198 
199  tm->reset();
200 
201  return H;
202  }
203 
211  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
212  void ReuseXpetraPreconditioner(const Teuchos::RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >& A,
214  std::string timerName = "MueLu setup time";
215  RCP<Teuchos::Time> tm = Teuchos::TimeMonitor::getNewTimer(timerName);
216  tm->start();
217 
218  typedef Scalar SC;
219  typedef LocalOrdinal LO;
220  typedef GlobalOrdinal GO;
221  typedef Node NO;
222 
223  typedef Xpetra::Matrix<SC,LO,GO,NO> Matrix;
224  typedef Xpetra::Operator<SC,LO,GO,NO> Operator;
225 
226  TEUCHOS_TEST_FOR_EXCEPTION(!H->GetNumLevels(), Exceptions::RuntimeError,
227  "MueLu::ReuseXpetraPreconditioner: Hierarchy has no levels in it");
228  TEUCHOS_TEST_FOR_EXCEPTION(!H->GetLevel(0)->IsAvailable("A"), Exceptions::RuntimeError,
229  "MueLu::ReuseXpetraPreconditioner: Hierarchy has no fine level operator");
230  RCP<Level> level0 = H->GetLevel(0);
231 
232  RCP<Operator> O0 = level0->Get<RCP<Operator> >("A");
233  RCP<Matrix> A0 = Teuchos::rcp_dynamic_cast<Matrix>(O0);
234 
235  if (!A0.is_null()) {
236  // If a user provided a "number of equations" argument in a parameter list
237  // during the initial setup, we must honor that settings and reuse it for
238  // all consequent setups.
239  A->SetFixedBlockSize(A0->GetFixedBlockSize());
240  }
241  level0->Set("A", A);
242 
243  H->SetupRe();
244 
245  tm->stop();
246  tm->incrementNumCalls();
247 
248  if (H->GetVerbLevel() & Statistics0) {
249  const bool alwaysWriteLocal = true;
250  const bool writeGlobalStats = true;
251  const bool writeZeroTimers = false;
252  const bool ignoreZeroTimers = true;
253  const std::string filter = timerName;
254  Teuchos::TimeMonitor::summarize(A->getRowMap()->getComm().ptr(), std::cout, alwaysWriteLocal, writeGlobalStats,
255  writeZeroTimers, Teuchos::Union, filter, ignoreZeroTimers);
256  }
257 
258  tm->reset();
259  }
260 
261 } //namespace
262 
263 #endif /* PACKAGES_MUELU_ADAPTERS_XPETRA_MUELU_CREATEXPETRAPRECONDITIONER_HPP_ */
void ReuseXpetraPreconditioner(const Teuchos::RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > &A, Teuchos::RCP< MueLu::Hierarchy< Scalar, LocalOrdinal, GlobalOrdinal, Node >> &H)
Helper function to reuse an existing MueLu preconditioner.
static void AddNonSerializableDataToHierarchy(HierarchyManager &HM, Hierarchy &H, const ParameterList &nonSerialList)
Teuchos::RCP< MueLu::Hierarchy< Scalar, LocalOrdinal, GlobalOrdinal, Node > > CreateXpetraPreconditioner(Teuchos::RCP< Xpetra::Matrix< Scalar, LocalOrdinal, GlobalOrdinal, Node > > op, const Teuchos::ParameterList &inParamList, Teuchos::RCP< Xpetra::MultiVector< double, LocalOrdinal, GlobalOrdinal, Node > > coords=Teuchos::null, Teuchos::RCP< Xpetra::MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node > > nullspace=Teuchos::null)
Helper function to create a MueLu preconditioner that can be used by Xpetra.Given an Xpetra::Matrix...
Namespace for MueLu classes and methods.
Print statistics that do not involve significant additional computation.
Class that accepts ML-style parameters and builds a MueLu preconditioner. This interpreter uses the s...
Exception throws to report errors in the internal logical of the program.
Provides methods to build a multigrid hierarchy and apply multigrid cycles.
long ExtractNonSerializableData(const Teuchos::ParameterList &inList, Teuchos::ParameterList &serialList, Teuchos::ParameterList &nonSerialList)