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

Generated on Wed May 12 21:26:54 2010 for Thyra Operator/Vector Support by  doxygen 1.4.7