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()),
60  invFactory_(Teuchos::null),
61  diagString_("<label me!>"),
62  printResidual_(false) {}
63 
68  const Teuchos::RCP<Teko::InverseFactory>& invFactory, const std::string& label,
69  const Teuchos::RCP<std::ostream>& os, bool printResidual)
70  : outputStream_(Teko::getOutputStream()),
71  invFactory_(invFactory),
72  diagString_(label),
73  printResidual_(printResidual) {
74  initTimers(diagString_);
75 
76  if (os != Teuchos::null) outputStream_ = os;
77 }
78 
80  // check timers for null
81  if (buildTimer_ == Teuchos::null || rebuildTimer_ == Teuchos::null) {
82  // (*outputStream_) << "DiagnosticPreconditionerFactory \"" << diagString_ << "\": "
83  // << "Timers not initialized" << std::endl;
84 
85  return;
86  }
87 
88  double initBuildTime = totalInitialBuildTime();
89  int initBuilds = numInitialBuilds();
90 
91  double initRebuildTime = totalRebuildTime();
92  int initRebuilds = numRebuilds();
93 
94  (*outputStream_) << "DiagnosticPreconditionerFactory \"" << diagString_ << "\":\n";
95 
96  // print build string
97  (*outputStream_) << " build elapsed = " << initBuildTime << ", "
98  << "num builds = " << initBuilds << ", ";
99  if (initBuilds > 0)
100  (*outputStream_) << "timer/app = " << initBuildTime / double(initBuilds) << "\n";
101  else
102  (*outputStream_) << "timer/app = "
103  << "none"
104  << "\n";
105 
106  // print rebuild string
107  (*outputStream_) << " rebuild elapsed = " << initRebuildTime << ", "
108  << "num rebuilds = " << initRebuilds << ", ";
109  if (initRebuilds > 0)
110  (*outputStream_) << "timer/app = " << initRebuildTime / double(initRebuilds) << "\n";
111  else
112  (*outputStream_) << "timer/app = "
113  << "none"
114  << "\n";
115 
116  // print total string
117  (*outputStream_) << " total elapsed = " << initRebuildTime + initBuildTime << ", "
118  << "num rebuilds = " << initRebuilds + initBuilds << ", ";
119  if (initBuilds + initRebuilds > 0)
120  (*outputStream_) << "timer/app = "
121  << (initRebuildTime + initBuildTime) / double(initRebuilds + initBuilds)
122  << std::endl;
123  else
124  (*outputStream_) << "timer/app = "
125  << "none" << std::endl;
126 }
127 
132  LinearOp& lo, PreconditionerState& state) const {
133  using Teuchos::RCP;
134  using Teuchos::rcp_dynamic_cast;
135 
136  TEUCHOS_TEST_FOR_EXCEPTION(
137  invFactory_ == Teuchos::null, std::runtime_error,
138  "ERROR: Teko::DiagnosticPreconditionerFactory::buildPreconditionerOperator requires that an "
139  << "inverse factory has been set. Currently it is null!");
140 
141  TEUCHOS_TEST_FOR_EXCEPTION(
142  buildTimer_ == Teuchos::null || rebuildTimer_ == Teuchos::null, std::runtime_error,
143  "ERROR: Teko::DiagnosticPreconditionerFactory::buildPreconditionerOperator requires that "
144  << "the timers be initialized. Currently they are null! (label = \"" << diagString_
145  << "\")");
146 
147  // build user specified preconditioner
148  ModifiableLinearOp& diagOp_ptr = state.getModifiableOp("diagnosticOp");
149 
150  if (diagOp_ptr == Teuchos::null) {
151  ModifiableLinearOp invOp;
152  {
153  // start timer on construction, end on destruction
154  Teuchos::TimeMonitor monitor(*buildTimer_, false);
155 
156  invOp = Teko::buildInverse(*invFactory_, lo);
157  }
158 
159  // only printing residual requires use of forward operator
160  if (printResidual_)
161  diagOp_ptr = createDiagnosticLinearOp(outputStream_, lo, invOp, diagString_);
162  else
163  diagOp_ptr = createDiagnosticLinearOp(outputStream_, invOp, diagString_);
164  } else {
165  RCP<DiagnosticLinearOp> diagOp = rcp_dynamic_cast<DiagnosticLinearOp>(diagOp_ptr);
166 
167  // only printing residual requires use of forward operator
168  if (printResidual_) diagOp->setForwardOp(lo);
169 
170  ModifiableLinearOp invOp = diagOp->getModifiableOp();
171  {
172  // start timer on construction, end on destruction
173  Teuchos::TimeMonitor monitor(*rebuildTimer_, false);
174 
175  Teko::rebuildInverse(*invFactory_, lo, invOp);
176  }
177  }
178 
179  return diagOp_ptr.getConst();
180 }
181 
186  const Teuchos::ParameterList& settings) {
187  TEUCHOS_TEST_FOR_EXCEPTION(
188  not settings.isParameter("Inverse Factory"), std::runtime_error,
189  "Parameter \"Inverse Factory\" is required by a Teko::DiagnosticPreconditionerFactory");
190  TEUCHOS_TEST_FOR_EXCEPTION(
191  not settings.isParameter("Descriptive Label"), std::runtime_error,
192  "Parameter \"Descriptive Label\" is required by a Teko::DiagnosticPreconditionerFactory");
193 
194  // grab library and preconditioner name
195  std::string invName = settings.get<std::string>("Inverse Factory");
196  diagString_ = settings.get<std::string>("Descriptive Label");
197 
198  // build preconditioner factory
199  Teuchos::RCP<const InverseLibrary> il = getInverseLibrary();
200  invFactory_ = il->getInverseFactory(invName);
201  TEUCHOS_TEST_FOR_EXCEPTION(invFactory_ == Teuchos::null, std::runtime_error,
202  "ERROR: \"Inverse Factory\" = " << invName << " could not be found");
203 
204  if (settings.isParameter("Print Residual")) printResidual_ = settings.get<bool>("Print Residual");
205 
206  // build timers to use
207  initTimers(diagString_);
208 }
209 
213 Teuchos::RCP<Teuchos::ParameterList> DiagnosticPreconditionerFactory::getRequestedParameters()
214  const {
215  TEUCHOS_TEST_FOR_EXCEPTION(
216  invFactory_ == Teuchos::null, std::runtime_error,
217  "ERROR: Teko::DiagnosticPreconditionerFactory::getRequestedParameters requires that a "
218  << "preconditioner factory has been set. Currently it is null!");
219 
220  return invFactory_->getRequestedParameters();
221 }
222 
225 bool DiagnosticPreconditionerFactory::updateRequestedParameters(const Teuchos::ParameterList& pl) {
226  TEUCHOS_TEST_FOR_EXCEPTION(
227  invFactory_ == Teuchos::null, std::runtime_error,
228  "ERROR: Teko::DiagnosticPreconditionerFactory::updateRequestedParameters requires that a "
229  << "preconditioner factory has been set. Currently it is null!");
230 
231  return invFactory_->updateRequestedParameters(pl);
232 }
233 
234 void DiagnosticPreconditionerFactory::initTimers(const std::string& str) {
235  buildTimer_ = Teuchos::rcp(new Teuchos::Time(str + " buildTimer"));
236  rebuildTimer_ = Teuchos::rcp(new Teuchos::Time(str + " rebuildTimer"));
237 }
238 
239 } // 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.