48#include "Teko_SmootherPreconditionerFactory.hpp"
50#include "Teko_PreconditionerInverseFactory.hpp"
51#include "Thyra_MultiVectorStdOps.hpp"
56class SmootherRequestMesg :
public RequestMesg {
58 SmootherRequestMesg(
unsigned int block)
59 : RequestMesg(
"__smoother_request_message__")
62 unsigned int getBlock()
const
73SmootherLinearOp::SmootherLinearOp(
const LinearOp & A,
const LinearOp & invM,
unsigned int applications,
bool useDestAsInitialGuess)
74 : A_(A), invM_(invM), applications_(applications), initialGuessType_(Unspecified), requestMesg_(Teuchos::null)
77 initialGuessType_ = useDestAsInitialGuess ? DestAsInitialGuess : NoInitialGuess;
80SmootherLinearOp::SmootherLinearOp(
const LinearOp & A,
const LinearOp & invM,
unsigned int applications,
unsigned int block)
81 : A_(A), invM_(invM), applications_(applications), initialGuessType_(RequestInitialGuess), requestMesg_(Teuchos::null)
83 requestMesg_ = Teuchos::rcp(
new SmootherRequestMesg(block));
86void SmootherLinearOp::implicitApply(
const MultiVector & b, MultiVector & x,
87 const double alpha,
const double beta)
const
97 switch(initialGuessType_) {
98 case RequestInitialGuess:
100 error =
deepcopy(getRequestHandler()->request<MultiVector>(*requestMesg_));
101 Thyra::assign<double>(x.ptr(),*error);
103 case DestAsInitialGuess:
107 Thyra::assign<double>(x.ptr(),0.0);
112 TEUCHOS_ASSERT(
false);
115 for(
unsigned int current=0;current<applications_;++current) {
117 Teko::applyOp(A_,error,scrap);
118 Teko::update(-1.0,scrap,1.0,residual);
121 Thyra::assign(error.ptr(),0.0);
122 Teko::applyOp(invM_,residual,error);
125 Teko::update(1.0,error,1.0,x);
130void SmootherLinearOp::setRequestHandler(
const Teuchos::RCP<RequestHandler> & rh)
132 Teko_DEBUG_SCOPE(
"SmootherLinearOp::setRequestHandler",10);
133 requestHandler_ = rh;
137Teuchos::RCP<RequestHandler> SmootherLinearOp::getRequestHandler()
const
139 Teko_DEBUG_SCOPE(
"SmootherLinearOp::getRequestHandler",10);
140 return requestHandler_;
143LinearOp buildSmootherLinearOp(
const LinearOp & A,
const LinearOp & invM,
unsigned int applications,
bool useDestAsInitialGuess)
145 return Teuchos::rcp(
new SmootherLinearOp(A,invM,applications,useDestAsInitialGuess));
148LinearOp buildSmootherLinearOp(
const LinearOp & A,
const LinearOp & invM,
unsigned int applications,
unsigned int initialGuessBlock)
150 return Teuchos::rcp(
new SmootherLinearOp(A,invM,applications,initialGuessBlock));
159SmootherPreconditionerFactory::SmootherPreconditionerFactory()
160 : sweepCount_(0), initialGuessType_(Unspecified), initialGuessBlock_(0), precFactory_(Teuchos::null)
166LinearOp SmootherPreconditionerFactory::buildPreconditionerOperator(LinearOp & lo,PreconditionerState & state)
const
168 TEUCHOS_TEST_FOR_EXCEPTION(precFactory_==Teuchos::null,std::runtime_error,
169 "ERROR: Teko::SmootherPreconditionerFactory::buildPreconditionerOperator requires that a "
170 <<
"preconditioner factory has been set. Currently it is null!");
173 TEUCHOS_ASSERT(sweepCount_>0);
174 TEUCHOS_ASSERT(initialGuessType_!=Unspecified);
175 TEUCHOS_ASSERT(precFactory_!=Teuchos::null);
178 ModifiableLinearOp & invM = state.getModifiableOp(
"prec");
179 if(invM==Teuchos::null)
185 switch(initialGuessType_) {
186 case RequestInitialGuess:
187 return buildSmootherLinearOp(lo,invM,sweepCount_,initialGuessBlock_);
188 case DestAsInitialGuess:
189 return buildSmootherLinearOp(lo,invM,sweepCount_,
true);
191 return buildSmootherLinearOp(lo,invM,sweepCount_,
false);
194 TEUCHOS_ASSERT(
false);
198 TEUCHOS_ASSERT(
false);
199 return Teuchos::null;
205void SmootherPreconditionerFactory::initializeFromParameterList(
const Teuchos::ParameterList & settings)
210 const std::string str_sweepCount =
"Sweep Count";
211 const std::string str_initialGuessBlock =
"Initial Guess Block";
212 const std::string str_destAsInitialGuess =
"Destination As Initial Guess";
213 const std::string str_precType =
"Preconditioner Type";
218 initialGuessType_ = Unspecified;
219 initialGuessBlock_ = 0;
221 precFactory_ = Teuchos::null;
226 if(settings.isParameter(str_sweepCount))
227 sweepCount_ = settings.get<
int>(str_sweepCount);
232 if(settings.isParameter(str_initialGuessBlock)) {
233 initialGuessBlock_ = settings.get<
int>(str_initialGuessBlock);
234 initialGuessType_ = RequestInitialGuess;
237 if(settings.isParameter(str_destAsInitialGuess)) {
238 bool useDest = settings.get<
bool>(str_destAsInitialGuess);
240 TEUCHOS_TEST_FOR_EXCEPTION(initialGuessType_!=Unspecified, std::runtime_error,
241 "Cannot set both \"" << str_initialGuessBlock <<
242 "\" and \"" << str_destAsInitialGuess <<
"\"");
244 initialGuessType_ = DestAsInitialGuess;
249 if(initialGuessType_==Unspecified)
250 initialGuessType_ = NoInitialGuess;
255 TEUCHOS_TEST_FOR_EXCEPTION(not settings.isParameter(str_precType),std::runtime_error,
256 "Parameter \"" << str_precType <<
"\" is required by a Teko::SmootherPreconditionerFactory");
260 std::string precName = settings.get<std::string>(str_precType);
263 precFactory_ = il->getInverseFactory(precName);
264 TEUCHOS_TEST_FOR_EXCEPTION(precFactory_==Teuchos::null,std::runtime_error,
265 "ERROR: \"" << str_precType <<
"\" = " << precName
266 <<
" could not be found");
271 TEUCHOS_ASSERT(sweepCount_>0);
272 TEUCHOS_ASSERT(initialGuessType_!=Unspecified);
273 TEUCHOS_ASSERT(precFactory_!=Teuchos::null);
InverseLinearOp buildInverse(const InverseFactory &factory, const LinearOp &A)
Build an inverse operator using a factory and a linear operator.
void rebuildInverse(const InverseFactory &factory, const LinearOp &A, InverseLinearOp &invA)
MultiVector deepcopy(const MultiVector &v)
Perform a deep copy of the vector.
Teuchos::RCP< const InverseLibrary > getInverseLibrary() const
Get the inverse library used by this preconditioner factory.