MueLu  Version of the Day
MueLu_HierarchyUtils_def.hpp
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 #ifndef MUELU_HIERARCHYUTILS_DEF_HPP
47 #define MUELU_HIERARCHYUTILS_DEF_HPP
48 
49 #include <Xpetra_Matrix.hpp>
50 #include <Xpetra_Operator.hpp>
51 
54 #include "MueLu_SmootherBase.hpp"
55 #include "MueLu_SmootherFactory.hpp"
56 #include "MueLu_FactoryManager.hpp"
57 
58 //TODO/FIXME: DeclareInput(, **this**) cannot be used here
59 
60 namespace MueLu {
61 
62 
63  // Adds the following non-serializable data (A,P,R,Nullspace,Coordinates) from level-specific sublist nonSerialList,
64  // calling AddNewLevel as appropriate.
65  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
67  for (ParameterList::ConstIterator it = paramList.begin(); it != paramList.end(); it++) {
68  const std::string& levelName = it->first;
69 
70  // Check for mach of the form "level X" where X is a positive integer
71  if (paramList.isSublist(levelName) && levelName.find("level ") == 0 && levelName.size() > 6) {
72  int levelID = strtol(levelName.substr(6).c_str(), 0, 0);
73  if (levelID > 0)
74  {
75  // Do enough level adding so we can be sure to add the data to the right place
76  for (int i = H.GetNumLevels(); i <= levelID; i++)
77  H.AddNewLevel();
78  }
79  RCP<Level> level = H.GetLevel(levelID);
80 
81  RCP<FactoryManager> M = Teuchos::rcp_dynamic_cast<FactoryManager>(HM.GetFactoryManager(levelID));
82  TEUCHOS_TEST_FOR_EXCEPTION(M.is_null(), Exceptions::InvalidArgument, "MueLu::Utils::AddNonSerializableDataToHierarchy: cannot get FactoryManager");
83 
84  // Grab the level sublist & loop over parameters
85  const ParameterList& levelList = paramList.sublist(levelName);
86  for (ParameterList::ConstIterator it2 = levelList.begin(); it2 != levelList.end(); it2++) {
87  const std::string& name = it2->first;
88  TEUCHOS_TEST_FOR_EXCEPTION(name != "A" && name != "P" && name != "R" &&
89  name != "Nullspace" && name != "Coordinates" &&
91  "MueLu::Utils::AddNonSerializableDataToHierarchy: parameter list contains unknown data type");
92 
93  if (name == "A") {
94  level->Set(name, Teuchos::getValue<RCP<Matrix > > (it2->second),NoFactory::get());
95  M->SetFactory(name, NoFactory::getRCP()); // TAW: not sure about this: be aware that this affects all levels
96  // However, A is accessible through NoFactory anyway, so it should
97  // be fine here.
98  }
99  else if( name == "P" || name == "R") {
101  level->Set(name, Teuchos::getValue<RCP<Matrix > > (it2->second), M->GetFactory(name).get());
102  }
103  else if (name == "Nullspace")
104  {
106  level->Set(name, Teuchos::getValue<RCP<MultiVector > >(it2->second), NoFactory::get());
107  //M->SetFactory(name, NoFactory::getRCP()); // TAW: generally it is a bad idea to overwrite the factory manager data here
108  // One should do this only in very special cases
109  }
110  else if(name == "Coordinates") //Scalar of Coordinates MV is always double
111  {
113  level->Set(name, Teuchos::getValue<RCP<Xpetra::MultiVector<double, LocalOrdinal, GlobalOrdinal, Node> > >(it2->second), NoFactory::get());
114  //M->SetFactory(name, NoFactory::getRCP()); // TAW: generally it is a bad idea to overwrite the factory manager data here
115  }
116  #ifdef HAVE_MUELU_MATLAB
117  else
118  {
119  //Custom variable for Muemex
120  size_t typeNameStart = name.find_first_not_of(' ');
121  size_t typeNameEnd = name.find(' ', typeNameStart);
122  std::string typeName = name.substr(typeNameStart, typeNameEnd - typeNameStart);
123  std::transform(typeName.begin(), typeName.end(), typeName.begin(), ::tolower);
124  level->AddKeepFlag(name, NoFactory::get(), MueLu::UserData);
125  if(typeName == "matrix")
126  level->Set(name, Teuchos::getValue<RCP<Matrix> >(it2->second), NoFactory::get());
127  else if(typeName == "multivector")
128  level->Set(name, Teuchos::getValue<RCP<MultiVector> >(it2->second), NoFactory::get());
129  else if(typeName == "map")
130  level->Set(name, Teuchos::getValue<RCP<Xpetra::Map<LocalOrdinal, GlobalOrdinal, Node> > >(it2->second), NoFactory::get());
131  else if(typeName == "ordinalvector")
132  level->Set(name, Teuchos::getValue<RCP<Xpetra::Vector<LocalOrdinal, LocalOrdinal, GlobalOrdinal, Node> > >(it2->second), NoFactory::get());
133  else if(typeName == "scalar")
134  level->Set(name, Teuchos::getValue<Scalar>(it2->second), NoFactory::get());
135  else if(typeName == "double")
136  level->Set(name, Teuchos::getValue<double>(it2->second), NoFactory::get());
137  else if(typeName == "complex")
138  level->Set(name, Teuchos::getValue<std::complex<double> >(it2->second), NoFactory::get());
139  else if(typeName == "int")
140  level->Set(name, Teuchos::getValue<int>(it2->second), NoFactory::get());
141  else if(typeName == "string")
142  level->Set(name, Teuchos::getValue<std::string>(it2->second), NoFactory::get());
143  }
144  #endif
145  }
146  }
147  }
148  }
149 
150 } // namespace MueLu
151 
152 #define MUELU_HIERARCHY_UTILS_SHORT
153 #endif // MUELU_HIERARCHYHELPERS_DEF_HPP
This class specifies the default factory that should generate some data on a Level if the data does n...
RCP< Level > & GetLevel(const int levelID=0)
Retrieve a certain level from hierarchy.
static void AddNonSerializableDataToHierarchy(HierarchyManager &HM, Hierarchy &H, const ParameterList &nonSerialList)
ConstIterator begin() const
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
bool isSublist(const std::string &name) const
void AddNewLevel()
Add a new level at the end of the hierarchy.
User data are always kept. This flag is set automatically when Level::Set("data", data) is used...
Namespace for MueLu classes and methods.
bool IsParamMuemexVariable(const std::string &name)
RCP< FactoryManagerBase > GetFactoryManager(int levelID) const
static const NoFactory * get()
bool is_null() const
ConstIterator end() const
params_t::ConstIterator ConstIterator
void AddKeepFlag(const std::string &ename, const FactoryBase *factory=NoFactory::get(), KeepType keep=MueLu::Keep)
void Set(const std::string &ename, const T &entry, const FactoryBase *factory=NoFactory::get())
void SetFactory(const std::string &varName, const RCP< const FactoryBase > &factory)
Set Factory.
const RCP< const FactoryBase > GetFactory(const std::string &varName) const
Get factory associated with a particular data name.
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
Provides methods to build a multigrid hierarchy and apply multigrid cycles.
std::string typeName(const T &t)
Exception throws to report invalid user entry.
static const RCP< const NoFactory > getRCP()
Static Get() functions.