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 // ***********************************************************************
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 
48 #include "MueLu_Exceptions.hpp"
49 
50 namespace MueLu {
51 
52 /* See also: ML_Epetra::UpdateList */
58 void MergeParameterList(const Teuchos::ParameterList &source, Teuchos::ParameterList &dest, bool overWrite) {
59  for (Teuchos::ParameterList::ConstIterator param = source.begin(); param != source.end(); ++param)
60  if (dest.isParameter(source.name(param)) == false || overWrite)
61  dest.setEntry(source.name(param), source.entry(param));
62 }
63 
65  using std::string;
67 
68  newList.setName(List.name());
69 
70  // Copy general (= not level-specific) options and sublists to the new list.
71  // - Coarse and level-specific parameters are not copied yet. They will be moved to sublists later.
72  // - Already existing level-specific lists are copied to the new list but the coarse list is not copied
73  // yet because it has to be modified before copy (s/coarse/smoother/)
74  for (ParameterList::ConstIterator param = List.begin(); param != List.end(); ++param) {
75  const string &pname = List.name(param);
76 
77  if ((pname.find(" (level", 0) == string::npos || pname.find("smoother: list (level", 0) == 0 || pname.find("aggregation: list (level", 0) == 0) &&
78  (pname.find("coarse: ", 0) == string::npos)) {
79  newList.setEntry(pname, List.entry(param));
80  }
81  } // for
82 
83  // Copy of the sublist "coarse: list" to the new list. Change "coarse:" to "smoother:" along the way.
84  if (List.isSublist("coarse: list")) {
85  const ParameterList &coarseList = List.sublist("coarse: list");
86  ParameterList &newCoarseList = newList.sublist("coarse: list");
87  for (ParameterList::ConstIterator param = coarseList.begin(); param != coarseList.end(); ++param) {
88  const string &pname = coarseList.name(param);
89 
90  if (pname.find("coarse:", 0) == 0) {
91  // change "coarse: " to "smoother:"
92  newCoarseList.setEntry("smoother: " + pname.substr(8), coarseList.entry(param));
93  } else {
94  newCoarseList.setEntry(pname, coarseList.entry(param));
95  }
96  }
97  } // if
98 
99  // Copy of level-specific parameters and coarse parameters to sublist
100  for (ParameterList::ConstIterator param = List.begin(); param != List.end(); ++param) {
101  const string &pname = List.name(param);
102  if (pname.find(" (level", 0) != string::npos && pname.find("smoother: list (level", 0) != 0 && pname.find("aggregation: list (level", 0) != 0) {
103  // Copy level-specific parameters (smoother and aggregation)
104 
105  // Scan pname (ex: pname="smoother: type (level 2)")
106  string type, option;
107  int levelID = -1;
108  {
109  typedef Teuchos::ArrayRCP<char>::size_type size_type; // (!)
110  Teuchos::Array<char> ctype(size_type(pname.size() + 1));
111  Teuchos::Array<char> coption(size_type(pname.size() + 1));
112 
113  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")
114  type = string(ctype.getRawPtr());
115  option = string(coption.getRawPtr());
116  option.resize(option.size() - 1); // remove final white-space
117 
118  if (matched != 3 || (type != "smoother:" && type != "aggregation:")) {
119  TEUCHOS_TEST_FOR_EXCEPTION(true, MueLu::Exceptions::RuntimeError, "MueLu::CreateSublist(), Line " << __LINE__ << ". "
120  << "Error in creating level-specific sublists" << std::endl
121  << "Offending parameter: " << pname << std::endl);
122  }
123  }
124 
125  // Create/grab the corresponding sublist of newList
126  ParameterList &newSubList = newList.sublist(type + " list (level " + Teuchos::toString(levelID) + ")");
127  // Shove option w/o level number into sublist
128  newSubList.setEntry(type + " " + option, List.entry(param));
129 
130  } else if (pname.find("coarse:", 0) == 0 && pname != "coarse: list") {
131  // Copy coarse parameters
132  ParameterList &newCoarseList = newList.sublist("coarse: list"); // the coarse sublist is created only if there is at least one "coarse:" parameter
133  newCoarseList.setEntry("smoother: " + pname.substr(8), List.entry(param)); // change "coarse: " to "smoother:"
134  } // end if
135 
136  } // for
137 
138 } // MueLu::CreateSublist()
139 
140 // Usage: GetMLSubList(paramList, "smoother", 2);
141 const Teuchos::ParameterList &GetMLSubList(const Teuchos::ParameterList &paramList, const std::string &type, int levelID) {
142  static const Teuchos::ParameterList emptyParamList;
143 
144  char levelChar[11];
145  sprintf(levelChar, "(level %d)", levelID);
146  std::string levelStr(levelChar);
147 
148  if (paramList.isSublist(type + ": list " + levelStr)) {
149  return paramList.sublist(type + ": list " + levelStr);
150  } else {
151  return emptyParamList;
152  }
153 }
154 
155 // Extract all the parameters that begin with "str:" (but skip sublist)
158 
159  for (Teuchos::ParameterList::ConstIterator param = paramList.begin(); param != paramList.end(); ++param) {
160  const Teuchos::ParameterEntry &entry = paramList.entry(param);
161  const std::string &pname = paramList.name(param);
162  if (pname.find(str + ":", 0) == 0 && !entry.isList()) {
163  subList->setEntry(pname, entry);
164  }
165  }
166 
167  return subList;
168 }
169 
170 // replace all string occurrences "from" with "to" in "str"
171 void replaceAll(std::string &str, const std::string &from, const std::string &to) {
172  if (from.empty())
173  return;
174  size_t start_pos = 0;
175  while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
176  str.replace(start_pos, from.length(), to);
177  start_pos += to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
178  }
179 }
180 
181 } // 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)