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_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_CoupledAggregationFactory.hpp"
92 #include "MueLu_CoordinatesTransferFactory.hpp"
93 #include "MueLu_DirectSolver.hpp"
94 #include "MueLu_DropNegativeEntriesFactory.hpp"
95 #include "MueLu_EminPFactory.hpp"
96 #include "MueLu_FilteredAFactory.hpp"
97 #include "MueLu_FineLevelInputDataFactory.hpp"
98 #include "MueLu_GeneralGeometricPFactory.hpp"
99 #include "MueLu_GenericRFactory.hpp"
100 #include "MueLu_GeometricInterpolationPFactory.hpp"
101 #include "MueLu_InterfaceAggregationFactory.hpp"
102 #include "MueLu_InterfaceMappingTransferFactory.hpp"
103 #include "MueLu_InitialBlockNumberFactory.hpp"
104 #include "MueLu_IndefBlockedDiagonalSmoother.hpp"
105 #include "MueLu_IsorropiaInterface.hpp"
106 #include "MueLu_LineDetectionFactory.hpp"
107 #include "MueLu_LocalOrdinalTransferFactory.hpp"
108 #include "MueLu_RepartitionInterface.hpp"
109 #include "MueLu_RepartitionBlockDiagonalFactory.hpp"
110 #include "MueLu_MapTransferFactory.hpp"
111 #include "MueLu_MatrixAnalysisFactory.hpp"
112 #include "MueLu_MultiVectorTransferFactory.hpp"
113 #include "MueLu_NotayAggregationFactory.hpp"
114 #include "MueLu_NullspaceFactory.hpp"
115 #include "MueLu_NullspacePresmoothFactory.hpp"
116 #include "MueLu_PatternFactory.hpp"
117 #include "MueLu_PgPFactory.hpp"
118 #include "MueLu_RebalanceBlockInterpolationFactory.hpp"
119 #include "MueLu_RebalanceBlockRestrictionFactory.hpp"
120 #include "MueLu_RebalanceBlockAcFactory.hpp"
121 #include "MueLu_RebalanceTransferFactory.hpp"
122 #include "MueLu_RegionRFactory.hpp"
123 #include "MueLu_RepartitionFactory.hpp"
124 #include "MueLu_RepartitionHeuristicFactory.hpp"
125 #include "MueLu_RAPFactory.hpp"
126 #include "MueLu_RAPShiftFactory.hpp"
127 #include "MueLu_RebalanceAcFactory.hpp"
128 #include "MueLu_ReorderBlockAFactory.hpp"
129 #include "MueLu_SaPFactory.hpp"
130 #include "MueLu_ScaledNullspaceFactory.hpp"
131 #include "MueLu_SegregatedAFactory.hpp"
132 #include "MueLu_SemiCoarsenPFactory.hpp"
133 #include "MueLu_SchurComplementFactory.hpp"
134 #include "MueLu_SimpleSmoother.hpp"
135 #include "MueLu_SmootherFactory.hpp"
136 #include "MueLu_StructuredAggregationFactory.hpp"
137 #include "MueLu_StructuredLineDetectionFactory.hpp"
138 #include "MueLu_SubBlockAFactory.hpp"
139 #ifdef HAVE_MUELU_TEKO
140 #include "MueLu_TekoSmoother.hpp"
141 #endif
142 #include "MueLu_TentativePFactory.hpp"
143 #include "MueLu_ToggleCoordinatesTransferFactory.hpp"
144 #include "MueLu_TogglePFactory.hpp"
145 #include "MueLu_TrilinosSmoother.hpp"
146 #include "MueLu_TransPFactory.hpp"
147 #include "MueLu_UncoupledAggregationFactory.hpp"
148 #include "MueLu_HybridAggregationFactory.hpp"
149 #include "MueLu_UnsmooshFactory.hpp"
150 #include "MueLu_UserAggregationFactory.hpp"
151 #include "MueLu_UserPFactory.hpp"
152 #include "MueLu_UzawaSmoother.hpp"
153 #include "MueLu_VariableDofLaplacianFactory.hpp"
154 #include "MueLu_ZeroSubBlockAFactory.hpp"
155 #include "MueLu_ZoltanInterface.hpp"
156 #include "MueLu_Zoltan2Interface.hpp"
157 #include "MueLu_NodePartitionInterface.hpp"
158 
159 
160 #ifdef HAVE_MUELU_KOKKOS_REFACTOR
161 #include "MueLu_AmalgamationFactory_kokkos.hpp"
162 #include "MueLu_CoalesceDropFactory_kokkos.hpp"
163 #include "MueLu_CoarseMapFactory_kokkos.hpp"
164 #include "MueLu_CoordinatesTransferFactory_kokkos.hpp"
165 #include "MueLu_GeometricInterpolationPFactory_kokkos.hpp"
166 #include "MueLu_NullspaceFactory_kokkos.hpp"
167 #include "MueLu_SaPFactory_kokkos.hpp"
168 #include "MueLu_SemiCoarsenPFactory_kokkos.hpp"
169 #include "MueLu_StructuredAggregationFactory_kokkos.hpp"
170 #include "MueLu_TentativePFactory_kokkos.hpp"
171 #include "MueLu_UncoupledAggregationFactory_kokkos.hpp"
172 #endif
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:
208 
226  virtual RCP<const FactoryBase> BuildFactory(const Teuchos::ParameterEntry& param, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
227  // Find factory
228  std::string factoryName;
229  Teuchos::ParameterList paramList;
230  if (!param.isList()) {
231  factoryName = Teuchos::getValue<std::string>(param);
232  } else {
233  paramList = Teuchos::getValue<Teuchos::ParameterList>(param);
234  factoryName = paramList.get<std::string>("factory");
235  }
236 
237  // TODO: see how Teko handles this (=> register factories).
238  if (factoryName == "AggregateQualityEstimateFactory") return Build2<AggregateQualityEstimateFactory> (paramList, factoryMapIn, factoryManagersIn);
239  if (factoryName == "AggregationExportFactory") return Build2<AggregationExportFactory> (paramList, factoryMapIn, factoryManagersIn);
240  if (factoryName == "AmalgamationFactory") return Build2<AmalgamationFactory> (paramList, factoryMapIn, factoryManagersIn);
241  if (factoryName == "BlockedCoarseMapFactory") return Build2<BlockedCoarseMapFactory> (paramList, factoryMapIn, factoryManagersIn);
242  if (factoryName == "BlockedRAPFactory") return BuildRAPFactory<BlockedRAPFactory> (paramList, factoryMapIn, factoryManagersIn);
243  if (factoryName == "BrickAggregationFactory") return Build2<BrickAggregationFactory> (paramList, factoryMapIn, factoryManagersIn);
244  if (factoryName == "ClassicalMapFactory") return Build2<ClassicalMapFactory> (paramList, factoryMapIn, factoryManagersIn);
245  if (factoryName == "ClassicalPFactory") return Build2<ClassicalPFactory> (paramList, factoryMapIn, factoryManagersIn);
246  if (factoryName == "CloneRepartitionInterface") return Build2<CloneRepartitionInterface> (paramList, factoryMapIn, factoryManagersIn);
247  if (factoryName == "CoarseMapFactory") return Build2<CoarseMapFactory> (paramList, factoryMapIn, factoryManagersIn);
248  if (factoryName == "CoarseningVisualizationFactory") return Build2<CoarseningVisualizationFactory> (paramList, factoryMapIn, factoryManagersIn);
249  if (factoryName == "CoalesceDropFactory") return Build2<CoalesceDropFactory> (paramList, factoryMapIn, factoryManagersIn);
250  if (factoryName == "SmooVecCoalesceDropFactory") return Build2<SmooVecCoalesceDropFactory> (paramList, factoryMapIn, factoryManagersIn);
251  if (factoryName == "ConstraintFactory") return Build2<ConstraintFactory> (paramList, factoryMapIn, factoryManagersIn);
252  if (factoryName == "CoupledAggregationFactory") return BuildCoupledAggregationFactory (paramList, factoryMapIn, factoryManagersIn);
253  if (factoryName == "CoordinatesTransferFactory") return Build2<CoordinatesTransferFactory> (paramList, factoryMapIn, factoryManagersIn);
254  if (factoryName == "DirectSolver") return BuildDirectSolver (paramList, factoryMapIn, factoryManagersIn);
255  if (factoryName == "DropNegativeEntriesFactory") return Build2<DropNegativeEntriesFactory> (paramList, factoryMapIn, factoryManagersIn);
256  if (factoryName == "EminPFactory") return Build2<EminPFactory> (paramList, factoryMapIn, factoryManagersIn);
257  if (factoryName == "FilteredAFactory") return Build2<FilteredAFactory> (paramList, factoryMapIn, factoryManagersIn);
258  if (factoryName == "FineLevelInputDataFactory") return Build2<FineLevelInputDataFactory> (paramList, factoryMapIn, factoryManagersIn);
259  if (factoryName == "GeneralGeometricPFactory") return Build2<GeneralGeometricPFactory> (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 == "InitialBlockNumberFactory") return Build2<InitialBlockNumberFactory> (paramList, factoryMapIn, factoryManagersIn);
266  if (factoryName == "LineDetectionFactory") return Build2<LineDetectionFactory> (paramList, factoryMapIn, factoryManagersIn);
267  // LocalOrdinalTransferFactory is a utility factory that can be used for multiple things, so there is no default
268  // if (factoryName == "LocalOrdinalTransferFactory") return Build2<LocalOrdinalTransferFactory> (paramList, factoryMapIn, factoryManagersIn);
269  if (factoryName == "MapTransferFactory") return Build2<MapTransferFactory> (paramList, factoryMapIn, factoryManagersIn);
270  if (factoryName == "MatrixAnalysisFactory") return Build2<MatrixAnalysisFactory> (paramList, factoryMapIn, factoryManagersIn);
271  if (factoryName == "MultiVectorTransferFactory") return Build2<MultiVectorTransferFactory> (paramList, factoryMapIn, factoryManagersIn);
272  if (factoryName == "NoFactory") return MueLu::NoFactory::getRCP();
273  if (factoryName == "NoSmoother") return rcp(new SmootherFactory(Teuchos::null));
274 #ifdef HAVE_MUELU_KOKKOS_REFACTOR
275  if (factoryName == "NotayAggregationFactory") return Build2<NotayAggregationFactory> (paramList, factoryMapIn, factoryManagersIn);
276 #endif
277  if (factoryName == "NullspaceFactory") return Build2<NullspaceFactory> (paramList, factoryMapIn, factoryManagersIn);
278  if (factoryName == "NullspacePresmoothFactory") return Build2<NullspacePresmoothFactory> (paramList, factoryMapIn, factoryManagersIn);
279  if (factoryName == "PatternFactory") return Build2<PatternFactory> (paramList, factoryMapIn, factoryManagersIn);
280  if (factoryName == "PgPFactory") return Build2<PgPFactory> (paramList, factoryMapIn, factoryManagersIn);
281  if (factoryName == "SaPFactory") return Build2<SaPFactory> (paramList, factoryMapIn, factoryManagersIn);
282  if (factoryName == "RAPFactory") return BuildRAPFactory<RAPFactory> (paramList, factoryMapIn, factoryManagersIn);
283  if (factoryName == "RAPShiftFactory") return BuildRAPFactory<RAPShiftFactory> (paramList, factoryMapIn, factoryManagersIn);
284  if (factoryName == "RebalanceAcFactory") return Build2<RebalanceAcFactory> (paramList, factoryMapIn, factoryManagersIn);
285  if (factoryName == "RebalanceTransferFactory") return Build2<RebalanceTransferFactory> (paramList, factoryMapIn, factoryManagersIn);
286 #ifdef HAVE_MUELU_KOKKOS_REFACTOR
287  if (factoryName == "RegionRFactory") return Build2<RegionRFactory> (paramList, factoryMapIn, factoryManagersIn);
288 #endif
289  if (factoryName == "ReorderBlockAFactory") return Build2<ReorderBlockAFactory> (paramList, factoryMapIn, factoryManagersIn);
290  if (factoryName == "RepartitionInterface") return Build2<RepartitionInterface> (paramList, factoryMapIn, factoryManagersIn);
291  if (factoryName == "ScaledNullspaceFactory") return Build2<ScaledNullspaceFactory> (paramList, factoryMapIn, factoryManagersIn);
292  if (factoryName == "SegregatedAFactory") return Build2<SegregatedAFactory> (paramList, factoryMapIn, factoryManagersIn);
293  if (factoryName == "SemiCoarsenPFactory") return Build2<SemiCoarsenPFactory> (paramList, factoryMapIn, factoryManagersIn);
294  if (factoryName == "StructuredAggregationFactory") return Build2<StructuredAggregationFactory> (paramList, factoryMapIn, factoryManagersIn);
295  if (factoryName == "StructuredLineDetectionFactory") return Build2<StructuredLineDetectionFactory> (paramList, factoryMapIn, factoryManagersIn);
296  if (factoryName == "SubBlockAFactory") return Build2<SubBlockAFactory> (paramList, factoryMapIn, factoryManagersIn);
297  if (factoryName == "TentativePFactory") return Build2<TentativePFactory> (paramList, factoryMapIn, factoryManagersIn);
298  if (factoryName == "ToggleCoordinatesTransferFactory") return BuildToggleCoordinatesTransferFactory (paramList, factoryMapIn, factoryManagersIn);
299  if (factoryName == "TogglePFactory") return BuildTogglePFactory<TogglePFactory> (paramList, factoryMapIn, factoryManagersIn);
300  if (factoryName == "TransPFactory") return Build2<TransPFactory> (paramList, factoryMapIn, factoryManagersIn);
301  if (factoryName == "TrilinosSmoother") return BuildTrilinosSmoother (paramList, factoryMapIn, factoryManagersIn);
302  if (factoryName == "UncoupledAggregationFactory") return Build2<UncoupledAggregationFactory> (paramList, factoryMapIn, factoryManagersIn);
303  if (factoryName == "UnsmooshFactory") return Build2<UnsmooshFactory> (paramList, factoryMapIn, factoryManagersIn);
304  if (factoryName == "UserAggregationFactory") return Build2<UserAggregationFactory> (paramList, factoryMapIn, factoryManagersIn);
305  if (factoryName == "UserPFactory") return Build2<UserPFactory> (paramList, factoryMapIn, factoryManagersIn);
306  if (factoryName == "VariableDofLaplacianFactory") return Build2<VariableDofLaplacianFactory> (paramList, factoryMapIn, factoryManagersIn);
307  if (factoryName == "ZeroSubBlockAFactory") return Build2<ZeroSubBlockAFactory> (paramList, factoryMapIn, factoryManagersIn);
308 #ifdef HAVE_MUELU_KOKKOS_REFACTOR
309  if (factoryName == "AmalgamationFactory_kokkos") return Build2<AmalgamationFactory_kokkos> (paramList, factoryMapIn, factoryManagersIn);
310  if (factoryName == "CoalesceDropFactory_kokkos") return Build2<CoalesceDropFactory_kokkos> (paramList, factoryMapIn, factoryManagersIn);
311  if (factoryName == "CoarseMapFactory_kokkos") return Build2<CoarseMapFactory_kokkos> (paramList, factoryMapIn, factoryManagersIn);
312  if (factoryName == "CoordinatesTransferFactory_kokkos") return Build2<CoordinatesTransferFactory_kokkos> (paramList, factoryMapIn, factoryManagersIn);
313  if (factoryName == "GeometricInterpolationPFactory_kokkos") return Build2<GeometricInterpolationPFactory_kokkos> (paramList, factoryMapIn, factoryManagersIn);
314  if (factoryName == "NullspaceFactory_kokkos") return Build2<NullspaceFactory_kokkos> (paramList, factoryMapIn, factoryManagersIn);
315  if (factoryName == "SaPFactory_kokkos") return Build2<SaPFactory_kokkos> (paramList, factoryMapIn, factoryManagersIn);
316  if (factoryName == "SemiCoarsenPFactory_kokkos") return Build2<SemiCoarsenPFactory_kokkos> (paramList, factoryMapIn, factoryManagersIn);
317  if (factoryName == "StructuredAggregationFactory_kokkos") return Build2<StructuredAggregationFactory_kokkos> (paramList, factoryMapIn, factoryManagersIn);
318  if (factoryName == "TentativePFactory_kokkos") return Build2<TentativePFactory_kokkos> (paramList, factoryMapIn, factoryManagersIn);
319  if (factoryName == "UncoupledAggregationFactory_kokkos") return Build2<UncoupledAggregationFactory_kokkos> (paramList, factoryMapIn, factoryManagersIn);
320 #endif
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 << paramList << std::endl
402  << "'" << factoryName << "' is not a factory name but an existing instance of a factory." << std::endl
403  << "Extra parameters cannot be specified after the creation of the object." << std::endl << std::endl
404  << "Correct syntaxes includes:" << std::endl
405  << " <Parameter name=\"...\" type=\"string\" value=\"" << factoryName << "\"/>" << std::endl
406  << "or" << std::endl
407  << " <ParameterList name=\"...\"><Parameter name=\"factory\" type=\"string\" value=\"" << factoryName << "\"/></ParameterList>" << std::endl
408  );
409 
410  return factoryMapIn.find(factoryName)->second;
411  }
412 
413  TEUCHOS_TEST_FOR_EXCEPTION(true, Exceptions::RuntimeError, "MueLu::FactoryFactory: unknown factory name : " << factoryName);
414 
415  TEUCHOS_UNREACHABLE_RETURN(Teuchos::null);
416  }
417 
418  //
419  //
420  //
421 
422  // FOLLOWING FUNCTIONS SHOULD LIVE WITH THE CORRESPONDING CLASS
423 
424  //
425  //
426  //
427 
428 #define arraysize(ar) (sizeof(ar) / sizeof(ar[0]))
429 
430  template <class T> // T must implement the Factory interface
431  RCP<T> Build(const Teuchos::ParameterList& paramList, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
432  RCP<T> factory = rcp(new T());
433 
434  const char* strarray[] = {"A", "P", "R", "Graph", "UnAmalgamationInfo", "Aggregates", "Nullspace", "TransferFactory", "DofsPerNode"};
435  std::vector<std::string> v(strarray, strarray + arraysize(strarray));
436  for (size_t i = 0; i < v.size(); ++i)
437  if (paramList.isParameter(v[i]))
438  factory->SetFactory(v[i], BuildFactory(paramList.getEntry(v[i]), factoryMapIn, factoryManagersIn));
439 
440  return factory;
441  }
442 
443  template <class T> // T must implement the Factory interface
444  RCP<T> Build2(const Teuchos::ParameterList& paramList, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
445  RCP<T> factory = rcp(new T());
446 
447  ParameterList paramListWithFactories;
448 
449  // Read the RCP<Factory> parameters of the class T
450  RCP<const ParameterList> validParamList = factory->GetValidParameterList(); // TODO check for Teuchos::null (no parameter list validation)
451  TEUCHOS_TEST_FOR_EXCEPTION(validParamList == Teuchos::null, Exceptions::RuntimeError, "FactoryFactory::Build2: default parameter list is null. Please fix this.");
452  for (ParameterList::ConstIterator param = validParamList->begin(); param != validParamList->end(); ++param) {
453  const std::string& pName = validParamList->name(param);
454 
455  if (!paramList.isParameter(pName)) {
456  // Ignore unknown parameters
457  continue;
458  }
459 
460  if (validParamList->isType< RCP<const FactoryBase> >(pName)) {
461  // Generate or get factory described by param
462  RCP<const FactoryBase> generatingFact = BuildFactory(paramList.getEntry(pName), factoryMapIn, factoryManagersIn);
463  paramListWithFactories.set(pName, generatingFact);
464  } else if (validParamList->isType<RCP<const ParameterList> >(pName)) {
465  if (pName == "ParameterList") {
466  // NOTE: we cannot use
467  // subList = sublist(rcpFromRef(paramList), pName)
468  // here as that would result in sublist also being a reference to a temporary object.
469  // The resulting dereferencing in the corresponding factory would then segfault
470  RCP<const ParameterList> subList = Teuchos::sublist(rcp(new ParameterList(paramList)), pName);
471  paramListWithFactories.set(pName, subList);
472  }
473  } else {
474  paramListWithFactories.setEntry(pName, paramList.getEntry(pName));
475  }
476  }
477 
478  // Configure the factory
479  factory->SetParameterList(paramListWithFactories);
480 
481  return factory;
482  }
483 
484  template <class T> // T must implement the Factory interface
485  RCP<T> BuildRAPFactory(const Teuchos::ParameterList & paramList, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
486  RCP<T> factory;
487  if (paramList.isSublist("TransferFactories") == false) {
488  factory = Build2<T>(paramList, factoryMapIn, factoryManagersIn);
489 
490  } else {
491  RCP<Teuchos::ParameterList> paramListNonConst = rcp(new Teuchos::ParameterList(paramList));
492  RCP<const Teuchos::ParameterList> transferFactories = rcp(new Teuchos::ParameterList(*sublist(paramListNonConst, "TransferFactories")));
493 
494  paramListNonConst->remove("TransferFactories");
495 
496  factory = Build2<T>(*paramListNonConst, factoryMapIn, factoryManagersIn);
497 
498  for (Teuchos::ParameterList::ConstIterator param = transferFactories->begin(); param != transferFactories->end(); ++param) {
499  RCP<const FactoryBase> p = BuildFactory(transferFactories->entry(param), factoryMapIn, factoryManagersIn);
500  factory->AddTransferFactory(p);
501  }
502  }
503 
504  return factory;
505  }
506 
507  template <class T> // T must implement the Factory interface
508  RCP<T> BuildTogglePFactory(const Teuchos::ParameterList & paramList, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
509  RCP<T> factory;
510  if (paramList.isSublist("TransferFactories") == false) {
511  //TODO put in an error message: the TogglePFactory needs a TransferFactories sublist!
512  factory = Build2<T>(paramList, factoryMapIn, factoryManagersIn);
513 
514  } else {
515  RCP<Teuchos::ParameterList> paramListNonConst = rcp(new Teuchos::ParameterList(paramList));
516  RCP<const Teuchos::ParameterList> transferFactories = rcp(new Teuchos::ParameterList(*sublist(paramListNonConst, "TransferFactories")));
517 
518  paramListNonConst->remove("TransferFactories");
519 
520  // build TogglePFactory
521  factory = Build2<T>(*paramListNonConst, factoryMapIn, factoryManagersIn);
522 
523  // count how many prolongation factories and how many coarse null space factories have been declared.
524  // the numbers must match!
525  int numProlongatorFactories = 0;
526  int numPtentFactories = 0;
527  int numCoarseNspFactories = 0;
528  for (Teuchos::ParameterList::ConstIterator param = transferFactories->begin(); param != transferFactories->end(); ++param) {
529  size_t foundNsp = transferFactories->name(param).find("Nullspace");
530  if (foundNsp != std::string::npos && foundNsp == 0 && transferFactories->name(param).length()==10) {
531  numCoarseNspFactories++;
532  continue;
533  }
534  size_t foundPtent = transferFactories->name(param).find("Ptent");
535  if (foundPtent != std::string::npos && foundPtent == 0 && transferFactories->name(param).length()==6) {
536  numPtentFactories++;
537  continue;
538  }
539  size_t foundP = transferFactories->name(param).find("P");
540  if (foundP != std::string::npos && foundP == 0 && transferFactories->name(param).length()==2) {
541  numProlongatorFactories++;
542  continue;
543  }
544  }
545  TEUCHOS_TEST_FOR_EXCEPTION(numProlongatorFactories!=numCoarseNspFactories, Exceptions::RuntimeError, "FactoryFactory::BuildToggleP: The user has to provide the same number of prolongator and coarse nullspace factories!");
546  TEUCHOS_TEST_FOR_EXCEPTION(numPtentFactories!=numCoarseNspFactories, Exceptions::RuntimeError, "FactoryFactory::BuildToggleP: The user has to provide the same number of ptent and coarse nullspace factories!");
547  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.");
548 
549  // create empty vectors with data
550  std::vector<Teuchos::ParameterEntry> prolongatorFactoryNames(numProlongatorFactories);
551  std::vector<Teuchos::ParameterEntry> coarseNspFactoryNames(numProlongatorFactories);
552  std::vector<Teuchos::ParameterEntry> ptentFactoryNames(numProlongatorFactories);
553 
554  for (Teuchos::ParameterList::ConstIterator param = transferFactories->begin(); param != transferFactories->end(); ++param) {
555  size_t foundNsp = transferFactories->name(param).find("Nullspace");
556  if (foundNsp != std::string::npos && foundNsp == 0 && transferFactories->name(param).length()==10) {
557  int number = atoi(&(transferFactories->name(param).at(9)));
558  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!");
559  coarseNspFactoryNames[number-1] = transferFactories->entry(param);
560  continue;
561  }
562  size_t foundPtent = transferFactories->name(param).find("Ptent");
563  if (foundPtent != std::string::npos && foundPtent == 0 && transferFactories->name(param).length()==6) {
564  int number = atoi(&(transferFactories->name(param).at(5)));
565  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!");
566  ptentFactoryNames[number-1] = transferFactories->entry(param);
567  continue;
568  }
569  size_t foundP = transferFactories->name(param).find("P");
570  if (foundP != std::string::npos && foundP == 0 && transferFactories->name(param).length()==2) {
571  int number = atoi(&(transferFactories->name(param).at(1)));
572  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!");
573  prolongatorFactoryNames[number-1] = transferFactories->entry(param);
574  continue;
575  }
576  }
577 
578  // register all prolongation factories in TogglePFactory
579  for (std::vector<Teuchos::ParameterEntry>::const_iterator it = prolongatorFactoryNames.begin(); it != prolongatorFactoryNames.end(); ++it) {
580  RCP<const FactoryBase> p = BuildFactory(*it, factoryMapIn, factoryManagersIn);
581  factory->AddProlongatorFactory(p);
582  }
583 
584  // register all tentative prolongation factories in TogglePFactory
585  for (std::vector<Teuchos::ParameterEntry>::const_iterator it = ptentFactoryNames.begin(); it != ptentFactoryNames.end(); ++it) {
586  RCP<const FactoryBase> p = BuildFactory(*it, factoryMapIn, factoryManagersIn);
587  factory->AddPtentFactory(p);
588  }
589 
590  // register all coarse nullspace factories in TogglePFactory
591  for (std::vector<Teuchos::ParameterEntry>::const_iterator it = coarseNspFactoryNames.begin(); it != coarseNspFactoryNames.end(); ++it) {
592  RCP<const FactoryBase> p = BuildFactory(*it, factoryMapIn, factoryManagersIn);
593  factory->AddCoarseNullspaceFactory(p);
594  }
595  }
596  return factory;
597  }
598 
599  RCP<ToggleCoordinatesTransferFactory> BuildToggleCoordinatesTransferFactory(const Teuchos::ParameterList & paramList, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
600  RCP<ToggleCoordinatesTransferFactory> factory;
601  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!");
602 
603  RCP<Teuchos::ParameterList> paramListNonConst = rcp(new Teuchos::ParameterList(paramList));
604  RCP<const Teuchos::ParameterList> transferFactories = rcp(new Teuchos::ParameterList(*sublist(paramListNonConst, "TransferFactories")));
605  paramListNonConst->remove("TransferFactories");
606 
607  // build CoordinatesTransferFactory
608  factory = Build2<ToggleCoordinatesTransferFactory>(*paramListNonConst, factoryMapIn, factoryManagersIn);
609 
610  // count how many coordinate transfer factories have been declared.
611  // the numbers must match!
612  int numCoordTransferFactories = 0;
613  for (Teuchos::ParameterList::ConstIterator param = transferFactories->begin(); param != transferFactories->end(); ++param) {
614  size_t foundCoordinates = transferFactories->name(param).find("Coordinates");
615  if (foundCoordinates != std::string::npos && foundCoordinates == 0 && transferFactories->name(param).length()==12) {
616  numCoordTransferFactories++;
617  continue;
618  }
619  }
620  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.");
621 
622  // create empty vectors with data
623  std::vector<Teuchos::ParameterEntry> coarseCoordsFactoryNames(numCoordTransferFactories);
624 
625  for (Teuchos::ParameterList::ConstIterator param = transferFactories->begin(); param != transferFactories->end(); ++param) {
626  size_t foundCoords = transferFactories->name(param).find("Coordinates");
627  if (foundCoords != std::string::npos && foundCoords == 0 && transferFactories->name(param).length()==12) {
628  int number = atoi(&(transferFactories->name(param).at(11)));
629  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!");
630  coarseCoordsFactoryNames[number-1] = transferFactories->entry(param);
631  continue;
632  }
633  }
634 
635  // register all coarse nullspace factories in TogglePFactory
636  for (std::vector<Teuchos::ParameterEntry>::const_iterator it = coarseCoordsFactoryNames.begin(); it != coarseCoordsFactoryNames.end(); ++it) {
637  RCP<const FactoryBase> p = BuildFactory(*it, factoryMapIn, factoryManagersIn);
638  factory->AddCoordTransferFactory(p);
639  }
640 
641  return factory;
642  }
643 
645  RCP<FactoryBase> BuildCoupledAggregationFactory(const Teuchos::ParameterList& paramList, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
646  RCP<CoupledAggregationFactory> factory = Build<CoupledAggregationFactory>(paramList, factoryMapIn, factoryManagersIn);
647 
648  if (paramList.isParameter("aggregation: ordering"))
649  factory->SetOrdering(paramList.get<std::string>("aggregation: ordering"));
650 
651  if (paramList.isParameter("aggregation: max selected neighbors"))
652  factory->SetMaxNeighAlreadySelected(paramList.get<int>("aggregation: max selected neighbors"));
653 
654  if (paramList.isParameter("Phase3AggCreation"))
655  factory->SetPhase3AggCreation(paramList.get<double>("Phase3AggCreation"));
656 
657  if(paramList.isParameter("aggregation: min agg size"))
658  factory->SetMinNodesPerAggregate(paramList.get<int>("aggregation: min agg size"));
659 
660  return factory;
661  }
662 
664  // Parameter List Parsing:
665  // <ParameterList name="smootherFact1">
666  // <Parameter name="factory" type="string" value="TrilinosSmoother"/>
667  // <Parameter name="verbose" type="string" value="Warnings"/>
668  // <Parameter name="type" type="string" value="RELAXATION"/>
669  // <ParameterList name="ParameterList">
670  // ...
671  // </ParameterList>
672  // </ParameterList>
673  RCP<FactoryBase> BuildTrilinosSmoother(const Teuchos::ParameterList & paramList, const FactoryMap & factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
674  if (paramList.begin() == paramList.end())
675  return rcp(new SmootherFactory(rcp(new TrilinosSmoother())));
676 
677  TEUCHOS_TEST_FOR_EXCEPTION(paramList.get<std::string>("factory") != "TrilinosSmoother", Exceptions::RuntimeError, "");
678 
679  // Is it true? TEUCHOS_TEST_FOR_EXCEPTION(!paramList.isParameter("type"), Exceptions::RuntimeError, "TrilinosSmoother: parameter 'type' is mandatory");
680  // type="" is default in TrilinosSmoother, but what happen then?
681 
682  std::string type=""; if(paramList.isParameter("type")) type = paramList.get<std::string>("type");
683  int overlap=0; if(paramList.isParameter("overlap")) overlap = paramList.get<int> ("overlap");
684  // std::string verbose; if(paramList.isParameter("verbose")) verbose = paramList.get<std::string>("verbose");
685  Teuchos::ParameterList params; if(paramList.isParameter("ParameterList")) params = paramList.get<Teuchos::ParameterList>("ParameterList");
686 
687  // parameters from SmootherFactory
688  //bool bKeepSmootherData = false; if(paramList.isParameter("keep smoother data")) bKeepSmootherData = paramList.get<bool>("keep smoother data");
689 
690  // Read in factory information for smoothers (if available...)
691  // NOTE: only a selected number of factories can be used with the Trilinos smoother
692  // smoothers usually work with the global data available (which is A and the transfers P and R)
693 
694  Teuchos::RCP<TrilinosSmoother> trilSmoo = Teuchos::rcp(new TrilinosSmoother(type, params, overlap));
695 
696  if (paramList.isParameter("LineDetection_Layers")) {
697  RCP<const FactoryBase> generatingFact = BuildFactory(paramList.getEntry("LineDetection_Layers"), factoryMapIn, factoryManagersIn);
698  trilSmoo->SetFactory("LineDetection_Layers", generatingFact);
699  }
700  if (paramList.isParameter("LineDetection_VertLineIds")) {
701  RCP<const FactoryBase> generatingFact = BuildFactory(paramList.getEntry("LineDetection_Layers"), factoryMapIn, factoryManagersIn);
702  trilSmoo->SetFactory("LineDetection_Layers", generatingFact);
703  }
704  if (paramList.isParameter("CoarseNumZLayers")) {
705  RCP<const FactoryBase> generatingFact = BuildFactory(paramList.getEntry("CoarseNumZLayers"), factoryMapIn, factoryManagersIn);
706  trilSmoo->SetFactory("CoarseNumZLayers", generatingFact);
707  }
708 
709  RCP<SmootherFactory> smooFact = rcp(new SmootherFactory(Teuchos::null));
710  Teuchos::ParameterList smooFactParams;
711  //smooFactParams.setEntry("keep smoother data", paramList.getEntry("keep smoother data"));
712  smooFact->SetParameterList(smooFactParams);
713  smooFact->SetSmootherPrototypes(trilSmoo);
714  return smooFact;
715  }
716 
717 #ifdef HAVE_MUELU_MATLAB
719  // Parameter List Parsing:
720  // <ParameterList name="smootherFact1">
721  // <Parameter name="factory" type="string" value="MatlabSmoother"/>
722  // <Parameter name="Setup Function" type="string" value="mySmootherSetup.m"/>
723  // <Parameter name="Solve Function" type="string" value="mySmootherSolve.m"/>
724  // <!--A is implicitly included in this list and nothing else is needed to get diagonal-->
725  // <Parameter name="Needs" type="string" value=""/>
726  // <!--A,x,b are also assumed inputs to the solver: only one additional arg then (diag)-->
727  // <Parameter name="Number of Solver Args" type="int" value="1"/>
728  // </ParameterList>
729  RCP<FactoryBase> BuildMatlabSmoother(const Teuchos::ParameterList & paramList, const FactoryMap & factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
730  if (paramList.begin() == paramList.end())
731  return rcp(new SmootherFactory(rcp(new MatlabSmoother())));
732 
733  TEUCHOS_TEST_FOR_EXCEPTION(paramList.get<std::string>("factory") != "MatlabSmoother", Exceptions::RuntimeError, "");
734 
735  // Read in factory information for smoothers (if available...)
736  // NOTE: only a selected number of factories can be used with the Trilinos smoother
737  // smoothers usually work with the global data available (which is A and the transfers P and R)
738 
739  Teuchos::RCP<MatlabSmoother> matSmoo = Teuchos::rcp(new MatlabSmoother(paramList));
740 
741  return rcp(new SmootherFactory(matSmoo));
742  }
743 #endif
744 
745  RCP<FactoryBase> BuildDirectSolver(const Teuchos::ParameterList& paramList, const FactoryMap& /* factoryMapIn */, const FactoryManagerMap& /* factoryManagersIn */) const {
746  if (paramList.begin() == paramList.end())
747  return rcp(new SmootherFactory(rcp(new DirectSolver()), Teuchos::null));
748 
749  TEUCHOS_TEST_FOR_EXCEPTION(paramList.get<std::string>("factory") != "DirectSolver", Exceptions::RuntimeError, "");
750 
751  std::string type; if(paramList.isParameter("type")) type = paramList.get<std::string>("type");
752  // std::string verbose; if(paramList.isParameter("verbose")) verbose = paramList.get<std::string>("verbose");
753  Teuchos::ParameterList params; if(paramList.isParameter("ParameterList")) params = paramList.get<Teuchos::ParameterList>("ParameterList");
754 
755  return rcp(new SmootherFactory(rcp(new DirectSolver(type, params)), Teuchos::null));
756  }
757 
758  template <class T> // T must implement the Factory interface
759  RCP<FactoryBase> BuildBlockedSmoother(const Teuchos::ParameterList& paramList, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
760  // read in sub lists
761  RCP<ParameterList> paramListNonConst = rcp(new ParameterList(paramList));
762 
763  // internal vector of factory managers
764  std::vector<RCP<FactoryManager> > facManagers;
765 
766  // loop over all "block%i" sublists in parameter list
767  int blockid = 1;
768  bool blockExists = true;
769  while (blockExists == true) {
770  std::stringstream ss;
771  ss << "block" << blockid;
772 
773  if(paramList.isSublist(ss.str()) == true) {
774  // we either have a parameter group or we have a list of factories in here
775  RCP<const ParameterList> b = rcp(new ParameterList(*sublist(paramListNonConst, ss.str())));
776 
777  RCP<FactoryManager> M = Teuchos::null;
778 
779  if (b->isParameter("group")) {
780  // use a factory manager
781  std::string facManagerName = b->get< std::string >("group");
782  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.");
783  RCP<FactoryManagerBase> Mb = factoryManagersIn.find(facManagerName)->second;
784  M = Teuchos::rcp_dynamic_cast<FactoryManager>(Mb);
785  TEUCHOS_TEST_FOR_EXCEPTION(M==Teuchos::null, Exceptions::RuntimeError, "Failed to cast FactoryManagerBase object to FactoryManager.");
786  } else {
787  // read in the list of factories
788  M = rcp(new FactoryManager());
789  for (ParameterList::ConstIterator param = b->begin(); param != b->end(); ++param) {
790  RCP<const FactoryBase> p = BuildFactory(b->entry(param), factoryMapIn, factoryManagersIn);
791  M->SetFactory(b->name(param),p);
792  }
793  }
794 
795  // add factory manager to internal vector of factory managers
796  M->SetIgnoreUserData(true);
797  facManagers.push_back(M);
798  paramListNonConst->remove(ss.str());
799  blockid++;
800  } else {
801  blockExists = false;
802  break;
803  }
804 
805  }
806 
807  // create a new blocked smoother
808  RCP<T> bs = Build2<T>(*paramListNonConst, factoryMapIn, factoryManagersIn);
809 
810  // important: set block factory for A here!
811  // TAW: 7/6/2016: We should not need to set/hardcode the blocked operator here.
812  // The user might want to overwrite this in the xml file, so just
813  // use what is declared as "A"
814  //bs->SetFactory("A", MueLu::NoFactory::getRCP());
815 
816  for (int i = 0; i<Teuchos::as<int>(facManagers.size()); i++) {
817  bs->AddFactoryManager(facManagers[i],i);
818  }
819 
820  return rcp(new SmootherFactory(bs));
821  }
822 
823 #ifdef HAVE_MUELU_TEKO
824  RCP<FactoryBase> BuildTekoSmoother(const Teuchos::ParameterList& paramList, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
825  // read in sub lists
826  RCP<ParameterList> paramListNonConst = rcp(new ParameterList(paramList));
827  RCP<ParameterList> tekoParams = rcp(new ParameterList(paramListNonConst->sublist("Inverse Factory Library")));
828  paramListNonConst->remove("Inverse Factory Library");
829 
830  // create a new blocked smoother
831  RCP<TekoSmoother> bs = Build2<TekoSmoother>(*paramListNonConst, factoryMapIn, factoryManagersIn);
832 
833  // important: set block factory for A here!
834  // TAW: 7/6/2016: We should not need to set/hardcode the blocked operator here.
835  // The user might want to overwrite this in the xml file, so just
836  // use what is declared as "A"
837  //bs->SetFactory("A", MueLu::NoFactory::getRCP());
838 
839  // Set Teko parameters ("Inverse Factory Library")
840  bs->SetTekoParameters(tekoParams);
841 
842  return rcp(new SmootherFactory(bs));
843  }
844 #endif
845 
846  RCP<FactoryBase> BuildBlockedDirectSolver(const Teuchos::ParameterList& /* paramList */, const FactoryMap& /* factoryMapIn */, const FactoryManagerMap& /* factoryManagersIn */) const {
847  //if (paramList.begin() == paramList.end())
848  return rcp(new SmootherFactory(rcp(new BlockedDirectSolver())));
849 
850  /*TEUCHOS_TEST_FOR_EXCEPTION(paramList.get<std::string>("factory") != "DirectSolver", Exceptions::RuntimeError, "");
851 
852  std::string type; if(paramList.isParameter("type")) type = paramList.get<std::string>("type");
853  // std::string verbose; if(paramList.isParameter("verbose")) verbose = paramList.get<std::string>("verbose");
854  Teuchos::ParameterList params; if(paramList.isParameter("ParameterList")) params = paramList.get<Teuchos::ParameterList>("ParameterList");
855 
856  return rcp(new SmootherFactory(rcp(new DirectSolver(type, params))));*/
857  }
858 
859  //RCP<FactoryBase> BuildBlockedPFactory(const Teuchos::ParameterList& paramList, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
860  // RCP<BlockedPFactory> pfac = rcp(new BlockedPFactory());
861 
862  template <class T> // T must implement the Factory interface
863  RCP<T> BuildBlockedFactory(const Teuchos::ParameterList & paramList, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
864  RCP<T> pfac = Teuchos::null;
865 
866  // read in sub lists
867  RCP<ParameterList> paramListNonConst = rcp(new ParameterList(paramList));
868 
869  // internal vector of factory managers
870  std::vector<RCP<FactoryManager> > facManagers;
871 
872  // loop over all "block%i" sublists in parameter list
873  int blockid = 1;
874  bool blockExists = true;
875  while (blockExists == true) {
876  std::stringstream ss;
877  ss << "block" << blockid;
878 
879  if(paramList.isSublist(ss.str()) == true) {
880  // we either have a parameter group or we have a list of factories in here
881  RCP<const ParameterList> b = rcp(new ParameterList(*sublist(paramListNonConst, ss.str())));
882 
883  RCP<FactoryManager> M = Teuchos::null;
884 
885  if (b->isParameter("group")) {
886  // use a factory manager
887  std::string facManagerName = b->get< std::string >("group");
888  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.");
889  RCP<FactoryManagerBase> Mb = factoryManagersIn.find(facManagerName)->second;
890  M = Teuchos::rcp_dynamic_cast<FactoryManager>(Mb);
891  TEUCHOS_TEST_FOR_EXCEPTION(M==Teuchos::null, Exceptions::RuntimeError, "Failed to cast FactoryManagerBase object to FactoryManager.");
892  } else {
893  // read in the list of factories
894  M = rcp(new FactoryManager());
895  for (ParameterList::ConstIterator param = b->begin(); param != b->end(); ++param) {
896  RCP<const FactoryBase> p = BuildFactory(b->entry(param), factoryMapIn, factoryManagersIn);
897  M->SetFactory(b->name(param),p);
898  }
899  }
900 
901  // add factory manager to internal vector of factory managers
902  M->SetIgnoreUserData(true);
903  facManagers.push_back(M);
904  paramListNonConst->remove(ss.str());
905  blockid++;
906  } else {
907  blockExists = false;
908  break;
909  }
910 
911  }
912 
913  // build BlockedPFactory (without sub block information)
914  pfac = Build2<T>(*paramListNonConst, factoryMapIn, factoryManagersIn);
915 
916  // add FactoryManager objects
917  for(size_t i = 0; i<facManagers.size(); i++) {
918  pfac->AddFactoryManager(facManagers[i]); // add factory manager
919  }
920 
921  return pfac;
922  }
923 
924 
925  template <class T> // T must implement the Factory interface
926  RCP<T> BuildBlockedCoordFactory(const Teuchos::ParameterList & paramList, const FactoryMap& factoryMapIn, const FactoryManagerMap& factoryManagersIn) const {
927  RCP<T> pfac = Teuchos::null;
928 
929  // read in sub lists
930  RCP<ParameterList> paramListNonConst = rcp(new ParameterList(paramList));
931 
932  // internal vector of factory managers
933  std::vector<RCP<const FactoryBase> > facBase;
934 
935  // loop over all "block%i" sublists in parameter list
936  int blockid = 1;
937  bool blockExists = true;
938  while (blockExists == true) {
939  std::stringstream ss;
940  ss << "block" << blockid;
941 
942  if(paramList.isSublist(ss.str()) == true) {
943  // we either have a parameter group or we have a list of factories in here
944  RCP<const ParameterList> b = rcp(new ParameterList(*sublist(paramListNonConst, ss.str())));
945 
946  // read in the list of factories
947  for (ParameterList::ConstIterator param = b->begin(); param != b->end(); ++param) {
948  RCP<const FactoryBase> p = BuildFactory(b->entry(param), factoryMapIn, factoryManagersIn);
949  facBase.push_back(p);
950  }
951 
952  // add factory manager to internal vector of factory managers
953  paramListNonConst->remove(ss.str());
954  blockid++;
955  } else {
956  blockExists = false;
957  break;
958  }
959 
960  }
961 
962  // build BlockedPFactory (without sub block information)
963  pfac = Build2<T>(*paramListNonConst, factoryMapIn, factoryManagersIn);
964 
965  // add FactoryManager objects
966  for(size_t i = 0; i<facBase.size(); i++) {
967  pfac->AddFactory(facBase[i]); // add factory manager
968  }
969 
970  return pfac;
971  }
972 
973  }; // class
974 } // namespace MueLu
975 
976 #define MUELU_FACTORYFACTORY_SHORT
977 #endif // MUELU_FACTORYFACTORY_DECL_HPP
978 
979  // TODO: handle factory parameters
980  // TODO: parameter validator
981  // TODO: static
982  // 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< T > BuildBlockedCoordFactory(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