Teko Version of the Day
Loading...
Searching...
No Matches
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
25namespace Teko {
26
27using Teuchos::RCP;
28using Teuchos::rcp;
29
30static RCP<Teuchos::StringToIntegralParameterEntryValidator<Teko::DiagonalType> > scalingTypeVdtor;
31
32template <typename ScalarT>
33NeumannSeriesPreconditionerFactory<ScalarT>::NeumannSeriesPreconditionerFactory()
34 : numberOfTerms_(1), scalingType_(Teko::NotDiag) {}
35
37template <typename ScalarT>
38bool NeumannSeriesPreconditionerFactory<ScalarT>::isCompatible(
39 const Thyra::LinearOpSourceBase<ScalarT> & /* fwdOpSrc */) const {
40 return true;
41}
42
44template <typename ScalarT>
45RCP<Thyra::PreconditionerBase<ScalarT> > NeumannSeriesPreconditionerFactory<ScalarT>::createPrec()
46 const {
47 return rcp(new Thyra::DefaultPreconditioner<ScalarT>());
48}
49
58template <typename ScalarT>
59void 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
100template <typename ScalarT>
101void 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
115template <typename ScalarT>
116void 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
135template <typename ScalarT>
136RCP<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,
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
163template <typename ScalarT>
164RCP<Teuchos::ParameterList> NeumannSeriesPreconditionerFactory<ScalarT>::unsetParameterList() {
165 Teuchos::RCP<Teuchos::ParameterList> oldList = paramList_;
166 paramList_ = Teuchos::null;
167 return oldList;
168}
169
171template <typename ScalarT>
172RCP<const Teuchos::ParameterList> NeumannSeriesPreconditionerFactory<ScalarT>::getParameterList()
173 const {
174 return paramList_;
175}
176
178template <typename ScalarT>
179RCP<Teuchos::ParameterList>
180NeumannSeriesPreconditionerFactory<ScalarT>::getNonconstParameterList() {
181 return paramList_;
182}
183
184template <typename ScalarT>
185std::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
@ NotDiag
For user convenience, if Teko recieves this value, exceptions will be thrown.
@ AbsRowSum
Specifies that the diagonal entry is .
@ Diagonal
Specifies that just the diagonal is used.
@ Lumped
Specifies that row sum is used to form a diagonal.