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<const FactoryBase> FactoryManager<Scalar, LocalOrdinal, GlobalOrdinal, Node>::GetDefaultFactory(const std::string& varName) const {
96  if (defaultFactoryTable_.count(varName)) {
97  // The factory for this name was already created (possibly, for previous level, if we reuse factory manager)
98  return defaultFactoryTable_.find(varName)->second;
99 
100  } else {
101  // No factory was created for this name, but we may know which one to create
102  if (varName == "A") return SetAndReturnDefaultFactory(varName, rcp(new RAPFactory()));
103  if (varName == "RAP Pattern") return GetFactory("A");
104  if (varName == "AP Pattern") return GetFactory("A");
105  if (varName == "Ptent") return SetAndReturnDefaultFactory(varName, rcp(new TentativePFactory()));
106  if (varName == "P") {
107  // GetFactory("Ptent"): we need to use the same factory instance for both "P" and "Nullspace"
108  RCP<Factory> factory = rcp(new SaPFactory());
109  factory->SetFactory("P", GetFactory("Ptent"));
110  return SetAndReturnDefaultFactory(varName, factory);
111  }
112  if (varName == "Nullspace") {
113  // GetFactory("Ptent"): we need to use the same factory instance for both "P" and "Nullspace"
114  RCP<Factory> factory = rcp(new NullspaceFactory());
115  factory->SetFactory("Nullspace", GetFactory("Ptent"));
116  return SetAndReturnDefaultFactory(varName, factory);
117  }
118 
119  if (varName == "R") return SetAndReturnDefaultFactory(varName, rcp(new TransPFactory()));
120 #if defined(HAVE_MUELU_ZOLTAN) && defined(HAVE_MPI)
121  if (varName == "Partition") return SetAndReturnDefaultFactory(varName, rcp(new ZoltanInterface()));
122 #endif //ifdef HAVE_MPI
123 
124  if (varName == "Importer") {
125 #ifdef HAVE_MPI
126  return SetAndReturnDefaultFactory(varName, rcp(new RepartitionFactory()));
127 #else
128  return SetAndReturnDefaultFactory(varName, NoFactory::getRCP());
129 #endif
130  }
131  if (varName == "number of partitions") {
132 #ifdef HAVE_MPI
133  return SetAndReturnDefaultFactory(varName, rcp(new RepartitionHeuristicFactory()));
134 #else
135  return SetAndReturnDefaultFactory(varName, NoFactory::getRCP());
136 #endif
137  }
138 
139  if (varName == "Graph") return SetAndReturnDefaultFactory(varName, rcp(new CoalesceDropFactory()));
140  if (varName == "UnAmalgamationInfo") return SetAndReturnDefaultFactory(varName, rcp(new AmalgamationFactory())); //GetFactory("Graph"));
141  if (varName == "Aggregates") return SetAndReturnDefaultFactory(varName, rcp(new UncoupledAggregationFactory()));
142  if (varName == "CoarseMap") return SetAndReturnDefaultFactory(varName, rcp(new CoarseMapFactory()));
143  if (varName == "DofsPerNode") return GetFactory("Graph");
144  if (varName == "Filtering") return GetFactory("Graph");
145  if (varName == "LineDetection_VertLineIds") return SetAndReturnDefaultFactory(varName, rcp(new LineDetectionFactory()));
146  if (varName == "LineDetection_Layers") return GetFactory("LineDetection_VertLineIds");
147  if (varName == "CoarseNumZLayers") return GetFactory("LineDetection_VertLineIds");
148 
149  // Same factory for both Pre and Post Smoother. Factory for key "Smoother" can be set by users.
150  if (varName == "PreSmoother") return GetFactory("Smoother");
151  if (varName == "PostSmoother") return GetFactory("Smoother");
152 
153  if (varName == "Ppattern") {
154  RCP<PatternFactory> PpFact = rcp(new PatternFactory);
155  PpFact->SetFactory("P", GetFactory("Ptent"));
156  return SetAndReturnDefaultFactory(varName, PpFact);
157  }
158  if (varName == "Constraint") return SetAndReturnDefaultFactory(varName, rcp(new ConstraintFactory()));
159 
160  if (varName == "Smoother") {
161  Teuchos::ParameterList smootherParamList;
162  smootherParamList.set("relaxation: type", "Symmetric Gauss-Seidel");
163  smootherParamList.set("relaxation: sweeps", Teuchos::OrdinalTraits<LO>::one());
164  smootherParamList.set("relaxation: damping factor", Teuchos::ScalarTraits<Scalar>::one());
165  return SetAndReturnDefaultFactory(varName, rcp(new SmootherFactory(rcp(new TrilinosSmoother("RELAXATION", smootherParamList)))));
166  }
167  if (varName == "CoarseSolver") return SetAndReturnDefaultFactory(varName, rcp(new SmootherFactory(rcp(new DirectSolver()), Teuchos::null)));
168 
169  TEUCHOS_TEST_FOR_EXCEPTION(true, MueLu::Exceptions::RuntimeError, "MueLu::FactoryManager::GetDefaultFactory(): No default factory available for building '" + varName + "'.");
170  }
171  }
172 
173  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
174  const RCP<const FactoryBase> FactoryManager<Scalar, LocalOrdinal, GlobalOrdinal, Node>::SetAndReturnDefaultFactory(const std::string& varName, const RCP<const FactoryBase>& factory) const {
175  TEUCHOS_TEST_FOR_EXCEPTION(factory.is_null(), Exceptions::RuntimeError, "The default factory for building '" << varName << "' is null");
176 
177  GetOStream(Runtime1) << "Using default factory (" << factory->description() << ") for building '" << varName << "'." << std::endl;
178 
179  defaultFactoryTable_[varName] = factory;
180 
181  return defaultFactoryTable_[varName];
182  }
183 
184  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
186  std::map<std::string, RCP<const FactoryBase> >::const_iterator it;
187 
188  Teuchos::FancyOStream& fancy = GetOStream(Debug);
189 
190  fancy << "Users factory table (factoryTable_):" << std::endl;
191  for (it = factoryTable_.begin(); it != factoryTable_.end(); it++)
192  fancy << " " << it->first << " -> " << Teuchos::toString(it->second.get()) << std::endl;
193 
194  fancy << "Default factory table (defaultFactoryTable_):" << std::endl;
195  for (it = defaultFactoryTable_.begin(); it != defaultFactoryTable_.end(); it++)
196  fancy << " " << it->first << " -> " << Teuchos::toString(it->second.get()) << std::endl;
197  }
198 
199 #ifdef HAVE_MUELU_DEBUG
200  template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
202  std::map<std::string, RCP<const FactoryBase> >::const_iterator it;
203 
204  for (it = factoryTable_.begin(); it != factoryTable_.end(); it++)
205  if (!it->second.is_null())
206  it->second->ResetDebugData();
207 
208  for (it = defaultFactoryTable_.begin(); it != defaultFactoryTable_.end(); it++)
209  if (!it->second.is_null())
210  it->second->ResetDebugData();
211  }
212 #endif
213 
214 } // namespace MueLu
215 
216 //TODO: add operator[]
217 //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.
218 //TODO: add an option 'NoDefault' to check if we are using any default factory.
219 //TODO: use Teuchos::ConstNonConstObjectContainer to allow user to modify factories after a GetFactory()
220 
221 #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.
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 ...
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< 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.Input/output of SaPFactory
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.