MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_Level.hpp
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#ifndef MUELU_LEVEL_HPP
11#define MUELU_LEVEL_HPP
12
13#include <algorithm> // for swap
14#include <map> // for _Rb_tree_const_iterator, etc
15#include <ostream> // for basic_ostream, etc
16#include <string> // for char_traits, string, etc
17#include <utility> // for pair
18
19#include <Teuchos_Describable.hpp> // for operator<<
20#include <Teuchos_FancyOStream.hpp> // for FancyOStream
21#include <Teuchos_RCPDecl.hpp> // for RCP
22#include <Teuchos_RCP.hpp> // for RCP::operator->, etc
23#include <Teuchos_TestForException.hpp> // for TEUCHOS_TEST_FOR_EXCEPTION
24
25#include <Xpetra_Map.hpp> // for UnderlyingLib definition
26
28#include "MueLu_Exceptions.hpp" // for RuntimeError
30#include "MueLu_KeepType.hpp"
31#include "MueLu_NoFactory.hpp"
32#include "MueLu_Utilities.hpp"
34#include "MueLu_VerbosityLevel.hpp" // for MsgType::Default, VerbLevel
35
36namespace MueLu {
37
63class Level : public BaseClass {
64 public:
66
68
69 Level();
70
71 Level(RCP<FactoryManagerBase>& factoryManager);
72
74 virtual ~Level();
75
77
79
81 RCP<Level> Build();
82
84
86
87
89 int GetLevelID() const;
90
92 void SetLevelID(int levelID);
93
95 RCP<Level>& GetPreviousLevel();
96
99 void SetPreviousLevel(const RCP<Level>& previousLevel);
101
103
104
105 // Users should not use this method.
106 void SetFactoryManager(const RCP<const FactoryManagerBase>& factoryManager);
107
109 // Users should not use this method
110 const RCP<const FactoryManagerBase> GetFactoryManager();
112
114
115
119 template <class T>
120 void Set(const std::string& ename, const T& entry, const FactoryBase* factory = NoFactory::get()) {
121 const FactoryBase* fac = GetFactory(ename, factory);
122
123 if (fac == NoFactory::get()) {
124 // Any data set with a NoFactory gets UserData keep flag by default
126 }
127
128 // Store entry only if data have been requested (or any keep flag)
129 if (IsRequested(ename, factory) || GetKeepFlag(ename, factory) != 0) {
130 TEUCHOS_TEST_FOR_EXCEPTION(!IsKey(factory, ename), Exceptions::RuntimeError, "" + ename + " not found in");
131 map_[factory][ename]->SetData(entry);
132
133 } else {
134 GetOStream(Runtime1) << "Level::Set: Not storing \"" << ename << "\" generated by factory " << factory->ShortClassName() << "[" << factory->GetID() << "]"
135 << " on level " << toString(GetLevelID()) << ", as it has not been requested and no keep flags were set for it" << std::endl;
136 }
137 } // Set
138
140
143
145
153 template <class T>
154 T& Get(const std::string& ename, const FactoryBase* factory = NoFactory::get()) {
155 const FactoryBase* fac = GetFactory(ename, factory);
156 /* printf("(l=%d) getting \"%20s\" generated by %10p [actually, generated by %p (%43s)]\n",
157 levelID_, ename.c_str(), factory, fac, fac->description().c_str());*/
158
159 TEUCHOS_TEST_FOR_EXCEPTION(!IsKey(fac, ename), Exceptions::RuntimeError, "\"" + ename + "\" generated by factory \"" + fac->description() + "\" not found on level " + toString(GetLevelID()) + ".");
160
161 if (!IsAvailable(ename, fac)) {
162 TEUCHOS_TEST_FOR_EXCEPTION(NumRequests(fac, ename) < 1 && GetKeepFlag(ename, fac) == 0, Exceptions::RuntimeError,
163 "\"" << ename << "\" has not been requested (counter = " << NumRequests(fac, ename) << ", "
164 "KeepFlag = "
165 << GetKeepFlag(ename, fac) << "). " << std::endl
166 << "Generating factory:" << *fac << " NoFactory = " << NoFactory::get());
167 fac->CallBuild(*this);
168 Release(*fac);
169 }
170
171 TEUCHOS_TEST_FOR_EXCEPTION(!IsAvailable(ename, fac), Exceptions::RuntimeError,
172 "MueLu::Level::Get(): factory did not produce expected output on level " << GetLevelID()
173 << ". The data \"" << ename << "\" has not been generated by " << *fac);
174
175 return map_[fac][ename]->template GetData<T>();
176 }
177
179 template <class T>
180 void Get(const std::string& ename, T& rValue, const FactoryBase* factory = NoFactory::get()) {
181 rValue = Get<T>(ename, factory);
182 }
183
184 template <class T>
185 bool IsType(const std::string& ename, const FactoryBase* factory = NoFactory::get()) {
186 const FactoryBase* fac = GetFactory(ename, factory);
187
188 TEUCHOS_TEST_FOR_EXCEPTION(!IsKey(fac, ename), Exceptions::RuntimeError, "\"" + ename + "\" generated by factory \"" + fac->description() + "\" not found on level " + toString(GetLevelID()) + ".");
189
190 if (!IsAvailable(ename, fac)) {
191 TEUCHOS_TEST_FOR_EXCEPTION(NumRequests(fac, ename) < 1 && GetKeepFlag(ename, fac) == 0, Exceptions::RuntimeError,
192 "\"" << ename << "\" has not been requested (counter = " << NumRequests(fac, ename) << ", "
193 "KeepFlag = "
194 << GetKeepFlag(ename, fac) << "). " << std::endl
195 << "Generating factory:" << *fac << " NoFactory = " << NoFactory::get());
196 fac->CallBuild(*this);
197 Release(*fac);
198 }
199
200 TEUCHOS_TEST_FOR_EXCEPTION(!IsAvailable(ename, fac), Exceptions::RuntimeError,
201 "MueLu::Level::Get(): factory did not produce expected output on level " << GetLevelID()
202 << ". The data \"" << ename << "\" has not been generated by " << *fac);
203
204 return map_[fac][ename]->template CheckType<T>();
205 }
206
213 std::string GetTypeName(const std::string& ename, const FactoryBase* factory = NoFactory::get());
214
216
218
219
221 // This method is intented to be used by user drivers for printing, debugging or to keep some computed data for a next run of the setup phase.
222 //
223 // This method is an alias for: AddKeepFlag(ename, factory, MueLu::Keep)
224 // See also the description of KeepEnum for more information.
225 //
226 // To undo a keep request, one can use:
227 // - Delete(ename, factory) to delete the data and remove the "Keep" flag
228 // - or RemoveKeepFlag(ename, factory, MueLu::Keep) to go back to previous condition (data are kept only if internal MueLu logic need so).
229 //
230 // Note: Level variables tagged using this methods are also keep on the levels built using this.Build().
231 // This means that is you request to keep a specific variable on a fine level, all the coarser level that are created automatically during the setup phase will also retain the same variable.
232 void Keep(const std::string& ename, const FactoryBase* factory) { AddKeepFlag(ename, factory, MueLu::Keep); } // Note: do not add default value for input parameter 'factory'
233
235 // Special cases:
236 // - If entry (ename, factory) does not exist, nothing is done.
237 // - If entry exists but counter !=, entry cannot be desallocated before counter set to 0 (using Release()) so an exeption is thrown.
238 void Delete(const std::string& ename, const FactoryBase* factory);
239
241 void Clear();
242
245 void ExpertClear();
246
250 bool IsKept(const std::string& ename, const FactoryBase* factory, KeepType keep) const { return GetKeepFlag(ename, factory) & keep; }
251
256 void AddKeepFlag(const std::string& ename, const FactoryBase* factory = NoFactory::get(), KeepType keep = MueLu::Keep); // TODO: remove default value for input parameter 'factory'?
257
261 void RemoveKeepFlag(const std::string& ename, const FactoryBase* factory, KeepType keep = MueLu::All);
262
264 KeepType GetKeepFlag(const std::string& ename, const FactoryBase* factory) const;
265
267
270
271
273 void Request(const FactoryBase& factory);
274
276 void Release(const FactoryBase& factory);
277
279 void DeclareInput(const std::string& ename, const FactoryBase* factory, const FactoryBase* requestedBy = NoFactory::get());
280
282 void DeclareDependencies(const FactoryBase* factory, bool bRequestOnly = false, bool bReleaseOnly = false);
283
285 void Request(const std::string& ename, const FactoryBase* factory = NoFactory::get(), const FactoryBase* requestedBy = NoFactory::get());
286
288 void Release(const std::string& ename, const FactoryBase* factory = NoFactory::get(), const FactoryBase* requestedBy = NoFactory::get());
289
291
293
294
296 bool IsAvailable(const std::string& ename, const FactoryBase* factory = NoFactory::get()) const;
297
299 bool IsRequested(const std::string& ename, const FactoryBase* factory = NoFactory::get()) const;
300
302
304
306 std::string description() const;
307
309 // TODO: print only shows requested variables. check if we also list kept factories with ref counter=0?
310 void print(std::ostream& out, const VerbLevel verbLevel = Default) const;
311
312#if defined(HAVE_MUELU_BOOST) && defined(HAVE_MUELU_BOOST_FOR_REAL) && defined(BOOST_VERSION) && (BOOST_VERSION >= 104400)
313 void UpdateGraph(std::map<const FactoryBase*, BoostVertex>& vindices,
314 std::map<std::pair<BoostVertex, BoostVertex>, std::string>& edges,
315 BoostProperties& dp,
316 BoostGraph& graph) const;
317#endif
318
320
325
326 void setlib(Xpetra::UnderlyingLib lib2) { lib_ = lib2; }
327 Xpetra::UnderlyingLib lib() { return lib_; }
328
329 void SetComm(RCP<const Teuchos::Comm<int> > const& comm) { comm_ = comm; }
330 RCP<const Teuchos::Comm<int> > GetComm() const { return comm_; }
331
332 private:
334 Level(const Level& source);
335
337 //
338 // If factory == NULL, the default factory is defined as follow:
339 // - If user data is available, it is considered as the default and the factory manager is ignored.
340 // => The default factory is then NoFactory.
341 // - Else, the factory manager is used to get the default factory.
342 //
343 // This strategy allows to use the same factory manager on the fine and coarse level without any trouble.
344 // Example :
345 //
346 // FineLevel:
347 // ----------
348 // A -> User provided
349 // Nullspace -> User provided
350 //
351 // CoarseLevel:
352 // ------------
353 // A -> RAPFactory
354 // NullSpace -> NullspaceFactory
355 //
356 const FactoryBase* GetFactory(const std::string& varname, const FactoryBase* factory) const;
357
359 Xpetra::UnderlyingLib lib_;
360 RCP<const Teuchos::Comm<int> > comm_;
361
362 using Key1 = const FactoryBase*;
363 using Key2 = const std::string;
364 using Value = RCP<VariableContainer>;
365 using SubMap = Teuchos::map<Key2, Value>;
366 using TwoKeyMap = Teuchos::map<Key1, SubMap>;
367
368 int levelID_; // id number associated with level
369 RCP<const FactoryManagerBase> factoryManager_;
370 RCP<Level> previousLevel_; // linked list of Level
372
374
375
377 bool IsKey(const FactoryBase* factory, const std::string& ename) const;
378
379 bool IsAvailableFactory(const FactoryBase* factory) const;
380
381 bool IsRequested(const Value& v) const;
382
383 bool IsRequestedBy(const FactoryBase* factory, const std::string& ename, const FactoryBase* requestedBy) const;
384
385 bool IsRequestedBy(const Value& v, const FactoryBase* requestedBy) const;
386
387 bool IsRequestedFactory(const FactoryBase* factory) const;
388
389 const Value& Get(const FactoryBase* factory, const std::string& ename) const;
390
391 int NumRequests(const FactoryBase* factory, const std::string& ename) const;
392
393 int CountRequestedFactory(const FactoryBase* factory) const;
394
396
397}; // class Level
398
399} // namespace MueLu
400
401// TODO: Caps should not matter
402
403#endif // MUELU_LEVEL_HPP
Base class for MueLu classes.
virtual std::string description() const
Return a simple one-line description of this object.
Exception throws to report errors in the internal logical of the program.
Base class for factories (e.g., R, P, and A_coarse).
virtual void CallBuild(Level &requestedLevel) const =0
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.
const FactoryBase * GetFactory(const std::string &varname, const FactoryBase *factory) const
If input factory == NULL, returns the default factory. Else, return input factory.
const std::string Key2
void SetComm(RCP< const Teuchos::Comm< int > > const &comm)
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()
RCP< Level > Build()
std::string description() const
Return a simple one-line description of this object.
bool IsType(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Xpetra::UnderlyingLib lib_
void Get(const std::string &ename, T &rValue, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access).
Level(const Level &source)
Copy constructor.
void setlib(Xpetra::UnderlyingLib lib2)
RCP< Level > & GetPreviousLevel()
Previous level.
static RequestMode requestMode_
void Release(const FactoryBase &factory)
Decrement the storage counter for all the inputs of a factory.
int CountRequestedFactory(const FactoryBase *factory) const
RCP< const Teuchos::Comm< int > > GetComm() const
const RCP< const FactoryManagerBase > GetFactoryManager()
returns the current factory manager
void SetLevelID(int levelID)
Set level number.
void print(std::ostream &out, const VerbLevel verbLevel=Default) const
Printing method.
RCP< Level > previousLevel_
void RemoveKeepFlag(const std::string &ename, const FactoryBase *factory, KeepType keep=MueLu::All)
int GetLevelID() const
Return level number.
std::string GetTypeName(const std::string &ename, const FactoryBase *factory=NoFactory::get())
GetTypeName returns type string of variable stored using ename and factory.
RCP< VariableContainer > Value
void Clear()
Delete all data that have been retained after the setup phase using Final flag.
void AddKeepFlag(const std::string &ename, const FactoryBase *factory=NoFactory::get(), KeepType keep=MueLu::Keep)
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access)....
void DeclareDependencies(const FactoryBase *factory, bool bRequestOnly=false, bool bReleaseOnly=false)
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput() to declare factory depe...
bool IsRequestedFactory(const FactoryBase *factory) const
RequestMode GetRequestMode() const
RCP< const Teuchos::Comm< int > > comm_
KeepType GetKeepFlag(const std::string &ename, const FactoryBase *factory) const
Get the flag combination set for variable 'ename' generated by 'factory'.
void Set(const std::string &ename, const T &entry, const FactoryBase *factory=NoFactory::get())
RCP< const FactoryManagerBase > factoryManager_
bool IsKept(const std::string &ename, const FactoryBase *factory, KeepType keep) const
bool IsAvailableFactory(const FactoryBase *factory) const
virtual ~Level()
Destructor.
Teuchos::map< Key1, SubMap > TwoKeyMap
Sub-map container (Key2 -> Value)
bool IsRequested(const std::string &ename, const FactoryBase *factory=NoFactory::get()) const
Test whether a need has been requested. Note: this tells nothing about whether the need's value exist...
int NumRequests(const FactoryBase *factory, const std::string &ename) const
void Request(const FactoryBase &factory)
Increment the storage counter for all the inputs of a factory.
bool IsRequestedBy(const FactoryBase *factory, const std::string &ename, const FactoryBase *requestedBy) const
void SetPreviousLevel(const RCP< Level > &previousLevel)
Xpetra::UnderlyingLib lib()
int levelID_
Map of a map (Key1 -> SubMap)
TwoKeyMap map_
Teuchos::map< Key2, Value > SubMap
bool IsKey(const FactoryBase *factory, const std::string &ename) const
Test whether some information about (ename, factory) are stored.
void Keep(const std::string &ename, const FactoryBase *factory)
Request to keep variable 'ename' generated by 'factory' after the setup phase.
void Delete(const std::string &ename, const FactoryBase *factory)
Delete data that have been retained after the setup phase (using Keep(), AddKeepFlag(),...
static const NoFactory * get()
An exception safe way to call the method 'Level::SetFactoryManager()'.
Teuchos::FancyOStream & GetOStream(MsgType type, int thisProcRankOnly=0) const
Get an output stream for outputting the input message type.
Namespace for MueLu classes and methods.
@ Keep
Always keep data, even accross run. This flag is set by Level::Keep(). This flag is propagated to coa...
@ UserData
User data are always kept. This flag is set automatically when Level::Set("data", data) is used....
@ Runtime1
Description of what is happening (more verbose)
short KeepType
std::string toString(const T &what)
Little helper function to convert non-string types to strings.