Thyra_DefaultSpmdMultiVector.hpp

00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //    Thyra: Interfaces and Support for Abstract Numerical Algorithms
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 
00029 #ifndef THYRA_DEFAULT_SPMD_MULTI_VECTOR_BASE_HPP
00030 #define THYRA_DEFAULT_SPMD_MULTI_VECTOR_BASE_HPP
00031 
00032 // Define to make some verbose output
00033 //#define THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00034 
00035 #include "Thyra_DefaultSpmdMultiVectorDecl.hpp"
00036 #include "Thyra_SpmdMultiVectorBase.hpp"
00037 #include "Thyra_DefaultSpmdVector.hpp"
00038 
00039 namespace Thyra {
00040 
00041 //
00042 // Simple utility class to copy back multi-vector entries
00043 //
00044 
00045 template<class Scalar>
00046 class CopyBackSpmdMultiVectorEntries {
00047 public:
00048   CopyBackSpmdMultiVectorEntries(
00049     const int numCols, const int cols[]
00050     ,const Scalar *localValuesView, const Index localSubDim
00051     ,Scalar *localValues,const Index leadingDim
00052     )
00053     :cols_(cols,cols+numCols)
00054     ,localValuesView_(localValuesView),localSubDim_(localSubDim)
00055     ,localValues_(localValues),leadingDim_(leadingDim)
00056     {}
00057   ~CopyBackSpmdMultiVectorEntries()
00058     {
00059       //std::cout << "\nEntering CopyBackSpmdMultiVectorEntries::~CopyBackSpmdMultiVectorEntries()...\n";
00060       // Copy from contiguous storage
00061       const int    numCols = cols_.size();
00062       const Scalar *lvv    = &*localValuesView_;
00063       Scalar       *lv     = &*localValues_;
00064       for( int k = 0; k < numCols; ++k ) {
00065         const int col_k = cols_[k];
00066         const Scalar *lvv_k  = lvv + localSubDim_*k;
00067         Scalar       *lv_k   = lv + leadingDim_*col_k;
00068         //std::cout << "\nlvv_k = ["; for( int j = 0; j < localSubDim_; ++j ) std::cout << lvv_k[j] << ","; std::cout << "]\n";
00069         std::copy( lvv_k, lvv_k + localSubDim_, lv_k );
00070         //std::cout << "\nlv_k = ["; for( int j = 0; j < localSubDim_; ++j ) std::cout << lv_k[j] << ","; std::cout << "]\n";
00071       }
00072       //std::cout << "\nLeaving CopyBackSpmdMultiVectorEntries::~CopyBackSpmdMultiVectorEntries()\n";
00073     }
00074 private:
00075   std::vector<int>   cols_;
00076   const Scalar       *localValuesView_;
00077   Index              localSubDim_;
00078   Scalar             *localValues_;
00079   Index              leadingDim_;
00080   // Not defined and not to be called
00081   CopyBackSpmdMultiVectorEntries();
00082   CopyBackSpmdMultiVectorEntries(const CopyBackSpmdMultiVectorEntries&);
00083   CopyBackSpmdMultiVectorEntries& operator=(const CopyBackSpmdMultiVectorEntries&);
00084 };
00085 
00086 //
00087 // DefaultSpmdMultiVector
00088 //
00089 
00090 // Constructors/initializers/accessors
00091 
00092 template<class Scalar>
00093 DefaultSpmdMultiVector<Scalar>::DefaultSpmdMultiVector()
00094   :leadingDim_(0)
00095 {}
00096 
00097 template<class Scalar>
00098 DefaultSpmdMultiVector<Scalar>::DefaultSpmdMultiVector(
00099   const Teuchos::RefCountPtr<const SpmdVectorSpaceBase<Scalar> >         &spmdRangeSpace
00100   ,const Teuchos::RefCountPtr<const ScalarProdVectorSpaceBase<Scalar> >  &domainSpace
00101   )
00102 {
00103   initialize(spmdRangeSpace,domainSpace);
00104 }
00105 
00106 template<class Scalar>
00107 DefaultSpmdMultiVector<Scalar>::DefaultSpmdMultiVector(
00108   const Teuchos::RefCountPtr<const SpmdVectorSpaceBase<Scalar> >         &spmdRangeSpace
00109   ,const Teuchos::RefCountPtr<const ScalarProdVectorSpaceBase<Scalar> >  &domainSpace
00110   ,const Teuchos::RefCountPtr<Scalar>                                    &localValues
00111   ,const Index                                                           leadingDim
00112   )
00113 {
00114   initialize(spmdRangeSpace,domainSpace,localValues,leadingDim);
00115 }
00116 
00117 template<class Scalar>
00118 void DefaultSpmdMultiVector<Scalar>::initialize(
00119   const Teuchos::RefCountPtr<const SpmdVectorSpaceBase<Scalar> >         &spmdRangeSpace
00120   ,const Teuchos::RefCountPtr<const ScalarProdVectorSpaceBase<Scalar> >  &domainSpace
00121   )
00122 {
00123   const Index localSubDim = spmdRangeSpace->localSubDim();
00124   initialize(
00125     spmdRangeSpace
00126     ,domainSpace
00127     ,Teuchos::rcp(
00128       localSubDim ? new Scalar[localSubDim*domainSpace->dim()] : 0
00129       ,Teuchos::DeallocArrayDelete<Scalar>()
00130       ,true
00131       )
00132     ,localSubDim
00133     );
00134 }
00135 
00136 template<class Scalar>
00137 void DefaultSpmdMultiVector<Scalar>::initialize(
00138   const Teuchos::RefCountPtr<const SpmdVectorSpaceBase<Scalar> >         &spmdRangeSpace
00139   ,const Teuchos::RefCountPtr<const ScalarProdVectorSpaceBase<Scalar> >  &domainSpace
00140   ,const Teuchos::RefCountPtr<Scalar>                                    &localValues
00141   ,const Index                                                           leadingDim
00142   )
00143 {
00144 #ifdef TEUCHOS_DEBUG
00145   TEST_FOR_EXCEPT(spmdRangeSpace.get()==NULL);
00146   TEST_FOR_EXCEPT(domainSpace.get()==NULL);
00147   TEST_FOR_EXCEPT(localValues.get()==NULL);
00148   TEST_FOR_EXCEPT(leadingDim < spmdRangeSpace->localSubDim());
00149 #endif
00150   spmdRangeSpace_ = spmdRangeSpace;
00151   domainSpace_   = domainSpace;
00152   localValues_   = localValues;
00153   leadingDim_    = leadingDim;
00154   this->updateSpmdSpace();
00155 }
00156 
00157 template<class Scalar>
00158 void DefaultSpmdMultiVector<Scalar>::uninitialize(
00159   Teuchos::RefCountPtr<const SpmdVectorSpaceBase<Scalar> >         *spmdRangeSpace
00160   ,Teuchos::RefCountPtr<const ScalarProdVectorSpaceBase<Scalar> >  *domainSpace
00161   ,Teuchos::RefCountPtr<Scalar>                                    *localValues
00162   ,Index                                                           *leadingDim
00163   )
00164 {
00165   if(spmdRangeSpace) *spmdRangeSpace = spmdRangeSpace_;
00166   if(domainSpace)   *domainSpace   = domainSpace_;
00167   if(localValues)   *localValues   = localValues_;
00168   if(leadingDim)    *leadingDim    = leadingDim_;
00169 
00170   spmdRangeSpace_  = Teuchos::null;
00171   domainSpace_    = Teuchos::null;
00172   localValues_    = Teuchos::null;
00173   leadingDim_     = 0;
00174 
00175   this->updateSpmdSpace();
00176 }
00177 
00178 // Overridden from Teuchos::Describable
00179 
00180 template<class Scalar>
00181 std::string DefaultSpmdMultiVector<Scalar>::description() const
00182 {
00183   std::ostringstream oss;
00184   oss<<"DefaultSpmdMultiVector<"<<Teuchos::ScalarTraits<Scalar>::name()<<">";
00185   return oss.str();
00186 }
00187 
00188 // Overridden from EuclideanLinearOpBase
00189 
00190 template<class Scalar>
00191 Teuchos::RefCountPtr< const ScalarProdVectorSpaceBase<Scalar> >
00192 DefaultSpmdMultiVector<Scalar>::domainScalarProdVecSpc() const
00193 {
00194 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00195   std::cerr << "\nSpmdMultiVectorStd<Scalar>::domainScalarProdVecSpc() const called!\n";
00196 #endif
00197   return domainSpace_;
00198 }
00199 
00200 // Overridden from MultiVectorBase
00201 
00202 template<class Scalar>
00203 Teuchos::RefCountPtr<VectorBase<Scalar> >
00204 DefaultSpmdMultiVector<Scalar>::col(Index j)
00205 {
00206 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00207   std::cerr << "\nSpmdMultiVectorStd<Scalar>::col() called!\n";
00208 #endif
00209 #ifdef TEUCHOS_DEBUG
00210   TEST_FOR_EXCEPT( !( 0 <= j && j < this->domain()->dim() ) );
00211 #endif
00212   return Teuchos::rcp(
00213     new DefaultSpmdVector<Scalar>(
00214       spmdRangeSpace_
00215       ,Teuchos::rcp( (&*localValues_) + j*leadingDim_, false )
00216       ,1
00217       )
00218     );
00219   //return Teuchos::rcp(new DefaultVectorMultiVector<Scalar>(subView(Range1D(j,j))));
00220 }
00221 
00222 template<class Scalar>
00223 Teuchos::RefCountPtr<MultiVectorBase<Scalar> >
00224 DefaultSpmdMultiVector<Scalar>::subView( const Range1D& col_rng_in )
00225 {
00226 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00227   std::cerr << "\nSpmdMultiVectorStd<Scalar>::subView() called!\n";
00228 #endif
00229   const Range1D colRng = this->validateColRange(col_rng_in);
00230   return Teuchos::rcp(
00231     new DefaultSpmdMultiVector<Scalar>(
00232       spmdRangeSpace_
00233       ,Teuchos::rcp_dynamic_cast<const ScalarProdVectorSpaceBase<Scalar> >(
00234         spmdRangeSpace_->smallVecSpcFcty()->createVecSpc(colRng.size())
00235         ,true
00236         )
00237       ,Teuchos::rcp( (&*localValues_) + colRng.lbound()*leadingDim_, false )
00238       ,leadingDim_
00239       )
00240     );
00241 }
00242 
00243 template<class Scalar>
00244 Teuchos::RefCountPtr<const MultiVectorBase<Scalar> >
00245 DefaultSpmdMultiVector<Scalar>::subView( const int numCols, const int cols[] ) const
00246 {
00247   Teuchos::RefCountPtr<Scalar> localValuesView = createContiguousCopy(numCols,cols);
00248   return 
00249     Teuchos::rcp(
00250       new DefaultSpmdMultiVector<Scalar>(
00251         spmdRangeSpace_
00252         ,Teuchos::rcp_dynamic_cast<const ScalarProdVectorSpaceBase<Scalar> >(
00253           spmdRangeSpace_->smallVecSpcFcty()->createVecSpc(numCols)
00254           ,true)
00255         ,localValuesView
00256         ,spmdRangeSpace_->localSubDim()
00257         )
00258       );
00259 }
00260 
00261 template<class Scalar>
00262 Teuchos::RefCountPtr<MultiVectorBase<Scalar> >
00263 DefaultSpmdMultiVector<Scalar>::subView( const int numCols, const int cols[] )
00264 {
00265   Teuchos::RefCountPtr<Scalar> localValuesView = createContiguousCopy(numCols,cols);
00266   const Index localSubDim = spmdRangeSpace_->localSubDim();
00267   Teuchos::RefCountPtr<MultiVectorBase<Scalar> >
00268     view = Teuchos::rcp(
00269       new DefaultSpmdMultiVector<Scalar>(
00270         spmdRangeSpace_
00271         ,Teuchos::rcp_dynamic_cast<const ScalarProdVectorSpaceBase<Scalar> >(
00272           spmdRangeSpace_->smallVecSpcFcty()->createVecSpc(numCols)
00273           ,true)
00274         ,localValuesView
00275         ,localSubDim
00276         )
00277       );
00278   Teuchos::RefCountPtr<CopyBackSpmdMultiVectorEntries<Scalar> >
00279     copyBackView
00280     = Teuchos::rcp(
00281       new CopyBackSpmdMultiVectorEntries<Scalar>(
00282         numCols,cols,&*localValuesView,localSubDim,&*localValues_,leadingDim_
00283         )
00284       );
00285   Teuchos::set_extra_data(copyBackView,"copyBackView",&view,Teuchos::PRE_DESTROY);
00286   return view;
00287 }
00288 
00289 // Overridden from SpmdMultiVectorBase
00290 
00291 template<class Scalar>
00292 Teuchos::RefCountPtr<const SpmdVectorSpaceBase<Scalar> >
00293 DefaultSpmdMultiVector<Scalar>::spmdSpace() const
00294 {
00295 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00296   std::cerr << "\nSpmdMultiVectorStd<Scalar>::spmdSpace() const called!\n";
00297 #endif
00298   return spmdRangeSpace_;
00299 }
00300 
00301 template<class Scalar>
00302 void DefaultSpmdMultiVector<Scalar>::getLocalData(
00303   Scalar **localValues, Index *leadingDim
00304   )
00305 {
00306 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00307   std::cerr << "\nSpmdMultiVectorStd<Scalar>::getLocalData() called!\n";
00308 #endif
00309 #ifdef TEUCHOS_DEBUG
00310   TEST_FOR_EXCEPT( localValues==NULL );
00311   TEST_FOR_EXCEPT( leadingDim==NULL );
00312 #endif
00313   *localValues = &*localValues_;
00314   *leadingDim  = leadingDim_;
00315 }
00316 
00317 template<class Scalar>
00318 void DefaultSpmdMultiVector<Scalar>::commitLocalData( Scalar *localValues )
00319 {
00320 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00321   std::cerr << "\nSpmdMultiVectorStd<Scalar>::commitLocalData() called!\n";
00322 #endif
00323 #ifdef TEUCHOS_DEBUG
00324   TEST_FOR_EXCEPT( localValues!=&*localValues_ );
00325 #endif
00326   // Nothing to commit!
00327 }
00328 
00329 template<class Scalar>
00330 void DefaultSpmdMultiVector<Scalar>::getLocalData(
00331   const Scalar **localValues, Index *leadingDim
00332   ) const
00333 {
00334 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00335   std::cerr << "\nSpmdMultiVectorStd<Scalar>::getLocalData() called!\n";
00336 #endif
00337 #ifdef TEUCHOS_DEBUG
00338   TEST_FOR_EXCEPT( localValues==NULL );
00339   TEST_FOR_EXCEPT( leadingDim==NULL );
00340 #endif
00341   *localValues = &*localValues_;
00342   *leadingDim  = leadingDim_;
00343 }
00344 
00345 template<class Scalar>
00346 void DefaultSpmdMultiVector<Scalar>::freeLocalData( const Scalar *localValues ) const
00347 {
00348 #ifdef TEUCHOS_DEBUG
00349   TEST_FOR_EXCEPT( localValues!=&*localValues_ );
00350 #endif
00351 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00352   std::cerr << "\nSpmdMultiVectorStd<Scalar>::commitLocalData() called!\n";
00353 #endif
00354   // Nothing to free
00355 }
00356 
00357 // private
00358 
00359 template<class Scalar>
00360 Teuchos::RefCountPtr<Scalar>
00361 DefaultSpmdMultiVector<Scalar>::createContiguousCopy(
00362   const int numCols, const int cols[]
00363   ) const
00364 {
00365 #ifdef TEUCHOS_DEBUG
00366   const VectorSpaceBase<Scalar>  &domain   = *domainSpace_;
00367   const Index                    dimDomain = domain.dim();
00368   const char msg_err[] = "MultiVectorDefaultBase<Scalar>::subView(numCols,cols[]): Error!";
00369   TEST_FOR_EXCEPTION( numCols < 1 || dimDomain < numCols, std::invalid_argument, msg_err );
00370 #endif
00371   const Index localSubDim = spmdRangeSpace_->localSubDim();
00372   Teuchos::RefCountPtr<Scalar>
00373     localValuesView
00374     = Teuchos::rcp(
00375       new Scalar[numCols*localSubDim], Teuchos::DeallocArrayDelete<Scalar>(), true
00376       );
00377   // Copy to contiguous storage
00378   const Scalar *lv   = &*localValues_;
00379   Scalar       *lvv  = &*localValuesView;
00380   for( int k = 0; k < numCols; ++k ) {
00381     const int col_k = cols[k];
00382 #ifdef TEUCHOS_DEBUG
00383     TEST_FOR_EXCEPTION(
00384       !( 0<= col_k && col_k < dimDomain ), std::invalid_argument
00385       ,msg_err << " col["<<k<<"] = " << col_k
00386       << " is not in the range [0,"<<(dimDomain-1)<<"]!"
00387       );
00388 #endif
00389     const Scalar *lv_k   = lv + leadingDim_*col_k;
00390     Scalar       *lvv_k  = lvv + localSubDim*k;
00391     std::copy( lv_k, lv_k + localSubDim, lvv_k );
00392   }
00393   return localValuesView;
00394 }
00395 
00396 } // end namespace Thyra
00397 
00398 #endif // THYRA_DEFAULT_SPMD_MULTI_VECTOR_BASE_HPP

Generated on Thu Sep 18 12:32:31 2008 for Thyra Operator/Vector Support by doxygen 1.3.9.1