MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
52 namespace MueLu {
53 
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 
93  factoryManager_ = factoryManager;
94  }
95 
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
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) {
137  RequestMode prev = requestMode_;
139  factory.CallDeclareInput(*this);
140  requestMode_ = prev;
141  }
142 
143  void Level::Release(const FactoryBase& factory) {
144  RequestMode prev = requestMode_;
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)) {
223  map_[fac][ename] = newVar;
224  }
225 
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 
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 
276  void Level::Clear() {
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;
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, 18);
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, 15);
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 
392  // factory ptr
393  if (factory == NoFactory::get())
394  outputter.outputField("NoFactory");
395  else
396  outputter.outputField(factory);
397 
398 
399  int reqcount = NumRequests(factory, ename); // request counter
400  outputter.outputField(reqcount);
401 
402  KeepType keepType = GetKeepFlag(ename, factory);
403  if (keepType != 0) {
404  std::stringstream ss;
405  if (keepType & MueLu::UserData) { ss << "User"; }
406  if (keepType & MueLu::Keep) { ss << "Keep"; }
407  if (keepType & MueLu::Final) { ss << "Final"; }
408  outputter.outputField(ss.str());
409  } else {
410  outputter.outputField("No");
411  }
412 
413  if (IsAvailable(ename, factory)) {
414  std::string strType = it->second->GetTypeName();
415 
416  if (strType == "int") {
417  outputter.outputField(strType);
418  outputter.outputField(it->second->GetData<int>());
419  } else if (strType == "double") {
420  outputter.outputField(strType);
421  outputter.outputField(it->second->GetData<double>());
422  } else if (strType == "string") {
423  outputter.outputField(strType);
424  outputter.outputField(it->second->GetData<std::string>());
425  } else {
426  size_t npos = std::string::npos;
427 
428  if (strType.find("MueLu::Aggregates") != npos) outputter.outputField("Aggregates");
429  else if (strType.find("MueLu::AmalgamationInfo") != npos) outputter.outputField("AmalgamationInfo");
430  else if (strType.find("MueLu::Constraint") != npos) outputter.outputField("Constraint");
431  else if (strType.find("MueLu::Graph") != npos) outputter.outputField("Graph");
432  else if (strType.find("MueLu::SmootherBase") != npos) outputter.outputField("SmootherBase");
433  else if (strType.find("MueLu::SmootherPrototype") != npos) outputter.outputField("SmootherPrototype");
434  else if (strType.find("Xpetra::Export") != npos) outputter.outputField("Export");
435  else if (strType.find("Xpetra::Import") != npos) outputter.outputField("Import");
436  else if (strType.find("Xpetra::Map") != npos) outputter.outputField("Map");
437  else if (strType.find("Xpetra::Matrix") != npos) outputter.outputField("Matrix" );
438  else if (strType.find("Xpetra::MultiVector") != npos) outputter.outputField("Vector");
439  else if (strType.find("Xpetra::Operator") != npos) outputter.outputField("Operator");
440  else outputter.outputField(strType);
441 
442  outputter.outputField("available");
443  }
444 
445  } else {
446  outputter.outputField("unknown");
447  outputter.outputField("not available");
448  }
449 
450  typedef VariableContainer::request_container container_type;
451  const container_type& requestedBy = it->second->Requests();
452  std::ostringstream ss;
453  for (container_type::const_iterator ct = requestedBy.begin(); ct != requestedBy.end(); ct++) {
454  if (ct != requestedBy.begin()) ss << ",";
455  ss << ct->first;
456  if (ct->second > 1) ss << "(" << ct->second << ")";
457  }
458  outputter.outputField(ss.str());
459 
460  outputter.nextRow();
461  }
462  } // for (TwoKeyMap::const_iterator kt = map_.begin(); kt != map_.end(); kt++) {
463  }
464 
465 #if defined(HAVE_MUELU_BOOST) && defined(HAVE_MUELU_BOOST_FOR_REAL) && defined(BOOST_VERSION) && (BOOST_VERSION >= 104400)
466  void Level::UpdateGraph(std::map<const FactoryBase*, BoostVertex>& vindices,
467  std::map<std::pair<BoostVertex, BoostVertex>, std::string>& edges,
468  BoostProperties& dp,
469  BoostGraph& graph) const {
470  size_t vind = vindices.size();
471 
472  for (TwoKeyMap::const_iterator it1 = map_.begin(); it1 != map_.end(); it1++) {
473  if (vindices.find(it1->first) == vindices.end()) {
474  BoostVertex boost_vertex = boost::add_vertex(graph);
475  boost::put("label", dp, boost_vertex, it1->first->description());
476  vindices[it1->first] = vind++;
477  }
478 
479  for (SubMap::const_iterator it2 = it1->second.begin(); it2 != it1->second.end(); it2++) {
480  const VariableContainer::request_container& requests = it2->second->Requests();
481  for (VariableContainer::request_container::const_iterator rit = requests.begin(); rit != requests.end(); rit++) {
482  if (vindices.find(rit->first) == vindices.end()) {
483  // requested by factory which is unknown
484  BoostVertex boost_vertex = boost::add_vertex(graph);
485  boost::put("label", dp, boost_vertex, rit->first->description());
486  vindices[rit->first] = vind++;
487  }
488 
489  edges[std::pair<BoostVertex,BoostVertex>(vindices[rit->first], vindices[it1->first])] = it2->first;
490  }
491  }
492  }
493  }
494 #endif
495 
496  // 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.
497  const FactoryBase* Level::GetFactory(const std::string& ename, const FactoryBase* factory) const {
498  if (factory != NULL)
499  return factory;
500 
501  // If IgnoreUserData == false and if variable "ename" generated by NoFactory is provided by the user (MueLu::UserData),
502  // use user-provided data by default without querying the FactoryManager.
503  // When FactoryManager == null, we consider that IgnoreUserData == false.
504  if ((factoryManager_ == Teuchos::null || factoryManager_->IgnoreUserData() == false) &&
505  (IsAvailable(ename, NoFactory::get()) && IsKept(ename, NoFactory::get(), MueLu::UserData))) {
506  return NoFactory::get();
507  }
508 
509  // Query factory manager
510  TEUCHOS_TEST_FOR_EXCEPTION(factoryManager_ == null, Exceptions::RuntimeError, "MueLu::Level("<< levelID_ << ")::GetFactory(" << ename << ", " << factory << "): No FactoryManager");
511  const FactoryBase* fac = factoryManager_->GetFactory(ename).get();
512  TEUCHOS_TEST_FOR_EXCEPTION(fac == NULL, Exceptions::RuntimeError, "MueLu::Level("<< levelID_ << ")::GetFactory(" << ename << ", " << factory << "): Default factory returned by FactoryManager cannot be NULL");
513  return fac;
514  }
515 
517 
518 } //namespace MueLu
519 
520 //TODO: Caps should not matter
virtual void CallDeclareInput(Level &requestedLevel) const =0
KeepType GetKeepFlag(const std::string &ename, const FactoryBase *factory) const
Get the flag combination set for variable &#39;ename&#39; generated by &#39;factory&#39;.
Teuchos::FancyOStream & GetOStream(MsgType type, int thisProcRankOnly=0) const
Get an output stream for outputting the input message type.
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.
bool IsKept(const std::string &ename, const FactoryBase *factory, KeepType keep) const
void DeclareDependencies(const FactoryBase *factory, bool bRequestOnly=false, bool bReleaseOnly=false)
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput() to declare factory depe...
void Release(const FactoryBase &factory)
Decrement the storage counter for all the inputs of a factory.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
short KeepType
KeepType GetKeepFlag() const
Returns the keep flag combination.
TwoKeyMap map_
Print additional debugging information.
RCP< Level > previousLevel_
User data are always kept. This flag is set automatically when Level::Set(&quot;data&quot;, data) is used...
void RemoveKeepFlag(KeepType keep=UserData)
Removes a keep flag to the flag combination.
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
void Request(const FactoryBase *reqFactory)
Request data.
int CountRequestedFactory(const FactoryBase *factory) const
static const NoFactory * get()
virtual std::string ShortClassName() const
Return the class name of the object, without template parameters and without namespace.
std::map< const FactoryBase *, int > request_container
Additional warnings.
Base class for factories (e.g., R, P, and A_coarse).
void Clear()
Delete all data that have been retained after the setup phase using Final flag.
bool IsRequestedBy(const FactoryBase *factory, const std::string &ename, const FactoryBase *requestedBy) const
const FactoryBase * GetFactory(const std::string &varname, const FactoryBase *factory) const
If input factory == NULL, returns the default factory. Else, return input factory.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
void ExpertClear()
bool IsKept(KeepType keep) const
Returns true if at least one keep flag is set.
static RequestMode requestMode_
Keep data only for this run. Used to keep data useful for Hierarchy::Iterate(). Data will be deleted ...
int levelID_
Map of a map (Key1 -&gt; SubMap)
void Release(const FactoryBase *reqFactory)
Release data.
void RemoveKeepFlag(const std::string &ename, const FactoryBase *factory, KeepType keep=MueLu::All)
std::string description() const
Return a simple one-line description of this object.
Always keep data, even accross run. This flag is set by Level::Keep(). This flag is propagated to coa...
int NumRequests(const FactoryBase *factory, const std::string &ename) const
void AddKeepFlag(const std::string &ename, const FactoryBase *factory=NoFactory::get(), KeepType keep=MueLu::Keep)
Both UserData and Keep flags force data to be kept and reused for the next run. Do not use MueLu::Nex...
bool IsAvailableFactory(const FactoryBase *factory) const
RCP< Level > Build()
Definition: MueLu_Level.cpp:54
void print(std::ostream &out, const VerbLevel verbLevel=Default) const
Printing method.
void SetLevelID(int levelID)
Set level number.
Definition: MueLu_Level.cpp:78
RCP< const FactoryManagerBase > factoryManager_
bool IsRequestedFactory(const FactoryBase *factory) const
const RCP< const FactoryManagerBase > GetFactoryManager()
returns the current factory manager
Definition: MueLu_Level.cpp:96
int GetLevelID() const
Return level number.
Definition: MueLu_Level.cpp:76
Exception throws to report errors in the internal logical of the program.
Class that stores all relevant data for a variable.
bool IsKey(const FactoryBase *factory, const std::string &ename) const
Test whether some information about (ename, factory) are stored.
void DeclareInput(const std::string &ename, const FactoryBase *factory, const FactoryBase *requestedBy=NoFactory::get())
Callback from FactoryBase::CallDeclareInput() and FactoryBase::DeclareInput()
bool IsRequested(const FactoryBase *reqFactory) const
Returns true, if data is requested by reqFactory.
virtual std::string description() const
Return a simple one-line description of this object.
Exception throws to report data dependency problems between factories.
bool IsAvailable(const std::string &ename, const FactoryBase *factory=NoFactory::get()) const
Test whether a need&#39;s value has been saved.
void Request(const FactoryBase &factory)
Increment the storage counter for all the inputs of a factory.