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