MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MueLu_ParameterListUtils.cpp
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 
11 #include "MueLu_Exceptions.hpp"
12 
13 namespace MueLu {
14 
15 /* See also: ML_Epetra::UpdateList */
21 void MergeParameterList(const Teuchos::ParameterList &source, Teuchos::ParameterList &dest, bool overWrite) {
22  for (Teuchos::ParameterList::ConstIterator param = source.begin(); param != source.end(); ++param)
23  if (dest.isParameter(source.name(param)) == false || overWrite)
24  dest.setEntry(source.name(param), source.entry(param));
25 }
26 
28  using std::string;
30 
31  newList.setName(List.name());
32 
33  // Copy general (= not level-specific) options and sublists to the new list.
34  // - Coarse and level-specific parameters are not copied yet. They will be moved to sublists later.
35  // - Already existing level-specific lists are copied to the new list but the coarse list is not copied
36  // yet because it has to be modified before copy (s/coarse/smoother/)
37  for (ParameterList::ConstIterator param = List.begin(); param != List.end(); ++param) {
38  const string &pname = List.name(param);
39 
40  if ((pname.find(" (level", 0) == string::npos || pname.find("smoother: list (level", 0) == 0 || pname.find("aggregation: list (level", 0) == 0) &&
41  (pname.find("coarse: ", 0) == string::npos)) {
42  newList.setEntry(pname, List.entry(param));
43  }
44  } // for
45 
46  // Copy of the sublist "coarse: list" to the new list. Change "coarse:" to "smoother:" along the way.
47  if (List.isSublist("coarse: list")) {
48  const ParameterList &coarseList = List.sublist("coarse: list");
49  ParameterList &newCoarseList = newList.sublist("coarse: list");
50  for (ParameterList::ConstIterator param = coarseList.begin(); param != coarseList.end(); ++param) {
51  const string &pname = coarseList.name(param);
52 
53  if (pname.find("coarse:", 0) == 0) {
54  // change "coarse: " to "smoother:"
55  newCoarseList.setEntry("smoother: " + pname.substr(8), coarseList.entry(param));
56  } else {
57  newCoarseList.setEntry(pname, coarseList.entry(param));
58  }
59  }
60  } // if
61 
62  // Copy of level-specific parameters and coarse parameters to sublist
63  for (ParameterList::ConstIterator param = List.begin(); param != List.end(); ++param) {
64  const string &pname = List.name(param);
65  if (pname.find(" (level", 0) != string::npos && pname.find("smoother: list (level", 0) != 0 && pname.find("aggregation: list (level", 0) != 0) {
66  // Copy level-specific parameters (smoother and aggregation)
67 
68  // Scan pname (ex: pname="smoother: type (level 2)")
69  string type, option;
70  int levelID = -1;
71  {
72  typedef Teuchos::ArrayRCP<char>::size_type size_type; // (!)
73  Teuchos::Array<char> ctype(size_type(pname.size() + 1));
74  Teuchos::Array<char> coption(size_type(pname.size() + 1));
75 
76  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")
77  type = string(ctype.getRawPtr());
78  option = string(coption.getRawPtr());
79  option.resize(option.size() - 1); // remove final white-space
80 
81  if (matched != 3 || (type != "smoother:" && type != "aggregation:")) {
82  TEUCHOS_TEST_FOR_EXCEPTION(true, MueLu::Exceptions::RuntimeError, "MueLu::CreateSublist(), Line " << __LINE__ << ". "
83  << "Error in creating level-specific sublists" << std::endl
84  << "Offending parameter: " << pname << std::endl);
85  }
86  }
87 
88  // Create/grab the corresponding sublist of newList
89  ParameterList &newSubList = newList.sublist(type + " list (level " + Teuchos::toString(levelID) + ")");
90  // Shove option w/o level number into sublist
91  newSubList.setEntry(type + " " + option, List.entry(param));
92 
93  } else if (pname.find("coarse:", 0) == 0 && pname != "coarse: list") {
94  // Copy coarse parameters
95  ParameterList &newCoarseList = newList.sublist("coarse: list"); // the coarse sublist is created only if there is at least one "coarse:" parameter
96  newCoarseList.setEntry("smoother: " + pname.substr(8), List.entry(param)); // change "coarse: " to "smoother:"
97  } // end if
98 
99  } // for
100 
101 } // MueLu::CreateSublist()
102 
103 // Usage: GetMLSubList(paramList, "smoother", 2);
104 const Teuchos::ParameterList &GetMLSubList(const Teuchos::ParameterList &paramList, const std::string &type, int levelID) {
105  static const Teuchos::ParameterList emptyParamList;
106 
107  char levelChar[11];
108  sprintf(levelChar, "(level %d)", levelID);
109  std::string levelStr(levelChar);
110 
111  if (paramList.isSublist(type + ": list " + levelStr)) {
112  return paramList.sublist(type + ": list " + levelStr);
113  } else {
114  return emptyParamList;
115  }
116 }
117 
118 // Extract all the parameters that begin with "str:" (but skip sublist)
121 
122  for (Teuchos::ParameterList::ConstIterator param = paramList.begin(); param != paramList.end(); ++param) {
123  const Teuchos::ParameterEntry &entry = paramList.entry(param);
124  const std::string &pname = paramList.name(param);
125  if (pname.find(str + ":", 0) == 0 && !entry.isList()) {
126  subList->setEntry(pname, entry);
127  }
128  }
129 
130  return subList;
131 }
132 
133 // replace all string occurrences "from" with "to" in "str"
134 void replaceAll(std::string &str, const std::string &from, const std::string &to) {
135  if (from.empty())
136  return;
137  size_t start_pos = 0;
138  while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
139  str.replace(start_pos, from.length(), to);
140  start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
141  }
142 }
143 
144 } // namespace MueLu
const std::string & name() const
void MergeParameterList(const Teuchos::ParameterList &source, Teuchos::ParameterList &dest, bool overWrite)
: merge two parameter lists
ParameterList & setEntry(const std::string &name, U &&entry)
ConstIterator end() const
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
const Teuchos::ParameterList & GetMLSubList(const Teuchos::ParameterList &paramList, const std::string &type, int levelID)
bool isParameter(const std::string &name) const
void CreateSublists(const ParameterList &List, ParameterList &newList)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
bool isSublist(const std::string &name) const
Teuchos::RCP< Teuchos::ParameterList > ExtractSetOfParameters(const Teuchos::ParameterList &paramList, const std::string &str)
params_t::ConstIterator ConstIterator
ConstIterator begin() const
const ParameterEntry & entry(ConstIterator i) const
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
ParameterList & setName(const std::string &name)
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)
std::string toString(const T &t)