MueLu  Version of the Day
MueLu_FactoryManager_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_FACTORYMANAGER_DEF_HPP
47 #define MUELU_FACTORYMANAGER_DEF_HPP
48 
49 #include <Teuchos_ParameterList.hpp>
50 
51 // Headers for factories used by default:
52 #include "MueLu_AmalgamationFactory.hpp"
53 #include "MueLu_CoalesceDropFactory.hpp"
54 #include "MueLu_CoarseMapFactory.hpp"
55 #include "MueLu_ConstraintFactory.hpp"
56 #include "MueLu_CoordinatesTransferFactory.hpp"
57 #include "MueLu_DirectSolver.hpp"
58 #include "MueLu_LineDetectionFactory.hpp"
59 // #include "MueLu_MultiVectorTransferFactory.hpp"
60 #include "MueLu_NoFactory.hpp"
61 #include "MueLu_NullspaceFactory.hpp"
62 #include "MueLu_PatternFactory.hpp"
63 #include "MueLu_RAPFactory.hpp"
64 #include "MueLu_RepartitionHeuristicFactory.hpp"
65 #include "MueLu_RepartitionFactory.hpp"
66 #include "MueLu_SaPFactory.hpp"
67 #include "MueLu_SmootherFactory.hpp"
68 #include "MueLu_TentativePFactory.hpp"
69 #include "MueLu_TransPFactory.hpp"
70 #include "MueLu_TrilinosSmoother.hpp"
71 #include "MueLu_UncoupledAggregationFactory.hpp"
72 #include "MueLu_HybridAggregationFactory.hpp"
73 #include "MueLu_ZoltanInterface.hpp"
74 
75 #ifdef HAVE_MUELU_KOKKOS_REFACTOR
76 #include "MueLu_CoalesceDropFactory_kokkos.hpp"
77 #include "MueLu_CoarseMapFactory_kokkos.hpp"
78 #include "MueLu_CoordinatesTransferFactory_kokkos.hpp"
79 #include "MueLu_NullspaceFactory_kokkos.hpp"
80 #include "MueLu_SaPFactory_kokkos.hpp"
81 #include "MueLu_TentativePFactory_kokkos.hpp"
82 #include "MueLu_UncoupledAggregationFactory_kokkos.hpp"
83 #endif
84 
86 
87 
88 namespace MueLu {
89 
90 #ifndef HAVE_MUELU_KOKKOS_REFACTOR
91 #define MUELU_KOKKOS_FACTORY(varName, oldFactory, newFactory) \
92  SetAndReturnDefaultFactory(varName, rcp(new oldFactory()));
93 #else
94 #define MUELU_KOKKOS_FACTORY(varName, oldFactory, newFactory) \
95  (!useKokkos_) ? SetAndReturnDefaultFactory(varName, rcp(new oldFactory())) : \
96  SetAndReturnDefaultFactory(varName, rcp(new newFactory()));
97 #endif
98 
99  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
100  void FactoryManager<Scalar, LocalOrdinal, GlobalOrdinal, Node>::SetFactory(const std::string& varName, const RCP<const FactoryBase>& factory) {
101  factoryTable_[varName] = factory;
102  }
103 
104  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
105  const RCP<const FactoryBase> FactoryManager<Scalar, LocalOrdinal, GlobalOrdinal, Node>::GetFactory(const std::string& varName) const {
106  if (factoryTable_.count(varName)) {
107  // Search user provided factories
108  return factoryTable_.find(varName)->second;
109  }
110 
111  // Search/create default factory for this name
112  return GetDefaultFactory(varName);
113  }
114 
115  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
116  const RCP<FactoryBase> FactoryManager<Scalar, LocalOrdinal, GlobalOrdinal, Node>::GetFactoryNonConst(const std::string& varName) {
117  return Teuchos::rcp_const_cast<FactoryBase>(GetFactory(varName));
118  }
119 
120  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
122  if (factoryTable_.count(varName)) return true;
123  return false;
124  }
125 
126  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
127  const RCP<const FactoryBase> FactoryManager<Scalar, LocalOrdinal, GlobalOrdinal, Node>::GetDefaultFactory(const std::string& varName) const {
128  if (defaultFactoryTable_.count(varName)) {
129  // The factory for this name was already created (possibly, for previous level, if we reuse factory manager)
130  return defaultFactoryTable_.find(varName)->second;
131 
132  } else {
133  // No factory was created for this name, but we may know which one to create
134  if (varName == "A") return SetAndReturnDefaultFactory(varName, rcp(new RAPFactory()));
135  if (varName == "RAP Pattern") return GetFactory("A");
136  if (varName == "AP Pattern") return GetFactory("A");
137  if (varName == "Ptent") return MUELU_KOKKOS_FACTORY(varName, TentativePFactory, TentativePFactory_kokkos);
138  if (varName == "P") {
139  // GetFactory("Ptent"): we need to use the same factory instance for both "P" and "Nullspace"
140  RCP<Factory> factory;
141 #ifdef HAVE_MUELU_KOKKOS_REFACTOR
142  if (useKokkos_)
143  factory = rcp(new SaPFactory_kokkos());
144  else
145 #endif
146  factory = rcp(new SaPFactory());
147  factory->SetFactory("P", GetFactory("Ptent"));
148  return SetAndReturnDefaultFactory(varName, factory);
149  }
150  if (varName == "Nullspace") {
151  // GetFactory("Ptent"): we need to use the same factory instance for both "P" and "Nullspace"
152  RCP<Factory> factory;
153 #ifdef HAVE_MUELU_KOKKOS_REFACTOR
154  if (useKokkos_)
155  factory = rcp(new NullspaceFactory_kokkos());
156  else
157 #endif
158  factory = rcp(new NullspaceFactory());
159  factory->SetFactory("Nullspace", GetFactory("Ptent"));
160  return SetAndReturnDefaultFactory(varName, factory);
161  }
162  if (varName == "Coordinates") return GetFactory("Ptent");
163 
164  if (varName == "R") return SetAndReturnDefaultFactory(varName, rcp(new TransPFactory()));
165 #if defined(HAVE_MUELU_ZOLTAN) && defined(HAVE_MPI)
166  if (varName == "Partition") return SetAndReturnDefaultFactory(varName, rcp(new ZoltanInterface()));
167 #endif //ifdef HAVE_MPI
168 
169  if (varName == "Importer") {
170 #ifdef HAVE_MPI
171  return SetAndReturnDefaultFactory(varName, rcp(new RepartitionFactory()));
172 #else
173  return SetAndReturnDefaultFactory(varName, NoFactory::getRCP());
174 #endif
175  }
176  if (varName == "number of partitions") {
177 #ifdef HAVE_MPI
178  return SetAndReturnDefaultFactory(varName, rcp(new RepartitionHeuristicFactory()));
179 #else
180  return SetAndReturnDefaultFactory(varName, NoFactory::getRCP());
181 #endif
182  }
183 
184  if (varName == "Graph") return MUELU_KOKKOS_FACTORY(varName, CoalesceDropFactory, CoalesceDropFactory_kokkos);
185  if (varName == "UnAmalgamationInfo") return SetAndReturnDefaultFactory(varName, rcp(new AmalgamationFactory())); //GetFactory("Graph"));
186  if (varName == "Aggregates") return MUELU_KOKKOS_FACTORY(varName, UncoupledAggregationFactory, UncoupledAggregationFactory_kokkos);
187  if (varName == "CoarseMap") return MUELU_KOKKOS_FACTORY(varName, CoarseMapFactory, CoarseMapFactory_kokkos);
188  if (varName == "DofsPerNode") return GetFactory("Graph");
189  if (varName == "Filtering") return GetFactory("Graph");
190  if (varName == "LineDetection_VertLineIds") return SetAndReturnDefaultFactory(varName, rcp(new LineDetectionFactory()));
191  if (varName == "LineDetection_Layers") return GetFactory("LineDetection_VertLineIds");
192  if (varName == "CoarseNumZLayers") return GetFactory("LineDetection_VertLineIds");
193 
194  // Non-Galerkin
195  if (varName == "K") return GetFactory("A");
196  if (varName == "M") return GetFactory("A");
197 
198  // Same factory for both Pre and Post Smoother. Factory for key "Smoother" can be set by users.
199  if (varName == "PreSmoother") return GetFactory("Smoother");
200  if (varName == "PostSmoother") return GetFactory("Smoother");
201 
202  if (varName == "Ppattern") {
203  RCP<PatternFactory> PpFact = rcp(new PatternFactory);
204  PpFact->SetFactory("P", GetFactory("Ptent"));
205  return SetAndReturnDefaultFactory(varName, PpFact);
206  }
207  if (varName == "Constraint") return SetAndReturnDefaultFactory(varName, rcp(new ConstraintFactory()));
208 
209  if (varName == "Smoother") {
210  Teuchos::ParameterList smootherParamList;
211  smootherParamList.set("relaxation: type", "Symmetric Gauss-Seidel");
212  smootherParamList.set("relaxation: sweeps", Teuchos::OrdinalTraits<LO>::one());
213  smootherParamList.set("relaxation: damping factor", Teuchos::ScalarTraits<Scalar>::one());
214  return SetAndReturnDefaultFactory(varName, rcp(new SmootherFactory(rcp(new TrilinosSmoother("RELAXATION", smootherParamList)))));
215  }
216  if (varName == "CoarseSolver") return SetAndReturnDefaultFactory(varName, rcp(new SmootherFactory(rcp(new DirectSolver()), Teuchos::null)));
217 
218 #ifdef HAVE_MUELU_INTREPID2
219  // If we're asking for it, find who made P
220  if (varName == "pcoarsen: element to node map") return GetFactory("P");
221 #endif
222 
223  TEUCHOS_TEST_FOR_EXCEPTION(true, MueLu::Exceptions::RuntimeError, "MueLu::FactoryManager::GetDefaultFactory(): No default factory available for building '" + varName + "'.");
224  }
225  }
226 
227  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
228  const RCP<const FactoryBase> FactoryManager<Scalar, LocalOrdinal, GlobalOrdinal, Node>::SetAndReturnDefaultFactory(const std::string& varName, const RCP<const FactoryBase>& factory) const {
229  TEUCHOS_TEST_FOR_EXCEPTION(factory.is_null(), Exceptions::RuntimeError, "The default factory for building '" << varName << "' is null");
230 
231  GetOStream(Runtime1) << "Using default factory (" << factory->description() << ") for building '" << varName << "'." << std::endl;
232 
233  defaultFactoryTable_[varName] = factory;
234 
235  return defaultFactoryTable_[varName];
236  }
237 
238  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
240  std::map<std::string, RCP<const FactoryBase> >::const_iterator it;
241 
242  Teuchos::FancyOStream& fancy = GetOStream(Debug);
243 
244  fancy << "Users factory table (factoryTable_):" << std::endl;
245  for (it = factoryTable_.begin(); it != factoryTable_.end(); it++)
246  fancy << " " << it->first << " -> " << Teuchos::toString(it->second.get()) << std::endl;
247 
248  fancy << "Default factory table (defaultFactoryTable_):" << std::endl;
249  for (it = defaultFactoryTable_.begin(); it != defaultFactoryTable_.end(); it++)
250  fancy << " " << it->first << " -> " << Teuchos::toString(it->second.get()) << std::endl;
251  }
252 
253 #ifdef HAVE_MUELU_DEBUG
254  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
256  std::map<std::string, RCP<const FactoryBase> >::const_iterator it;
257 
258  for (it = factoryTable_.begin(); it != factoryTable_.end(); it++)
259  if (!it->second.is_null())
260  it->second->ResetDebugData();
261 
262  for (it = defaultFactoryTable_.begin(); it != defaultFactoryTable_.end(); it++)
263  if (!it->second.is_null())
264  it->second->ResetDebugData();
265  }
266 #endif
267 
268 
269 #undef MUELU_KOKKOS_FACTORY
270 
271 } // namespace MueLu
272 
273 //TODO: add operator[]
274 //TODO: should we use a parameterList instead of a std::map? It might be useful to tag which factory have been used and report unused factory.
275 //TODO: add an option 'NoDefault' to check if we are using any default factory.
276 //TODO: use Teuchos::ConstNonConstObjectContainer to allow user to modify factories after a GetFactory()
277 
278 #endif // MUELU_FACTORYMANAGER_DEF_HPP
MueLu::AmalgamationFactory
AmalgamationFactory for subblocks of strided map based amalgamation data.
Definition: MueLu_AmalgamationFactory_decl.hpp:75
MueLu::NullspaceFactory
Factory for generating nullspace.
Definition: MueLu_NullspaceFactory_decl.hpp:106
MueLu::ZoltanInterface
Interface to Zoltan library.
Definition: MueLu_ZoltanInterface_decl.hpp:115
MueLu::ConstraintFactory
Factory for building the constraint operator.
Definition: MueLu_ConstraintFactory_decl.hpp:66
MueLu::Runtime1
Description of what is happening (more verbose)
Definition: MueLu_VerbosityLevel.hpp:63
MueLu::toString
std::string toString(const T &what)
Little helper function to convert non-string types to strings.
Definition: MueLu_Utilities_decl.hpp:952
MueLu::TrilinosSmoother
Class that encapsulates external library smoothers.
Definition: MueLu_TrilinosSmoother_decl.hpp:83
MueLu::DirectSolver
Class that encapsulates direct solvers. Autoselection of AmesosSmoother or Amesos2Smoother according ...
Definition: MueLu_DirectSolver_decl.hpp:78
MueLu::UncoupledAggregationFactory
Factory for building uncoupled aggregates.
Definition: MueLu_UncoupledAggregationFactory_decl.hpp:145
MueLu_NoFactory.hpp
MueLu
Namespace for MueLu classes and methods.
Definition: MueLu_BrickAggregationFactory_decl.hpp:76
MueLu::Debug
Print additional debugging information.
Definition: MueLu_VerbosityLevel.hpp:79
MueLu::FactoryManager::Print
void Print() const
Definition: MueLu_FactoryManager_def.hpp:239
MueLu::RepartitionFactory
Factory for building permutation matrix that can be be used to shuffle data (matrices,...
Definition: MueLu_RepartitionFactory_decl.hpp:112
MueLu::FactoryManager::SetFactory
void SetFactory(const std::string &varName, const RCP< const FactoryBase > &factory)
Set Factory.
Definition: MueLu_FactoryManager_def.hpp:100
MueLu::FactoryManager::GetFactoryNonConst
const RCP< FactoryBase > GetFactoryNonConst(const std::string &varName)
Get factory associated with a particular data name (NONCONST version)
Definition: MueLu_FactoryManager_def.hpp:116
MueLu::Exceptions::RuntimeError
Exception throws to report errors in the internal logical of the program.
Definition: MueLu_Exceptions.hpp:70
MueLu_FactoryManager_decl.hpp
MueLu::LineDetectionFactory
Factory for building line detection information.
Definition: MueLu_LineDetectionFactory_decl.hpp:68
MueLu::TransPFactory
Factory for building restriction operators.
Definition: MueLu_TransPFactory_decl.hpp:73
MueLu::FactoryManager::SetAndReturnDefaultFactory
const RCP< const FactoryBase > SetAndReturnDefaultFactory(const std::string &varName, const RCP< const FactoryBase > &factory) const
Definition: MueLu_FactoryManager_def.hpp:228
MueLu::PatternFactory
Factory for building nonzero patterns for energy minimization.
Definition: MueLu_PatternFactory_decl.hpp:64
MueLu::SmootherFactory
Generic Smoother Factory for generating the smoothers of the MG hierarchy.
Definition: MueLu_SmootherFactory_decl.hpp:91
MueLu::FactoryManager::GetDefaultFactory
const RCP< const FactoryBase > GetDefaultFactory(const std::string &varName) const
Definition: MueLu_FactoryManager_def.hpp:127
MUELU_KOKKOS_FACTORY
#define MUELU_KOKKOS_FACTORY(varName, oldFactory, newFactory)
Definition: MueLu_FactoryManager_def.hpp:91
MueLu::RepartitionHeuristicFactory
Factory for determing the number of partitions for rebalancing.
Definition: MueLu_RepartitionHeuristicFactory_decl.hpp:119
MueLu::RAPFactory
Factory for building coarse matrices.
Definition: MueLu_RAPFactory_decl.hpp:73
MueLu::CoarseMapFactory
Factory for generating coarse level map. Used by TentativePFactory.
Definition: MueLu_CoarseMapFactory_decl.hpp:114
MueLu::TentativePFactory
Factory for building tentative prolongator.
Definition: MueLu_TentativePFactory_decl.hpp:122
MueLu::SaPFactory
Factory for building Smoothed Aggregation prolongators.
Definition: MueLu_SaPFactory_decl.hpp:96
MueLu::FactoryManager::GetFactory
const RCP< const FactoryBase > GetFactory(const std::string &varName) const
Get factory associated with a particular data name.
Definition: MueLu_FactoryManager_def.hpp:105
MueLu::FactoryManager
This class specifies the default factory that should generate some data on a Level if the data does n...
Definition: MueLu_FactoryManager_decl.hpp:103
MueLu::FactoryManager::hasFactory
bool hasFactory(const std::string &varName) const
Check.
Definition: MueLu_FactoryManager_def.hpp:121
MueLu::CoalesceDropFactory
Factory for creating a graph base on a given matrix.
Definition: MueLu_CoalesceDropFactory_decl.hpp:135
MueLu::NoFactory::getRCP
static const RCP< const NoFactory > getRCP()
Static Get() functions.
Definition: MueLu_NoFactory.hpp:90