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__")
62 unsigned int getBlock()
const
73 SmootherLinearOp::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;
80 SmootherLinearOp::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));
87 const double alpha,
const double beta)
const
91 MultiVector residual = deepcopy(b);
92 MultiVector scrap = deepcopy(b);
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);
132 Teko_DEBUG_SCOPE(
"SmootherLinearOp::setRequestHandler",10);
133 requestHandler_ = rh;
139 Teko_DEBUG_SCOPE(
"SmootherLinearOp::getRequestHandler",10);
140 return requestHandler_;
143 LinearOp buildSmootherLinearOp(
const LinearOp & A,
const LinearOp & invM,
unsigned int applications,
bool useDestAsInitialGuess)
145 return Teuchos::rcp(
new SmootherLinearOp(A,invM,applications,useDestAsInitialGuess));
148 LinearOp buildSmootherLinearOp(
const LinearOp & A,
const LinearOp & invM,
unsigned int applications,
unsigned int initialGuessBlock)
150 return Teuchos::rcp(
new SmootherLinearOp(A,invM,applications,initialGuessBlock));
159 SmootherPreconditionerFactory::SmootherPreconditionerFactory()
160 : sweepCount_(0), initialGuessType_(Unspecified), initialGuessBlock_(0), precFactory_(Teuchos::null)
166 LinearOp 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;
205 void 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");
259 Teuchos::RCP<const InverseLibrary> il = getInverseLibrary();
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);
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.