MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MueLu_MLParameterListInterpreter_def.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // MueLu: A package for multigrid based preconditioning
4 //
5 // Copyright 2012 NTESS and the MueLu contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef MUELU_MLPARAMETERLISTINTERPRETER_DEF_HPP
11 #define MUELU_MLPARAMETERLISTINTERPRETER_DEF_HPP
12 
14 
15 #include "MueLu_ConfigDefs.hpp"
16 #if defined(HAVE_MUELU_ML)
17 #include <ml_ValidateParameters.h>
18 #endif
19 
20 #include <Xpetra_Matrix.hpp>
21 #include <Xpetra_MatrixUtils.hpp>
22 #include <Xpetra_MultiVector.hpp>
23 #include <Xpetra_MultiVectorFactory.hpp>
24 #include <Xpetra_Operator.hpp>
25 
27 
28 #include "MueLu_Level.hpp"
29 #include "MueLu_Hierarchy.hpp"
30 #include "MueLu_FactoryManager.hpp"
31 
32 #include "MueLu_TentativePFactory.hpp"
33 #include "MueLu_SaPFactory.hpp"
34 #include "MueLu_PgPFactory.hpp"
35 #include "MueLu_AmalgamationFactory.hpp"
36 #include "MueLu_TransPFactory.hpp"
37 #include "MueLu_GenericRFactory.hpp"
38 #include "MueLu_SmootherPrototype.hpp"
39 #include "MueLu_SmootherFactory.hpp"
40 #include "MueLu_TrilinosSmoother.hpp"
41 #include "MueLu_IfpackSmoother.hpp"
42 #include "MueLu_DirectSolver.hpp"
43 #include "MueLu_HierarchyUtils.hpp"
44 #include "MueLu_RAPFactory.hpp"
45 #include "MueLu_CoalesceDropFactory.hpp"
46 #include "MueLu_UncoupledAggregationFactory.hpp"
47 #include "MueLu_NullspaceFactory.hpp"
49 
50 #include "MueLu_CoalesceDropFactory_kokkos.hpp"
51 // #include "MueLu_CoordinatesTransferFactory_kokkos.hpp"
52 #include "MueLu_TentativePFactory_kokkos.hpp"
53 
54 #if defined(HAVE_MUELU_ISORROPIA) && defined(HAVE_MPI)
55 #include "MueLu_IsorropiaInterface.hpp"
56 #include "MueLu_RepartitionHeuristicFactory.hpp"
57 #include "MueLu_RepartitionFactory.hpp"
58 #include "MueLu_RebalanceTransferFactory.hpp"
59 #include "MueLu_RepartitionInterface.hpp"
60 #include "MueLu_RebalanceAcFactory.hpp"
61 //#include "MueLu_RebalanceMapFactory.hpp"
62 #endif
63 
64 // Note: do not add options that are only recognized by MueLu.
65 
66 // TODO: this parameter list interpreter should force MueLu to use default ML parameters
67 // - Ex: smoother sweep=2 by default for ML
68 
69 // Read a parameter value from a parameter list and store it into a variable named 'varName'
70 #define MUELU_READ_PARAM(paramList, paramStr, varType, defaultValue, varName) \
71  varType varName = defaultValue; \
72  if (paramList.isParameter(paramStr)) varName = paramList.get<varType>(paramStr);
73 
74 // Read a parameter value from a paraeter list and copy it into a new parameter list (with another parameter name)
75 #define MUELU_COPY_PARAM(paramList, paramStr, varType, defaultValue, outParamList, outParamStr) \
76  if (paramList.isParameter(paramStr)) \
77  outParamList.set(outParamStr, paramList.get<varType>(paramStr)); \
78  else \
79  outParamList.set(outParamStr, static_cast<varType>(defaultValue));
80 
81 namespace MueLu {
82 
83 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
85  : nullspace_(NULL)
86  , xcoord_(NULL)
87  , ycoord_(NULL)
88  , zcoord_(NULL)
89  , TransferFacts_(factoryList)
90  , blksize_(1) {
91  if (paramList.isParameter("xml parameter file")) {
92  std::string filename = paramList.get("xml parameter file", "");
93  if (filename.length() != 0) {
94  TEUCHOS_TEST_FOR_EXCEPTION(comm.is_null(), Exceptions::RuntimeError, "xml parameter file requires a valid comm");
95  Teuchos::ParameterList paramList2 = paramList;
96  Teuchos::updateParametersFromXmlFileAndBroadcast(filename, Teuchos::Ptr<Teuchos::ParameterList>(&paramList2), *comm);
97  paramList2.remove("xml parameter file");
98  SetParameterList(paramList2);
99  } else
100  SetParameterList(paramList);
101  } else
102  SetParameterList(paramList);
103 }
104 
105 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
107  : nullspace_(NULL)
108  , TransferFacts_(factoryList)
109  , blksize_(1) {
110  Teuchos::RCP<Teuchos::ParameterList> paramList = Teuchos::getParametersFromXmlFile(xmlFileName);
111  SetParameterList(*paramList);
112 }
113 
114 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
116  Teuchos::ParameterList paramList = paramList_in;
117 
118  //
119  // Read top-level of the parameter list
120  //
121 
122  // hard-coded default values == ML defaults according to the manual
123  MUELU_READ_PARAM(paramList, "ML output", int, 0, verbosityLevel);
124  MUELU_READ_PARAM(paramList, "max levels", int, 10, maxLevels);
125  MUELU_READ_PARAM(paramList, "PDE equations", int, 1, nDofsPerNode);
126 
127  MUELU_READ_PARAM(paramList, "coarse: max size", int, 128, maxCoarseSize);
128 
129  MUELU_READ_PARAM(paramList, "aggregation: type", std::string, "Uncoupled", agg_type);
130  // MUELU_READ_PARAM(paramList, "aggregation: threshold", double, 0.0, agg_threshold);
131  MUELU_READ_PARAM(paramList, "aggregation: damping factor", double, (double)4 / (double)3, agg_damping);
132  // MUELU_READ_PARAM(paramList, "aggregation: smoothing sweeps", int, 1, agg_smoothingsweeps);
133  MUELU_READ_PARAM(paramList, "aggregation: nodes per aggregate", int, 1, minPerAgg);
134  MUELU_READ_PARAM(paramList, "aggregation: keep Dirichlet bcs", bool, false, bKeepDirichletBcs); // This is a MueLu specific extension that does not exist in ML
135  MUELU_READ_PARAM(paramList, "aggregation: max neighbours already aggregated", int, 0, maxNbrAlreadySelected); // This is a MueLu specific extension that does not exist in M
136  MUELU_READ_PARAM(paramList, "aggregation: aux: enable", bool, false, agg_use_aux);
137  MUELU_READ_PARAM(paramList, "aggregation: aux: threshold", double, false, agg_aux_thresh);
138 
139  MUELU_READ_PARAM(paramList, "null space: type", std::string, "default vectors", nullspaceType);
140  MUELU_READ_PARAM(paramList, "null space: dimension", int, -1, nullspaceDim); // TODO: ML default not in documentation
141  MUELU_READ_PARAM(paramList, "null space: vectors", double*, NULL, nullspaceVec); // TODO: ML default not in documentation
142 
143  MUELU_READ_PARAM(paramList, "energy minimization: enable", bool, false, bEnergyMinimization);
144 
145  MUELU_READ_PARAM(paramList, "RAP: fix diagonal", bool, false, bFixDiagonal); // This is a MueLu specific extension that does not exist in ML
146 
147  MUELU_READ_PARAM(paramList, "x-coordinates", double*, NULL, xcoord);
148  MUELU_READ_PARAM(paramList, "y-coordinates", double*, NULL, ycoord);
149  MUELU_READ_PARAM(paramList, "z-coordinates", double*, NULL, zcoord);
150 
151  //
152  // Move smoothers/aggregation/coarse parameters to sublists
153  //
154 
155  // ML allows to have level-specific smoothers/aggregation/coarse parameters at the top level of the list or/and defined in sublists:
156  // See also: ML Guide section 6.4.1, MueLu::CreateSublists, ML_CreateSublists
157  ParameterList paramListWithSubList;
158  MueLu::CreateSublists(paramList, paramListWithSubList);
159  paramList = paramListWithSubList; // swap
160 
161  // pull out "use kokkos refactor"
162  bool setKokkosRefactor = false;
163  bool useKokkosRefactor = !Node::is_serial;
164  if (paramList.isType<bool>("use kokkos refactor")) {
165  useKokkosRefactor = paramList.get<bool>("use kokkos refactor");
166  setKokkosRefactor = true;
167  paramList.remove("use kokkos refactor");
168  }
169 
170  //
171  // Validate parameter list
172  //
173 
174  {
175  bool validate = paramList.get("ML validate parameter list", true); /* true = default in ML */
176  if (validate) {
177 #if defined(HAVE_MUELU_ML) && defined(HAVE_MUELU_EPETRA)
178  // Validate parameter list using ML validator
179  int depth = paramList.get("ML validate depth", 5); /* 5 = default in ML */
180  TEUCHOS_TEST_FOR_EXCEPTION(!ML_Epetra::ValidateMLPParameters(paramList, depth), Exceptions::RuntimeError,
181  "ERROR: ML's Teuchos::ParameterList contains incorrect parameter!");
182 #else
183  // If no validator available: issue a warning and set parameter value to false in the output list
184  this->GetOStream(Warnings0) << "Warning: MueLu_ENABLE_ML=OFF. The parameter list cannot be validated." << std::endl;
185  paramList.set("ML validate parameter list", false);
186 
187 #endif // HAVE_MUELU_ML
188  } // if(validate)
189  } // scope
190 
191  // Matrix option
192  blksize_ = nDofsPerNode;
193 
194  // Translate verbosity parameter
195 
196  // Translate verbosity parameter
197  MsgType eVerbLevel = None;
198  if (verbosityLevel == 0) eVerbLevel = None;
199  if (verbosityLevel >= 1) eVerbLevel = Low;
200  if (verbosityLevel >= 5) eVerbLevel = Medium;
201  if (verbosityLevel >= 10) eVerbLevel = High;
202  if (verbosityLevel >= 11) eVerbLevel = Extreme;
203  if (verbosityLevel >= 42) eVerbLevel = Test;
204  if (verbosityLevel >= 43) eVerbLevel = InterfaceTest;
205  this->verbosity_ = eVerbLevel;
206 
207  TEUCHOS_TEST_FOR_EXCEPTION(agg_type != "Uncoupled", Exceptions::RuntimeError,
208  "MueLu::MLParameterListInterpreter::SetParameterList(): parameter \"aggregation: type\": only 'Uncoupled' aggregation is supported.");
209 
210  // Create MueLu factories
211  RCP<Factory> dropFact;
212  if (useKokkosRefactor)
213  dropFact = rcp(new CoalesceDropFactory_kokkos());
214  else
215  dropFact = rcp(new CoalesceDropFactory());
216 
217  if (agg_use_aux) {
218  dropFact->SetParameter("aggregation: drop scheme", Teuchos::ParameterEntry(std::string("distance laplacian")));
219  dropFact->SetParameter("aggregation: drop tol", Teuchos::ParameterEntry(agg_aux_thresh));
220  }
221 
222  // Uncoupled aggregation
223  RCP<Factory> AggFact = Teuchos::null;
224  AggFact = rcp(new UncoupledAggregationFactory());
225 
226  AggFact->SetFactory("Graph", dropFact);
227  AggFact->SetFactory("DofsPerNode", dropFact);
228  AggFact->SetParameter("aggregation: preserve Dirichlet points", Teuchos::ParameterEntry(bKeepDirichletBcs));
229  AggFact->SetParameter("aggregation: ordering", Teuchos::ParameterEntry(std::string("natural")));
230  AggFact->SetParameter("aggregation: max selected neighbors", Teuchos::ParameterEntry(maxNbrAlreadySelected));
231  AggFact->SetParameter("aggregation: min agg size", Teuchos::ParameterEntry(minPerAgg));
232 
233  if (verbosityLevel > 3) {
234  std::ostringstream oss;
235  oss << "========================= Aggregate option summary  =========================" << std::endl;
236  oss << "min Nodes per aggregate :              " << minPerAgg << std::endl;
237  oss << "min # of root nbrs already aggregated : " << maxNbrAlreadySelected << std::endl;
238  oss << "aggregate ordering :                    natural" << std::endl;
239  oss << "=============================================================================" << std::endl;
240  this->GetOStream(Runtime1) << oss.str();
241  }
242 
243  RCP<Factory> PFact;
244  RCP<Factory> RFact;
245  RCP<Factory> PtentFact;
246  if (useKokkosRefactor)
247  PtentFact = rcp(new TentativePFactory_kokkos());
248  else
249  PtentFact = rcp(new TentativePFactory());
250  if (agg_damping == 0.0 && bEnergyMinimization == false) {
251  // tentative prolongation operator (PA-AMG)
252  PFact = PtentFact;
253  RFact = rcp(new TransPFactory());
254  } else if (agg_damping != 0.0 && bEnergyMinimization == false) {
255  // smoothed aggregation (SA-AMG)
256  RCP<Factory> SaPFact = rcp(new SaPFactory());
257  SaPFact->SetParameter("sa: damping factor", ParameterEntry(agg_damping));
258  PFact = SaPFact;
259  RFact = rcp(new TransPFactory());
260  } else if (bEnergyMinimization == true) {
261  // Petrov Galerkin PG-AMG smoothed aggregation (energy minimization in ML)
262  PFact = rcp(new PgPFactory());
263  RFact = rcp(new GenericRFactory());
264  }
265 
266  RCP<RAPFactory> AcFact = rcp(new RAPFactory());
267  AcFact->SetParameter("RepairMainDiagonal", Teuchos::ParameterEntry(bFixDiagonal));
268  for (size_t i = 0; i < TransferFacts_.size(); i++) {
269  AcFact->AddTransferFactory(TransferFacts_[i]);
270  }
271 
272  //
273  // introduce rebalancing
274  //
275 #if defined(HAVE_MUELU_ISORROPIA) && defined(HAVE_MPI)
276  Teuchos::RCP<Factory> RebalancedPFact = Teuchos::null;
277  Teuchos::RCP<Factory> RebalancedRFact = Teuchos::null;
278  Teuchos::RCP<Factory> RepartitionFact = Teuchos::null;
279  Teuchos::RCP<RebalanceAcFactory> RebalancedAFact = Teuchos::null;
280 
281  MUELU_READ_PARAM(paramList, "repartition: enable", int, 0, bDoRepartition);
282  if (bDoRepartition == 1) {
283  // The Factory Manager will be configured to return the rebalanced versions of P, R, A by default.
284  // Everytime we want to use the non-rebalanced versions, we need to explicitly define the generating factory.
285  RFact->SetFactory("P", PFact);
286  //
287  AcFact->SetFactory("P", PFact);
288  AcFact->SetFactory("R", RFact);
289 
290  // define rebalancing factory for coarse matrix
292  rebAmalgFact->SetFactory("A", AcFact);
293 
294  MUELU_READ_PARAM(paramList, "repartition: max min ratio", double, 1.3, maxminratio);
295  MUELU_READ_PARAM(paramList, "repartition: min per proc", int, 512, minperproc);
296 
297  // Repartitioning heuristic
299  {
300  Teuchos::ParameterList paramListRepFact;
301  paramListRepFact.set("repartition: min rows per proc", minperproc);
302  paramListRepFact.set("repartition: max imbalance", maxminratio);
303  RepartitionHeuristicFact->SetParameterList(paramListRepFact);
304  }
305  RepartitionHeuristicFact->SetFactory("A", AcFact);
306 
307  // create "Partition"
309  isoInterface->SetFactory("A", AcFact);
310  isoInterface->SetFactory("number of partitions", RepartitionHeuristicFact);
311  isoInterface->SetFactory("UnAmalgamationInfo", rebAmalgFact);
312 
313  // create "Partition" by unamalgamtion
315  repInterface->SetFactory("A", AcFact);
316  repInterface->SetFactory("number of partitions", RepartitionHeuristicFact);
317  repInterface->SetFactory("AmalgamatedPartition", isoInterface);
318  // repInterface->SetFactory("UnAmalgamationInfo", rebAmalgFact); // not necessary?
319 
320  // Repartitioning (creates "Importer" from "Partition")
321  RepartitionFact = Teuchos::rcp(new RepartitionFactory());
322  RepartitionFact->SetFactory("A", AcFact);
323  RepartitionFact->SetFactory("number of partitions", RepartitionHeuristicFact);
324  RepartitionFact->SetFactory("Partition", repInterface);
325 
326  // Reordering of the transfer operators
327  RebalancedPFact = Teuchos::rcp(new RebalanceTransferFactory());
328  RebalancedPFact->SetParameter("type", Teuchos::ParameterEntry(std::string("Interpolation")));
329  RebalancedPFact->SetFactory("P", PFact);
330  RebalancedPFact->SetFactory("Nullspace", PtentFact);
331  RebalancedPFact->SetFactory("Importer", RepartitionFact);
332 
333  RebalancedRFact = Teuchos::rcp(new RebalanceTransferFactory());
334  RebalancedRFact->SetParameter("type", Teuchos::ParameterEntry(std::string("Restriction")));
335  RebalancedRFact->SetFactory("R", RFact);
336  RebalancedRFact->SetFactory("Importer", RepartitionFact);
337 
338  // Compute Ac from rebalanced P and R
339  RebalancedAFact = Teuchos::rcp(new RebalanceAcFactory());
340  RebalancedAFact->SetFactory("A", AcFact);
341  }
342 #else // #ifdef HAVE_MUELU_ISORROPIA
343  // Get rid of [-Wunused] warnings
344  //(void)
345  //
346  // ^^^ FIXME (mfh 17 Nov 2013) That definitely doesn't compile.
347 #endif
348 
349  //
350  // Nullspace factory
351  //
352 
353  // Set fine level nullspace
354  // extract pre-computed nullspace from ML parameter list
355  // store it in nullspace_ and nullspaceDim_
356  if (nullspaceType != "default vectors") {
357  TEUCHOS_TEST_FOR_EXCEPTION(nullspaceType != "pre-computed", Exceptions::RuntimeError, "MueLu::MLParameterListInterpreter: no valid nullspace (no pre-computed null space). error.");
358  TEUCHOS_TEST_FOR_EXCEPTION(nullspaceDim == -1, Exceptions::RuntimeError, "MueLu::MLParameterListInterpreter: no valid nullspace (nullspace dim == -1). error.");
359  TEUCHOS_TEST_FOR_EXCEPTION(nullspaceVec == NULL, Exceptions::RuntimeError, "MueLu::MLParameterListInterpreter: no valid nullspace (nullspace == NULL). You have to provide a valid fine-level nullspace in \'null space: vectors\'");
360 
361  nullspaceDim_ = nullspaceDim;
362  nullspace_ = nullspaceVec;
363  }
364 
366  nspFact->SetFactory("Nullspace", PtentFact);
367 
368  // Stash coordinates
369  xcoord_ = xcoord;
370  ycoord_ = ycoord;
371  zcoord_ = zcoord;
372 
373  //
374  // Hierarchy + FactoryManager
375  //
376 
377  // Hierarchy options
378  this->numDesiredLevel_ = maxLevels;
379  this->maxCoarseSize_ = maxCoarseSize;
380 
381  //
382  // Coarse Smoother
383  //
384  ParameterList& coarseList = paramList.sublist("coarse: list");
385  // check whether coarse solver is set properly. If not, set default coarse solver.
386  if (!coarseList.isParameter("smoother: type"))
387  coarseList.set("smoother: type", "Amesos-KLU"); // set default coarse solver according to ML 5.0 guide
388  RCP<SmootherFactory> coarseFact = GetSmootherFactory(coarseList, Teuchos::null);
389 
390  // Smoothers Top Level Parameters
391 
392  RCP<ParameterList> topLevelSmootherParam = ExtractSetOfParameters(paramList, "smoother");
393 
394  //
395 
396  // Prepare factory managers
397  // TODO: smootherFact can be reuse accross level if same parameters/no specific parameterList
398 
399  for (int levelID = 0; levelID < maxLevels; levelID++) {
400  //
401  // Level FactoryManager
402  //
403 
404  RCP<FactoryManager> manager = rcp(new FactoryManager());
405  if (setKokkosRefactor)
406  manager->SetKokkosRefactor(useKokkosRefactor);
407 
408  //
409  // Smoothers
410  //
411 
412  {
413  // Merge level-specific parameters with global parameters. level-specific parameters takes precedence.
414  // TODO: unit-test this part alone
415 
416  ParameterList levelSmootherParam = GetMLSubList(paramList, "smoother", levelID); // copy
417  MergeParameterList(*topLevelSmootherParam, levelSmootherParam, false); /* false = do no overwrite levelSmootherParam parameters by topLevelSmootherParam parameters */
418  // std::cout << std::endl << "Merged List for level " << levelID << std::endl;
419  // std::cout << levelSmootherParam << std::endl;
420 
421  RCP<SmootherFactory> smootherFact = GetSmootherFactory(levelSmootherParam, Teuchos::null); // TODO: missing AFact input arg.
422 
423  manager->SetFactory("Smoother", smootherFact);
424  }
425 
426  //
427  // Misc
428  //
429 
430  manager->SetFactory("CoarseSolver", coarseFact); // TODO: should not be done in the loop
431  manager->SetFactory("Graph", dropFact);
432  manager->SetFactory("Aggregates", AggFact);
433  manager->SetFactory("DofsPerNode", dropFact);
434  manager->SetFactory("Ptent", PtentFact);
435 
436 #if defined(HAVE_MUELU_ISORROPIA) && defined(HAVE_MPI)
437  if (bDoRepartition == 1) {
438  manager->SetFactory("A", RebalancedAFact);
439  manager->SetFactory("P", RebalancedPFact);
440  manager->SetFactory("R", RebalancedRFact);
441  manager->SetFactory("Nullspace", RebalancedPFact);
442  manager->SetFactory("Importer", RepartitionFact);
443  } else {
444 #endif // #ifdef HAVE_MUELU_ISORROPIA
445  manager->SetFactory("Nullspace", nspFact); // use same nullspace factory throughout all multigrid levels
446  manager->SetFactory("A", AcFact); // same RAP factory for all levels
447  manager->SetFactory("P", PFact); // same prolongator and restrictor factories for all levels
448  manager->SetFactory("R", RFact); // same prolongator and restrictor factories for all levels
449 #if defined(HAVE_MUELU_ISORROPIA) && defined(HAVE_MPI)
450  }
451 #endif
452 
453  this->AddFactoryManager(levelID, 1, manager);
454  } // for (level loop)
455 }
456 
457 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
459  // if nullspace_ has already been extracted from ML parameter list
460  // make nullspace available for MueLu
461  if (nullspace_ != NULL) {
462  RCP<Level> fineLevel = H.GetLevel(0);
463  RCP<Operator> Op = fineLevel->Get<RCP<Operator> >("A");
464  RCP<Matrix> A = rcp_dynamic_cast<Matrix>(Op);
465  if (!A.is_null()) {
466  const RCP<const Map> rowMap = fineLevel->Get<RCP<Matrix> >("A")->getRowMap();
467  RCP<MultiVector> nullspace = MultiVectorFactory::Build(rowMap, nullspaceDim_, true);
468 
469  for (size_t i = 0; i < Teuchos::as<size_t>(nullspaceDim_); i++) {
470  Teuchos::ArrayRCP<Scalar> nullspacei = nullspace->getDataNonConst(i);
471  const size_t myLength = nullspace->getLocalLength();
472 
473  for (size_t j = 0; j < myLength; j++) {
474  nullspacei[j] = nullspace_[i * myLength + j];
475  }
476  }
477 
478  fineLevel->Set("Nullspace", nullspace);
479  }
480  }
481 
482  // Do the same for coordinates
483  size_t num_coords = 0;
484  double* coordPTR[3];
485  if (xcoord_) {
486  coordPTR[0] = xcoord_;
487  num_coords++;
488  if (ycoord_) {
489  coordPTR[1] = ycoord_;
490  num_coords++;
491  if (zcoord_) {
492  coordPTR[2] = zcoord_;
493  num_coords++;
494  }
495  }
496  }
497  if (num_coords) {
498  Teuchos::RCP<Level> fineLevel = H.GetLevel(0);
499  Teuchos::RCP<Operator> Op = fineLevel->Get<RCP<Operator> >("A");
500  Teuchos::RCP<Matrix> A = rcp_dynamic_cast<Matrix>(Op);
501  if (!A.is_null()) {
502  const Teuchos::RCP<const Map> rowMap = fineLevel->Get<RCP<Matrix> >("A")->getRowMap();
503  Teuchos::RCP<MultiVector> coordinates = MultiVectorFactory::Build(rowMap, num_coords, true);
504 
505  for (size_t i = 0; i < num_coords; i++) {
506  Teuchos::ArrayRCP<Scalar> coordsi = coordinates->getDataNonConst(i);
507  const size_t myLength = coordinates->getLocalLength();
508  for (size_t j = 0; j < myLength; j++) {
509  coordsi[j] = coordPTR[i][j];
510  }
511  }
512  fineLevel->Set("Coordinates", coordinates);
513  }
514  }
515 
517 }
518 
519 // TODO: code factorization with MueLu_ParameterListInterpreter.
520 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
524  const RCP<FactoryBase>& AFact) {
525  typedef Teuchos::ScalarTraits<Scalar> STS;
526  SC one = STS::one();
527 
528  std::string type = "symmetric Gauss-Seidel"; // default
529 
530  //
531  // Get 'type'
532  //
533 
534  // //TODO: fix defaults!!
535 
536  // // Default coarse grid smoother
537  // std::string type;
538  // if ("smoother" == "coarse") {
539  // #if (defined(HAVE_MUELU_EPETRA) && defined( HAVE_MUELU_AMESOS)) || (defined(HAVE_MUELU_AMESOS2)) // FIXME: test is wrong (ex: compiled with Epetra&&Tpetra&&Amesos2 but without Amesos => error running Epetra problem)
540  // type = ""; // use default defined by AmesosSmoother or Amesos2Smoother
541  // #else
542  // type = "symmetric Gauss-Seidel"; // use a sym Gauss-Seidel (with no damping) as fallback "coarse solver" (TODO: needs Ifpack(2))
543  // #endif
544  // } else {
545  // // TODO: default smoother?
546  // type = "";
547  // }
548 
549  if (paramList.isParameter("smoother: type")) type = paramList.get<std::string>("smoother: type");
550  TEUCHOS_TEST_FOR_EXCEPTION(type.empty(), Exceptions::RuntimeError, "MueLu::MLParameterListInterpreter: no \"smoother: type\" in the smoother parameter list" << std::endl
551  << paramList);
552 
553  //
554  // Create the smoother prototype
555  //
556 
557  RCP<SmootherPrototype> smooProto;
558  std::string ifpackType;
559  Teuchos::ParameterList smootherParamList;
560 
561  if (type == "Jacobi" || type == "Gauss-Seidel" || type == "symmetric Gauss-Seidel") {
562  if (type == "symmetric Gauss-Seidel") type = "Symmetric Gauss-Seidel"; // FIXME
563 
564  ifpackType = "RELAXATION";
565  smootherParamList.set("relaxation: type", type);
566 
567  MUELU_COPY_PARAM(paramList, "smoother: sweeps", int, 2, smootherParamList, "relaxation: sweeps");
568  MUELU_COPY_PARAM(paramList, "smoother: damping factor", Scalar, one, smootherParamList, "relaxation: damping factor");
569 
570  smooProto = rcp(new TrilinosSmoother(ifpackType, smootherParamList, 0));
571  smooProto->SetFactory("A", AFact);
572 
573  } else if (type == "Chebyshev" || type == "MLS") {
574  ifpackType = "CHEBYSHEV";
575 
576  MUELU_COPY_PARAM(paramList, "smoother: sweeps", int, 2, smootherParamList, "chebyshev: degree");
577  if (paramList.isParameter("smoother: MLS alpha")) {
578  MUELU_COPY_PARAM(paramList, "smoother: MLS alpha", double, 20, smootherParamList, "chebyshev: ratio eigenvalue");
579  } else {
580  MUELU_COPY_PARAM(paramList, "smoother: Chebyshev alpha", double, 20, smootherParamList, "chebyshev: ratio eigenvalue");
581  }
582 
583  smooProto = rcp(new TrilinosSmoother(ifpackType, smootherParamList, 0));
584  smooProto->SetFactory("A", AFact);
585 
586  } else if (type == "Hiptmair") {
587  ifpackType = "HIPTMAIR";
588  std::string subSmootherType = "Chebyshev";
589  if (paramList.isParameter("subsmoother: type"))
590  subSmootherType = paramList.get<std::string>("subsmoother: type");
591  std::string subSmootherIfpackType;
592  if (subSmootherType == "Chebyshev")
593  subSmootherIfpackType = "CHEBYSHEV";
594  else if (subSmootherType == "Jacobi" || subSmootherType == "Gauss-Seidel" || subSmootherType == "symmetric Gauss-Seidel") {
595  if (subSmootherType == "symmetric Gauss-Seidel") subSmootherType = "Symmetric Gauss-Seidel"; // FIXME
596  subSmootherIfpackType = "RELAXATION";
597  } else
598  TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, "MueLu::MLParameterListInterpreter: unknown smoother type. '" << subSmootherType << "' not supported by MueLu.");
599 
600  smootherParamList.set("hiptmair: smoother type 1", subSmootherIfpackType);
601  smootherParamList.set("hiptmair: smoother type 2", subSmootherIfpackType);
602 
603  auto smoother1ParamList = smootherParamList.sublist("hiptmair: smoother list 1");
604  auto smoother2ParamList = smootherParamList.sublist("hiptmair: smoother list 2");
605 
606  if (subSmootherType == "Chebyshev") {
607  MUELU_COPY_PARAM(paramList, "subsmoother: edge sweeps", int, 2, smoother1ParamList, "chebyshev: degree");
608  MUELU_COPY_PARAM(paramList, "subsmoother: node sweeps", int, 2, smoother2ParamList, "chebyshev: degree");
609 
610  MUELU_COPY_PARAM(paramList, "subsmoother: Chebyshev", double, 20, smoother1ParamList, "chebyshev: ratio eigenvalue");
611  MUELU_COPY_PARAM(paramList, "subsmoother: Chebyshev", double, 20, smoother2ParamList, "chebyshev: ratio eigenvalue");
612  } else {
613  MUELU_COPY_PARAM(paramList, "subsmoother: edge sweeps", int, 2, smoother1ParamList, "relaxation: sweeps");
614  MUELU_COPY_PARAM(paramList, "subsmoother: node sweeps", int, 2, smoother2ParamList, "relaxation: sweeps");
615 
616  MUELU_COPY_PARAM(paramList, "subsmoother: SGS damping factor", double, 0.8, smoother2ParamList, "relaxation: damping factor");
617  }
618 
619  smooProto = rcp(new TrilinosSmoother(ifpackType, smootherParamList, 0));
620  smooProto->SetFactory("A", AFact);
621 
622  } else if (type == "IFPACK") { // TODO: this option is not described in the ML Guide v5.0
623 
624 #if defined(HAVE_MUELU_EPETRA) && defined(HAVE_MUELU_IFPACK)
625  ifpackType = paramList.get<std::string>("smoother: ifpack type");
626 
627  if (ifpackType == "ILU") {
628  // TODO fix this (type mismatch double vs. int)
629  // MUELU_COPY_PARAM(paramList, "smoother: ifpack level-of-fill", double /*int*/, 0.0 /*2*/, smootherParamList, "fact: level-of-fill");
630  if (paramList.isParameter("smoother: ifpack level-of-fill"))
631  smootherParamList.set("fact: level-of-fill", Teuchos::as<int>(paramList.get<double>("smoother: ifpack level-of-fill")));
632  else
633  smootherParamList.set("fact: level-of-fill", as<int>(0));
634 
635  MUELU_COPY_PARAM(paramList, "smoother: ifpack overlap", int, 2, smootherParamList, "partitioner: overlap");
636 
637  // TODO change to TrilinosSmoother as soon as Ifpack2 supports all preconditioners from Ifpack
638  smooProto =
639  MueLu::GetIfpackSmoother<Scalar, LocalOrdinal, GlobalOrdinal, Node>(ifpackType,
640  smootherParamList,
641  paramList.get<int>("smoother: ifpack overlap"));
642  smooProto->SetFactory("A", AFact);
643  } else {
644  TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, "MueLu::MLParameterListInterpreter: unknown ML smoother type " + type + " (IFPACK) not supported by MueLu. Only ILU is supported.");
645  }
646 #else
647  TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, "MueLu::MLParameterListInterpreter: MueLu compiled without Ifpack support");
648 #endif
649 
650  } else if (type.length() > strlen("Amesos") && type.substr(0, strlen("Amesos")) == "Amesos") { /* catch Amesos-* */
651  std::string solverType = type.substr(strlen("Amesos") + 1); /* ("Amesos-KLU" -> "KLU") */
652 
653  // Validator: following upper/lower case is what is allowed by ML
654  bool valid = false;
655  const int validatorSize = 5;
656  std::string validator[validatorSize] = {"Superlu", "Superludist", "KLU", "UMFPACK", "MUMPS"}; /* TODO: should "" be allowed? */
657  for (int i = 0; i < validatorSize; i++) {
658  if (validator[i] == solverType) valid = true;
659  }
660  TEUCHOS_TEST_FOR_EXCEPTION(!valid, Exceptions::RuntimeError, "MueLu::MLParameterListInterpreter: unknown smoother type. '" << type << "' not supported.");
661 
662  // FIXME: MueLu should accept any Upper/Lower case. Not the case for the moment
663  std::transform(solverType.begin() + 1, solverType.end(), solverType.begin() + 1, ::tolower);
664 
665  smooProto = Teuchos::rcp(new DirectSolver(solverType, Teuchos::ParameterList()));
666  smooProto->SetFactory("A", AFact);
667 
668  } else {
669  TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, "MueLu::MLParameterListInterpreter: unknown smoother type. '" << type << "' not supported by MueLu.");
670  }
671  TEUCHOS_TEST_FOR_EXCEPTION(smooProto == Teuchos::null, Exceptions::RuntimeError, "MueLu::MLParameterListInterpreter: no smoother prototype. fatal error.");
672 
673  //
674  // Create the smoother factory
675  //
676 
677  RCP<SmootherFactory> SmooFact = rcp(new SmootherFactory());
678 
679  // Set parameters of the smoother factory
680  MUELU_READ_PARAM(paramList, "smoother: pre or post", std::string, "both", preOrPost);
681  if (preOrPost == "both") {
682  SmooFact->SetSmootherPrototypes(smooProto, smooProto);
683  } else if (preOrPost == "pre") {
684  SmooFact->SetSmootherPrototypes(smooProto, Teuchos::null);
685  } else if (preOrPost == "post") {
686  SmooFact->SetSmootherPrototypes(Teuchos::null, smooProto);
687  }
688 
689  return SmooFact;
690 }
691 
692 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
694  // check if it's a TwoLevelFactoryBase based transfer factory
695  TEUCHOS_TEST_FOR_EXCEPTION(Teuchos::rcp_dynamic_cast<TwoLevelFactoryBase>(factory) == Teuchos::null, Exceptions::BadCast, "Transfer factory is not derived from TwoLevelFactoryBase. Since transfer factories will be handled by the RAPFactory they have to be derived from TwoLevelFactoryBase!");
696  TransferFacts_.push_back(factory);
697 }
698 
699 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
701  return TransferFacts_.size();
702 }
703 
704 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
706  try {
707  Matrix& A = dynamic_cast<Matrix&>(Op);
708  if (A.IsFixedBlockSizeSet() && (A.GetFixedBlockSize() != blksize_))
709  this->GetOStream(Warnings0) << "Setting matrix block size to " << blksize_ << " (value of the parameter in the list) "
710  << "instead of " << A.GetFixedBlockSize() << " (provided matrix)." << std::endl;
711 
712  A.SetFixedBlockSize(blksize_);
713 
714 #ifdef HAVE_MUELU_DEBUG
715  MatrixUtils::checkLocalRowMapMatchesColMap(A);
716 #endif // HAVE_MUELU_DEBUG
717 
718  } catch (std::bad_cast&) {
719  this->GetOStream(Warnings0) << "Skipping setting block size as the operator is not a matrix" << std::endl;
720  }
721 }
722 
723 } // namespace MueLu
724 
725 #define MUELU_MLPARAMETERLISTINTERPRETER_SHORT
726 #endif /* MUELU_MLPARAMETERLISTINTERPRETER_DEF_HPP */
727 
728 // TODO: see if it can be factorized with ML interpreter (ex: generation of Ifpack param list)
Important warning messages (one line)
Generic Smoother Factory for generating the smoothers of the MG hierarchy.
Exception indicating invalid cast attempted.
This class specifies the default factory that should generate some data on a Level if the data does n...
void MergeParameterList(const Teuchos::ParameterList &source, Teuchos::ParameterList &dest, bool overWrite)
: merge two parameter lists
Factory for determing the number of partitions for rebalancing.
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access). Usage: Level-&gt;Get&lt; RCP&lt;Matrix&gt; &gt;(&quot;A&quot;, factory) if factory == NULL =&gt; use default factory.
RCP< Level > & GetLevel(const int levelID=0)
Retrieve a certain level from hierarchy.
virtual void SetFactory(const std::string &varName, const RCP< const FactoryBase > &factory)
Configuration.
T & get(const std::string &name, T def_value)
Class that encapsulates external library smoothers.
Interface to IsorropiaInterface to Isorropia allowing to access other rebalancing/repartitioning algo...
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Factory for building permutation matrix that can be be used to shuffle data (matrices, vectors) among processes.
void SetKokkosRefactor(const bool useKokkos)
std::string tolower(const std::string &str)
void AddTransferFactory(const RCP< const FactoryBase > &factory)
Add transfer factory in the end of list of transfer factories in RepartitionAcFactory.
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
#define MUELU_READ_PARAM(paramList, paramStr, varType, defaultValue, varName)
const Teuchos::ParameterList & GetMLSubList(const Teuchos::ParameterList &paramList, const std::string &type, int levelID)
void AddTransferFactory(const RCP< FactoryBase > &factory)
Add transfer factory in the end of list of transfer factories for RAPFactory.
Factory for building tentative prolongator.
Class that encapsulates direct solvers. Autoselection of AmesosSmoother or Amesos2Smoother according ...
Factory for building restriction operators using a prolongator factory.
virtual void SetupHierarchy(Hierarchy &H) const
Setup Hierarchy object.
bool isParameter(const std::string &name) const
void CreateSublists(const ParameterList &List, ParameterList &newList)
bool remove(std::string const &name, bool throwIfNotExists=true)
virtual void SetParameterList(const Teuchos::ParameterList &paramList)
Set parameters from a parameter list and return with default values.
void SetSmootherPrototypes(RCP< SmootherPrototype > preAndPostSmootherPrototype)
Set smoother prototypes.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
MueLu::DefaultScalar Scalar
static RCP< SmootherFactory > GetSmootherFactory(const Teuchos::ParameterList &paramList, const RCP< FactoryBase > &AFact=Teuchos::null)
Read smoother options and build the corresponding smoother factory.
virtual void SetupOperator(Operator &Op) const
Setup Operator object.
Teuchos::RCP< Teuchos::ParameterList > ExtractSetOfParameters(const Teuchos::ParameterList &paramList, const std::string &str)
size_t NumTransferFactories() const
Returns number of transfer factories.
AmalgamationFactory for subblocks of strided map based amalgamation data.
Applies permutation to grid transfer operators.
void Set(const std::string &ename, const T &entry, const FactoryBase *factory=NoFactory::get())
virtual void SetupHierarchy(Hierarchy &H) const
Setup Hierarchy object.
void SetParameter(const std::string &name, const ParameterEntry &entry)
Set a parameter directly as a ParameterEntry.
void SetFactory(const std::string &varName, const RCP< const FactoryBase > &factory)
Set Factory.
Factory for creating a graph based on a given matrix.
Helper class which transforms an &quot;AmalgamatedPartition&quot; array to an unamalgamated &quot;Partition&quot;...
void SetParameterList(const Teuchos::ParameterList &paramList)
Scalar SC
bool isType(const std::string &name) const
Factory for building restriction operators.
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
Factory for creating a graph based on a given matrix.
Factory for building coarse matrices.
Exception throws to report errors in the internal logical of the program.
Description of what is happening (more verbose)
Factory for building coarse matrices.
#define MUELU_COPY_PARAM(paramList, paramStr, varType, defaultValue, outParamList, outParamStr)
Factory for building Petrov-Galerkin Smoothed Aggregation prolongators.
Factory for building Smoothed Aggregation prolongators.Input/output of SaPFactory
Factory for building uncoupled aggregates.
Provides methods to build a multigrid hierarchy and apply multigrid cycles.
Factory for generating nullspace.
bool is_null() const