MueLu Version of the Day
Loading...
Searching...
No Matches
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
13#include <Teuchos_ParameterList.hpp>
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
49namespace MueLu {
50
51#define MUELU_KOKKOS_FACTORY(varName, oldFactory, newFactory) \
52 (!useKokkos_) ? SetAndReturnDefaultFactory(varName, rcp(new oldFactory())) : SetAndReturnDefaultFactory(varName, rcp(new newFactory()));
53
54template <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
60template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
61FactoryManager<Scalar, LocalOrdinal, GlobalOrdinal, Node>::FactoryManager(const std::map<std::string, RCP<const FactoryBase> >& factoryTable) {
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
67template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
69
70template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
71void FactoryManager<Scalar, LocalOrdinal, GlobalOrdinal, Node>::SetFactory(const std::string& varName, const RCP<const FactoryBase>& factory) {
72 factoryTable_[varName] = factory;
73}
74
75template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
76const RCP<const FactoryBase> FactoryManager<Scalar, LocalOrdinal, GlobalOrdinal, Node>::GetFactory(const std::string& varName) const {
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
86template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
88 return Teuchos::rcp_const_cast<FactoryBase>(GetFactory(varName));
89}
90
91template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
93 if (factoryTable_.count(varName)) return true;
94 return false;
95}
96
97template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
98const RCP<const FactoryBase> FactoryManager<Scalar, LocalOrdinal, GlobalOrdinal, Node>::GetDefaultFactory(const std::string& varName) const {
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 == "MinvA") return NoFactory::getRCP();
107 if (varName == "Minv") return NoFactory::getRCP();
108 if (varName == "Ainv") return SetAndReturnDefaultFactory(varName, rcp(new InverseApproximationFactory()));
109 if (varName == "RAP Pattern") return GetFactory("A");
110 if (varName == "AP Pattern") return GetFactory("A");
111 if (varName == "Ptent") return MUELU_KOKKOS_FACTORY(varName, TentativePFactory, TentativePFactory_kokkos);
112 if (varName == "P") {
113 // GetFactory("Ptent"): we need to use the same factory instance for both "P" and "Nullspace"
114 RCP<Factory> factory = rcp(new SaPFactory());
115 factory->SetFactory("P", GetFactory("Ptent"));
116 return SetAndReturnDefaultFactory(varName, factory);
117 }
118 if (varName == "Nullspace") {
119 // GetFactory("Ptent"): we need to use the same factory instance for both "P" and "Nullspace"
120 RCP<Factory> factory = rcp(new NullspaceFactory());
121 factory->SetFactory("Nullspace", GetFactory("Ptent"));
122 return SetAndReturnDefaultFactory(varName, factory);
123 }
124 if (varName == "Scaled Nullspace") return SetAndReturnDefaultFactory(varName, rcp(new ScaledNullspaceFactory()));
125 if (varName == "Material") {
126 auto fact = rcp(new MultiVectorTransferFactory());
127 Teuchos::ParameterList pl;
128 pl.set("Vector name", "Material");
129 pl.set("Transfer name", "Aggregates");
130 pl.set("Normalize", true);
131 fact->SetParameterList(pl);
132 return fact;
133 }
134 if (varName == "Coordinates") return GetFactory("Ptent");
135 if (varName == "Node Comm") return GetFactory("Ptent");
136
137 if (varName == "R") return SetAndReturnDefaultFactory(varName, rcp(new TransPFactory()));
138 if (varName == "RfromPfactory") return GetFactory("P");
139#if defined(HAVE_MUELU_ZOLTAN) && defined(HAVE_MPI)
140 if (varName == "Partition") return SetAndReturnDefaultFactory(varName, rcp(new ZoltanInterface()));
141#endif // ifdef HAVE_MPI
142
143 if (varName == "Importer") {
144#ifdef HAVE_MPI
145 return SetAndReturnDefaultFactory(varName, rcp(new RepartitionFactory()));
146#else
147 return SetAndReturnDefaultFactory(varName, NoFactory::getRCP());
148#endif
149 }
150 if (varName == "number of partitions") {
151#ifdef HAVE_MPI
152 return SetAndReturnDefaultFactory(varName, rcp(new RepartitionHeuristicFactory()));
153#else
154 return SetAndReturnDefaultFactory(varName, NoFactory::getRCP());
155#endif
156 }
157 if (varName == "repartition: heuristic target rows per process") return GetFactory("number of partitions");
158
159 if (varName == "Graph") return MUELU_KOKKOS_FACTORY(varName, CoalesceDropFactory, CoalesceDropFactory_kokkos);
160 if (varName == "UnAmalgamationInfo") return SetAndReturnDefaultFactory(varName, rcp(new AmalgamationFactory()));
161 if (varName == "Aggregates") return SetAndReturnDefaultFactory(varName, rcp(new UncoupledAggregationFactory()));
162 if (varName == "AggregateQualities") return SetAndReturnDefaultFactory(varName, rcp(new AggregateQualityEstimateFactory()));
163 if (varName == "CoarseMap") return SetAndReturnDefaultFactory(varName, rcp(new CoarseMapFactory()));
164 if (varName == "DofsPerNode") return GetFactory("Graph");
165 if (varName == "Filtering") return GetFactory("Graph");
166 if (varName == "BlockNumber") return SetAndReturnDefaultFactory(varName, rcp(new InitialBlockNumberFactory()));
167 if (varName == "LineDetection_VertLineIds") return SetAndReturnDefaultFactory(varName, rcp(new LineDetectionFactory()));
168 if (varName == "LineDetection_Layers") return GetFactory("LineDetection_VertLineIds");
169 if (varName == "CoarseNumZLayers") return GetFactory("LineDetection_VertLineIds");
170
171 // Structured
172 if (varName == "structuredInterpolationOrder") return SetAndReturnDefaultFactory(varName, rcp(new StructuredAggregationFactory()));
173
174 // Non-Galerkin
175 if (varName == "K") return GetFactory("A");
176 if (varName == "M") return GetFactory("A");
177 if (varName == "Mdiag") return GetFactory("A");
178 if (varName == "cfl-based shift array") return GetFactory("A");
179
180 // Same factory for both Pre and Post Smoother. Factory for key "Smoother" can be set by users.
181 if (varName == "PreSmoother") return GetFactory("Smoother");
182 if (varName == "PostSmoother") return GetFactory("Smoother");
183
184 if (varName == "Ppattern") {
185 RCP<PatternFactory> PpFact = rcp(new PatternFactory);
186 PpFact->SetFactory("P", GetFactory("Ptent"));
187 return SetAndReturnDefaultFactory(varName, PpFact);
188 }
189 if (varName == "Constraint") return SetAndReturnDefaultFactory(varName, rcp(new ConstraintFactory()));
190
191 if (varName == "Smoother") {
192 Teuchos::ParameterList smootherParamList;
193 smootherParamList.set("relaxation: type", "Symmetric Gauss-Seidel");
194 smootherParamList.set("relaxation: sweeps", Teuchos::OrdinalTraits<LO>::one());
195 smootherParamList.set("relaxation: damping factor", Teuchos::ScalarTraits<Scalar>::one());
196 return SetAndReturnDefaultFactory(varName, rcp(new SmootherFactory(rcp(new TrilinosSmoother("RELAXATION", smootherParamList)))));
197 }
198 if (varName == "CoarseSolver") return SetAndReturnDefaultFactory(varName, rcp(new SmootherFactory(rcp(new DirectSolver()), Teuchos::null)));
199
200 if (varName == "DualNodeID2PrimalNodeID") return SetAndReturnDefaultFactory(varName, rcp(new InterfaceMappingTransferFactory()));
201 if (varName == "CoarseDualNodeID2PrimalNodeID") return SetAndReturnDefaultFactory(varName, rcp(new InterfaceAggregationFactory()));
202#if defined(HAVE_MUELU_INTREPID2) && defined(HAVE_MUELU_EXPERIMENTAL)
203 // If we're asking for it, find who made P
204 if (varName == "pcoarsen: element to node map") return GetFactory("P");
205#endif
206
207 // NOTE: These are user data, but we might want to print them, so they need a default factory
208 if (varName == "Pnodal") return NoFactory::getRCP();
209 if (varName == "NodeMatrix") return NoFactory::getRCP();
210 if (varName == "NodeAggMatrix") return NoFactory::getRCP();
211
212 TEUCHOS_TEST_FOR_EXCEPTION(true, MueLu::Exceptions::RuntimeError, "MueLu::FactoryManager::GetDefaultFactory(): No default factory available for building '" + varName + "'.");
213 }
214}
215
216template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
217const RCP<const FactoryBase> FactoryManager<Scalar, LocalOrdinal, GlobalOrdinal, Node>::SetAndReturnDefaultFactory(const std::string& varName, const RCP<const FactoryBase>& factory) const {
218 TEUCHOS_TEST_FOR_EXCEPTION(factory.is_null(), Exceptions::RuntimeError, "The default factory for building '" << varName << "' is null");
219
220 GetOStream(Runtime1) << "Using default factory (" << factory->ShortClassName() << "[" << factory->GetID() << "]) for building '" << varName << "'." << std::endl;
221
222 defaultFactoryTable_[varName] = factory;
223
224 return defaultFactoryTable_[varName];
225}
226
227template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
229 std::map<std::string, RCP<const FactoryBase> >::const_iterator it;
230 Teuchos::FancyOStream& fancy = GetOStream(Debug);
231 // auto & fancy = std::cout;// For debugging
232
233 fancy << "Users factory table (factoryTable_):" << std::endl;
234 for (it = factoryTable_.begin(); it != factoryTable_.end(); it++) {
235 fancy << " " << it->first << " -> ";
236 if (it->second.get() == NoFactory::get())
237 fancy << "NoFactory";
238 else if (!it->second.get())
239 fancy << "NULL";
240 else {
241 fancy << it->second.get()->ShortClassName() << "[" << it->second.get()->GetID() << "]";
242#ifdef HAVE_MUELU_DEBUG
243 fancy << "(" << Teuchos::toString(it->second.get()) << ")";
244#endif
245 }
246 fancy << std::endl;
247 }
248
249 fancy << "Default factory table (defaultFactoryTable_):" << std::endl;
250 for (it = defaultFactoryTable_.begin(); it != defaultFactoryTable_.end(); it++) {
251 fancy << " " << it->first << " -> ";
252 if (it->second.get() == NoFactory::get())
253 fancy << "NoFactory";
254 else if (!it->second.get())
255 fancy << "NULL";
256 else {
257 fancy << it->second.get()->ShortClassName() << "[" << it->second.get()->GetID() << "]";
258#ifdef HAVE_MUELU_DEBUG
259 fancy << "(" << Teuchos::toString(it->second.get()) << ")";
260#endif
261 }
262 fancy << std::endl;
263 }
264}
265
266#ifdef HAVE_MUELU_DEBUG
267template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
269 std::map<std::string, RCP<const FactoryBase> >::const_iterator it;
270
271 for (it = factoryTable_.begin(); it != factoryTable_.end(); it++)
272 if (!it->second.is_null())
273 it->second->ResetDebugData();
274
275 for (it = defaultFactoryTable_.begin(); it != defaultFactoryTable_.end(); it++)
276 if (!it->second.is_null())
277 it->second->ResetDebugData();
278}
279#endif
280
281#undef MUELU_KOKKOS_FACTORY
282
283} // namespace MueLu
284
285// TODO: add operator[]
286// 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.
287// TODO: add an option 'NoDefault' to check if we are using any default factory.
288// TODO: use Teuchos::ConstNonConstObjectContainer to allow user to modify factories after a GetFactory()
289
290#endif // MUELU_FACTORYMANAGER_DEF_HPP
#define MUELU_KOKKOS_FACTORY(varName, oldFactory, newFactory)
An factory which assigns each aggregate a quality estimate. Originally developed by Napov and Notay i...
AmalgamationFactory for subblocks of strided map based amalgamation data.
Factory for creating a graph based on a given matrix.
Factory for creating a graph based on a given matrix.
Factory for generating coarse level map. Used by TentativePFactory.
Factory for building the constraint operator.
Class that encapsulates direct solvers. Autoselection of AmesosSmoother or Amesos2Smoother according ...
Exception throws to report errors in the internal logical of the program.
This class specifies the default factory that should generate some data on a Level if the data does n...
const RCP< const FactoryBase > GetDefaultFactory(const std::string &varName) const
const RCP< const FactoryBase > SetAndReturnDefaultFactory(const std::string &varName, const RCP< const FactoryBase > &factory) const
void SetFactory(const std::string &varName, const RCP< const FactoryBase > &factory)
Set Factory.
bool hasFactory(const std::string &varName) const
Check.
const RCP< const FactoryBase > GetFactory(const std::string &varName) const
Get factory associated with a particular data name.
const RCP< FactoryBase > GetFactoryNonConst(const std::string &varName)
Get factory associated with a particular data name (NONCONST version)
virtual ~FactoryManager()
Destructor.
Class for generating an initial LocalOrdinal-type BlockNumber vector, based on an input paraemter for...
Factory for building aggregates for Lagrange multipliers in surface-coupled problems.
Transfer mapping data for interface aggregation to the coarse level.
Factory for building the approximate inverse of a matrix.
Factory for building line detection information.
Class for restricting a MultiVector from a finer to a coarser level.
static const RCP< const NoFactory > getRCP()
Static Get() functions.
static const NoFactory * get()
Factory for generating nullspace.
Factory for building nonzero patterns for energy minimization.
Factory for building coarse matrices.
Factory for building permutation matrix that can be be used to shuffle data (matrices,...
Factory for determing the number of partitions for rebalancing.
Factory for building Smoothed Aggregation prolongators.
Factory for generating a very special nullspace.
Generic Smoother Factory for generating the smoothers of the MG hierarchy.
Factory for building aggregates on structured grids.
Factory for building tentative prolongator.
Factory for building restriction operators.
Class that encapsulates external library smoothers.
Interface to Zoltan library.
Namespace for MueLu classes and methods.
@ Debug
Print additional debugging information.
@ Runtime1
Description of what is happening (more verbose)