MueLu Version of the Day
Loading...
Searching...
No Matches
Thyra_MueLuTpetraQ2Q1PreconditionerFactory_def.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// MueLu: A package for multigrid based preconditioning
4//
5// Copyright 2012 NTESS and the MueLu contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef THYRA_MUELU_TPETRA_Q2Q1PRECONDITIONER_FACTORY_DEF_HPP
11#define THYRA_MUELU_TPETRA_Q2Q1PRECONDITIONER_FACTORY_DEF_HPP
12
13#ifdef HAVE_MUELU_EXPERIMENTAL
14
16
17#include <Thyra_DefaultPreconditioner.hpp>
18#include <Thyra_TpetraLinearOp.hpp>
19#include <Thyra_TpetraThyraWrappers.hpp>
20
21#include <Teuchos_Ptr.hpp>
22#include <Teuchos_TestForException.hpp>
23#include <Teuchos_Assert.hpp>
24#include <Teuchos_Time.hpp>
25#include <Teuchos_FancyOStream.hpp>
26#include <Teuchos_VerbosityLevel.hpp>
27
28#include <Teko_Utilities.hpp>
29
30#include <Xpetra_BlockedCrsMatrix.hpp>
31#include <Xpetra_CrsMatrixWrap.hpp>
32#include <Xpetra_IO.hpp>
33#include <Xpetra_MapExtractorFactory.hpp>
34#include <Xpetra_Matrix.hpp>
35#include <Xpetra_MatrixMatrix.hpp>
36
37#include "MueLu.hpp"
38
39#include "MueLu_Q2Q1PFactory.hpp"
40#include "MueLu_Q2Q1uPFactory.hpp"
41
42#include "MueLu_AmalgamationFactory.hpp"
43#include "MueLu_BaseClass.hpp"
44#include "MueLu_BlockedDirectSolver.hpp"
45#include "MueLu_BlockedPFactory.hpp"
46#include "MueLu_BlockedRAPFactory.hpp"
47#include "MueLu_BraessSarazinSmoother.hpp"
48#include "MueLu_CoalesceDropFactory.hpp"
49#include "MueLu_ConstraintFactory.hpp"
51#include "MueLu_DirectSolver.hpp"
52#include "MueLu_EminPFactory.hpp"
53#include "MueLu_FactoryManager.hpp"
54#include "MueLu_FilteredAFactory.hpp"
55#include "MueLu_GenericRFactory.hpp"
56#include "MueLu_Level.hpp"
57#include "MueLu_PatternFactory.hpp"
58#include "MueLu_SchurComplementFactory.hpp"
59#include "MueLu_SmootherFactory.hpp"
60#include "MueLu_SmootherPrototype.hpp"
61#include "MueLu_SubBlockAFactory.hpp"
62#include "MueLu_TpetraOperator.hpp"
63#include "MueLu_TrilinosSmoother.hpp"
64
65#include <string>
66
67namespace Thyra {
68
69#define MUELU_GPD(name, type, defaultValue) \
70 (paramList.isParameter(name) ? paramList.get<type>(name) : defaultValue)
71
72using Teuchos::Array;
73using Teuchos::ArrayRCP;
74using Teuchos::ArrayView;
75using Teuchos::as;
76using Teuchos::ParameterList;
77using Teuchos::RCP;
78using Teuchos::rcp;
79using Teuchos::rcp_const_cast;
80using Teuchos::rcp_dynamic_cast;
81
82// Constructors/initializers/accessors
83template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
85
86// Overridden from PreconditionerFactoryBase
87template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
89 typedef Thyra ::TpetraLinearOp<SC, LO, GO, NO> ThyraTpetraLinOp;
90 typedef Tpetra::Operator<SC, LO, GO, NO> TpetraLinOp;
91 typedef Tpetra::CrsMatrix<SC, LO, GO, NO> TpetraCrsMat;
92
93 const RCP<const LinearOpBase<SC> > fwdOp = fwdOpSrc.getOp();
94 const RCP<const ThyraTpetraLinOp> thyraTpetraFwdOp = rcp_dynamic_cast<const ThyraTpetraLinOp>(fwdOp);
95 const RCP<const TpetraLinOp> tpetraFwdOp = Teuchos::nonnull(thyraTpetraFwdOp) ? thyraTpetraFwdOp->getConstTpetraOperator() : Teuchos::null;
96 const RCP<const TpetraCrsMat> tpetraFwdCrsMat = rcp_dynamic_cast<const TpetraCrsMat>(tpetraFwdOp);
97
98 return Teuchos::nonnull(tpetraFwdCrsMat);
99}
100
101template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
102RCP<PreconditionerBase<Scalar> >
106
107template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
109 initializePrec(const RCP<const LinearOpSourceBase<Scalar> >& fwdOpSrc, PreconditionerBase<Scalar>* prec, const ESupportSolveUse supportSolveUse) const {
110 // Check precondition
111 TEUCHOS_ASSERT(Teuchos::nonnull(fwdOpSrc));
112 TEUCHOS_ASSERT(this->isCompatible(*fwdOpSrc));
113 TEUCHOS_ASSERT(prec);
114
115 // Retrieve wrapped concrete Tpetra matrix from FwdOp
116 const RCP<const LinearOpBase<SC> > fwdOp = fwdOpSrc->getOp();
117 TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(fwdOp));
118
119 typedef Thyra::TpetraLinearOp<SC, LO, GO, NO> ThyraTpetraLinOp;
120 const RCP<const ThyraTpetraLinOp> thyraTpetraFwdOp = rcp_dynamic_cast<const ThyraTpetraLinOp>(fwdOp);
121 TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(thyraTpetraFwdOp));
122
123 typedef Tpetra::Operator<SC, LO, GO, NO> TpetraLinOp;
124 const RCP<const TpetraLinOp> tpetraFwdOp = thyraTpetraFwdOp->getConstTpetraOperator();
125 TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(tpetraFwdOp));
126
127 typedef Tpetra::CrsMatrix<SC, LO, GO, NO> TpetraCrsMat;
128 const RCP<const TpetraCrsMat> tpetraFwdCrsMat = rcp_dynamic_cast<const TpetraCrsMat>(tpetraFwdOp);
129 TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(tpetraFwdCrsMat));
130
131 // Retrieve concrete preconditioner object
132 const Teuchos::Ptr<DefaultPreconditioner<SC> > defaultPrec = Teuchos::ptr(dynamic_cast<DefaultPreconditioner<SC>*>(prec));
133 TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(defaultPrec));
134
135 // Workaround since MueLu interface does not accept const matrix as input
136 const RCP<TpetraCrsMat> tpetraFwdCrsMatNonConst = rcp_const_cast<TpetraCrsMat>(tpetraFwdCrsMat);
137
138 // Create and compute the initial preconditioner
139
140 // Create a copy, as we may remove some things from the list
141 ParameterList paramList = *paramList_;
142
143 typedef Tpetra::MultiVector<SC, LO, GO, NO> MultiVector;
144 RCP<MultiVector> coords, nullspace, velCoords, presCoords;
145 ArrayRCP<LO> p2vMap;
146 Teko::LinearOp thA11, thA12, thA21, thA11_9Pt;
147 if (paramList.isType<RCP<MultiVector> >("Coordinates")) {
148 coords = paramList.get<RCP<MultiVector> >("Coordinates");
149 paramList.remove("Coordinates");
150 }
151 if (paramList.isType<RCP<MultiVector> >("Nullspace")) {
152 nullspace = paramList.get<RCP<MultiVector> >("Nullspace");
153 paramList.remove("Nullspace");
154 }
155 if (paramList.isType<RCP<MultiVector> >("Velcoords")) {
156 velCoords = paramList.get<RCP<MultiVector> >("Velcoords");
157 paramList.remove("Velcoords");
158 }
159 if (paramList.isType<RCP<MultiVector> >("Prescoords")) {
160 presCoords = paramList.get<RCP<MultiVector> >("Prescoords");
161 paramList.remove("Prescoords");
162 }
163 if (paramList.isType<ArrayRCP<LO> >("p2vMap")) {
164 p2vMap = paramList.get<ArrayRCP<LO> >("p2vMap");
165 paramList.remove("p2vMap");
166 }
167 if (paramList.isType<Teko::LinearOp>("A11")) {
168 thA11 = paramList.get<Teko::LinearOp>("A11");
169 paramList.remove("A11");
170 }
171 if (paramList.isType<Teko::LinearOp>("A12")) {
172 thA12 = paramList.get<Teko::LinearOp>("A12");
173 paramList.remove("A12");
174 }
175 if (paramList.isType<Teko::LinearOp>("A21")) {
176 thA21 = paramList.get<Teko::LinearOp>("A21");
177 paramList.remove("A21");
178 }
179 if (paramList.isType<Teko::LinearOp>("A11_9Pt")) {
180 thA11_9Pt = paramList.get<Teko::LinearOp>("A11_9Pt");
181 paramList.remove("A11_9Pt");
182 }
183
184 typedef MueLu::TpetraOperator<SC, LO, GO, NO> MueLuOperator;
185 const RCP<MueLuOperator> mueluPrecOp = Q2Q1MkPrecond(paramList, velCoords, presCoords, p2vMap, thA11, thA12, thA21, thA11_9Pt);
186
187 const RCP<LinearOpBase<SC> > thyraPrecOp = Thyra::createLinearOp(RCP<TpetraLinOp>(mueluPrecOp));
188 defaultPrec->initializeUnspecified(thyraPrecOp);
189}
190
191template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
193 uninitializePrec(PreconditionerBase<Scalar>* prec, RCP<const LinearOpSourceBase<Scalar> >* fwdOp, ESupportSolveUse* supportSolveUse) const {
194 // Check precondition
195 TEUCHOS_ASSERT(prec);
196
197 // Retrieve concrete preconditioner object
198 const Teuchos::Ptr<DefaultPreconditioner<SC> > defaultPrec = Teuchos::ptr(dynamic_cast<DefaultPreconditioner<SC>*>(prec));
199 TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(defaultPrec));
200
201 if (fwdOp) {
202 // TODO: Implement properly instead of returning default value
203 *fwdOp = Teuchos::null;
204 }
205
206 if (supportSolveUse) {
207 // TODO: Implement properly instead of returning default value
208 *supportSolveUse = Thyra::SUPPORT_SOLVE_UNSPECIFIED;
209 }
210
211 defaultPrec->uninitialize();
212}
213
214// Overridden from ParameterListAcceptor
215template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
217 TEUCHOS_TEST_FOR_EXCEPT(Teuchos::is_null(paramList));
218 paramList_ = paramList;
219}
220
221template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
222RCP<ParameterList>
226
227template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
228RCP<ParameterList>
230 RCP<ParameterList> savedParamList = paramList_;
231 paramList_ = Teuchos::null;
232 return savedParamList;
233}
234
235template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
236RCP<const ParameterList>
240
241template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
242RCP<const ParameterList>
244 static RCP<const ParameterList> validPL;
245
246 if (validPL.is_null())
247 validPL = rcp(new ParameterList());
248
249 return validPL;
250}
251
252template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
253RCP<MueLu::TpetraOperator<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
255 Q2Q1MkPrecond(const ParameterList& paramList,
256 const RCP<Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >& velCoords,
257 const RCP<Tpetra::MultiVector<Scalar, LocalOrdinal, GlobalOrdinal, Node> >& presCoords,
258 const ArrayRCP<LocalOrdinal>& p2vMap,
259 const Teko::LinearOp& thA11, const Teko::LinearOp& thA12, const Teko::LinearOp& thA21, const Teko::LinearOp& thA11_9Pt) const {
260 using Teuchos::null;
261
262 typedef Tpetra::CrsMatrix<SC, LO, GO, NO> TP_Crs;
263 typedef Tpetra::Operator<SC, LO, GO, NO> TP_Op;
264
265 typedef Xpetra::BlockedCrsMatrix<SC, LO, GO, NO> BlockedCrsMatrix;
266 typedef Xpetra::CrsMatrix<SC, LO, GO, NO> CrsMatrix;
267 typedef Xpetra::CrsMatrixWrap<SC, LO, GO, NO> CrsMatrixWrap;
268 typedef Xpetra::MapExtractorFactory<SC, LO, GO, NO> MapExtractorFactory;
269 typedef Xpetra::MapExtractor<SC, LO, GO, NO> MapExtractor;
270 typedef Xpetra::Map<LO, GO, NO> Map;
271 typedef Xpetra::MapFactory<LO, GO, NO> MapFactory;
272 typedef Xpetra::Matrix<SC, LO, GO, NO> Matrix;
273 typedef Xpetra::MatrixFactory<SC, LO, GO, NO> MatrixFactory;
274 typedef Xpetra::StridedMapFactory<LO, GO, NO> StridedMapFactory;
275
276 typedef MueLu::Hierarchy<SC, LO, GO, NO> Hierarchy;
277
278 const RCP<const Teuchos::Comm<int> > comm = velCoords->getMap()->getComm();
279
280 // Pull out Tpetra matrices
281 RCP<Thyra::LinearOpBase<SC> > ThNonConstA11 = rcp_const_cast<Thyra::LinearOpBase<double> >(thA11);
282 RCP<Thyra::LinearOpBase<SC> > ThNonConstA21 = rcp_const_cast<Thyra::LinearOpBase<double> >(thA21);
283 RCP<Thyra::LinearOpBase<SC> > ThNonConstA12 = rcp_const_cast<Thyra::LinearOpBase<double> >(thA12);
284 RCP<Thyra::LinearOpBase<SC> > ThNonConstA11_9Pt = rcp_const_cast<Thyra::LinearOpBase<double> >(thA11_9Pt);
285
286 RCP<TP_Op> TpetA11 = Thyra::TpetraOperatorVectorExtraction<SC, LO, GO, NO>::getTpetraOperator(ThNonConstA11);
287 RCP<TP_Op> TpetA21 = Thyra::TpetraOperatorVectorExtraction<SC, LO, GO, NO>::getTpetraOperator(ThNonConstA21);
288 RCP<TP_Op> TpetA12 = Thyra::TpetraOperatorVectorExtraction<SC, LO, GO, NO>::getTpetraOperator(ThNonConstA12);
289 RCP<TP_Op> TpetA11_9Pt = Thyra::TpetraOperatorVectorExtraction<SC, LO, GO, NO>::getTpetraOperator(ThNonConstA11_9Pt);
290
291 RCP<TP_Crs> TpetCrsA11 = rcp_dynamic_cast<TP_Crs>(TpetA11);
292 RCP<TP_Crs> TpetCrsA21 = rcp_dynamic_cast<TP_Crs>(TpetA21);
293 RCP<TP_Crs> TpetCrsA12 = rcp_dynamic_cast<TP_Crs>(TpetA12);
294 RCP<TP_Crs> TpetCrsA11_9Pt = rcp_dynamic_cast<TP_Crs>(TpetA11_9Pt);
295
296 RCP<Matrix> A_11 = Xpetra::toXpetra(TpetCrsA11);
297 RCP<Matrix> tmp_A_21 = Xpetra::toXpetra(TpetCrsA21); // needs map modification
298 RCP<Matrix> tmp_A_12 = Xpetra::toXpetra(TpetCrsA12); // needs map modification
299 RCP<Matrix> A_11_9Pt = Xpetra::toXpetra(TpetCrsA11_9Pt);
300
301 Xpetra::global_size_t numVel = A_11->getRowMap()->getLocalNumElements();
302 Xpetra::global_size_t numPres = tmp_A_21->getRowMap()->getLocalNumElements();
303
304 // Create new A21 with map so that the global indices of the row map starts
305 // from numVel+1 (where numVel is the number of rows in the A11 block)
306 RCP<const Map> domainMap2 = tmp_A_12->getDomainMap();
307 RCP<const Map> rangeMap2 = tmp_A_21->getRangeMap();
308 Xpetra::global_size_t numRows2 = rangeMap2->getLocalNumElements();
309 Xpetra::global_size_t numCols2 = domainMap2->getLocalNumElements();
310 ArrayView<const GO> rangeElem2 = rangeMap2->getLocalElementList();
311 ArrayView<const GO> domainElem2 = domainMap2->getLocalElementList();
312 ArrayView<const GO> rowElem1 = tmp_A_12->getRowMap()->getLocalElementList();
313 ArrayView<const GO> colElem1 = tmp_A_21->getColMap()->getLocalElementList();
314
315 Xpetra::UnderlyingLib lib = domainMap2->lib();
316 GO indexBase = domainMap2->getIndexBase();
317
318 Array<GO> newRowElem2(numRows2, 0);
319 for (Xpetra::global_size_t i = 0; i < numRows2; i++)
320 newRowElem2[i] = numVel + rangeElem2[i];
321
322 RCP<const Map> newRangeMap2 = MapFactory::Build(lib, numRows2, newRowElem2, indexBase, comm);
323
324 // maybe should be column map???
325 Array<GO> newColElem2(numCols2, 0);
326 for (Xpetra::global_size_t i = 0; i < numCols2; i++)
327 newColElem2[i] = numVel + domainElem2[i];
328
329 RCP<const Map> newDomainMap2 = MapFactory::Build(lib, numCols2, newColElem2, indexBase, comm);
330
331 RCP<Matrix> A_12 = MatrixFactory::Build(tmp_A_12->getRangeMap(), newDomainMap2, tmp_A_12->getLocalMaxNumRowEntries());
332 RCP<Matrix> A_21 = MatrixFactory::Build(newRangeMap2, tmp_A_21->getDomainMap(), tmp_A_21->getLocalMaxNumRowEntries());
333
334 RCP<CrsMatrix> A_11_crs = rcp_dynamic_cast<CrsMatrixWrap>(A_11)->getCrsMatrix();
335 RCP<CrsMatrix> A_12_crs = rcp_dynamic_cast<CrsMatrixWrap>(A_12)->getCrsMatrix();
336 RCP<CrsMatrix> A_21_crs = rcp_dynamic_cast<CrsMatrixWrap>(A_21)->getCrsMatrix();
337 RCP<CrsMatrix> A_11_crs_9Pt = rcp_dynamic_cast<CrsMatrixWrap>(A_11_9Pt)->getCrsMatrix();
338
339#if 0
340 RCP<Matrix> A_22 = MatrixFactory::Build(newRangeMap2, newDomainMap2, 1);
341 RCP<CrsMatrix> A_22_crs = rcp_dynamic_cast<CrsMatrixWrap>(A_22) ->getCrsMatrix();
342
343 // FIXME: why do we need to perturb A_22?
344 Array<SC> smallVal(1, 1.0e-10);
345
346 // FIXME: could this be sped up using expertStaticFillComplete?
347 // There was an attempt on doing it, but it did not do the proper thing
348 // with empty columns. See git history
349 ArrayView<const LO> inds;
350 ArrayView<const SC> vals;
351 for (LO row = 0; row < as<LO>(numRows2); ++row) {
352 tmp_A_21->getLocalRowView(row, inds, vals);
353
354 size_t nnz = inds.size();
355 Array<GO> newInds(nnz, 0);
356 for (LO colID = 0; colID < as<LO>(nnz); colID++)
357 newInds[colID] = colElem1[inds[colID]];
358
359 A_21_crs->insertGlobalValues(newRowElem2[row], newInds, vals);
360 A_22_crs->insertGlobalValues(newRowElem2[row], Array<LO>(1, newRowElem2[row]), smallVal);
361 }
362 A_21_crs->fillComplete(tmp_A_21->getDomainMap(), newRangeMap2);
363 A_22_crs->fillComplete(newDomainMap2, newRangeMap2);
364#else
365 RCP<Matrix> A_22 = Teuchos::null;
366 RCP<CrsMatrix> A_22_crs = Teuchos::null;
367
368 ArrayView<const LO> inds;
369 ArrayView<const SC> vals;
370 for (LO row = 0; row < as<LO>(numRows2); ++row) {
371 tmp_A_21->getLocalRowView(row, inds, vals);
372
373 size_t nnz = inds.size();
374 Array<GO> newInds(nnz, 0);
375 for (LO colID = 0; colID < as<LO>(nnz); colID++)
376 newInds[colID] = colElem1[inds[colID]];
377
378 A_21_crs->insertGlobalValues(newRowElem2[row], newInds, vals);
379 }
380 A_21_crs->fillComplete(tmp_A_21->getDomainMap(), newRangeMap2);
381#endif
382
383 // Create new A12 with map so that the global indices of the ColMap starts
384 // from numVel+1 (where numVel is the number of rows in the A11 block)
385 for (LO row = 0; row < as<LO>(tmp_A_12->getRowMap()->getLocalNumElements()); ++row) {
386 tmp_A_12->getLocalRowView(row, inds, vals);
387
388 size_t nnz = inds.size();
389 Array<GO> newInds(nnz, 0);
390 for (LO colID = 0; colID < as<LO>(nnz); colID++)
391 newInds[colID] = newColElem2[inds[colID]];
392
393 A_12_crs->insertGlobalValues(rowElem1[row], newInds, vals);
394 }
395 A_12_crs->fillComplete(newDomainMap2, tmp_A_12->getRangeMap());
396
397 RCP<Matrix> A_12_abs = Absolute(*A_12);
398 RCP<Matrix> A_21_abs = Absolute(*A_21);
399
400 // =========================================================================
401 // Preconditioner construction - I (block)
402 // =========================================================================
403 RCP<Teuchos::FancyOStream> fancy = Teuchos::fancyOStream(Teuchos::rcpFromRef(std::cout));
404 Teuchos::FancyOStream& out = *fancy;
405 out.setOutputToRootOnly(0);
406 RCP<Matrix> BBt = Xpetra::MatrixMatrix<SC, LO, GO, NO>::Multiply(*A_21, false, *A_12, false, out);
407 RCP<Matrix> BBt_abs = Xpetra::MatrixMatrix<SC, LO, GO, NO>::Multiply(*A_21_abs, false, *A_12_abs, false, out);
408
409 SC dropTol = (paramList.get<int>("useFilters") ? paramList.get<double>("tau_1") : 0.00);
410 RCP<Matrix> filteredA = FilterMatrix(*A_11, *A_11, dropTol);
411 RCP<Matrix> filteredB = FilterMatrix(*BBt, *BBt_abs, dropTol);
412
413 RCP<Matrix> fA_11_crs = rcp_dynamic_cast<CrsMatrixWrap>(filteredA);
414 RCP<Matrix> fA_12_crs = Teuchos::null;
415 RCP<Matrix> fA_21_crs = Teuchos::null;
416 RCP<Matrix> fA_22_crs = rcp_dynamic_cast<CrsMatrixWrap>(filteredB);
417
418 // Build the large filtered matrix which requires strided maps
419 std::vector<size_t> stridingInfo(1, 1);
420 int stridedBlockId = -1;
421
422 Array<GO> elementList(numVel + numPres); // Not RCP ... does this get cleared ?
423 Array<GO> velElem = A_12_crs->getRangeMap()->getLocalElementList();
424 Array<GO> presElem = A_21_crs->getRangeMap()->getLocalElementList();
425
426 for (Xpetra::global_size_t i = 0; i < numVel; i++) elementList[i] = velElem[i];
427 for (Xpetra::global_size_t i = numVel; i < numVel + numPres; i++) elementList[i] = presElem[i - numVel];
428 RCP<const Map> fullMap = StridedMapFactory::Build(Xpetra::UseTpetra, numVel + numPres, elementList(), indexBase, stridingInfo, comm);
429
430 std::vector<RCP<const Map> > partMaps(2);
431 partMaps[0] = StridedMapFactory::Build(Xpetra::UseTpetra, numVel, velElem, indexBase, stridingInfo, comm);
432 partMaps[1] = StridedMapFactory::Build(Xpetra::UseTpetra, numPres, presElem, indexBase, stridingInfo, comm, stridedBlockId, numVel);
433
434 // Map extractors are necessary for Xpetra's block operators
435 RCP<const MapExtractor> mapExtractor = MapExtractorFactory::Build(fullMap, partMaps);
436 RCP<BlockedCrsMatrix> fA = rcp(new BlockedCrsMatrix(mapExtractor, mapExtractor, 10));
437 fA->setMatrix(0, 0, fA_11_crs);
438 fA->setMatrix(0, 1, fA_12_crs);
439 fA->setMatrix(1, 0, fA_21_crs);
440 fA->setMatrix(1, 1, fA_22_crs);
441 fA->fillComplete();
442
443 // -------------------------------------------------------------------------
444 // Preconditioner construction - I.a (filtered hierarchy)
445 // -------------------------------------------------------------------------
447 SetDependencyTree(M, paramList);
448
449 RCP<Hierarchy> H = rcp(new Hierarchy);
450 RCP<MueLu::Level> finestLevel = H->GetLevel(0);
451 finestLevel->Set("A", rcp_dynamic_cast<Matrix>(fA));
452 finestLevel->Set("p2vMap", p2vMap);
453 finestLevel->Set("CoordinatesVelocity", Xpetra::toXpetra(velCoords));
454 finestLevel->Set("CoordinatesPressure", Xpetra::toXpetra(presCoords));
455 finestLevel->Set("AForPat", A_11_9Pt);
456 H->SetMaxCoarseSize(MUELU_GPD("coarse: max size", int, 1));
457
458 // The first invocation of Setup() builds the hierarchy using the filtered
459 // matrix. This build includes the grid transfers but not the creation of the
460 // smoothers.
461 // NOTE: we need to indicate what should be kept from the first invocation
462 // for the second invocation, which then focuses on building the smoothers
463 // for the unfiltered matrix.
464 H->Keep("P", M.GetFactory("P").get());
465 H->Keep("R", M.GetFactory("R").get());
466 H->Keep("Ptent", M.GetFactory("Ptent").get());
467 H->Setup(M, 0, MUELU_GPD("max levels", int, 3));
468
469#if 0
470 for (int i = 1; i < H->GetNumLevels(); i++) {
471 RCP<Matrix> P = H->GetLevel(i)->template Get<RCP<Matrix> >("P");
472 RCP<BlockedCrsMatrix> Pcrs = rcp_dynamic_cast<BlockedCrsMatrix>(P);
473 RCP<Matrix> Pp = Pcrs->getMatrix(1,1);
474 RCP<Matrix> Pv = Pcrs->getMatrix(0,0);
475
476 Xpetra::IO<SC,LO,GO,NO>::Write("Pp_l" + MueLu::toString(i) + ".mm", *Pp);
477 Xpetra::IO<SC,LO,GO,NO>::Write("Pv_l" + MueLu::toString(i) + ".mm", *Pv);
478 }
479#endif
480
481 // -------------------------------------------------------------------------
482 // Preconditioner construction - I.b (smoothers for unfiltered matrix)
483 // -------------------------------------------------------------------------
484 std::string smootherType = MUELU_GPD("smoother: type", std::string, "vanka");
485 ParameterList smootherParams;
486 if (paramList.isSublist("smoother: params"))
487 smootherParams = paramList.sublist("smoother: params");
488 M.SetFactory("Smoother", GetSmoother(smootherType, smootherParams, false /*coarseSolver?*/));
489
490 std::string coarseType = MUELU_GPD("coarse: type", std::string, "direct");
491 ParameterList coarseParams;
492 if (paramList.isSublist("coarse: params"))
493 coarseParams = paramList.sublist("coarse: params");
494 M.SetFactory("CoarseSolver", GetSmoother(coarseType, coarseParams, true /*coarseSolver?*/));
495
496#ifdef HAVE_MUELU_DEBUG
497 M.ResetDebugData();
498#endif
499
500 RCP<BlockedCrsMatrix> A = rcp(new BlockedCrsMatrix(mapExtractor, mapExtractor, 10));
501 A->setMatrix(0, 0, A_11);
502 A->setMatrix(0, 1, A_12);
503 A->setMatrix(1, 0, A_21);
504 A->setMatrix(1, 1, A_22);
505 A->fillComplete();
506
507 H->GetLevel(0)->Set("A", rcp_dynamic_cast<Matrix>(A));
508
509 H->Setup(M, 0, H->GetNumLevels());
510
511 return rcp(new MueLu::TpetraOperator<SC, LO, GO, NO>(H));
512}
513
514template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
515RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
517 FilterMatrix(Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& A, Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& Pattern, Scalar dropTol) const {
518 typedef Xpetra::Matrix<SC, LO, GO, NO> Matrix;
519 typedef MueLu::AmalgamationFactory<SC, LO, GO, NO> AmalgamationFactory;
520 typedef MueLu::CoalesceDropFactory<SC, LO, GO, NO> CoalesceDropFactory;
521 typedef MueLu::FilteredAFactory<SC, LO, GO, NO> FilteredAFactory;
522 typedef MueLu::LWGraph<LO, GO, NO> GraphBase;
523
524 RCP<GraphBase> filteredGraph;
525 {
526 // Get graph pattern for the pattern matrix
527 MueLu::Level level;
528 level.SetLevelID(1);
529
530 level.Set<RCP<Matrix> >("A", rcpFromRef(Pattern));
531
532 RCP<AmalgamationFactory> amalgFactory = rcp(new AmalgamationFactory());
533
534 RCP<CoalesceDropFactory> dropFactory = rcp(new CoalesceDropFactory());
535 ParameterList dropParams = *(dropFactory->GetValidParameterList());
536 dropParams.set("lightweight wrap", true);
537 dropParams.set("aggregation: drop scheme", "classical");
538 dropParams.set("aggregation: drop tol", dropTol);
539 // dropParams.set("Dirichlet detection threshold", <>);
540 dropFactory->SetParameterList(dropParams);
541 dropFactory->SetFactory("UnAmalgamationInfo", amalgFactory);
542
543 // Build
544 level.Request("Graph", dropFactory.get());
545 dropFactory->Build(level);
546
547 level.Get("Graph", filteredGraph, dropFactory.get());
548 }
549
550 RCP<Matrix> filteredA;
551 {
552 // Filter the original matrix, not the pattern one
553 MueLu::Level level;
554 level.SetLevelID(1);
555
556 level.Set("A", rcpFromRef(A));
557 level.Set("Graph", filteredGraph);
558 level.Set("Filtering", true);
559
560 RCP<FilteredAFactory> filterFactory = rcp(new FilteredAFactory());
561 ParameterList filterParams = *(filterFactory->GetValidParameterList());
562 // We need a graph that has proper structure in it. Therefore, we need to
563 // drop older pattern, i.e. not to reuse it
564 filterParams.set("filtered matrix: reuse graph", false);
565 filterParams.set("filtered matrix: use lumping", false);
566 filterFactory->SetParameterList(filterParams);
567
568 // Build
569 level.Request("A", filterFactory.get());
570 filterFactory->Build(level);
571
572 level.Get("A", filteredA, filterFactory.get());
573 }
574
575 // Zero out row sums by fixing the diagonal
576 filteredA->resumeFill();
577 size_t numRows = filteredA->getRowMap()->getLocalNumElements();
578 for (size_t i = 0; i < numRows; i++) {
579 ArrayView<const LO> inds;
580 ArrayView<const SC> vals;
581 filteredA->getLocalRowView(i, inds, vals);
582
583 size_t nnz = inds.size();
584
585 Array<SC> valsNew = vals;
586
587 LO diagIndex = -1;
588 SC diag = Teuchos::ScalarTraits<SC>::zero();
589 for (size_t j = 0; j < nnz; j++) {
590 diag += vals[j];
591 if (inds[j] == Teuchos::as<int>(i))
592 diagIndex = j;
593 }
594 TEUCHOS_TEST_FOR_EXCEPTION(diagIndex == -1, MueLu::Exceptions::RuntimeError,
595 "No diagonal found");
596 if (nnz <= 1)
597 continue;
598
599 valsNew[diagIndex] -= diag;
600
601 filteredA->replaceLocalValues(i, inds, valsNew);
602 }
603 filteredA->fillComplete();
604
605 return filteredA;
606}
607
608template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
611 typedef MueLu::BlockedPFactory<SC, LO, GO, NO> BlockedPFactory;
612 typedef MueLu::GenericRFactory<SC, LO, GO, NO> GenericRFactory;
613 typedef MueLu::BlockedRAPFactory<SC, LO, GO, NO> BlockedRAPFactory;
614 typedef MueLu::SmootherFactory<SC, LO, GO, NO> SmootherFactory;
615 typedef MueLu::BlockedDirectSolver<SC, LO, GO, NO> BlockedDirectSolver;
616 typedef MueLu::FactoryManager<SC, LO, GO, NO> FactoryManager;
617
618 // Pressure and velocity dependency trees are identical. The only
619 // difference is that pressure has to go first, so that velocity can use
620 // some of pressure data
621 RCP<FactoryManager> M11 = rcp(new FactoryManager()), M22 = rcp(new FactoryManager());
622 M11->SetKokkosRefactor(paramList.get<bool>("use kokkos refactor"));
623 M22->SetKokkosRefactor(paramList.get<bool>("use kokkos refactor"));
624 SetBlockDependencyTree(*M11, 0, 0, "velocity", paramList);
625 SetBlockDependencyTree(*M22, 1, 1, "pressure", paramList);
626
627 RCP<BlockedPFactory> PFact = rcp(new BlockedPFactory());
628 ParameterList pParamList = *(PFact->GetValidParameterList());
629 pParamList.set("backwards", true); // do pressure first
630 PFact->SetParameterList(pParamList);
631 PFact->AddFactoryManager(M11);
632 PFact->AddFactoryManager(M22);
633 M.SetFactory("P", PFact);
634
635 RCP<GenericRFactory> RFact = rcp(new GenericRFactory());
636 RFact->SetFactory("P", PFact);
637 M.SetFactory("R", RFact);
638
639 RCP<MueLu::Factory> AcFact = rcp(new BlockedRAPFactory());
640 AcFact->SetFactory("R", RFact);
641 AcFact->SetFactory("P", PFact);
642 M.SetFactory("A", AcFact);
643
644 // Smoothers will be set later
645 M.SetFactory("Smoother", Teuchos::null);
646
647 RCP<MueLu::Factory> coarseFact = rcp(new SmootherFactory(rcp(new BlockedDirectSolver()), Teuchos::null));
648 // M.SetFactory("CoarseSolver", coarseFact);
649 M.SetFactory("CoarseSolver", Teuchos::null);
650}
651
652template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
654 SetBlockDependencyTree(MueLu::FactoryManager<Scalar, LocalOrdinal, GlobalOrdinal, Node>& M, LocalOrdinal row, LocalOrdinal col, const std::string& mode, const ParameterList& paramList) const {
655 typedef MueLu::ConstraintFactory<SC, LO, GO, NO> ConstraintFactory;
656 typedef MueLu::EminPFactory<SC, LO, GO, NO> EminPFactory;
657 typedef MueLu::GenericRFactory<SC, LO, GO, NO> GenericRFactory;
658 typedef MueLu::PatternFactory<SC, LO, GO, NO> PatternFactory;
659 typedef MueLu::Q2Q1PFactory<SC, LO, GO, NO> Q2Q1PFactory;
660 typedef MueLu::Q2Q1uPFactory<SC, LO, GO, NO> Q2Q1uPFactory;
661 typedef MueLu::SubBlockAFactory<SC, LO, GO, NO> SubBlockAFactory;
662
663 RCP<SubBlockAFactory> AFact = rcp(new SubBlockAFactory());
664 AFact->SetFactory("A", MueLu::NoFactory::getRCP());
665 AFact->SetParameter("block row", Teuchos::ParameterEntry(row));
666 AFact->SetParameter("block col", Teuchos::ParameterEntry(col));
667 M.SetFactory("A", AFact);
668
669 RCP<MueLu::Factory> Q2Q1Fact;
670
671 const bool isStructured = false;
672
673 if (isStructured) {
674 Q2Q1Fact = rcp(new Q2Q1PFactory);
675
676 } else {
677 Q2Q1Fact = rcp(new Q2Q1uPFactory);
678 ParameterList q2q1ParamList = *(Q2Q1Fact->GetValidParameterList());
679 q2q1ParamList.set("mode", mode);
680 if (paramList.isParameter("dump status"))
681 q2q1ParamList.set("dump status", paramList.get<bool>("dump status"));
682 if (paramList.isParameter("phase2"))
683 q2q1ParamList.set("phase2", paramList.get<bool>("phase2"));
684 if (paramList.isParameter("tau_2"))
685 q2q1ParamList.set("tau_2", paramList.get<double>("tau_2"));
686 Q2Q1Fact->SetParameterList(q2q1ParamList);
687 }
688 Q2Q1Fact->SetFactory("A", AFact);
689 M.SetFactory("Ptent", Q2Q1Fact);
690
691 RCP<PatternFactory> patternFact = rcp(new PatternFactory);
692 ParameterList patternParams = *(patternFact->GetValidParameterList());
693 // Our prolongator constructs the exact pattern we are going to use,
694 // therefore we do not expand it
695 patternParams.set("emin: pattern order", 0);
696 patternFact->SetParameterList(patternParams);
697 patternFact->SetFactory("A", AFact);
698 patternFact->SetFactory("P", Q2Q1Fact);
699 M.SetFactory("Ppattern", patternFact);
700
701 RCP<ConstraintFactory> CFact = rcp(new ConstraintFactory);
702 CFact->SetFactory("Ppattern", patternFact);
703 M.SetFactory("Constraint", CFact);
704
705 RCP<EminPFactory> EminPFact = rcp(new EminPFactory());
706 ParameterList eminParams = *(EminPFact->GetValidParameterList());
707 if (paramList.isParameter("emin: num iterations"))
708 eminParams.set("emin: num iterations", paramList.get<int>("emin: num iterations"));
709 if (mode == "pressure") {
710 eminParams.set("emin: iterative method", "cg");
711 } else {
712 eminParams.set("emin: iterative method", "gmres");
713 if (paramList.isParameter("emin: iterative method"))
714 eminParams.set("emin: iterative method", paramList.get<std::string>("emin: iterative method"));
715 }
716 EminPFact->SetParameterList(eminParams);
717 EminPFact->SetFactory("A", AFact);
718 EminPFact->SetFactory("Constraint", CFact);
719 EminPFact->SetFactory("P", Q2Q1Fact);
720 M.SetFactory("P", EminPFact);
721
722 if (mode == "velocity" && (!paramList.isParameter("velocity: use transpose") || paramList.get<bool>("velocity: use transpose") == false)) {
723 // Pressure system is symmetric, so it does not matter
724 // Velocity system may benefit from running emin in restriction mode (with A^T)
725 RCP<GenericRFactory> RFact = rcp(new GenericRFactory());
726 RFact->SetFactory("P", EminPFact);
727 M.SetFactory("R", RFact);
728 }
729}
730
731template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
732RCP<MueLu::FactoryBase>
734 GetSmoother(const std::string& type, const ParameterList& paramList, bool coarseSolver) const {
735 typedef Teuchos::ParameterEntry ParameterEntry;
736
737 typedef MueLu::BlockedDirectSolver<SC, LO, GO, NO> BlockedDirectSolver;
738 typedef MueLu::BraessSarazinSmoother<SC, LO, GO, NO> BraessSarazinSmoother;
739 typedef MueLu::DirectSolver<SC, LO, GO, NO> DirectSolver;
740 typedef MueLu::FactoryManager<SC, LO, GO, NO> FactoryManager;
741 typedef MueLu::SchurComplementFactory<SC, LO, GO, NO> SchurComplementFactory;
742 typedef MueLu::SmootherFactory<SC, LO, GO, NO> SmootherFactory;
743 typedef MueLu::SmootherPrototype<SC, LO, GO, NO> SmootherPrototype;
744 typedef MueLu::TrilinosSmoother<SC, LO, GO, NO> TrilinosSmoother;
745
746 RCP<SmootherPrototype> smootherPrototype;
747 if (type == "none") {
748 return Teuchos::null;
749
750 } else if (type == "vanka") {
751 // Set up Vanka smoothing via a combination of Schwarz and block relaxation.
752 ParameterList schwarzList;
753 schwarzList.set("schwarz: overlap level", as<int>(0));
754 schwarzList.set("schwarz: zero starting solution", false);
755 schwarzList.set("subdomain solver name", "Block_Relaxation");
756
757 ParameterList& innerSolverList = schwarzList.sublist("subdomain solver parameters");
758 innerSolverList.set("partitioner: type", "user");
759 innerSolverList.set("partitioner: overlap", MUELU_GPD("partitioner: overlap", int, 1));
760 innerSolverList.set("relaxation: type", MUELU_GPD("relaxation: type", std::string, "Gauss-Seidel"));
761 innerSolverList.set("relaxation: sweeps", MUELU_GPD("relaxation: sweeps", int, 1));
762 innerSolverList.set("relaxation: damping factor", MUELU_GPD("relaxation: damping factor", double, 0.5));
763 innerSolverList.set("relaxation: zero starting solution", false);
764 // innerSolverList.set("relaxation: backward mode", MUELU_GPD("relaxation: backward mode", bool, true); NOT SUPPORTED YET
765
766 std::string ifpackType = "SCHWARZ";
767
768 smootherPrototype = rcp(new TrilinosSmoother(ifpackType, schwarzList));
769
770 } else if (type == "schwarz") {
771 std::string ifpackType = "SCHWARZ";
772
773 smootherPrototype = rcp(new TrilinosSmoother(ifpackType, paramList));
774
775 } else if (type == "braess-sarazin") {
776 // Define smoother/solver for BraessSarazin
777 SC omega = MUELU_GPD("bs: omega", double, 1.0);
778 bool lumping = MUELU_GPD("bs: lumping", bool, false);
779
780 RCP<SchurComplementFactory> schurFact = rcp(new SchurComplementFactory());
781 schurFact->SetParameter("omega", ParameterEntry(omega));
782 schurFact->SetParameter("lumping", ParameterEntry(lumping));
783 schurFact->SetFactory("A", MueLu::NoFactory::getRCP());
784
785 // Schur complement solver
786 RCP<SmootherPrototype> schurSmootherPrototype;
787 std::string schurSmootherType = (paramList.isParameter("schur smoother: type") ? paramList.get<std::string>("schur smoother: type") : "RELAXATION");
788 if (schurSmootherType == "RELAXATION") {
789 ParameterList schurSmootherParams = paramList.sublist("schur smoother: params");
790 // schurSmootherParams.set("relaxation: damping factor", omega);
791 schurSmootherPrototype = rcp(new TrilinosSmoother(schurSmootherType, schurSmootherParams));
792 } else {
793 schurSmootherPrototype = rcp(new DirectSolver());
794 }
795 schurSmootherPrototype->SetFactory("A", schurFact);
796
797 RCP<SmootherFactory> schurSmootherFact = rcp(new SmootherFactory(schurSmootherPrototype));
798
799 // Define temporary FactoryManager that is used as input for BraessSarazin smoother
800 RCP<FactoryManager> braessManager = rcp(new FactoryManager());
801 braessManager->SetFactory("A", schurFact); // SchurComplement operator for correction step (defined as "A")
802 braessManager->SetFactory("Smoother", schurSmootherFact); // solver/smoother for correction step
803 braessManager->SetFactory("PreSmoother", schurSmootherFact);
804 braessManager->SetFactory("PostSmoother", schurSmootherFact);
805 braessManager->SetIgnoreUserData(true); // always use data from factories defined in factory manager
806
807 smootherPrototype = rcp(new BraessSarazinSmoother());
808 smootherPrototype->SetParameter("Sweeps", ParameterEntry(MUELU_GPD("bs: sweeps", int, 1)));
809 smootherPrototype->SetParameter("lumping", ParameterEntry(lumping));
810 smootherPrototype->SetParameter("Damping factor", ParameterEntry(omega));
811 smootherPrototype->SetParameter("q2q1 mode", ParameterEntry(true));
812 rcp_dynamic_cast<BraessSarazinSmoother>(smootherPrototype)->AddFactoryManager(braessManager, 0); // set temporary factory manager in BraessSarazin smoother
813
814 } else if (type == "ilu") {
815 std::string ifpackType = "RILUK";
816
817 smootherPrototype = rcp(new TrilinosSmoother(ifpackType, paramList));
818
819 } else if (type == "direct") {
820 smootherPrototype = rcp(new BlockedDirectSolver());
821
822 } else {
823 throw MueLu::Exceptions::RuntimeError("Unknown smoother type: \"" + type + "\"");
824 }
825
826 return coarseSolver ? rcp(new SmootherFactory(smootherPrototype, Teuchos::null)) : rcp(new SmootherFactory(smootherPrototype));
827}
828
829template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
830RCP<Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node> >
831MueLuTpetraQ2Q1PreconditionerFactory<Scalar, LocalOrdinal, GlobalOrdinal, Node>::Absolute(const Xpetra::Matrix<Scalar, LocalOrdinal, GlobalOrdinal, Node>& A) const {
832 typedef Xpetra::CrsMatrix<SC, LO, GO, NO> CrsMatrix;
833 typedef Xpetra::CrsMatrixWrap<SC, LO, GO, NO> CrsMatrixWrap;
834 typedef Xpetra::Matrix<SC, LO, GO, NO> Matrix;
835
836 const CrsMatrixWrap& Awrap = dynamic_cast<const CrsMatrixWrap&>(A);
837
838 ArrayRCP<const size_t> iaA;
839 ArrayRCP<const LO> jaA;
840 ArrayRCP<const SC> valA;
841 Awrap.getCrsMatrix()->getAllValues(iaA, jaA, valA);
842
843 ArrayRCP<size_t> iaB(iaA.size());
844 ArrayRCP<LO> jaB(jaA.size());
845 ArrayRCP<SC> valB(valA.size());
846 for (int i = 0; i < iaA.size(); i++) iaB[i] = iaA[i];
847 for (int i = 0; i < jaA.size(); i++) jaB[i] = jaA[i];
848 for (int i = 0; i < valA.size(); i++) valB[i] = Teuchos::ScalarTraits<SC>::magnitude(valA[i]);
849
850 RCP<Matrix> B = rcp(new CrsMatrixWrap(A.getRowMap(), A.getColMap(), 0));
851 RCP<CrsMatrix> Bcrs = toCrsMatrix(B);
852 Bcrs->setAllValues(iaB, jaB, valB);
853 Bcrs->expertStaticFillComplete(A.getDomainMap(), A.getRangeMap());
854
855 return B;
856}
857
858// Public functions overridden from Teuchos::Describable
859template <class Scalar, class LocalOrdinal, class GlobalOrdinal, class Node>
861 return "Thyra::MueLuTpetraQ2Q1PreconditionerFactory";
862}
863
864} // namespace Thyra
865
866#endif
867#endif // ifdef THYRA_MUELU_TPETRA_Q2Q1PRECONDITIONER_FACTORY_DEF_HPP
Various adapters that will create a MueLu preconditioner that is a Tpetra::Operator.
MueLu::DefaultLocalOrdinal LocalOrdinal
MueLu::DefaultScalar Scalar
#define MUELU_GPD(name, type, defaultValue)
AmalgamationFactory for subblocks of strided map based amalgamation data.
direct solver for nxn blocked matrices
Factory for building blocked, segregated prolongation operators.
Factory for building coarse matrices.
BraessSarazin smoother for 2x2 block matrices.
Factory for creating a graph based on a given matrix.
Factory for building the constraint operator.
Class that encapsulates direct solvers. Autoselection of AmesosSmoother or Amesos2Smoother according ...
Factory for building Energy Minimization prolongators.
Exception throws to report errors in the internal logical of the program.
This class specifies the default factory that should generate some data on a Level if the data does n...
void SetFactory(const std::string &varName, const RCP< const FactoryBase > &factory)
Set Factory.
const RCP< const FactoryBase > GetFactory(const std::string &varName) const
Get factory associated with a particular data name.
Factory for building filtered matrices using filtered graphs.
Factory for building restriction operators using a prolongator factory.
Provides methods to build a multigrid hierarchy and apply multigrid cycles.
Lightweight MueLu representation of a compressed row storage graph.
Class that holds all level-specific information.
void SetLevelID(int levelID)
Set level number.
T & Get(const std::string &ename, const FactoryBase *factory=NoFactory::get())
Get data without decrementing associated storage counter (i.e., read-only access)....
void Set(const std::string &ename, const T &entry, const FactoryBase *factory=NoFactory::get())
void Request(const FactoryBase &factory)
Increment the storage counter for all the inputs of a factory.
static const RCP< const NoFactory > getRCP()
Static Get() functions.
Factory for building nonzero patterns for energy minimization.
Factory for building the Schur Complement for a 2x2 block matrix.
Generic Smoother Factory for generating the smoothers of the MG hierarchy.
Base class for smoother prototypes.
Factory for building a thresholded operator.
Wraps an existing MueLu::Hierarchy as a Tpetra::Operator.
Class that encapsulates external library smoothers.
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Teuchos::RCP< Xpetra::Matrix< SC, LO, GO, NO > > FilterMatrix(Xpetra::Matrix< SC, LO, GO, NO > &A, Xpetra::Matrix< SC, LO, GO, NO > &Pattern, SC dropTol) const
void SetDependencyTree(MueLu::FactoryManager< SC, LO, GO, NO > &M, const ParameterList &paramList) const
Teuchos::RCP< Xpetra::Matrix< SC, LO, GO, NO > > Absolute(const Xpetra::Matrix< SC, LO, GO, NO > &A) const
void uninitializePrec(PreconditionerBase< SC > *prec, Teuchos::RCP< const LinearOpSourceBase< SC > > *fwdOp, ESupportSolveUse *supportSolveUse) const
void SetBlockDependencyTree(MueLu::FactoryManager< SC, LO, GO, NO > &M, LO row, LO col, const std::string &mode, const ParameterList &paramList) const
Teuchos::RCP< MueLu::TpetraOperator< SC, LO, GO, NO > > Q2Q1MkPrecond(const ParameterList &paramList, const Teuchos::RCP< Tpetra::MultiVector< SC, LO, GO, NO > > &velCoords, const Teuchos::RCP< Tpetra::MultiVector< SC, LO, GO, NO > > &presCoords, const Teuchos::ArrayRCP< LO > &p2vMap, const Teko::LinearOp &thA11, const Teko::LinearOp &thA12, const Teko::LinearOp &thA21, const Teko::LinearOp &thA11_9Pt) const
RCP< MueLu::FactoryBase > GetSmoother(const std::string &type, const ParameterList &paramList, bool coarseSolver) const
void initializePrec(const Teuchos::RCP< const LinearOpSourceBase< SC > > &fwdOp, PreconditionerBase< SC > *prec, const ESupportSolveUse supportSolveUse) const
void setParameterList(const Teuchos::RCP< Teuchos::ParameterList > &paramList)
Teuchos::RCP< const Teuchos::ParameterList > getParameterList() const
std::string toString(const T &what)
Little helper function to convert non-string types to strings.