Teko  Version of the Day
 All Classes Files Functions Variables Pages
Teko_PreconditionerInverseFactory.cpp
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 /*
11 // @header
12 //
13 // ***********************************************************************
14 //
15 // teko: a package for block and physics based preconditioning
16 // copyright 2010 sandia corporation
17 //
18 // under the terms of contract de-ac04-94al85000 with sandia corporation,
19 // the u.s. government retains certain rights in this software.
20 //
21 // redistribution and use in source and binary forms, with or without
22 // modification, are permitted provided that the following conditions are
23 // met:
24 //
25 // 1. redistributions of source code must retain the above copyright
26 // notice, this list of conditions and the following disclaimer.
27 //
28 // 2. redistributions in binary form must reproduce the above copyright
29 // notice, this list of conditions and the following disclaimer in the
30 // documentation and/or other materials provided with the distribution.
31 //
32 // 3. neither the name of the corporation nor the names of the
33 // contributors may be used to endorse or promote products derived from
34 // this software without specific prior written permission.
35 //
36 // this software is provided by sandia corporation "as is" and any
37 // express or implied warranties, including, but not limited to, the
38 // implied warranties of merchantability and fitness for a particular
39 // purpose are disclaimed. in no event shall sandia corporation or the
40 // contributors be liable for any direct, indirect, incidental, special,
41 // exemplary, or consequential damages (including, but not limited to,
42 // procurement of substitute goods or services; loss of use, data, or
43 // profits; or business interruption) however caused and on any theory of
44 // liability, whether in contract, strict liability, or tort (including
45 // negligence or otherwise) arising in any way out of the use of this
46 // software, even if advised of the possibility of such damage.
47 //
48 // questions? contact eric c. cyr (eccyr@sandia.gov)
49 //
50 // ***********************************************************************
51 //
52 // @header
53 */
54 
55 #include "Teko_PreconditionerInverseFactory.hpp"
56 
57 // Thyra includes
58 #include "Thyra_DefaultLinearOpSource.hpp"
59 #include "Thyra_DefaultInverseLinearOp.hpp"
60 #include "Thyra_DefaultPreconditioner.hpp"
61 
62 // Stratimikos includes
63 #include "Stratimikos_DefaultLinearSolverBuilder.hpp"
64 
65 // Teko includes
66 #include "Teko_Utilities.hpp"
67 #include "Teko_BlockPreconditionerFactory.hpp"
68 #include "Teko_Preconditioner.hpp"
69 #include "Teko_PreconditionerLinearOp.hpp"
70 #include "Teko_SolveInverseFactory.hpp"
71 
72 using Teuchos::rcp;
73 using Teuchos::RCP;
74 using Teuchos::rcp_const_cast;
75 using Teuchos::rcp_dynamic_cast;
76 
77 namespace Teko {
78 
88 PreconditionerInverseFactory::PreconditionerInverseFactory(
89  const Teuchos::RCP<Thyra::PreconditionerFactoryBase<double> >& precFactory,
90  const Teuchos::RCP<Teko::RequestHandler>& rh)
91  : precFactory_(precFactory) {
93 }
94 
109 PreconditionerInverseFactory::PreconditionerInverseFactory(
110  const Teuchos::RCP<Thyra::PreconditionerFactoryBase<double> >& precFactory,
111  const Teuchos::RCP<const Teuchos::ParameterList>& xtraParam,
112  const Teuchos::RCP<Teko::RequestHandler>& rh)
113  : precFactory_(precFactory) {
114  if (xtraParam != Teuchos::null)
115  extraParams_ = rcp(new Teuchos::ParameterList(*xtraParam));
116  else
117  extraParams_ = Teuchos::null; // make it explicit
118 
119  setRequestHandler(rh);
120 }
121 
123 PreconditionerInverseFactory::PreconditionerInverseFactory(
124  const PreconditionerInverseFactory& pFactory)
125  : precFactory_(pFactory.precFactory_) {
126  setRequestHandler(pFactory.getRequestHandler());
127 }
128 
138 InverseLinearOp PreconditionerInverseFactory::buildInverse(const LinearOp& linearOp) const {
139  RCP<Thyra::PreconditionerBase<double> > prec = precFactory_->createPrec();
140  precFactory_->initializePrec(Thyra::defaultLinearOpSource(linearOp), &*prec);
141 
142  RCP<Teko::PreconditionerLinearOp<double> > precOp =
144 
145  return precOp;
146 }
147 
160 InverseLinearOp PreconditionerInverseFactory::buildInverse(
161  const LinearOp& linearOp, const PreconditionerState& parentState) const {
162  Teko_DEBUG_SCOPE("PreconditionerInverseFactory::buildInverse(A,parentState)", 10);
163  RCP<Thyra::PreconditionerBase<double> > prec = precFactory_->createPrec();
164 
165  {
166  Teko_DEBUG_SCOPE("Casting to Teko::Preconditioner", 10);
167  // pass state downward if a Teko::Preconditioner object is begin used
168  RCP<Teko::Preconditioner> tekoPrec = Teuchos::rcp_dynamic_cast<Teko::Preconditioner>(prec);
169  if (tekoPrec != Teuchos::null) {
170  Teko_DEBUG_SCOPE("Merging states", 10);
171  tekoPrec->mergeStateObject(parentState);
172  }
173  }
174 
175  precFactory_->initializePrec(Thyra::defaultLinearOpSource(linearOp), &*prec);
176 
177  RCP<Teko::PreconditionerLinearOp<double> > precOp =
179 
180  return precOp;
181 }
182 
194 void PreconditionerInverseFactory::rebuildInverse(const LinearOp& source,
195  InverseLinearOp& dest) const {
196  Teko_DEBUG_MSG("BEGIN PreconditionerInverseFactory::rebuildInverse", 10);
197 
198  RCP<Thyra::PreconditionerBase<double> > prec =
199  Teuchos::rcp_dynamic_cast<Teko::PreconditionerLinearOp<double> >(dest)
200  ->getNonconstPreconditioner();
201 
202  precFactory_->initializePrec(Thyra::defaultLinearOpSource(source), &*prec);
203 
204  Teko_DEBUG_MSG("END PreconditionerInverseFactory::rebuildInverse", 10);
205 }
206 
215 Teuchos::RCP<const Teuchos::ParameterList> PreconditionerInverseFactory::getParameterList() const {
216  return precFactory_->getParameterList();
217 }
218 
233 Teuchos::RCP<Teuchos::ParameterList> PreconditionerInverseFactory::getRequestedParameters() const {
234  Teuchos::RCP<BlockPreconditionerFactory> bpf =
235  rcp_dynamic_cast<BlockPreconditionerFactory>(precFactory_);
236 
237  // request the parameters from a BPF is required
238  if (bpf != Teuchos::null) return bpf->getRequestedParameters();
239 
240  // for non block preconditioners see if there are user requested additional parameters
241  return extraParams_;
242 }
243 
257 bool PreconditionerInverseFactory::updateRequestedParameters(const Teuchos::ParameterList& pl) {
258  Teuchos::RCP<BlockPreconditionerFactory> bpf =
259  rcp_dynamic_cast<BlockPreconditionerFactory>(precFactory_);
260 
261  // update the parameters of a BPF is required
262  if (bpf != Teuchos::null) return bpf->updateRequestedParameters(pl);
263 
264  // for non block preconditioners see if there are user requested additional parameters
265  if (extraParams_ == Teuchos::null) return true;
266 
267  Teuchos::ParameterList::ConstIterator itr;
268  RCP<Teuchos::ParameterList> srcPl = precFactory_->unsetParameterList();
269 
270  // find name of settings sublist
271  std::string subName = "";
272  for (itr = srcPl->begin(); itr != srcPl->end(); ++itr) {
273  // search for std::string with "Settings" in name
274  if (itr->first.find("Settings") != std::string::npos) {
275  subName = itr->first;
276  continue;
277  }
278  }
279 
280  // update fails if no settings list was found
281  if (subName == "") {
282  precFactory_->setParameterList(srcPl);
283  return false;
284  }
285 
286  // add extra parameters to list
287  Teuchos::ParameterList& settingsList = srcPl->sublist(subName);
288  for (itr = pl.begin(); itr != pl.end(); ++itr) {
289  if (extraParams_->isParameter(itr->first)) settingsList.setEntry(itr->first, itr->second);
290  }
291 
292  // set the parameter list
293  precFactory_->setParameterList(srcPl);
294 
295  return true;
296 }
297 
298 void PreconditionerInverseFactory::setupParameterListFromRequestHandler() {
299  // for non block preconditioners see if there are user requested additional parameters
300  if (extraParams_ == Teuchos::null) return;
301 
302  Teuchos::ParameterList::ConstIterator itr;
303  RCP<Teuchos::ParameterList> srcPl = precFactory_->unsetParameterList();
304 
305  // find name of settings sublist
306  std::string subName = "";
307  for (itr = srcPl->begin(); itr != srcPl->end(); ++itr) {
308  // search for std::string with "Settings" in name
309  if (itr->first.find("Settings") != std::string::npos) {
310  subName = itr->first;
311  continue;
312  }
313  }
314 
315  // update fails if no settings list was found
316  /*
317  if(subName=="") {
318  precFactory_->setParameterList(srcPl);
319  return;
320  }*/
321 
322  Teuchos::RCP<Teko::RequestHandler> rh = getRequestHandler();
323  TEUCHOS_TEST_FOR_EXCEPTION(
324  rh == Teuchos::null, std::runtime_error,
325  "PreconditionerInverseFactory::setupParameterListFromRequestHandler: no request handler set");
326 
327  // add extra parameters to list
328  rh->preRequest<Teuchos::RCP<Teuchos::ParameterList> >(RequestMesg(extraParams_));
329  Teuchos::RCP<Teuchos::ParameterList> requestParams =
330  rh->request<Teuchos::RCP<Teuchos::ParameterList> >(RequestMesg(extraParams_));
331 
332  TEUCHOS_TEST_FOR_EXCEPTION(requestParams == Teuchos::null, std::runtime_error,
333  "User specified request not satisfied!");
334 
335  // If there is no Settings sublist, assume that the list itself contains the settings
336  if (subName == "") {
337  for (itr = requestParams->begin(); itr != requestParams->end(); ++itr)
338  srcPl->setEntry(itr->first, itr->second);
339  } else {
340  Teuchos::ParameterList& settingsList = srcPl->sublist(subName);
341  for (itr = requestParams->begin(); itr != requestParams->end(); ++itr)
342  settingsList.setEntry(itr->first, itr->second);
343  }
344 
345  // reset with updated parameter list
346  precFactory_->setParameterList(srcPl);
347 }
348 
349 } // namespace Teko
void setRequestHandler(const Teuchos::RCP< RequestHandler > &rh)
Set the request handler with pointers to the appropriate callbacks.
Class that wraps a PreconditionerBase object it makes it behave like a linear operator.
An extension of the Thyra::DefaultPreconditioner class with some specializations useful for use withi...