MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MueLu_Factory.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 
10 #include "MueLu_Factory.hpp"
11 
12 namespace MueLu {
13 
15 #ifdef HAVE_MUELU_DEBUG
16  : multipleCallCheck_(FIRSTCALL)
17  , lastLevelID_(-1)
18 #endif
19 {
20 }
21 
23 Factory::~Factory() = default;
24 
25 void Factory::SetFactory(const std::string& varName, const RCP<const FactoryBase>& factory) {
26  RCP<const FactoryBase> f = factory;
27  SetParameter(varName, ParameterEntry(f)); // parameter validation done in ParameterListAcceptorImpl
28 }
29 
30 const RCP<const FactoryBase> Factory::GetFactory(const std::string& varName) const {
31  // Special treatment for "NoFactory"
32  if (varName == "NoFactory")
33  return MueLu::NoFactory::getRCP();
34 
35  if (!GetParameterList().isParameter(varName) && GetValidParameterList() == Teuchos::null) {
36  // If the parameter is not on the list and there is not validator, the defaults values for 'varName' is not set.
37  // Failback by using directly the FactoryManager
38  // NOTE: call to GetValidParameterList() can be costly for classes that validate parameters.
39  // But it get called only (lazy '&&' operator) if the parameter 'varName' is not on the paramlist and
40  // the parameter 'varName' is always on the list when validator is present and 'varName' is valid (at least the default value is set).
41  return Teuchos::null;
42  }
43 
44  return GetParameterList().get<RCP<const FactoryBase> >(varName);
45 }
46 
48  RCP<ParameterList> paramList = rcp(new ParameterList(list));
49  // Remove FactoryBase entries from the list
50  // The solution would be much more elegant if ParameterList support std::list like operations
51  // In that case, we could simply write:
52  // for (ParameterList::ConstIterator it = paramList.begin(); it != paramList.end(); it++)
53  // if (paramList.isType<RCP<const FactoryBase> >(it->first))
54  // it = paramList.erase(it);
55  // else
56  // it++;
57  ParameterList::ConstIterator it = paramList->begin();
58  while (it != paramList->end()) {
59  it = paramList->begin();
60 
61  for (; it != paramList->end(); it++)
62  if (paramList->isType<RCP<const FactoryBase> >(it->first))
63  paramList->remove(it->first);
64  }
65  return paramList;
66 }
67 
69  return Teuchos::null; // Teuchos::null == GetValidParameterList() not implemented == skip validation and no default values (dangerous)
70 }
71 
72 void Factory::Input(Level& level, const std::string& varName) const {
73  level.DeclareInput(varName, GetFactory(varName).get(), this);
74 }
75 // Similar to the other Input, but we have an alias (varParamName) to the generated data name (varName)
76 void Factory::Input(Level& level, const std::string& varName, const std::string& varParamName) const {
77  level.DeclareInput(varName, GetFactory(varParamName).get(), this);
78 }
79 
80 bool Factory::IsAvailable(Level& level, const std::string& varName) const {
81  return level.IsAvailable(varName, GetFactory(varName).get());
82 }
83 
85 
87 
88 #ifdef HAVE_MUELU_DEBUG
89 void Factory::EnableMultipleCallCheck() const { multipleCallCheck_ = ENABLED; }
90 void Factory::DisableMultipleCallCheck() const { multipleCallCheck_ = DISABLED; }
91 void Factory::ResetDebugData() const {
92  if (multipleCallCheck_ == FIRSTCALL && lastLevelID_ == -1)
93  return;
94 
95  multipleCallCheck_ = FIRSTCALL;
96  lastLevelID_ = -1;
97 
98  const ParameterList& paramList = GetParameterList();
99 
100  // We cannot use just FactoryManager to specify which factories call ResetDebugData().
101  // The problem is that some factories are not present in the manager, but
102  // instead are only accessible through a parameter list of some factory.
103  // For instance, FilteredAFactory is only accessible from SaPFactory but
104  // nowhere else. So we miss those, and do not reset the data, resulting
105  // in problems.
106  // Therefore, for each factory we need to go through its dependent
107  // factories, and call reset on them.
108  for (ParameterList::ConstIterator it = paramList.begin(); it != paramList.end(); it++)
109  if (paramList.isType<RCP<const FactoryBase> >(it->first)) {
110  RCP<const Factory> fact = rcp_dynamic_cast<const Factory>(paramList.get<RCP<const FactoryBase> >(it->first));
111  if (fact != Teuchos::null && fact != NoFactory::getRCP())
112  fact->ResetDebugData();
113  }
114 }
115 
116 void Factory::EnableMultipleCheckGlobally() { multipleCallCheckGlobal_ = ENABLED; }
117 void Factory::DisableMultipleCheckGlobally() { multipleCallCheckGlobal_ = DISABLED; }
118 
119 #else
122 void Factory::ResetDebugData() const {}
125 #endif
126 
127 bool Factory::timerSync_ = false;
128 #ifdef HAVE_MUELU_DEBUG
129 Factory::multipleCallCheckEnum Factory::multipleCallCheckGlobal_ = ENABLED;
130 #endif
131 
132 } // namespace MueLu
virtual const Teuchos::ParameterList & GetParameterList() const
void DisableMultipleCallCheck() const
virtual void SetFactory(const std::string &varName, const RCP< const FactoryBase > &factory)
Configuration.
T & get(const std::string &name, T def_value)
static void DisableTimerSync()
RCP< ParameterList > RemoveFactoriesFromList(const ParameterList &list) const
static void DisableMultipleCheckGlobally()
static void EnableTimerSync()
Factory()
Constructor.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Class that holds all level-specific information.
Definition: MueLu_Level.hpp:63
void EnableMultipleCallCheck() const
params_t::ConstIterator ConstIterator
static bool timerSync_
static const RCP< const NoFactory > getRCP()
Static Get() functions.
virtual RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
void ResetDebugData() const
void SetParameter(const std::string &name, const ParameterEntry &entry)
Set a parameter directly as a ParameterEntry.
bool IsAvailable(Level &level, const std::string &varName) const
static void EnableMultipleCheckGlobally()
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()
void Input(Level &level, const std::string &varName) const
const RCP< const FactoryBase > GetFactory(const std::string &varName) const
Default implementation of FactoryAcceptor::GetFactory()
bool IsAvailable(const std::string &ename, const FactoryBase *factory=NoFactory::get()) const
Test whether a need&#39;s value has been saved.
virtual ~Factory()
Destructor.