Belos Package Browser (Single Doxygen Collection)  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BelosLinearProblem.hpp
Go to the documentation of this file.
1 
2 // @HEADER
3 // *****************************************************************************
4 // Belos: Block Linear Solvers Package
5 //
6 // Copyright 2004-2016 NTESS and the Belos contributors.
7 // SPDX-License-Identifier: BSD-3-Clause
8 // *****************************************************************************
9 // @HEADER
10 
11 #ifndef BELOS_LINEAR_PROBLEM_HPP
12 #define BELOS_LINEAR_PROBLEM_HPP
13 
17 #include "BelosMultiVecTraits.hpp"
18 #include "BelosOperatorTraits.hpp"
20 #include "Teuchos_TimeMonitor.hpp"
21 
22 namespace Belos {
23 
25 
26 
29  class LinearProblemError : public BelosError {
30  public:
31  LinearProblemError (const std::string& what_arg) :
32  BelosError(what_arg) {}
33  };
34 
36 
49  template <class ScalarType, class MV, class OP>
50  class LinearProblem {
51  public:
52 
54 
55 
62  LinearProblem (void);
63 
71  const Teuchos::RCP<MV> &X,
72  const Teuchos::RCP<const MV> &B);
73 
77  LinearProblem (const LinearProblem<ScalarType,MV,OP>& Problem);
78 
80  virtual ~LinearProblem (void) {}
81 
83 
85 
86 
91  A_ = A;
92  isSet_=false;
93  }
94 
101  void setLHS (const Teuchos::RCP<MV> &X) {
102  X_ = X;
103  isSet_=false;
104  }
105 
110  void setRHS (const Teuchos::RCP<const MV> &B) {
111  B_ = B;
112  isSet_=false;
113  }
114 
121  R0_user_ = R0;
122  isSet_=false;
123  }
124 
131  PR0_user_ = PR0;
132  isSet_=false;
133  }
134 
138  void setLeftPrec(const Teuchos::RCP<const OP> &LP) { LP_ = LP; }
139 
143  void setRightPrec(const Teuchos::RCP<const OP> &RP) { RP_ = RP; }
144 
153  virtual void setCurrLS ();
154 
164  virtual void setLSIndex (const std::vector<int>& index);
165 
176  void setHermitian( bool isSym = true ) { isHermitian_ = isSym; }
177 
184  void setLabel (const std::string& label);
185 
222  virtual
225  bool updateLP = false,
226  ScalarType scale = Teuchos::ScalarTraits<ScalarType>::one());
227 
245  virtual
248  ScalarType scale = Teuchos::ScalarTraits<ScalarType>::one() ) const
249  { return const_cast<LinearProblem<ScalarType,MV,OP> *>(this)->updateSolution( update, false, scale ); }
250 
252 
254 
255 
281  virtual
282  bool
283  setProblem (const Teuchos::RCP<MV> &newX = Teuchos::null,
284  const Teuchos::RCP<const MV> &newB = Teuchos::null);
285 
287 
289 
290 
292  Teuchos::RCP<const OP> getOperator() const { return(A_); }
293 
295  Teuchos::RCP<MV> getLHS() const { return(X_); }
296 
298  Teuchos::RCP<const MV> getRHS() const { return(B_); }
299 
302 
308 
324 
340 
342  Teuchos::RCP<const OP> getLeftPrec() const { return(LP_); };
343 
346 
368  const std::vector<int>& getLSIndex() const { return(rhsIndex_); }
369 
376  int getLSNumber() const { return(lsNum_); }
377 
385  return Teuchos::tuple(timerOp_,timerPrec_);
386  }
387 
388 
390 
392 
393 
401  bool isSolutionUpdated() const { return(solutionUpdated_); }
402 
404  bool isProblemSet() const { return(isSet_); }
405 
411  bool isHermitian() const { return(isHermitian_); }
412 
414  bool isLeftPrec() const { return(LP_!=Teuchos::null); }
415 
417  bool isRightPrec() const { return(RP_!=Teuchos::null); }
418 
420 
422 
423 
425 
432  virtual void apply( const MV& x, MV& y ) const;
433 
441  virtual void applyOp( const MV& x, MV& y ) const;
442 
449  virtual void applyLeftPrec( const MV& x, MV& y ) const;
450 
457  virtual void applyRightPrec( const MV& x, MV& y ) const;
458 
460 
464  virtual void computeCurrResVec( MV* R , const MV* X = 0, const MV* B = 0 ) const;
465 
467 
471  virtual void computeCurrPrecResVec( MV* R, const MV* X = 0, const MV* B = 0 ) const;
472 
474 
475  protected:
476 
479 
482 
485 
488 
491 
494 
497 
500 
503 
506 
509 
512 
515 
518 
521 
523  std::vector<int> rhsIndex_;
524 
526  int lsNum_;
527 
529 
530 
532  bool isSet_;
533 
537 
540 
542 
544  std::string label_;
545 
546  private:
547 
550  };
551 
552  //--------------------------------------------
553  // Constructor Implementations
554  //--------------------------------------------
555 
556  template <class ScalarType, class MV, class OP>
558  blocksize_(0),
559  num2Solve_(0),
560  rhsIndex_(0),
561  lsNum_(0),
562  isSet_(false),
563  isHermitian_(false),
564  solutionUpdated_(false),
565  label_("Belos")
566  {
567  }
568 
569  template <class ScalarType, class MV, class OP>
571  const Teuchos::RCP<MV> &X,
573  ) :
574  A_(A),
575  X_(X),
576  B_(B),
577  blocksize_(0),
578  num2Solve_(0),
579  rhsIndex_(0),
580  lsNum_(0),
581  isSet_(false),
582  isHermitian_(false),
583  solutionUpdated_(false),
584  label_("Belos")
585  {
586  }
587 
588  template <class ScalarType, class MV, class OP>
590  A_(Problem.A_),
591  X_(Problem.X_),
592  curX_(Problem.curX_),
593  B_(Problem.B_),
594  curB_(Problem.curB_),
595  R0_(Problem.R0_),
596  PR0_(Problem.PR0_),
597  R0_user_(Problem.R0_user_),
598  PR0_user_(Problem.PR0_user_),
599  LP_(Problem.LP_),
600  RP_(Problem.RP_),
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_)
611  {
612  }
613 
614  template <class ScalarType, class MV, class OP>
615  void LinearProblem<ScalarType,MV,OP>::setLSIndex(const std::vector<int>& index)
616  {
617  // Set new linear systems using the indices in index.
618  rhsIndex_ = index;
619 
620  // Compute the new block linear system.
621  // ( first clean up old linear system )
622  curB_ = Teuchos::null;
623  curX_ = Teuchos::null;
624 
625  // Create indices for the new linear system.
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;
635  validIdx++;
636  }
637  else {
638  iIndex[ivalidIdx] = i;
639  ivalidIdx++;
640  }
641  }
642  vldIndex.resize(validIdx);
643  newIndex.resize(validIdx);
644  iIndex.resize(ivalidIdx);
645  num2Solve_ = validIdx;
646 
647  // Create the new linear system using index
648  if (num2Solve_ != blocksize_) {
649  newIndex.resize(num2Solve_);
650  vldIndex.resize(num2Solve_);
651  //
652  // First create multivectors of blocksize.
653  // Fill the RHS with random vectors LHS with zero vectors.
654  curX_ = MVT::Clone( *X_, blocksize_ );
655  MVT::MvInit(*curX_);
656  Teuchos::RCP<MV> tmpCurB = MVT::Clone( *B_, blocksize_ );
657  MVT::MvRandom(*tmpCurB);
658  //
659  // Now put in the part of B into curB
660  Teuchos::RCP<const MV> tptr = MVT::CloneView( *B_, vldIndex );
661  MVT::SetBlock( *tptr, newIndex, *tmpCurB );
662  curB_ = tmpCurB;
663  //
664  // Now put in the part of X into curX
665  tptr = MVT::CloneView( *X_, vldIndex );
666  MVT::SetBlock( *tptr, newIndex, *curX_ );
667  //
668  solutionUpdated_ = false;
669  }
670  else {
671  curX_ = MVT::CloneViewNonConst( *X_, rhsIndex_ );
672  curB_ = MVT::CloneView( *B_, rhsIndex_ );
673  }
674  //
675  // Increment the number of linear systems that have been loaded into this object.
676  //
677  lsNum_++;
678  }
679 
680 
681  template <class ScalarType, class MV, class OP>
683  {
684  //
685  // We only need to copy the solutions back if the linear systems of
686  // interest are less than the block size.
687  //
688  if (num2Solve_ < blocksize_) {
689  //
690  // Get a view of the current solutions and correction std::vector.
691  //
692  int validIdx = 0;
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;
699  validIdx++;
700  }
701  }
702  Teuchos::RCP<MV> tptr = MVT::CloneViewNonConst( *curX_, newIndex );
703  MVT::SetBlock( *tptr, vldIndex, *X_ );
704  }
705  //
706  // Clear the current vectors of this linear system so that any future calls
707  // to get the vectors for this system return null pointers.
708  //
709  curX_ = Teuchos::null;
710  curB_ = Teuchos::null;
711  rhsIndex_.resize(0);
712  }
713 
714 
715  template <class ScalarType, class MV, class OP>
719  bool updateLP,
720  ScalarType scale)
721  {
722  using Teuchos::RCP;
723  using Teuchos::null;
724 
725  RCP<MV> newSoln;
726  if (update.is_null())
727  { // The caller didn't supply an update vector, so we assume
728  // that the current solution curX_ is unchanged, and return a
729  // pointer to it.
730  newSoln = curX_;
731  }
732  else // the update vector is NOT null.
733  {
734  if (updateLP) // The caller wants us to update the linear problem.
735  {
736  if (RP_.is_null())
737  { // There is no right preconditioner.
738  // curX_ := curX_ + scale * update.
739  MVT::MvAddMv( 1.0, *curX_, scale, *update, *curX_ );
740  }
741  else
742  { // There is indeed a right preconditioner, so apply it
743  // before computing the new solution.
744  RCP<MV> rightPrecUpdate =
745  MVT::Clone (*update, MVT::GetNumberVecs (*update));
746  applyRightPrec( *update, *rightPrecUpdate );
747  // curX_ := curX_ + scale * rightPrecUpdate.
748  MVT::MvAddMv( 1.0, *curX_, scale, *rightPrecUpdate, *curX_ );
749  }
750  solutionUpdated_ = true;
751  newSoln = curX_;
752  }
753  else
754  { // Rather than updating our stored current solution curX_,
755  // we make a copy and compute the new solution in the
756  // copy, without modifying curX_.
757  newSoln = MVT::Clone (*update, MVT::GetNumberVecs (*update));
758  if (RP_.is_null())
759  { // There is no right preconditioner.
760  // newSoln := curX_ + scale * update.
761  MVT::MvAddMv( 1.0, *curX_, scale, *update, *newSoln );
762  }
763  else
764  { // There is indeed a right preconditioner, so apply it
765  // before computing the new solution.
766  RCP<MV> rightPrecUpdate =
767  MVT::Clone (*update, MVT::GetNumberVecs (*update));
768  applyRightPrec( *update, *rightPrecUpdate );
769  // newSoln := curX_ + scale * rightPrecUpdate.
770  MVT::MvAddMv( 1.0, *curX_, scale, *rightPrecUpdate, *newSoln );
771  }
772  }
773  }
774  return newSoln;
775  }
776 
777  template <class ScalarType, class MV, class OP>
778  void LinearProblem<ScalarType,MV,OP>::setLabel(const std::string& label)
779  {
780  if (label != label_) {
781  label_ = label;
782  // Create new timers if they have already been created.
783  if (timerOp_ != Teuchos::null) {
784  std::string opLabel = label_ + ": Operation Op*x";
785 #ifdef BELOS_TEUCHOS_TIME_MONITOR
786  timerOp_ = Teuchos::TimeMonitor::getNewCounter( opLabel );
787 #endif
788  }
789  if (timerPrec_ != Teuchos::null) {
790  std::string precLabel = label_ + ": Operation Prec*x";
791 #ifdef BELOS_TEUCHOS_TIME_MONITOR
792  timerPrec_ = Teuchos::TimeMonitor::getNewCounter( precLabel );
793 #endif
794  }
795  }
796  }
797 
798  template <class ScalarType, class MV, class OP>
799  bool
802  const Teuchos::RCP<const MV> &newB)
803  {
804  // Create timers if the haven't been created yet.
805  if (timerOp_ == Teuchos::null) {
806  std::string opLabel = label_ + ": Operation Op*x";
807 #ifdef BELOS_TEUCHOS_TIME_MONITOR
808  timerOp_ = Teuchos::TimeMonitor::getNewCounter( opLabel );
809 #endif
810  }
811  if (timerPrec_ == Teuchos::null) {
812  std::string precLabel = label_ + ": Operation Prec*x";
813 #ifdef BELOS_TEUCHOS_TIME_MONITOR
814  timerPrec_ = Teuchos::TimeMonitor::getNewCounter( precLabel );
815 #endif
816  }
817 
818  Y_temp_ = Teuchos::null;
819 
820  // Set the linear system using the arguments newX and newB
821  if (newX != Teuchos::null)
822  X_ = newX;
823  if (newB != Teuchos::null)
824  B_ = newB;
825 
826  // Invalidate the current linear system indices and multivectors.
827  rhsIndex_.resize(0);
828  curX_ = Teuchos::null;
829  curB_ = Teuchos::null;
830 
831  // If we didn't set a matrix A, a left-hand side X, or a
832  // right-hand side B, then we didn't set the problem.
833  if (A_ == Teuchos::null || X_ == Teuchos::null || B_ == Teuchos::null) {
834  isSet_ = false;
835  return isSet_;
836  }
837 
838  // Reset whether the solution has been updated. (We're just
839  // setting the problem now, so of course we haven't updated the
840  // solution yet.)
841  solutionUpdated_ = false;
842 
843  // Compute the initial residuals.
844  if(Teuchos::is_null(R0_user_)) {
845  if (R0_==Teuchos::null || MVT::GetNumberVecs( *R0_ )!=MVT::GetNumberVecs( *B_ )) {
846  R0_ = MVT::Clone( *B_, MVT::GetNumberVecs( *B_ ) );
847  }
848  computeCurrResVec( &*R0_, &*X_, &*B_ );
849 
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_ ) );
853  }
854  applyLeftPrec( *R0_, *PR0_ );
855  }
856  else {
857  PR0_ = R0_;
858  }
859  }
860  else { // User specified the residuals
861  // If the user did not specify the right sized residual, create one and set R0_user_ to null.
862  if (MVT::GetNumberVecs( *R0_user_ )!=MVT::GetNumberVecs( *B_ )) {
863  Teuchos::RCP<MV> helper = MVT::Clone( *B_, MVT::GetNumberVecs( *B_ ) );
864  computeCurrResVec( &*helper, &*X_, &*B_ );
865  R0_user_ = Teuchos::null;
866  R0_ = helper;
867  }
868 
869  if (LP_!=Teuchos::null) {
870  // If the user provided preconditioned residual is the wrong size or pointing at
871  // the wrong object, create one and set the PR0_user_ to null.
872  if (PR0_user_==Teuchos::null || (PR0_user_==R0_) || (PR0_user_==R0_user_)
873  || (MVT::GetNumberVecs(*PR0_user_)!=MVT::GetNumberVecs(*B_))) {
874  Teuchos::RCP<MV> helper = MVT::Clone( *B_, MVT::GetNumberVecs( *B_ ) );
875 
876  // Get the initial residual from getInitResVec because R0_user_ may be null from above.
877  applyLeftPrec( *getInitResVec(), *helper );
878  PR0_user_ = Teuchos::null;
879  PR0_ = helper;
880  }
881  }
882  else {
883  // The preconditioned initial residual vector is the residual vector.
884  // NOTE: R0_user_ could be null if incompatible.
885  if (R0_user_!=Teuchos::null)
886  {
887  PR0_user_ = R0_user_;
888  }
889  else
890  {
891  PR0_user_ = Teuchos::null;
892  PR0_ = R0_;
893  }
894  }
895  }
896 
897  // The problem has been set and is ready for use.
898  isSet_ = true;
899 
900  // Return isSet.
901  return isSet_;
902  }
903 
904  template <class ScalarType, class MV, class OP>
906  {
907  if(Teuchos::nonnull(R0_user_)) {
908  return R0_user_;
909  }
910  return(R0_);
911  }
912 
913  template <class ScalarType, class MV, class OP>
915  {
916  if(Teuchos::nonnull(PR0_user_)) {
917  return PR0_user_;
918  }
919  return(PR0_);
920  }
921 
922  template <class ScalarType, class MV, class OP>
924  {
925  if (isSet_) {
926  return curX_;
927  }
928  else {
929  return Teuchos::null;
930  }
931  }
932 
933  template <class ScalarType, class MV, class OP>
935  {
936  if (isSet_) {
937  return curB_;
938  }
939  else {
940  return Teuchos::null;
941  }
942  }
943 
944  template <class ScalarType, class MV, class OP>
945  void LinearProblem<ScalarType,MV,OP>::apply( const MV& x, MV& y ) const
946  {
947  using Teuchos::null;
948  using Teuchos::RCP;
949 
950  const bool leftPrec = LP_ != null;
951  const bool rightPrec = RP_ != null;
952 
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);
957  }
958  }
959 
960  //
961  // No preconditioning.
962  //
963  if (!leftPrec && !rightPrec) {
964  applyOp( x, y );
965  }
966  //
967  // Preconditioning is being done on both sides
968  //
969  else if( leftPrec && rightPrec )
970  {
971  applyRightPrec( x, y );
972  applyOp( y, *Y_temp_ );
973  applyLeftPrec( *Y_temp_, y );
974  }
975  //
976  // Preconditioning is only being done on the left side
977  //
978  else if( leftPrec )
979  {
980  applyOp( x, *Y_temp_ );
981  applyLeftPrec( *Y_temp_, y );
982  }
983  //
984  // Preconditioning is only being done on the right side
985  //
986  else
987  {
988  applyRightPrec( x, *Y_temp_ );
989  applyOp( *Y_temp_, y );
990  }
991  }
992 
993  template <class ScalarType, class MV, class OP>
994  void LinearProblem<ScalarType,MV,OP>::applyOp( const MV& x, MV& y ) const {
995  if (A_.get()) {
996 #ifdef BELOS_TEUCHOS_TIME_MONITOR
997  Teuchos::TimeMonitor OpTimer(*timerOp_);
998 #endif
999  OPT::Apply( *A_,x, y);
1000  }
1001  else {
1002  MVT::MvAddMv( Teuchos::ScalarTraits<ScalarType>::one(), x,
1004  }
1005  }
1006 
1007  template <class ScalarType, class MV, class OP>
1008  void LinearProblem<ScalarType,MV,OP>::applyLeftPrec( const MV& x, MV& y ) const {
1009  if (LP_!=Teuchos::null) {
1010 #ifdef BELOS_TEUCHOS_TIME_MONITOR
1011  Teuchos::TimeMonitor PrecTimer(*timerPrec_);
1012 #endif
1013  OPT::Apply( *LP_,x, y);
1014  }
1015  else {
1016  MVT::MvAddMv( Teuchos::ScalarTraits<ScalarType>::one(), x,
1018  }
1019  }
1020 
1021  template <class ScalarType, class MV, class OP>
1022  void LinearProblem<ScalarType,MV,OP>::applyRightPrec( const MV& x, MV& y ) const {
1023  if (RP_!=Teuchos::null) {
1024 #ifdef BELOS_TEUCHOS_TIME_MONITOR
1025  Teuchos::TimeMonitor PrecTimer(*timerPrec_);
1026 #endif
1027  OPT::Apply( *RP_,x, y);
1028  }
1029  else {
1030  MVT::MvAddMv( Teuchos::ScalarTraits<ScalarType>::one(), x,
1032  }
1033  }
1034 
1035  template <class ScalarType, class MV, class OP>
1036  void LinearProblem<ScalarType,MV,OP>::computeCurrPrecResVec( MV* R, const MV* X, const MV* B ) const {
1037 
1038  if (R) {
1039  if (X && B) // The entries are specified, so compute the residual of Op(A)X = B
1040  {
1041  if (LP_!=Teuchos::null)
1042  {
1043  Teuchos::RCP<MV> R_temp = MVT::Clone( *B, MVT::GetNumberVecs( *B ) );
1044  applyOp( *X, *R_temp );
1045  MVT::MvAddMv( -1.0, *R_temp, 1.0, *B, *R_temp );
1046  applyLeftPrec( *R_temp, *R );
1047  }
1048  else
1049  {
1050  applyOp( *X, *R );
1051  MVT::MvAddMv( -1.0, *R, 1.0, *B, *R );
1052  }
1053  }
1054  else {
1055  // The solution and right-hand side may not be specified, check and use which ones exist.
1056  Teuchos::RCP<const MV> localB, localX;
1057  if (B)
1058  localB = Teuchos::rcp( B, false );
1059  else
1060  localB = curB_;
1061 
1062  if (X)
1063  localX = Teuchos::rcp( X, false );
1064  else
1065  localX = curX_;
1066 
1067  if (LP_!=Teuchos::null)
1068  {
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 );
1073  }
1074  else
1075  {
1076  applyOp( *localX, *R );
1077  MVT::MvAddMv( -1.0, *R, 1.0, *localB, *R );
1078  }
1079  }
1080  }
1081  }
1082 
1083 
1084  template <class ScalarType, class MV, class OP>
1085  void LinearProblem<ScalarType,MV,OP>::computeCurrResVec( MV* R, const MV* X, const MV* B ) const {
1086 
1087  if (R) {
1088  if (X && B) // The entries are specified, so compute the residual of Op(A)X = B
1089  {
1090  applyOp( *X, *R );
1091  MVT::MvAddMv( -1.0, *R, 1.0, *B, *R );
1092  }
1093  else {
1094  // The solution and right-hand side may not be specified, check and use which ones exist.
1095  Teuchos::RCP<const MV> localB, localX;
1096  if (B)
1097  localB = Teuchos::rcp( B, false );
1098  else
1099  localB = curB_;
1100 
1101  if (X)
1102  localX = Teuchos::rcp( X, false );
1103  else
1104  localX = curX_;
1105 
1106  applyOp( *localX, *R );
1107  MVT::MvAddMv( -1.0, *R, 1.0, *localB, *R );
1108  }
1109  }
1110  }
1111 
1112 } // end Belos namespace
1113 
1114 #endif /* BELOS_LINEAR_PROBLEM_HPP */
1115 
1116 
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.
static RCP< Time > getNewCounter(const std::string &name)
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?
bool is_null(const RCP< T > &p)
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.
MultiVecTraits< ScalarType, MV > MVT
bool isLeftPrec() const
Whether the linear system is being preconditioned on the left.
OperatorTraits< ScalarType, MV, OP > OPT
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.
Definition: BelosTypes.hpp:28
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 ( &lt;= blocksize_ )
void setInitPrecResVec(const Teuchos::RCP< const MV > &PR0)
Set the user-defined preconditioned residual of linear problem .
Teuchos::RCP< Teuchos::Time > timerPrec_