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