MueLu  Version of the Day
MueLu_ParameterListAcceptor.hpp
Go to the documentation of this file.
1 #ifndef MUELU_PARAMETERLISTACCEPTOR_HPP
2 #define MUELU_PARAMETERLISTACCEPTOR_HPP
3 
4 #include <iostream>
5 
6 #include "Teuchos_RCP.hpp"
7 #include "Teuchos_ParameterList.hpp"
8 #include "Teuchos_ParameterEntry.hpp"
9 #include "Teuchos_StandardParameterEntryValidators.hpp"
10 
11 // TODO See also: Teuchos::ParameterListAcceptor, Teko::Clonable
12 
13 namespace MueLu {
14  using Teuchos::ParameterList;
15  using Teuchos::ParameterEntry;
16  using Teuchos::RCP;
17 
18  // Printing the valid parameter list only showing documentation fields
19  inline void printParameterListOptions(std::ostream &os, const Teuchos::ParameterList & p) {
20  p.print(os, Teuchos::ParameterList::PrintOptions().showDoc(true).indent(2).showTypes(true));
21  os << std::endl;
22  }
23 
29 
30  public:
31 
35 
36  virtual ~ParameterListAcceptor() { }
37 
41 
46  // Questions:
47  // - Do we want this function to be static?
48  // => yes, but we also want it virtual. So static is not possible. But this method does not access any instance specific data.
49  // - Do we want to pass an optional param list as input parameter?
50  // yes => if some parameters depends of other parameters, this would allow to return different default / valid parameters according to already set parameters.
51  // Ex: fact: ILUT => extra param threshold; fact: ILUK => extra param level-of-fill
52  //
53  // If a parameter is unused AND default, it is printed as [default] by std::cout << paramList but printed as unused by paramList.unused(std::cout).
54  // So if we set default parameters in getValidParameters() that are not used, user will get a warning message. We don't want that for [default].
55  // One solution is to never set any unused parameter in getValidParameters().
56  // If some parameters are available only conditionnaly, do not set them by default in setValidParameters when the conditions are not met.
57  //
58  virtual RCP<const ParameterList> GetValidParameterList() const = 0;
59 
61  //
62  // Questions:
63  // - Input: const ParameterList or not const? IE: do we want to modify user paramlist directly?
64  // => not const: user can make a copy outside if he do not want us to modify his initial paramlist.
65  // - Input: RCP or just reference? RCP avoid the copy of the parameter list but
66  // I'm afraid that a user modify the list outside of the class after doing a SetParameterList
67  // (this by-pass the validation and can create some confusion).
68  // In another hand, if we use a copy of the list, we do not set the "[used]"/["unused"] flag
69  // on the original list during Build(). GetParameterList has to be called to retrieve the list with the correct flags.
70  //
71  // What we really want is for the user to have a const version outside and MueLu having a non-const version inside.
72  // Is there a C++ pattern to do that?
73  virtual void SetParameterList(const ParameterList& paramList) = 0;
74 
75  // Get the parameter list.
76  // Teuchos::ParameterListAcceptor also provides a non-const version of this but I don't see why.
77  // We don't want a user to mess with the internal parameter list.
78  // To change a parameter, one can make a copy and call SetParameterList again.
79  // No need for RCP, it's just a view
80  virtual const Teuchos::ParameterList & GetParameterList() const = 0;
81 
83  virtual void SetParameter(const std::string &name, const ParameterEntry &entry) = 0;
84 
86  virtual const ParameterEntry & GetParameter(const std::string &name) const = 0;
87 
88  virtual void GetDocumentation(std::ostream &os) const = 0;
89 
91 
92  }; //class ParameterListAcceptor
93 
94  // Partial implementation of ParameterListAcceptor that stores the object parameters in an internal parameterList
96 
97  public:
98 
100 
102  bool warnings = false; //TODO
103  if (warnings)
104  paramList_.unused(std::cout);
105  }
106 
107  virtual void SetParameterList(const ParameterList& paramList) {
108  // This call is only for cosmetic reasons.
109  // If one calls SetParameterList before GetParameterList, that would mean
110  // that paramList_ has not been initialized yet. Therefore, the parameter
111  // would be put in it in the order user provided, and not in the order of
112  // valid parameter list. We'd like to have consistency in the order, so
113  // we do this extra call, which is no-op if paramList_ has already been
114  // initialized.
115  paramList_ = GetParameterList();
116 
117  paramList_.setParameters(paramList);
118 
119  // Validate and add defaults parameters.
120  RCP<const ParameterList> validParamList = GetValidParameterList();
121  if (validParamList != Teuchos::null) {
122  paramList_.validateParametersAndSetDefaults(*validParamList);
123  } else {
124  // Teuchos::null means that GetValidParameterList() not implemented.
125  // As such, we skip validation and have not way to set default values,
126  // which is potentially dangerous
127  }
128  }
129 
130  // The returned list always has an entry for each valid parameter.
131  // Therefore, there is not need to test if a parameter is present before getting it.
132  virtual const Teuchos::ParameterList& GetParameterList() const {
133  if (paramList_.numParams() == 0) {
134  // Set paramList_ to the default list
135  RCP<const ParameterList> validParamList = GetValidParameterList();
136  if (validParamList != Teuchos::null) {
137  // Instead of simply doing
138  // paramList_ = *validParamList;
139  // we use more complicated Teuchos calls, because we would like to
140  // have [default] values in the beginning
141  paramList_.validateParametersAndSetDefaults(*validParamList);
142  }
143 
144  } else {
145  // We are sure that the list has all the valid parameters defined
146  // because the parameter list validation process adds the default
147  // values to the user list
148  }
149 
150  return paramList_;
151  }
152 
153  void SetParameter(const std::string& name, const ParameterEntry& entry) {
154  Teuchos::ParameterList paramList;
155  paramList.setEntry(name, entry);
156  SetParameterList(paramList); // This forces revalidation of the list
157  }
158 
159  const ParameterEntry & GetParameter(const std::string &name) const {
160  return GetParameterList().getEntry(name);
161  }
162 
163  virtual void GetDocumentation(std::ostream &os) const {
164  // default implementation
165 
166  RCP<const ParameterList> validParamList = GetValidParameterList();
167  if (validParamList == Teuchos::null) {
168  os << "## Documentation not available:" << std::endl;
169  return;
170  }
171 
172  os << "## Parameters:" << std::endl;
173  printParameterListOptions(os, *validParamList);
174 
175  os << "## Fully described default method:" << std::endl;
176  validParamList->print(os, 2, true, false);
177  os << std::endl;
178  }
179 
180  private:
181 
182  mutable // mutable can be avoid by changing return type of GetParameterList() to RCP but conceptually, I like the fact that GetParameterList returns ref to param list.
183  Teuchos::ParameterList paramList_; // Private: Use GetParameterList() to access this list
184  // This list might be empty before calling GetParameterList()
185  // but it is populate with automatically if needed in SetParameterList/GetParameterList/...
186  // Therefore, there is no need to test if a parameter exist before accessing it with pL.get("paramName")
187  // in sub classes.
188 
189  // Note: Teuchos::ParameterListAcceptor has a getMyParamList() function to access paramList_ without going through the logic of getParameterList()
190  // Do we need that too?
191 
192  };
193 
194 
195 }
196 
197 #endif // MUELU_PARAMETERLISTACCEPTOR_HPP
Namespace for MueLu classes and methods.
virtual const Teuchos::ParameterList & GetParameterList() const
virtual const ParameterEntry & GetParameter(const std::string &name) const =0
Retrieves a const entry with the name name.
virtual void SetParameterList(const ParameterList &paramList)=0
Set parameters from a parameter list and return with default values.
virtual void SetParameterList(const ParameterList &paramList)
Set parameters from a parameter list and return with default values.
virtual const Teuchos::ParameterList & GetParameterList() const =0
Abstract interface of a class accepting parameter lists.
void SetParameter(const std::string &name, const ParameterEntry &entry)
Set a parameter directly as a ParameterEntry.
virtual void SetParameter(const std::string &name, const ParameterEntry &entry)=0
Set a parameter directly as a ParameterEntry.
virtual RCP< const ParameterList > GetValidParameterList() const =0
Return a const parameter list of valid parameters that setParameterList() will accept.
void printParameterListOptions(std::ostream &os, const Teuchos::ParameterList &p)
const ParameterEntry & GetParameter(const std::string &name) const
Retrieves a const entry with the name name.
virtual void GetDocumentation(std::ostream &os) const =0
virtual void GetDocumentation(std::ostream &os) const