10#include <Teuchos_TabularOutputter.hpp>
25 , factoryManager_(factoryManager) {}
30 RCP<Level> newLevel = rcp(
new Level());
33 for (TwoKeyMap::const_iterator kt =
map_.begin(); kt !=
map_.end(); kt++) {
36 for (SubMap::const_iterator it = kt->second.begin(); it != kt->second.end(); it++) {
37 const std::string& ename = it->first;
43 newLevel->Keep(ename, factory);
55 GetOStream(
Warnings1) <<
"Level::SetLevelID(): Changing an already defined LevelID (previousID=" <<
levelID_ <<
", newID=" << levelID <<
")" << std::endl;
64 GetOStream(
Warnings1) <<
"Level::SetPreviousLevel(): PreviousLevel was already defined" << std::endl;
82 "MueLu::Level::GetTypeString(): Data "
84 <<
"\" generated by " << *fac <<
" is not available.");
86 return map_[fac][ename]->GetTypeName();
90 if (!
IsKey(factory, ename))
96 TEUCHOS_TEST_FOR_EXCEPTION(
IsRequested(ename, factory) ==
true,
Exceptions::RuntimeError,
"MueLu::Level::Delete(): IsRequested() == true. Ref counter != 0. You are not allowed to delete data that are still in use.");
103 TEUCHOS_TEST_FOR_EXCEPTION(
IsAvailable(ename, factory) ==
true,
Exceptions::RuntimeError,
"MueLu::Level::Delete(): Internal error (Post condition). Data have not been deleted.");
107 if (!
IsKey(factory, ename)) {
110 map_[factory][ename] = newVar;
113 map_[factory][ename]->AddKeepFlag(keep);
118 if (!
IsKey(factory, ename))
122 Teuchos::RCP<MueLu::VariableContainer>& v =
map_[factory][ename];
123 v->RemoveKeepFlag(keep);
126 if ((v->IsRequested() ==
false) && (v->GetKeepFlag() == 0)) {
129 map_[factory].erase(ename);
130 if (
map_.count(factory) == 0)
136 if (!
IsKey(factory, ename))
139 return Get(factory, ename)->GetKeepFlag();
159 Request(ename, factory, requestedBy);
162 std::ostringstream msg;
163 msg << requestedBy->
ShortClassName() <<
"::DeclareInput: (" << e.what() <<
") unable to find or generate requested data \""
164 << ename <<
"\" with generating factory \"" << ((factory != NULL) ? factory->
ShortClassName() :
"null") <<
"\" [" << factory <<
"]";
165 msg <<
"\n during request for data \"" << std::setw(15) << ename <<
"\" on level " <<
GetLevelID()
166 <<
" by factory " << std::setw(25) << requestedBy->
ShortClassName() <<
" [" << requestedBy <<
"]";
170 std::ostringstream msg;
171 msg << e.what() <<
"\n during request for data \"" << std::setw(15) << ename <<
"\" on level " <<
GetLevelID()
172 <<
" by factory " << std::setw(25) << requestedBy->
ShortClassName() <<
" [" << requestedBy <<
"]";
177 Release(ename, factory, requestedBy);
180 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"MueLu::Level::DeclareInput(): requestMode_ undefined.");
184 if (bRequestOnly && bReleaseOnly)
185 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"MueLu::Level::DeclareDependencies(): Both bRequestOnly and bReleaseOnly set to true makes no sense.");
188 if (bReleaseOnly ==
false)
Request(*factory);
191 if (bRequestOnly ==
false)
Release(*factory);
194 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"MueLu::Level::DeclareDependencies(): requestMode_ undefined.");
226 if (!
IsKey(fac, ename)) {
228 map_[fac][ename] = newVar;
231 Teuchos::RCP<MueLu::VariableContainer>& v =
map_[fac][ename];
232 v->Request(requestedBy);
266 Teuchos::RCP<MueLu::VariableContainer>& v =
map_[fac][ename];
267 v->Release(requestedBy);
270 if ((v->IsRequested() ==
false) && (v->GetKeepFlag() == 0)) {
273 map_[fac].erase(ename);
274 if (
map_.count(fac) == 0)
282 if (!
IsKey(factory, ename))
285 return Get(factory, ename)->IsAvailable();
293 if (!
IsKey(factory, ename))
308 for (TwoKeyMap::const_iterator kt =
map_.begin(); kt !=
map_.end(); kt++) {
311 for (SubMap::const_iterator it = kt->second.begin(); it != kt->second.end(); it++) {
314 const std::string ename = it->first;
326 if (
IsKey(factory, ename)) {
327 GetOStream(
Errors) <<
"Level::Clear found Internal data inconsistency" << std::endl;
342 }
while (wasRemoved ==
true);
346 TwoKeyMap::const_iterator kt =
map_.begin();
347 while (kt !=
map_.end()) {
350 SubMap::const_iterator it = kt->second.begin();
351 while (it != kt->second.end()) {
352 const std::string& ename = it->first;
355 Teuchos::RCP<MueLu::VariableContainer>& v =
map_[factory][ename];
357 if (v->GetKeepFlag() == 0 ||
362 map_[factory].erase(ename);
363 if (
map_.count(factory) == 0) {
370 if (
map_.count(factory) == 0) {
379 std::ostringstream out;
381 out <<
"{ levelID = " <<
levelID_ <<
"}";
386 if (!(verbLevel &
Debug))
389 out <<
"LevelID = " <<
GetLevelID() << std::endl;
391 typedef Teuchos::TabularOutputter TTO;
393 outputter.pushFieldSpec(
"data name", TTO::STRING, TTO::LEFT, TTO::GENERAL, 20);
394 outputter.pushFieldSpec(
"gen. factory addr.", TTO::STRING, TTO::LEFT, TTO::GENERAL, 40);
395 outputter.pushFieldSpec(
"req", TTO::INT, TTO::LEFT, TTO::GENERAL, 3);
396 outputter.pushFieldSpec(
"keep", TTO::STRING, TTO::LEFT, TTO::GENERAL, 5);
397 outputter.pushFieldSpec(
"type", TTO::STRING, TTO::LEFT, TTO::GENERAL, 18);
398 outputter.pushFieldSpec(
"data", TTO::STRING, TTO::LEFT, TTO::GENERAL, 14);
399 outputter.pushFieldSpec(
"req'd by", TTO::STRING, TTO::LEFT, TTO::GENERAL, 20);
400 outputter.outputHeader();
402 for (TwoKeyMap::const_iterator kt =
map_.begin(); kt !=
map_.end(); kt++) {
405 for (SubMap::const_iterator it = kt->second.begin(); it != kt->second.end(); it++) {
406 const std::string& ename = it->first;
408 outputter.outputField(ename);
418 outputter.outputField(
"Null");
420 outputter.outputField(
"NoFactory");
422 std::ostringstream oss;
424#ifdef HAVE_MUELU_DEBUG
425 oss <<
"(" << factory <<
")";
427 outputter.outputField(oss.str());
431 outputter.outputField(reqcount);
435 std::stringstream ss;
445 outputter.outputField(ss.str());
447 outputter.outputField(
"No");
451 std::string strType = it->second->GetTypeName();
453 if (strType ==
"int") {
454 outputter.outputField(strType);
455 outputter.outputField(it->second->GetData<
int>());
456 }
else if (strType ==
"double") {
457 outputter.outputField(strType);
458 outputter.outputField(it->second->GetData<
double>());
459 }
else if (strType ==
"string") {
460 outputter.outputField(strType);
461 outputter.outputField(it->second->GetData<std::string>());
463 size_t npos = std::string::npos;
465 if (strType.find(
"MueLu::Aggregates") != npos)
466 outputter.outputField(
"Aggregates");
467 else if (strType.find(
"MueLu::AmalgamationInfo") != npos)
468 outputter.outputField(
"AmalgamationInfo");
469 else if (strType.find(
"MueLu::Constraint") != npos)
470 outputter.outputField(
"Constraint");
471 else if (strType.find(
"MueLu::SmootherBase") != npos)
472 outputter.outputField(
"SmootherBase");
473 else if (strType.find(
"MueLu::SmootherPrototype") != npos)
474 outputter.outputField(
"SmootherPrototype");
475 else if (strType.find(
"Xpetra::Export") != npos)
476 outputter.outputField(
"Export");
477 else if (strType.find(
"Xpetra::Import") != npos)
478 outputter.outputField(
"Import");
479 else if (strType.find(
"Xpetra::Map") != npos)
480 outputter.outputField(
"Map");
481 else if (strType.find(
"Xpetra::Matrix") != npos)
482 outputter.outputField(
"Matrix");
483 else if (strType.find(
"Xpetra::MultiVector") != npos)
484 outputter.outputField(
"Vector");
485 else if (strType.find(
"Xpetra::Operator") != npos)
486 outputter.outputField(
"Operator");
488 outputter.outputField(strType);
490 outputter.outputField(
"available");
494 outputter.outputField(
"unknown");
495 outputter.outputField(
"not available");
499 const container_type& requestedBy = it->second->Requests();
500 std::ostringstream ss;
501 for (container_type::const_iterator ct = requestedBy.begin(); ct != requestedBy.end(); ct++) {
502 if (ct != requestedBy.begin()) ss <<
",";
503 ss << ct->first->ShortClassName() <<
"[" << ct->first->GetID() <<
"]";
504#ifdef HAVE_MUELU_DEBUG
505 ss <<
"(" << ct->first <<
")";
508 if (ct->second > 1) ss <<
"x" << ct->second;
510 outputter.outputField(ss.str());
517#if defined(HAVE_MUELU_BOOST) && defined(HAVE_MUELU_BOOST_FOR_REAL) && defined(BOOST_VERSION) && (BOOST_VERSION >= 104400)
518void Level::UpdateGraph(std::map<const FactoryBase*, BoostVertex>& vindices,
519 std::map<std::pair<BoostVertex, BoostVertex>, std::string>& edges,
521 BoostGraph& graph)
const {
522 size_t vind = vindices.size();
524 for (TwoKeyMap::const_iterator it1 =
map_.begin(); it1 !=
map_.end(); it1++) {
525 if (vindices.find(it1->first) == vindices.end()) {
526 BoostVertex boost_vertex = boost::add_vertex(graph);
527 std::ostringstream oss;
528 oss << it1->first->ShortClassName() <<
"[" << it1->first->GetID() <<
"]";
529 boost::put(
"label", dp, boost_vertex, oss.str());
530 vindices[it1->first] = vind++;
533 for (SubMap::const_iterator it2 = it1->second.begin(); it2 != it1->second.end(); it2++) {
535 for (VariableContainer::request_container::const_iterator rit = requests.begin(); rit != requests.end(); rit++) {
536 if (vindices.find(rit->first) == vindices.end()) {
538 BoostVertex boost_vertex = boost::add_vertex(graph);
539 std::ostringstream oss;
540 oss << rit->first->ShortClassName() <<
"[" << rit->first->GetID() <<
"]";
541 boost::put(
"label", dp, boost_vertex, oss.str());
542 vindices[rit->first] = vind++;
545 edges[std::pair<BoostVertex, BoostVertex>(vindices[rit->first], vindices[it1->first])] = it2->first;
568 TEUCHOS_TEST_FOR_EXCEPTION(fac == NULL,
Exceptions::RuntimeError,
"MueLu::Level(" <<
levelID_ <<
")::GetFactory(" << ename <<
", " << factory <<
"): Default factory returned by FactoryManager cannot be NULL");
573 TwoKeyMap::const_iterator it =
map_.find(factory);
574 return (it !=
map_.end()) ? (it->second).count(ename) :
false;
578 TwoKeyMap::const_iterator it =
map_.find(factory);
579 if (it ==
map_.end())
581 for (SubMap::const_iterator sit = it->second.begin(); sit != it->second.end(); sit++) {
582 if (sit->second->IsAvailable())
590 "Internal logic error: if counter == 0, the entry in countTable_ should have been deleted");
591 return v->IsRequested();
595 if (!
IsKey(factory, ename))
603 "Internal logic error: if counter == 0, the entry in countTable_ should have been deleted");
604 return v->IsRequested(requestedBy);
608 TwoKeyMap::const_iterator it =
map_.find(factory);
609 if (it ==
map_.end())
611 for (SubMap::const_iterator sit = it->second.begin(); sit != it->second.end(); sit++)
618 TwoKeyMap::const_iterator it =
map_.find(factory);
621 SubMap::const_iterator sit = it->second.find(ename);
622 TEUCHOS_TEST_FOR_EXCEPTION(sit == it->second.end(),
Exceptions::RuntimeError,
"Key (" << factory <<
", " << ename <<
") does not exist.");
629 const Teuchos::RCP<MueLu::VariableContainer>& v =
Get(factory, ename);
631 "NumRequests(): Internal logic error: if counter == 0, the entry in countTable_ should have been deleted");
632 return v->NumAllRequests();
636 TwoKeyMap::const_iterator it =
map_.find(factory);
637 if (it ==
map_.end())
641 for (SubMap::const_iterator sit = it->second.begin(); sit != it->second.end(); sit++)
642 cnt += sit->second->NumAllRequests();
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()
std::string description() const
Return a simple one-line description of this object.
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
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
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
virtual ~Level()
Destructor.
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)
void SetFactoryManager(const RCP< const FactoryManagerBase > &factoryManager)
Set default factories (used internally by Hierarchy::SetLevel()).
int levelID_
Map of a map (Key1 -> SubMap)
bool IsKey(const FactoryBase *factory, const std::string &ename) const
Test whether some information about (ename, factory) are stored.
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()
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.
@ Warnings1
Additional warnings.