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