MueLu Version of the Day
Loading...
Searching...
No Matches
MueLu_Level.cpp
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#include <Teuchos_TabularOutputter.hpp>
47
48#include "MueLu_Level.hpp"
49
51
52namespace MueLu {
53
54 RCP<Level> Level::Build() {
55 RCP<Level> newLevel = rcp(new Level());
56
57 // Copy 'keep' status of variables
58 for (TwoKeyMap::const_iterator kt = map_.begin(); kt != map_.end(); kt++) {
59 const FactoryBase* factory = kt->first;
60
61 for (SubMap::const_iterator it = kt->second.begin(); it != kt->second.end(); it++) {
62 const std::string& ename = it->first;
63
64 if (IsKept(ename, factory, MueLu::Keep)) { // MueLu::Keep is the only flag propagated
65 if (factory == NULL) // TODO: Is this possible?? Throw exception. Not supposed to use the FactoryManager here.
66 newLevel->Keep(ename, NoFactory::get());
67 else
68 newLevel->Keep(ename, factory);
69 }
70 }
71 }
72
73 return newLevel;
74 }
75
76 int Level::GetLevelID() const { return levelID_; }
77
78 void Level::SetLevelID(int levelID) {
79 if (levelID_ != -1 && levelID_ != levelID)
80 GetOStream(Warnings1) << "Level::SetLevelID(): Changing an already defined LevelID (previousID=" << levelID_ << ", newID=" << levelID << ")" << std::endl;
81
82 levelID_ = levelID;
83 }
84
85 void Level::SetPreviousLevel(const RCP<Level> & previousLevel) {
86 if (previousLevel_ != Teuchos::null && previousLevel_ != previousLevel)
87 GetOStream(Warnings1) << "Level::SetPreviousLevel(): PreviousLevel was already defined" << std::endl;
88
89 previousLevel_ = previousLevel;
90 }
91
92 void Level::SetFactoryManager(const RCP<const FactoryManagerBase> & factoryManager) {
93 factoryManager_ = factoryManager;
94 }
95
96 const RCP<const FactoryManagerBase> Level::GetFactoryManager() {
97 return factoryManager_;
98 }
99
100 void Level::AddKeepFlag(const std::string& ename, const FactoryBase* factory, KeepType keep) {
101 if (!IsKey(factory, ename)) {
102 // If the entry does not exist, create it to store the keep flag
103 Teuchos::RCP<MueLu::VariableContainer> newVar = Teuchos::rcp(new MueLu::VariableContainer);
104 map_[factory][ename] = newVar;
105 }
106 // Set the flag
107 map_[factory][ename]->AddKeepFlag(keep);
108 }
109
110 void Level::RemoveKeepFlag(const std::string& ename, const FactoryBase* factory, KeepType keep) {
111 // No entry = nothing to do
112 if (!IsKey(factory, ename))
113 return;
114
115 // Remove the flag
116 Teuchos::RCP<MueLu::VariableContainer>& v = map_[factory][ename];
117 v->RemoveKeepFlag(keep);
118
119 // Remove data if no keep flag left and counter == 0
120 if ((v->IsRequested() == false) && (v->GetKeepFlag() == 0)) {
121 v = Teuchos::null; // free data
122
123 map_[factory].erase(ename);
124 if (map_.count(factory) == 0)
125 map_.erase(factory);
126 }
127 }
128
129 KeepType Level::GetKeepFlag(const std::string& ename, const FactoryBase* factory) const {
130 if (!IsKey(factory,ename))
131 return false;
132
133 return Get(factory, ename)->GetKeepFlag();
134 }
135
136 void Level::Request(const FactoryBase& factory) {
139 factory.CallDeclareInput(*this);
140 requestMode_ = prev;
141 }
142
143 void Level::Release(const FactoryBase& factory) {
146 factory.CallDeclareInput(*this);
147 requestMode_ = prev;
148 }
149
150 void Level::DeclareInput(const std::string& ename, const FactoryBase* factory, const FactoryBase* requestedBy) {
151 if (requestMode_ == REQUEST) {
152 try {
153 Request(ename, factory, requestedBy);
154
155 } catch (Exceptions::DependencyError& e) {
156 std::ostringstream msg;
157 msg << requestedBy->ShortClassName() << "::DeclareInput: (" << e.what() << ") unable to find or generate requested data \""
158 << ename << "\" with generating factory \"" << ((factory != NULL) ? factory->ShortClassName() : "null") << "\" [" << factory << "]";
159 msg << "\n during request for data \"" << std::setw(15) << ename << "\" on level " << GetLevelID()
160 << " by factory " << std::setw(25) << requestedBy->ShortClassName() << " [" << requestedBy << "]";
161 throw Exceptions::RuntimeError(msg.str());
162
163 } catch (Exceptions::RuntimeError &e) {
164 std::ostringstream msg;
165 msg << e.what() << "\n during request for data \"" << std::setw(15) << ename << "\" on level " << GetLevelID()
166 << " by factory " << std::setw(25) << requestedBy->ShortClassName() << " [" << requestedBy << "]";
167 throw Exceptions::RuntimeError(msg.str());
168 }
169
170 } else if (requestMode_ == RELEASE) {
171 Release(ename, factory, requestedBy);
172
173 } else
174 TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, "MueLu::Level::DeclareInput(): requestMode_ undefined.");
175 }
176
177 void Level::DeclareDependencies(const FactoryBase* factory, bool bRequestOnly, bool bReleaseOnly) { //TODO: replace bReleaseOnly, bReleaseOnly by one RequestMode enum
178 if (bRequestOnly && bReleaseOnly)
179 TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, "MueLu::Level::DeclareDependencies(): Both bRequestOnly and bReleaseOnly set to true makes no sense.");
180
181 if (requestMode_ == REQUEST) {
182
183 if (bReleaseOnly == false) Request(*factory);
184
185 } else if (requestMode_ == RELEASE) {
186
187 if (bRequestOnly == false) Release(*factory);
188
189 } else TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, "MueLu::Level::DeclareDependencies(): requestMode_ undefined.");
190 }
191
192 void Level::Request(const std::string& ename, const FactoryBase* factory, const FactoryBase* requestedBy) {
193 const FactoryBase* fac = GetFactory(ename, factory);
194 // printf("(l=%d) [%43s] requesting \"%20s\" generated by %10p [actually, generated by %p (%43s)]\n",
195 // levelID_, requestedBy->description().c_str(), ename.c_str(), factory, fac, fac->description().c_str());
196
197 // We request factory only if necessary, i.e.
198 // - factory has not been requested before, and
199 // - we need data which is not available
200 // Let us consider an RAP factory in the reuse scenario. The factory generates "A" (coarse matrix) and
201 // "RAP graph" (pattern of A). Typically, "A" has keep flag Final, which is cleared during next Setup, but
202 // "RAP graph" has flag Keep, which is not cleared as it is part of NextRun. Therefore, during next Setup
203 // we have RAP factory with available "RAP graph" but not available "A".
204 //
205 // During the regular construction phase, we will do a single request: ("A", RAPFactory). Suppose, we used
206 // bool test = (IsRequestedFactory(fac) == false && IsAvailable(fac) == false);
207 // This is incorrect, as IsAvailable(fac) checks whether there is *any* data generated by factory, which there is
208 // ("A"), and the dependencies of the factory would not be requested despite the need for them (we need fine A, P, and
209 // R to generate Ac even if we know sparsity pattern of Ac).
210 //
211 // On the other hand,
212 // bool test = (IsRequestedFactory(fac) == false && IsAvailable(ename, fac) == false);
213 // is correct as ("A", fac) is not available (only ("RAP graph", fac) is), and dependent factories would be
214 // properly requested.
215 //
216 // This way, factory is requested only once (because of the IsRequested(fac) check), and only when one of the needed
217 // pieces of data is not availble.
218 bool test = (IsRequestedFactory(fac) == false && IsAvailable(ename, fac) == false);
219
220 // This request must be done before calling Request(*fac) to avoid circular dependency problems.
221 if (!IsKey(fac, ename)) {
222 Teuchos::RCP<MueLu::VariableContainer> newVar = Teuchos::rcp(new MueLu::VariableContainer);
223 map_[fac][ename] = newVar;
224 }
225
226 Teuchos::RCP<MueLu::VariableContainer>& v = map_[fac][ename];
227 v->Request(requestedBy);
228
229 // The value of IsRequestedFactory(fac) is true, due to the above request.
230 // That is why a temporary boolean "test" is used!
231 TEUCHOS_TEST_FOR_EXCEPTION(IsRequestedFactory(fac) != true, Exceptions::RuntimeError, "Level::Request(ename, factory): internal logic error.");
232
233 if (test) {
234 // Call Request for factory dependencies.
235 // We only do that if necessary, see comments above
236 Request(*fac);
237 }
238 }
239
240 void Level::Release(const std::string& ename, const FactoryBase* factory, const FactoryBase* requestedBy) {
241 const FactoryBase* fac = GetFactory(ename, factory);
242 // printf("(l=%d) [%43s] releasing \"%20s\" generated by %10p [actually, generated by %p (%43s)]\n",
243 // levelID_, requestedBy->description().c_str(), ename.c_str(), factory, fac, fac->description().c_str());
244
245 // Only a factory which has requested (fac,ename) is allowed to release it again.
246 // Do not release data if it has not been requested by the factory "requestedBy"
247 // Note: when data is released (fac,ename) depends on it often happened that some
248 // of this data has (recursively) been released too often
249 if (IsRequestedBy(fac, ename, requestedBy)) {
250
251 // In general all data (fac,ename) depends on is released when calling Get in generating factory (fac) Build method
252 // Here we check the need to release the dependencies of some data that has been requested (by factory "requestedBy")
253 // but the corresponding Build function of factory "fac" has never been called. Therefore the dependencies
254 // have never been released. Do it now.
255 if (CountRequestedFactory(fac) == 1 && // check if factory fac is not requested by another factory
256 IsAvailableFactory(fac) == false) { // check if Build function of factory fac has been called
257 Release(*fac);
258 }
259
260 TEUCHOS_TEST_FOR_EXCEPTION(!IsKey(fac,ename), Exceptions::RuntimeError, "\"" + ename + "\" not found. Do a request first.");
261
262 Teuchos::RCP<MueLu::VariableContainer>& v = map_[fac][ename];
263 v->Release(requestedBy);
264
265 // Remove data if no keep flag left and counter == 0
266 if ((v->IsRequested() == false) && (v->GetKeepFlag() == 0)) {
267 v = Teuchos::null; // free data
268
269 map_[fac].erase(ename);
270 if (map_.count(fac) == 0)
271 map_.erase(fac);
272 }
273 }
274 }
275
277 // TODO: needs some love, ugly as it is
278 // The ugliness is the fact that we restart both loops when we remove a single element
279 bool wasRemoved;
280 do {
281 wasRemoved = false;
282 for (TwoKeyMap::const_iterator kt = map_.begin(); kt != map_.end(); kt++) {
283 const FactoryBase* factory = kt->first;
284
285 for (SubMap::const_iterator it = kt->second.begin(); it != kt->second.end(); it++) {
286 // We really want a reference here, but because later we'll need to check whether the
287 // key was removed, we should copy the value
288 const std::string ename = it->first;
289
290 // We clear all the data that
291 // a) has not been requested
292 // b) is not being kept using NextRun (e.g., we clear out Final data)
293 if (!IsKept(ename, factory, MueLu::NextRun)) {
294 RemoveKeepFlag(ename, factory, MueLu::All); // will delete the data if counter == 0
295
296 // To prevent infinite looping, we need to check whether we have
297 // actually removed the data. In buggy code it may happen that we
298 // were unable to do that, for instance, if the data was outstanding
299 // request
300 if (IsKey(factory, ename)) {
301 GetOStream(Errors) << "Level::Clear found Internal data inconsistency" << std::endl;
302 print(GetOStream(Errors), VERB_EXTREME);
303
304 throw Exceptions::RuntimeError("Level::Clear found Internal data inconsistency");
305 }
306
307 wasRemoved = true;
308 break;
309 }
310 }
311
312 if (wasRemoved)
313 break;
314 }
315
316 } while (wasRemoved == true);
317 }
318
320 TwoKeyMap::const_iterator kt = map_.begin();
321 while (kt != map_.end()) {
322 const FactoryBase* factory = kt->first;
323
324 SubMap::const_iterator it = kt->second.begin();
325 while ( it != kt->second.end()) {
326 const std::string& ename = it->first;
327
328 // obtain variable container
329 Teuchos::RCP<MueLu::VariableContainer>& v = map_[factory][ename];
330
331 if (v->GetKeepFlag() == 0 ||
332 v->IsKept(MueLu::UserData) == true ||
333 v->IsKept(MueLu::Final) == true) {
334 it++;
335 v = Teuchos::null; // free data
336 map_[factory].erase(ename);
337 if (map_.count(factory) == 0) {
338 break; // last occurrence for factory has been removed. proceed with next factory
339 }
340 }
341 else
342 it++;
343 } // end for it
344
345 if (map_.count(factory) == 0) {
346 kt++;
347 map_.erase(factory);
348 } else kt++;
349 }
350 }
351
352 std::string Level::description() const {
353 std::ostringstream out;
354 out << BaseClass::description();
355 out << "{ levelID = " << levelID_ << "}";
356 return out.str();
357 }
358
359 void Level::print(std::ostream& out, const VerbLevel verbLevel) const {
360 if (!(verbLevel & Debug))
361 return;
362
363 out << "LevelID = " << GetLevelID() << std::endl;
364
365 typedef Teuchos::TabularOutputter TTO;
366 TTO outputter(out);
367 outputter.pushFieldSpec("data name", TTO::STRING, TTO::LEFT, TTO::GENERAL, 20);
368 outputter.pushFieldSpec("gen. factory addr.", TTO::STRING, TTO::LEFT, TTO::GENERAL, 40);
369 outputter.pushFieldSpec("req", TTO::INT, TTO::LEFT, TTO::GENERAL, 3);
370 outputter.pushFieldSpec("keep", TTO::STRING, TTO::LEFT, TTO::GENERAL, 5);
371 outputter.pushFieldSpec("type", TTO::STRING, TTO::LEFT, TTO::GENERAL, 18);
372 outputter.pushFieldSpec("data", TTO::STRING, TTO::LEFT, TTO::GENERAL, 14);
373 outputter.pushFieldSpec("req'd by", TTO::STRING, TTO::LEFT, TTO::GENERAL, 20);
374 outputter.outputHeader();
375
376 for (TwoKeyMap::const_iterator kt = map_.begin(); kt != map_.end(); kt++) {
377 const FactoryBase* factory = kt->first;
378
379 for (SubMap::const_iterator it = kt->second.begin(); it != kt->second.end(); it++) {
380 const std::string& ename = it->first;
381
382 outputter.outputField(ename); // variable name
383
384 // NOTE: We cannot dereference the factory pointer and call factory->description() as we do not know
385 // if the factory still exist (the factory pointer is a raw pointer by design). Instead, the level
386 // should store the factory description internally as a string for debugging purpose (and in debug mode only).
387 // // factory name
388 // std::stringstream ss1;
389 // ss1 << (*kt)->description();
390 // outputter.outputField((ss1.str()).substr(0,30));
391 if(factory == 0) {
392 outputter.outputField("Null");
393 }
394 else if (factory == NoFactory::get()) {
395 outputter.outputField("NoFactory");
396 }
397 else {
398 std::ostringstream oss; oss << factory->ShortClassName() << "["<<factory->GetID()<<"]";
399#ifdef HAVE_MUELU_DEBUG
400 oss<<"(" << factory <<")";
401#endif
402 outputter.outputField(oss.str());
403 }
404
405 int reqcount = NumRequests(factory, ename); // request counter
406 outputter.outputField(reqcount);
407
408 KeepType keepType = GetKeepFlag(ename, factory);
409 if (keepType != 0) {
410 std::stringstream ss;
411 if (keepType & MueLu::UserData) { ss << "User"; }
412 if (keepType & MueLu::Keep) { ss << "Keep"; }
413 if (keepType & MueLu::Final) { ss << "Final"; }
414 outputter.outputField(ss.str());
415 } else {
416 outputter.outputField("No");
417 }
418
419 if (IsAvailable(ename, factory)) {
420 std::string strType = it->second->GetTypeName();
421
422 if (strType == "int") {
423 outputter.outputField(strType);
424 outputter.outputField(it->second->GetData<int>());
425 } else if (strType == "double") {
426 outputter.outputField(strType);
427 outputter.outputField(it->second->GetData<double>());
428 } else if (strType == "string") {
429 outputter.outputField(strType);
430 outputter.outputField(it->second->GetData<std::string>());
431 } else {
432 size_t npos = std::string::npos;
433
434 if (strType.find("MueLu::Aggregates") != npos) outputter.outputField("Aggregates");
435 else if (strType.find("MueLu::AmalgamationInfo") != npos) outputter.outputField("AmalgamationInfo");
436 else if (strType.find("MueLu::Constraint") != npos) outputter.outputField("Constraint");
437 else if (strType.find("MueLu::Graph") != npos) outputter.outputField("Graph");
438 else if (strType.find("MueLu::SmootherBase") != npos) outputter.outputField("SmootherBase");
439 else if (strType.find("MueLu::SmootherPrototype") != npos) outputter.outputField("SmootherPrototype");
440 else if (strType.find("Xpetra::Export") != npos) outputter.outputField("Export");
441 else if (strType.find("Xpetra::Import") != npos) outputter.outputField("Import");
442 else if (strType.find("Xpetra::Map") != npos) outputter.outputField("Map");
443 else if (strType.find("Xpetra::Matrix") != npos) outputter.outputField("Matrix" );
444 else if (strType.find("Xpetra::MultiVector") != npos) outputter.outputField("Vector");
445 else if (strType.find("Xpetra::Operator") != npos) outputter.outputField("Operator");
446 else outputter.outputField(strType);
447
448 outputter.outputField("available");
449 }
450
451 } else {
452 outputter.outputField("unknown");
453 outputter.outputField("not available");
454 }
455
456 typedef VariableContainer::request_container container_type;
457 const container_type& requestedBy = it->second->Requests();
458 std::ostringstream ss;
459 for (container_type::const_iterator ct = requestedBy.begin(); ct != requestedBy.end(); ct++) {
460 if (ct != requestedBy.begin()) ss << ",";
461 ss << ct->first->ShortClassName() <<"["<<ct->first->GetID()<<"]";
462#ifdef HAVE_MUELU_DEBUG
463 ss<<"("<<ct->first<<")";
464#endif
465
466 if (ct->second > 1) ss << "x" << ct->second;
467 }
468 outputter.outputField(ss.str());
469
470 outputter.nextRow();
471 }
472 } // for (TwoKeyMap::const_iterator kt = map_.begin(); kt != map_.end(); kt++) {
473 }
474
475#if defined(HAVE_MUELU_BOOST) && defined(HAVE_MUELU_BOOST_FOR_REAL) && defined(BOOST_VERSION) && (BOOST_VERSION >= 104400)
476 void Level::UpdateGraph(std::map<const FactoryBase*, BoostVertex>& vindices,
477 std::map<std::pair<BoostVertex, BoostVertex>, std::string>& edges,
478 BoostProperties& dp,
479 BoostGraph& graph) const {
480 size_t vind = vindices.size();
481
482 for (TwoKeyMap::const_iterator it1 = map_.begin(); it1 != map_.end(); it1++) {
483 if (vindices.find(it1->first) == vindices.end()) {
484 BoostVertex boost_vertex = boost::add_vertex(graph);
485 std::ostringstream oss; oss<<it1->first->ShortClassName() << "[" << it1->first->GetID() << "]";
486 boost::put("label", dp, boost_vertex, oss.str());
487 vindices[it1->first] = vind++;
488 }
489
490 for (SubMap::const_iterator it2 = it1->second.begin(); it2 != it1->second.end(); it2++) {
491 const VariableContainer::request_container& requests = it2->second->Requests();
492 for (VariableContainer::request_container::const_iterator rit = requests.begin(); rit != requests.end(); rit++) {
493 if (vindices.find(rit->first) == vindices.end()) {
494 // requested by factory which is unknown
495 BoostVertex boost_vertex = boost::add_vertex(graph);
496 std::ostringstream oss; oss<<rit->first->ShortClassName() << "[" << rit->first->GetID() << "]";
497 boost::put("label", dp, boost_vertex, oss.str());
498 vindices[rit->first] = vind++;
499 }
500
501 edges[std::pair<BoostVertex,BoostVertex>(vindices[rit->first], vindices[it1->first])] = it2->first;
502 }
503 }
504 }
505 }
506#endif
507
508 // JG Note: should the option IgnoreUserData() moved to the Factory interface or on the specific factories that are using this option? It would simplify the level class.
509 const FactoryBase* Level::GetFactory(const std::string& ename, const FactoryBase* factory) const {
510 if (factory != NULL)
511 return factory;
512
513 // If IgnoreUserData == false and if variable "ename" generated by NoFactory is provided by the user (MueLu::UserData),
514 // use user-provided data by default without querying the FactoryManager.
515 // When FactoryManager == null, we consider that IgnoreUserData == false.
516 if ((factoryManager_ == Teuchos::null || factoryManager_->IgnoreUserData() == false) &&
518 return NoFactory::get();
519 }
520
521 // Query factory manager
522 TEUCHOS_TEST_FOR_EXCEPTION(factoryManager_ == null, Exceptions::RuntimeError, "MueLu::Level("<< levelID_ << ")::GetFactory(" << ename << ", " << factory << "): No FactoryManager");
523 const FactoryBase* fac = factoryManager_->GetFactory(ename).get();
524 TEUCHOS_TEST_FOR_EXCEPTION(fac == NULL, Exceptions::RuntimeError, "MueLu::Level("<< levelID_ << ")::GetFactory(" << ename << ", " << factory << "): Default factory returned by FactoryManager cannot be NULL");
525 return fac;
526 }
527
529
530} //namespace MueLu
531
532//TODO: Caps should not matter
virtual std::string ShortClassName() const
Return the class name of the object, without template parameters and without namespace.
virtual std::string description() const
Return a simple one-line description of this object.
Exception throws to report data dependency problems between factories.
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 CallDeclareInput(Level &requestedLevel) const =0
int GetID() const
return unique factory id
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.
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()
RCP< Level > Build()
Definition: MueLu_Level.cpp:54
std::string description() const
Return a simple one-line description of this object.
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
const RCP< const FactoryManagerBase > GetFactoryManager()
returns the current factory manager
Definition: MueLu_Level.cpp:96
void SetLevelID(int levelID)
Set level number.
Definition: MueLu_Level.cpp:78
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.
Definition: MueLu_Level.cpp:76
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 ExpertClear()
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
KeepType GetKeepFlag(const std::string &ename, const FactoryBase *factory) const
Get the flag combination set for variable 'ename' generated by 'factory'.
RCP< const FactoryManagerBase > factoryManager_
bool IsKept(const std::string &ename, const FactoryBase *factory, KeepType keep) const
bool IsAvailableFactory(const FactoryBase *factory) const
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)
Definition: MueLu_Level.cpp:85
void SetFactoryManager(const RCP< const FactoryManagerBase > &factoryManager)
Set default factories (used internally by Hierarchy::SetLevel()).
Definition: MueLu_Level.cpp:92
int levelID_
Map of a map (Key1 -> SubMap)
TwoKeyMap map_
bool IsKey(const FactoryBase *factory, const std::string &ename) const
Test whether some information about (ename, factory) are stored.
static const NoFactory * get()
Class that stores all relevant data for a variable.
std::map< const FactoryBase *, int > request_container
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.
@ Final
Keep data only for this run. Used to keep data useful for Hierarchy::Iterate(). Data will be deleted ...
@ Keep
Always keep data, even accross run. This flag is set by Level::Keep(). This flag is propagated to coa...
@ NextRun
Both UserData and Keep flags force data to be kept and reused for the next run. Do not use MueLu::Nex...
@ UserData
User data are always kept. This flag is set automatically when Level::Set("data", data) is used....
@ Debug
Print additional debugging information.
@ Errors
Errors.
@ Warnings1
Additional warnings.
short KeepType