Thyra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Thyra_LinearOpWithSolveFactoryExamples.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_LINEAR_OP_WITH_SOLVE_EXAMPLES_HPP
11 #define THYRA_LINEAR_OP_WITH_SOLVE_EXAMPLES_HPP
12 
13 
14 #include "Thyra_LinearOpWithSolveFactoryBase.hpp"
15 #include "Thyra_LinearOpWithSolveFactoryHelpers.hpp"
16 #include "Thyra_LinearOpWithSolveBase.hpp"
17 #include "Thyra_PreconditionerFactoryHelpers.hpp"
18 #include "Thyra_DefaultScaledAdjointLinearOp.hpp"
19 #include "Thyra_DefaultPreconditioner.hpp"
20 #include "Thyra_MultiVectorStdOps.hpp"
21 #include "Thyra_VectorStdOps.hpp"
22 #include "Thyra_VectorBase.hpp"
23 
24 
25 namespace Thyra {
26 
27 
28 //
29 // Helper code
30 //
31 
42 template<class Scalar>
44 public:
46  virtual ~LinearOpChanger() {}
48  virtual void changeOp( const Teuchos::Ptr<LinearOpBase<Scalar> > &op ) const = 0;
49 };
50 
54 template<class Scalar>
55 class NullLinearOpChanger : public LinearOpChanger<Scalar> {
56 public:
58  void changeOp( const Teuchos::Ptr<LinearOpBase<Scalar> > &op ) const {}
59 };
60 
61 
62 } // namespace Thyra
63 
64 
65 //
66 // Individual non-externally preconditioned use cases
67 //
68 
69 
70 // begin singleLinearSolve
74 template<class Scalar>
75 void singleLinearSolve(
81  )
82 {
84  using Teuchos::rcpFromRef;
85  Teuchos::OSTab tab(out);
86  out << "\nPerforming a single linear solve ...\n";
87  // Create the LOWSB object that will be used to solve the linear system
89  Thyra::linearOpWithSolve(lowsFactory, rcpFromRef(A));
90  // Solve the system using a default solve criteria using a non-member helper function
91  assign(x, ST::zero()); // Must initialize to a guess before solve!
93  status = Thyra::solve<Scalar>(*invertibleA, Thyra::NOTRANS, b, x);
94  out << "\nSolve status:\n" << status;
95 } // end singleLinearSolve
96 
97 
98 // begin createScaledAdjointLinearOpWithSolve
103 template<class Scalar>
105 createScaledAdjointLinearOpWithSolve(
106  const Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > &A,
107  const Scalar &scalar,
110  )
111 {
112  Teuchos::OSTab tab(out);
113  out << "\nCreating a scaled adjoint LinearOpWithSolveBase object ...\n";
114  // Create the LOWSB object that will be used to solve the linear system
116  Thyra::linearOpWithSolve(lowsFactory,scale(scalar,adjoint(A)));
117  out << "\nCreated LOWSB object:\n" << describe(*invertibleAdjointA,
119  return invertibleAdjointA;
120 } // end createScaledAdjointLinearOpWithSolve
121 
122 
123 // begin solveNumericalChangeSolve
128 template<class Scalar>
129 void solveNumericalChangeSolve(
131  const Thyra::LinearOpChanger<Scalar> &opChanger,
133  const Thyra::VectorBase<Scalar> &b1,
135  const Thyra::VectorBase<Scalar> &b2,
138  )
139 {
140  using Teuchos::as; using Teuchos::ptr; using Teuchos::rcpFromPtr;
141  Teuchos::OSTab tab(out);
142  out << "\nPerforming a solve, changing the operator, then performing another"
143  << " solve ...\n";
144  // Get a local non-owned RCP to A to be used by lowsFactory
145  Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > rcpA = rcpFromPtr(A);
146  // Create the LOWSB object that will be used to solve the linear system
148  lowsFactory.createOp();
149  // Initialize the invertible linear operator given the forward operator
150  Thyra::initializeOp<Scalar>(lowsFactory, rcpA, invertibleA.ptr());
151  // Solve the system using a default solve criteria using a non-member helper function
152  Thyra::assign(x1, as<Scalar>(0.0));
153  Thyra::solve<Scalar>(*invertibleA, Thyra::NOTRANS, b1, x1);
154  // Before the forward operator A is changed it is recommended that you
155  // uninitialize *invertibleA first to avoid accidental use of *invertiableA
156  // while it may be in an inconsistent state from the time between *A changes
157  // and *invertibleA is explicitly updated. However, this step is not
158  // required!
159  Thyra::uninitializeOp<Scalar>(lowsFactory, invertibleA.ptr());
160  // Change the operator and reinitialize the invertible operator
161  opChanger.changeOp(A);
162  Thyra::initializeOp<Scalar>(lowsFactory, rcpA, invertibleA.ptr());
163  // Note that above will reuse any factorization structures that may have been
164  // created in the first call to initializeOp(...).
165  // Finally, solve another linear system with new values of A
166  Thyra::assign<Scalar>(x2, as<Scalar>(0.0));
167  Thyra::solve<Scalar>(*invertibleA, Thyra::NOTRANS, b2, x2);
168 } // end solveNumericalChangeSolve
169 
170 
171 // begin solveSmallNumericalChangeSolve
177 template<class Scalar>
178 void solveSmallNumericalChangeSolve(
180  const Thyra::LinearOpChanger<Scalar> &opSmallChanger,
182  const Thyra::VectorBase<Scalar> &b1,
184  const Thyra::VectorBase<Scalar> &b2,
187  )
188 {
189  using Teuchos::ptr; using Teuchos::as; using Teuchos::rcpFromPtr;
190  Teuchos::OSTab tab(out);
191  out << "\nPerforming a solve, changing the operator in a very small way,"
192  << " then performing another solve ...\n";
193  // Get a local non-owned RCP to A to be used by lowsFactory
194  Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > rcpA = rcpFromPtr(A);
195  // Create the LOWSB object that will be used to solve the linear system
197  lowsFactory.createOp();
198  // Initialize the invertible linear operator given the forward operator
199  Thyra::initializeOp<Scalar>(lowsFactory, rcpA, invertibleA.ptr());
200  // Solve the system using a default solve criteria using a non-member helper function
201  Thyra::assign(x1, as<Scalar>(0.0));
202  Thyra::solve<Scalar>(*invertibleA, Thyra::NOTRANS, b1, x1);
203  // Before the forward operator A is changed it is recommended that you
204  // uninitialize *invertibleA first to avoid accidental use of *invertiableA
205  // while it may be in an inconsistent state from the time between *A changes
206  // and *invertibleA is explicitly updated. However, this step is not
207  // required!
208  Thyra::uninitializeOp<Scalar>(lowsFactory, invertibleA.ptr());
209  // Change the operator and reinitialize the invertible operator
210  opSmallChanger.changeOp(A);
211  Thyra::initializeAndReuseOp<Scalar>(lowsFactory, rcpA, invertibleA.ptr());
212  // Note that above a maximum amount of reuse will be achieved, such as
213  // keeping the same preconditioner.
214  Thyra::assign(x2, as<Scalar>(0.0));
215  Thyra::solve<Scalar>(*invertibleA, Thyra::NOTRANS, b2, x2);
216 } // end solveSmallNumericalChangeSolve
217 
218 
219 // begin solveMajorChangeSolve
225 template<class Scalar>
226 void solveMajorChangeSolve(
228  const Thyra::LinearOpChanger<Scalar> &opMajorChanger,
230  const Thyra::VectorBase<Scalar> &b1,
232  const Thyra::VectorBase<Scalar> &b2,
235  )
236 {
237  using Teuchos::as; using Teuchos::rcpFromPtr;
238  Teuchos::OSTab tab(out);
239  out << "\nPerforming a solve, changing the operator in a major way, then performing"
240  << " another solve ...\n";
241  // Get a local non-owned RCP to A to be used by lowsFactory
242  Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > rcpA = rcpFromPtr(A);
243  // Create the LOWSB object that will be used to solve the linear system
245  lowsFactory.createOp();
246  // Initialize the invertible linear operator given the forward operator
247  Thyra::initializeOp<Scalar>(lowsFactory, rcpA, invertibleA.ptr());
248  // Solve the system using a default solve criteria using a non-member helper function
249  Thyra::assign(x1, as<Scalar>(0.0));
250  Thyra::solve<Scalar>(*invertibleA, Thyra::NOTRANS, b1, x1);
251  // Before the forward operator A is changed it is recommended that you
252  // uninitialize *invertibleA first to avoid accidental use of *invertiableA
253  // while it may be in an inconsistent state from the time between *A changes
254  // and *invertibleA is explicitly updated. However, this step is not
255  // required!
256  Thyra::uninitializeOp<Scalar>(lowsFactory, invertibleA.ptr());
257  // Change the operator in some major way (perhaps even changing its structure)
258  opMajorChanger.changeOp(A);
259  // Recreate the LOWSB object and initialize it from scratch
260  invertibleA = lowsFactory.createOp();
261  Thyra::initializeOp<Scalar>(lowsFactory, rcpA, invertibleA.ptr());
262  // Solve another set of linear systems
263  Thyra::assign(x2, as<Scalar>(0.0));
264  Thyra::solve<Scalar>(*invertibleA, Thyra::NOTRANS, b2, x2);
265 } // end solveMajorChangeSolve
266 
267 
268 //
269 // Individual externally preconditioned use cases
270 //
271 
272 
273 // begin createGeneralPreconditionedLinearOpWithSolve
279 template<class Scalar>
281 createGeneralPreconditionedLinearOpWithSolve(
282  const Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > &A,
286  )
287 {
288  Teuchos::OSTab tab(out);
289  out << "\nCreating an externally preconditioned LinearOpWithSolveBase object ...\n";
291  lowsFactory.createOp();
292  Thyra::initializePreconditionedOp<Scalar>(lowsFactory, A, P, invertibleA.ptr());
293  out << "\nCreated LOWSB object:\n" << describe(*invertibleA, Teuchos::VERB_MEDIUM);
294  return invertibleA;
295 } // end createGeneralPreconditionedLinearOpWithSolve
296 
297 
298 // begin createUnspecifiedPreconditionedLinearOpWithSolve
304 template<class Scalar>
306 createUnspecifiedPreconditionedLinearOpWithSolve(
307  const Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > &A,
308  const Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > &P_op,
311  )
312 {
313  Teuchos::OSTab tab(out);
314  out << "\nCreating an LinearOpWithSolveBase object given a preconditioner operator"
315  << " not targeted to the left or right ...\n";
317  lowsFactory.createOp();
318  Thyra::initializePreconditionedOp<Scalar>(lowsFactory, A,
319  Thyra::unspecifiedPrec<Scalar>(P_op), invertibleA.ptr());
320  // Above, the lowsFactory object will decide whether to apply the single
321  // preconditioner operator on the left or on the right.
322  out << "\nCreated LOWSB object:\n" << describe(*invertibleA, Teuchos::VERB_MEDIUM);
323  return invertibleA;
324 } // end createUnspecifiedPreconditionedLinearOpWithSolve
325 
326 
327 // begin createLeftPreconditionedLinearOpWithSolve
333 template<class Scalar>
335 createLeftPreconditionedLinearOpWithSolve(
336  const Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > &A,
337  const Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > &P_op_left,
340  )
341 {
342  Teuchos::OSTab tab(out);
343  out << "\nCreating an LinearOpWithSolveBase object given a left preconditioner"
344  << " operator ...\n";
346  lowsFactory.createOp();
347  Thyra::initializePreconditionedOp<Scalar>(lowsFactory, A,
348  Thyra::leftPrec<Scalar>(P_op_left), invertibleA.ptr());
349  out << "\nCreated LOWSB object:\n" << describe(*invertibleA, Teuchos::VERB_MEDIUM);
350  return invertibleA;
351 } // end createLeftPreconditionedLinearOpWithSolve
352 
353 
354 // begin createRightPreconditionedLinearOpWithSolve
360 template<class Scalar>
362 createRightPreconditionedLinearOpWithSolve(
363  const Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > &A,
364  const Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > &P_op_right,
367  )
368 {
369  Teuchos::OSTab tab(out);
370  out << "\nCreating an LinearOpWithSolveBase object given a right"
371  << " preconditioner operator ...\n";
373  lowsFactory.createOp();
374  Thyra::initializePreconditionedOp<Scalar>(lowsFactory, A,
375  Thyra::rightPrec<Scalar>(P_op_right), invertibleA.ptr());
376  out << "\nCreated LOWSB object:\n" << describe(*invertibleA, Teuchos::VERB_MEDIUM);
377  return invertibleA;
378 } // end createRightPreconditionedLinearOpWithSolve
379 
380 
381 // begin createLeftRightPreconditionedLinearOpWithSolve
387 template<class Scalar>
389 createLeftRightPreconditionedLinearOpWithSolve(
390  const Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > &A,
391  const Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > &P_op_left,
392  const Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > &P_op_right,
395  )
396 {
397  Teuchos::OSTab tab(out);
398  out << "\nCreating an LinearOpWithSolveBase object given a left and"
399  << "right preconditioner operator ...\n";
401  lowsFactory.createOp();
402  Thyra::initializePreconditionedOp<Scalar>(lowsFactory, A,
403  Thyra::splitPrec<Scalar>(P_op_left, P_op_right), invertibleA.ptr());
404  out << "\nCreated LOWSB object:\n" << describe(*invertibleA, Teuchos::VERB_MEDIUM);
405  return invertibleA;
406 } // end createLeftRightPreconditionedLinearOpWithSolve
407 
408 
409 // begin createMatrixPreconditionedLinearOpWithSolve
415 template<class Scalar>
417 createMatrixPreconditionedLinearOpWithSolve(
418  const Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > &A,
419  const Teuchos::RCP<const Thyra::LinearOpBase<Scalar> > &A_approx,
422  )
423 {
424  Teuchos::OSTab tab(out);
425  out << "\nCreating a LinearOpWithSolveBase object given an approximate forward"
426  << " operator to define the preconditioner ...\n";
428  lowsFactory.createOp();
429  Thyra::initializeApproxPreconditionedOp<Scalar>(lowsFactory, A, A_approx,
430  invertibleA.ptr());
431  out << "\nCreated LOWSB object:\n" << describe(*invertibleA, Teuchos::VERB_MEDIUM);
432  return invertibleA;
433 } // end createMatrixPreconditionedLinearOpWithSolve
434 
435 
436 // begin externalPreconditionerReuseWithSolves
440 template<class Scalar>
441 void externalPreconditionerReuseWithSolves(
442  const Teuchos::Ptr<Thyra::LinearOpBase<Scalar> > &A_inout,
443  const Thyra::LinearOpChanger<Scalar> &opChanger,
445  const Thyra::PreconditionerFactoryBase<Scalar> &precFactory,
446  const Thyra::VectorBase<Scalar> &b1,
448  const Thyra::VectorBase<Scalar> &b2,
451  )
452 {
453  using Teuchos::tab; using Teuchos::rcpFromPtr;
455  Teuchos::OSTab tab2(out);
456  out << "\nShowing resuse of the preconditioner ...\n";
457  Teuchos::RCP<Thyra::LinearOpBase<Scalar> > A = rcpFromPtr(A_inout);
458  // Create the initial preconditioner for the input forward operator
460  precFactory.createPrec();
461  Thyra::initializePrec<Scalar>(precFactory, A, P.ptr());
462  // Create the invertible LOWS object given the preconditioner
464  lowsFactory.createOp();
465  Thyra::initializePreconditionedOp<Scalar>(lowsFactory, A, P, invertibleA.ptr());
466  // Solve the first linear system
467  assign(x1, ST::zero());
468  Thyra::SolveStatus<Scalar> status1 = Thyra::solve<Scalar>(*invertibleA,
469  Thyra::NOTRANS, b1, x1);
470  out << "\nSolve status:\n" << status1;
471  // Change the forward linear operator without changing the preconditioner
472  opChanger.changeOp(A.ptr());
473  // Warning! After the above change the integrity of the preconditioner
474  // linear operators in P is undefined. For some implementations of the
475  // preconditioner, its behavior will remain unchanged (e.g. ILU) which in
476  // other cases the behavior will change but the preconditioner will still
477  // work (e.g. Jacobi). However, there may be valid implementations where
478  // the preconditioner will simply break if the forward operator that it is
479  // based on breaks.
480  //
481  // Reinitialize the LOWS object given the updated forward operator A and the
482  // old preconditioner P.
483  Thyra::initializePreconditionedOp<Scalar>(lowsFactory, A, P, invertibleA.ptr());
484  // Solve the second linear system
485  assign(x2, ST::zero());
486  Thyra::SolveStatus<Scalar>status2 = Thyra::solve<Scalar>(*invertibleA,
487  Thyra::NOTRANS, b2, x2);
488  out << "\nSolve status:\n" << status2;
489 } // end externalPreconditionerReuseWithSolves
490 
491 
492 //
493 // Combined use cases
494 //
495 
496 
502 template<class Scalar>
503 void nonExternallyPreconditionedLinearSolveUseCases(
506  bool supportsAdjoints,
508  )
509 {
510  using Teuchos::as;
511  Teuchos::OSTab tab(out);
512  out << "\nRunning example use cases for a LinearOpWithSolveFactoryBase object ...\n";
513  // Create a non-const A object (don't worry, it will not be changed)
514  const Teuchos::Ptr<Thyra::LinearOpBase<Scalar> > A_nonconst =
515  Teuchos::ptrFromRef(const_cast<Thyra::LinearOpBase<Scalar>&>(A));
516  // Create the RHS (which is just a random set of coefficients)
518  b1 = Thyra::createMember(A.range()),
519  b2 = Thyra::createMember(A.range());
520  Thyra::randomize( as<Scalar>(-1.0), as<Scalar>(+1.0), b1.ptr() );
521  Thyra::randomize( as<Scalar>(-1.0), as<Scalar>(+1.0), b2.ptr() );
522  // Create the LHS for the linear solve
524  x1 = Thyra::createMember(A.domain()),
525  x2 = Thyra::createMember(A.domain());
526  // Perform a single, non-adjoint, linear solve
527  singleLinearSolve(A, lowsFactory, *b1, x1.ptr(), out);
528  // Creating a scaled adjoint LinearOpWithSolveBase object
529  if(supportsAdjoints) {
531  invertibleAdjointA = createScaledAdjointLinearOpWithSolve(
532  Teuchos::rcp(&A,false),as<Scalar>(2.0),lowsFactory,out);
533  }
534  // Perform a solve, change the operator, and then solve again.
535  solveNumericalChangeSolve<Scalar>(
536  A_nonconst, // Don't worry, it will not be changed!
537  Thyra::NullLinearOpChanger<Scalar>(), // This object will not really change A!
538  lowsFactory, *b1, x1.ptr(), *b2, x1.ptr(), out );
539  // Perform a solve, change the operator in a very small way, and then solve again.
540  solveSmallNumericalChangeSolve<Scalar>(
541  A_nonconst, // Don't worry, it will not be changed!
542  Thyra::NullLinearOpChanger<Scalar>(), // This object will not really change A!
543  lowsFactory, *b1, x1.ptr(), *b2, x1.ptr(), out );
544  // Perform a solve, change the operator in a major way, and then solve again.
545  solveMajorChangeSolve<Scalar>(
546  A_nonconst, // Don't worry, it will not be changed!
547  Thyra::NullLinearOpChanger<Scalar>(), // This object will not really change A!
548  lowsFactory, *b1, x1.ptr(), *b2, x1.ptr(), out );
549 }
550 
551 
557 template<class Scalar>
558 void externallyPreconditionedLinearSolveUseCases(
561  const Thyra::PreconditionerFactoryBase<Scalar> &precFactory,
562  const bool supportsLeftPrec,
563  const bool supportsRightPrec,
565  )
566 {
567  using Teuchos::rcpFromRef; using Teuchos::as;
568  Teuchos::OSTab tab(out);
569  out << "\nRunning example use cases with an externally defined"
570  << " preconditioner with a LinearOpWithSolveFactoryBase object ...\n";
571  // Create a non-const A object (don't worry, it will not be changed)
572  const Teuchos::Ptr<Thyra::LinearOpBase<Scalar> > A_nonconst =
573  Teuchos::ptrFromRef(const_cast<Thyra::LinearOpBase<Scalar>&>(A));
574  // Create the RHS (which is just a random set of coefficients)
576  b1 = Thyra::createMember(A.range()),
577  b2 = Thyra::createMember(A.range());
578  Thyra::randomize( as<Scalar>(-1.0), as<Scalar>(+1.0), b1.ptr() );
579  Thyra::randomize( as<Scalar>(-1.0), as<Scalar>(+1.0), b2.ptr() );
580  // Create the LHS for the linear solve
582  x1 = Thyra::createMember(A.domain()),
583  x2 = Thyra::createMember(A.domain());
584  // Create a preconditioner for the input forward operator
586  P = precFactory.createPrec();
587  Thyra::initializePrec<Scalar>(precFactory, rcpFromRef(A), P.ptr());
588  // Above, we don't really know the nature of the preconditioner. It could a
589  // single linear operator to be applied on the left or the right or it could
590  // be a split preconditioner with different linear operators to be applied
591  // on the right or left. Or, it could be a single linear operator that is
592  // not targeted to the left or the right.
593  //
594  // Create a LOWSB object given the created preconditioner
596  invertibleA = createGeneralPreconditionedLinearOpWithSolve<Scalar>(
597  Teuchos::rcp(&A, false), P.getConst(), lowsFactory, out);
598  // Grab a preconditioner operator out of the preconditioner object
600  // Clang 3.2 issues a warning if semicolons are on the same line as
601  // the 'if' statement. It's good practice in any case to make the
602  // empty 'if' body clear.
603  if (nonnull (P_op = P->getUnspecifiedPrecOp ()))
604  ;
605  else if (nonnull (P_op = P->getLeftPrecOp ()))
606  ;
607  else if (nonnull (P_op = P->getRightPrecOp ()))
608  ;
609  // Create a LOWSB object given an unspecified preconditioner operator
610  invertibleA = createUnspecifiedPreconditionedLinearOpWithSolve(
611  rcpFromRef(A), P_op, lowsFactory, out);
612  // Create a LOWSB object given a left preconditioner operator
613  if(supportsLeftPrec) {
614  invertibleA = createLeftPreconditionedLinearOpWithSolve(
615  rcpFromRef(A), P_op, lowsFactory,out);
616  }
617  // Create a LOWSB object given a right preconditioner operator
618  if(supportsRightPrec) {
619  invertibleA = createRightPreconditionedLinearOpWithSolve(
620  rcpFromRef(A), P_op, lowsFactory, out);
621  }
622  // Create a LOWSB object given (bad set of) left and right preconditioner
623  // operators
624  if( supportsLeftPrec && supportsRightPrec ) {
625  invertibleA = createLeftRightPreconditionedLinearOpWithSolve(
626  rcpFromRef(A), P_op, P_op, lowsFactory, out);
627  }
628  // Create a LOWSB object given a (very good) approximate forward linear
629  // operator to construct the preconditoner from..
630  invertibleA = createMatrixPreconditionedLinearOpWithSolve<Scalar>(
631  rcpFromRef(A), rcpFromRef(A), lowsFactory,out);
632  // Preconditioner reuse example
633  externalPreconditionerReuseWithSolves<Scalar>(
634  A_nonconst, // Don't worry, it will not be changed!
635  Thyra::NullLinearOpChanger<Scalar>(), // This object will not really change A!
636  lowsFactory, precFactory,
637  *b1, x1.ptr(), *b2, x2.ptr(), out );
638 }
639 
640 
641 #endif // THYRA_LINEAR_OP_WITH_SOLVE_EXAMPLES_HPP
void changeOp(const Teuchos::Ptr< LinearOpBase< Scalar > > &op) const
virtual RCP< const VectorSpaceBase< Scalar > > range() const =0
Return a smart pointer for the range space for this operator.
Silly abstract strategy interface for changing Thyra::LinearOpBase objects.
void assign(const Ptr< MultiVectorBase< Scalar > > &V, Scalar alpha)
V = alpha.
Use the non-transposed operator.
virtual RCP< PreconditionerBase< Scalar > > createPrec() const =0
Create an (uninitialized) LinearOpBase object to be initialized as the preconditioner later in this-&gt;...
Simple interface class to access a precreated preconditioner as one or more linear operators objects ...
virtual RCP< LinearOpWithSolveBase< Scalar > > createOp() const =0
Create an (uninitialized) LinearOpWithSolveBase object to be initialized later in this-&gt;initializeOp(...
RCP< const LinearOpBase< Scalar > > scale(const Scalar &scalar, const RCP< const LinearOpBase< Scalar > > &Op, const std::string &label="")
Build an implicit const scaled linear operator.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Factory interface for creating LinearOpWithSolveBase objects from compatible LinearOpBase objects...
Ptr< T > ptr() const
Abstract interface for finite-dimensional dense vectors.
Factory interface for creating preconditioner objects from LinearOpBase objects.
Simple struct for the return status from a solve.
Base class for all linear operators.
RCP< const LinearOpBase< Scalar > > adjoint(const RCP< const LinearOpBase< Scalar > > &Op, const std::string &label="")
Build an implicit const adjoined linear operator.
virtual RCP< const VectorSpaceBase< Scalar > > domain() const =0
Return a smart pointer for the domain space for this operator.
bool nonnull(const boost::shared_ptr< T > &p)
TypeTo as(const TypeFrom &t)
virtual void changeOp(const Teuchos::Ptr< LinearOpBase< Scalar > > &op) const =0