Teko Version of the Day
Loading...
Searching...
No Matches
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
72using Teuchos::rcp;
73using Teuchos::RCP;
74using Teuchos::rcp_const_cast;
75using Teuchos::rcp_dynamic_cast;
76
77namespace Teko {
78
88PreconditionerInverseFactory::PreconditionerInverseFactory(
89 const Teuchos::RCP<Thyra::PreconditionerFactoryBase<double> >& precFactory,
90 const Teuchos::RCP<Teko::RequestHandler>& rh)
91 : precFactory_(precFactory) {
92 setRequestHandler(rh);
93}
94
109PreconditionerInverseFactory::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
123PreconditionerInverseFactory::PreconditionerInverseFactory(
124 const PreconditionerInverseFactory& pFactory)
125 : precFactory_(pFactory.precFactory_) {
126 setRequestHandler(pFactory.getRequestHandler());
127}
128
138InverseLinearOp 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
160InverseLinearOp 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
194void 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
215Teuchos::RCP<const Teuchos::ParameterList> PreconditionerInverseFactory::getParameterList() const {
216 return precFactory_->getParameterList();
217}
218
233Teuchos::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
257bool 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
298void 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
Class that wraps a PreconditionerBase object it makes it behave like a linear operator.