Teko  Version of the Day
 All Classes Files Functions Variables Pages
Teko_NeumannSeriesPreconditionerFactory.hpp
1 // @HEADER
2 // *****************************************************************************
3 // Teko: A package for block and physics based preconditioning
4 //
5 // Copyright 2010 NTESS and the Teko contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef __Teko_NeumannSeriesPreconditionerFactory_hpp__
11 #define __Teko_NeumannSeriesPreconditionerFactory_hpp__
12 
13 #include "Teko_NeumannSeriesPreconditionerFactoryDecl.hpp"
14 
15 #include "Thyra_DefaultPreconditioner.hpp"
16 #include "Thyra_DefaultPreconditioner.hpp"
17 #include "Thyra_DefaultScaledAdjointLinearOp.hpp"
18 #include "Thyra_DefaultAddedLinearOp.hpp"
19 #include "Thyra_DefaultMultipliedLinearOp.hpp"
20 #include "Thyra_DefaultIdentityLinearOp.hpp"
21 
22 #include "Teuchos_Array.hpp"
23 #include "Teuchos_StandardParameterEntryValidators.hpp"
24 
25 namespace Teko {
26 
27 using Teuchos::RCP;
28 using Teuchos::rcp;
29 
30 static RCP<Teuchos::StringToIntegralParameterEntryValidator<Teko::DiagonalType> > scalingTypeVdtor;
31 
32 template <typename ScalarT>
33 NeumannSeriesPreconditionerFactory<ScalarT>::NeumannSeriesPreconditionerFactory()
34  : numberOfTerms_(1), scalingType_(Teko::NotDiag) {}
35 
37 template <typename ScalarT>
38 bool NeumannSeriesPreconditionerFactory<ScalarT>::isCompatible(
39  const Thyra::LinearOpSourceBase<ScalarT> & /* fwdOpSrc */) const {
40  return true;
41 }
42 
44 template <typename ScalarT>
45 RCP<Thyra::PreconditionerBase<ScalarT> > NeumannSeriesPreconditionerFactory<ScalarT>::createPrec()
46  const {
47  return rcp(new Thyra::DefaultPreconditioner<ScalarT>());
48 }
49 
58 template <typename ScalarT>
59 void NeumannSeriesPreconditionerFactory<ScalarT>::initializePrec(
60  const RCP<const Thyra::LinearOpSourceBase<ScalarT> > &fwdOpSrc,
61  Thyra::PreconditionerBase<ScalarT> *prec,
62  const Thyra::ESupportSolveUse /* supportSolveUse */) const {
63  using Thyra::add;
64  using Thyra::multiply;
65  using Thyra::scale;
66 
67  RCP<const Thyra::LinearOpBase<ScalarT> > M; // left-preconditioner
68  RCP<const Thyra::LinearOpBase<ScalarT> > A = fwdOpSrc->getOp();
69  if (scalingType_ != Teko::NotDiag) {
70  M = Teko::getInvDiagonalOp(A, scalingType_);
71  A = Thyra::multiply(M, A);
72  }
73 
74  RCP<const Thyra::LinearOpBase<ScalarT> > id = Thyra::identity<ScalarT>(A->range()); // I
75  RCP<const Thyra::LinearOpBase<ScalarT> > idMA = add(id, scale(-1.0, A)); // I - A
76 
77  RCP<const Thyra::LinearOpBase<ScalarT> > precOp;
78  if (numberOfTerms_ == 1) {
79  // no terms requested, just return identity matrix
80  precOp = id;
81  } else {
82  int iters = numberOfTerms_ - 1;
83  // use Horner's method to computed higher order polynomials
84  precOp = add(scale(2.0, id), scale(-1.0, A)); // I + (I - A)
85  for (int i = 0; i < iters; i++) precOp = add(id, multiply(idMA, precOp)); // I + (I - A) * p
86  }
87 
88  // multiply by the preconditioner if it exists
89  if (M != Teuchos::null) precOp = Thyra::multiply(precOp, M);
90 
91  // must first cast that to be initialized
92  Thyra::DefaultPreconditioner<ScalarT> &dPrec =
93  Teuchos::dyn_cast<Thyra::DefaultPreconditioner<ScalarT> >(*prec);
94 
95  // this const-cast is unfortunate...needs to be fixed (larger than it seems!) ECC FIXME!
96  dPrec.initializeUnspecified(Teuchos::rcp_const_cast<Thyra::LinearOpBase<ScalarT> >(precOp));
97 }
98 
100 template <typename ScalarT>
101 void NeumannSeriesPreconditionerFactory<ScalarT>::uninitializePrec(
102  Thyra::PreconditionerBase<ScalarT> *prec,
103  RCP<const Thyra::LinearOpSourceBase<ScalarT> > * /* fwdOpSrc */,
104  Thyra::ESupportSolveUse * /* supportSolveUse */) const {
105  Thyra::DefaultPreconditioner<ScalarT> &dPrec =
106  Teuchos::dyn_cast<Thyra::DefaultPreconditioner<ScalarT> >(*prec);
107 
108  // wipe out any old preconditioner
109  dPrec.uninitialize();
110 }
111 
112 // for ParameterListAcceptor
113 
115 template <typename ScalarT>
116 void NeumannSeriesPreconditionerFactory<ScalarT>::setParameterList(
117  const RCP<Teuchos::ParameterList> &paramList) {
118  TEUCHOS_TEST_FOR_EXCEPT(paramList == Teuchos::null);
119 
120  // check the parameters are correct
121  paramList->validateParametersAndSetDefaults(*getValidParameters(), 0);
122 
123  // store the parameter list
124  paramList_ = paramList;
125 
126  numberOfTerms_ = paramList_->get<int>("Number of Terms");
127 
128  // get the scaling type
129  scalingType_ = Teko::NotDiag;
130  const Teuchos::ParameterEntry *entry = paramList_->getEntryPtr("Scaling Type");
131  if (entry != NULL) scalingType_ = scalingTypeVdtor->getIntegralValue(*entry);
132 }
133 
135 template <typename ScalarT>
136 RCP<const Teuchos::ParameterList> NeumannSeriesPreconditionerFactory<ScalarT>::getValidParameters()
137  const {
138  static RCP<Teuchos::ParameterList> validPL;
139 
140  // only fill valid parameter list once
141  if (validPL == Teuchos::null) {
142  RCP<Teuchos::ParameterList> pl = rcp(new Teuchos::ParameterList());
143 
144  // build the validator for scaling type
145  scalingTypeVdtor = Teuchos::stringToIntegralParameterEntryValidator<DiagonalType>(
146  Teuchos::tuple<std::string>("Diagonal", "Lumped", "AbsRowSum", "None"),
147  Teuchos::tuple<Teko::DiagonalType>(Teko::Diagonal, Teko::Lumped, Teko::AbsRowSum,
148  Teko::NotDiag),
149  "Scaling Type");
150 
151  pl->set<int>("Number of Terms", 1,
152  "The number of terms to use in the Neumann series expansion.");
153  pl->set("Scaling Type", "None", "The number of terms to use in the Neumann series expansion.",
154  scalingTypeVdtor);
155 
156  validPL = pl;
157  }
158 
159  return validPL;
160 }
161 
163 template <typename ScalarT>
164 RCP<Teuchos::ParameterList> NeumannSeriesPreconditionerFactory<ScalarT>::unsetParameterList() {
165  Teuchos::RCP<Teuchos::ParameterList> oldList = paramList_;
166  paramList_ = Teuchos::null;
167  return oldList;
168 }
169 
171 template <typename ScalarT>
172 RCP<const Teuchos::ParameterList> NeumannSeriesPreconditionerFactory<ScalarT>::getParameterList()
173  const {
174  return paramList_;
175 }
176 
178 template <typename ScalarT>
179 RCP<Teuchos::ParameterList>
180 NeumannSeriesPreconditionerFactory<ScalarT>::getNonconstParameterList() {
181  return paramList_;
182 }
183 
184 template <typename ScalarT>
185 std::string NeumannSeriesPreconditionerFactory<ScalarT>::description() const {
186  std::ostringstream oss;
187  oss << "Teko::NeumannSeriesPreconditionerFactory";
188  return oss.str();
189 }
190 
191 } // end namespace Teko
192 
193 #endif