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