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 // MueLu: A package for multigrid based preconditioning
4 //
5 // Copyright 2012 NTESS and the MueLu contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef MUELU_FACTORYMANAGER_DEF_HPP
11 #define MUELU_FACTORYMANAGER_DEF_HPP
12 
14 
15 // Headers for factories used by default:
16 #include "MueLu_AmalgamationFactory.hpp"
17 #include "MueLu_CoalesceDropFactory.hpp"
18 #include "MueLu_CoarseMapFactory.hpp"
19 #include "MueLu_ConstraintFactory.hpp"
20 #include "MueLu_AggregateQualityEstimateFactory.hpp"
21 #include "MueLu_DirectSolver.hpp"
22 #include "MueLu_InitialBlockNumberFactory.hpp"
23 #include "MueLu_LineDetectionFactory.hpp"
24 #include "MueLu_MultiVectorTransferFactory.hpp"
25 #include "MueLu_NoFactory.hpp"
26 #include "MueLu_NullspaceFactory.hpp"
27 #include "MueLu_PatternFactory.hpp"
28 #include "MueLu_RAPFactory.hpp"
29 #include "MueLu_RepartitionHeuristicFactory.hpp"
30 #include "MueLu_RepartitionFactory.hpp"
31 #include "MueLu_SaPFactory.hpp"
32 #include "MueLu_ScaledNullspaceFactory.hpp"
33 #include "MueLu_SmootherFactory.hpp"
34 #include "MueLu_TentativePFactory.hpp"
35 #include "MueLu_TransPFactory.hpp"
36 #include "MueLu_TrilinosSmoother.hpp"
37 #include "MueLu_UncoupledAggregationFactory.hpp"
38 #include "MueLu_StructuredAggregationFactory.hpp"
39 #include "MueLu_ZoltanInterface.hpp"
40 #include "MueLu_InterfaceMappingTransferFactory.hpp"
41 #include "MueLu_InterfaceAggregationFactory.hpp"
42 #include "MueLu_InverseApproximationFactory.hpp"
43 
44 #include "MueLu_CoalesceDropFactory_kokkos.hpp"
45 #include "MueLu_TentativePFactory_kokkos.hpp"
46 
48 
49 namespace MueLu {
50 
51 #define MUELU_KOKKOS_FACTORY(varName, oldFactory, newFactory) \
52  (!useKokkos_) ? SetAndReturnDefaultFactory(varName, rcp(new oldFactory())) : SetAndReturnDefaultFactory(varName, rcp(new newFactory()));
53 
54 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
56  SetIgnoreUserData(false); // set IgnorUserData flag to false (default behaviour)
57  useKokkos_ = !Node::is_serial;
58 }
59 
60 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
62  factoryTable_ = factoryTable;
63  SetIgnoreUserData(false); // set IgnorUserData flag to false (default behaviour) //TODO: use parent class constructor instead
64  useKokkos_ = !Node::is_serial;
65 }
66 
67 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
69 
70 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
72  factoryTable_[varName] = factory;
73 }
74 
75 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
77  if (factoryTable_.count(varName)) {
78  // Search user provided factories
79  return factoryTable_.find(varName)->second;
80  }
81 
82  // Search/create default factory for this name
83  return GetDefaultFactory(varName);
84 }
85 
86 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
88  return Teuchos::rcp_const_cast<FactoryBase>(GetFactory(varName));
89 }
90 
91 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
93  if (factoryTable_.count(varName)) return true;
94  return false;
95 }
96 
97 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
99  if (defaultFactoryTable_.count(varName)) {
100  // The factory for this name was already created (possibly, for previous level, if we reuse factory manager)
101  return defaultFactoryTable_.find(varName)->second;
102 
103  } else {
104  // No factory was created for this name, but we may know which one to create
105  if (varName == "A") return SetAndReturnDefaultFactory(varName, rcp(new RAPFactory()));
106  if (varName == "Ainv") return SetAndReturnDefaultFactory(varName, rcp(new InverseApproximationFactory()));
107  if (varName == "RAP Pattern") return GetFactory("A");
108  if (varName == "AP Pattern") return GetFactory("A");
109  if (varName == "Ptent") return MUELU_KOKKOS_FACTORY(varName, TentativePFactory, TentativePFactory_kokkos);
110  if (varName == "P") {
111  // GetFactory("Ptent"): we need to use the same factory instance for both "P" and "Nullspace"
112  RCP<Factory> factory = rcp(new SaPFactory());
113  factory->SetFactory("P", GetFactory("Ptent"));
114  return SetAndReturnDefaultFactory(varName, factory);
115  }
116  if (varName == "Nullspace") {
117  // GetFactory("Ptent"): we need to use the same factory instance for both "P" and "Nullspace"
118  RCP<Factory> factory = rcp(new NullspaceFactory());
119  factory->SetFactory("Nullspace", GetFactory("Ptent"));
120  return SetAndReturnDefaultFactory(varName, factory);
121  }
122  if (varName == "Scaled Nullspace") return SetAndReturnDefaultFactory(varName, rcp(new ScaledNullspaceFactory()));
123  if (varName == "Material") {
124  auto fact = rcp(new MultiVectorTransferFactory());
126  pl.set("Vector name", "Material");
127  pl.set("Transfer name", "Ptent");
128  pl.set("Normalize", true);
129  fact->SetParameterList(pl);
130  return fact;
131  }
132  if (varName == "Coordinates") return GetFactory("Ptent");
133  if (varName == "Node Comm") return GetFactory("Ptent");
134 
135  if (varName == "R") return SetAndReturnDefaultFactory(varName, rcp(new TransPFactory()));
136  if (varName == "RfromPfactory") return GetFactory("P");
137 #if defined(HAVE_MUELU_ZOLTAN) && defined(HAVE_MPI)
138  if (varName == "Partition") return SetAndReturnDefaultFactory(varName, rcp(new ZoltanInterface()));
139 #endif // ifdef HAVE_MPI
140 
141  if (varName == "Importer") {
142 #ifdef HAVE_MPI
143  return SetAndReturnDefaultFactory(varName, rcp(new RepartitionFactory()));
144 #else
145  return SetAndReturnDefaultFactory(varName, NoFactory::getRCP());
146 #endif
147  }
148  if (varName == "number of partitions") {
149 #ifdef HAVE_MPI
150  return SetAndReturnDefaultFactory(varName, rcp(new RepartitionHeuristicFactory()));
151 #else
152  return SetAndReturnDefaultFactory(varName, NoFactory::getRCP());
153 #endif
154  }
155  if (varName == "repartition: heuristic target rows per process") return GetFactory("number of partitions");
156 
157  if (varName == "Graph") return MUELU_KOKKOS_FACTORY(varName, CoalesceDropFactory, CoalesceDropFactory_kokkos);
158  if (varName == "UnAmalgamationInfo") return SetAndReturnDefaultFactory(varName, rcp(new AmalgamationFactory()));
159  if (varName == "Aggregates") return SetAndReturnDefaultFactory(varName, rcp(new UncoupledAggregationFactory()));
160  if (varName == "AggregateQualities") return SetAndReturnDefaultFactory(varName, rcp(new AggregateQualityEstimateFactory()));
161  if (varName == "CoarseMap") return SetAndReturnDefaultFactory(varName, rcp(new CoarseMapFactory()));
162  if (varName == "DofsPerNode") return GetFactory("Graph");
163  if (varName == "Filtering") return GetFactory("Graph");
164  if (varName == "BlockNumber") return SetAndReturnDefaultFactory(varName, rcp(new InitialBlockNumberFactory()));
165  if (varName == "LineDetection_VertLineIds") return SetAndReturnDefaultFactory(varName, rcp(new LineDetectionFactory()));
166  if (varName == "LineDetection_Layers") return GetFactory("LineDetection_VertLineIds");
167  if (varName == "CoarseNumZLayers") return GetFactory("LineDetection_VertLineIds");
168 
169  // Structured
170  if (varName == "structuredInterpolationOrder") return SetAndReturnDefaultFactory(varName, rcp(new StructuredAggregationFactory()));
171 
172  // Non-Galerkin
173  if (varName == "K") return GetFactory("A");
174  if (varName == "M") return GetFactory("A");
175  if (varName == "Mdiag") return GetFactory("A");
176  if (varName == "cfl-based shift array") return GetFactory("A");
177 
178  // Same factory for both Pre and Post Smoother. Factory for key "Smoother" can be set by users.
179  if (varName == "PreSmoother") return GetFactory("Smoother");
180  if (varName == "PostSmoother") return GetFactory("Smoother");
181 
182  if (varName == "Ppattern") {
183  RCP<PatternFactory> PpFact = rcp(new PatternFactory);
184  PpFact->SetFactory("P", GetFactory("Ptent"));
185  return SetAndReturnDefaultFactory(varName, PpFact);
186  }
187  if (varName == "Constraint") return SetAndReturnDefaultFactory(varName, rcp(new ConstraintFactory()));
188 
189  if (varName == "Smoother") {
190  Teuchos::ParameterList smootherParamList;
191  smootherParamList.set("relaxation: type", "Symmetric Gauss-Seidel");
192  smootherParamList.set("relaxation: sweeps", Teuchos::OrdinalTraits<LO>::one());
193  smootherParamList.set("relaxation: damping factor", Teuchos::ScalarTraits<Scalar>::one());
194  return SetAndReturnDefaultFactory(varName, rcp(new SmootherFactory(rcp(new TrilinosSmoother("RELAXATION", smootherParamList)))));
195  }
196  if (varName == "CoarseSolver") return SetAndReturnDefaultFactory(varName, rcp(new SmootherFactory(rcp(new DirectSolver()), Teuchos::null)));
197 
198  if (varName == "DualNodeID2PrimalNodeID") return SetAndReturnDefaultFactory(varName, rcp(new InterfaceMappingTransferFactory()));
199  if (varName == "CoarseDualNodeID2PrimalNodeID") return SetAndReturnDefaultFactory(varName, rcp(new InterfaceAggregationFactory()));
200 #ifdef HAVE_MUELU_INTREPID2
201  // If we're asking for it, find who made P
202  if (varName == "pcoarsen: element to node map") return GetFactory("P");
203 #endif
204 
205  // NOTE: These are user data, but we might want to print them, so they need a default factory
206  if (varName == "Pnodal") return NoFactory::getRCP();
207  if (varName == "NodeMatrix") return NoFactory::getRCP();
208  if (varName == "NodeAggMatrix") return NoFactory::getRCP();
209 
210  TEUCHOS_TEST_FOR_EXCEPTION(true, MueLu::Exceptions::RuntimeError, "MueLu::FactoryManager::GetDefaultFactory(): No default factory available for building '" + varName + "'.");
211  }
212 }
213 
214 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
216  TEUCHOS_TEST_FOR_EXCEPTION(factory.is_null(), Exceptions::RuntimeError, "The default factory for building '" << varName << "' is null");
217 
218  GetOStream(Runtime1) << "Using default factory (" << factory->ShortClassName() << "[" << factory->GetID() << "]) for building '" << varName << "'." << std::endl;
219 
220  defaultFactoryTable_[varName] = factory;
221 
222  return defaultFactoryTable_[varName];
223 }
224 
225 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
227  std::map<std::string, RCP<const FactoryBase> >::const_iterator it;
228  Teuchos::FancyOStream& fancy = GetOStream(Debug);
229  // auto & fancy = std::cout;// For debugging
230 
231  fancy << "Users factory table (factoryTable_):" << std::endl;
232  for (it = factoryTable_.begin(); it != factoryTable_.end(); it++) {
233  fancy << " " << it->first << " -> ";
234  if (it->second.get() == NoFactory::get())
235  fancy << "NoFactory";
236  else if (!it->second.get())
237  fancy << "NULL";
238  else {
239  fancy << it->second.get()->ShortClassName() << "[" << it->second.get()->GetID() << "]";
240 #ifdef HAVE_MUELU_DEBUG
241  fancy << "(" << Teuchos::toString(it->second.get()) << ")";
242 #endif
243  }
244  fancy << std::endl;
245  }
246 
247  fancy << "Default factory table (defaultFactoryTable_):" << std::endl;
248  for (it = defaultFactoryTable_.begin(); it != defaultFactoryTable_.end(); it++) {
249  fancy << " " << it->first << " -> ";
250  if (it->second.get() == NoFactory::get())
251  fancy << "NoFactory";
252  else if (!it->second.get())
253  fancy << "NULL";
254  else {
255  fancy << it->second.get()->ShortClassName() << "[" << it->second.get()->GetID() << "]";
256 #ifdef HAVE_MUELU_DEBUG
257  fancy << "(" << Teuchos::toString(it->second.get()) << ")";
258 #endif
259  }
260  fancy << std::endl;
261  }
262 }
263 
264 #ifdef HAVE_MUELU_DEBUG
265 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
267  std::map<std::string, RCP<const FactoryBase> >::const_iterator it;
268 
269  for (it = factoryTable_.begin(); it != factoryTable_.end(); it++)
270  if (!it->second.is_null())
271  it->second->ResetDebugData();
272 
273  for (it = defaultFactoryTable_.begin(); it != defaultFactoryTable_.end(); it++)
274  if (!it->second.is_null())
275  it->second->ResetDebugData();
276 }
277 #endif
278 
279 #undef MUELU_KOKKOS_FACTORY
280 
281 } // namespace MueLu
282 
283 // TODO: add operator[]
284 // 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.
285 // TODO: add an option 'NoDefault' to check if we are using any default factory.
286 // TODO: use Teuchos::ConstNonConstObjectContainer to allow user to modify factories after a GetFactory()
287 
288 #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 building aggregates on structured grids.
Factory for determing the number of partitions for rebalancing.
Factory for generating coarse level map. Used by TentativePFactory.
virtual void SetFactory(const std::string &varName, const RCP< const FactoryBase > &factory)
Configuration.
Class for generating an initial LocalOrdinal-type BlockNumber vector, based on an input paraemter for...
Class that encapsulates external library smoothers.
#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
Class for restricting a MultiVector from a finer to a coarser level.
int GetID() const
return unique factory id
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
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.
static const NoFactory * get()
Factory for building tentative prolongator.
Class that encapsulates direct solvers. Autoselection of AmesosSmoother or Amesos2Smoother according ...
virtual std::string ShortClassName() const
Return the class name of the object, without template parameters and without namespace.
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).
Factory for building the approximate inverse of a matrix.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Factory for building line detection information.
Transfer mapping data for interface aggregation to the coarse level.
AmalgamationFactory for subblocks of strided map based amalgamation data.
static const RCP< const NoFactory > getRCP()
Static Get() functions.
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 generating a very special nullspace.
virtual ~FactoryManager()
Destructor.
Factory for building aggregates for Lagrange multipliers in surface-coupled problems.
Factory for creating a graph based on a given matrix.
Factory for building nonzero patterns for energy minimization.
#define MUELU_KOKKOS_FACTORY(varName, oldFactory, newFactory)
Factory for building restriction operators.
Factory for creating a graph based on a given matrix.
Exception throws to report errors in the internal logical of the program.
Description of what is happening (more verbose)
Factory for building coarse matrices.
An factory which assigns each aggregate a quality estimate. Originally developed by Napov and Notay i...
Factory for building Smoothed Aggregation prolongators.Input/output of SaPFactory
Factory for building uncoupled aggregates.
std::string toString(const T &t)
Factory for generating nullspace.
bool is_null() const