MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MueLu_Factory.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_FACTORY_HPP
47 #define MUELU_FACTORY_HPP
48 
49 #include <string>
50 #include <deque> // for _Deque_iterator, operator!=
51 #include <ostream> // for operator<<, etc
52 #include "Teuchos_ENull.hpp" // for ENull::null
53 #include "Teuchos_FilteredIterator.hpp" // for FilteredIterator, etc
54 #include "Teuchos_ParameterEntry.hpp" // for ParameterEntry
55 #include "Teuchos_ParameterList.hpp" // for ParameterList, etc
56 #include "Teuchos_RCPDecl.hpp" // for RCP
57 #include "Teuchos_RCPNode.hpp" // for operator<<
58 #include "Teuchos_StringIndexedOrderedValueObjectContainer.hpp"
59 #include "Teuchos_RCP.hpp"
60 
61 #include "MueLu_ConfigDefs.hpp"
62 #include "MueLu_FactoryBase.hpp"
65 #include "MueLu_Level.hpp"
66 
67 namespace MueLu {
68 
70  public:
72 
74  Factory()
75 #ifdef HAVE_MUELU_DEBUG
76  : multipleCallCheck_(FIRSTCALL)
77  , lastLevelID_(-1)
78 #endif
79  {
80  }
81 
83  virtual ~Factory() {}
85 
87 
90  virtual void SetFactory(const std::string& varName, const RCP<const FactoryBase>& factory) {
91  RCP<const FactoryBase> f = factory;
92  SetParameter(varName, ParameterEntry(f)); // parameter validation done in ParameterListAcceptorImpl
93  }
94 
96  const RCP<const FactoryBase> GetFactory(const std::string& varName) const {
97  // Special treatment for "NoFactory"
98  if (varName == "NoFactory")
99  return MueLu::NoFactory::getRCP();
100 
101  if (!GetParameterList().isParameter(varName) && GetValidParameterList() == Teuchos::null) {
102  // If the parameter is not on the list and there is not validator, the defaults values for 'varName' is not set.
103  // Failback by using directly the FactoryManager
104  // NOTE: call to GetValidParameterList() can be costly for classes that validate parameters.
105  // But it get called only (lazy '&&' operator) if the parameter 'varName' is not on the paramlist and
106  // the parameter 'varName' is always on the list when validator is present and 'varName' is valid (at least the default value is set).
107  return Teuchos::null;
108  }
109 
110  return GetParameterList().get<RCP<const FactoryBase> >(varName);
111  }
112 
113  RCP<ParameterList> RemoveFactoriesFromList(const ParameterList& list) const {
114  RCP<ParameterList> paramList = rcp(new ParameterList(list));
115  // Remove FactoryBase entries from the list
116  // The solution would be much more elegant if ParameterList support std::list like operations
117  // In that case, we could simply write:
118  // for (ParameterList::ConstIterator it = paramList.begin(); it != paramList.end(); it++)
119  // if (paramList.isType<RCP<const FactoryBase> >(it->first))
120  // it = paramList.erase(it);
121  // else
122  // it++;
123  ParameterList::ConstIterator it = paramList->begin();
124  while (it != paramList->end()) {
125  it = paramList->begin();
126 
127  for (; it != paramList->end(); it++)
128  if (paramList->isType<RCP<const FactoryBase> >(it->first))
129  paramList->remove(it->first);
130  }
131  return paramList;
132  }
133 
134  // SetParameterList(...);
135 
136  // GetParameterList(...);
137 
139 
141  return Teuchos::null; // Teuchos::null == GetValidParameterList() not implemented == skip validation and no default values (dangerous)
142  }
143 
144  protected:
145  void Input(Level& level, const std::string& varName) const {
146  level.DeclareInput(varName, GetFactory(varName).get(), this);
147  }
148  // Similar to the other Input, but we have an alias (varParamName) to the generated data name (varName)
149  void Input(Level& level, const std::string& varName, const std::string& varParamName) const {
150  level.DeclareInput(varName, GetFactory(varParamName).get(), this);
151  }
152 
153  template <class T>
154  T Get(Level& level, const std::string& varName) const {
155  return level.Get<T>(varName, GetFactory(varName).get());
156  }
157  // Similar to the other Get, but we have an alias (varParamName) to the generated data name (varName)
158  template <class T>
159  T Get(Level& level, const std::string& varName, const std::string& varParamName) const {
160  return level.Get<T>(varName, GetFactory(varParamName).get());
161  }
162 
163  template <class T>
164  void Set(Level& level, const std::string& varName, const T& data) const {
165  return level.Set<T>(varName, data, this);
166  }
167 
168  template <class T>
169  bool IsType(Level& level, const std::string& varName) const {
170  return level.IsType<T>(varName, GetFactory(varName).get());
171  }
172 
173  bool IsAvailable(Level& level, const std::string& varName) const {
174  return level.IsAvailable(varName, GetFactory(varName).get());
175  }
176 
177  public:
178  static void EnableTimerSync() { timerSync_ = true; }
179  static void DisableTimerSync() { timerSync_ = false; }
180 
181  protected:
182  static bool timerSync_;
183 
184 #ifdef HAVE_MUELU_DEBUG
185  public:
186  enum multipleCallCheckEnum{ENABLED, DISABLED, FIRSTCALL};
187 
188  void EnableMultipleCallCheck() const { multipleCallCheck_ = ENABLED; }
189  void DisableMultipleCallCheck() const { multipleCallCheck_ = DISABLED; }
190  void ResetDebugData() const {
191  if (multipleCallCheck_ == FIRSTCALL && lastLevelID_ == -1)
192  return;
193 
194  multipleCallCheck_ = FIRSTCALL;
195  lastLevelID_ = -1;
196 
197  const ParameterList& paramList = GetParameterList();
198 
199  // We cannot use just FactoryManager to specify which factories call ResetDebugData().
200  // The problem is that some factories are not present in the manager, but
201  // instead are only accessible through a parameter list of some factory.
202  // For instance, FilteredAFactory is only accessible from SaPFactory but
203  // nowhere else. So we miss those, and do not reset the data, resulting
204  // in problems.
205  // Therefore, for each factory we need to go through its dependent
206  // factories, and call reset on them.
207  for (ParameterList::ConstIterator it = paramList.begin(); it != paramList.end(); it++)
208  if (paramList.isType<RCP<const FactoryBase> >(it->first)) {
209  RCP<const Factory> fact = rcp_dynamic_cast<const Factory>(paramList.get<RCP<const FactoryBase> >(it->first));
210  if (fact != Teuchos::null && fact != NoFactory::getRCP())
211  fact->ResetDebugData();
212  }
213  }
214 
215  static void EnableMultipleCheckGlobally() { multipleCallCheckGlobal_ = ENABLED; }
216  static void DisableMultipleCheckGlobally() { multipleCallCheckGlobal_ = DISABLED; }
217 
218  protected:
219  mutable multipleCallCheckEnum multipleCallCheck_;
220  static multipleCallCheckEnum multipleCallCheckGlobal_;
221  mutable int lastLevelID_;
222 #else
223  public:
224  void EnableMultipleCallCheck() const {}
225  void DisableMultipleCallCheck() const {}
226  void ResetDebugData() const {}
229 #endif
230 }; // class Factory
231 
232 } // namespace MueLu
233 
234 #define MUELU_FACTORY_SHORT
235 #endif // ifndef MUELU_FACTORY_HPP
virtual const Teuchos::ParameterList & GetParameterList() const
void DisableMultipleCallCheck() const
ConstIterator end() const
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.
T & get(const std::string &name, T def_value)
static void DisableMultipleCheckGlobally()
Base class for factories (e.g., R, P, and A_coarse).
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Class that holds all level-specific information.
Definition: MueLu_Level.hpp:99
void EnableMultipleCallCheck() const
Constructor.
params_t::ConstIterator ConstIterator
ConstIterator begin() const
static void EnableMultipleCheckGlobally()
void ResetDebugData() const
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.
bool IsType(const std::string &ename, const FactoryBase *factory=NoFactory::get())
virtual void SetFactory(const std::string &varName, const RCP< const FactoryBase > &factory)=0
Configuration.
bool isType(const std::string &name) const
virtual const RCP< const FactoryBase > GetFactory(const std::string &varName) const =0
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()
bool IsAvailable(const std::string &ename, const FactoryBase *factory=NoFactory::get()) const
Test whether a need&#39;s value has been saved.
virtual Teuchos::RCP< const Teuchos::ParameterList > GetValidParameterList() const =0
Return a const parameter list of valid parameters that setParameterList() will accept.
static const RCP< const NoFactory > getRCP()
Static Get() functions.