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 BELOS_GMRESPOLYOP_HPP
00030 #define BELOS_GMRESPOLYOP_HPP
00031
00036 #include "BelosOperatorTraits.hpp"
00037 #include "BelosMultiVecTraits.hpp"
00038 #include "BelosLinearProblem.hpp"
00039 #include "BelosConfigDefs.hpp"
00040 #include "Teuchos_RCP.hpp"
00041 #include "Teuchos_SerialDenseMatrix.hpp"
00042 #include "Teuchos_SerialDenseVector.hpp"
00043
00055 namespace Belos {
00056
00057 template <class ScalarType, class MV, class OP>
00058 class GmresPolyOp {
00059 public:
00060
00062
00063
00065 GmresPolyOp() {}
00066
00068 GmresPolyOp( const Teuchos::RCP<LinearProblem<ScalarType,MV,OP> >& problem_in,
00069 const Teuchos::RCP<Teuchos::SerialDenseMatrix<int, ScalarType> >& hess,
00070 const Teuchos::RCP<Teuchos::SerialDenseMatrix<int, ScalarType> >& comb,
00071 const Teuchos::RCP<Teuchos::SerialDenseVector<int, ScalarType> >& scal
00072 )
00073 : problem_(problem_in), LP_(problem_in->getLeftPrec()), RP_(problem_in->getRightPrec()), H_(hess), y_(comb), r0_(scal)
00074 {
00075 dim_ = y_->numRows();
00076 }
00077
00079 virtual ~GmresPolyOp() {};
00081
00083
00084
00090 void Apply ( const MV& x, MV& y, ETrans trans=NOTRANS );
00091
00092 private:
00093
00094 typedef MultiVecTraits<ScalarType,MV> MVT;
00095 typedef Teuchos::ScalarTraits<ScalarType> SCT ;
00096
00097 int dim_;
00098 Teuchos::RCP<LinearProblem<ScalarType,MV,OP> > problem_;
00099 Teuchos::RCP<const OP> LP_, RP_;
00100 Teuchos::RCP<MV> V_, wL_, wR_;
00101 Teuchos::RCP<Teuchos::SerialDenseMatrix<int,ScalarType> > H_, y_;
00102 Teuchos::RCP<Teuchos::SerialDenseVector<int,ScalarType> > r0_;
00103 };
00104
00105 template <class ScalarType, class MV, class OP>
00106 void GmresPolyOp<ScalarType, MV, OP>::Apply( const MV& x, MV& y, ETrans trans )
00107 {
00108
00109 if (V_ == Teuchos::null) {
00110 V_ = MVT::Clone( x, dim_ );
00111 if (LP_ != Teuchos::null)
00112 wL_ = MVT::Clone( y, 1 );
00113 if (RP_ != Teuchos::null)
00114 wR_ = MVT::Clone( y, 1 );
00115 }
00116
00117
00118
00119 int n = MVT::GetNumberVecs( x );
00120 std::vector<int> idxi(1), idxi2, idxj(1);
00121 Teuchos::RCP<MV> v_curr, v_next, v_prev;
00122
00123
00124 for (int j=0; j<n; ++j) {
00125
00126 idxi[0] = 0;
00127 idxj[0] = j;
00128 Teuchos::RCP<const MV> x_view = MVT::CloneView( x, idxj );
00129 Teuchos::RCP<MV> y_view = MVT::CloneView( y, idxj );
00130 if (LP_ != Teuchos::null) {
00131 v_curr = MVT::CloneView( *V_, idxi );
00132 problem_->applyLeftPrec( *x_view, *v_curr );
00133 } else {
00134 MVT::SetBlock( *x_view, idxi, *V_ );
00135 }
00136
00137 for (int i=0; i<dim_-1; ++i) {
00138
00139
00140 idxi2.resize(i+1);
00141 for (int ii=0; ii<i+1; ++ii) { idxi2[ii] = ii; }
00142 v_prev = MVT::CloneView( *V_, idxi2 );
00143 v_curr = MVT::CloneView( *V_, idxi );
00144 idxi[0] = i+1;
00145 v_next = MVT::CloneView( *V_, idxi );
00146
00147
00148
00149
00150
00151 if (RP_ != Teuchos::null) {
00152 problem_->applyRightPrec( *v_curr, *wR_ );
00153 } else {
00154 wR_ = v_curr;
00155 }
00156
00157 if (LP_ == Teuchos::null) {
00158 wL_ = v_next;
00159 }
00160
00161 problem_->applyOp( *wR_, *wL_ );
00162
00163 if (LP_ != Teuchos::null) {
00164 problem_->applyLeftPrec( *wL_, *v_next );
00165 }
00166
00167
00168 Teuchos::SerialDenseMatrix<int,ScalarType> h(Teuchos::View,*H_,i+1,1,0,i);
00169 MVT::MvTimesMatAddMv( -SCT::one(), *v_prev, h, SCT::one(), *v_next );
00170
00171
00172 MVT::MvScale( *v_next, SCT::one()/(*H_)(i+1,i) );
00173 }
00174
00175
00176 if (RP_ != Teuchos::null) {
00177 MVT::MvTimesMatAddMv( SCT::one()/(*r0_)(0), *V_, *y_, SCT::zero(), *wR_ );
00178 problem_->applyRightPrec( *wR_, *y_view );
00179 } else {
00180 MVT::MvTimesMatAddMv( SCT::one()/(*r0_)(0), *V_, *y_, SCT::zero(), *y_view );
00181 }
00182 }
00183 }
00184
00186
00187
00188
00190
00194 template <class ScalarType, class MV, class OP>
00195 class OperatorTraits < ScalarType, MV, GmresPolyOp<ScalarType,MV,OP> >
00196 {
00197 public:
00198
00200 static void Apply ( const GmresPolyOp<ScalarType,MV,OP>& Op,
00201 const MV& x, MV& y,
00202 ETrans trans=NOTRANS )
00203 { Op.Apply( x, y, trans ); }
00204
00205 };
00206
00207 }
00208
00209 #endif
00210
00211