MueLu  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
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>
101  factoryTable_[varName] = factory;
102  }
103 
104  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
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>
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>
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  if (varName == "Node Comm") return GetFactory("Ptent");
164 
165  if (varName == "R") return SetAndReturnDefaultFactory(varName, rcp(new TransPFactory()));
166 #if defined(HAVE_MUELU_ZOLTAN) && defined(HAVE_MPI)
167  if (varName == "Partition") return SetAndReturnDefaultFactory(varName, rcp(new ZoltanInterface()));
168 #endif //ifdef HAVE_MPI
169 
170  if (varName == "Importer") {
171 #ifdef HAVE_MPI
172  return SetAndReturnDefaultFactory(varName, rcp(new RepartitionFactory()));
173 #else
174  return SetAndReturnDefaultFactory(varName, NoFactory::getRCP());
175 #endif
176  }
177  if (varName == "number of partitions") {
178 #ifdef HAVE_MPI
179  return SetAndReturnDefaultFactory(varName, rcp(new RepartitionHeuristicFactory()));
180 #else
181  return SetAndReturnDefaultFactory(varName, NoFactory::getRCP());
182 #endif
183  }
184  if (varName == "repartition: heuristic target rows per process") return GetFactory("number of partitions");
185 
186  if (varName == "Graph") return MUELU_KOKKOS_FACTORY(varName, CoalesceDropFactory, CoalesceDropFactory_kokkos);
187  if (varName == "UnAmalgamationInfo") return SetAndReturnDefaultFactory(varName, rcp(new AmalgamationFactory())); //GetFactory("Graph"));
188  if (varName == "Aggregates") return MUELU_KOKKOS_FACTORY(varName, UncoupledAggregationFactory, UncoupledAggregationFactory_kokkos);
189  if (varName == "CoarseMap") return MUELU_KOKKOS_FACTORY(varName, CoarseMapFactory, CoarseMapFactory_kokkos);
190  if (varName == "DofsPerNode") return GetFactory("Graph");
191  if (varName == "Filtering") return GetFactory("Graph");
192  if (varName == "LineDetection_VertLineIds") return SetAndReturnDefaultFactory(varName, rcp(new LineDetectionFactory()));
193  if (varName == "LineDetection_Layers") return GetFactory("LineDetection_VertLineIds");
194  if (varName == "CoarseNumZLayers") return GetFactory("LineDetection_VertLineIds");
195 
196  // Non-Galerkin
197  if (varName == "K") return GetFactory("A");
198  if (varName == "M") return GetFactory("A");
199  if (varName == "Mdiag") return GetFactory("A");
200  if (varName == "cfl-based shift array") return GetFactory("A");
201 
202  // Same factory for both Pre and Post Smoother. Factory for key "Smoother" can be set by users.
203  if (varName == "PreSmoother") return GetFactory("Smoother");
204  if (varName == "PostSmoother") return GetFactory("Smoother");
205 
206  if (varName == "Ppattern") {
207  RCP<PatternFactory> PpFact = rcp(new PatternFactory);
208  PpFact->SetFactory("P", GetFactory("Ptent"));
209  return SetAndReturnDefaultFactory(varName, PpFact);
210  }
211  if (varName == "Constraint") return SetAndReturnDefaultFactory(varName, rcp(new ConstraintFactory()));
212 
213  if (varName == "Smoother") {
214  Teuchos::ParameterList smootherParamList;
215  smootherParamList.set("relaxation: type", "Symmetric Gauss-Seidel");
216  smootherParamList.set("relaxation: sweeps", Teuchos::OrdinalTraits<LO>::one());
217  smootherParamList.set("relaxation: damping factor", Teuchos::ScalarTraits<Scalar>::one());
218  return SetAndReturnDefaultFactory(varName, rcp(new SmootherFactory(rcp(new TrilinosSmoother("RELAXATION", smootherParamList)))));
219  }
220  if (varName == "CoarseSolver") return SetAndReturnDefaultFactory(varName, rcp(new SmootherFactory(rcp(new DirectSolver()), Teuchos::null)));
221 
222 #ifdef HAVE_MUELU_INTREPID2
223  // If we're asking for it, find who made P
224  if (varName == "pcoarsen: element to node map") return GetFactory("P");
225 #endif
226 
227  TEUCHOS_TEST_FOR_EXCEPTION(true, MueLu::Exceptions::RuntimeError, "MueLu::FactoryManager::GetDefaultFactory(): No default factory available for building '" + varName + "'.");
228  }
229  }
230 
231  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
233  TEUCHOS_TEST_FOR_EXCEPTION(factory.is_null(), Exceptions::RuntimeError, "The default factory for building '" << varName << "' is null");
234 
235  GetOStream(Runtime1) << "Using default factory (" << factory->description() << ") for building '" << varName << "'." << std::endl;
236 
237  defaultFactoryTable_[varName] = factory;
238 
239  return defaultFactoryTable_[varName];
240  }
241 
242  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
244  std::map<std::string, RCP<const FactoryBase> >::const_iterator it;
245 
246  Teuchos::FancyOStream& fancy = GetOStream(Debug);
247 
248  fancy << "Users factory table (factoryTable_):" << std::endl;
249  for (it = factoryTable_.begin(); it != factoryTable_.end(); it++)
250  fancy << " " << it->first << " -> " << Teuchos::toString(it->second.get()) << std::endl;
251 
252  fancy << "Default factory table (defaultFactoryTable_):" << std::endl;
253  for (it = defaultFactoryTable_.begin(); it != defaultFactoryTable_.end(); it++)
254  fancy << " " << it->first << " -> " << Teuchos::toString(it->second.get()) << std::endl;
255  }
256 
257 #ifdef HAVE_MUELU_DEBUG
258  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
260  std::map<std::string, RCP<const FactoryBase> >::const_iterator it;
261 
262  for (it = factoryTable_.begin(); it != factoryTable_.end(); it++)
263  if (!it->second.is_null())
264  it->second->ResetDebugData();
265 
266  for (it = defaultFactoryTable_.begin(); it != defaultFactoryTable_.end(); it++)
267  if (!it->second.is_null())
268  it->second->ResetDebugData();
269  }
270 #endif
271 
272 
273 #undef MUELU_KOKKOS_FACTORY
274 
275 } // namespace MueLu
276 
277 //TODO: add operator[]
278 //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.
279 //TODO: add an option 'NoDefault' to check if we are using any default factory.
280 //TODO: use Teuchos::ConstNonConstObjectContainer to allow user to modify factories after a GetFactory()
281 
282 #endif // MUELU_FACTORYMANAGER_DEF_HPP
Generic Smoother Factory for generating the smoothers of the MG hierarchy.
This class specifies the default factory that should generate some data on a Level if the data does n...
Factory for determing the number of partitions for rebalancing.
Factory for generating coarse level map. Used by TentativePFactory.
Class that encapsulates external library smoothers.
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Factory for building permutation matrix that can be be used to shuffle data (matrices, vectors) among processes.
Print additional debugging information.
const RCP< const FactoryBase > GetDefaultFactory(const std::string &varName) const
bool hasFactory(const std::string &varName) const
Check.
Interface to Zoltan library.This interface provides access to partitioning methods in Zoltan...
const RCP< const FactoryBase > GetFactory(const std::string &varName) const
Get factory associated with a particular data name.
Factory for building tentative prolongator.
Class that encapsulates direct solvers. Autoselection of AmesosSmoother or Amesos2Smoother according ...
const RCP< const FactoryBase > SetAndReturnDefaultFactory(const std::string &varName, const RCP< const FactoryBase > &factory) const
Base class for factories (e.g., R, P, and A_coarse).
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Factory for building line detection information.
AmalgamationFactory for subblocks of strided map based amalgamation data.
Factory for building the constraint operator.
void SetFactory(const std::string &varName, const RCP< const FactoryBase > &factory)
Set Factory.
const RCP< FactoryBase > GetFactoryNonConst(const std::string &varName)
Get factory associated with a particular data name (NONCONST version)
Factory for creating a graph base on a given matrix.
virtual void SetFactory(const std::string &varName, const RCP< const FactoryBase > &factory)=0
Configuration.
Factory for building nonzero patterns for energy minimization.
#define MUELU_KOKKOS_FACTORY(varName, oldFactory, newFactory)
Factory for building restriction operators.
Exception throws to report errors in the internal logical of the program.
Description of what is happening (more verbose)
Factory for building coarse matrices.
Factory for building Smoothed Aggregation prolongators.
Factory for building uncoupled aggregates.
virtual std::string description() const
Return a simple one-line description of this object.
std::string toString(const T &t)
Factory for generating nullspace.
static const RCP< const NoFactory > getRCP()
Static Get() functions.
bool is_null() const