42 #ifndef THYRA_LINEAR_OP_WITH_SOLVE_EXAMPLES_HPP
43 #define THYRA_LINEAR_OP_WITH_SOLVE_EXAMPLES_HPP
46 #include "Thyra_LinearOpWithSolveFactoryBase.hpp"
47 #include "Thyra_LinearOpWithSolveFactoryHelpers.hpp"
48 #include "Thyra_LinearOpWithSolveBase.hpp"
49 #include "Thyra_PreconditionerFactoryHelpers.hpp"
50 #include "Thyra_DefaultScaledAdjointLinearOp.hpp"
51 #include "Thyra_DefaultPreconditioner.hpp"
52 #include "Thyra_MultiVectorStdOps.hpp"
53 #include "Thyra_VectorStdOps.hpp"
54 #include "Thyra_VectorBase.hpp"
74 template<
class Scalar>
86 template<
class Scalar>
106 template<
class Scalar>
107 void singleLinearSolve(
116 using Teuchos::rcpFromRef;
118 out <<
"\nPerforming a single linear solve ...\n";
121 Thyra::linearOpWithSolve(lowsFactory, rcpFromRef(A));
125 status = Thyra::solve<Scalar>(*invertibleA,
Thyra::NOTRANS, b, x);
126 out <<
"\nSolve status:\n" << status;
135 template<
class Scalar>
137 createScaledAdjointLinearOpWithSolve(
139 const Scalar &scalar,
145 out <<
"\nCreating a scaled adjoint LinearOpWithSolveBase object ...\n";
148 Thyra::linearOpWithSolve(lowsFactory,
scale(scalar,
adjoint(A)));
149 out <<
"\nCreated LOWSB object:\n" << describe(*invertibleAdjointA,
151 return invertibleAdjointA;
160 template<
class Scalar>
161 void solveNumericalChangeSolve(
172 using Teuchos::as;
using Teuchos::ptr;
using Teuchos::rcpFromPtr;
174 out <<
"\nPerforming a solve, changing the operator, then performing another"
182 Thyra::initializeOp<Scalar>(lowsFactory, rcpA, invertibleA.
ptr());
184 Thyra::assign(x1, as<Scalar>(0.0));
191 Thyra::uninitializeOp<Scalar>(lowsFactory, invertibleA.ptr());
194 Thyra::initializeOp<Scalar>(lowsFactory, rcpA, invertibleA.ptr());
198 Thyra::assign<Scalar>(x2, as<Scalar>(0.0));
209 template<
class Scalar>
210 void solveSmallNumericalChangeSolve(
221 using Teuchos::ptr;
using Teuchos::as;
using Teuchos::rcpFromPtr;
223 out <<
"\nPerforming a solve, changing the operator in a very small way,"
224 <<
" then performing another solve ...\n";
231 Thyra::initializeOp<Scalar>(lowsFactory, rcpA, invertibleA.
ptr());
233 Thyra::assign(x1, as<Scalar>(0.0));
240 Thyra::uninitializeOp<Scalar>(lowsFactory, invertibleA.ptr());
243 Thyra::initializeAndReuseOp<Scalar>(lowsFactory, rcpA, invertibleA.ptr());
246 Thyra::assign(x2, as<Scalar>(0.0));
257 template<
class Scalar>
258 void solveMajorChangeSolve(
271 out <<
"\nPerforming a solve, changing the operator in a major way, then performing"
272 <<
" another solve ...\n";
279 Thyra::initializeOp<Scalar>(lowsFactory, rcpA, invertibleA.
ptr());
281 Thyra::assign(x1, as<Scalar>(0.0));
288 Thyra::uninitializeOp<Scalar>(lowsFactory, invertibleA.ptr());
292 invertibleA = lowsFactory.createOp();
293 Thyra::initializeOp<Scalar>(lowsFactory, rcpA, invertibleA.ptr());
295 Thyra::assign(x2, as<Scalar>(0.0));
311 template<
class Scalar>
313 createGeneralPreconditionedLinearOpWithSolve(
321 out <<
"\nCreating an externally preconditioned LinearOpWithSolveBase object ...\n";
324 Thyra::initializePreconditionedOp<Scalar>(lowsFactory, A, P, invertibleA.
ptr());
336 template<
class Scalar>
338 createUnspecifiedPreconditionedLinearOpWithSolve(
346 out <<
"\nCreating an LinearOpWithSolveBase object given a preconditioner operator"
347 <<
" not targeted to the left or right ...\n";
350 Thyra::initializePreconditionedOp<Scalar>(lowsFactory, A,
351 Thyra::unspecifiedPrec<Scalar>(P_op), invertibleA.
ptr());
365 template<
class Scalar>
367 createLeftPreconditionedLinearOpWithSolve(
375 out <<
"\nCreating an LinearOpWithSolveBase object given a left preconditioner"
376 <<
" operator ...\n";
379 Thyra::initializePreconditionedOp<Scalar>(lowsFactory, A,
380 Thyra::leftPrec<Scalar>(P_op_left), invertibleA.
ptr());
392 template<
class Scalar>
394 createRightPreconditionedLinearOpWithSolve(
402 out <<
"\nCreating an LinearOpWithSolveBase object given a right"
403 <<
" preconditioner operator ...\n";
406 Thyra::initializePreconditionedOp<Scalar>(lowsFactory, A,
407 Thyra::rightPrec<Scalar>(P_op_right), invertibleA.
ptr());
419 template<
class Scalar>
421 createLeftRightPreconditionedLinearOpWithSolve(
430 out <<
"\nCreating an LinearOpWithSolveBase object given a left and"
431 <<
"right preconditioner operator ...\n";
434 Thyra::initializePreconditionedOp<Scalar>(lowsFactory, A,
435 Thyra::splitPrec<Scalar>(P_op_left, P_op_right), invertibleA.
ptr());
447 template<
class Scalar>
449 createMatrixPreconditionedLinearOpWithSolve(
457 out <<
"\nCreating a LinearOpWithSolveBase object given an approximate forward"
458 <<
" operator to define the preconditioner ...\n";
461 Thyra::initializeApproxPreconditionedOp<Scalar>(lowsFactory, A, A_approx,
472 template<
class Scalar>
473 void externalPreconditionerReuseWithSolves(
485 using Teuchos::tab;
using Teuchos::rcpFromPtr;
488 out <<
"\nShowing resuse of the preconditioner ...\n";
493 Thyra::initializePrec<Scalar>(precFactory, A, P.
ptr());
497 Thyra::initializePreconditionedOp<Scalar>(lowsFactory, A, P, invertibleA.
ptr());
502 out <<
"\nSolve status:\n" << status1;
515 Thyra::initializePreconditionedOp<Scalar>(lowsFactory, A, P, invertibleA.ptr());
520 out <<
"\nSolve status:\n" << status2;
534 template<
class Scalar>
535 void nonExternallyPreconditionedLinearSolveUseCases(
538 bool supportsAdjoints,
544 out <<
"\nRunning example use cases for a LinearOpWithSolveFactoryBase object ...\n";
550 b1 = Thyra::createMember(A.
range()),
551 b2 = Thyra::createMember(A.
range());
552 Thyra::randomize( as<Scalar>(-1.0), as<Scalar>(+1.0), b1.
ptr() );
553 Thyra::randomize( as<Scalar>(-1.0), as<Scalar>(+1.0), b2.ptr() );
556 x1 = Thyra::createMember(A.
domain()),
557 x2 = Thyra::createMember(A.
domain());
559 singleLinearSolve(A, lowsFactory, *b1, x1.
ptr(), out);
561 if(supportsAdjoints) {
563 invertibleAdjointA = createScaledAdjointLinearOpWithSolve(
564 Teuchos::rcp(&A,
false),as<Scalar>(2.0),lowsFactory,out);
567 solveNumericalChangeSolve<Scalar>(
570 lowsFactory, *b1, x1.
ptr(), *b2, x1.ptr(), out );
572 solveSmallNumericalChangeSolve<Scalar>(
575 lowsFactory, *b1, x1.
ptr(), *b2, x1.ptr(), out );
577 solveMajorChangeSolve<Scalar>(
580 lowsFactory, *b1, x1.
ptr(), *b2, x1.ptr(), out );
589 template<
class Scalar>
590 void externallyPreconditionedLinearSolveUseCases(
594 const bool supportsLeftPrec,
595 const bool supportsRightPrec,
601 out <<
"\nRunning example use cases with an externally defined"
602 <<
" preconditioner with a LinearOpWithSolveFactoryBase object ...\n";
608 b1 = Thyra::createMember(A.
range()),
609 b2 = Thyra::createMember(A.
range());
610 Thyra::randomize( as<Scalar>(-1.0), as<Scalar>(+1.0), b1.
ptr() );
611 Thyra::randomize( as<Scalar>(-1.0), as<Scalar>(+1.0), b2.ptr() );
614 x1 = Thyra::createMember(A.
domain()),
615 x2 = Thyra::createMember(A.
domain());
619 Thyra::initializePrec<Scalar>(precFactory, rcpFromRef(A), P.ptr());
628 invertibleA = createGeneralPreconditionedLinearOpWithSolve<Scalar>(
629 Teuchos::rcp(&A,
false), P.getConst(), lowsFactory, out);
635 if (
nonnull (P_op = P->getUnspecifiedPrecOp ()))
637 else if (
nonnull (P_op = P->getLeftPrecOp ()))
639 else if (
nonnull (P_op = P->getRightPrecOp ()))
642 invertibleA = createUnspecifiedPreconditionedLinearOpWithSolve(
643 rcpFromRef(A), P_op, lowsFactory, out);
645 if(supportsLeftPrec) {
646 invertibleA = createLeftPreconditionedLinearOpWithSolve(
647 rcpFromRef(A), P_op, lowsFactory,out);
650 if(supportsRightPrec) {
651 invertibleA = createRightPreconditionedLinearOpWithSolve(
652 rcpFromRef(A), P_op, lowsFactory, out);
656 if( supportsLeftPrec && supportsRightPrec ) {
657 invertibleA = createLeftRightPreconditionedLinearOpWithSolve(
658 rcpFromRef(A), P_op, P_op, lowsFactory, out);
662 invertibleA = createMatrixPreconditionedLinearOpWithSolve<Scalar>(
663 rcpFromRef(A), rcpFromRef(A), lowsFactory,out);
665 externalPreconditionerReuseWithSolves<Scalar>(
668 lowsFactory, precFactory,
669 *b1, x1.
ptr(), *b2, x2.ptr(), out );
673 #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->...
Simple interface class to access a precreated preconditioner as one or more linear operators objects ...
virtual ~LinearOpChanger()
virtual RCP< LinearOpWithSolveBase< Scalar > > createOp() const =0
Create an (uninitialized) LinearOpWithSolveBase object to be initialized later in this->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...
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