Belos Version of the Day
Loading...
Searching...
No Matches
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
19#include "Teuchos_ParameterList.hpp"
20#include "Teuchos_TimeMonitor.hpp"
21
22namespace Belos {
23
25
26
30 public:
31 LinearProblemError (const std::string& what_arg) :
33 };
34
36
49 template <class ScalarType, class MV, class OP>
51 public:
52
54
55
62 LinearProblem (void);
63
70 LinearProblem (const Teuchos::RCP<const OP> &A,
71 const Teuchos::RCP<MV> &X,
72 const Teuchos::RCP<const MV> &B);
73
78
80 virtual ~LinearProblem (void) {}
81
83
85
86
90 void setOperator (const Teuchos::RCP<const OP> &A) {
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
120 void setInitResVec(const Teuchos::RCP<const MV> &R0) {
121 R0_user_ = R0;
122 isSet_=false;
123 }
124
130 void setInitPrecResVec(const Teuchos::RCP<const MV> &PR0) {
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
223 Teuchos::RCP<MV>
224 updateSolution (const Teuchos::RCP<MV>& update = Teuchos::null,
225 bool updateLP = false,
226 ScalarType scale = Teuchos::ScalarTraits<ScalarType>::one());
227
245 virtual
246 Teuchos::RCP<MV>
247 updateSolution( const Teuchos::RCP<MV>& update = Teuchos::null,
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
301 Teuchos::RCP<const MV> getInitResVec() const;
302
307 Teuchos::RCP<const MV> getInitPrecResVec() const;
308
323 Teuchos::RCP<MV> getCurrLHSVec();
324
339 Teuchos::RCP<const MV> getCurrRHSVec();
340
342 Teuchos::RCP<const OP> getLeftPrec() const { return(LP_); };
343
345 Teuchos::RCP<const OP> getRightPrec() const { return(RP_); };
346
368 const std::vector<int>& getLSIndex() const { return(rhsIndex_); }
369
376 int getLSNumber() const { return(lsNum_); }
377
384 Teuchos::Array<Teuchos::RCP<Teuchos::Time> > getTimers() const {
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
478 Teuchos::RCP<const OP> A_;
479
481 Teuchos::RCP<MV> X_;
482
484 Teuchos::RCP<MV> curX_;
485
487 Teuchos::RCP<const MV> B_;
488
490 Teuchos::RCP<const MV> curB_;
491
493 Teuchos::RCP<MV> R0_;
494
496 Teuchos::RCP<MV> PR0_;
497
499 Teuchos::RCP<const MV> R0_user_;
500
502 Teuchos::RCP<const MV> PR0_user_;
503
505 Teuchos::RCP<const OP> LP_;
506
508 Teuchos::RCP<const OP> RP_;
509
511 mutable Teuchos::RCP<MV> Y_temp_;
512
514 mutable Teuchos::RCP<Teuchos::Time> timerOp_, timerPrec_;
515
518
521
523 std::vector<int> rhsIndex_;
524
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>
570 LinearProblem<ScalarType,MV,OP>::LinearProblem(const Teuchos::RCP<const OP> &A,
571 const Teuchos::RCP<MV> &X,
572 const Teuchos::RCP<const MV> &B
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];
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];
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>
716 Teuchos::RCP<MV>
718 updateSolution (const Teuchos::RCP<MV>& update,
719 bool updateLP,
721 {
722 using Teuchos::RCP;
723 using Teuchos::null;
724
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.
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.
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>
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
801 setProblem (const Teuchos::RCP<MV> &newX,
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,
1003 Teuchos::ScalarTraits<ScalarType>::zero(), x, y );
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,
1017 Teuchos::ScalarTraits<ScalarType>::zero(), x, y );
1018 }
1019 }
1020
1021 template <class ScalarType, class MV, class OP>
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,
1031 Teuchos::ScalarTraits<ScalarType>::zero(), x, y );
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
Declaration of basic traits for the multivector type.
Class which defines basic traits for the operator type.
Parent class to all Belos exceptions.
Exception thrown to signal error with the Belos::LinearProblem object.
LinearProblemError(const std::string &what_arg)
A linear system to solve, and its associated information.
Teuchos::RCP< const MV > PR0_user_
User-defined preconditioned initial residual of the linear system.
std::vector< int > rhsIndex_
Indices of current linear systems being solver for.
bool isSet_
Has the linear problem to solve been set?
void setLabel(const std::string &label)
Set the label prefix used by the timers in this object.
bool isRightPrec() const
Whether the linear system is being preconditioned on the right.
void setInitPrecResVec(const Teuchos::RCP< const MV > &PR0)
Set the user-defined preconditioned residual of linear problem .
int blocksize_
Current block size of linear system.
virtual void applyLeftPrec(const MV &x, MV &y) const
Apply ONLY the left preconditioner to x, returning y.
bool isSolutionUpdated() const
Has the current approximate solution been updated?
std::string label_
Linear problem label that prefixes the timer labels.
Teuchos::RCP< const MV > curB_
Current right-hand side of the linear system.
void setLeftPrec(const Teuchos::RCP< const OP > &LP)
Set left preconditioner (LP) of linear problem .
Teuchos::RCP< const MV > B_
Right-hand side of linear system.
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.
virtual ~LinearProblem(void)
Destructor (declared virtual for memory safety of derived classes).
virtual void apply(const MV &x, MV &y) const
Apply the composite operator of this linear problem to x, returning y.
void setLHS(const Teuchos::RCP< MV > &X)
Set left-hand-side X of linear problem .
virtual void setLSIndex(const std::vector< int > &index)
Tell the linear problem which linear system(s) need to be solved next.
bool solutionUpdated_
Has the current approximate solution been updated?
Teuchos::RCP< MV > PR0_
Preconditioned initial residual of the linear system.
virtual void applyRightPrec(const MV &x, MV &y) const
Apply ONLY the right preconditioner to x, returning y.
Teuchos::RCP< const OP > LP_
Left preconditioning operator of linear system.
Teuchos::RCP< const OP > getLeftPrec() const
Get a pointer to the left preconditioner.
Teuchos::RCP< const MV > R0_user_
User-defined initial residual of the linear system.
Teuchos::RCP< MV > curX_
Current solution vector of the linear system.
Teuchos::RCP< MV > R0_
Initial residual of the linear system.
void setRightPrec(const Teuchos::RCP< const OP > &RP)
Set right preconditioner (RP) of linear problem .
virtual void setCurrLS()
Tell the linear problem that the solver is finished with the current linear system.
int getLSNumber() const
The number of linear systems that have been set.
void setHermitian(bool isSym=true)
Tell the linear problem that the (preconditioned) operator is Hermitian.
void setOperator(const Teuchos::RCP< const OP > &A)
Set the operator A of the linear problem .
bool isProblemSet() const
Whether the problem has been set.
int num2Solve_
Number of linear systems that are currently being solver for ( <= blocksize_ )
Teuchos::RCP< Teuchos::Time > timerPrec_
Teuchos::RCP< const MV > getInitPrecResVec() const
A pointer to the preconditioned initial residual vector.
Teuchos::RCP< const OP > getRightPrec() const
Get a pointer to the right preconditioner.
Teuchos::RCP< const OP > getOperator() const
A pointer to the (unpreconditioned) operator A.
Teuchos::RCP< Teuchos::Time > timerOp_
Timers.
const std::vector< int > & getLSIndex() const
(Zero-based) indices of the linear system(s) currently being solved.
Teuchos::Array< Teuchos::RCP< Teuchos::Time > > getTimers() const
The timers for this object.
bool isHermitian_
Whether the operator A is symmetric (in real arithmetic, or Hermitian in complex arithmetic).
LinearProblem(void)
Default constructor.
void setRHS(const Teuchos::RCP< const MV > &B)
Set right-hand-side B of linear problem .
Teuchos::RCP< const MV > getRHS() const
A pointer to the right-hand side B.
bool isHermitian() const
Whether the (preconditioned) operator is Hermitian.
Teuchos::RCP< MV > getLHS() const
A pointer to the left-hand side X.
virtual void applyOp(const MV &x, MV &y) const
Apply ONLY the operator to x, returning y.
Teuchos::RCP< const MV > getInitResVec() const
A pointer to the initial unpreconditioned residual vector.
Teuchos::RCP< MV > getCurrLHSVec()
Get a pointer to the current left-hand side (solution) of the linear system.
bool isLeftPrec() const
Whether the linear system is being preconditioned on the left.
Teuchos::RCP< const MV > getCurrRHSVec()
Get a pointer to the current right-hand side of the linear system.
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.
int lsNum_
Number of linear systems that have been loaded in this linear problem object.
Teuchos::RCP< MV > Y_temp_
Scratch vector for use in apply()
Teuchos::RCP< MV > X_
Solution vector of linear system.
Teuchos::RCP< const OP > A_
Operator of linear system.
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.
void setInitResVec(const Teuchos::RCP< const MV > &R0)
Set the user-defined residual of linear problem .
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.
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 OP > RP_
Right preconditioning operator of linear system.
Alternative run-time polymorphic interface for operators.
Operator()
Default constructor (does nothing).

Generated for Belos by doxygen 1.9.8