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  if (bReleaseOnly == false) Request(*factory);
183 
184  } else if (requestMode_ == RELEASE) {
185  if (bRequestOnly == false) Release(*factory);
186 
187  } else
188  TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, "MueLu::Level::DeclareDependencies(): requestMode_ undefined.");
189 }
190 
191 void Level::Request(const std::string& ename, const FactoryBase* factory, const FactoryBase* requestedBy) {
192  const FactoryBase* fac = GetFactory(ename, factory);
193  // printf("(l=%d) [%43s] requesting \"%20s\" generated by %10p [actually, generated by %p (%43s)]\n",
194  // levelID_, requestedBy->description().c_str(), ename.c_str(), factory, fac, fac->description().c_str());
195 
196  // We request factory only if necessary, i.e.
197  // - factory has not been requested before, and
198  // - we need data which is not available
199  // Let us consider an RAP factory in the reuse scenario. The factory generates "A" (coarse matrix) and
200  // "RAP graph" (pattern of A). Typically, "A" has keep flag Final, which is cleared during next Setup, but
201  // "RAP graph" has flag Keep, which is not cleared as it is part of NextRun. Therefore, during next Setup
202  // we have RAP factory with available "RAP graph" but not available "A".
203  //
204  // During the regular construction phase, we will do a single request: ("A", RAPFactory). Suppose, we used
205  // bool test = (IsRequestedFactory(fac) == false && IsAvailable(fac) == false);
206  // This is incorrect, as IsAvailable(fac) checks whether there is *any* data generated by factory, which there is
207  // ("A"), and the dependencies of the factory would not be requested despite the need for them (we need fine A, P, and
208  // R to generate Ac even if we know sparsity pattern of Ac).
209  //
210  // On the other hand,
211  // bool test = (IsRequestedFactory(fac) == false && IsAvailable(ename, fac) == false);
212  // is correct as ("A", fac) is not available (only ("RAP graph", fac) is), and dependent factories would be
213  // properly requested.
214  //
215  // This way, factory is requested only once (because of the IsRequested(fac) check), and only when one of the needed
216  // pieces of data is not availble.
217  bool test = (IsRequestedFactory(fac) == false && IsAvailable(ename, fac) == false);
218 
219  // This request must be done before calling Request(*fac) to avoid circular dependency problems.
220  if (!IsKey(fac, ename)) {
222  map_[fac][ename] = newVar;
223  }
224 
226  v->Request(requestedBy);
227 
228  // The value of IsRequestedFactory(fac) is true, due to the above request.
229  // That is why a temporary boolean "test" is used!
230  TEUCHOS_TEST_FOR_EXCEPTION(IsRequestedFactory(fac) != true, Exceptions::RuntimeError, "Level::Request(ename, factory): internal logic error.");
231 
232  if (test) {
233  // Call Request for factory dependencies.
234  // We only do that if necessary, see comments above
235  Request(*fac);
236  }
237 }
238 
239 void Level::Release(const std::string& ename, const FactoryBase* factory, const FactoryBase* requestedBy) {
240  const FactoryBase* fac = GetFactory(ename, factory);
241  // printf("(l=%d) [%43s] releasing \"%20s\" generated by %10p [actually, generated by %p (%43s)]\n",
242  // levelID_, requestedBy->description().c_str(), ename.c_str(), factory, fac, fac->description().c_str());
243 
244  // Only a factory which has requested (fac,ename) is allowed to release it again.
245  // Do not release data if it has not been requested by the factory "requestedBy"
246  // Note: when data is released (fac,ename) depends on it often happened that some
247  // of this data has (recursively) been released too often
248  if (IsRequestedBy(fac, ename, requestedBy)) {
249  // In general all data (fac,ename) depends on is released when calling Get in generating factory (fac) Build method
250  // Here we check the need to release the dependencies of some data that has been requested (by factory "requestedBy")
251  // but the corresponding Build function of factory "fac" has never been called. Therefore the dependencies
252  // have never been released. Do it now.
253  if (CountRequestedFactory(fac) == 1 && // check if factory fac is not requested by another factory
254  IsAvailableFactory(fac) == false) { // check if Build function of factory fac has been called
255  Release(*fac);
256  }
257 
258  TEUCHOS_TEST_FOR_EXCEPTION(!IsKey(fac, ename), Exceptions::RuntimeError, "\"" + ename + "\" not found. Do a request first.");
259 
261  v->Release(requestedBy);
262 
263  // Remove data if no keep flag left and counter == 0
264  if ((v->IsRequested() == false) && (v->GetKeepFlag() == 0)) {
265  v = Teuchos::null; // free data
266 
267  map_[fac].erase(ename);
268  if (map_.count(fac) == 0)
269  map_.erase(fac);
270  }
271  }
272 }
273 
274 void Level::Clear() {
275  // TODO: needs some love, ugly as it is
276  // The ugliness is the fact that we restart both loops when we remove a single element
277  bool wasRemoved;
278  do {
279  wasRemoved = false;
280  for (TwoKeyMap::const_iterator kt = map_.begin(); kt != map_.end(); kt++) {
281  const FactoryBase* factory = kt->first;
282 
283  for (SubMap::const_iterator it = kt->second.begin(); it != kt->second.end(); it++) {
284  // We really want a reference here, but because later we'll need to check whether the
285  // key was removed, we should copy the value
286  const std::string ename = it->first;
287 
288  // We clear all the data that
289  // a) has not been requested
290  // b) is not being kept using NextRun (e.g., we clear out Final data)
291  if (!IsKept(ename, factory, MueLu::NextRun)) {
292  RemoveKeepFlag(ename, factory, MueLu::All); // will delete the data if counter == 0
293 
294  // To prevent infinite looping, we need to check whether we have
295  // actually removed the data. In buggy code it may happen that we
296  // were unable to do that, for instance, if the data was outstanding
297  // request
298  if (IsKey(factory, ename)) {
299  GetOStream(Errors) << "Level::Clear found Internal data inconsistency" << std::endl;
301 
302  throw Exceptions::RuntimeError("Level::Clear found Internal data inconsistency");
303  }
304 
305  wasRemoved = true;
306  break;
307  }
308  }
309 
310  if (wasRemoved)
311  break;
312  }
313 
314  } while (wasRemoved == true);
315 }
316 
318  TwoKeyMap::const_iterator kt = map_.begin();
319  while (kt != map_.end()) {
320  const FactoryBase* factory = kt->first;
321 
322  SubMap::const_iterator it = kt->second.begin();
323  while (it != kt->second.end()) {
324  const std::string& ename = it->first;
325 
326  // obtain variable container
327  Teuchos::RCP<MueLu::VariableContainer>& v = map_[factory][ename];
328 
329  if (v->GetKeepFlag() == 0 ||
330  v->IsKept(MueLu::UserData) == true ||
331  v->IsKept(MueLu::Final) == true) {
332  it++;
333  v = Teuchos::null; // free data
334  map_[factory].erase(ename);
335  if (map_.count(factory) == 0) {
336  break; // last occurrence for factory has been removed. proceed with next factory
337  }
338  } else
339  it++;
340  } // end for it
341 
342  if (map_.count(factory) == 0) {
343  kt++;
344  map_.erase(factory);
345  } else
346  kt++;
347  }
348 }
349 
350 std::string Level::description() const {
351  std::ostringstream out;
352  out << BaseClass::description();
353  out << "{ levelID = " << levelID_ << "}";
354  return out.str();
355 }
356 
357 void Level::print(std::ostream& out, const VerbLevel verbLevel) const {
358  if (!(verbLevel & Debug))
359  return;
360 
361  out << "LevelID = " << GetLevelID() << std::endl;
362 
363  typedef Teuchos::TabularOutputter TTO;
364  TTO outputter(out);
365  outputter.pushFieldSpec("data name", TTO::STRING, TTO::LEFT, TTO::GENERAL, 20);
366  outputter.pushFieldSpec("gen. factory addr.", TTO::STRING, TTO::LEFT, TTO::GENERAL, 40);
367  outputter.pushFieldSpec("req", TTO::INT, TTO::LEFT, TTO::GENERAL, 3);
368  outputter.pushFieldSpec("keep", TTO::STRING, TTO::LEFT, TTO::GENERAL, 5);
369  outputter.pushFieldSpec("type", TTO::STRING, TTO::LEFT, TTO::GENERAL, 18);
370  outputter.pushFieldSpec("data", TTO::STRING, TTO::LEFT, TTO::GENERAL, 14);
371  outputter.pushFieldSpec("req'd by", TTO::STRING, TTO::LEFT, TTO::GENERAL, 20);
372  outputter.outputHeader();
373 
374  for (TwoKeyMap::const_iterator kt = map_.begin(); kt != map_.end(); kt++) {
375  const FactoryBase* factory = kt->first;
376 
377  for (SubMap::const_iterator it = kt->second.begin(); it != kt->second.end(); it++) {
378  const std::string& ename = it->first;
379 
380  outputter.outputField(ename); // variable name
381 
382  // NOTE: We cannot dereference the factory pointer and call factory->description() as we do not know
383  // if the factory still exist (the factory pointer is a raw pointer by design). Instead, the level
384  // should store the factory description internally as a string for debugging purpose (and in debug mode only).
385  // // factory name
386  // std::stringstream ss1;
387  // ss1 << (*kt)->description();
388  // outputter.outputField((ss1.str()).substr(0,30));
389  if (factory == 0) {
390  outputter.outputField("Null");
391  } else if (factory == NoFactory::get()) {
392  outputter.outputField("NoFactory");
393  } else {
394  std::ostringstream oss;
395  oss << factory->ShortClassName() << "[" << factory->GetID() << "]";
396 #ifdef HAVE_MUELU_DEBUG
397  oss << "(" << factory << ")";
398 #endif
399  outputter.outputField(oss.str());
400  }
401 
402  int reqcount = NumRequests(factory, ename); // request counter
403  outputter.outputField(reqcount);
404 
405  KeepType keepType = GetKeepFlag(ename, factory);
406  if (keepType != 0) {
407  std::stringstream ss;
408  if (keepType & MueLu::UserData) {
409  ss << "User";
410  }
411  if (keepType & MueLu::Keep) {
412  ss << "Keep";
413  }
414  if (keepType & MueLu::Final) {
415  ss << "Final";
416  }
417  outputter.outputField(ss.str());
418  } else {
419  outputter.outputField("No");
420  }
421 
422  if (IsAvailable(ename, factory)) {
423  std::string strType = it->second->GetTypeName();
424 
425  if (strType == "int") {
426  outputter.outputField(strType);
427  outputter.outputField(it->second->GetData<int>());
428  } else if (strType == "double") {
429  outputter.outputField(strType);
430  outputter.outputField(it->second->GetData<double>());
431  } else if (strType == "string") {
432  outputter.outputField(strType);
433  outputter.outputField(it->second->GetData<std::string>());
434  } else {
435  size_t npos = std::string::npos;
436 
437  if (strType.find("MueLu::Aggregates") != npos)
438  outputter.outputField("Aggregates");
439  else if (strType.find("MueLu::AmalgamationInfo") != npos)
440  outputter.outputField("AmalgamationInfo");
441  else if (strType.find("MueLu::Constraint") != npos)
442  outputter.outputField("Constraint");
443  else if (strType.find("MueLu::SmootherBase") != npos)
444  outputter.outputField("SmootherBase");
445  else if (strType.find("MueLu::SmootherPrototype") != npos)
446  outputter.outputField("SmootherPrototype");
447  else if (strType.find("Xpetra::Export") != npos)
448  outputter.outputField("Export");
449  else if (strType.find("Xpetra::Import") != npos)
450  outputter.outputField("Import");
451  else if (strType.find("Xpetra::Map") != npos)
452  outputter.outputField("Map");
453  else if (strType.find("Xpetra::Matrix") != npos)
454  outputter.outputField("Matrix");
455  else if (strType.find("Xpetra::MultiVector") != npos)
456  outputter.outputField("Vector");
457  else if (strType.find("Xpetra::Operator") != npos)
458  outputter.outputField("Operator");
459  else
460  outputter.outputField(strType);
461 
462  outputter.outputField("available");
463  }
464 
465  } else {
466  outputter.outputField("unknown");
467  outputter.outputField("not available");
468  }
469 
470  typedef VariableContainer::request_container container_type;
471  const container_type& requestedBy = it->second->Requests();
472  std::ostringstream ss;
473  for (container_type::const_iterator ct = requestedBy.begin(); ct != requestedBy.end(); ct++) {
474  if (ct != requestedBy.begin()) ss << ",";
475  ss << ct->first->ShortClassName() << "[" << ct->first->GetID() << "]";
476 #ifdef HAVE_MUELU_DEBUG
477  ss << "(" << ct->first << ")";
478 #endif
479 
480  if (ct->second > 1) ss << "x" << ct->second;
481  }
482  outputter.outputField(ss.str());
483 
484  outputter.nextRow();
485  }
486  } // for (TwoKeyMap::const_iterator kt = map_.begin(); kt != map_.end(); kt++) {
487 }
488 
489 #if defined(HAVE_MUELU_BOOST) && defined(HAVE_MUELU_BOOST_FOR_REAL) && defined(BOOST_VERSION) && (BOOST_VERSION >= 104400)
490 void Level::UpdateGraph(std::map<const FactoryBase*, BoostVertex>& vindices,
491  std::map<std::pair<BoostVertex, BoostVertex>, std::string>& edges,
492  BoostProperties& dp,
493  BoostGraph& graph) const {
494  size_t vind = vindices.size();
495 
496  for (TwoKeyMap::const_iterator it1 = map_.begin(); it1 != map_.end(); it1++) {
497  if (vindices.find(it1->first) == vindices.end()) {
498  BoostVertex boost_vertex = boost::add_vertex(graph);
499  std::ostringstream oss;
500  oss << it1->first->ShortClassName() << "[" << it1->first->GetID() << "]";
501  boost::put("label", dp, boost_vertex, oss.str());
502  vindices[it1->first] = vind++;
503  }
504 
505  for (SubMap::const_iterator it2 = it1->second.begin(); it2 != it1->second.end(); it2++) {
506  const VariableContainer::request_container& requests = it2->second->Requests();
507  for (VariableContainer::request_container::const_iterator rit = requests.begin(); rit != requests.end(); rit++) {
508  if (vindices.find(rit->first) == vindices.end()) {
509  // requested by factory which is unknown
510  BoostVertex boost_vertex = boost::add_vertex(graph);
511  std::ostringstream oss;
512  oss << rit->first->ShortClassName() << "[" << rit->first->GetID() << "]";
513  boost::put("label", dp, boost_vertex, oss.str());
514  vindices[rit->first] = vind++;
515  }
516 
517  edges[std::pair<BoostVertex, BoostVertex>(vindices[rit->first], vindices[it1->first])] = it2->first;
518  }
519  }
520  }
521 }
522 #endif
523 
524 // 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.
525 const FactoryBase* Level::GetFactory(const std::string& ename, const FactoryBase* factory) const {
526  if (factory != NULL)
527  return factory;
528 
529  // If IgnoreUserData == false and if variable "ename" generated by NoFactory is provided by the user (MueLu::UserData),
530  // use user-provided data by default without querying the FactoryManager.
531  // When FactoryManager == null, we consider that IgnoreUserData == false.
532  if ((factoryManager_ == Teuchos::null || factoryManager_->IgnoreUserData() == false) &&
533  (IsAvailable(ename, NoFactory::get()) && IsKept(ename, NoFactory::get(), MueLu::UserData))) {
534  return NoFactory::get();
535  }
536 
537  // Query factory manager
538  TEUCHOS_TEST_FOR_EXCEPTION(factoryManager_ == null, Exceptions::RuntimeError, "MueLu::Level(" << levelID_ << ")::GetFactory(" << ename << ", " << factory << "): No FactoryManager");
539  const FactoryBase* fac = factoryManager_->GetFactory(ename).get();
540  TEUCHOS_TEST_FOR_EXCEPTION(fac == NULL, Exceptions::RuntimeError, "MueLu::Level(" << levelID_ << ")::GetFactory(" << ename << ", " << factory << "): Default factory returned by FactoryManager cannot be NULL");
541  return fac;
542 }
543 
545 
546 } // namespace MueLu
547 
548 // 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;.
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.
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.
int GetID() const
return unique factory id
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.
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.