Teko Version of the Day
Loading...
Searching...
No Matches
Teko_DiagnosticPreconditionerFactory.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// Teko includes
11#include "Teko_DiagnosticPreconditionerFactory.hpp"
12
13#include "Teko_PreconditionerInverseFactory.hpp"
15
16#include "Teuchos_TimeMonitor.hpp"
17
18namespace Teko {
19
22 : outputStream_(Teko::getOutputStream()),
23 invFactory_(Teuchos::null),
24 diagString_("<label me!>"),
25 printResidual_(false) {}
26
31 const Teuchos::RCP<Teko::InverseFactory>& invFactory, const std::string& label,
32 const Teuchos::RCP<std::ostream>& os, bool printResidual)
33 : outputStream_(Teko::getOutputStream()),
34 invFactory_(invFactory),
35 precFactory_(Teuchos::null),
36 diagString_(label),
37 printResidual_(printResidual) {
38 initTimers(diagString_);
39
40 if (os != Teuchos::null) outputStream_ = os;
41}
42
47 const Teuchos::RCP<Teko::InverseFactory>& invFactory,
48 const Teuchos::RCP<Teko::InverseFactory>& precFactory, const std::string& label,
49 const Teuchos::RCP<std::ostream>& os, bool printResidual)
50 : outputStream_(Teko::getOutputStream()),
51 invFactory_(invFactory),
52 precFactory_(precFactory),
53 diagString_(label),
54 printResidual_(printResidual) {
55 initTimers(diagString_);
56
57 if (os != Teuchos::null) outputStream_ = os;
58}
59
60double DiagnosticPreconditionerFactory::totalInitialBuildTime() const {
61 return buildTimer_->totalElapsedTime() + precBuildTimer_->totalElapsedTime();
62}
63
64double DiagnosticPreconditionerFactory::totalRebuildTime() const {
65 return rebuildTimer_->totalElapsedTime() + precRebuildTimer_->totalElapsedTime();
66}
67
69 // check timers for null
70 if (buildTimer_ == Teuchos::null || rebuildTimer_ == Teuchos::null) {
71 // (*outputStream_) << "DiagnosticPreconditionerFactory \"" << diagString_ << "\": "
72 // << "Timers not initialized" << std::endl;
73
74 return;
75 }
76
77 double initBuildTime = totalInitialBuildTime();
78 int initBuilds = numInitialBuilds();
79
80 double initRebuildTime = totalRebuildTime();
81 int initRebuilds = numRebuilds();
82
83 (*outputStream_) << "DiagnosticPreconditionerFactory \"" << diagString_ << "\":\n";
84
85 // print build string
86 (*outputStream_) << " build elapsed = " << initBuildTime << ", "
87 << "num builds = " << initBuilds << ", ";
88 if (initBuilds > 0)
89 (*outputStream_) << "timer/app = " << initBuildTime / double(initBuilds) << "\n";
90 else
91 (*outputStream_) << "timer/app = "
92 << "none"
93 << "\n";
94
95 // print rebuild string
96 (*outputStream_) << " rebuild elapsed = " << initRebuildTime << ", "
97 << "num rebuilds = " << initRebuilds << ", ";
98 if (initRebuilds > 0)
99 (*outputStream_) << "timer/app = " << initRebuildTime / double(initRebuilds) << "\n";
100 else
101 (*outputStream_) << "timer/app = "
102 << "none"
103 << "\n";
104
105 // print total string
106 (*outputStream_) << " total elapsed = " << initRebuildTime + initBuildTime << ", "
107 << "num rebuilds = " << initRebuilds + initBuilds << ", ";
108 if (initBuilds + initRebuilds > 0)
109 (*outputStream_) << "timer/app = "
110 << (initRebuildTime + initBuildTime) / double(initRebuilds + initBuilds)
111 << std::endl;
112 else
113 (*outputStream_) << "timer/app = "
114 << "none" << std::endl;
115}
116
121 LinearOp& lo, PreconditionerState& state) const {
122 using Teuchos::RCP;
123 using Teuchos::rcp_dynamic_cast;
124
125 TEUCHOS_TEST_FOR_EXCEPTION(
126 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(
131 buildTimer_ == Teuchos::null || rebuildTimer_ == Teuchos::null, std::runtime_error,
132 "ERROR: Teko::DiagnosticPreconditionerFactory::buildPreconditionerOperator requires that "
133 << "the timers be initialized. Currently they are null! (label = \"" << diagString_
134 << "\")");
135
136 // build user specified preconditioner
137 ModifiableLinearOp& diagOp_ptr = state.getModifiableOp("diagnosticOp");
138 ModifiableLinearOp& diagOp_prec_ptr = state.getModifiableOp("prec_diagnosticOp");
139
140 if (precFactory_ != Teuchos::null) {
141 if (diagOp_prec_ptr == Teuchos::null) {
142 {
143 // start timer on construction, end on destruction
144 Teuchos::TimeMonitor monitor(*precBuildTimer_, false);
145
146 diagOp_prec_ptr = precFactory_->buildInverse(lo);
147 }
148
149 state.addModifiableOp("prec_diagnosticOp", diagOp_prec_ptr);
150 } else {
151 Teuchos::TimeMonitor monitor(*precRebuildTimer_, false);
152 Teko::rebuildInverse(*precFactory_, lo, diagOp_prec_ptr);
153 }
154 }
155
156 if (diagOp_ptr == Teuchos::null) {
157 ModifiableLinearOp invOp;
158 {
159 // start timer on construction, end on destruction
160 Teuchos::TimeMonitor monitor(*buildTimer_, false);
161
162 if (diagOp_prec_ptr.is_null())
163 invOp = Teko::buildInverse(*invFactory_, lo);
164 else
165 invOp = Teko::buildInverse(*invFactory_, lo, diagOp_prec_ptr);
166 }
167
168 // only printing residual requires use of forward operator
169 if (printResidual_)
170 diagOp_ptr = createDiagnosticLinearOp(outputStream_, lo, invOp, diagString_);
171 else
172 diagOp_ptr = createDiagnosticLinearOp(outputStream_, invOp, diagString_);
173 } else {
174 RCP<DiagnosticLinearOp> diagOp = rcp_dynamic_cast<DiagnosticLinearOp>(diagOp_ptr);
175
176 // only printing residual requires use of forward operator
177 if (printResidual_) diagOp->setForwardOp(lo);
178
179 ModifiableLinearOp invOp = diagOp->getModifiableOp();
180 {
181 // start timer on construction, end on destruction
182 Teuchos::TimeMonitor monitor(*rebuildTimer_, false);
183
184 if (diagOp_prec_ptr.is_null())
185 Teko::rebuildInverse(*invFactory_, lo, invOp);
186 else
187 Teko::rebuildInverse(*invFactory_, lo, diagOp_prec_ptr, invOp);
188 }
189 }
190
191 return diagOp_ptr.getConst();
192}
193
198 const Teuchos::ParameterList& settings) {
199 TEUCHOS_TEST_FOR_EXCEPTION(
200 not settings.isParameter("Inverse Factory"), std::runtime_error,
201 "Parameter \"Inverse Factory\" is required by a Teko::DiagnosticPreconditionerFactory");
202 TEUCHOS_TEST_FOR_EXCEPTION(
203 not settings.isParameter("Descriptive Label"), std::runtime_error,
204 "Parameter \"Descriptive Label\" is required by a Teko::DiagnosticPreconditionerFactory");
205
206 // grab library and preconditioner name
207 std::string invName = settings.get<std::string>("Inverse Factory");
208 std::string precName = "";
209 if (settings.isParameter("Preconditioner Factory"))
210 precName = settings.get<std::string>("Preconditioner Factory");
211 diagString_ = settings.get<std::string>("Descriptive Label");
212
213 // build preconditioner factory
214 Teuchos::RCP<const InverseLibrary> il = getInverseLibrary();
215 invFactory_ = il->getInverseFactory(invName);
216 if (precName != "") precFactory_ = il->getInverseFactory(precName);
217 TEUCHOS_TEST_FOR_EXCEPTION(invFactory_ == Teuchos::null, std::runtime_error,
218 "ERROR: \"Inverse Factory\" = " << invName << " could not be found");
219
220 if (settings.isParameter("Print Residual")) printResidual_ = settings.get<bool>("Print Residual");
221
222 // build timers to use
223 initTimers(diagString_);
224}
225
230 const {
231 TEUCHOS_TEST_FOR_EXCEPTION(
232 invFactory_ == Teuchos::null, std::runtime_error,
233 "ERROR: Teko::DiagnosticPreconditionerFactory::getRequestedParameters requires that a "
234 << "preconditioner factory has been set. Currently it is null!");
235
236 return invFactory_->getRequestedParameters();
237}
238
242 TEUCHOS_TEST_FOR_EXCEPTION(
243 invFactory_ == Teuchos::null, std::runtime_error,
244 "ERROR: Teko::DiagnosticPreconditionerFactory::updateRequestedParameters requires that a "
245 << "preconditioner factory has been set. Currently it is null!");
246
247 bool success = true;
248 success &= invFactory_->updateRequestedParameters(pl);
249 if (precFactory_) success &= precFactory_->updateRequestedParameters(pl);
250
251 return success;
252}
253
254void DiagnosticPreconditionerFactory::initTimers(const std::string& str) {
255 buildTimer_ = Teuchos::rcp(new Teuchos::Time(str + " buildTimer"));
256 rebuildTimer_ = Teuchos::rcp(new Teuchos::Time(str + " rebuildTimer"));
257 precBuildTimer_ = Teuchos::rcp(new Teuchos::Time(str + " precBuildTimer"));
258 precRebuildTimer_ = Teuchos::rcp(new Teuchos::Time(str + " precRebuildTimer"));
259}
260
261} // end namespace Teko
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.
ModifiableLinearOp createDiagnosticLinearOp(const Teuchos::RCP< std::ostream > &os, const ModifiableLinearOp &A, const std::string &label)
Constructor method for building DiagnosticLinearOp.
Teuchos::RCP< const InverseLibrary > getInverseLibrary() const
Get the inverse library used by this preconditioner factory.
An implementation of a state object preconditioners.
virtual void addModifiableOp(const std::string &name, const Teko::ModifiableLinearOp &mlo)
Add a named operator to the state object.
virtual Teko::ModifiableLinearOp & getModifiableOp(const std::string &name)
Add a named operator to the state object.