10 #include <Teuchos_TabularOutputter.hpp>
25 , factoryManager_(factoryManager) {}
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))
107 if (!
IsKey(factory, ename)) {
110 map_[factory][ename] = newVar;
113 map_[factory][ename]->AddKeepFlag(keep);
118 if (!
IsKey(factory, ename))
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);
184 if (bRequestOnly && bReleaseOnly)
188 if (bReleaseOnly ==
false)
Request(*factory);
191 if (bRequestOnly ==
false)
Release(*factory);
226 if (!
IsKey(fac, ename)) {
228 map_[fac][ename] = newVar;
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;
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;
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)
518 void 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;
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);
631 "NumRequests(): Internal logic error: if counter == 0, the entry in countTable_ should have been deleted");
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 void CallDeclareInput(Level &requestedLevel) const =0
virtual ~Level()
Destructor.
KeepType GetKeepFlag(const std::string &ename, const FactoryBase *factory) const
Get the flag combination set for variable 'ename' generated by 'factory'.
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->Get< RCP<Matrix> >("A", factory) if factory == NULL => 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)
KeepType GetKeepFlag() const
Returns the keep flag combination.
Print additional debugging information.
RCP< Level > previousLevel_
User data are always kept. This flag is set automatically when Level::Set("data", 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)
void SetFactoryManager(const RCP< const FactoryManagerBase > &factoryManager)
Set default factories (used internally by Hierarchy::SetLevel()).
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.
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)
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 ...
void Delete(const std::string &ename, const FactoryBase *factory)
Delete data that have been retained after the setup phase (using Keep(), AddKeepFlag(), or internal MueLu logic).
int levelID_
Map of a map (Key1 -> SubMap)
std::string GetTypeName(const std::string &ename, const FactoryBase *factory=NoFactory::get())
GetTypeName returns type string of variable stored using ename and factory.
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 > & GetPreviousLevel()
Previous level.
void print(std::ostream &out, const VerbLevel verbLevel=Default) const
Printing method.
void SetLevelID(int levelID)
Set level number.
RCP< const FactoryManagerBase > factoryManager_
bool IsRequestedFactory(const FactoryBase *factory) const
const RCP< const FactoryManagerBase > GetFactoryManager()
returns the current factory manager
int GetLevelID() const
Return level number.
Exception throws to report errors in the internal logical of the program.
Class that stores all relevant data for a variable.
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...
bool IsKey(const FactoryBase *factory, const std::string &ename) const
Test whether some information about (ename, factory) are stored.
int NumAllRequests() const
Returns the number of times the data has been requested.
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's value has been saved.
void Request(const FactoryBase &factory)
Increment the storage counter for all the inputs of a factory.