11 #include "Teko_SmootherPreconditionerFactory.hpp"
13 #include "Teko_PreconditionerInverseFactory.hpp"
14 #include "Thyra_MultiVectorStdOps.hpp"
19 class SmootherRequestMesg :
public RequestMesg {
21 SmootherRequestMesg(
unsigned int block)
22 : RequestMesg(
"__smoother_request_message__"), block_(block) {}
24 unsigned int getBlock()
const {
return block_; }
34 SmootherLinearOp::SmootherLinearOp(
const LinearOp& A,
const LinearOp& invM,
35 unsigned int applications,
bool useDestAsInitialGuess)
38 applications_(applications),
39 initialGuessType_(Unspecified),
40 requestMesg_(Teuchos::null) {
42 initialGuessType_ = useDestAsInitialGuess ? DestAsInitialGuess : NoInitialGuess;
45 SmootherLinearOp::SmootherLinearOp(
const LinearOp& A,
const LinearOp& invM,
46 unsigned int applications,
unsigned int block)
49 applications_(applications),
50 initialGuessType_(RequestInitialGuess),
51 requestMesg_(Teuchos::null) {
52 requestMesg_ = Teuchos::rcp(
new SmootherRequestMesg(block));
56 const double beta)
const {
59 MultiVector residual = deepcopy(b);
60 MultiVector scrap = deepcopy(b);
65 switch (initialGuessType_) {
66 case RequestInitialGuess:
68 error = deepcopy(getRequestHandler()->request<MultiVector>(*requestMesg_));
69 Thyra::assign<double>(x.ptr(), *error);
71 case DestAsInitialGuess:
75 Thyra::assign<double>(x.ptr(), 0.0);
79 default: TEUCHOS_ASSERT(
false);
82 for (
unsigned int current = 0; current < applications_; ++current) {
84 Teko::applyOp(A_, error, scrap);
85 Teko::update(-1.0, scrap, 1.0, residual);
88 Thyra::assign(error.ptr(), 0.0);
89 Teko::applyOp(invM_, residual, error);
92 Teko::update(1.0, error, 1.0, x);
98 Teko_DEBUG_SCOPE(
"SmootherLinearOp::setRequestHandler", 10);
104 Teko_DEBUG_SCOPE(
"SmootherLinearOp::getRequestHandler", 10);
105 return requestHandler_;
108 LinearOp buildSmootherLinearOp(
const LinearOp& A,
const LinearOp& invM,
unsigned int applications,
109 bool useDestAsInitialGuess) {
110 return Teuchos::rcp(
new SmootherLinearOp(A, invM, applications, useDestAsInitialGuess));
113 LinearOp buildSmootherLinearOp(
const LinearOp& A,
const LinearOp& invM,
unsigned int applications,
114 unsigned int initialGuessBlock) {
115 return Teuchos::rcp(
new SmootherLinearOp(A, invM, applications, initialGuessBlock));
123 SmootherPreconditionerFactory::SmootherPreconditionerFactory()
125 initialGuessType_(Unspecified),
126 initialGuessBlock_(0),
127 precFactory_(Teuchos::null) {}
132 LinearOp SmootherPreconditionerFactory::buildPreconditionerOperator(
133 LinearOp& lo, PreconditionerState& state)
const {
134 TEUCHOS_TEST_FOR_EXCEPTION(
135 precFactory_ == Teuchos::null, std::runtime_error,
136 "ERROR: Teko::SmootherPreconditionerFactory::buildPreconditionerOperator requires that a "
137 <<
"preconditioner factory has been set. Currently it is null!");
140 TEUCHOS_ASSERT(sweepCount_ > 0);
141 TEUCHOS_ASSERT(initialGuessType_ != Unspecified);
142 TEUCHOS_ASSERT(precFactory_ != Teuchos::null);
145 ModifiableLinearOp& invM = state.getModifiableOp(
"prec");
146 if (invM == Teuchos::null)
152 switch (initialGuessType_) {
153 case RequestInitialGuess:
154 return buildSmootherLinearOp(lo, invM, sweepCount_, initialGuessBlock_);
155 case DestAsInitialGuess:
156 return buildSmootherLinearOp(lo, invM, sweepCount_,
true);
158 return buildSmootherLinearOp(lo, invM, sweepCount_,
false);
160 default: TEUCHOS_ASSERT(
false);
164 TEUCHOS_ASSERT(
false);
165 return Teuchos::null;
171 void SmootherPreconditionerFactory::initializeFromParameterList(
172 const Teuchos::ParameterList& settings) {
176 const std::string str_sweepCount =
"Sweep Count";
177 const std::string str_initialGuessBlock =
"Initial Guess Block";
178 const std::string str_destAsInitialGuess =
"Destination As Initial Guess";
179 const std::string str_precType =
"Preconditioner Type";
184 initialGuessType_ = Unspecified;
185 initialGuessBlock_ = 0;
187 precFactory_ = Teuchos::null;
192 if (settings.isParameter(str_sweepCount)) sweepCount_ = settings.get<
int>(str_sweepCount);
197 if (settings.isParameter(str_initialGuessBlock)) {
198 initialGuessBlock_ = settings.get<
int>(str_initialGuessBlock);
199 initialGuessType_ = RequestInitialGuess;
202 if (settings.isParameter(str_destAsInitialGuess)) {
203 bool useDest = settings.get<
bool>(str_destAsInitialGuess);
205 TEUCHOS_TEST_FOR_EXCEPTION(initialGuessType_ != Unspecified, std::runtime_error,
206 "Cannot set both \"" << str_initialGuessBlock <<
"\" and \""
207 << str_destAsInitialGuess <<
"\"");
209 initialGuessType_ = DestAsInitialGuess;
214 if (initialGuessType_ == Unspecified) initialGuessType_ = NoInitialGuess;
219 TEUCHOS_TEST_FOR_EXCEPTION(
220 not settings.isParameter(str_precType), std::runtime_error,
221 "Parameter \"" << str_precType <<
"\" is required by a Teko::SmootherPreconditionerFactory");
224 Teuchos::RCP<const InverseLibrary> il = getInverseLibrary();
225 std::string precName = settings.get<std::string>(str_precType);
228 precFactory_ = il->getInverseFactory(precName);
229 TEUCHOS_TEST_FOR_EXCEPTION(
230 precFactory_ == Teuchos::null, std::runtime_error,
231 "ERROR: \"" << str_precType <<
"\" = " << precName <<
" could not be found");
236 TEUCHOS_ASSERT(sweepCount_ > 0);
237 TEUCHOS_ASSERT(initialGuessType_ != Unspecified);
238 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.