MueLu  Version of the Day
MueLu_FactoryFactory_decl.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_FACTORYFACTORY_DECL_HPP
47 #define MUELU_FACTORYFACTORY_DECL_HPP
48 
49 #include <string>
50 #include <vector>
51 
52 #include <Teuchos_ParameterEntry.hpp>
53 #include <Teuchos_Array.hpp>
54 
55 #include "MueLu_ConfigDefs.hpp"
57 
59 
60 #include "MueLu_FactoryBase.hpp"
61 #include "MueLu_FactoryManager.hpp"
65 #include "MueLu_Hierarchy_fwd.hpp"
66 
67 #include "MueLu_Monitor.hpp"
68 #include "MueLu_Exceptions.hpp"
69 
70 #include "MueLu_AggregationExportFactory.hpp"
71 #include "MueLu_AmalgamationFactory.hpp"
72 #include "MueLu_BlackBoxPFactory.hpp"
73 #include "MueLu_BlockedCoarseMapFactory.hpp"
74 #include "MueLu_BlockedCoordinatesTransferFactory.hpp"
75 #include "MueLu_BlockedDirectSolver.hpp"
76 #include "MueLu_BlockedGaussSeidelSmoother.hpp"
77 #include "MueLu_BlockedJacobiSmoother.hpp"
78 #include "MueLu_BlockedPFactory.hpp"
79 #include "MueLu_BlockedRAPFactory.hpp"
80 #include "MueLu_BraessSarazinSmoother.hpp"
81 #include "MueLu_BrickAggregationFactory.hpp"
82 #include "MueLu_CloneRepartitionInterface.hpp"
83 #include "MueLu_CoalesceDropFactory.hpp"
84 #include "MueLu_CoarseMapFactory.hpp"
85 #include "MueLu_CoarseningVisualizationFactory.hpp"
86 #include "MueLu_ConstraintFactory.hpp"
87 #include "MueLu_CoupledAggregationFactory.hpp"
88 #include "MueLu_CoordinatesTransferFactory.hpp"
89 #include "MueLu_DirectSolver.hpp"
90 #include "MueLu_DropNegativeEntriesFactory.hpp"
91 #include "MueLu_EminPFactory.hpp"
92 #include "MueLu_FilteredAFactory.hpp"
93 #include "MueLu_FineLevelInputDataFactory.hpp"
94 #include "MueLu_GeneralGeometricPFactory.hpp"
95 #include "MueLu_GenericRFactory.hpp"
96 #include "MueLu_GeometricInterpolationPFactory.hpp"
97 #include "MueLu_IndefBlockedDiagonalSmoother.hpp"
98 #include "MueLu_IsorropiaInterface.hpp"
99 #include "MueLu_LineDetectionFactory.hpp"
100 #include "MueLu_RepartitionInterface.hpp"
101 #include "MueLu_RepartitionBlockDiagonalFactory.hpp"
102 #include "MueLu_MapTransferFactory.hpp"
103 #include "MueLu_MatrixAnalysisFactory.hpp"
104 #include "MueLu_MultiVectorTransferFactory.hpp"
105 #include "MueLu_NullspaceFactory.hpp"
106 #include "MueLu_NullspacePresmoothFactory.hpp"
107 #include "MueLu_PatternFactory.hpp"
108 #include "MueLu_PgPFactory.hpp"
109 #include "MueLu_RebalanceBlockInterpolationFactory.hpp"
110 #include "MueLu_RebalanceBlockRestrictionFactory.hpp"
111 #include "MueLu_RebalanceBlockAcFactory.hpp"
112 #include "MueLu_RebalanceTransferFactory.hpp"
113 #include "MueLu_RepartitionFactory.hpp"
114 #include "MueLu_RepartitionHeuristicFactory.hpp"
115 #include "MueLu_RAPFactory.hpp"
116 #include "MueLu_RAPShiftFactory.hpp"
117 #include "MueLu_RebalanceAcFactory.hpp"
118 #include "MueLu_ReorderBlockAFactory.hpp"
119 #include "MueLu_SaPFactory.hpp"
120 #include "MueLu_SegregatedAFactory.hpp"
121 #include "MueLu_SemiCoarsenPFactory.hpp"
122 #include "MueLu_SchurComplementFactory.hpp"
123 #include "MueLu_SimpleSmoother.hpp"
124 #include "MueLu_SmootherFactory.hpp"
125 #include "MueLu_StructuredAggregationFactory.hpp"
126 #include "MueLu_StructuredLineDetectionFactory.hpp"
127 #include "MueLu_SubBlockAFactory.hpp"
128 #ifdef HAVE_MUELU_TEKO
129 #include "MueLu_TekoSmoother.hpp"
130 #endif
131 #include "MueLu_TentativePFactory.hpp"
132 #include "MueLu_ToggleCoordinatesTransferFactory.hpp"
133 #include "MueLu_TogglePFactory.hpp"
134 #include "MueLu_TrilinosSmoother.hpp"
135 #include "MueLu_TransPFactory.hpp"
136 #include "MueLu_UncoupledAggregationFactory.hpp"
137 #include "MueLu_HybridAggregationFactory.hpp"
138 #include "MueLu_UnsmooshFactory.hpp"
139 #include "MueLu_UserAggregationFactory.hpp"
140 #include "MueLu_UserPFactory.hpp"
141 #include "MueLu_UzawaSmoother.hpp"
142 #include "MueLu_VariableDofLaplacianFactory.hpp"
143 #include "MueLu_ZoltanInterface.hpp"
144 #include "MueLu_Zoltan2Interface.hpp"
145 
146 #ifdef HAVE_MUELU_KOKKOS_REFACTOR
147 #include "MueLu_CoalesceDropFactory_kokkos.hpp"
148 #include "MueLu_CoarseMapFactory_kokkos.hpp"
149 #include "MueLu_CoordinatesTransferFactory_kokkos.hpp"
150 #include "MueLu_NullspaceFactory_kokkos.hpp"
151 #include "MueLu_SaPFactory_kokkos.hpp"
152 #include "MueLu_TentativePFactory_kokkos.hpp"
153 #include "MueLu_UncoupledAggregationFactory_kokkos.hpp"
154 #endif
155 
156 #ifdef HAVE_MUELU_MATLAB
157 // This is distasteful, but (sadly) neccesary due to peculiarities in MueLu's build system.
158 #include "../matlab/src/MueLu_SingleLevelMatlabFactory_decl.hpp"
159 #include "../matlab/src/MueLu_SingleLevelMatlabFactory_def.hpp"
160 #include "../matlab/src/MueLu_TwoLevelMatlabFactory_decl.hpp"
161 #include "../matlab/src/MueLu_TwoLevelMatlabFactory_def.hpp"
162 #include "../matlab/src/MueLu_MatlabSmoother_decl.hpp"
163 #include "../matlab/src/MueLu_MatlabSmoother_def.hpp"
164 #endif
165 
166 #ifdef HAVE_MUELU_INTREPID2
167 #include "MueLu_IntrepidPCoarsenFactory.hpp"
168 #endif
169 
170 namespace MueLu {
171 
178  template <class Scalar = double, class LocalOrdinal = int, class GlobalOrdinal = LocalOrdinal, class Node = KokkosClassic::DefaultNode::DefaultNodeType>
179  class FactoryFactory : public BaseClass {
180 #undef MUELU_FACTORYFACTORY_SHORT
181 #include "MueLu_UseShortNames.hpp"
182 
183  typedef std::map<std::string, RCP<const FactoryBase> > FactoryMap; // TODO: remove
184  typedef std::map<std::string, RCP<FactoryManagerBase> > FactoryManagerMap;
185 
186  public:
187 
205  virtual RCP<const FactoryBase> BuildFactory(const Teuchos::ParameterEntry& param, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
206  // Find factory
207  std::string factoryName;
208  Teuchos::ParameterList paramList;
209  if (!param.isList()) {
210  factoryName = Teuchos::getValue<std::string>(param);
211  } else {
212  paramList = Teuchos::getValue<Teuchos::ParameterList>(param);
213  factoryName = paramList.get<std::string>("factory");
214  }
215 
216  // TODO: see how Teko handles this (=> register factories).
217  if (factoryName == "AggregationExportFactory") return Build2<AggregationExportFactory> (paramList, factoryMapIn, factoryManagersIn);
218  if (factoryName == "AmalgamationFactory") return Build2<AmalgamationFactory> (paramList, factoryMapIn, factoryManagersIn);
219  if (factoryName == "BlockedCoarseMapFactory") return Build2<BlockedCoarseMapFactory> (paramList, factoryMapIn, factoryManagersIn);
220  if (factoryName == "BlockedCoordinatesTransferFactory") return Build2<BlockedCoordinatesTransferFactory> (paramList, factoryMapIn, factoryManagersIn);
221  if (factoryName == "BlockedRAPFactory") return BuildRAPFactory<BlockedRAPFactory> (paramList, factoryMapIn, factoryManagersIn);
222  if (factoryName == "BrickAggregationFactory") return Build2<BrickAggregationFactory> (paramList, factoryMapIn, factoryManagersIn);
223  if (factoryName == "CloneRepartitionInterface") return Build2<CloneRepartitionInterface> (paramList, factoryMapIn, factoryManagersIn);
224  if (factoryName == "CoarseMapFactory") return Build2<CoarseMapFactory> (paramList, factoryMapIn, factoryManagersIn);
225  if (factoryName == "CoarseningVisualizationFactory") return Build2<CoarseningVisualizationFactory> (paramList, factoryMapIn, factoryManagersIn);
226  if (factoryName == "CoalesceDropFactory") return Build2<CoalesceDropFactory> (paramList, factoryMapIn, factoryManagersIn);
227  if (factoryName == "ConstraintFactory") return Build2<ConstraintFactory> (paramList, factoryMapIn, factoryManagersIn);
228  if (factoryName == "CoupledAggregationFactory") return BuildCoupledAggregationFactory (paramList, factoryMapIn, factoryManagersIn);
229  if (factoryName == "CoordinatesTransferFactory") return Build2<CoordinatesTransferFactory> (paramList, factoryMapIn, factoryManagersIn);
230  if (factoryName == "DirectSolver") return BuildDirectSolver (paramList, factoryMapIn, factoryManagersIn);
231  if (factoryName == "DropNegativeEntriesFactory") return Build2<DropNegativeEntriesFactory> (paramList, factoryMapIn, factoryManagersIn);
232  if (factoryName == "EminPFactory") return Build2<EminPFactory> (paramList, factoryMapIn, factoryManagersIn);
233  if (factoryName == "FilteredAFactory") return Build2<FilteredAFactory> (paramList, factoryMapIn, factoryManagersIn);
234  if (factoryName == "FineLevelInputDataFactory") return Build2<FineLevelInputDataFactory> (paramList, factoryMapIn, factoryManagersIn);
235  if (factoryName == "GeneralGeometricPFactory") return Build2<GeneralGeometricPFactory> (paramList, factoryMapIn, factoryManagersIn);
236  if (factoryName == "GenericRFactory") return Build2<GenericRFactory> (paramList, factoryMapIn, factoryManagersIn);
237  if (factoryName == "GeometricInterpolationPFactory") return Build2<GeometricInterpolationPFactory> (paramList, factoryMapIn, factoryManagersIn);
238  if (factoryName == "LineDetectionFactory") return Build2<LineDetectionFactory> (paramList, factoryMapIn, factoryManagersIn);
239  if (factoryName == "MapTransferFactory") return Build2<MapTransferFactory> (paramList, factoryMapIn, factoryManagersIn);
240  if (factoryName == "MatrixAnalysisFactory") return Build2<MatrixAnalysisFactory> (paramList, factoryMapIn, factoryManagersIn);
241  if (factoryName == "MultiVectorTransferFactory") return Build2<MultiVectorTransferFactory> (paramList, factoryMapIn, factoryManagersIn);
242  if (factoryName == "NoFactory") return MueLu::NoFactory::getRCP();
243  if (factoryName == "NoSmoother") return rcp(new SmootherFactory(Teuchos::null));
244  if (factoryName == "NullspaceFactory") return Build2<NullspaceFactory> (paramList, factoryMapIn, factoryManagersIn);
245  if (factoryName == "NullspacePresmoothFactory") return Build2<NullspacePresmoothFactory> (paramList, factoryMapIn, factoryManagersIn);
246  if (factoryName == "PatternFactory") return Build2<PatternFactory> (paramList, factoryMapIn, factoryManagersIn);
247  if (factoryName == "PgPFactory") return Build2<PgPFactory> (paramList, factoryMapIn, factoryManagersIn);
248  if (factoryName == "SaPFactory") return Build2<SaPFactory> (paramList, factoryMapIn, factoryManagersIn);
249  if (factoryName == "RAPFactory") return BuildRAPFactory<RAPFactory> (paramList, factoryMapIn, factoryManagersIn);
250  if (factoryName == "RAPShiftFactory") return BuildRAPFactory<RAPShiftFactory> (paramList, factoryMapIn, factoryManagersIn);
251  if (factoryName == "RebalanceAcFactory") return Build2<RebalanceAcFactory> (paramList, factoryMapIn, factoryManagersIn);
252  if (factoryName == "RebalanceTransferFactory") return Build2<RebalanceTransferFactory> (paramList, factoryMapIn, factoryManagersIn);
253  if (factoryName == "ReorderBlockAFactory") return Build2<ReorderBlockAFactory> (paramList, factoryMapIn, factoryManagersIn);
254  if (factoryName == "RepartitionInterface") return Build2<RepartitionInterface> (paramList, factoryMapIn, factoryManagersIn);
255  if (factoryName == "SegregatedAFactory") return Build2<SegregatedAFactory> (paramList, factoryMapIn, factoryManagersIn);
256  if (factoryName == "SemiCoarsenPFactory") return Build2<SemiCoarsenPFactory> (paramList, factoryMapIn, factoryManagersIn);
257  if (factoryName == "StructuredAggregationFactory") return Build2<StructuredAggregationFactory> (paramList, factoryMapIn, factoryManagersIn);
258  if (factoryName == "StructuredLineDetectionFactory") return Build2<StructuredLineDetectionFactory> (paramList, factoryMapIn, factoryManagersIn);
259  if (factoryName == "SubBlockAFactory") return Build2<SubBlockAFactory> (paramList, factoryMapIn, factoryManagersIn);
260  if (factoryName == "TentativePFactory") return Build2<TentativePFactory> (paramList, factoryMapIn, factoryManagersIn);
261  if (factoryName == "ToggleCoordinatesTransferFactory") return BuildToggleCoordinatesTransferFactory (paramList, factoryMapIn, factoryManagersIn);
262  if (factoryName == "TogglePFactory") return BuildTogglePFactory<TogglePFactory> (paramList, factoryMapIn, factoryManagersIn);
263  if (factoryName == "TransPFactory") return Build2<TransPFactory> (paramList, factoryMapIn, factoryManagersIn);
264  if (factoryName == "TrilinosSmoother") return BuildTrilinosSmoother (paramList, factoryMapIn, factoryManagersIn);
265  if (factoryName == "UncoupledAggregationFactory") return Build2<UncoupledAggregationFactory> (paramList, factoryMapIn, factoryManagersIn);
266  if (factoryName == "HybridAggregationFactory") return Build2<HybridAggregationFactory> (paramList, factoryMapIn, factoryManagersIn);
267  if (factoryName == "UnsmooshFactory") return Build2<UnsmooshFactory> (paramList, factoryMapIn, factoryManagersIn);
268  if (factoryName == "UserAggregationFactory") return Build2<UserAggregationFactory> (paramList, factoryMapIn, factoryManagersIn);
269  if (factoryName == "UserPFactory") return Build2<UserPFactory> (paramList, factoryMapIn, factoryManagersIn);
270  if (factoryName == "VariableDofLaplacianFactory") return Build2<VariableDofLaplacianFactory> (paramList, factoryMapIn, factoryManagersIn);
271 #ifdef HAVE_MUELU_KOKKOS_REFACTOR
272  if (factoryName == "CoalesceDropFactory_kokkos") return Build2<CoalesceDropFactory_kokkos> (paramList, factoryMapIn, factoryManagersIn);
273  if (factoryName == "CoarseMapFactory_kokkos") return Build2<CoarseMapFactory_kokkos> (paramList, factoryMapIn, factoryManagersIn);
274  if (factoryName == "CoordinatesTransferFactory_kokkos") return Build2<CoordinatesTransferFactory_kokkos> (paramList, factoryMapIn, factoryManagersIn);
275  if (factoryName == "NullspaceFactory_kokkos") return Build2<NullspaceFactory_kokkos> (paramList, factoryMapIn, factoryManagersIn);
276  if (factoryName == "SaPFactory_kokkos") return Build2<SaPFactory_kokkos> (paramList, factoryMapIn, factoryManagersIn);
277  if (factoryName == "TentativePFactory_kokkos") return Build2<TentativePFactory_kokkos> (paramList, factoryMapIn, factoryManagersIn);
278  if (factoryName == "UncoupledAggregationFactory_kokkos") return Build2<UncoupledAggregationFactory_kokkos> (paramList, factoryMapIn, factoryManagersIn);
279 #endif
280 
281  if (factoryName == "ZoltanInterface") {
282 #if defined(HAVE_MUELU_ZOLTAN) && defined(HAVE_MPI)
283  return Build2<ZoltanInterface>(paramList, factoryMapIn, factoryManagersIn);
284 #else
285  TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, "MueLu::FactoryFactory:BuildFactory(): Cannot create a ZoltanInterface object: Zoltan is disabled: HAVE_MUELU_ZOLTAN && HAVE_MPI == false.");
286 #endif // HAVE_MUELU_ZOLTAN && HAVE_MPI
287  }
288  if (factoryName == "Zoltan2Interface") {
289 #if defined(HAVE_MUELU_ZOLTAN2) && defined(HAVE_MPI)
290  return Build2<Zoltan2Interface>(paramList, factoryMapIn, factoryManagersIn);
291 #else
292  TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, "MueLu::FactoryFactory:BuildFactory(): Cannot create a Zoltan2Interface object: Zoltan2 is disabled: HAVE_MUELU_ZOLTAN2 && HAVE_MPI == false.");
293 #endif // HAVE_MUELU_ZOLTAN2 && HAVE_MPI
294  }
295  if (factoryName == "IsorropiaInterface") {
296 #if defined(HAVE_MUELU_ISORROPIA) && defined(HAVE_MPI)
297  return Build2<IsorropiaInterface>(paramList, factoryMapIn, factoryManagersIn);
298 #else
299  TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, "MueLu::FactoryFactory:BuildFactory(): Cannot create a IsorropiaInterface object: Isorropia is disabled: HAVE_MUELU_ISORROPIA && HAVE_MPI == false.");
300 #endif // HAVE_MUELU_ZOLTAN2 && HAVE_MPI
301  }
302 
303  if (factoryName == "RepartitionFactory") {
304 #ifdef HAVE_MPI
305  return Build2<RepartitionFactory>(paramList, factoryMapIn, factoryManagersIn);
306 #else
307  TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, "MueLu::FactoryFactory:BuildFactory(): Cannot create a RepartitionFactory object: HAVE_MPI == false.");
308 #endif // HAVE_MPI
309  }
310  if (factoryName == "RepartitionHeuristicFactory") {
311 #ifdef HAVE_MPI
312  return Build2<RepartitionHeuristicFactory>(paramList, factoryMapIn, factoryManagersIn);
313 #else
314  TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, "MueLu::FactoryFactory:BuildFactory(): Cannot create a RepartitionHeuristicFactory object: HAVE_MPI == false.");
315 #endif // HAVE_MPI
316  }
317  // Blocked factories
318  if (factoryName == "BlockedDirectSolver") return BuildBlockedDirectSolver(paramList, factoryMapIn, factoryManagersIn);
319  if (factoryName == "BlockedGaussSeidelSmoother") return BuildBlockedSmoother<BlockedGaussSeidelSmoother>(paramList, factoryMapIn, factoryManagersIn);
320  if (factoryName == "BlockedJacobiSmoother") return BuildBlockedSmoother<BlockedJacobiSmoother>(paramList, factoryMapIn, factoryManagersIn);
321  if (factoryName == "BlockedPFactory") return BuildBlockedFactory<BlockedPFactory>(paramList, factoryMapIn, factoryManagersIn);
322  if (factoryName == "BraessSarazinSmoother") return BuildBlockedSmoother<BraessSarazinSmoother>(paramList, factoryMapIn, factoryManagersIn);
323  if (factoryName == "IndefiniteBlockDiagonalSmoother") return BuildBlockedSmoother<IndefBlockedDiagonalSmoother>(paramList, factoryMapIn, factoryManagersIn);
324  if (factoryName == "SimpleSmoother") return BuildBlockedSmoother<SimpleSmoother>(paramList, factoryMapIn, factoryManagersIn);
325  if (factoryName == "SchurComplementFactory") return Build2<SchurComplementFactory> (paramList, factoryMapIn, factoryManagersIn);
326  if (factoryName == "RebalanceBlockRestrictionFactory")return BuildBlockedFactory<RebalanceBlockRestrictionFactory>(paramList, factoryMapIn, factoryManagersIn);
327  if (factoryName == "RebalanceBlockAcFactory") return BuildBlockedFactory<RebalanceBlockAcFactory>(paramList, factoryMapIn, factoryManagersIn);
328  if (factoryName == "RebalanceBlockInterpolationFactory") return BuildBlockedFactory<RebalanceBlockInterpolationFactory>(paramList, factoryMapIn, factoryManagersIn);
329 #ifdef HAVE_MPI
330  if (factoryName == "RepartitionBlockDiagonalFactory") return Build2<RepartitionBlockDiagonalFactory> (paramList, factoryMapIn, factoryManagersIn);
331 #endif
332 #ifdef HAVE_MUELU_TEKO
333  if (factoryName == "TekoSmoother") return BuildTekoSmoother(paramList, factoryMapIn, factoryManagersIn);
334 #endif
335  if (factoryName == "UzawaSmoother") return BuildBlockedSmoother<UzawaSmoother>(paramList, factoryMapIn, factoryManagersIn);
336 
337  // Matlab factories
338 #ifdef HAVE_MUELU_MATLAB
339  if (factoryName == "TwoLevelMatlabFactory") return Build2<TwoLevelMatlabFactory> (paramList, factoryMapIn, factoryManagersIn);
340  if (factoryName == "SingleLevelMatlabFactory") return Build2<SingleLevelMatlabFactory> (paramList, factoryMapIn, factoryManagersIn);
341  if (factoryName == "MatlabSmoother") return BuildMatlabSmoother (paramList, factoryMapIn, factoryManagersIn);
342 #endif
343 
344 #ifdef HAVE_MUELU_INTREPID2
345  if (factoryName == "IntrepidPCoarsenFactory") return Build2<IntrepidPCoarsenFactory> (paramList, factoryMapIn, factoryManagersIn);
346 #endif
347 
348  // Use a user defined factories (in <Factories> node)
349  if (factoryMapIn.find(factoryName) != factoryMapIn.end()) {
350  TEUCHOS_TEST_FOR_EXCEPTION((param.isList() && (++paramList.begin() != paramList.end())), Exceptions::RuntimeError,
351  "MueLu::FactoryFactory: Error during the parsing of: " << std::endl << paramList << std::endl
352  << "'" << factoryName << "' is not a factory name but an existing instance of a factory." << std::endl
353  << "Extra parameters cannot be specified after the creation of the object." << std::endl << std::endl
354  << "Correct syntaxes includes:" << std::endl
355  << " <Parameter name=\"...\" type=\"string\" value=\"" << factoryName << "\"/>" << std::endl
356  << "or" << std::endl
357  << " <ParameterList name=\"...\"><Parameter name=\"factory\" type=\"string\" value=\"" << factoryName << "\"/></ParameterList>" << std::endl
358  );
359 
360  return factoryMapIn.find(factoryName)->second;
361  }
362 
363  TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, "MueLu::FactoryFactory: unknown factory name : " << factoryName);
364 
365  TEUCHOS_UNREACHABLE_RETURN(Teuchos::null);
366  }
367 
368  //
369  //
370  //
371 
372  // FOLLOWING FUNCTIONS SHOULD LIVE WITH THE CORRESPONDING CLASS
373 
374  //
375  //
376  //
377 
378 #define arraysize(ar) (sizeof(ar) / sizeof(ar[0]))
379 
380  template <class T> // T must implement the Factory interface
381  RCP<T> Build(const Teuchos::ParameterList& paramList, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
382  RCP<T> factory = rcp(new T());
383 
384  const char* strarray[] = {"A", "P", "R", "Graph", "UnAmalgamationInfo", "Aggregates", "Nullspace", "TransferFactory", "DofsPerNode"};
385  std::vector<std::string> v(strarray, strarray + arraysize(strarray));
386  for (size_t i = 0; i < v.size(); ++i)
387  if (paramList.isParameter(v[i]))
388  factory->SetFactory(v[i], BuildFactory(paramList.getEntry(v[i]), factoryMapIn, factoryManagersIn));
389 
390  return factory;
391  }
392 
393  template <class T> // T must implement the Factory interface
394  RCP<T> Build2(const Teuchos::ParameterList& paramList, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
395  RCP<T> factory = rcp(new T());
396 
397  ParameterList paramListWithFactories;
398 
399  // Read the RCP<Factory> parameters of the class T
400  RCP<const ParameterList> validParamList = factory->GetValidParameterList(); // TODO check for Teuchos::null (no parameter list validation)
401  TEUCHOS_TEST_FOR_EXCEPTION(validParamList == Teuchos::null, Exceptions::RuntimeError, "FactoryFactory::Build2: default parameter list is null. Please fix this.");
402  for (ParameterList::ConstIterator param = validParamList->begin(); param != validParamList->end(); ++param) {
403  const std::string& pName = validParamList->name(param);
404 
405  if (!paramList.isParameter(pName)) {
406  // Ignore unknown parameters
407  continue;
408  }
409 
410  if (validParamList->isType< RCP<const FactoryBase> >(pName)) {
411  // Generate or get factory described by param
412  RCP<const FactoryBase> generatingFact = BuildFactory(paramList.getEntry(pName), factoryMapIn, factoryManagersIn);
413  paramListWithFactories.set(pName, generatingFact);
414  } else if (validParamList->isType<RCP<const ParameterList> >(pName)) {
415  if (pName == "ParameterList") {
416  // NOTE: we cannot use
417  // subList = sublist(rcpFromRef(paramList), pName)
418  // here as that would result in sublist also being a reference to a temporary object.
419  // The resulting dereferencing in the corresponding factory would then segfault
420  RCP<const ParameterList> subList = Teuchos::sublist(rcp(new ParameterList(paramList)), pName);
421  paramListWithFactories.set(pName, subList);
422  }
423  } else {
424  paramListWithFactories.setEntry(pName, paramList.getEntry(pName));
425  }
426  }
427 
428  // Configure the factory
429  factory->SetParameterList(paramListWithFactories);
430 
431  return factory;
432  }
433 
434  template <class T> // T must implement the Factory interface
435  RCP<T> BuildRAPFactory(const Teuchos::ParameterList & paramList, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
436  RCP<T> factory;
437  if (paramList.isSublist("TransferFactories") == false) {
438  factory = Build2<T>(paramList, factoryMapIn, factoryManagersIn);
439 
440  } else {
441  RCP<Teuchos::ParameterList> paramListNonConst = rcp(new Teuchos::ParameterList(paramList));
442  RCP<const Teuchos::ParameterList> transferFactories = rcp(new Teuchos::ParameterList(*sublist(paramListNonConst, "TransferFactories")));
443 
444  paramListNonConst->remove("TransferFactories");
445 
446  factory = Build2<T>(*paramListNonConst, factoryMapIn, factoryManagersIn);
447 
448  for (Teuchos::ParameterList::ConstIterator param = transferFactories->begin(); param != transferFactories->end(); ++param) {
449  RCP<const FactoryBase> p = BuildFactory(transferFactories->entry(param), factoryMapIn, factoryManagersIn);
450  factory->AddTransferFactory(p);
451  }
452  }
453 
454  return factory;
455  }
456 
457  template <class T> // T must implement the Factory interface
458  RCP<T> BuildTogglePFactory(const Teuchos::ParameterList & paramList, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
459  RCP<T> factory;
460  if (paramList.isSublist("TransferFactories") == false) {
461  //TODO put in an error message: the TogglePFactory needs a TransferFactories sublist!
462  factory = Build2<T>(paramList, factoryMapIn, factoryManagersIn);
463 
464  } else {
465  RCP<Teuchos::ParameterList> paramListNonConst = rcp(new Teuchos::ParameterList(paramList));
466  RCP<const Teuchos::ParameterList> transferFactories = rcp(new Teuchos::ParameterList(*sublist(paramListNonConst, "TransferFactories")));
467 
468  paramListNonConst->remove("TransferFactories");
469 
470  // build TogglePFactory
471  factory = Build2<T>(*paramListNonConst, factoryMapIn, factoryManagersIn);
472 
473  // count how many prolongation factories and how many coarse null space factories have been declared.
474  // the numbers must match!
475  int numProlongatorFactories = 0;
476  int numPtentFactories = 0;
477  int numCoarseNspFactories = 0;
478  for (Teuchos::ParameterList::ConstIterator param = transferFactories->begin(); param != transferFactories->end(); ++param) {
479  size_t foundNsp = transferFactories->name(param).find("Nullspace");
480  if (foundNsp != std::string::npos && foundNsp == 0 && transferFactories->name(param).length()==10) {
481  numCoarseNspFactories++;
482  continue;
483  }
484  size_t foundPtent = transferFactories->name(param).find("Ptent");
485  if (foundPtent != std::string::npos && foundPtent == 0 && transferFactories->name(param).length()==6) {
486  numPtentFactories++;
487  continue;
488  }
489  size_t foundP = transferFactories->name(param).find("P");
490  if (foundP != std::string::npos && foundP == 0 && transferFactories->name(param).length()==2) {
491  numProlongatorFactories++;
492  continue;
493  }
494  }
495  TEUCHOS_TEST_FOR_EXCEPTION(numProlongatorFactories!=numCoarseNspFactories, Exceptions::RuntimeError, "FactoryFactory::BuildToggleP: The user has to provide the same number of prolongator and coarse nullspace factories!");
496  TEUCHOS_TEST_FOR_EXCEPTION(numPtentFactories!=numCoarseNspFactories, Exceptions::RuntimeError, "FactoryFactory::BuildToggleP: The user has to provide the same number of ptent and coarse nullspace factories!");
497  TEUCHOS_TEST_FOR_EXCEPTION(numProlongatorFactories < 2, Exceptions::RuntimeError, "FactoryFactory::BuildToggleP: The TogglePFactory needs at least two different prolongation operators. The factories have to be provided using the names P%i and Nullspace %i, where %i denotes a number between 1 and 9.");
498 
499  // create empty vectors with data
500  std::vector<Teuchos::ParameterEntry> prolongatorFactoryNames(numProlongatorFactories);
501  std::vector<Teuchos::ParameterEntry> coarseNspFactoryNames(numProlongatorFactories);
502  std::vector<Teuchos::ParameterEntry> ptentFactoryNames(numProlongatorFactories);
503 
504  for (Teuchos::ParameterList::ConstIterator param = transferFactories->begin(); param != transferFactories->end(); ++param) {
505  size_t foundNsp = transferFactories->name(param).find("Nullspace");
506  if (foundNsp != std::string::npos && foundNsp == 0 && transferFactories->name(param).length()==10) {
507  int number = atoi(&(transferFactories->name(param).at(9)));
508  TEUCHOS_TEST_FOR_EXCEPTION(number < 1 || number > numProlongatorFactories, Exceptions::RuntimeError, "FactoryFactory::BuildToggleP: Please use the format Nullspace%i with %i an integer between 1 and the maximum number of prolongation operators in TogglePFactory!");
509  coarseNspFactoryNames[number-1] = transferFactories->entry(param);
510  continue;
511  }
512  size_t foundPtent = transferFactories->name(param).find("Ptent");
513  if (foundPtent != std::string::npos && foundPtent == 0 && transferFactories->name(param).length()==6) {
514  int number = atoi(&(transferFactories->name(param).at(5)));
515  TEUCHOS_TEST_FOR_EXCEPTION(number < 1 || number > numPtentFactories, Exceptions::RuntimeError, "FactoryFactory::BuildToggleP: Please use the format Ptent%i with %i an integer between 1 and the maximum number of prolongation operators in TogglePFactory!");
516  ptentFactoryNames[number-1] = transferFactories->entry(param);
517  continue;
518  }
519  size_t foundP = transferFactories->name(param).find("P");
520  if (foundP != std::string::npos && foundP == 0 && transferFactories->name(param).length()==2) {
521  int number = atoi(&(transferFactories->name(param).at(1)));
522  TEUCHOS_TEST_FOR_EXCEPTION(number < 1 || number > numProlongatorFactories, Exceptions::RuntimeError, "FactoryFactory::BuildToggleP: Please use the format P%i with %i an integer between 1 and the maximum number of prolongation operators in TogglePFactory!");
523  prolongatorFactoryNames[number-1] = transferFactories->entry(param);
524  continue;
525  }
526  }
527 
528  // register all prolongation factories in TogglePFactory
529  for (std::vector<Teuchos::ParameterEntry>::const_iterator it = prolongatorFactoryNames.begin(); it != prolongatorFactoryNames.end(); ++it) {
530  RCP<const FactoryBase> p = BuildFactory(*it, factoryMapIn, factoryManagersIn);
531  factory->AddProlongatorFactory(p);
532  }
533 
534  // register all tentative prolongation factories in TogglePFactory
535  for (std::vector<Teuchos::ParameterEntry>::const_iterator it = ptentFactoryNames.begin(); it != ptentFactoryNames.end(); ++it) {
536  RCP<const FactoryBase> p = BuildFactory(*it, factoryMapIn, factoryManagersIn);
537  factory->AddPtentFactory(p);
538  }
539 
540  // register all coarse nullspace factories in TogglePFactory
541  for (std::vector<Teuchos::ParameterEntry>::const_iterator it = coarseNspFactoryNames.begin(); it != coarseNspFactoryNames.end(); ++it) {
542  RCP<const FactoryBase> p = BuildFactory(*it, factoryMapIn, factoryManagersIn);
543  factory->AddCoarseNullspaceFactory(p);
544  }
545  }
546  return factory;
547  }
548 
549  RCP<ToggleCoordinatesTransferFactory> BuildToggleCoordinatesTransferFactory(const Teuchos::ParameterList & paramList, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
550  RCP<ToggleCoordinatesTransferFactory> factory;
551  TEUCHOS_TEST_FOR_EXCEPTION(paramList.isSublist("TransferFactories") == false, Exceptions::RuntimeError, "FactoryFactory::BuildToggleCoordinatesTransferFactory: the ToggleCoordinatesTransferFactory needs a sublist 'TransferFactories' containing information about the subfactories for coordinate transfer!");
552 
553  RCP<Teuchos::ParameterList> paramListNonConst = rcp(new Teuchos::ParameterList(paramList));
554  RCP<const Teuchos::ParameterList> transferFactories = rcp(new Teuchos::ParameterList(*sublist(paramListNonConst, "TransferFactories")));
555  paramListNonConst->remove("TransferFactories");
556 
557  // build CoordinatesTransferFactory
558  factory = Build2<ToggleCoordinatesTransferFactory>(*paramListNonConst, factoryMapIn, factoryManagersIn);
559 
560  // count how many coordinate transfer factories have been declared.
561  // the numbers must match!
562  int numCoordTransferFactories = 0;
563  for (Teuchos::ParameterList::ConstIterator param = transferFactories->begin(); param != transferFactories->end(); ++param) {
564  size_t foundCoordinates = transferFactories->name(param).find("Coordinates");
565  if (foundCoordinates != std::string::npos && foundCoordinates == 0 && transferFactories->name(param).length()==12) {
566  numCoordTransferFactories++;
567  continue;
568  }
569  }
570  TEUCHOS_TEST_FOR_EXCEPTION(numCoordTransferFactories != 2, Exceptions::RuntimeError, "FactoryFactory::BuildToggleCoordinatesTransfer: The ToggleCoordinatesTransferFactory needs two (different) coordinate transfer factories. The factories have to be provided using the names Coordinates%i, where %i denotes a number between 1 and 9.");
571 
572  // create empty vectors with data
573  std::vector<Teuchos::ParameterEntry> coarseCoordsFactoryNames(numCoordTransferFactories);
574 
575  for (Teuchos::ParameterList::ConstIterator param = transferFactories->begin(); param != transferFactories->end(); ++param) {
576  size_t foundCoords = transferFactories->name(param).find("Coordinates");
577  if (foundCoords != std::string::npos && foundCoords == 0 && transferFactories->name(param).length()==12) {
578  int number = atoi(&(transferFactories->name(param).at(11)));
579  TEUCHOS_TEST_FOR_EXCEPTION(number < 1 || number > numCoordTransferFactories, Exceptions::RuntimeError, "FactoryFactory::BuildToggleCoordinatesTransfer: Please use the format Coordinates%i with %i an integer between 1 and the maximum number of coordinate transfer factories in ToggleCoordinatesTransferFactory!");
580  coarseCoordsFactoryNames[number-1] = transferFactories->entry(param);
581  continue;
582  }
583  }
584 
585  // register all coarse nullspace factories in TogglePFactory
586  for (std::vector<Teuchos::ParameterEntry>::const_iterator it = coarseCoordsFactoryNames.begin(); it != coarseCoordsFactoryNames.end(); ++it) {
587  RCP<const FactoryBase> p = BuildFactory(*it, factoryMapIn, factoryManagersIn);
588  factory->AddCoordTransferFactory(p);
589  }
590 
591  return factory;
592  }
593 
595  RCP<FactoryBase> BuildCoupledAggregationFactory(const Teuchos::ParameterList& paramList, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
596  RCP<CoupledAggregationFactory> factory = Build<CoupledAggregationFactory>(paramList, factoryMapIn, factoryManagersIn);
597 
598  if (paramList.isParameter("aggregation: ordering"))
599  factory->SetOrdering(paramList.get<std::string>("aggregation: ordering"));
600 
601  if (paramList.isParameter("aggregation: max selected neighbors"))
602  factory->SetMaxNeighAlreadySelected(paramList.get<int>("aggregation: max selected neighbors"));
603 
604  if (paramList.isParameter("Phase3AggCreation"))
605  factory->SetPhase3AggCreation(paramList.get<double>("Phase3AggCreation"));
606 
607  if(paramList.isParameter("aggregation: min agg size"))
608  factory->SetMinNodesPerAggregate(paramList.get<int>("aggregation: min agg size"));
609 
610  return factory;
611  }
612 
614  // Parameter List Parsing:
615  // <ParameterList name="smootherFact1">
616  // <Parameter name="factory" type="string" value="TrilinosSmoother"/>
617  // <Parameter name="verbose" type="string" value="Warnings"/>
618  // <Parameter name="type" type="string" value="RELAXATION"/>
619  // <ParameterList name="ParameterList">
620  // ...
621  // </ParameterList>
622  // </ParameterList>
623  RCP<FactoryBase> BuildTrilinosSmoother(const Teuchos::ParameterList & paramList, const FactoryMap & factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
624  if (paramList.begin() == paramList.end())
625  return rcp(new SmootherFactory(rcp(new TrilinosSmoother())));
626 
627  TEUCHOS_TEST_FOR_EXCEPTION(paramList.get<std::string>("factory") != "TrilinosSmoother", Exceptions::RuntimeError, "");
628 
629  // Is it true? TEUCHOS_TEST_FOR_EXCEPTION(!paramList.isParameter("type"), Exceptions::RuntimeError, "TrilinosSmoother: parameter 'type' is mandatory");
630  // type="" is default in TrilinosSmoother, but what happen then?
631 
632  std::string type=""; if(paramList.isParameter("type")) type = paramList.get<std::string>("type");
633  int overlap=0; if(paramList.isParameter("overlap")) overlap = paramList.get<int> ("overlap");
634  // std::string verbose; if(paramList.isParameter("verbose")) verbose = paramList.get<std::string>("verbose");
635  Teuchos::ParameterList params; if(paramList.isParameter("ParameterList")) params = paramList.get<Teuchos::ParameterList>("ParameterList");
636 
637  // parameters from SmootherFactory
638  //bool bKeepSmootherData = false; if(paramList.isParameter("keep smoother data")) bKeepSmootherData = paramList.get<bool>("keep smoother data");
639 
640  // Read in factory information for smoothers (if available...)
641  // NOTE: only a selected number of factories can be used with the Trilinos smoother
642  // smoothers usually work with the global data available (which is A and the transfers P and R)
643 
644  Teuchos::RCP<TrilinosSmoother> trilSmoo = Teuchos::rcp(new TrilinosSmoother(type, params, overlap));
645 
646  if (paramList.isParameter("LineDetection_Layers")) {
647  RCP<const FactoryBase> generatingFact = BuildFactory(paramList.getEntry("LineDetection_Layers"), factoryMapIn, factoryManagersIn);
648  trilSmoo->SetFactory("LineDetection_Layers", generatingFact);
649  }
650  if (paramList.isParameter("LineDetection_VertLineIds")) {
651  RCP<const FactoryBase> generatingFact = BuildFactory(paramList.getEntry("LineDetection_Layers"), factoryMapIn, factoryManagersIn);
652  trilSmoo->SetFactory("LineDetection_Layers", generatingFact);
653  }
654  if (paramList.isParameter("CoarseNumZLayers")) {
655  RCP<const FactoryBase> generatingFact = BuildFactory(paramList.getEntry("CoarseNumZLayers"), factoryMapIn, factoryManagersIn);
656  trilSmoo->SetFactory("CoarseNumZLayers", generatingFact);
657  }
658 
659  RCP<SmootherFactory> smooFact = rcp(new SmootherFactory(Teuchos::null));
660  Teuchos::ParameterList smooFactParams;
661  //smooFactParams.setEntry("keep smoother data", paramList.getEntry("keep smoother data"));
662  smooFact->SetParameterList(smooFactParams);
663  smooFact->SetSmootherPrototypes(trilSmoo);
664  return smooFact;
665  }
666 
667 #ifdef HAVE_MUELU_MATLAB
668  // Parameter List Parsing:
670  // <ParameterList name="smootherFact1">
671  // <Parameter name="factory" type="string" value="MatlabSmoother"/>
672  // <Parameter name="Setup Function" type="string" value="mySmootherSetup.m"/>
673  // <Parameter name="Solve Function" type="string" value="mySmootherSolve.m"/>
674  // <!--A is implicitly included in this list and nothing else is needed to get diagonal-->
675  // <Parameter name="Needs" type="string" value=""/>
676  // <!--A,x,b are also assumed inputs to the solver: only one additional arg then (diag)-->
677  // <Parameter name="Number of Solver Args" type="int" value="1"/>
678  // </ParameterList>
679  RCP<FactoryBase> BuildMatlabSmoother(const Teuchos::ParameterList & paramList, const FactoryMap & factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
680  if (paramList.begin() == paramList.end())
681  return rcp(new SmootherFactory(rcp(new MatlabSmoother())));
682 
683  TEUCHOS_TEST_FOR_EXCEPTION(paramList.get<std::string>("factory") != "MatlabSmoother", Exceptions::RuntimeError, "");
684 
685  // Read in factory information for smoothers (if available...)
686  // NOTE: only a selected number of factories can be used with the Trilinos smoother
687  // smoothers usually work with the global data available (which is A and the transfers P and R)
688 
689  Teuchos::RCP<MatlabSmoother> matSmoo = Teuchos::rcp(new MatlabSmoother(paramList));
690 
691  return rcp(new SmootherFactory(matSmoo));
692  }
693 #endif
694 
695  RCP<FactoryBase> BuildDirectSolver(const Teuchos::ParameterList& paramList, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
696  if (paramList.begin() == paramList.end())
697  return rcp(new SmootherFactory(rcp(new DirectSolver()), Teuchos::null));
698 
699  TEUCHOS_TEST_FOR_EXCEPTION(paramList.get<std::string>("factory") != "DirectSolver", Exceptions::RuntimeError, "");
700 
701  std::string type; if(paramList.isParameter("type")) type = paramList.get<std::string>("type");
702  // std::string verbose; if(paramList.isParameter("verbose")) verbose = paramList.get<std::string>("verbose");
703  Teuchos::ParameterList params; if(paramList.isParameter("ParameterList")) params = paramList.get<Teuchos::ParameterList>("ParameterList");
704 
705  return rcp(new SmootherFactory(rcp(new DirectSolver(type, params)), Teuchos::null));
706  }
707 
708  template <class T> // T must implement the Factory interface
709  RCP<FactoryBase> BuildBlockedSmoother(const Teuchos::ParameterList& paramList, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
710  // read in sub lists
711  RCP<ParameterList> paramListNonConst = rcp(new ParameterList(paramList));
712 
713  // internal vector of factory managers
714  std::vector<RCP<FactoryManager> > facManagers;
715 
716  // loop over all "block%i" sublists in parameter list
717  int blockid = 1;
718  bool blockExists = true;
719  while (blockExists == true) {
720  std::stringstream ss;
721  ss << "block" << blockid;
722 
723  if(paramList.isSublist(ss.str()) == true) {
724  // we either have a parameter group or we have a list of factories in here
725  RCP<const ParameterList> b = rcp(new ParameterList(*sublist(paramListNonConst, ss.str())));
726 
727  RCP<FactoryManager> M = Teuchos::null;
728 
729  if (b->isParameter("group")) {
730  // use a factory manager
731  std::string facManagerName = b->get< std::string >("group");
732  TEUCHOS_TEST_FOR_EXCEPTION(factoryManagersIn.count(facManagerName) != 1, Exceptions::RuntimeError, "Factory manager has not been found. Please check the spelling of the factory managers in your xml file.");
733  RCP<FactoryManagerBase> Mb = factoryManagersIn.find(facManagerName)->second;
734  M = Teuchos::rcp_dynamic_cast<FactoryManager>(Mb);
735  TEUCHOS_TEST_FOR_EXCEPTION(M==Teuchos::null, Exceptions::RuntimeError, "Failed to cast FactoryManagerBase object to FactoryManager.");
736  } else {
737  // read in the list of factories
738  M = rcp(new FactoryManager());
739  for (ParameterList::ConstIterator param = b->begin(); param != b->end(); ++param) {
740  RCP<const FactoryBase> p = BuildFactory(b->entry(param), factoryMapIn, factoryManagersIn);
741  M->SetFactory(b->name(param),p);
742  }
743  }
744 
745  // add factory manager to internal vector of factory managers
746  M->SetIgnoreUserData(true);
747  facManagers.push_back(M);
748  paramListNonConst->remove(ss.str());
749  blockid++;
750  } else {
751  blockExists = false;
752  break;
753  }
754 
755  }
756 
757  // create a new blocked smoother
758  RCP<T> bs = Build2<T>(*paramListNonConst, factoryMapIn, factoryManagersIn);
759 
760  // important: set block factory for A here!
761  // TAW: 7/6/2016: We should not need to set/hardcode the blocked operator here.
762  // The user might want to overwrite this in the xml file, so just
763  // use what is declared as "A"
764  //bs->SetFactory("A", MueLu::NoFactory::getRCP());
765 
766  for (int i = 0; i<Teuchos::as<int>(facManagers.size()); i++) {
767  bs->AddFactoryManager(facManagers[i],i);
768  }
769 
770  return rcp(new SmootherFactory(bs));
771  }
772 
773 #ifdef HAVE_MUELU_TEKO
774  RCP<FactoryBase> BuildTekoSmoother(const Teuchos::ParameterList& paramList, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
775  // read in sub lists
776  RCP<ParameterList> paramListNonConst = rcp(new ParameterList(paramList));
777  RCP<ParameterList> tekoParams = rcp(new ParameterList(paramListNonConst->sublist("Inverse Factory Library")));
778  paramListNonConst->remove("Inverse Factory Library");
779 
780  // create a new blocked smoother
781  RCP<TekoSmoother> bs = Build2<TekoSmoother>(*paramListNonConst, factoryMapIn, factoryManagersIn);
782 
783  // important: set block factory for A here!
784  // TAW: 7/6/2016: We should not need to set/hardcode the blocked operator here.
785  // The user might want to overwrite this in the xml file, so just
786  // use what is declared as "A"
787  //bs->SetFactory("A", MueLu::NoFactory::getRCP());
788 
789  // Set Teko parameters ("Inverse Factory Library")
790  bs->SetTekoParameters(tekoParams);
791 
792  return rcp(new SmootherFactory(bs));
793  }
794 #endif
795 
796  RCP<FactoryBase> BuildBlockedDirectSolver(const Teuchos::ParameterList& paramList, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
797  //if (paramList.begin() == paramList.end())
798  return rcp(new SmootherFactory(rcp(new BlockedDirectSolver())));
799 
800  /*TEUCHOS_TEST_FOR_EXCEPTION(paramList.get<std::string>("factory") != "DirectSolver", Exceptions::RuntimeError, "");
801 
802  std::string type; if(paramList.isParameter("type")) type = paramList.get<std::string>("type");
803  // std::string verbose; if(paramList.isParameter("verbose")) verbose = paramList.get<std::string>("verbose");
804  Teuchos::ParameterList params; if(paramList.isParameter("ParameterList")) params = paramList.get<Teuchos::ParameterList>("ParameterList");
805 
806  return rcp(new SmootherFactory(rcp(new DirectSolver(type, params))));*/
807  }
808 
809  //RCP<FactoryBase> BuildBlockedPFactory(const Teuchos::ParameterList& paramList, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
810  // RCP<BlockedPFactory> pfac = rcp(new BlockedPFactory());
811 
812  template <class T> // T must implement the Factory interface
813  RCP<T> BuildBlockedFactory(const Teuchos::ParameterList & paramList, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
814  RCP<T> pfac = Teuchos::null;
815 
816  // read in sub lists
817  RCP<ParameterList> paramListNonConst = rcp(new ParameterList(paramList));
818 
819  // internal vector of factory managers
820  std::vector<RCP<FactoryManager> > facManagers;
821 
822  // loop over all "block%i" sublists in parameter list
823  int blockid = 1;
824  bool blockExists = true;
825  while (blockExists == true) {
826  std::stringstream ss;
827  ss << "block" << blockid;
828 
829  if(paramList.isSublist(ss.str()) == true) {
830  // we either have a parameter group or we have a list of factories in here
831  RCP<const ParameterList> b = rcp(new ParameterList(*sublist(paramListNonConst, ss.str())));
832 
833  RCP<FactoryManager> M = Teuchos::null;
834 
835  if (b->isParameter("group")) {
836  // use a factory manager
837  std::string facManagerName = b->get< std::string >("group");
838  TEUCHOS_TEST_FOR_EXCEPTION(factoryManagersIn.count(facManagerName) != 1, Exceptions::RuntimeError, "Factory manager has not been found. Please check the spelling of the factory managers in your xml file.");
839  RCP<FactoryManagerBase> Mb = factoryManagersIn.find(facManagerName)->second;
840  M = Teuchos::rcp_dynamic_cast<FactoryManager>(Mb);
841  TEUCHOS_TEST_FOR_EXCEPTION(M==Teuchos::null, Exceptions::RuntimeError, "Failed to cast FactoryManagerBase object to FactoryManager.");
842  } else {
843  // read in the list of factories
844  M = rcp(new FactoryManager());
845  for (ParameterList::ConstIterator param = b->begin(); param != b->end(); ++param) {
846  RCP<const FactoryBase> p = BuildFactory(b->entry(param), factoryMapIn, factoryManagersIn);
847  M->SetFactory(b->name(param),p);
848  }
849  }
850 
851  // add factory manager to internal vector of factory managers
852  M->SetIgnoreUserData(true);
853  facManagers.push_back(M);
854  paramListNonConst->remove(ss.str());
855  blockid++;
856  } else {
857  blockExists = false;
858  break;
859  }
860 
861  }
862 
863  // build BlockedPFactory (without sub block information)
864  pfac = Build2<T>(*paramListNonConst, factoryMapIn, factoryManagersIn);
865 
866  // add FactoryManager objects
867  for(size_t i = 0; i<facManagers.size(); i++) {
868  pfac->AddFactoryManager(facManagers[i]); // add factory manager
869  }
870 
871  return pfac;
872  }
873  }; // class
874 } // namespace MueLu
875 
876 #define MUELU_FACTORYFACTORY_SHORT
877 #endif // MUELU_FACTORYFACTORY_DECL_HPP
878 
879  // TODO: handle factory parameters
880  // TODO: parameter validator
881  // TODO: static
882  // TODO: default parameters should not be duplicated here and on the Factory (ex: default for overlap (=0) is defined both here and on TrilinosSmoother constructors)
RCP< FactoryBase > BuildMatlabSmoother(const Teuchos::ParameterList &paramList, const FactoryMap &factoryMapIn, const FactoryManagerMap &factoryManagersIn) const
MatlabSmoother.
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...
RCP< FactoryBase > BuildBlockedSmoother(const Teuchos::ParameterList &paramList, const FactoryMap &factoryMapIn, const FactoryManagerMap &factoryManagersIn) const
RCP< T > Build(const Teuchos::ParameterList &paramList, const FactoryMap &factoryMapIn, const FactoryManagerMap &factoryManagersIn) const
Factory that can generate other factories from.
Class that encapsulates external library smoothers.
virtual RCP< const FactoryBase > BuildFactory(const Teuchos::ParameterEntry &param, const FactoryMap &factoryMapIn, const FactoryManagerMap &factoryManagersIn) const
: Interpret Factory parameter list and build new factory
RCP< T > BuildBlockedFactory(const Teuchos::ParameterList &paramList, const FactoryMap &factoryMapIn, const FactoryManagerMap &factoryManagersIn) const
RCP< ToggleCoordinatesTransferFactory > BuildToggleCoordinatesTransferFactory(const Teuchos::ParameterList &paramList, const FactoryMap &factoryMapIn, const FactoryManagerMap &factoryManagersIn) const
RCP< T > Build2(const Teuchos::ParameterList &paramList, const FactoryMap &factoryMapIn, const FactoryManagerMap &factoryManagersIn) const
Namespace for MueLu classes and methods.
Class that encapsulates direct solvers. Autoselection of AmesosSmoother or Amesos2Smoother according ...
#define arraysize(ar)
std::map< std::string, RCP< FactoryManagerBase > > FactoryManagerMap
std::map< std::string, RCP< const FactoryBase > > FactoryMap
RCP< FactoryBase > BuildBlockedDirectSolver(const Teuchos::ParameterList &paramList, const FactoryMap &factoryMapIn, const FactoryManagerMap &factoryManagersIn) const
direct solver for nxn blocked matrices
RCP< T > BuildRAPFactory(const Teuchos::ParameterList &paramList, const FactoryMap &factoryMapIn, const FactoryManagerMap &factoryManagersIn) const
Base class for MueLu classes.
Class that encapsulates Matlab smoothers.
RCP< FactoryBase > BuildTekoSmoother(const Teuchos::ParameterList &paramList, const FactoryMap &factoryMapIn, const FactoryManagerMap &factoryManagersIn) const
RCP< FactoryBase > BuildTrilinosSmoother(const Teuchos::ParameterList &paramList, const FactoryMap &factoryMapIn, const FactoryManagerMap &factoryManagersIn) const
TrilinosSmoother.
RCP< FactoryBase > BuildCoupledAggregationFactory(const Teuchos::ParameterList &paramList, const FactoryMap &factoryMapIn, const FactoryManagerMap &factoryManagersIn) const
CoupledAggregationFactory.
Exception throws to report errors in the internal logical of the program.
RCP< T > BuildTogglePFactory(const Teuchos::ParameterList &paramList, const FactoryMap &factoryMapIn, const FactoryManagerMap &factoryManagersIn) const
RCP< FactoryBase > BuildDirectSolver(const Teuchos::ParameterList &paramList, const FactoryMap &factoryMapIn, const FactoryManagerMap &factoryManagersIn) const
static const RCP< const NoFactory > getRCP()
Static Get() functions.