Teko Version of the Day
Loading...
Searching...
No Matches
Teko_DiagnosticPreconditionerFactory.cpp
1/*
2// @HEADER
3//
4// ***********************************************************************
5//
6// Teko: A package for block and physics based preconditioning
7// Copyright 2010 Sandia Corporation
8//
9// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
10// the U.S. Government retains certain rights in this software.
11//
12// Redistribution and use in source and binary forms, with or without
13// modification, are permitted provided that the following conditions are
14// met:
15//
16// 1. Redistributions of source code must retain the above copyright
17// notice, this list of conditions and the following disclaimer.
18//
19// 2. Redistributions in binary form must reproduce the above copyright
20// notice, this list of conditions and the following disclaimer in the
21// documentation and/or other materials provided with the distribution.
22//
23// 3. Neither the name of the Corporation nor the names of the
24// contributors may be used to endorse or promote products derived from
25// this software without specific prior written permission.
26//
27// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
28// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
31// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38//
39// Questions? Contact Eric C. Cyr (eccyr@sandia.gov)
40//
41// ***********************************************************************
42//
43// @HEADER
44
45*/
46
47// Teko includes
48#include "Teko_DiagnosticPreconditionerFactory.hpp"
49
50#include "Teko_PreconditionerInverseFactory.hpp"
52
53#include "Teuchos_TimeMonitor.hpp"
54
55namespace Teko {
56
59 : outputStream_(Teko::getOutputStream()), invFactory_(Teuchos::null), diagString_("<label me!>"), printResidual_(false)
60{ }
61
65DiagnosticPreconditionerFactory::DiagnosticPreconditionerFactory(const Teuchos::RCP<Teko::InverseFactory> & invFactory, const std::string & label,
66 const Teuchos::RCP<std::ostream> & os,bool printResidual)
67 : outputStream_(Teko::getOutputStream()), invFactory_(invFactory), diagString_(label), printResidual_(printResidual)
68{
69 initTimers(diagString_);
70
71 if(os!=Teuchos::null)
72 outputStream_ = os;
73}
74
76{
77 // check timers for null
78 if(buildTimer_==Teuchos::null || rebuildTimer_==Teuchos::null) {
79 // (*outputStream_) << "DiagnosticPreconditionerFactory \"" << diagString_ << "\": "
80 // << "Timers not initialized" << std::endl;
81
82 return;
83 }
84
85 double initBuildTime = totalInitialBuildTime();
86 int initBuilds = numInitialBuilds();
87
88 double initRebuildTime = totalRebuildTime();
89 int initRebuilds = numRebuilds();
90
91 (*outputStream_) << "DiagnosticPreconditionerFactory \"" << diagString_ << "\":\n";
92
93 // print build string
94 (*outputStream_) << " build elapsed = " << initBuildTime << ", "
95 << "num builds = " << initBuilds << ", ";
96 if(initBuilds>0)
97 (*outputStream_) << "timer/app = " << initBuildTime / double(initBuilds) << "\n";
98 else
99 (*outputStream_) << "timer/app = " << "none" << "\n";
100
101 // print rebuild string
102 (*outputStream_) << " rebuild elapsed = " << initRebuildTime << ", "
103 << "num rebuilds = " << initRebuilds << ", ";
104 if(initRebuilds>0)
105 (*outputStream_) << "timer/app = " << initRebuildTime / double(initRebuilds) << "\n";
106 else
107 (*outputStream_) << "timer/app = " << "none" << "\n";
108
109 // print total string
110 (*outputStream_) << " total elapsed = " << initRebuildTime+initBuildTime << ", "
111 << "num rebuilds = " << initRebuilds+initBuilds << ", ";
112 if(initBuilds+initRebuilds>0)
113 (*outputStream_) << "timer/app = " << (initRebuildTime+initBuildTime) / double(initRebuilds+initBuilds) << std::endl;
114 else
115 (*outputStream_) << "timer/app = " << "none" << std::endl;
116}
117
122{
123 using Teuchos::RCP;
124 using Teuchos::rcp_dynamic_cast;
125
126 TEUCHOS_TEST_FOR_EXCEPTION(invFactory_==Teuchos::null,std::runtime_error,
127 "ERROR: Teko::DiagnosticPreconditionerFactory::buildPreconditionerOperator requires that an "
128 << "inverse factory has been set. Currently it is null!");
129
130 TEUCHOS_TEST_FOR_EXCEPTION(buildTimer_==Teuchos::null || rebuildTimer_==Teuchos::null,std::runtime_error,
131 "ERROR: Teko::DiagnosticPreconditionerFactory::buildPreconditionerOperator requires that "
132 << "the timers be initialized. Currently they are null! (label = \"" << diagString_ << "\")");
133
134 // build user specified preconditioner
135 ModifiableLinearOp & diagOp_ptr = state.getModifiableOp("diagnosticOp");
136
137 if(diagOp_ptr==Teuchos::null) {
138 ModifiableLinearOp invOp;
139 {
140 // start timer on construction, end on destruction
141 Teuchos::TimeMonitor monitor(*buildTimer_,false);
142
143 invOp = Teko::buildInverse(*invFactory_,lo);
144 }
145
146 // only printing residual requires use of forward operator
147 if(printResidual_)
148 diagOp_ptr = createDiagnosticLinearOp(outputStream_,lo,invOp,diagString_);
149 else
150 diagOp_ptr = createDiagnosticLinearOp(outputStream_,invOp,diagString_);
151 }
152 else {
153 RCP<DiagnosticLinearOp> diagOp = rcp_dynamic_cast<DiagnosticLinearOp>(diagOp_ptr);
154
155 // only printing residual requires use of forward operator
156 if(printResidual_)
157 diagOp->setForwardOp(lo);
158
159 ModifiableLinearOp invOp = diagOp->getModifiableOp();
160 {
161 // start timer on construction, end on destruction
162 Teuchos::TimeMonitor monitor(*rebuildTimer_,false);
163
164 Teko::rebuildInverse(*invFactory_,lo,invOp);
165 }
166 }
167
168 return diagOp_ptr.getConst();
169}
170
174void DiagnosticPreconditionerFactory::initializeFromParameterList(const Teuchos::ParameterList & settings)
175{
176 TEUCHOS_TEST_FOR_EXCEPTION(not settings.isParameter("Inverse Factory"),std::runtime_error,
177 "Parameter \"Inverse Factory\" is required by a Teko::DiagnosticPreconditionerFactory");
178 TEUCHOS_TEST_FOR_EXCEPTION(not settings.isParameter("Descriptive Label"),std::runtime_error,
179 "Parameter \"Descriptive Label\" is required by a Teko::DiagnosticPreconditionerFactory");
180
181 // grab library and preconditioner name
182 std::string invName = settings.get<std::string>("Inverse Factory");
183 diagString_ = settings.get<std::string>("Descriptive Label");
184
185 // build preconditioner factory
186 Teuchos::RCP<const InverseLibrary> il = getInverseLibrary();
187 invFactory_ = il->getInverseFactory(invName);
188 TEUCHOS_TEST_FOR_EXCEPTION(invFactory_==Teuchos::null,std::runtime_error,
189 "ERROR: \"Inverse Factory\" = " << invName
190 << " could not be found");
191
192 if(settings.isParameter("Print Residual"))
193 printResidual_ = settings.get<bool>("Print Residual");
194
195 // build timers to use
196 initTimers(diagString_);
197}
198
202Teuchos::RCP<Teuchos::ParameterList> DiagnosticPreconditionerFactory::getRequestedParameters() const
203{
204 TEUCHOS_TEST_FOR_EXCEPTION(invFactory_==Teuchos::null,std::runtime_error,
205 "ERROR: Teko::DiagnosticPreconditionerFactory::getRequestedParameters requires that a "
206 << "preconditioner factory has been set. Currently it is null!");
207
208 return invFactory_->getRequestedParameters();
209}
210
214{
215 TEUCHOS_TEST_FOR_EXCEPTION(invFactory_==Teuchos::null,std::runtime_error,
216 "ERROR: Teko::DiagnosticPreconditionerFactory::updateRequestedParameters requires that a "
217 << "preconditioner factory has been set. Currently it is null!");
218
219 return invFactory_->updateRequestedParameters(pl);
220}
221
222void DiagnosticPreconditionerFactory::initTimers(const std::string & str)
223{
224 buildTimer_ = Teuchos::rcp(new Teuchos::Time(str+" buildTimer"));
225 rebuildTimer_ = Teuchos::rcp(new Teuchos::Time(str+" rebuildTimer"));
226}
227
228} // end namespace Teko
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)
virtual ~DiagnosticPreconditionerFactory()
default destructor: prints out diagnostic string
virtual bool updateRequestedParameters(const Teuchos::ParameterList &pl)
Update this object with the fields from a parameter list.
virtual void initializeFromParameterList(const Teuchos::ParameterList &settings)
This function builds the internals of the preconditioner factory from a parameter list.
DiagnosticPreconditionerFactory()
Default constructor, for use with the AutoClone class.
virtual Teuchos::RCP< Teuchos::ParameterList > getRequestedParameters() const
Request the additional parameters this preconditioner factory needs.
virtual LinearOp buildPreconditionerOperator(LinearOp &lo, PreconditionerState &state) const
Function that is called to build the preconditioner for the linear operator that is passed in.
Teuchos::RCP< const InverseLibrary > getInverseLibrary() const
Get the inverse library used by this preconditioner factory.
An implementation of a state object preconditioners.