MueLu Version of the Day
Loading...
Searching...
No Matches
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
67namespace MueLu {
68
70
71 public:
73
76#ifdef HAVE_MUELU_DEBUG
77 : multipleCallCheck_(FIRSTCALL), lastLevelID_(-1)
78#endif
79 { }
80
82 virtual ~Factory() { }
84
86
87
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")
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
140 virtual RCP<const ParameterList> GetValidParameterList() const {
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 { }
222 void ResetDebugData() const { }
225#endif
226 }; //class Factory
227
228} //namespace MueLu
229
230#define MUELU_FACTORY_SHORT
231#endif //ifndef MUELU_FACTORY_HPP
Base class for factories (e.g., R, P, and A_coarse).
static void DisableMultipleCheckGlobally()
void Input(Level &level, const std::string &varName) const
static bool timerSync_
void ResetDebugData() const
void DisableMultipleCallCheck() const
void Input(Level &level, const std::string &varName, const std::string &varParamName) const
static void EnableMultipleCheckGlobally()
static void DisableTimerSync()
T Get(Level &level, const std::string &varName) const
virtual void SetFactory(const std::string &varName, const RCP< const FactoryBase > &factory)
Configuration.
virtual ~Factory()
Destructor.
void Set(Level &level, const std::string &varName, const T &data) const
bool IsAvailable(Level &level, const std::string &varName) const
virtual RCP< const ParameterList > GetValidParameterList() const
Return a const parameter list of valid parameters that setParameterList() will accept.
Factory()
Constructor.
const RCP< const FactoryBase > GetFactory(const std::string &varName) const
Default implementation of FactoryAcceptor::GetFactory()
RCP< ParameterList > RemoveFactoriesFromList(const ParameterList &list) const
void EnableMultipleCallCheck() const
static void EnableTimerSync()
T Get(Level &level, const std::string &varName, const std::string &varParamName) const
Class that holds all level-specific information.
bool IsAvailable(const std::string &ename, const FactoryBase *factory=NoFactory::get()) const
Test whether a need's value has been saved.
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access)....
void Set(const std::string &ename, const T &entry, const FactoryBase *factory=NoFactory::get())
static const RCP< const NoFactory > getRCP()
Static Get() functions.
virtual const Teuchos::ParameterList & GetParameterList() const
void SetParameter(const std::string &name, const ParameterEntry &entry)
Set a parameter directly as a ParameterEntry.
Namespace for MueLu classes and methods.