Thyra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
20 namespace Thyra {
21 
22 
23 // Constructors/initializers/accessors
24 
25 
26 template<class Scalar>
28 {}
29 
30 
31 template<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 
47 template<class Scalar>
49  const Teuchos::RCP<const LinearOpWithSolveBase<Scalar> > &lows,
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 
63 template<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 
79 template<class Scalar>
81  const Teuchos::RCP<const LinearOpWithSolveBase<Scalar> > &lows,
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 
95 template<class Scalar>
97 {
98  lows_.uninitialize();
99  fwdSolveCriteria_ = Teuchos::null;
100  adjSolveCriteria_ = Teuchos::null;
101 }
102 
103 
104 // Overridden form InverseLinearOpBase
105 
106 
107 template<class Scalar>
109 {
110  return lows_.isConst();
111 }
112 
113 
114 template<class Scalar>
117 {
118  return lows_.getNonconstObj();
119 }
120 
121 
122 template<class Scalar>
125 {
126  return lows_.getConstObj();
127 }
128 
129 
130 // Overridden from LinearOpBase
131 
132 
133 template<class Scalar>
136 {
137  assertInitialized();
138  return lows_.getConstObj()->domain();
139 }
140 
141 
142 template<class Scalar>
145 {
146  assertInitialized();
147  return lows_.getConstObj()->range();
148 }
149 
150 
151 template<class Scalar>
154 {
155  return Teuchos::null; // Not supported yet but could be!
156 }
157 
158 
159 // Overridden from Teuchos::Describable
160 
161 
162 template<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 
177 template<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) {
189  case Teuchos::VERB_LOW:
190  out << this->description() << std::endl;
191  break;
193  case Teuchos::VERB_HIGH:
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 
222 template<class Scalar>
224 {
225  if (nonnull(lows_)) {
226  return solveSupports(*lows_.getConstObj(),M_trans);
227  }
228  return false;
229 }
230 
231 
232 template<class Scalar>
234  const EOpTransp M_trans,
235  const MultiVectorBase<Scalar> &X,
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 
294 template<class Scalar>
295 template<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 
327 template<class Scalar>
329 Thyra::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 
345 template<class Scalar>
347 Thyra::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
Base class for all linear operators that can support a high-level solve operation.
EOpTransp
Enumeration for determining how a linear operator is applied. `*.
basic_OSTab< char > OSTab
RCP< const LinearOpBase< Scalar > > clone() const
DefaultInverseLinearOp()
Constructs to uninitialized (see postconditions for uninitialize()).
bool opSupportedImpl(EOpTransp M_trans) const
Returns true only if all constituent operators support M_trans.
void describe(FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Use the non-transposed operator.
EOpTransp real_trans(EOpTransp transp)
Return NOTRANS or TRANS for real scalar valued operators and this also is used for determining struct...
RCP< const VectorSpaceBase< Scalar > > range() const
Returns this-&gt;getLows()-&gt;domain() if &lt;t&gt;this-&gt;getLows().get()!=NULL and returns Teuchos::null otherwi...
void applyImpl(const EOpTransp M_trans, const MultiVectorBase< Scalar > &X, const Ptr< MultiVectorBase< Scalar > > &Y, const Scalar alpha, const Scalar beta) const
Throw an exception if a solve fails to converge.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Interface for a collection of column vectors called a multi-vector.
Ptr< T > ptr() const
virtual std::string description() const
TEUCHOSCORE_LIB_DLL_EXPORT std::string toString(const EVerbosityLevel verbLevel)
Simple struct for the return status from a solve.
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 .
RCP< const VectorSpaceBase< Scalar > > domain() const
Returns this-&gt;getLows()-&gt;range() if &lt;t&gt;this-&gt;getLows().get()!=NULL and returns Teuchos::null otherwis...
bool nonnull(const boost::shared_ptr< T > &p)
EThrowOnSolveFailure
Determines what to do if inverse solve fails.
The requested solution criteria has likely been achieved.
Exception type thrown on an catastrophic solve failure.
Simple struct that defines the requested solution criteria for a solve.
RCP< const LinearOpWithSolveBase< Scalar > > getLows() const
Concrete LinearOpBase subclass that creates an implicit LinearOpBase object using the inverse action ...
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
RCP< LinearOpWithSolveBase< Scalar > > getNonconstLows()