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 
71  public:
73 
75  Factory()
76 #ifdef HAVE_MUELU_DEBUG
77  : multipleCallCheck_(FIRSTCALL), lastLevelID_(-1)
78 #endif
79  { }
80 
82  virtual ~Factory() { }
84 
86 
89  virtual void SetFactory(const std::string& varName, const RCP<const FactoryBase>& factory) {
90  RCP<const FactoryBase> f = factory;
91  SetParameter(varName, ParameterEntry(f)); // parameter validation done in ParameterListAcceptorImpl
92  }
93 
95  const RCP<const FactoryBase> GetFactory(const std::string& varName) const {
96 
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 
146  void Input(Level& level, const std::string& varName) const {
147  level.DeclareInput(varName, GetFactory(varName).get(), this);
148  }
149  // Similar to the other Input, but we have an alias (varParamName) to the generated data name (varName)
150  void Input(Level& level, const std::string& varName, const std::string& varParamName) const {
151  level.DeclareInput(varName, GetFactory(varParamName).get(), this);
152  }
153 
154  template <class T>
155  T Get(Level& level, const std::string& varName) const {
156  return level.Get<T>(varName, GetFactory(varName).get());
157  }
158  // Similar to the other Get, but we have an alias (varParamName) to the generated data name (varName)
159  template <class T>
160  T Get(Level& level, const std::string& varName, const std::string& varParamName) const {
161  return level.Get<T>(varName, GetFactory(varParamName).get());
162  }
163 
164  template <class T>
165  void Set(Level& level, const std::string& varName, const T& data) const {
166  return level.Set<T>(varName, data, this);
167  }
168 
169  bool IsAvailable(Level& level, const std::string& varName) const {
170  return level.IsAvailable(varName, GetFactory(varName).get());
171  }
172 
173  public:
174  static void EnableTimerSync() { timerSync_ = true; }
175  static void DisableTimerSync() { timerSync_ = false; }
176 
177  protected:
178  static bool timerSync_;
179 
180 #ifdef HAVE_MUELU_DEBUG
181  public:
182  enum multipleCallCheckEnum { ENABLED, DISABLED, FIRSTCALL };
183 
184  void EnableMultipleCallCheck() const { multipleCallCheck_ = ENABLED; }
185  void DisableMultipleCallCheck() const { multipleCallCheck_ = DISABLED; }
186  void ResetDebugData() const {
187  if (multipleCallCheck_ == FIRSTCALL && lastLevelID_ == -1)
188  return;
189 
190  multipleCallCheck_ = FIRSTCALL;
191  lastLevelID_ = -1;
192 
193  const ParameterList& paramList = GetParameterList();
194 
195  // We cannot use just FactoryManager to specify which factories call ResetDebugData().
196  // The problem is that some factories are not present in the manager, but
197  // instead are only accessible through a parameter list of some factory.
198  // For instance, FilteredAFactory is only accessible from SaPFactory but
199  // nowhere else. So we miss those, and do not reset the data, resulting
200  // in problems.
201  // Therefore, for each factory we need to go through its dependent
202  // factories, and call reset on them.
203  for (ParameterList::ConstIterator it = paramList.begin(); it != paramList.end(); it++)
204  if (paramList.isType<RCP<const FactoryBase> >(it->first)) {
205  RCP<const Factory> fact = rcp_dynamic_cast<const Factory >(paramList.get<RCP<const FactoryBase> >(it->first));
206  if (fact != Teuchos::null && fact != NoFactory::getRCP())
207  fact->ResetDebugData();
208  }
209  }
210 
211  static void EnableMultipleCheckGlobally() { multipleCallCheckGlobal_ = ENABLED; }
212  static void DisableMultipleCheckGlobally() { multipleCallCheckGlobal_ = DISABLED; }
213 
214  protected:
215  mutable multipleCallCheckEnum multipleCallCheck_;
216  static multipleCallCheckEnum multipleCallCheckGlobal_;
217  mutable int lastLevelID_;
218 #else
219  public:
220  void EnableMultipleCallCheck() const { }
221  void DisableMultipleCallCheck() const { }
222  void ResetDebugData() const { }
223  static void EnableMultipleCheckGlobally() { }
225 #endif
226  }; //class Factory
227 
228 } //namespace MueLu
229 
230 #define MUELU_FACTORY_SHORT
231 #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.
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.