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 
00044 namespace Belos {
00045   
00047   //
00048   // Implementation of the Belos::MultiVecTraits for Thyra::MultiVectorBase
00049   //
00051 
00060   template<class ScalarType>
00061   class MultiVecTraits< ScalarType, Thyra::MultiVectorBase<ScalarType> >
00062   {
00063   private:
00064     typedef Thyra::MultiVectorBase<ScalarType> TMVB;
00065     typedef Teuchos::ScalarTraits<ScalarType> ST;
00066     typedef typename ST::magnitudeType magType;
00067   public:
00068 
00071 
00076     static Teuchos::RCP<TMVB> Clone( const TMVB& mv, const int numvecs )
00077     { 
00078       Teuchos::RCP<TMVB> c = Thyra::createMembers( mv.range(), numvecs ); 
00079       return c;
00080     }
00081 
00086     static Teuchos::RCP<TMVB> CloneCopy( const TMVB& mv )
00087     { 
00088       int numvecs = mv.domain()->dim();
00089       // create the new multivector
00090       Teuchos::RCP< TMVB > cc = Thyra::createMembers( mv.range(), numvecs );
00091       // copy the data from the source multivector to the new multivector
00092       Thyra::assign(&*cc, mv);
00093       return cc;
00094     }
00095 
00101     static Teuchos::RCP<TMVB> CloneCopy( const TMVB& mv, const std::vector<int>& index )
00102     { 
00103       int numvecs = index.size();
00104       // create the new multivector
00105       Teuchos::RCP< TMVB > cc = Thyra::createMembers( mv.range(), numvecs );
00106       // create a view to the relevant part of the source multivector
00107       Teuchos::RCP< const TMVB > view = mv.subView( numvecs, &(index[0]) );
00108       // copy the data from the relevant view to the new multivector
00109       Thyra::assign(&*cc, *view);
00110       return cc;
00111     }
00112 
00118     static Teuchos::RCP<TMVB> CloneView( TMVB& mv, const std::vector<int>& index )
00119     {
00120       int numvecs = index.size();
00121 
00122       // We do not assume that the indices are sorted, nor do we check that
00123       // index.size() > 0. This code is fail-safe, in the sense that a zero
00124       // length index std::vector will pass the error on the Thyra.
00125 
00126       // Thyra has two ways to create an indexed View:
00127       // * contiguous (via a range of columns)
00128       // * indexed (via a std::vector of column indices)
00129       // The former is significantly more efficient than the latter, in terms of
00130       // computations performed with/against the created view.
00131       // We will therefore check to see if the given indices are contiguous, and
00132       // if so, we will use the contiguous view creation method.
00133 
00134       int lb = index[0];
00135       bool contig = true;
00136       for (int i=0; i<numvecs; i++) {
00137         if (lb+i != index[i]) contig = false;
00138       }
00139 
00140       Teuchos::RCP< TMVB > cc;
00141       if (contig) {
00142         const Thyra::Range1D rng(lb,lb+numvecs-1);
00143         // create a contiguous view to the relevant part of the source multivector
00144         cc = mv.subView(rng);
00145       }
00146       else {
00147         // create an indexed view to the relevant part of the source multivector
00148         cc = mv.subView( numvecs, &(index[0]) );
00149       }
00150       return cc;
00151     }
00152 
00158     static Teuchos::RCP<const TMVB> CloneView( const TMVB& mv, const std::vector<int>& index )
00159     {
00160       int numvecs = index.size();
00161 
00162       // We do not assume that the indices are sorted, nor do we check that
00163       // index.size() > 0. This code is fail-safe, in the sense that a zero
00164       // length index std::vector will pass the error on the Thyra.
00165 
00166       // Thyra has two ways to create an indexed View:
00167       // * contiguous (via a range of columns)
00168       // * indexed (via a std::vector of column indices)
00169       // The former is significantly more efficient than the latter, in terms of
00170       // computations performed with/against the created view.
00171       // We will therefore check to see if the given indices are contiguous, and
00172       // if so, we will use the contiguous view creation method.
00173 
00174       int lb = index[0];
00175       bool contig = true;
00176       for (int i=0; i<numvecs; i++) {
00177         if (lb+i != index[i]) contig = false;
00178       }
00179 
00180       Teuchos::RCP< const TMVB > cc;
00181       if (contig) {
00182         const Thyra::Range1D rng(lb,lb+numvecs-1);
00183         // create a contiguous view to the relevant part of the source multivector
00184         cc = mv.subView(rng);
00185       }
00186       else {
00187         // create an indexed view to the relevant part of the source multivector
00188         cc = mv.subView( numvecs, &(index[0]) );
00189       }
00190       return cc;
00191     }
00192 
00194 
00197 
00199     static int GetVecLength( const TMVB& mv )
00200     { return mv.range()->dim(); }
00201 
00203     static int GetNumberVecs( const TMVB& mv )
00204     { return mv.domain()->dim(); }
00205 
00207 
00210 
00213     static void MvTimesMatAddMv( const ScalarType alpha, const TMVB& A, 
00214          const Teuchos::SerialDenseMatrix<int,ScalarType>& B, 
00215          const ScalarType beta, TMVB& mv )
00216     {
00217       int m = B.numRows();
00218       int n = B.numCols();
00219       // Create a view of the B object!
00220       Teuchos::RCP< const TMVB >
00221         B_thyra = Thyra::createMembersView(
00222           A.domain()
00223           ,RTOpPack::ConstSubMultiVectorView<ScalarType>(0,m,0,n,&B(0,0),B.stride())
00224           );
00225       // perform the operation via A: mv <- alpha*A*B_thyra + beta*mv
00226       A.apply(Thyra::NONCONJ_ELE,*B_thyra,&mv,alpha,beta);
00227     }
00228 
00231     static void MvAddMv( const ScalarType alpha, const TMVB& A, 
00232                          const ScalarType beta,  const TMVB& B, TMVB& mv )
00233     { 
00234       ScalarType coef[2], zero = Teuchos::ScalarTraits<ScalarType>::zero();
00235       const TMVB * in[2];
00236 
00237       in[0] = &A;
00238       in[1] = &B;
00239       coef[0] = alpha;
00240       coef[1] = beta;
00241 
00242       Thyra::linear_combination(2,coef,in,zero,&mv);
00243     }
00244 
00247     static void MvScale ( TMVB& mv, const ScalarType alpha )
00248     { Thyra::scale(alpha,&mv); }
00249 
00252     static void MvScale ( TMVB& mv, const std::vector<ScalarType>& alpha )
00253     {
00254       for (unsigned int i=0; i<alpha.size(); i++) {
00255         Thyra::scale(alpha[i],mv.col(i).get());
00256       }
00257     }
00258 
00261     static void MvTransMv( const ScalarType alpha, const TMVB& A, const TMVB& mv, 
00262                            Teuchos::SerialDenseMatrix<int,ScalarType>& B )
00263     { 
00264       // Create a multivector to hold the result (m by n)
00265       int m = A.domain()->dim();
00266       int n = mv.domain()->dim();
00267       // Create a view of the B object!
00268       Teuchos::RCP< TMVB >
00269         B_thyra = Thyra::createMembersView(
00270           A.domain()
00271           ,RTOpPack::SubMultiVectorView<ScalarType>(0,m,0,n,&B(0,0),B.stride())
00272           );
00273       A.applyTranspose(Thyra::CONJ_ELE,mv,&*B_thyra,alpha,Teuchos::ScalarTraits<ScalarType>::zero());
00274     }
00275 
00279     static void MvDot( const TMVB& mv, const TMVB& A, std::vector<ScalarType>& b )
00280     { Thyra::dots(mv,A,&(b[0])); }
00281 
00283 
00286 
00290     static void MvNorm( const TMVB& mv, std::vector<magType>& normvec, NormType type = TwoNorm )
00291     { Thyra::norms_2(mv,&(normvec[0])); }
00292 
00294 
00297 
00300     static void SetBlock( const TMVB& A, const std::vector<int>& index, TMVB& mv )
00301     { 
00302       // Extract the "numvecs" columns of mv indicated by the index std::vector.
00303       int numvecs = index.size();
00304       std::vector<int> indexA(numvecs);
00305       int numAcols = A.domain()->dim();
00306       for (int i=0; i<numvecs; i++) {
00307         indexA[i] = i;
00308       }
00309       // Thyra::assign requires that both arguments have the same number of 
00310       // vectors. Enforce this, by shrinking one to match the other.
00311       if ( numAcols < numvecs ) {
00312         // A does not have enough columns to satisfy index_plus. Shrink
00313         // index_plus.
00314         numvecs = numAcols;
00315       }
00316       else if ( numAcols > numvecs ) {
00317         numAcols = numvecs;
00318         indexA.resize( numAcols );
00319       }
00320       // create a view to the relevant part of the source multivector
00321       Teuchos::RCP< const TMVB > relsource = A.subView( numAcols, &(indexA[0]) );
00322       // create a view to the relevant part of the destination multivector
00323       Teuchos::RCP< TMVB > reldest = mv.subView( numvecs, &(index[0]) );
00324       // copy the data to the destination multivector subview
00325       Thyra::assign(&*reldest, *relsource);
00326     }
00327 
00330     static void MvRandom( TMVB& mv )
00331     { 
00332       // Thyra::randomize generates via a uniform distribution on [l,u]
00333       // We will use this to generate on [-1,1]
00334       Thyra::randomize(-Teuchos::ScalarTraits<ScalarType>::one(),
00335                         Teuchos::ScalarTraits<ScalarType>::one(),
00336                        &mv);
00337     }
00338 
00341     static void MvInit( TMVB& mv, ScalarType alpha = Teuchos::ScalarTraits<ScalarType>::zero() )
00342     { Thyra::assign(&mv,alpha); }
00343 
00345 
00348 
00351     static void MvPrint( const TMVB& mv, std::ostream& os )
00352       { os << describe(mv,Teuchos::VERB_EXTREME); }
00353 
00355 
00356   };        
00357 
00359   //
00360   // Implementation of the Belos::OperatorTraits for Thyra::LinearOpBase
00361   //
00363 
00372   template <class ScalarType> 
00373   class OperatorTraits < ScalarType, Thyra::MultiVectorBase<ScalarType>, Thyra::LinearOpBase<ScalarType> >
00374   {
00375   private:
00376     typedef Thyra::MultiVectorBase<ScalarType> TMVB;
00377     typedef Thyra::LinearOpBase<ScalarType>    TLOB;
00378   public:
00379     
00383     static void Apply ( const TLOB& Op, const TMVB& x, TMVB& y )
00384     { 
00385       Op.apply(Thyra::NONCONJ_ELE,x,&y);
00386     }
00387     
00388   };
00389   
00390 } // end of Belos namespace 
00391 
00392 #endif 
00393 // end of file BELOS_THYRA_ADAPTER_HPP

Generated on Wed Jul 22 13:20:34 2009 for Stratimikos by doxygen 1.5.8