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_EXAMPLE_TRIDIAG_SERIAL_LINEAR_OP_HPP
00030 #define THYRA_EXAMPLE_TRIDIAG_SERIAL_LINEAR_OP_HPP
00031
00032 #include "Thyra_SpmdLinearOpBase.hpp"
00033
00068 template<class Scalar>
00069 class ExampleTridiagSerialLinearOp : public Thyra::SpmdLinearOpBase<Scalar> {
00070 private:
00071
00072 Thyra::Index dim_;
00073 std::vector<Scalar> lower_;
00074 std::vector<Scalar> diag_;
00075 std::vector<Scalar> upper_;
00076
00077 public:
00078
00080 using Thyra::SpmdLinearOpBase<Scalar>::euclideanApply;
00081
00083 ExampleTridiagSerialLinearOp() : dim_(0) {}
00084
00086 ExampleTridiagSerialLinearOp( const Thyra::Index dim, const Scalar lower[], const Scalar diag[], const Scalar upper[] )
00087 { this->initialize(dim,lower,diag,upper); }
00088
00105 void initialize(
00106 const Thyra::Index dim
00107 ,const Scalar lower[]
00108 ,const Scalar diag[]
00109 ,const Scalar upper[]
00110 )
00111 {
00112 TEST_FOR_EXCEPT( dim < 2 );
00113 this->setLocalDimensions(Teuchos::null,dim,dim);
00114 dim_ = dim;
00115 lower_.resize(dim-1); for( int k = 0; k < dim-1; ++k ) lower_[k] = lower[k];
00116 diag_.resize(dim); for( int k = 0; k < dim; ++k ) diag_[k] = diag[k];
00117 upper_.resize(dim-1); for( int k = 0; k < dim-1; ++k ) upper_[k] = upper[k];
00118 }
00119
00120
00121
00122 std::string description() const
00123 {
00124 return (std::string("ExampleTridiagSerialLinearOp<") + Teuchos::ScalarTraits<Scalar>::name() + std::string(">"));
00125 }
00126
00127 protected:
00128
00129
00130
00131 bool opSupported(Thyra::EOpTransp M_trans) const { return true; }
00132
00133
00134
00135 void euclideanApply(
00136 const Thyra::EOpTransp M_trans
00137 ,const RTOpPack::ConstSubVectorView<Scalar> &x_in
00138 ,const RTOpPack::SubVectorView<Scalar> *y_out
00139 ,const Scalar alpha
00140 ,const Scalar beta
00141 ) const
00142 {
00143 typedef Teuchos::ScalarTraits<Scalar> ST;
00144
00145 const Scalar *x = x_in.values().get();
00146 Scalar *y = y_out->values().get();
00147
00148 Thyra::Index k = 0;
00149 if( beta == ST::zero() ) {
00150 for( k = 0; k < dim_; ++k ) y[k] = ST::zero();
00151 }
00152 else if( beta != ST::one() ) {
00153 for( k = 0; k < dim_; ++k ) y[k] *= beta;
00154 }
00155
00156 k = 0;
00157 if( M_trans == Thyra::NOTRANS ) {
00158 y[k] += alpha * ( diag_[k]*x[k] + upper_[k]*x[k+1] );
00159 for( k = 1; k < dim_ - 1; ++k )
00160 y[k] += alpha * ( lower_[k-1]*x[k-1] + diag_[k]*x[k] + upper_[k]*x[k+1] );
00161 y[k] += alpha * ( lower_[k-1]*x[k-1] + diag_[k]*x[k] );
00162 }
00163 else if( M_trans == Thyra::CONJ ) {
00164 y[k] += alpha * ( ST::conjugate(diag_[k])*x[k] + ST::conjugate(upper_[k])*x[k+1] );
00165 for( k = 1; k < dim_ - 1; ++k )
00166 y[k] += alpha * ( ST::conjugate(lower_[k-1])*x[k-1] + ST::conjugate(diag_[k])*x[k] + ST::conjugate(upper_[k])*x[k+1] );
00167 y[k] += alpha * ( ST::conjugate(lower_[k-1])*x[k-1] + ST::conjugate(diag_[k])*x[k] );
00168 }
00169 else if( M_trans == Thyra::TRANS ) {
00170 y[k] += alpha * ( diag_[k]*x[k] + lower_[k]*x[k+1] );
00171 for( k = 1; k < dim_ - 1; ++k )
00172 y[k] += alpha * ( upper_[k-1]*x[k-1] + diag_[k]*x[k] + lower_[k]*x[k+1] );
00173 y[k] += alpha * ( upper_[k-1]*x[k-1] + diag_[k]*x[k] );
00174 }
00175 else if( M_trans == Thyra::CONJTRANS ) {
00176 y[k] += alpha * ( ST::conjugate(diag_[k])*x[k] + ST::conjugate(lower_[k])*x[k+1] );
00177 for( k = 1; k < dim_ - 1; ++k )
00178 y[k] += alpha * ( ST::conjugate(upper_[k-1])*x[k-1] + ST::conjugate(diag_[k])*x[k] + ST::conjugate(lower_[k])*x[k+1] );
00179 y[k] += alpha * ( ST::conjugate(upper_[k-1])*x[k-1] + ST::conjugate(diag_[k])*x[k] );
00180 }
00181 else {
00182 TEST_FOR_EXCEPT(true);
00183 }
00184 }
00185
00186 };
00187
00188 #endif // THYRA_EXAMPLE_TRIDIAG_SERIAL_LINEAR_OP_HPP