MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MueLu_ML2MueLuParameterTranslator.cpp
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 
47 #include "MueLu_ConfigDefs.hpp"
48 #if defined(HAVE_MUELU_ML)
49 #include <ml_config.h>
50 #if defined(HAVE_ML_EPETRA) && defined(HAVE_ML_TEUCHOS)
51 #include <ml_ValidateParameters.h>
52 #include <ml_MultiLevelPreconditioner.h> // for default values
53 #include <ml_RefMaxwell.h>
54 #endif
55 #endif
56 
58 
59 namespace MueLu {
60 
61 std::string ML2MueLuParameterTranslator::GetSmootherFactory(const Teuchos::ParameterList& paramList, Teuchos::ParameterList& adaptingParamList, const std::string& pname, const std::string& value) {
62  TEUCHOS_TEST_FOR_EXCEPTION(pname != "coarse: type" && pname != "coarse: list" && pname != "smoother: type" && pname.find("smoother: list", 0) != 0,
64  "MueLu::MLParameterListInterpreter::Setup(): Only \"coarse: type\", \"smoother: type\" or \"smoother: list\" (\"coarse: list\") are "
65  "supported as ML parameters for transformation of smoother/solver parameters to MueLu");
66 
67  // string stream containing the smoother/solver xml parameters
68  std::stringstream mueluss;
69 
70  // Check whether we are dealing with coarse level (solver) parameters or level smoother parameters
71  std::string mode = "smoother:";
72  bool is_coarse = false;
73  if (pname.find("coarse:", 0) == 0) {
74  mode = "coarse:";
75  is_coarse = true;
76  }
77 
78  // check whether pre and/or post smoothing
79  std::string PreOrPost = "both";
80  if (paramList.isParameter(mode + " pre or post"))
81  PreOrPost = paramList.get<std::string>(mode + " pre or post");
82 
83  TEUCHOS_TEST_FOR_EXCEPTION(mode == "coarse:" && PreOrPost != "both", Exceptions::RuntimeError,
84  "MueLu::MLParameterListInterpreter::Setup(): The parameter \"coarse: pre or post\" is not supported by MueLu. "
85  "It does not make sense for direct solvers. For iterative solvers you obtain the same effect by increasing, "
86  "e.g., the number of sweeps for the coarse grid smoother. Please remove it from your parameters.");
87 
88  // select smoother type
89  std::string valuestr = value; // temporary variable
90  std::transform(valuestr.begin(), valuestr.end(), valuestr.begin(), ::tolower);
91  if (valuestr == "jacobi" || valuestr == "gauss-seidel" || valuestr == "symmetric gauss-seidel") {
92  std::string my_name;
93  if (PreOrPost == "both")
94  my_name = "\"" + pname + "\"";
95  else
96  my_name = "\"smoother: " + PreOrPost + " type\"";
97  mueluss << "<Parameter name=" << my_name << " type=\"string\" value=\"RELAXATION\"/>" << std::endl;
98 
99  } else if (valuestr == "hiptmair") {
100  std::string my_name;
101  if (PreOrPost == "both")
102  my_name = "\"" + pname + "\"";
103  else
104  my_name = "\"smoother: " + PreOrPost + " type\"";
105  mueluss << "<Parameter name=" << my_name << " type=\"string\" value=\"HIPTMAIR\"/>" << std::endl;
106 
107  } else if (valuestr == "ifpack") {
108  std::string my_name = "\"" + pname + "\"";
109  if (paramList.isParameter("smoother: ifpack type")) {
110  if (paramList.get<std::string>("smoother: ifpack type") == "ILU") {
111  mueluss << "<Parameter name=" << my_name << " type=\"string\" value=\"ILU\"/>" << std::endl;
112  adaptingParamList.remove("smoother: ifpack type", false);
113  }
114  if (paramList.get<std::string>("smoother: ifpack type") == "ILUT") {
115  mueluss << "<Parameter name=" << my_name << " type\" type=\"string\" value=\"ILUT\"/>" << std::endl;
116  adaptingParamList.remove("smoother: ifpack type", false);
117  }
118  }
119 
120  } else if ((valuestr == "chebyshev") || (valuestr == "mls")) {
121  std::string my_name = "\"" + pname + "\"";
122  mueluss << "<Parameter name=" << my_name << " type=\"string\" value=\"CHEBYSHEV\"/>" << std::endl;
123 
124  } else if (valuestr.length() > strlen("amesos") && valuestr.substr(0, strlen("amesos")) == "amesos") { /* catch Amesos-* */
125  std::string solverType = valuestr.substr(strlen("amesos") + 1); /* ("amesos-klu" -> "klu") */
126 
127  bool valid = false;
128  const int validatorSize = 5;
129  std::string validator[validatorSize] = {"superlu", "superludist", "klu", "umfpack", "mumps"};
130  for (int i = 0; i < validatorSize; i++)
131  if (validator[i] == solverType)
132  valid = true;
134  "MueLu::MLParameterListInterpreter: unknown smoother type. '" << solverType << "' not supported.");
135 
136  mueluss << "<Parameter name=\"" << pname << "\" type=\"string\" value=\"" << solverType << "\"/>" << std::endl;
137 
138  } else {
139  // TODO error message
140  std::cout << "error in " << __FILE__ << ":" << __LINE__ << " could not find valid smoother/solver" << std::endl;
141  }
142 
143  // set smoother: pre or post parameter
144  // Note that there is no "coarse: pre or post" in MueLu!
145  if (paramList.isParameter("smoother: pre or post") && mode == "smoother:") {
146  // std::cout << "paramList" << paramList << std::endl;
147  // std::string smootherPreOrPost = paramList.get<std::string>("smoother: pre or post");
148  // std::cout << "Create pre or post parameter with " << smootherPreOrPost << std::endl;
149  mueluss << "<Parameter name=\"smoother: pre or post\" type=\"string\" value=\"" << PreOrPost << "\"/>" << std::endl;
150  adaptingParamList.remove("smoother: pre or post", false);
151  }
152 
153  // create smoother parameter list
154  if (PreOrPost != "both") {
155  mueluss << "<ParameterList name=\"smoother: " << PreOrPost << " params\">" << std::endl;
156  } else {
157  mueluss << "<ParameterList name=\"" << mode << " params\">" << std::endl;
158  }
159 
160  // relaxation based smoothers:
161 
162  if (valuestr == "jacobi" || valuestr == "gauss-seidel" || valuestr == "symmetric gauss-seidel") {
163  if (valuestr == "jacobi") {
164  mueluss << "<Parameter name=\"relaxation: type\" type=\"string\" value=\"Jacobi\"/>" << std::endl;
165  adaptingParamList.remove("relaxation: type", false);
166  }
167  if (valuestr == "gauss-seidel") {
168  mueluss << "<Parameter name=\"relaxation: type\" type=\"string\" value=\"Gauss-Seidel\"/>" << std::endl;
169  adaptingParamList.remove("relaxation: type", false);
170  }
171  if (valuestr == "symmetric gauss-seidel") {
172  mueluss << "<Parameter name=\"relaxation: type\" type=\"string\" value=\"Symmetric Gauss-Seidel\"/>" << std::endl;
173  adaptingParamList.remove("relaxation: type", false);
174  }
175 
176  if (paramList.isParameter("smoother: sweeps")) {
177  mueluss << "<Parameter name=\"relaxation: sweeps\" type=\"int\" value=\"" << paramList.get<int>("smoother: sweeps") << "\"/>" << std::endl;
178  adaptingParamList.remove("smoother: sweeps", false);
179  }
180  if (paramList.isParameter("smoother: damping factor")) {
181  mueluss << "<Parameter name=\"relaxation: damping factor\" type=\"double\" value=\"" << paramList.get<double>("smoother: damping factor") << "\"/>" << std::endl;
182  adaptingParamList.remove("smoother: damping factor", false);
183  }
184  if (paramList.isParameter("smoother: use l1 Gauss-Seidel")) {
185  mueluss << "<Parameter name=\"relaxation: use l1\" type=\"bool\" value=\"" << paramList.get<bool>("smoother: use l1 Gauss-Seidel") << "\"/>" << std::endl;
186  adaptingParamList.remove("smoother: use l1 Gauss-Seidel", false);
187  }
188  }
189 
190  // Chebyshev
191  if (valuestr == "chebyshev") {
192  if (paramList.isParameter("smoother: polynomial order")) {
193  mueluss << "<Parameter name=\"chebyshev: degree\" type=\"int\" value=\"" << paramList.get<int>("smoother: polynomial order") << "\"/>" << std::endl;
194  adaptingParamList.remove("smoother: polynomial order", false);
195  } else {
196  mueluss << "<Parameter name=\"chebyshev: degree\" type=\"int\" value=\"2\"/>" << std::endl;
197  }
198  if (paramList.isParameter("smoother: Chebyshev alpha")) {
199  mueluss << "<Parameter name=\"chebyshev: ratio eigenvalue\" type=\"double\" value=\"" << paramList.get<double>("smoother: Chebyshev alpha") << "\"/>" << std::endl;
200  adaptingParamList.remove("smoother: Chebyshev alpha", false);
201  } else {
202  mueluss << "<Parameter name=\"chebyshev: ratio eigenvalue\" type=\"double\" value=\"20\"/>" << std::endl;
203  adaptingParamList.remove("smoother: Chebyshev alpha", false);
204  }
205  if (paramList.isParameter("eigen-analysis: type")) {
206  mueluss << "<Parameter name=\"eigen-analysis: type\" type=\"string\" value=\"" << paramList.get<std::string>("eigen-analysis: type") << "\"/>" << std::endl;
207  adaptingParamList.remove("eigen-analysis: type", false);
208  } else {
209  mueluss << "<Parameter name=\"eigen-analysis: type\" type=\"string\" value=\"cg\"/>" << std::endl;
210  }
211  }
212 
213  // MLS
214  if (valuestr == "mls") {
215  if (paramList.isParameter("smoother: MLS polynomial order")) {
216  mueluss << "<Parameter name=\"chebyshev: degree\" type=\"int\" value=\"" << paramList.get<int>("smoother: MLS polynomial order") << "\"/>" << std::endl;
217  adaptingParamList.remove("smoother: MLS polynomial order", false);
218  } else if (paramList.isParameter("smoother: polynomial order")) {
219  mueluss << "<Parameter name=\"chebyshev: degree\" type=\"int\" value=\"" << paramList.get<int>("smoother: polynomial order") << "\"/>" << std::endl;
220  adaptingParamList.remove("smoother: polynomial order", false);
221  } else {
222  mueluss << "<Parameter name=\"chebyshev: degree\" type=\"int\" value=\"2\"/>" << std::endl;
223  }
224  if (paramList.isParameter("smoother: MLS alpha")) {
225  mueluss << "<Parameter name=\"chebyshev: ratio eigenvalue\" type=\"double\" value=\"" << paramList.get<double>("smoother: MLS alpha") << "\"/>" << std::endl;
226  adaptingParamList.remove("smoother: MLS alpha", false);
227  } else if (paramList.isParameter("smoother: Chebyshev alpha")) {
228  mueluss << "<Parameter name=\"chebyshev: ratio eigenvalue\" type=\"double\" value=\"" << paramList.get<double>("smoother: Chebyshev alpha") << "\"/>" << std::endl;
229  adaptingParamList.remove("smoother: Chebyshev alpha", false);
230  } else {
231  mueluss << "<Parameter name=\"chebyshev: ratio eigenvalue\" type=\"double\" value=\"20\"/>" << std::endl;
232  }
233  if (paramList.isParameter("eigen-analysis: type")) {
234  mueluss << "<Parameter name=\"eigen-analysis: type\" type=\"string\" value=\"" << paramList.get<std::string>("eigen-analysis: type") << "\"/>" << std::endl;
235  adaptingParamList.remove("eigen-analysis: type", false);
236  } else {
237  mueluss << "<Parameter name=\"eigen-analysis: type\" type=\"string\" value=\"cg\"/>" << std::endl;
238  }
239  }
240 
241  if (valuestr == "hiptmair") {
242  std::string subSmootherType = "Chebyshev";
243  if (!is_coarse && paramList.isParameter("subsmoother: type"))
244  subSmootherType = paramList.get<std::string>("subsmoother: type");
245  if (is_coarse && paramList.isParameter("smoother: subsmoother type"))
246  subSmootherType = paramList.get<std::string>("smoother: subsmoother type");
247 
248  std::string subSmootherIfpackType;
249  if (subSmootherType == "Chebyshev")
250  subSmootherIfpackType = "CHEBYSHEV";
251  else if (subSmootherType == "Jacobi" || subSmootherType == "Gauss-Seidel" || subSmootherType == "symmetric Gauss-Seidel") {
252  if (subSmootherType == "symmetric Gauss-Seidel") subSmootherType = "Symmetric Gauss-Seidel"; // FIXME
253  subSmootherIfpackType = "RELAXATION";
254  } else
255  TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, "MueLu::MLParameterListTranslator: unknown smoother type. '" << subSmootherType << "' not supported by MueLu.");
256 
257  mueluss << "<Parameter name=\"hiptmair: smoother type 1\" type=\"string\" value=\"" << subSmootherIfpackType << "\"/>" << std::endl;
258  mueluss << "<Parameter name=\"hiptmair: smoother type 2\" type=\"string\" value=\"" << subSmootherIfpackType << "\"/>" << std::endl;
259 
260  mueluss << "<ParameterList name=\"hiptmair: smoother list 1\">" << std::endl;
261  if (subSmootherType == "Chebyshev") {
262  std::string edge_sweeps = is_coarse ? "smoother: edge sweeps" : "subsmoother: edge sweeps";
263  std::string cheby_alpha = is_coarse ? "smoother: Chebyshev alpha" : "subsmoother: Chebyshev_alpha";
264 
265  if (paramList.isParameter(edge_sweeps)) {
266  mueluss << "<Parameter name=\"chebyshev: degree\" type=\"int\" value=\"" << paramList.get<int>(edge_sweeps) << "\"/>" << std::endl;
267  adaptingParamList.remove("subsmoother: edge sweeps", false);
268  }
269  if (paramList.isParameter(cheby_alpha)) {
270  mueluss << "<Parameter name=\"chebyshev: ratio eigenvalue\" type=\"double\" value=\"" << paramList.get<double>(cheby_alpha) << "\"/>" << std::endl;
271  }
272  } else {
273  std::string edge_sweeps = is_coarse ? "smoother: edge sweeps" : "subsmoother: edge sweeps";
274  std::string SGS_damping = is_coarse ? "smoother: SGS damping factor" : "subsmoother: SGS damping factor";
275 
276  if (paramList.isParameter(edge_sweeps)) {
277  mueluss << "<Parameter name=\"relaxation: type\" type=\"string\" value=\"" << subSmootherType << "\"/>" << std::endl;
278  mueluss << "<Parameter name=\"relaxation: sweeps\" type=\"int\" value=\"" << paramList.get<int>(edge_sweeps) << "\"/>" << std::endl;
279  adaptingParamList.remove(edge_sweeps, false);
280  }
281  if (paramList.isParameter(SGS_damping)) {
282  mueluss << "<Parameter name=\"relaxation: damping factor\" type=\"double\" value=\"" << paramList.get<double>(SGS_damping) << "\"/>" << std::endl;
283  }
284  }
285  mueluss << "</ParameterList>" << std::endl;
286 
287  mueluss << "<ParameterList name=\"hiptmair: smoother list 2\">" << std::endl;
288  if (subSmootherType == "Chebyshev") {
289  std::string node_sweeps = is_coarse ? "smoother: node sweeps" : "subsmoother: node sweeps";
290  std::string cheby_alpha = is_coarse ? "smoother: Chebyshev alpha" : "subsmoother: Chebyshev_alpha";
291  if (paramList.isParameter(node_sweeps)) {
292  mueluss << "<Parameter name=\"chebyshev: degree\" type=\"int\" value=\"" << paramList.get<int>(node_sweeps) << "\"/>" << std::endl;
293  adaptingParamList.remove("subsmoother: node sweeps", false);
294  }
295  if (paramList.isParameter(cheby_alpha)) {
296  mueluss << "<Parameter name=\"chebyshev: ratio eigenvalue\" type=\"double\" value=\"" << paramList.get<double>(cheby_alpha) << "\"/>" << std::endl;
297  adaptingParamList.remove("subsmoother: Chebyshev alpha", false);
298  }
299  } else {
300  std::string node_sweeps = is_coarse ? "smoother: node sweeps" : "subsmoother: node sweeps";
301  std::string SGS_damping = is_coarse ? "smoother: SGS damping factor" : "subsmoother: SGS damping factor";
302 
303  if (paramList.isParameter(node_sweeps)) {
304  mueluss << "<Parameter name=\"relaxation: type\" type=\"string\" value=\"" << subSmootherType << "\"/>" << std::endl;
305  mueluss << "<Parameter name=\"relaxation: sweeps\" type=\"int\" value=\"" << paramList.get<int>(node_sweeps) << "\"/>" << std::endl;
306  adaptingParamList.remove("subsmoother: node sweeps", false);
307  }
308  if (paramList.isParameter(SGS_damping)) {
309  mueluss << "<Parameter name=\"relaxation: damping factor\" type=\"double\" value=\"" << paramList.get<double>(SGS_damping) << "\"/>" << std::endl;
310  adaptingParamList.remove("subsmoother: SGS damping factor", false);
311  }
312  }
313  mueluss << "</ParameterList>" << std::endl;
314  }
315 
316  // parameters for ILU based preconditioners
317  if (valuestr == "ifpack") {
318  // add Ifpack parameters
319  if (paramList.isParameter("smoother: ifpack overlap")) {
320  mueluss << "<Parameter name=\"partitioner: overlap\" type=\"int\" value=\"" << paramList.get<int>("smoother: ifpack overlap") << "\"/>" << std::endl;
321  adaptingParamList.remove("smoother: ifpack overlap", false);
322  }
323  if (paramList.isParameter("smoother: ifpack level-of-fill")) {
324  mueluss << "<Parameter name=\"fact: level-of-fill\" type=\"int\" value=\"" << paramList.get<int>("smoother: ifpack level-of-fill") << "\"/>" << std::endl;
325  adaptingParamList.remove("smoother: ifpack level-of-fill", false);
326  }
327  if (paramList.isParameter("smoother: ifpack absolute threshold")) {
328  mueluss << "<Parameter name=\"fact: absolute threshold\" type=\"int\" value=\"" << paramList.get<double>("smoother: ifpack absolute threshold") << "\"/>" << std::endl;
329  adaptingParamList.remove("smoother: ifpack absolute threshold", false);
330  }
331  if (paramList.isParameter("smoother: ifpack relative threshold")) {
332  mueluss << "<Parameter name=\"fact: relative threshold\" type=\"int\" value=\"" << paramList.get<double>("smoother: ifpack relative threshold") << "\"/>" << std::endl;
333  adaptingParamList.remove("smoother: ifpack relative threshold", false);
334  }
335  }
336 
337  mueluss << "</ParameterList>" << std::endl;
338 
339  // max coarse level size parameter (outside of smoother parameter lists)
340  if (paramList.isParameter("smoother: max size")) {
341  mueluss << "<Parameter name=\"coarse: max size\" type=\"int\" value=\"" << paramList.get<int>("smoother: max size") << "\"/>" << std::endl;
342  adaptingParamList.remove("smoother: max size", false);
343  }
344 
345  return mueluss.str();
346 }
347 
348 std::string ML2MueLuParameterTranslator::SetParameterList(const Teuchos::ParameterList& paramList_in, const std::string& defaultVals) {
349  Teuchos::ParameterList paramList = paramList_in;
350 
351  RCP<Teuchos::FancyOStream> out = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout)); // TODO: use internal out (GetOStream())
352 
353 #if defined(HAVE_MUELU_ML) && defined(HAVE_ML_EPETRA) && defined(HAVE_ML_TEUCHOS)
354 
355  // TODO alternative with standard parameterlist from ML user guide?
356 
357  if (defaultVals != "") {
358  TEUCHOS_TEST_FOR_EXCEPTION(defaultVals != "SA" && defaultVals != "NSSA" && defaultVals != "refmaxwell" && defaultVals != "Maxwell", Exceptions::RuntimeError,
359  "MueLu::MLParameterListInterpreter: only \"SA\", \"NSSA\", \"refmaxwell\" and \"Maxwell\" allowed as options for ML default parameters.");
360  Teuchos::ParameterList ML_defaultlist;
361  if (defaultVals == "refmaxwell")
362  ML_Epetra::SetDefaultsRefMaxwell(ML_defaultlist);
363  else
364  ML_Epetra::SetDefaults(defaultVals, ML_defaultlist);
365 
366  // merge user parameters with default parameters
367  MueLu::MergeParameterList(paramList_in, ML_defaultlist, true);
368  paramList = ML_defaultlist;
369  }
370 #else
371  if (defaultVals != "") {
372  // If no validator available: issue a warning and set parameter value to false in the output list
373  *out << "Warning: MueLu_ENABLE_ML=OFF, ML_ENABLE_Epetra=OFF or ML_ENABLE_TEUCHOS=OFF. No ML default values available." << std::endl;
374  }
375 #endif // HAVE_MUELU_ML && HAVE_ML_EPETRA && HAVE_ML_TEUCHOS
376 
377  //
378  // Move smoothers/aggregation/coarse parameters to sublists
379  //
380 
381  // ML allows to have level-specific smoothers/aggregation/coarse parameters at the top level of the list or/and defined in sublists:
382  // See also: ML Guide section 6.4.1, MueLu::CreateSublists, ML_CreateSublists
383  ParameterList paramListWithSubList;
384  MueLu::CreateSublists(paramList, paramListWithSubList);
385 
386  paramList = paramListWithSubList; // swap
387  Teuchos::ParameterList adaptingParamList = paramList; // copy of paramList which is used to removed already interpreted parameters
388 
389  //
390  // Validate parameter list
391  //
392  {
393  bool validate = paramList.get("ML validate parameter list", true); /* true = default in ML */
394  if (validate && defaultVals != "refmaxwell") {
395 #if defined(HAVE_MUELU_ML) && defined(HAVE_ML_EPETRA) && defined(HAVE_ML_TEUCHOS)
396  // Validate parameter list using ML validator
397  int depth = paramList.get("ML validate depth", 5); /* 5 = default in ML */
398  TEUCHOS_TEST_FOR_EXCEPTION(!ML_Epetra::ValidateMLPParameters(paramList, depth), Exceptions::RuntimeError,
399  "ERROR: ML's Teuchos::ParameterList contains incorrect parameter!");
400 #else
401  // If no validator available: issue a warning and set parameter value to false in the output list
402  *out << "Warning: MueLu_ENABLE_ML=OFF, ML_ENABLE_Epetra=OFF or ML_ENABLE_TEUCHOS=OFF. The parameter list cannot be validated." << std::endl;
403  paramList.set("ML validate parameter list", false);
404 
405 #endif // HAVE_MUELU_ML && HAVE_ML_EPETRA && HAVE_ML_TEUCHOS
406  } // if(validate)
407  } // scope
408 
409  {
410  // Special handling of ML's aux aggregation
411  //
412  // In ML, when "aggregation: aux: enable" == true, the threshold
413  // is set via "aggregation: aux: threshold" instead of
414  // "aggregation: threshold". In MueLu, we use "aggregation: drop
415  // tol" regardless of "sa: use filtering". So depending on
416  // "aggregation: aux: enable" we use either one or the other
417  // threshold to set "aggregation: drop tol".
418  if (paramListWithSubList.isParameter("aggregation: aux: enable") && paramListWithSubList.get<bool>("aggregation: aux: enable")) {
419  if (paramListWithSubList.isParameter("aggregation: aux: threshold")) {
420  paramListWithSubList.set("aggregation: threshold", paramListWithSubList.get<double>("aggregation: aux: threshold"));
421  paramListWithSubList.remove("aggregation: aux: threshold");
422  }
423  }
424  }
425 
426  // stringstream for concatenating xml parameter strings.
427  std::stringstream mueluss;
428 
429  // create surrounding MueLu parameter list
430  mueluss << "<ParameterList name=\"MueLu\">" << std::endl;
431 
432  // make sure that MueLu's phase1 matches ML's
433  mueluss << "<Parameter name=\"aggregation: match ML phase1\" type=\"bool\" value=\"true\"/>" << std::endl;
434 
435  // make sure that MueLu's phase2a matches ML's
436  mueluss << "<Parameter name=\"aggregation: match ML phase2a\" type=\"bool\" value=\"true\"/>" << std::endl;
437 
438  // make sure that MueLu's phase2b matches ML's
439  mueluss << "<Parameter name=\"aggregation: match ML phase2b\" type=\"bool\" value=\"true\"/>" << std::endl;
440 
441  // make sure that MueLu's drop tol matches ML's
442  mueluss << "<Parameter name=\"aggregation: use ml scaling of drop tol\" type=\"bool\" value=\"true\"/>" << std::endl;
443 
444  // loop over all ML parameters in provided parameter list
445  for (ParameterList::ConstIterator param = paramListWithSubList.begin(); param != paramListWithSubList.end(); ++param) {
446  // extract ML parameter name
447  const std::string& pname = paramListWithSubList.name(param);
448 
449  // extract corresponding (ML) value
450  // remove ParameterList specific information from result string
451  std::stringstream valuess;
452  valuess << paramList.entry(param);
453  std::string valuestr = valuess.str();
454  replaceAll(valuestr, "[unused]", "");
455  replaceAll(valuestr, "[default]", "");
456  valuestr = trim(valuestr);
457 
458  // transform ML parameter to corresponding MueLu parameter and generate XML string
459  std::string valueInterpreterStr = "\"" + valuestr + "\"";
460  std::string ret = MasterList::interpretParameterName(MasterList::ML2MueLu(pname), valueInterpreterStr);
461 
462  if ((pname == "aggregation: aux: enable") && (paramListWithSubList.get<bool>("aggregation: aux: enable"))) {
463  mueluss << "<Parameter name=\"aggregation: drop scheme\" type=\"string\" value=\""
464  << "distance laplacian"
465  << "\"/>" << std::endl;
466  }
467 
468  // special handling for verbosity level
469  if (pname == "ML output") {
470  // Translate verbosity parameter
471  int verbosityLevel = std::stoi(valuestr);
472  std::string eVerbLevel = "none";
473  if (verbosityLevel == 0) eVerbLevel = "none";
474  if (verbosityLevel >= 1) eVerbLevel = "low";
475  if (verbosityLevel >= 5) eVerbLevel = "medium";
476  if (verbosityLevel >= 10) eVerbLevel = "high";
477  if (verbosityLevel >= 11) eVerbLevel = "extreme";
478  if (verbosityLevel >= 42) eVerbLevel = "test";
479  if (verbosityLevel >= 666) eVerbLevel = "interfacetest";
480  mueluss << "<Parameter name=\"verbosity\" type=\"string\" value=\"" << eVerbLevel << "\"/>" << std::endl;
481  continue;
482  }
483 
484  // add XML string
485  if (ret != "") {
486  mueluss << ret << std::endl;
487 
488  // remove parameter from ML parameter list
489  adaptingParamList.remove(pname, false);
490  }
491 
492  // special handling for energy minimization
493  // TAW: this is not optimal for symmetric problems but at least works.
494  // for symmetric problems the "energy minimization" parameter should not exist anyway...
495  if (pname == "energy minimization: enable") {
496  mueluss << "<Parameter name=\"problem: symmetric\" type=\"bool\" value=\"false\"/>" << std::endl;
497  mueluss << "<Parameter name=\"transpose: use implicit\" type=\"bool\" value=\"false\"/>" << std::endl;
498  }
499 
500  // special handling for smoothers
501  if (pname == "smoother: type") {
502  mueluss << GetSmootherFactory(paramList, adaptingParamList, pname, valuestr);
503  }
504 
505  // special handling for level-specific smoothers
506  if (pname.find("smoother: list (level", 0) == 0) {
507  // Scan pname (ex: pname="smoother: type (level 2)")
508  std::string type, option;
509  int levelID = -1;
510  {
511  typedef Teuchos::ArrayRCP<char>::size_type size_type;
512  Teuchos::Array<char> ctype(size_type(pname.size() + 1));
513  Teuchos::Array<char> coption(size_type(pname.size() + 1));
514 
515  int matched = sscanf(pname.c_str(), "%s %[^(](level %d)", ctype.getRawPtr(), coption.getRawPtr(), &levelID); // use [^(] instead of %s to allow for strings with white-spaces (ex: "ifpack list")
516  type = std::string(ctype.getRawPtr());
517  option = std::string(coption.getRawPtr());
518  option.resize(option.size() - 1); // remove final white-space
519 
520  if (matched != 3 || (type != "smoother:")) {
521  TEUCHOS_TEST_FOR_EXCEPTION(true, MueLu::Exceptions::RuntimeError, "MueLu::CreateSublist(), Line " << __LINE__ << ". "
522  << "Error in creating level-specific sublists" << std::endl
523  << "Offending parameter: " << pname << std::endl);
524  }
525 
526  mueluss << "<ParameterList name=\"level " << levelID << "\">" << std::endl;
527  mueluss << GetSmootherFactory(paramList.sublist(pname), adaptingParamList.sublist(pname), "smoother: type", paramList.sublist(pname).get<std::string>("smoother: type"));
528  mueluss << "</ParameterList>" << std::endl;
529  }
530  }
531 
532  // special handling for coarse level
533  TEUCHOS_TEST_FOR_EXCEPTION(paramList.isParameter("coarse: type"), Exceptions::RuntimeError, "MueLu::MLParameterListInterpreter::Setup(): The parameter \"coarse: type\" should not exist but being stored in \"coarse: list\" instead.");
534  if (pname == "coarse: list") {
535  // interpret smoother/coarse solver data.
536  // Note, that we inspect the "coarse: list" sublist to define the "coarse" smoother/solver
537  // Be aware, that MueLu::CreateSublists renames the prefix of the parameters in the "coarse: list" from "coarse" to "smoother".
538  // Therefore, we have to check the values of the "smoother" parameters
539  mueluss << GetSmootherFactory(paramList.sublist("coarse: list"), adaptingParamList.sublist("coarse: list"), "coarse: type", paramList.sublist("coarse: list").get<std::string>("smoother: type"));
540  }
541  } // for
542 
543  mueluss << "</ParameterList>" << std::endl;
544 
545  return mueluss.str();
546 }
547 
548 } // namespace MueLu
static std::string SetParameterList(const Teuchos::ParameterList &paramList_in, const std::string &defaultVals)
: Interpret parameter list
const std::string & name() const
void MergeParameterList(const Teuchos::ParameterList &source, Teuchos::ParameterList &dest, bool overWrite)
: merge two parameter lists
ConstIterator end() const
T & get(const std::string &name, T def_value)
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
static std::string interpretParameterName(const std::string &name, const std::string &value)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
std::string tolower(const std::string &str)
bool isParameter(const std::string &name) const
static std::string GetSmootherFactory(const Teuchos::ParameterList &paramList, Teuchos::ParameterList &adaptingParamList, const std::string &pname, const std::string &value)
: Helper function which translates ML smoother/solver paramters to MueLu XML string ...
void CreateSublists(const ParameterList &List, ParameterList &newList)
bool remove(std::string const &name, bool throwIfNotExists=true)
params_t::ConstIterator ConstIterator
ConstIterator begin() const
const ParameterEntry & entry(ConstIterator i) const
static std::string ML2MueLu(const std::string &name)
Translate ML parameter to corresponding MueLu parameter.
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
Exception throws to report errors in the internal logical of the program.
void replaceAll(std::string &str, const std::string &from, const std::string &to)