10#include <Teuchos_TabularOutputter.hpp>
26 , factoryManager_(factoryManager) {}
31 RCP<Level> newLevel = rcp(
new Level());
34 for (TwoKeyMap::const_iterator kt =
map_.begin(); kt !=
map_.end(); kt++) {
37 for (SubMap::const_iterator it = kt->second.begin(); it != kt->second.end(); it++) {
38 const std::string& ename = it->first;
44 newLevel->Keep(ename, factory);
56 GetOStream(
Warnings1) <<
"Level::SetLevelID(): Changing an already defined LevelID (previousID=" <<
levelID_ <<
", newID=" << levelID <<
")" << std::endl;
65 GetOStream(
Warnings1) <<
"Level::SetPreviousLevel(): PreviousLevel was already defined" << std::endl;
83 "MueLu::Level::GetTypeString(): Data "
85 <<
"\" generated by " << *fac <<
" is not available.");
87 return map_[fac][ename]->GetTypeName();
91 if (!
IsKey(factory, ename))
97 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.");
104 TEUCHOS_TEST_FOR_EXCEPTION(
IsAvailable(ename, factory) ==
true,
Exceptions::RuntimeError,
"MueLu::Level::Delete(): Internal error (Post condition). Data have not been deleted.");
108 if (!
IsKey(factory, ename)) {
111 map_[factory][ename] = newVar;
114 map_[factory][ename]->AddKeepFlag(keep);
119 if (!
IsKey(factory, ename))
123 Teuchos::RCP<MueLu::VariableContainer>& v =
map_[factory][ename];
124 v->RemoveKeepFlag(keep);
127 if ((v->IsRequested() ==
false) && (v->GetKeepFlag() == 0)) {
130 map_[factory].erase(ename);
131 if (
map_.count(factory) == 0)
137 if (!
IsKey(factory, ename))
140 return Get(factory, ename)->GetKeepFlag();
160 Request(ename, factory, requestedBy);
163 std::ostringstream msg;
164 msg << requestedBy->
ShortClassName() <<
"::DeclareInput: (" << e.what() <<
") unable to find or generate requested data \""
165 << ename <<
"\" with generating factory \"" << ((factory != NULL) ? factory->
ShortClassName() :
"null") <<
"\" [" << factory <<
"]";
166 msg <<
"\n during request for data \"" << std::setw(15) << ename <<
"\" on level " <<
GetLevelID()
167 <<
" by factory " << std::setw(25) << requestedBy->
ShortClassName() <<
" [" << requestedBy <<
"]";
171 std::ostringstream msg;
172 msg << e.what() <<
"\n during request for data \"" << std::setw(15) << ename <<
"\" on level " <<
GetLevelID()
173 <<
" by factory " << std::setw(25) << requestedBy->
ShortClassName() <<
" [" << requestedBy <<
"]";
178 Release(ename, factory, requestedBy);
181 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"MueLu::Level::DeclareInput(): requestMode_ undefined.");
185 if (bRequestOnly && bReleaseOnly)
186 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"MueLu::Level::DeclareDependencies(): Both bRequestOnly and bReleaseOnly set to true makes no sense.");
189 if (bReleaseOnly ==
false)
Request(*factory);
192 if (bRequestOnly ==
false)
Release(*factory);
195 TEUCHOS_TEST_FOR_EXCEPTION(
true,
Exceptions::RuntimeError,
"MueLu::Level::DeclareDependencies(): requestMode_ undefined.");
227 if (!
IsKey(fac, ename)) {
229 map_[fac][ename] = newVar;
232 Teuchos::RCP<MueLu::VariableContainer>& v =
map_[fac][ename];
233 v->Request(requestedBy);
267 Teuchos::RCP<MueLu::VariableContainer>& v =
map_[fac][ename];
268 v->Release(requestedBy);
271 if ((v->IsRequested() ==
false) && (v->GetKeepFlag() == 0)) {
274 map_[fac].erase(ename);
275 if (
map_.count(fac) == 0)
283 if (!
IsKey(factory, ename))
286 return Get(factory, ename)->IsAvailable();
294 if (!
IsKey(factory, ename))
309 for (TwoKeyMap::const_iterator kt =
map_.begin(); kt !=
map_.end(); kt++) {
312 for (SubMap::const_iterator it = kt->second.begin(); it != kt->second.end(); it++) {
315 const std::string ename = it->first;
327 if (
IsKey(factory, ename)) {
328 GetOStream(
Errors) <<
"Level::Clear found Internal data inconsistency" << std::endl;
343 }
while (wasRemoved ==
true);
347 TwoKeyMap::const_iterator kt =
map_.begin();
348 while (kt !=
map_.end()) {
351 SubMap::const_iterator it = kt->second.begin();
352 while (it != kt->second.end()) {
353 const std::string& ename = it->first;
356 Teuchos::RCP<MueLu::VariableContainer>& v =
map_[factory][ename];
358 if (v->GetKeepFlag() == 0 ||
363 map_[factory].erase(ename);
364 if (
map_.count(factory) == 0) {
371 if (
map_.count(factory) == 0) {
380 std::ostringstream out;
382 out <<
"{ levelID = " <<
levelID_ <<
"}";
387 if (!(verbLevel &
Debug))
390 out <<
"LevelID = " <<
GetLevelID() << std::endl;
392 typedef Teuchos::TabularOutputter TTO;
394 outputter.pushFieldSpec(
"data name", TTO::STRING, TTO::LEFT, TTO::GENERAL, 20);
395 outputter.pushFieldSpec(
"gen. factory addr.", TTO::STRING, TTO::LEFT, TTO::GENERAL, 40);
396 outputter.pushFieldSpec(
"req", TTO::INT, TTO::LEFT, TTO::GENERAL, 3);
397 outputter.pushFieldSpec(
"keep", TTO::STRING, TTO::LEFT, TTO::GENERAL, 5);
398 outputter.pushFieldSpec(
"type", TTO::STRING, TTO::LEFT, TTO::GENERAL, 18);
399 outputter.pushFieldSpec(
"data", TTO::STRING, TTO::LEFT, TTO::GENERAL, 14);
400 outputter.pushFieldSpec(
"req'd by", TTO::STRING, TTO::LEFT, TTO::GENERAL, 20);
401 outputter.outputHeader();
403 for (TwoKeyMap::const_iterator kt =
map_.begin(); kt !=
map_.end(); kt++) {
406 for (SubMap::const_iterator it = kt->second.begin(); it != kt->second.end(); it++) {
407 const std::string& ename = it->first;
409 outputter.outputField(ename);
419 outputter.outputField(
"Null");
421 outputter.outputField(
"NoFactory");
423 std::ostringstream oss;
426 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() <<
"]";
505 ss <<
"(" << ct->first <<
")";
506 if (ct->second > 1) ss <<
"x" << ct->second;
508 outputter.outputField(ss.str());
515#if defined(HAVE_MUELU_BOOST) && defined(HAVE_MUELU_BOOST_FOR_REAL) && defined(BOOST_VERSION) && (BOOST_VERSION >= 104400)
516void Level::UpdateGraph(std::map<const FactoryBase*, BoostVertex>& vindices,
517 std::map<std::pair<BoostVertex, BoostVertex>, std::string>& edges,
519 BoostGraph& graph)
const {
520 size_t vind = vindices.size();
522 for (TwoKeyMap::const_iterator it1 =
map_.begin(); it1 !=
map_.end(); it1++) {
523 if (vindices.find(it1->first) == vindices.end()) {
524 BoostVertex boost_vertex = boost::add_vertex(graph);
525 std::ostringstream oss;
526 oss << it1->first->ShortClassName() <<
"[" << it1->first->GetID() <<
"]";
527 boost::put(
"label", dp, boost_vertex, oss.str());
528 vindices[it1->first] = vind++;
531 for (SubMap::const_iterator it2 = it1->second.begin(); it2 != it1->second.end(); it2++) {
533 for (VariableContainer::request_container::const_iterator rit = requests.begin(); rit != requests.end(); rit++) {
534 if (vindices.find(rit->first) == vindices.end()) {
536 BoostVertex boost_vertex = boost::add_vertex(graph);
537 std::ostringstream oss;
538 oss << rit->first->ShortClassName() <<
"[" << rit->first->GetID() <<
"]";
539 boost::put(
"label", dp, boost_vertex, oss.str());
540 vindices[rit->first] = vind++;
543 edges[std::pair<BoostVertex, BoostVertex>(vindices[rit->first], vindices[it1->first])] = it2->first;
566 TEUCHOS_TEST_FOR_EXCEPTION(fac == NULL,
Exceptions::RuntimeError,
"MueLu::Level(" <<
levelID_ <<
")::GetFactory(" << ename <<
", " << factory <<
"): Default factory returned by FactoryManager cannot be NULL");
571 TwoKeyMap::const_iterator it =
map_.find(factory);
572 return (it !=
map_.end()) ? (it->second).count(ename) :
false;
576 TwoKeyMap::const_iterator it =
map_.find(factory);
577 if (it ==
map_.end())
579 for (SubMap::const_iterator sit = it->second.begin(); sit != it->second.end(); sit++) {
580 if (sit->second->IsAvailable())
588 "Internal logic error: if counter == 0, the entry in countTable_ should have been deleted");
589 return v->IsRequested();
593 if (!
IsKey(factory, ename))
601 "Internal logic error: if counter == 0, the entry in countTable_ should have been deleted");
602 return v->IsRequested(requestedBy);
606 TwoKeyMap::const_iterator it =
map_.find(factory);
607 if (it ==
map_.end())
609 for (SubMap::const_iterator sit = it->second.begin(); sit != it->second.end(); sit++)
616 TwoKeyMap::const_iterator it =
map_.find(factory);
619 SubMap::const_iterator sit = it->second.find(ename);
620 TEUCHOS_TEST_FOR_EXCEPTION(sit == it->second.end(),
Exceptions::RuntimeError,
"Key (" << factory <<
", " << ename <<
") does not exist.");
627 const Teuchos::RCP<MueLu::VariableContainer>& v =
Get(factory, ename);
629 "NumRequests(): Internal logic error: if counter == 0, the entry in countTable_ should have been deleted");
630 return v->NumAllRequests();
634 TwoKeyMap::const_iterator it =
map_.find(factory);
635 if (it ==
map_.end())
639 for (SubMap::const_iterator sit = it->second.begin(); sit != it->second.end(); sit++)
640 cnt += sit->second->NumAllRequests();
static bool debug()
Whether MueLu is in debug mode.
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.