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::RCP<const SpmdVectorSpaceBase<Scalar> >         &spmdRangeSpace
00100   ,const Teuchos::RCP<const ScalarProdVectorSpaceBase<Scalar> >  &domainSpace
00101   )
00102 {
00103   initialize(spmdRangeSpace,domainSpace);
00104 }
00105 
00106 template<class Scalar>
00107 DefaultSpmdMultiVector<Scalar>::DefaultSpmdMultiVector(
00108   const Teuchos::RCP<const SpmdVectorSpaceBase<Scalar> >         &spmdRangeSpace
00109   ,const Teuchos::RCP<const ScalarProdVectorSpaceBase<Scalar> >  &domainSpace
00110   ,const Teuchos::RCP<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::RCP<const SpmdVectorSpaceBase<Scalar> >         &spmdRangeSpace
00120   ,const Teuchos::RCP<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::RCP<const SpmdVectorSpaceBase<Scalar> >         &spmdRangeSpace
00139   ,const Teuchos::RCP<const ScalarProdVectorSpaceBase<Scalar> >  &domainSpace
00140   ,const Teuchos::RCP<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::RCP<const SpmdVectorSpaceBase<Scalar> >         *spmdRangeSpace
00160   ,Teuchos::RCP<const ScalarProdVectorSpaceBase<Scalar> >  *domainSpace
00161   ,Teuchos::RCP<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 EuclideanLinearOpBase
00179 
00180 template<class Scalar>
00181 Teuchos::RCP< const ScalarProdVectorSpaceBase<Scalar> >
00182 DefaultSpmdMultiVector<Scalar>::domainScalarProdVecSpc() const
00183 {
00184 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00185   std::cerr << "\nSpmdMultiVectorStd<Scalar>::domainScalarProdVecSpc() const called!\n";
00186 #endif
00187   return domainSpace_;
00188 }
00189 
00190 // Overridden from MultiVectorBase
00191 
00192 template<class Scalar>
00193 Teuchos::RCP<VectorBase<Scalar> >
00194 DefaultSpmdMultiVector<Scalar>::col(Index j)
00195 {
00196 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00197   std::cerr << "\nSpmdMultiVectorStd<Scalar>::col() called!\n";
00198 #endif
00199 #ifdef TEUCHOS_DEBUG
00200   TEST_FOR_EXCEPT( !( 0 <= j && j < this->domain()->dim() ) );
00201 #endif
00202   return Teuchos::rcp(
00203     new DefaultSpmdVector<Scalar>(
00204       spmdRangeSpace_
00205       ,Teuchos::rcp( (&*localValues_) + j*leadingDim_, false )
00206       ,1
00207       )
00208     );
00209   //return Teuchos::rcp(new DefaultVectorMultiVector<Scalar>(subView(Range1D(j,j))));
00210 }
00211 
00212 template<class Scalar>
00213 Teuchos::RCP<MultiVectorBase<Scalar> >
00214 DefaultSpmdMultiVector<Scalar>::subView( const Range1D& col_rng_in )
00215 {
00216 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00217   std::cerr << "\nSpmdMultiVectorStd<Scalar>::subView() called!\n";
00218 #endif
00219   const Range1D colRng = this->validateColRange(col_rng_in);
00220   return Teuchos::rcp(
00221     new DefaultSpmdMultiVector<Scalar>(
00222       spmdRangeSpace_
00223       ,Teuchos::rcp_dynamic_cast<const ScalarProdVectorSpaceBase<Scalar> >(
00224         spmdRangeSpace_->smallVecSpcFcty()->createVecSpc(colRng.size())
00225         ,true
00226         )
00227       ,Teuchos::rcp( (&*localValues_) + colRng.lbound()*leadingDim_, false )
00228       ,leadingDim_
00229       )
00230     );
00231 }
00232 
00233 template<class Scalar>
00234 Teuchos::RCP<const MultiVectorBase<Scalar> >
00235 DefaultSpmdMultiVector<Scalar>::subView( const int numCols, const int cols[] ) const
00236 {
00237   Teuchos::RCP<Scalar> localValuesView = createContiguousCopy(numCols,cols);
00238   return 
00239     Teuchos::rcp(
00240       new DefaultSpmdMultiVector<Scalar>(
00241         spmdRangeSpace_
00242         ,Teuchos::rcp_dynamic_cast<const ScalarProdVectorSpaceBase<Scalar> >(
00243           spmdRangeSpace_->smallVecSpcFcty()->createVecSpc(numCols)
00244           ,true)
00245         ,localValuesView
00246         ,spmdRangeSpace_->localSubDim()
00247         )
00248       );
00249 }
00250 
00251 template<class Scalar>
00252 Teuchos::RCP<MultiVectorBase<Scalar> >
00253 DefaultSpmdMultiVector<Scalar>::subView( const int numCols, const int cols[] )
00254 {
00255   Teuchos::RCP<Scalar> localValuesView = createContiguousCopy(numCols,cols);
00256   const Index localSubDim = spmdRangeSpace_->localSubDim();
00257   Teuchos::RCP<MultiVectorBase<Scalar> >
00258     view = Teuchos::rcp(
00259       new DefaultSpmdMultiVector<Scalar>(
00260         spmdRangeSpace_
00261         ,Teuchos::rcp_dynamic_cast<const ScalarProdVectorSpaceBase<Scalar> >(
00262           spmdRangeSpace_->smallVecSpcFcty()->createVecSpc(numCols)
00263           ,true)
00264         ,localValuesView
00265         ,localSubDim
00266         )
00267       );
00268   Teuchos::RCP<CopyBackSpmdMultiVectorEntries<Scalar> >
00269     copyBackView
00270     = Teuchos::rcp(
00271       new CopyBackSpmdMultiVectorEntries<Scalar>(
00272         numCols,cols,&*localValuesView,localSubDim,&*localValues_,leadingDim_
00273         )
00274       );
00275   Teuchos::set_extra_data(copyBackView,"copyBackView",&view,Teuchos::PRE_DESTROY);
00276   return view;
00277 }
00278 
00279 // Overridden from SpmdMultiVectorBase
00280 
00281 template<class Scalar>
00282 Teuchos::RCP<const SpmdVectorSpaceBase<Scalar> >
00283 DefaultSpmdMultiVector<Scalar>::spmdSpace() const
00284 {
00285 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00286   std::cerr << "\nSpmdMultiVectorStd<Scalar>::spmdSpace() const called!\n";
00287 #endif
00288   return spmdRangeSpace_;
00289 }
00290 
00291 template<class Scalar>
00292 void DefaultSpmdMultiVector<Scalar>::getLocalData(
00293   Scalar **localValues, Index *leadingDim
00294   )
00295 {
00296 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00297   std::cerr << "\nSpmdMultiVectorStd<Scalar>::getLocalData() called!\n";
00298 #endif
00299 #ifdef TEUCHOS_DEBUG
00300   TEST_FOR_EXCEPT( localValues==NULL );
00301   TEST_FOR_EXCEPT( leadingDim==NULL );
00302 #endif
00303   *localValues = &*localValues_;
00304   *leadingDim  = leadingDim_;
00305 }
00306 
00307 template<class Scalar>
00308 void DefaultSpmdMultiVector<Scalar>::commitLocalData( Scalar *localValues )
00309 {
00310 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00311   std::cerr << "\nSpmdMultiVectorStd<Scalar>::commitLocalData() called!\n";
00312 #endif
00313 #ifdef TEUCHOS_DEBUG
00314   TEST_FOR_EXCEPT( localValues!=&*localValues_ );
00315 #endif
00316   // Nothing to commit!
00317 }
00318 
00319 template<class Scalar>
00320 void DefaultSpmdMultiVector<Scalar>::getLocalData(
00321   const Scalar **localValues, Index *leadingDim
00322   ) const
00323 {
00324 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00325   std::cerr << "\nSpmdMultiVectorStd<Scalar>::getLocalData() called!\n";
00326 #endif
00327 #ifdef TEUCHOS_DEBUG
00328   TEST_FOR_EXCEPT( localValues==NULL );
00329   TEST_FOR_EXCEPT( leadingDim==NULL );
00330 #endif
00331   *localValues = &*localValues_;
00332   *leadingDim  = leadingDim_;
00333 }
00334 
00335 template<class Scalar>
00336 void DefaultSpmdMultiVector<Scalar>::freeLocalData( const Scalar *localValues ) const
00337 {
00338 #ifdef TEUCHOS_DEBUG
00339   TEST_FOR_EXCEPT( localValues!=&*localValues_ );
00340 #endif
00341 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00342   std::cerr << "\nSpmdMultiVectorStd<Scalar>::commitLocalData() called!\n";
00343 #endif
00344   // Nothing to free
00345 }
00346 
00347 // private
00348 
00349 template<class Scalar>
00350 Teuchos::RCP<Scalar>
00351 DefaultSpmdMultiVector<Scalar>::createContiguousCopy(
00352   const int numCols, const int cols[]
00353   ) const
00354 {
00355 #ifdef TEUCHOS_DEBUG
00356   const VectorSpaceBase<Scalar>  &domain   = *domainSpace_;
00357   const Index                    dimDomain = domain.dim();
00358   const char msg_err[] = "MultiVectorDefaultBase<Scalar>::subView(numCols,cols[]): Error!";
00359   TEST_FOR_EXCEPTION( numCols < 1 || dimDomain < numCols, std::invalid_argument, msg_err );
00360 #endif
00361   const Index localSubDim = spmdRangeSpace_->localSubDim();
00362   Teuchos::RCP<Scalar>
00363     localValuesView
00364     = Teuchos::rcp(
00365       new Scalar[numCols*localSubDim], Teuchos::DeallocArrayDelete<Scalar>(), true
00366       );
00367   // Copy to contiguous storage
00368   const Scalar *lv   = &*localValues_;
00369   Scalar       *lvv  = &*localValuesView;
00370   for( int k = 0; k < numCols; ++k ) {
00371     const int col_k = cols[k];
00372 #ifdef TEUCHOS_DEBUG
00373     TEST_FOR_EXCEPTION(
00374       !( 0<= col_k && col_k < dimDomain ), std::invalid_argument
00375       ,msg_err << " col["<<k<<"] = " << col_k
00376       << " is not in the range [0,"<<(dimDomain-1)<<"]!"
00377       );
00378 #endif
00379     const Scalar *lv_k   = lv + leadingDim_*col_k;
00380     Scalar       *lvv_k  = lvv + localSubDim*k;
00381     std::copy( lv_k, lv_k + localSubDim, lvv_k );
00382   }
00383   return localValuesView;
00384 }
00385 
00386 } // end namespace Thyra
00387 
00388 #endif // THYRA_DEFAULT_SPMD_MULTI_VECTOR_BASE_HPP

Generated on Tue Oct 20 12:46:58 2009 for Thyra Operator/Vector Support by doxygen 1.4.7