48 #include "Teko_SmootherPreconditionerFactory.hpp"
50 #include "Teko_PreconditionerInverseFactory.hpp"
51 #include "Thyra_MultiVectorStdOps.hpp"
56 class SmootherRequestMesg :
public RequestMesg {
58 SmootherRequestMesg(
unsigned int block)
59 : RequestMesg(
"__smoother_request_message__"), block_(block) {}
61 unsigned int getBlock()
const {
return block_; }
71 SmootherLinearOp::SmootherLinearOp(
const LinearOp& A,
const LinearOp& invM,
72 unsigned int applications,
bool useDestAsInitialGuess)
75 applications_(applications),
76 initialGuessType_(Unspecified),
77 requestMesg_(Teuchos::null) {
79 initialGuessType_ = useDestAsInitialGuess ? DestAsInitialGuess : NoInitialGuess;
82 SmootherLinearOp::SmootherLinearOp(
const LinearOp& A,
const LinearOp& invM,
83 unsigned int applications,
unsigned int block)
86 applications_(applications),
87 initialGuessType_(RequestInitialGuess),
88 requestMesg_(Teuchos::null) {
89 requestMesg_ = Teuchos::rcp(
new SmootherRequestMesg(block));
93 const double beta)
const {
96 MultiVector residual = deepcopy(b);
97 MultiVector scrap = deepcopy(b);
102 switch (initialGuessType_) {
103 case RequestInitialGuess:
105 error = deepcopy(getRequestHandler()->request<MultiVector>(*requestMesg_));
106 Thyra::assign<double>(x.ptr(), *error);
108 case DestAsInitialGuess:
112 Thyra::assign<double>(x.ptr(), 0.0);
116 default: TEUCHOS_ASSERT(
false);
119 for (
unsigned int current = 0; current < applications_; ++current) {
121 Teko::applyOp(A_, error, scrap);
122 Teko::update(-1.0, scrap, 1.0, residual);
125 Thyra::assign(error.ptr(), 0.0);
126 Teko::applyOp(invM_, residual, error);
129 Teko::update(1.0, error, 1.0, x);
135 Teko_DEBUG_SCOPE(
"SmootherLinearOp::setRequestHandler", 10);
136 requestHandler_ = rh;
141 Teko_DEBUG_SCOPE(
"SmootherLinearOp::getRequestHandler", 10);
142 return requestHandler_;
145 LinearOp buildSmootherLinearOp(
const LinearOp& A,
const LinearOp& invM,
unsigned int applications,
146 bool useDestAsInitialGuess) {
147 return Teuchos::rcp(
new SmootherLinearOp(A, invM, applications, useDestAsInitialGuess));
150 LinearOp buildSmootherLinearOp(
const LinearOp& A,
const LinearOp& invM,
unsigned int applications,
151 unsigned int initialGuessBlock) {
152 return Teuchos::rcp(
new SmootherLinearOp(A, invM, applications, initialGuessBlock));
160 SmootherPreconditionerFactory::SmootherPreconditionerFactory()
162 initialGuessType_(Unspecified),
163 initialGuessBlock_(0),
164 precFactory_(Teuchos::null) {}
169 LinearOp SmootherPreconditionerFactory::buildPreconditionerOperator(
170 LinearOp& lo, PreconditionerState& state)
const {
171 TEUCHOS_TEST_FOR_EXCEPTION(
172 precFactory_ == Teuchos::null, std::runtime_error,
173 "ERROR: Teko::SmootherPreconditionerFactory::buildPreconditionerOperator requires that a "
174 <<
"preconditioner factory has been set. Currently it is null!");
177 TEUCHOS_ASSERT(sweepCount_ > 0);
178 TEUCHOS_ASSERT(initialGuessType_ != Unspecified);
179 TEUCHOS_ASSERT(precFactory_ != Teuchos::null);
182 ModifiableLinearOp& invM = state.getModifiableOp(
"prec");
183 if (invM == Teuchos::null)
189 switch (initialGuessType_) {
190 case RequestInitialGuess:
191 return buildSmootherLinearOp(lo, invM, sweepCount_, initialGuessBlock_);
192 case DestAsInitialGuess:
193 return buildSmootherLinearOp(lo, invM, sweepCount_,
true);
195 return buildSmootherLinearOp(lo, invM, sweepCount_,
false);
197 default: TEUCHOS_ASSERT(
false);
201 TEUCHOS_ASSERT(
false);
202 return Teuchos::null;
208 void SmootherPreconditionerFactory::initializeFromParameterList(
209 const Teuchos::ParameterList& settings) {
213 const std::string str_sweepCount =
"Sweep Count";
214 const std::string str_initialGuessBlock =
"Initial Guess Block";
215 const std::string str_destAsInitialGuess =
"Destination As Initial Guess";
216 const std::string str_precType =
"Preconditioner Type";
221 initialGuessType_ = Unspecified;
222 initialGuessBlock_ = 0;
224 precFactory_ = Teuchos::null;
229 if (settings.isParameter(str_sweepCount)) sweepCount_ = settings.get<
int>(str_sweepCount);
234 if (settings.isParameter(str_initialGuessBlock)) {
235 initialGuessBlock_ = settings.get<
int>(str_initialGuessBlock);
236 initialGuessType_ = RequestInitialGuess;
239 if (settings.isParameter(str_destAsInitialGuess)) {
240 bool useDest = settings.get<
bool>(str_destAsInitialGuess);
242 TEUCHOS_TEST_FOR_EXCEPTION(initialGuessType_ != Unspecified, std::runtime_error,
243 "Cannot set both \"" << str_initialGuessBlock <<
"\" and \""
244 << str_destAsInitialGuess <<
"\"");
246 initialGuessType_ = DestAsInitialGuess;
251 if (initialGuessType_ == Unspecified) initialGuessType_ = NoInitialGuess;
256 TEUCHOS_TEST_FOR_EXCEPTION(
257 not settings.isParameter(str_precType), std::runtime_error,
258 "Parameter \"" << str_precType <<
"\" is required by a Teko::SmootherPreconditionerFactory");
261 Teuchos::RCP<const InverseLibrary> il = getInverseLibrary();
262 std::string precName = settings.get<std::string>(str_precType);
265 precFactory_ = il->getInverseFactory(precName);
266 TEUCHOS_TEST_FOR_EXCEPTION(
267 precFactory_ == Teuchos::null, std::runtime_error,
268 "ERROR: \"" << str_precType <<
"\" = " << precName <<
" could not be found");
273 TEUCHOS_ASSERT(sweepCount_ > 0);
274 TEUCHOS_ASSERT(initialGuessType_ != Unspecified);
275 TEUCHOS_ASSERT(precFactory_ != Teuchos::null);
void rebuildInverse(const InverseFactory &factory, const LinearOp &A, InverseLinearOp &invA)
virtual void setRequestHandler(const Teuchos::RCP< RequestHandler > &rh)
Set the request handler with pointers to the appropriate callbacks.
InverseLinearOp buildInverse(const InverseFactory &factory, const LinearOp &A)
Build an inverse operator using a factory and a linear operator.
virtual Teuchos::RCP< RequestHandler > getRequestHandler() const
Get the request handler with pointers to the appropriate callbacks.
virtual void implicitApply(const MultiVector &x, MultiVector &y, const double alpha=1.0, const double beta=0.0) const
Perform a matrix vector multiply with this implicitly defined blocked operator.