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