11 #ifndef BELOS_LINEAR_PROBLEM_HPP
12 #define BELOS_LINEAR_PROBLEM_HPP
49 template <
class ScalarType,
class MV,
class OP>
164 virtual void setLSIndex (
const std::vector<int>& index);
184 void setLabel (
const std::string& label);
225 bool updateLP =
false,
432 virtual void apply(
const MV& x, MV& y )
const;
441 virtual void applyOp(
const MV& x, MV& y )
const;
464 virtual void computeCurrResVec( MV* R ,
const MV* X = 0,
const MV* B = 0 )
const;
556 template <
class ScalarType,
class MV,
class OP>
564 solutionUpdated_(false),
569 template <
class ScalarType,
class MV,
class OP>
583 solutionUpdated_(false),
588 template <
class ScalarType,
class MV,
class OP>
592 curX_(Problem.curX_),
594 curB_(Problem.curB_),
597 R0_user_(Problem.R0_user_),
598 PR0_user_(Problem.PR0_user_),
601 timerOp_(Problem.timerOp_),
602 timerPrec_(Problem.timerPrec_),
603 blocksize_(Problem.blocksize_),
604 num2Solve_(Problem.num2Solve_),
605 rhsIndex_(Problem.rhsIndex_),
606 lsNum_(Problem.lsNum_),
607 isSet_(Problem.isSet_),
608 isHermitian_(Problem.isHermitian_),
609 solutionUpdated_(Problem.solutionUpdated_),
610 label_(Problem.label_)
614 template <
class ScalarType,
class MV,
class OP>
622 curB_ = Teuchos::null;
623 curX_ = Teuchos::null;
626 int validIdx = 0, ivalidIdx = 0;
627 blocksize_ = rhsIndex_.size();
628 std::vector<int> vldIndex( blocksize_ );
629 std::vector<int> newIndex( blocksize_ );
630 std::vector<int> iIndex( blocksize_ );
631 for (
int i=0; i<blocksize_; ++i) {
632 if (rhsIndex_[i] > -1) {
633 vldIndex[validIdx] = rhsIndex_[i];
634 newIndex[validIdx] = i;
638 iIndex[ivalidIdx] = i;
642 vldIndex.resize(validIdx);
643 newIndex.resize(validIdx);
644 iIndex.resize(ivalidIdx);
645 num2Solve_ = validIdx;
648 if (num2Solve_ != blocksize_) {
649 newIndex.resize(num2Solve_);
650 vldIndex.resize(num2Solve_);
654 curX_ = MVT::Clone( *X_, blocksize_ );
657 MVT::MvRandom(*tmpCurB);
661 MVT::SetBlock( *tptr, newIndex, *tmpCurB );
665 tptr = MVT::CloneView( *X_, vldIndex );
666 MVT::SetBlock( *tptr, newIndex, *curX_ );
668 solutionUpdated_ =
false;
671 curX_ = MVT::CloneViewNonConst( *X_, rhsIndex_ );
672 curB_ = MVT::CloneView( *B_, rhsIndex_ );
681 template <
class ScalarType,
class MV,
class OP>
688 if (num2Solve_ < blocksize_) {
693 std::vector<int> newIndex( num2Solve_ );
694 std::vector<int> vldIndex( num2Solve_ );
695 for (
int i=0; i<blocksize_; ++i) {
696 if ( rhsIndex_[i] > -1 ) {
697 vldIndex[validIdx] = rhsIndex_[i];
698 newIndex[validIdx] = i;
703 MVT::SetBlock( *tptr, vldIndex, *X_ );
709 curX_ = Teuchos::null;
710 curB_ = Teuchos::null;
715 template <
class ScalarType,
class MV,
class OP>
739 MVT::MvAddMv( 1.0, *curX_, scale, *update, *curX_ );
744 RCP<MV> rightPrecUpdate =
745 MVT::Clone (*update, MVT::GetNumberVecs (*update));
746 applyRightPrec( *update, *rightPrecUpdate );
748 MVT::MvAddMv( 1.0, *curX_, scale, *rightPrecUpdate, *curX_ );
750 solutionUpdated_ =
true;
757 newSoln = MVT::Clone (*update, MVT::GetNumberVecs (*update));
761 MVT::MvAddMv( 1.0, *curX_, scale, *update, *newSoln );
766 RCP<MV> rightPrecUpdate =
767 MVT::Clone (*update, MVT::GetNumberVecs (*update));
768 applyRightPrec( *update, *rightPrecUpdate );
770 MVT::MvAddMv( 1.0, *curX_, scale, *rightPrecUpdate, *newSoln );
777 template <
class ScalarType,
class MV,
class OP>
780 if (label != label_) {
783 if (timerOp_ != Teuchos::null) {
784 std::string opLabel = label_ +
": Operation Op*x";
785 #ifdef BELOS_TEUCHOS_TIME_MONITOR
789 if (timerPrec_ != Teuchos::null) {
790 std::string precLabel = label_ +
": Operation Prec*x";
791 #ifdef BELOS_TEUCHOS_TIME_MONITOR
798 template <
class ScalarType,
class MV,
class OP>
805 if (timerOp_ == Teuchos::null) {
806 std::string opLabel = label_ +
": Operation Op*x";
807 #ifdef BELOS_TEUCHOS_TIME_MONITOR
811 if (timerPrec_ == Teuchos::null) {
812 std::string precLabel = label_ +
": Operation Prec*x";
813 #ifdef BELOS_TEUCHOS_TIME_MONITOR
818 Y_temp_ = Teuchos::null;
821 if (newX != Teuchos::null)
823 if (newB != Teuchos::null)
828 curX_ = Teuchos::null;
829 curB_ = Teuchos::null;
833 if (A_ == Teuchos::null || X_ == Teuchos::null || B_ == Teuchos::null) {
841 solutionUpdated_ =
false;
845 if (R0_==Teuchos::null || MVT::GetNumberVecs( *R0_ )!=MVT::GetNumberVecs( *B_ )) {
846 R0_ = MVT::Clone( *B_, MVT::GetNumberVecs( *B_ ) );
848 computeCurrResVec( &*R0_, &*X_, &*B_ );
850 if (LP_!=Teuchos::null) {
851 if (PR0_==Teuchos::null || (PR0_==R0_) || (MVT::GetNumberVecs(*PR0_)!=MVT::GetNumberVecs(*B_))) {
852 PR0_ = MVT::Clone( *B_, MVT::GetNumberVecs( *B_ ) );
854 applyLeftPrec( *R0_, *PR0_ );
862 if (MVT::GetNumberVecs( *R0_user_ )!=MVT::GetNumberVecs( *B_ )) {
864 computeCurrResVec( &*helper, &*X_, &*B_ );
865 R0_user_ = Teuchos::null;
869 if (LP_!=Teuchos::null) {
872 if (PR0_user_==Teuchos::null || (PR0_user_==R0_) || (PR0_user_==R0_user_)
873 || (MVT::GetNumberVecs(*PR0_user_)!=MVT::GetNumberVecs(*B_))) {
877 applyLeftPrec( *getInitResVec(), *helper );
878 PR0_user_ = Teuchos::null;
885 if (R0_user_!=Teuchos::null)
887 PR0_user_ = R0_user_;
891 PR0_user_ = Teuchos::null;
904 template <
class ScalarType,
class MV,
class OP>
913 template <
class ScalarType,
class MV,
class OP>
922 template <
class ScalarType,
class MV,
class OP>
929 return Teuchos::null;
933 template <
class ScalarType,
class MV,
class OP>
940 return Teuchos::null;
944 template <
class ScalarType,
class MV,
class OP>
950 const bool leftPrec = LP_ != null;
951 const bool rightPrec = RP_ != null;
953 if(leftPrec || rightPrec) {
954 const auto num_vecs_y = MVT::GetNumberVecs(y);
955 if(!Y_temp_ || MVT::GetNumberVecs(*Y_temp_) != num_vecs_y) {
956 Y_temp_ = MVT::Clone (y, num_vecs_y);
963 if (!leftPrec && !rightPrec) {
969 else if( leftPrec && rightPrec )
971 applyRightPrec( x, y );
972 applyOp( y, *Y_temp_ );
973 applyLeftPrec( *Y_temp_, y );
980 applyOp( x, *Y_temp_ );
981 applyLeftPrec( *Y_temp_, y );
988 applyRightPrec( x, *Y_temp_ );
989 applyOp( *Y_temp_, y );
993 template <
class ScalarType,
class MV,
class OP>
996 #ifdef BELOS_TEUCHOS_TIME_MONITOR
999 OPT::Apply( *A_,x, y);
1007 template <
class ScalarType,
class MV,
class OP>
1009 if (LP_!=Teuchos::null) {
1010 #ifdef BELOS_TEUCHOS_TIME_MONITOR
1013 OPT::Apply( *LP_,x, y);
1021 template <
class ScalarType,
class MV,
class OP>
1023 if (RP_!=Teuchos::null) {
1024 #ifdef BELOS_TEUCHOS_TIME_MONITOR
1027 OPT::Apply( *RP_,x, y);
1035 template <
class ScalarType,
class MV,
class OP>
1041 if (LP_!=Teuchos::null)
1044 applyOp( *X, *R_temp );
1045 MVT::MvAddMv( -1.0, *R_temp, 1.0, *B, *R_temp );
1046 applyLeftPrec( *R_temp, *R );
1051 MVT::MvAddMv( -1.0, *R, 1.0, *B, *R );
1067 if (LP_!=Teuchos::null)
1069 Teuchos::RCP<MV> R_temp = MVT::Clone( *localB, MVT::GetNumberVecs( *localB ) );
1070 applyOp( *localX, *R_temp );
1071 MVT::MvAddMv( -1.0, *R_temp, 1.0, *localB, *R_temp );
1072 applyLeftPrec( *R_temp, *R );
1076 applyOp( *localX, *R );
1077 MVT::MvAddMv( -1.0, *R, 1.0, *localB, *R );
1084 template <
class ScalarType,
class MV,
class OP>
1091 MVT::MvAddMv( -1.0, *R, 1.0, *B, *R );
1106 applyOp( *localX, *R );
1107 MVT::MvAddMv( -1.0, *R, 1.0, *localB, *R );
bool isHermitian_
Whether the operator A is symmetric (in real arithmetic, or Hermitian in complex arithmetic).
bool isSet_
Has the linear problem to solve been set?
Teuchos::RCP< MV > getLHS() const
A pointer to the left-hand side X.
Exception thrown to signal error with the Belos::LinearProblem object.
virtual void apply(const MV &x, MV &y) const
Apply the composite operator of this linear problem to x, returning y.
void setHermitian(bool isSym=true)
Tell the linear problem that the (preconditioned) operator is Hermitian.
virtual Teuchos::RCP< MV > updateSolution(const Teuchos::RCP< MV > &update=Teuchos::null, ScalarType scale=Teuchos::ScalarTraits< ScalarType >::one()) const
Compute the new solution to the linear system using the given update vector.
Teuchos::RCP< const MV > B_
Right-hand side of linear system.
bool isProblemSet() const
Whether the problem has been set.
Teuchos::RCP< const MV > getCurrRHSVec()
Get a pointer to the current right-hand side of the linear system.
Teuchos::RCP< MV > getCurrLHSVec()
Get a pointer to the current left-hand side (solution) of the linear system.
bool nonnull(const std::shared_ptr< T > &p)
virtual Teuchos::RCP< MV > updateSolution(const Teuchos::RCP< MV > &update=Teuchos::null, bool updateLP=false, ScalarType scale=Teuchos::ScalarTraits< ScalarType >::one())
Compute the new solution to the linear system using the given update vector.
bool is_null(const std::shared_ptr< T > &p)
Teuchos::RCP< const MV > R0_user_
User-defined initial residual of the linear system.
Declaration of basic traits for the multivector type.
virtual ~LinearProblem(void)
Destructor (declared virtual for memory safety of derived classes).
virtual bool setProblem(const Teuchos::RCP< MV > &newX=Teuchos::null, const Teuchos::RCP< const MV > &newB=Teuchos::null)
Set up the linear problem manager.
Teuchos::RCP< const MV > getInitPrecResVec() const
A pointer to the preconditioned initial residual vector.
Teuchos::RCP< MV > curX_
Current solution vector of the linear system.
Teuchos::RCP< const OP > LP_
Left preconditioning operator of linear system.
LinearProblem(void)
Default constructor.
void setOperator(const Teuchos::RCP< const OP > &A)
Set the operator A of the linear problem .
Teuchos::RCP< const MV > getRHS() const
A pointer to the right-hand side B.
Class which defines basic traits for the operator type.
virtual void setLSIndex(const std::vector< int > &index)
Tell the linear problem which linear system(s) need to be solved next.
virtual void computeCurrPrecResVec(MV *R, const MV *X=0, const MV *B=0) const
Compute a residual R for this operator given a solution X, and right-hand side B. ...
void setRHS(const Teuchos::RCP< const MV > &B)
Set right-hand-side B of linear problem .
bool isRightPrec() const
Whether the linear system is being preconditioned on the right.
Traits class which defines basic operations on multivectors.
virtual void applyOp(const MV &x, MV &y) const
Apply ONLY the operator to x, returning y.
Teuchos::RCP< const OP > getOperator() const
A pointer to the (unpreconditioned) operator A.
int blocksize_
Current block size of linear system.
const std::vector< int > & getLSIndex() const
(Zero-based) indices of the linear system(s) currently being solved.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
bool isSolutionUpdated() const
Has the current approximate solution been updated?
void setLeftPrec(const Teuchos::RCP< const OP > &LP)
Set left preconditioner (LP) of linear problem .
Teuchos::RCP< MV > Y_temp_
Scratch vector for use in apply()
A linear system to solve, and its associated information.
int getLSNumber() const
The number of linear systems that have been set.
Teuchos::Array< Teuchos::RCP< Teuchos::Time > > getTimers() const
The timers for this object.
bool isLeftPrec() const
Whether the linear system is being preconditioned on the left.
std::string label_
Linear problem label that prefixes the timer labels.
Teuchos::RCP< const MV > getInitResVec() const
A pointer to the initial unpreconditioned residual vector.
virtual void applyRightPrec(const MV &x, MV &y) const
Apply ONLY the right preconditioner to x, returning y.
int lsNum_
Number of linear systems that have been loaded in this linear problem object.
void setLabel(const std::string &label)
Set the label prefix used by the timers in this object.
Teuchos::RCP< const MV > PR0_user_
User-defined preconditioned initial residual of the linear system.
Teuchos::RCP< MV > R0_
Initial residual of the linear system.
Teuchos::RCP< const OP > A_
Operator of linear system.
virtual void applyLeftPrec(const MV &x, MV &y) const
Apply ONLY the left preconditioner to x, returning y.
Teuchos::RCP< MV > X_
Solution vector of linear system.
Teuchos::RCP< const OP > getLeftPrec() const
Get a pointer to the left preconditioner.
virtual void computeCurrResVec(MV *R, const MV *X=0, const MV *B=0) const
Compute a residual R for this operator given a solution X, and right-hand side B. ...
LinearProblemError(const std::string &what_arg)
bool solutionUpdated_
Has the current approximate solution been updated?
Teuchos::RCP< const OP > getRightPrec() const
Get a pointer to the right preconditioner.
virtual void setCurrLS()
Tell the linear problem that the solver is finished with the current linear system.
Teuchos::RCP< MV > PR0_
Preconditioned initial residual of the linear system.
Class which defines basic traits for the operator type.
bool isHermitian() const
Whether the (preconditioned) operator is Hermitian.
Parent class to all Belos exceptions.
void setRightPrec(const Teuchos::RCP< const OP > &RP)
Set right preconditioner (RP) of linear problem .
void setInitResVec(const Teuchos::RCP< const MV > &R0)
Set the user-defined residual of linear problem .
void setLHS(const Teuchos::RCP< MV > &X)
Set left-hand-side X of linear problem .
Teuchos::RCP< Teuchos::Time > timerOp_
Timers.
Teuchos::RCP< const OP > RP_
Right preconditioning operator of linear system.
std::vector< int > rhsIndex_
Indices of current linear systems being solver for.
Teuchos::RCP< const MV > curB_
Current right-hand side of the linear system.
int num2Solve_
Number of linear systems that are currently being solver for ( <= blocksize_ )
void setInitPrecResVec(const Teuchos::RCP< const MV > &PR0)
Set the user-defined preconditioned residual of linear problem .
Teuchos::RCP< Teuchos::Time > timerPrec_