Thyra Version of the Day
Loading...
Searching...
No Matches
Thyra_DefaultInverseLinearOp_def.hpp
1// @HEADER
2// *****************************************************************************
3// Thyra: Interfaces and Support for Abstract Numerical Algorithms
4//
5// Copyright 2004 NTESS and the Thyra contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#ifndef THYRA_DEFAULT_INVERSE_LINEAR_OP_DEF_HPP
11#define THYRA_DEFAULT_INVERSE_LINEAR_OP_DEF_HPP
12
13#include "Thyra_DefaultInverseLinearOp_decl.hpp"
14#include "Thyra_MultiVectorStdOps.hpp"
15#include "Thyra_AssertOp.hpp"
16#include "Teuchos_Utils.hpp"
17#include "Teuchos_TypeNameTraits.hpp"
18
19
20namespace Thyra {
21
22
23// Constructors/initializers/accessors
24
25
26template<class Scalar>
29
30
31template<class Scalar>
34 const SolveCriteria<Scalar> *fwdSolveCriteria,
35 const EThrowOnSolveFailure throwOnFwdSolveFailure,
36 const SolveCriteria<Scalar> *adjSolveCriteria,
37 const EThrowOnSolveFailure throwOnAdjSolveFailure
38 )
39{
40 initializeImpl(
41 lows,fwdSolveCriteria,throwOnFwdSolveFailure
42 ,adjSolveCriteria,throwOnAdjSolveFailure
43 );
44}
45
46
47template<class Scalar>
50 const SolveCriteria<Scalar> *fwdSolveCriteria,
51 const EThrowOnSolveFailure throwOnFwdSolveFailure,
52 const SolveCriteria<Scalar> *adjSolveCriteria,
53 const EThrowOnSolveFailure throwOnAdjSolveFailure
54 )
55{
56 initializeImpl(
57 lows,fwdSolveCriteria,throwOnFwdSolveFailure
58 ,adjSolveCriteria,throwOnAdjSolveFailure
59 );
60}
61
62
63template<class Scalar>
66 const SolveCriteria<Scalar> *fwdSolveCriteria,
67 const EThrowOnSolveFailure throwOnFwdSolveFailure,
68 const SolveCriteria<Scalar> *adjSolveCriteria,
69 const EThrowOnSolveFailure throwOnAdjSolveFailure
70 )
71{
72 initializeImpl(
73 lows,fwdSolveCriteria,throwOnFwdSolveFailure
74 ,adjSolveCriteria,throwOnAdjSolveFailure
75 );
76}
77
78
79template<class Scalar>
82 const SolveCriteria<Scalar> *fwdSolveCriteria,
83 const EThrowOnSolveFailure throwOnFwdSolveFailure,
84 const SolveCriteria<Scalar> *adjSolveCriteria,
85 const EThrowOnSolveFailure throwOnAdjSolveFailure
86 )
87{
88 initializeImpl(
89 lows,fwdSolveCriteria,throwOnFwdSolveFailure
90 ,adjSolveCriteria,throwOnAdjSolveFailure
91 );
92}
93
94
95template<class Scalar>
97{
98 lows_.uninitialize();
99 fwdSolveCriteria_ = Teuchos::null;
100 adjSolveCriteria_ = Teuchos::null;
101}
102
103
104// Overridden form InverseLinearOpBase
105
106
107template<class Scalar>
109{
110 return lows_.isConst();
111}
112
113
114template<class Scalar>
117{
118 return lows_.getNonconstObj();
119}
120
121
122template<class Scalar>
125{
126 return lows_.getConstObj();
127}
128
129
130// Overridden from LinearOpBase
131
132
133template<class Scalar>
136{
137 assertInitialized();
138 return lows_.getConstObj()->domain();
139}
140
141
142template<class Scalar>
145{
146 assertInitialized();
147 return lows_.getConstObj()->range();
148}
149
150
151template<class Scalar>
154{
155 return Teuchos::null; // Not supported yet but could be!
156}
157
158
159// Overridden from Teuchos::Describable
160
161
162template<class Scalar>
164{
165 assertInitialized();
166 std::ostringstream oss;
167 oss
169 << "lows="<<lows_.getConstObj()->description()
170 << ",fwdSolveCriteria="<<(fwdSolveCriteria_.get()?"...":"DEFAULT")
171 << ",adjSolveCriteria="<<(adjSolveCriteria_.get()?"...":"DEFAULT")
172 << "}";
173 return oss.str();
174}
175
176
177template<class Scalar>
180 const Teuchos::EVerbosityLevel verbLevel
181 ) const
182{
183 using Teuchos::RCP;
184 using Teuchos::OSTab;
185 assertInitialized();
186 OSTab tab(out);
187 switch(verbLevel) {
190 out << this->description() << std::endl;
191 break;
195 {
196 out
198 << "rangeDim=" << this->range()->dim()
199 << ",domainDim=" << this->domain()->dim() << "}:\n";
200 OSTab tab2(out);
201 out << "lows = ";
202 if(!lows_.getConstObj().get()) {
203 out << " NULL\n";
204 }
205 else {
206 out << Teuchos::describe(*lows_.getConstObj(),verbLevel);
207 }
208 break;
209 }
210 default:
211 TEUCHOS_TEST_FOR_EXCEPT(true); // Should never be called!
212 }
213}
214
215
216// protected
217
218
219// Overridden from LinearOpBase
220
221
222template<class Scalar>
224{
225 if (nonnull(lows_)) {
226 return solveSupports(*lows_.getConstObj(),M_trans);
227 }
228 return false;
229}
230
231
232template<class Scalar>
234 const EOpTransp M_trans,
236 const Ptr<MultiVectorBase<Scalar> > &Y,
237 const Scalar alpha,
238 const Scalar beta
239 ) const
240{
242 assertInitialized();
243 // ToDo: Put in hooks for propogating verbosity level
244 //
245 // Y = alpha*op(M)*X + beta*Y
246 //
247 // =>
248 //
249 // Y = beta*Y
250 // Y += alpha*inv(op(lows))*X
251 //
253 if(beta==ST::zero()) {
254 T = Teuchos::rcpFromPtr(Y);
255 }
256 else {
257 T = createMembers(Y->range(),Y->domain()->dim());
258 scale(beta, Y);
259 }
260 //
261 const Ptr<const SolveCriteria<Scalar> > solveCriteria =
262 (
263 real_trans(M_trans)==NOTRANS
264 ? fwdSolveCriteria_.ptr()
265 : adjSolveCriteria_.ptr()
266 );
267 assign(T.ptr(), ST::zero()); // Have to initialize before solve!
268 SolveStatus<Scalar> solveStatus =
269 Thyra::solve<Scalar>(*lows_.getConstObj(), M_trans, X, T.ptr(), solveCriteria);
270
272 nonnull(solveCriteria) && solveStatus.solveStatus!=SOLVE_STATUS_CONVERGED
273 && ( real_trans(M_trans)==NOTRANS
274 ? throwOnFwdSolveFailure_==THROW_ON_SOLVE_FAILURE
275 : throwOnAdjSolveFailure_==THROW_ON_SOLVE_FAILURE )
277 ,"Error, the LOWS object " << lows_.getConstObj()->description() << " returned an unconverged"
278 "status of " << toString(solveStatus.solveStatus) << " with the message "
279 << solveStatus.message << "."
280 );
281 //
282 if(beta==ST::zero()) {
283 scale(alpha, Y);
284 }
285 else {
286 update( alpha, *T, Y );
287 }
288}
289
290
291// private
292
293
294template<class Scalar>
295template<class LOWS>
297 const Teuchos::RCP<LOWS> &lows,
298 const SolveCriteria<Scalar> *fwdSolveCriteria,
299 const EThrowOnSolveFailure throwOnFwdSolveFailure,
300 const SolveCriteria<Scalar> *adjSolveCriteria,
301 const EThrowOnSolveFailure throwOnAdjSolveFailure
302 )
303{
304 lows_.initialize(lows);
305 if(fwdSolveCriteria)
306 fwdSolveCriteria_ = Teuchos::rcp(new SolveCriteria<Scalar>(*fwdSolveCriteria));
307 else
308 fwdSolveCriteria_ = Teuchos::null;
309 if(adjSolveCriteria)
310 adjSolveCriteria_ = Teuchos::rcp(new SolveCriteria<Scalar>(*adjSolveCriteria));
311 else
312 adjSolveCriteria_ = Teuchos::null;
313 throwOnFwdSolveFailure_ = throwOnFwdSolveFailure;
314 throwOnAdjSolveFailure_ = throwOnAdjSolveFailure;
315 const std::string lowsLabel = lows_.getConstObj()->getObjectLabel();
316 if(lowsLabel.length())
317 this->setObjectLabel( "inv("+lowsLabel+")" );
318}
319
320
321} // end namespace Thyra
322
323
324// Related non-member functions
325
326
327template<class Scalar>
329Thyra::nonconstInverse(
330 const RCP<LinearOpWithSolveBase<Scalar> > &A,
331 const Ptr<const SolveCriteria<Scalar> > &fwdSolveCriteria,
332 const EThrowOnSolveFailure throwOnFwdSolveFailure,
333 const Ptr<const SolveCriteria<Scalar> > &adjSolveCriteria,
334 const EThrowOnSolveFailure throwOnAdjSolveFailure
335 )
336{
337 return Teuchos::rcp(
338 new DefaultInverseLinearOp<Scalar>(
339 A, fwdSolveCriteria.get(), throwOnFwdSolveFailure,
340 adjSolveCriteria.get(), throwOnAdjSolveFailure
341 )
342 );
343}
344
345template<class Scalar>
347Thyra::inverse(
348 const RCP<const LinearOpWithSolveBase<Scalar> > &A,
349 const Ptr<const SolveCriteria<Scalar> > &fwdSolveCriteria,
350 const EThrowOnSolveFailure throwOnFwdSolveFailure,
351 const Ptr<const SolveCriteria<Scalar> > &adjSolveCriteria,
352 const EThrowOnSolveFailure throwOnAdjSolveFailure
353 )
354{
355 return Teuchos::rcp(
356 new DefaultInverseLinearOp<Scalar>(
357 A, fwdSolveCriteria.get(), throwOnFwdSolveFailure,
358 adjSolveCriteria.get(), throwOnAdjSolveFailure
359 )
360 );
361}
362
363
364//
365// Explicit instantiation macro
366//
367// Must be expanded from within the Thyra namespace!
368//
369
370
371#define THYRA_DEFAULT_INVERSE_LINEAR_OP_INSTANT(SCALAR) \
372 \
373 template class DefaultInverseLinearOp<SCALAR >; \
374 \
375 template RCP<LinearOpBase<SCALAR > > \
376 nonconstInverse( \
377 const RCP<LinearOpWithSolveBase<SCALAR > > &A, \
378 const Ptr<const SolveCriteria<SCALAR > > &fwdSolveCriteria, \
379 const EThrowOnSolveFailure throwOnFwdSolveFailure, \
380 const Ptr<const SolveCriteria<SCALAR > > &adjSolveCriteria, \
381 const EThrowOnSolveFailure throwOnAdjSolveFailure \
382 ); \
383 \
384 template RCP<LinearOpBase<SCALAR > > \
385 inverse( \
386 const RCP<const LinearOpWithSolveBase<SCALAR > > &A, \
387 const Ptr<const SolveCriteria<SCALAR > > &fwdSolveCriteria, \
388 const EThrowOnSolveFailure throwOnFwdSolveFailure, \
389 const Ptr<const SolveCriteria<SCALAR > > &adjSolveCriteria, \
390 const EThrowOnSolveFailure throwOnAdjSolveFailure \
391 );
392
393
394#endif // THYRA_DEFAULT_INVERSE_LINEAR_OP_DEF_HPP
virtual std::string description() const
Ptr< T > ptr() const
Exception type thrown on an catastrophic solve failure.
Concrete LinearOpBase subclass that creates an implicit LinearOpBase object using the inverse action ...
void applyImpl(const EOpTransp M_trans, const MultiVectorBase< Scalar > &X, const Ptr< MultiVectorBase< Scalar > > &Y, const Scalar alpha, const Scalar beta) const
RCP< const LinearOpWithSolveBase< Scalar > > getLows() const
RCP< const LinearOpBase< Scalar > > clone() const
void initialize(const RCP< LinearOpWithSolveBase< Scalar > > &lows, const SolveCriteria< Scalar > *fwdSolveCriteria=NULL, const EThrowOnSolveFailure throwOnFwdSolveFailure=THROW_ON_SOLVE_FAILURE, const SolveCriteria< Scalar > *adjSolveCriteria=NULL, const EThrowOnSolveFailure throwOnAdjSolveFailure=THROW_ON_SOLVE_FAILURE)
Initialize given a non-const LinearOpWithSolveBase object and an optional .
DefaultInverseLinearOp()
Constructs to uninitialized (see postconditions for uninitialize()).
RCP< const VectorSpaceBase< Scalar > > domain() const
Returns this->getLows()->range() if <t>this->getLows().get()!=NULL and returns Teuchos::null otherwis...
RCP< const VectorSpaceBase< Scalar > > range() const
Returns this->getLows()->domain() if <t>this->getLows().get()!=NULL and returns Teuchos::null otherwi...
void describe(FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
RCP< LinearOpWithSolveBase< Scalar > > getNonconstLows()
bool opSupportedImpl(EOpTransp M_trans) const
Returns true only if all constituent operators support M_trans.
Base class for all linear operators that can support a high-level solve operation.
Interface for a collection of column vectors called a multi-vector.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
@ SOLVE_STATUS_CONVERGED
The requested solution criteria has likely been achieved.
EThrowOnSolveFailure
Determines what to do if inverse solve fails.
@ THROW_ON_SOLVE_FAILURE
Throw an exception if a solve fails to converge.
EOpTransp
Enumeration for determining how a linear operator is applied. `*.
const char * toString(EConj conj)
Return a string name for a EOpTransp value. `*.
EOpTransp real_trans(EOpTransp transp)
Return NOTRANS or TRANS for real scalar valued operators and this also is used for determining struct...
@ NOTRANS
Use the non-transposed operator.
T_To & dyn_cast(T_From &from)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Simple struct that defines the requested solution criteria for a solve.
Simple struct for the return status from a solve.
std::string message
A simple one-line message (i.e. no newlines) returned from the solver.
ESolveStatus solveStatus
The return status of the solve.