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::RefCountPtr<TMVB> Clone( const TMVB& mv, const int numvecs )
00077     { 
00078       Teuchos::RefCountPtr<TMVB> c = Thyra::createMembers( mv.range(), numvecs ); 
00079       return c;
00080     }
00081 
00086     static Teuchos::RefCountPtr<TMVB> CloneCopy( const TMVB& mv )
00087     { 
00088       int numvecs = mv.domain()->dim();
00089       // create the new multivector
00090       Teuchos::RefCountPtr< 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::RefCountPtr<TMVB> CloneCopy( const TMVB& mv, const std::vector<int>& index )
00102     { 
00103       int numvecs = index.size();
00104       // create the new multivector
00105       Teuchos::RefCountPtr< TMVB > cc = Thyra::createMembers( mv.range(), numvecs );
00106       // create a view to the relevant part of the source multivector
00107       Teuchos::RefCountPtr< 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::RefCountPtr<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 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 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::RefCountPtr< 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::RefCountPtr<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 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 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::RefCountPtr< 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::RefCountPtr< 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 MvTransMv( const ScalarType alpha, const TMVB& A, const TMVB& mv, 
00248                            Teuchos::SerialDenseMatrix<int,ScalarType>& B )
00249     { 
00250       // Create a multivector to hold the result (m by n)
00251       int m = A.domain()->dim();
00252       int n = mv.domain()->dim();
00253       // Create a view of the B object!
00254       Teuchos::RefCountPtr< TMVB >
00255         B_thyra = Thyra::createMembersView(
00256           A.domain()
00257           ,RTOpPack::SubMultiVectorView<ScalarType>(0,m,0,n,&B(0,0),B.stride())
00258           );
00259       A.applyTranspose(Thyra::CONJ_ELE,mv,&*B_thyra,alpha,Teuchos::ScalarTraits<ScalarType>::zero());
00260     }
00261 
00265     static void MvDot( const TMVB& mv, const TMVB& A, std::vector<ScalarType>* b )
00266     { Thyra::dots(mv,A,&((*b)[0])); }
00267 
00269 
00272 
00276     static void MvNorm( const TMVB& mv, std::vector<magType>* normvec, NormType type = TwoNorm )
00277     { Thyra::norms_2(mv,&((*normvec)[0])); }
00278 
00280 
00283 
00286     static void SetBlock( const TMVB& A, const std::vector<int>& index, TMVB& mv )
00287     { 
00288       // Extract the "numvecs" columns of mv indicated by the index vector.
00289       int numvecs = index.size();
00290       std::vector<int> indexA(numvecs);
00291       int numAcols = A.domain()->dim();
00292       for (int i=0; i<numvecs; i++) {
00293         indexA[i] = i;
00294       }
00295       // Thyra::assign requires that both arguments have the same number of 
00296       // vectors. Enforce this, by shrinking one to match the other.
00297       if ( numAcols < numvecs ) {
00298         // A does not have enough columns to satisfy index_plus. Shrink
00299         // index_plus.
00300         numvecs = numAcols;
00301       }
00302       else if ( numAcols > numvecs ) {
00303         numAcols = numvecs;
00304         indexA.resize( numAcols );
00305       }
00306       // create a view to the relevant part of the source multivector
00307       Teuchos::RefCountPtr< const TMVB > relsource = A.subView( numAcols, &(indexA[0]) );
00308       // create a view to the relevant part of the destination multivector
00309       Teuchos::RefCountPtr< TMVB > reldest = mv.subView( numvecs, &(index[0]) );
00310       // copy the data to the destination multivector subview
00311       Thyra::assign(&*reldest, *relsource);
00312     }
00313 
00316     static void MvRandom( TMVB& mv )
00317     { 
00318       // Thyra::randomize generates via a uniform distribution on [l,u]
00319       // We will use this to generate on [-1,1]
00320       Thyra::randomize(-Teuchos::ScalarTraits<ScalarType>::one(),
00321                         Teuchos::ScalarTraits<ScalarType>::one(),
00322                        &mv);
00323     }
00324 
00327     static void MvInit( TMVB& mv, ScalarType alpha = Teuchos::ScalarTraits<ScalarType>::zero() )
00328     { Thyra::assign(&mv,alpha); }
00329 
00331 
00334 
00337     static void MvPrint( const TMVB& mv, ostream& os )
00338       { os << describe(mv,Teuchos::VERB_EXTREME); }
00339 
00341 
00342   };        
00343 
00345   //
00346   // Implementation of the Belos::OperatorTraits for Thyra::LinearOpBase
00347   //
00349 
00358   template <class ScalarType> 
00359   class OperatorTraits < ScalarType, Thyra::MultiVectorBase<ScalarType>, Thyra::LinearOpBase<ScalarType> >
00360   {
00361   private:
00362     typedef Thyra::MultiVectorBase<ScalarType> TMVB;
00363     typedef Thyra::LinearOpBase<ScalarType>    TLOB;
00364   public:
00365     
00369     static ReturnType Apply ( const TLOB& Op, const TMVB& x, TMVB& y )
00370     { 
00371       Op.apply(Thyra::NONCONJ_ELE,x,&y);
00372       return Ok; 
00373     }
00374     
00375   };
00376   
00377 } // end of Belos namespace 
00378 
00379 #endif 
00380 // end of file BELOS_THYRA_ADAPTER_HPP

Generated on Thu Sep 18 12:30:21 2008 for Belos Package Browser (Single Doxygen Collection) by doxygen 1.3.9.1