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_AggregateQualityEstimateFactory.hpp"
57 #include "MueLu_DirectSolver.hpp"
58 #include "MueLu_InitialBlockNumberFactory.hpp"
59 #include "MueLu_LineDetectionFactory.hpp"
60 // #include "MueLu_MultiVectorTransferFactory.hpp"
61 #include "MueLu_NoFactory.hpp"
62 #include "MueLu_NullspaceFactory.hpp"
63 #include "MueLu_PatternFactory.hpp"
64 #include "MueLu_RAPFactory.hpp"
65 #include "MueLu_RepartitionHeuristicFactory.hpp"
66 #include "MueLu_RepartitionFactory.hpp"
67 #include "MueLu_SaPFactory.hpp"
68 #include "MueLu_ScaledNullspaceFactory.hpp"
69 #include "MueLu_SmootherFactory.hpp"
70 #include "MueLu_TentativePFactory.hpp"
71 #include "MueLu_TransPFactory.hpp"
72 #include "MueLu_TrilinosSmoother.hpp"
73 #include "MueLu_UncoupledAggregationFactory.hpp"
74 #include "MueLu_StructuredAggregationFactory.hpp"
75 #include "MueLu_ZoltanInterface.hpp"
76 #include "MueLu_InterfaceMappingTransferFactory.hpp"
77 #include "MueLu_InterfaceAggregationFactory.hpp"
78 #include "MueLu_InverseApproximationFactory.hpp"
79 
80 #include "MueLu_CoalesceDropFactory_kokkos.hpp"
81 #include "MueLu_TentativePFactory_kokkos.hpp"
82 
84 
85 namespace MueLu {
86 
87 #define MUELU_KOKKOS_FACTORY(varName, oldFactory, newFactory) \
88  (!useKokkos_) ? SetAndReturnDefaultFactory(varName, rcp(new oldFactory())) : SetAndReturnDefaultFactory(varName, rcp(new newFactory()));
89 
90 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
92  factoryTable_[varName] = factory;
93 }
94 
95 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
97  if (factoryTable_.count(varName)) {
98  // Search user provided factories
99  return factoryTable_.find(varName)->second;
100  }
101 
102  // Search/create default factory for this name
103  return GetDefaultFactory(varName);
104 }
105 
106 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
108  return Teuchos::rcp_const_cast<FactoryBase>(GetFactory(varName));
109 }
110 
111 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
113  if (factoryTable_.count(varName)) return true;
114  return false;
115 }
116 
117 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
119  if (defaultFactoryTable_.count(varName)) {
120  // The factory for this name was already created (possibly, for previous level, if we reuse factory manager)
121  return defaultFactoryTable_.find(varName)->second;
122 
123  } else {
124  // No factory was created for this name, but we may know which one to create
125  if (varName == "A") return SetAndReturnDefaultFactory(varName, rcp(new RAPFactory()));
126  if (varName == "Ainv") return SetAndReturnDefaultFactory(varName, rcp(new InverseApproximationFactory()));
127  if (varName == "RAP Pattern") return GetFactory("A");
128  if (varName == "AP Pattern") return GetFactory("A");
129  if (varName == "Ptent") return MUELU_KOKKOS_FACTORY(varName, TentativePFactory, TentativePFactory_kokkos);
130  if (varName == "P") {
131  // GetFactory("Ptent"): we need to use the same factory instance for both "P" and "Nullspace"
132  RCP<Factory> factory = rcp(new SaPFactory());
133  factory->SetFactory("P", GetFactory("Ptent"));
134  return SetAndReturnDefaultFactory(varName, factory);
135  }
136  if (varName == "Nullspace") {
137  // GetFactory("Ptent"): we need to use the same factory instance for both "P" and "Nullspace"
138  RCP<Factory> factory = rcp(new NullspaceFactory());
139  factory->SetFactory("Nullspace", GetFactory("Ptent"));
140  return SetAndReturnDefaultFactory(varName, factory);
141  }
142  if (varName == "Scaled Nullspace") return SetAndReturnDefaultFactory(varName, rcp(new ScaledNullspaceFactory()));
143 
144  if (varName == "Coordinates") return GetFactory("Ptent");
145  if (varName == "Node Comm") return GetFactory("Ptent");
146 
147  if (varName == "R") return SetAndReturnDefaultFactory(varName, rcp(new TransPFactory()));
148  if (varName == "RfromPfactory") return GetFactory("P");
149 #if defined(HAVE_MUELU_ZOLTAN) && defined(HAVE_MPI)
150  if (varName == "Partition") return SetAndReturnDefaultFactory(varName, rcp(new ZoltanInterface()));
151 #endif // ifdef HAVE_MPI
152 
153  if (varName == "Importer") {
154 #ifdef HAVE_MPI
155  return SetAndReturnDefaultFactory(varName, rcp(new RepartitionFactory()));
156 #else
157  return SetAndReturnDefaultFactory(varName, NoFactory::getRCP());
158 #endif
159  }
160  if (varName == "number of partitions") {
161 #ifdef HAVE_MPI
162  return SetAndReturnDefaultFactory(varName, rcp(new RepartitionHeuristicFactory()));
163 #else
164  return SetAndReturnDefaultFactory(varName, NoFactory::getRCP());
165 #endif
166  }
167  if (varName == "repartition: heuristic target rows per process") return GetFactory("number of partitions");
168 
169  if (varName == "Graph") return MUELU_KOKKOS_FACTORY(varName, CoalesceDropFactory, CoalesceDropFactory_kokkos);
170  if (varName == "UnAmalgamationInfo") return SetAndReturnDefaultFactory(varName, rcp(new AmalgamationFactory()));
171  if (varName == "Aggregates") return SetAndReturnDefaultFactory(varName, rcp(new UncoupledAggregationFactory()));
172  if (varName == "AggregateQualities") return SetAndReturnDefaultFactory(varName, rcp(new AggregateQualityEstimateFactory()));
173  if (varName == "CoarseMap") return SetAndReturnDefaultFactory(varName, rcp(new CoarseMapFactory()));
174  if (varName == "DofsPerNode") return GetFactory("Graph");
175  if (varName == "Filtering") return GetFactory("Graph");
176  if (varName == "BlockNumber") return SetAndReturnDefaultFactory(varName, rcp(new InitialBlockNumberFactory()));
177  if (varName == "LineDetection_VertLineIds") return SetAndReturnDefaultFactory(varName, rcp(new LineDetectionFactory()));
178  if (varName == "LineDetection_Layers") return GetFactory("LineDetection_VertLineIds");
179  if (varName == "CoarseNumZLayers") return GetFactory("LineDetection_VertLineIds");
180 
181  // Structured
182  if (varName == "structuredInterpolationOrder") return SetAndReturnDefaultFactory(varName, rcp(new StructuredAggregationFactory()));
183 
184  // Non-Galerkin
185  if (varName == "K") return GetFactory("A");
186  if (varName == "M") return GetFactory("A");
187  if (varName == "Mdiag") return GetFactory("A");
188  if (varName == "cfl-based shift array") return GetFactory("A");
189 
190  // Same factory for both Pre and Post Smoother. Factory for key "Smoother" can be set by users.
191  if (varName == "PreSmoother") return GetFactory("Smoother");
192  if (varName == "PostSmoother") return GetFactory("Smoother");
193 
194  if (varName == "Ppattern") {
195  RCP<PatternFactory> PpFact = rcp(new PatternFactory);
196  PpFact->SetFactory("P", GetFactory("Ptent"));
197  return SetAndReturnDefaultFactory(varName, PpFact);
198  }
199  if (varName == "Constraint") return SetAndReturnDefaultFactory(varName, rcp(new ConstraintFactory()));
200 
201  if (varName == "Smoother") {
202  Teuchos::ParameterList smootherParamList;
203  smootherParamList.set("relaxation: type", "Symmetric Gauss-Seidel");
204  smootherParamList.set("relaxation: sweeps", Teuchos::OrdinalTraits<LO>::one());
205  smootherParamList.set("relaxation: damping factor", Teuchos::ScalarTraits<Scalar>::one());
206  return SetAndReturnDefaultFactory(varName, rcp(new SmootherFactory(rcp(new TrilinosSmoother("RELAXATION", smootherParamList)))));
207  }
208  if (varName == "CoarseSolver") return SetAndReturnDefaultFactory(varName, rcp(new SmootherFactory(rcp(new DirectSolver()), Teuchos::null)));
209 
210  if (varName == "DualNodeID2PrimalNodeID") return SetAndReturnDefaultFactory(varName, rcp(new InterfaceMappingTransferFactory()));
211  if (varName == "CoarseDualNodeID2PrimalNodeID") return SetAndReturnDefaultFactory(varName, rcp(new InterfaceAggregationFactory()));
212 #ifdef HAVE_MUELU_INTREPID2
213  // If we're asking for it, find who made P
214  if (varName == "pcoarsen: element to node map") return GetFactory("P");
215 #endif
216 
217  // NOTE: These are user data, but we might want to print them, so they need a default factory
218  if (varName == "Pnodal") return NoFactory::getRCP();
219  if (varName == "NodeMatrix") return NoFactory::getRCP();
220  if (varName == "NodeAggMatrix") return NoFactory::getRCP();
221 
222  TEUCHOS_TEST_FOR_EXCEPTION(true, MueLu::Exceptions::RuntimeError, "MueLu::FactoryManager::GetDefaultFactory(): No default factory available for building '" + varName + "'.");
223  }
224 }
225 
226 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
228  TEUCHOS_TEST_FOR_EXCEPTION(factory.is_null(), Exceptions::RuntimeError, "The default factory for building '" << varName << "' is null");
229 
230  GetOStream(Runtime1) << "Using default factory (" << factory->ShortClassName() << "[" << factory->GetID() << "]) for building '" << varName << "'." << std::endl;
231 
232  defaultFactoryTable_[varName] = factory;
233 
234  return defaultFactoryTable_[varName];
235 }
236 
237 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
239  std::map<std::string, RCP<const FactoryBase> >::const_iterator it;
240  Teuchos::FancyOStream& fancy = GetOStream(Debug);
241  // auto & fancy = std::cout;// For debugging
242 
243  fancy << "Users factory table (factoryTable_):" << std::endl;
244  for (it = factoryTable_.begin(); it != factoryTable_.end(); it++) {
245  fancy << " " << it->first << " -> ";
246  if (it->second.get() == NoFactory::get())
247  fancy << "NoFactory";
248  else if (!it->second.get())
249  fancy << "NULL";
250  else {
251  fancy << it->second.get()->ShortClassName() << "[" << it->second.get()->GetID() << "]";
252 #ifdef HAVE_MUELU_DEBUG
253  fancy << "(" << Teuchos::toString(it->second.get()) << ")";
254 #endif
255  }
256  fancy << std::endl;
257  }
258 
259  fancy << "Default factory table (defaultFactoryTable_):" << std::endl;
260  for (it = defaultFactoryTable_.begin(); it != defaultFactoryTable_.end(); it++) {
261  fancy << " " << it->first << " -> ";
262  if (it->second.get() == NoFactory::get())
263  fancy << "NoFactory";
264  else if (!it->second.get())
265  fancy << "NULL";
266  else {
267  fancy << it->second.get()->ShortClassName() << "[" << it->second.get()->GetID() << "]";
268 #ifdef HAVE_MUELU_DEBUG
269  fancy << "(" << Teuchos::toString(it->second.get()) << ")";
270 #endif
271  }
272  fancy << std::endl;
273  }
274 }
275 
276 #ifdef HAVE_MUELU_DEBUG
277 template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
279  std::map<std::string, RCP<const FactoryBase> >::const_iterator it;
280 
281  for (it = factoryTable_.begin(); it != factoryTable_.end(); it++)
282  if (!it->second.is_null())
283  it->second->ResetDebugData();
284 
285  for (it = defaultFactoryTable_.begin(); it != defaultFactoryTable_.end(); it++)
286  if (!it->second.is_null())
287  it->second->ResetDebugData();
288 }
289 #endif
290 
291 #undef MUELU_KOKKOS_FACTORY
292 
293 } // namespace MueLu
294 
295 // TODO: add operator[]
296 // 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.
297 // TODO: add an option 'NoDefault' to check if we are using any default factory.
298 // TODO: use Teuchos::ConstNonConstObjectContainer to allow user to modify factories after a GetFactory()
299 
300 #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.
Class for generating an initial LocalOrdinal-type BlockNumber vector, based on an input paraemter for...
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
int GetID() const
return unique factory id
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.
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.
Factory for building aggregates for Lagrange multipliers in surface-coupled problems.
Factory for creating a graph based 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.
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.
static const RCP< const NoFactory > getRCP()
Static Get() functions.
bool is_null() const