BelosThyraAdapter.hpp

Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //                 Belos: Block Eigensolvers Package
00005 //                 Copyright (2004) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00025 //
00026 // ***********************************************************************
00027 // @HEADER
00028 
00034 #ifndef BELOS_THYRA_ADAPTER_HPP
00035 #define BELOS_THYRA_ADAPTER_HPP
00036 
00037 #include "BelosMultiVecTraits.hpp"
00038 #include "BelosOperatorTraits.hpp"
00039 #include "BelosConfigDefs.hpp"
00040 
00041 #include <Thyra_DetachedMultiVectorView.hpp>
00042 #include <Thyra_MultiVectorBaseDecl.hpp>
00043 #include <Thyra_MultiVectorStdOps.hpp>
00044 
00045 namespace Belos {
00046   
00048   //
00049   // Implementation of the Belos::MultiVecTraits for Thyra::MultiVectorBase
00050   //
00052 
00061   template<class ScalarType>
00062   class MultiVecTraits< ScalarType, Thyra::MultiVectorBase<ScalarType> >
00063   {
00064   private:
00065     typedef Thyra::MultiVectorBase<ScalarType> TMVB;
00066     typedef Teuchos::ScalarTraits<ScalarType> ST;
00067     typedef typename ST::magnitudeType magType;
00068   public:
00069 
00072 
00077     static Teuchos::RCP<TMVB> Clone( const TMVB& mv, const int numvecs )
00078     { 
00079       Teuchos::RCP<TMVB> c = Thyra::createMembers( mv.range(), numvecs ); 
00080       return c;
00081     }
00082 
00087     static Teuchos::RCP<TMVB> CloneCopy( const TMVB& mv )
00088     { 
00089       int numvecs = mv.domain()->dim();
00090       // create the new multivector
00091       Teuchos::RCP< TMVB > cc = Thyra::createMembers( mv.range(), numvecs );
00092       // copy the data from the source multivector to the new multivector
00093       Thyra::assign(&*cc, mv);
00094       return cc;
00095     }
00096 
00102     static Teuchos::RCP<TMVB> CloneCopy( const TMVB& mv, const std::vector<int>& index )
00103     { 
00104       int numvecs = index.size();
00105       // create the new multivector
00106       Teuchos::RCP< TMVB > cc = Thyra::createMembers( mv.range(), numvecs );
00107       // create a view to the relevant part of the source multivector
00108       Teuchos::RCP< const TMVB > view = mv.subView( numvecs, &(index[0]) );
00109       // copy the data from the relevant view to the new multivector
00110       Thyra::assign(&*cc, *view);
00111       return cc;
00112     }
00113 
00119     static Teuchos::RCP<TMVB> CloneView( TMVB& mv, const std::vector<int>& index )
00120     {
00121       int numvecs = index.size();
00122 
00123       // We do not assume that the indices are sorted, nor do we check that
00124       // index.size() > 0. This code is fail-safe, in the sense that a zero
00125       // length index std::vector will pass the error on the Thyra.
00126 
00127       // Thyra has two ways to create an indexed View:
00128       // * contiguous (via a range of columns)
00129       // * indexed (via a std::vector of column indices)
00130       // The former is significantly more efficient than the latter, in terms of
00131       // computations performed with/against the created view.
00132       // We will therefore check to see if the given indices are contiguous, and
00133       // if so, we will use the contiguous view creation method.
00134 
00135       int lb = index[0];
00136       bool contig = true;
00137       for (int i=0; i<numvecs; i++) {
00138         if (lb+i != index[i]) contig = false;
00139       }
00140 
00141       Teuchos::RCP< TMVB > cc;
00142       if (contig) {
00143         const Thyra::Range1D rng(lb,lb+numvecs-1);
00144         // create a contiguous view to the relevant part of the source multivector
00145         cc = mv.subView(rng);
00146       }
00147       else {
00148         // create an indexed view to the relevant part of the source multivector
00149         cc = mv.subView( numvecs, &(index[0]) );
00150       }
00151       return cc;
00152     }
00153 
00159     static Teuchos::RCP<const TMVB> CloneView( const TMVB& mv, const std::vector<int>& index )
00160     {
00161       int numvecs = index.size();
00162 
00163       // We do not assume that the indices are sorted, nor do we check that
00164       // index.size() > 0. This code is fail-safe, in the sense that a zero
00165       // length index std::vector will pass the error on the Thyra.
00166 
00167       // Thyra has two ways to create an indexed View:
00168       // * contiguous (via a range of columns)
00169       // * indexed (via a std::vector of column indices)
00170       // The former is significantly more efficient than the latter, in terms of
00171       // computations performed with/against the created view.
00172       // We will therefore check to see if the given indices are contiguous, and
00173       // if so, we will use the contiguous view creation method.
00174 
00175       int lb = index[0];
00176       bool contig = true;
00177       for (int i=0; i<numvecs; i++) {
00178         if (lb+i != index[i]) contig = false;
00179       }
00180 
00181       Teuchos::RCP< const TMVB > cc;
00182       if (contig) {
00183         const Thyra::Range1D rng(lb,lb+numvecs-1);
00184         // create a contiguous view to the relevant part of the source multivector
00185         cc = mv.subView(rng);
00186       }
00187       else {
00188         // create an indexed view to the relevant part of the source multivector
00189         cc = mv.subView( numvecs, &(index[0]) );
00190       }
00191       return cc;
00192     }
00193 
00195 
00198 
00200     static int GetVecLength( const TMVB& mv )
00201     { return mv.range()->dim(); }
00202 
00204     static int GetNumberVecs( const TMVB& mv )
00205     { return mv.domain()->dim(); }
00206 
00208 
00211 
00214     static void MvTimesMatAddMv( const ScalarType alpha, const TMVB& A, 
00215          const Teuchos::SerialDenseMatrix<int,ScalarType>& B, 
00216          const ScalarType beta, TMVB& mv )
00217     {
00218       int m = B.numRows();
00219       int n = B.numCols();
00220       // Create a view of the B object!
00221       Teuchos::RCP< const TMVB >
00222         B_thyra = Thyra::createMembersView(
00223           A.domain()
00224           ,RTOpPack::ConstSubMultiVectorView<ScalarType>(0,m,0,n,&B(0,0),B.stride())
00225           );
00226       // perform the operation via A: mv <- alpha*A*B_thyra + beta*mv
00227       A.apply(Thyra::NONCONJ_ELE,*B_thyra,&mv,alpha,beta);
00228     }
00229 
00232     static void MvAddMv( const ScalarType alpha, const TMVB& A, 
00233                          const ScalarType beta,  const TMVB& B, TMVB& mv )
00234     { 
00235       ScalarType coef[2], zero = Teuchos::ScalarTraits<ScalarType>::zero();
00236       const TMVB * in[2];
00237 
00238       in[0] = &A;
00239       in[1] = &B;
00240       coef[0] = alpha;
00241       coef[1] = beta;
00242 
00243       Thyra::linear_combination(2,coef,in,zero,&mv);
00244     }
00245 
00248     static void MvScale ( TMVB& mv, const ScalarType alpha )
00249     { Thyra::scale(alpha,&mv); }
00250 
00253     static void MvScale ( TMVB& mv, const std::vector<ScalarType>& alpha )
00254     {
00255       for (unsigned int i=0; i<alpha.size(); i++) {
00256         Thyra::scale(alpha[i],mv.col(i).get());
00257       }
00258     }
00259 
00262     static void MvTransMv( const ScalarType alpha, const TMVB& A, const TMVB& mv, 
00263                            Teuchos::SerialDenseMatrix<int,ScalarType>& B )
00264     { 
00265       // Create a multivector to hold the result (m by n)
00266       int m = A.domain()->dim();
00267       int n = mv.domain()->dim();
00268       // Create a view of the B object!
00269       Teuchos::RCP< TMVB >
00270         B_thyra = Thyra::createMembersView(
00271           A.domain()
00272           ,RTOpPack::SubMultiVectorView<ScalarType>(0,m,0,n,&B(0,0),B.stride())
00273           );
00274       A.applyTranspose(Thyra::CONJ_ELE,mv,&*B_thyra,alpha,Teuchos::ScalarTraits<ScalarType>::zero());
00275     }
00276 
00280     static void MvDot( const TMVB& mv, const TMVB& A, std::vector<ScalarType>& b )
00281     { Thyra::dots(mv,A,&(b[0])); }
00282 
00284 
00287 
00291     static void MvNorm( const TMVB& mv, std::vector<magType>& normvec, NormType type = TwoNorm )
00292     { Thyra::norms_2(mv,&(normvec[0])); }
00293 
00295 
00298 
00301     static void SetBlock( const TMVB& A, const std::vector<int>& index, TMVB& mv )
00302     { 
00303       // Extract the "numvecs" columns of mv indicated by the index std::vector.
00304       int numvecs = index.size();
00305       std::vector<int> indexA(numvecs);
00306       int numAcols = A.domain()->dim();
00307       for (int i=0; i<numvecs; i++) {
00308         indexA[i] = i;
00309       }
00310       // Thyra::assign requires that both arguments have the same number of 
00311       // vectors. Enforce this, by shrinking one to match the other.
00312       if ( numAcols < numvecs ) {
00313         // A does not have enough columns to satisfy index_plus. Shrink
00314         // index_plus.
00315         numvecs = numAcols;
00316       }
00317       else if ( numAcols > numvecs ) {
00318         numAcols = numvecs;
00319         indexA.resize( numAcols );
00320       }
00321       // create a view to the relevant part of the source multivector
00322       Teuchos::RCP< const TMVB > relsource = A.subView( numAcols, &(indexA[0]) );
00323       // create a view to the relevant part of the destination multivector
00324       Teuchos::RCP< TMVB > reldest = mv.subView( numvecs, &(index[0]) );
00325       // copy the data to the destination multivector subview
00326       Thyra::assign(&*reldest, *relsource);
00327     }
00328 
00331     static void MvRandom( TMVB& mv )
00332     { 
00333       // Thyra::randomize generates via a uniform distribution on [l,u]
00334       // We will use this to generate on [-1,1]
00335       Thyra::randomize(-Teuchos::ScalarTraits<ScalarType>::one(),
00336                         Teuchos::ScalarTraits<ScalarType>::one(),
00337                        &mv);
00338     }
00339 
00342     static void MvInit( TMVB& mv, ScalarType alpha = Teuchos::ScalarTraits<ScalarType>::zero() )
00343     { Thyra::assign(&mv,alpha); }
00344 
00346 
00349 
00352     static void MvPrint( const TMVB& mv, std::ostream& os )
00353       { os << describe(mv,Teuchos::VERB_EXTREME); }
00354 
00356 
00357   };        
00358 
00360   //
00361   // Implementation of the Belos::OperatorTraits for Thyra::LinearOpBase
00362   //
00364 
00373   template <class ScalarType> 
00374   class OperatorTraits < ScalarType, Thyra::MultiVectorBase<ScalarType>, Thyra::LinearOpBase<ScalarType> >
00375   {
00376   private:
00377     typedef Thyra::MultiVectorBase<ScalarType> TMVB;
00378     typedef Thyra::LinearOpBase<ScalarType>    TLOB;
00379   public:
00380     
00384     static void Apply ( const TLOB& Op, const TMVB& x, TMVB& y )
00385     { 
00386       Op.apply(Thyra::NONCONJ_ELE,x,&y);
00387     }
00388     
00389   };
00390   
00391 } // end of Belos namespace 
00392 
00393 #endif 
00394 // end of file BELOS_THYRA_ADAPTER_HPP

Generated on Wed Jul 22 12:56:29 2009 for Stratimikos by  doxygen 1.5.8