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