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 
50 
51 #include <Teuchos_ParameterList.hpp>
52 
53 // Headers for factories used by default:
54 #include "MueLu_AmalgamationFactory.hpp"
55 #include "MueLu_CoalesceDropFactory.hpp"
56 #include "MueLu_CoarseMapFactory.hpp"
57 #include "MueLu_ConstraintFactory.hpp"
58 #include "MueLu_DirectSolver.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_SmootherFactory.hpp"
69 #include "MueLu_TentativePFactory.hpp"
70 #include "MueLu_TransPFactory.hpp"
71 #include "MueLu_TrilinosSmoother.hpp"
72 #include "MueLu_UncoupledAggregationFactory.hpp"
73 #include "MueLu_ZoltanInterface.hpp"
74 
75 
76 namespace MueLu {
77 
78  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
79  void FactoryManager<Scalar, LocalOrdinal, GlobalOrdinal, Node>::SetFactory(const std::string& varName, const RCP<const FactoryBase>& factory) {
80  factoryTable_[varName] = factory;
81  }
82 
83  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
84  const RCP<const FactoryBase> FactoryManager<Scalar, LocalOrdinal, GlobalOrdinal, Node>::GetFactory(const std::string& varName) const {
85  if (factoryTable_.count(varName)) {
86  // Search user provided factories
87  return factoryTable_.find(varName)->second;
88  }
89 
90  // Search/create default factory for this name
91  return GetDefaultFactory(varName);
92  }
93 
94  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
95  const RCP<FactoryBase> FactoryManager<Scalar, LocalOrdinal, GlobalOrdinal, Node>::GetFactoryNonConst(const std::string& varName) {
96  return Teuchos::rcp_const_cast<FactoryBase>(GetFactory(varName));
97  }
98 
99  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
100  const bool FactoryManager<Scalar, LocalOrdinal, GlobalOrdinal, Node>::hasFactory(const std::string& varName) const {
101  if (factoryTable_.count(varName)) return true;
102  return false;
103  }
104 
105  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
106  const RCP<const FactoryBase> FactoryManager<Scalar, LocalOrdinal, GlobalOrdinal, Node>::GetDefaultFactory(const std::string& varName) const {
107  if (defaultFactoryTable_.count(varName)) {
108  // The factory for this name was already created (possibly, for previous level, if we reuse factory manager)
109  return defaultFactoryTable_.find(varName)->second;
110 
111  } else {
112  // No factory was created for this name, but we may know which one to create
113  if (varName == "A") return SetAndReturnDefaultFactory(varName, rcp(new RAPFactory()));
114  if (varName == "RAP Pattern") return GetFactory("A");
115  if (varName == "AP Pattern") return GetFactory("A");
116  if (varName == "Ptent") return SetAndReturnDefaultFactory(varName, rcp(new TentativePFactory()));
117  if (varName == "P") {
118  // GetFactory("Ptent"): we need to use the same factory instance for both "P" and "Nullspace"
119  RCP<Factory> factory = rcp(new SaPFactory());
120  factory->SetFactory("P", GetFactory("Ptent"));
121  return SetAndReturnDefaultFactory(varName, factory);
122  }
123  if (varName == "Nullspace") {
124  // GetFactory("Ptent"): we need to use the same factory instance for both "P" and "Nullspace"
125  RCP<Factory> factory = rcp(new NullspaceFactory());
126  factory->SetFactory("Nullspace", GetFactory("Ptent"));
127  return SetAndReturnDefaultFactory(varName, factory);
128  }
129 
130  if (varName == "R") return SetAndReturnDefaultFactory(varName, rcp(new TransPFactory()));
131 #if defined(HAVE_MUELU_ZOLTAN) && defined(HAVE_MPI)
132  if (varName == "Partition") return SetAndReturnDefaultFactory(varName, rcp(new ZoltanInterface()));
133 #endif //ifdef HAVE_MPI
134 
135  if (varName == "Importer") {
136 #ifdef HAVE_MPI
137  return SetAndReturnDefaultFactory(varName, rcp(new RepartitionFactory()));
138 #else
139  return SetAndReturnDefaultFactory(varName, NoFactory::getRCP());
140 #endif
141  }
142  if (varName == "number of partitions") {
143 #ifdef HAVE_MPI
144  return SetAndReturnDefaultFactory(varName, rcp(new RepartitionHeuristicFactory()));
145 #else
146  return SetAndReturnDefaultFactory(varName, NoFactory::getRCP());
147 #endif
148  }
149 
150  if (varName == "Graph") return SetAndReturnDefaultFactory(varName, rcp(new CoalesceDropFactory()));
151  if (varName == "UnAmalgamationInfo") return SetAndReturnDefaultFactory(varName, rcp(new AmalgamationFactory())); //GetFactory("Graph"));
152  if (varName == "Aggregates") return SetAndReturnDefaultFactory(varName, rcp(new UncoupledAggregationFactory()));
153  if (varName == "CoarseMap") return SetAndReturnDefaultFactory(varName, rcp(new CoarseMapFactory()));
154  if (varName == "DofsPerNode") return GetFactory("Graph");
155  if (varName == "Filtering") return GetFactory("Graph");
156  if (varName == "LineDetection_VertLineIds") return SetAndReturnDefaultFactory(varName, rcp(new LineDetectionFactory()));
157  if (varName == "LineDetection_Layers") return GetFactory("LineDetection_VertLineIds");
158  if (varName == "CoarseNumZLayers") return GetFactory("LineDetection_VertLineIds");
159 
160  // Same factory for both Pre and Post Smoother. Factory for key "Smoother" can be set by users.
161  if (varName == "PreSmoother") return GetFactory("Smoother");
162  if (varName == "PostSmoother") return GetFactory("Smoother");
163 
164  if (varName == "Ppattern") {
165  RCP<PatternFactory> PpFact = rcp(new PatternFactory);
166  PpFact->SetFactory("P", GetFactory("Ptent"));
167  return SetAndReturnDefaultFactory(varName, PpFact);
168  }
169  if (varName == "Constraint") return SetAndReturnDefaultFactory(varName, rcp(new ConstraintFactory()));
170 
171  if (varName == "Smoother") {
172  Teuchos::ParameterList smootherParamList;
173  smootherParamList.set("relaxation: type", "Symmetric Gauss-Seidel");
174  smootherParamList.set("relaxation: sweeps", Teuchos::OrdinalTraits<LO>::one());
175  smootherParamList.set("relaxation: damping factor", Teuchos::ScalarTraits<Scalar>::one());
176  return SetAndReturnDefaultFactory(varName, rcp(new SmootherFactory(rcp(new TrilinosSmoother("RELAXATION", smootherParamList)))));
177  }
178  if (varName == "CoarseSolver") return SetAndReturnDefaultFactory(varName, rcp(new SmootherFactory(rcp(new DirectSolver()), Teuchos::null)));
179 
180 #ifdef HAVE_MUELU_INTREPID2
181  // If we're asking for it, find who made P
182  if (varName == "pcoarsen: element to node map") return GetFactory("P");
183 #endif
184 
185  TEUCHOS_TEST_FOR_EXCEPTION(true, MueLu::Exceptions::RuntimeError, "MueLu::FactoryManager::GetDefaultFactory(): No default factory available for building '" + varName + "'.");
186  }
187  }
188 
189  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
190  const RCP<const FactoryBase> FactoryManager<Scalar, LocalOrdinal, GlobalOrdinal, Node>::SetAndReturnDefaultFactory(const std::string& varName, const RCP<const FactoryBase>& factory) const {
191  TEUCHOS_TEST_FOR_EXCEPTION(factory.is_null(), Exceptions::RuntimeError, "The default factory for building '" << varName << "' is null");
192 
193  GetOStream(Runtime1) << "Using default factory (" << factory->description() << ") for building '" << varName << "'." << std::endl;
194 
195  defaultFactoryTable_[varName] = factory;
196 
197  return defaultFactoryTable_[varName];
198  }
199 
200  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
202  std::map<std::string, RCP<const FactoryBase> >::const_iterator it;
203 
204  Teuchos::FancyOStream& fancy = GetOStream(Debug);
205 
206  fancy << "Users factory table (factoryTable_):" << std::endl;
207  for (it = factoryTable_.begin(); it != factoryTable_.end(); it++)
208  fancy << " " << it->first << " -> " << Teuchos::toString(it->second.get()) << std::endl;
209 
210  fancy << "Default factory table (defaultFactoryTable_):" << std::endl;
211  for (it = defaultFactoryTable_.begin(); it != defaultFactoryTable_.end(); it++)
212  fancy << " " << it->first << " -> " << Teuchos::toString(it->second.get()) << std::endl;
213  }
214 
215 #ifdef HAVE_MUELU_DEBUG
216  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
218  std::map<std::string, RCP<const FactoryBase> >::const_iterator it;
219 
220  for (it = factoryTable_.begin(); it != factoryTable_.end(); it++)
221  if (!it->second.is_null())
222  it->second->ResetDebugData();
223 
224  for (it = defaultFactoryTable_.begin(); it != defaultFactoryTable_.end(); it++)
225  if (!it->second.is_null())
226  it->second->ResetDebugData();
227  }
228 #endif
229 
230 } // namespace MueLu
231 
232 //TODO: add operator[]
233 //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.
234 //TODO: add an option 'NoDefault' to check if we are using any default factory.
235 //TODO: use Teuchos::ConstNonConstObjectContainer to allow user to modify factories after a GetFactory()
236 
237 #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.
std::string toString(const T &what)
Little helper function to convert non-string types to strings.
const bool hasFactory(const std::string &varName) const
Check.
Class that encapsulates external library smoothers.
Factory for building permutation matrix that can be be used to shuffle data (matrices, vectors) among processes.
Print additional debugging information.
Namespace for MueLu classes and methods.
Interface to Zoltan library.This interface provides access to partitioning methods in Zoltan...
Factory for building tentative prolongator.
Class that encapsulates direct solvers. Autoselection of AmesosSmoother or Amesos2Smoother according ...
Base class for factories (e.g., R, P, and A_coarse).
const RCP< const FactoryBase > SetAndReturnDefaultFactory(const std::string &varName, const RCP< const FactoryBase > &factory) const
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)
const RCP< const FactoryBase > GetFactory(const std::string &varName) const
Get factory associated with a particular data name.
Factory for creating a graph base on a given matrix.
Factory for building nonzero patterns for energy minimization.
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.
const RCP< const FactoryBase > GetDefaultFactory(const std::string &varName) const
Factory for building uncoupled aggregates.
Factory for generating nullspace.
static const RCP< const NoFactory > getRCP()
Static Get() functions.