Teko  Version of the Day
 All Classes Files Functions Variables Pages
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 
55 namespace Teko {
56 
59  : outputStream_(Teko::getOutputStream()), invFactory_(Teuchos::null), diagString_("<label me!>"), printResidual_(false)
60 { }
61 
65 DiagnosticPreconditionerFactory::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 
174 void 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 
202 Teuchos::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 
213 bool DiagnosticPreconditionerFactory::updateRequestedParameters(const Teuchos::ParameterList & pl)
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 
222 void 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
void rebuildInverse(const InverseFactory &factory, const LinearOp &A, InverseLinearOp &invA)
virtual Teuchos::RCP< Teuchos::ParameterList > getRequestedParameters() const
Request the additional parameters this preconditioner factory needs.
virtual ~DiagnosticPreconditionerFactory()
default destructor: prints out diagnostic string
DiagnosticPreconditionerFactory()
Default constructor, for use with the AutoClone class.
virtual bool updateRequestedParameters(const Teuchos::ParameterList &pl)
Update this object with the fields from a parameter list.
This linear operator prints diagnostics about operator application and creation times. It is useful for debugging problems and determining bottle necks.
InverseLinearOp buildInverse(const InverseFactory &factory, const LinearOp &A)
Build an inverse operator using a factory and a linear operator.
Teuchos::RCP< const InverseLibrary > getInverseLibrary() const
Get the inverse library used by this preconditioner factory.
virtual void initializeFromParameterList(const Teuchos::ParameterList &settings)
This function builds the internals of the preconditioner factory from a parameter list...
An implementation of a state object preconditioners.
virtual LinearOp buildPreconditionerOperator(LinearOp &lo, PreconditionerState &state) const
Function that is called to build the preconditioner for the linear operator that is passed in...
virtual Teko::ModifiableLinearOp & getModifiableOp(const std::string &name)
Add a named operator to the state object.