00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef THYRA_LINEAR_OP_WITH_SOLVE_BASE_DECL_HPP
00030 #define THYRA_LINEAR_OP_WITH_SOLVE_BASE_DECL_HPP
00031
00032 #include "Thyra_LinearOpBaseDecl.hpp"
00033 #include "Thyra_SolveSupportTypes.hpp"
00034 #include "Teuchos_VerboseObject.hpp"
00035 #include "Teuchos_PromotionTraits.hpp"
00036
00037 namespace Thyra {
00038
00338 template <class RangeScalar, class DomainScalar = RangeScalar>
00339 class LinearOpWithSolveBase
00340 : virtual public LinearOpBase<RangeScalar,DomainScalar>
00341 , virtual public Teuchos::VerboseObject<LinearOpWithSolveBase<RangeScalar,DomainScalar> >
00342 {
00343 public:
00344
00346 typedef typename Teuchos::PromotionTraits<RangeScalar,DomainScalar>::promote PromotedScalar;
00347
00350
00406 virtual void solve(
00407 const EConj conj
00408 ,const MultiVectorBase<RangeScalar> &B
00409 ,MultiVectorBase<DomainScalar> *X
00410 ,const int numBlocks = 0
00411 ,const BlockSolveCriteria<PromotedScalar> blockSolveCriteria[] = NULL
00412 ,SolveStatus<PromotedScalar> blockSolveStatus[] = NULL
00413 ) const = 0;
00414
00416
00419
00425 virtual bool solveSupportsConj(EConj conj) const;
00426
00431 virtual bool solveTransposeSupportsConj(EConj conj) const;
00432
00439 virtual bool solveSupportsSolveMeasureType(EConj conj, const SolveMeasureType& solveMeasureType) const;
00440
00447 virtual bool solveTransposeSupportsSolveMeasureType(EConj conj, const SolveMeasureType& solveMeasureType) const;
00448
00505 virtual void solveTranspose(
00506 const EConj conj
00507 ,const MultiVectorBase<DomainScalar> &B
00508 ,MultiVectorBase<RangeScalar> *X
00509 ,const int numBlocks = 0
00510 ,const BlockSolveCriteria<PromotedScalar> blockSolveCriteria[] = NULL
00511 ,SolveStatus<PromotedScalar> blockSolveStatus[] = NULL
00512 ) const;
00513
00515
00516 };
00517
00518
00524 template<class Scalar>
00525 bool solveSupports(
00526 const LinearOpWithSolveBase<Scalar> &A
00527 ,const EOpTransp A_trans
00528 )
00529 {
00530 if( real_trans(A_trans) == NOTRANS ) {
00531 return A.solveSupportsConj(
00532 A_trans == NOTRANS ? NONCONJ_ELE : CONJ_ELE
00533 );
00534 }
00535 return A.solveTransposeSupportsConj(
00536 A_trans == TRANS ? NONCONJ_ELE : CONJ_ELE
00537 );
00538 }
00539
00540
00546 template<class Scalar>
00547 bool solveSupportsSolveMeasureType(
00548 const LinearOpWithSolveBase<Scalar> &A,
00549 const EOpTransp A_trans,
00550 const SolveMeasureType &solveMeasureType
00551 )
00552 {
00553 if( real_trans(A_trans) == NOTRANS ) {
00554 return A.solveSupportsSolveMeasureType(
00555 A_trans == NOTRANS ? NONCONJ_ELE : CONJ_ELE,
00556 solveMeasureType
00557 );
00558 }
00559 return A.solveTransposeSupportsSolveMeasureType(
00560 A_trans == TRANS ? NONCONJ_ELE : CONJ_ELE,
00561 solveMeasureType
00562 );
00563 }
00564
00565
00571 template<class Scalar>
00572 void solve(
00573 const LinearOpWithSolveBase<Scalar> &M,
00574 const EOpTransp M_trans,
00575 const MultiVectorBase<Scalar> &B,
00576 MultiVectorBase<Scalar> *X,
00577 const int numBlocks,
00578 const BlockSolveCriteria<Scalar> blockSolveCriteria[],
00579 SolveStatus<Scalar> blockSolveStatus[]
00580 )
00581 {
00582 if (real_trans(M_trans) == NOTRANS)
00583 M.solve(
00584 transToConj(M_trans),B,X,numBlocks,blockSolveCriteria,blockSolveStatus);
00585 else
00586 M.solveTranspose(
00587 transToConj(M_trans),B,X,numBlocks,blockSolveCriteria,blockSolveStatus);
00588 }
00589
00590
00603 template<class Scalar>
00604 SolveStatus<Scalar>
00605 solve(
00606 const LinearOpWithSolveBase<Scalar> &A
00607 ,const EOpTransp A_trans
00608 ,const MultiVectorBase<Scalar> &B
00609 ,MultiVectorBase<Scalar> *X
00610 ,const SolveCriteria<Scalar> *solveCriteria = NULL
00611 )
00612 {
00613 if(real_trans(A_trans)==NOTRANS)
00614 return solve(A,transToConj(A_trans),B,X,solveCriteria);
00615 return solveTranspose(A,transToConj(A_trans),B,X,solveCriteria);
00616 }
00617
00625 template<class RangeScalar, class DomainScalar>
00626 SolveStatus<typename LinearOpWithSolveBase<RangeScalar,DomainScalar>::PromotedScalar>
00627 solve(
00628 const LinearOpWithSolveBase<RangeScalar,DomainScalar> &A
00629 ,const EConj conj
00630 ,const MultiVectorBase<RangeScalar> &B
00631 ,MultiVectorBase<DomainScalar> *X
00632 ,const SolveCriteria<typename LinearOpWithSolveBase<RangeScalar,DomainScalar>::PromotedScalar>
00633 *solveCriteria = NULL
00634 )
00635 {
00636 typedef SolveCriteria<typename LinearOpWithSolveBase<RangeScalar,DomainScalar>::PromotedScalar> SC;
00637 typedef BlockSolveCriteria<typename LinearOpWithSolveBase<RangeScalar,DomainScalar>::PromotedScalar> BSC;
00638 typedef SolveStatus<typename LinearOpWithSolveBase<RangeScalar,DomainScalar>::PromotedScalar> BSS;
00639 SC defaultSolveCriteria;
00640 BSC blockSolveCriteria[1];
00641 BSS blockSolveStatus[1];
00642 blockSolveCriteria[0] = BSC(solveCriteria?*solveCriteria:defaultSolveCriteria,B.domain()->dim());
00643 A.solve(
00644 conj,B,X,1
00645 ,blockSolveCriteria
00646 ,blockSolveStatus
00647 );
00648 return blockSolveStatus[0];
00649 }
00650
00651
00659 template <class RangeScalar, class DomainScalar>
00660 SolveStatus<typename LinearOpWithSolveBase<RangeScalar,DomainScalar>::PromotedScalar>
00661 solveTranspose(
00662 const LinearOpWithSolveBase<RangeScalar,DomainScalar> &A
00663 ,const EConj conj
00664 ,const MultiVectorBase<DomainScalar> &B
00665 ,MultiVectorBase<RangeScalar> *X
00666 ,const SolveCriteria<typename LinearOpWithSolveBase<RangeScalar,DomainScalar>::PromotedScalar>
00667 *solveCriteria = NULL
00668 )
00669 {
00670 typedef SolveCriteria<typename LinearOpWithSolveBase<RangeScalar,DomainScalar>::PromotedScalar> SC;
00671 typedef BlockSolveCriteria<typename LinearOpWithSolveBase<RangeScalar,DomainScalar>::PromotedScalar> BSC;
00672 typedef SolveStatus<typename LinearOpWithSolveBase<RangeScalar,DomainScalar>::PromotedScalar> BSS;
00673 SC defaultSolveCriteria;
00674 BSC blockSolveCriteria[1];
00675 BSS blockSolveStatus[1];
00676 blockSolveCriteria[0] = BSC(solveCriteria?*solveCriteria:defaultSolveCriteria,B.domain()->dim());
00677 A.solveTranspose(
00678 conj,B,X,1
00679 ,blockSolveCriteria
00680 ,blockSolveStatus
00681 );
00682 return blockSolveStatus[0];
00683 }
00684
00685
00693 template<class RangeScalar, class DomainScalar>
00694 void solve(
00695 const LinearOpWithSolveBase<RangeScalar,DomainScalar> &A
00696 ,const EConj conj
00697 ,const MultiVectorBase<RangeScalar> &B
00698 ,MultiVectorBase<DomainScalar> *X
00699 ,const int numBlocks
00700 ,const BlockSolveCriteria<typename LinearOpWithSolveBase<RangeScalar,DomainScalar>::PromotedScalar>
00701 blockSolveCriteria[] = NULL
00702 ,SolveStatus<typename LinearOpWithSolveBase<RangeScalar,DomainScalar>::PromotedScalar>
00703 blockSolveStatus[] = NULL
00704 )
00705 {
00706 A.solve(conj,B,X,numBlocks,blockSolveCriteria,blockSolveStatus);
00707 }
00708
00709
00717 template <class RangeScalar, class DomainScalar>
00718 void solveTranspose(
00719 const LinearOpWithSolveBase<RangeScalar,DomainScalar> &A
00720 ,const EConj conj
00721 ,const MultiVectorBase<DomainScalar> &B
00722 ,MultiVectorBase<RangeScalar> *X
00723 ,const int numBlocks
00724 ,const BlockSolveCriteria<typename LinearOpWithSolveBase<RangeScalar,DomainScalar>::PromotedScalar>
00725 blockSolveCriteria[] = NULL
00726 ,SolveStatus<typename LinearOpWithSolveBase<RangeScalar,DomainScalar>::PromotedScalar>
00727 blockSolveStatus[] = NULL
00728 )
00729 {
00730 A.solveTranspose(conj,B,X,numBlocks,blockSolveCriteria,blockSolveStatus);
00731 }
00732
00734
00735 }
00736
00737 #endif // THYRA_LINEAR_OP_WITH_SOLVE_BASE_DECL_HPP
00738
00739
00740
00741
00742