Thyra Package Browser (Single Doxygen Collection) Version of the Day
Thyra_DefaultSpmdMultiVector_def.hpp
Go to the documentation of this file.
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_DEF_HPP
00030 #define THYRA_DEFAULT_SPMD_MULTI_VECTOR_DEF_HPP
00031 
00032 // Define to make some verbose output
00033 //#define THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00034 
00035 #include "Thyra_DefaultSpmdMultiVector_decl.hpp"
00036 #include "Thyra_SpmdMultiVectorBase.hpp"
00037 #include "Thyra_VectorSpaceFactoryBase.hpp"
00038 #include "Thyra_DefaultSpmdVector.hpp"
00039 #include "Teuchos_Assert.hpp"
00040 
00041 
00042 namespace Thyra {
00043 
00044 
00045 //
00046 // Simple utility class to copy back multi-vector entries
00047 //
00048 // ToDo: Refactor above to not use raw pointers!
00049 //
00050 template<class Scalar>
00051 class CopyBackSpmdMultiVectorEntries {
00052 public:
00053   CopyBackSpmdMultiVectorEntries(
00054     const ArrayView<const int> &cols,
00055     const ArrayRCP<const Scalar> &localValuesView, const Ordinal localSubDim,
00056     const ArrayRCP<Scalar> &localValues, const Ordinal leadingDim
00057     )
00058     : cols_(cols), localValuesView_(localValuesView), localSubDim_(localSubDim),
00059       localValues_(localValues), leadingDim_(leadingDim)
00060     {}
00061   ~CopyBackSpmdMultiVectorEntries()
00062     {
00063       typedef typename ArrayRCP<const Scalar>::const_iterator const_itr_t;
00064       typedef typename ArrayRCP<Scalar>::iterator itr_t;
00065       // Copy from contiguous storage column by column
00066       if (localValues_.strong_count()) {
00067         const int numCols = cols_.size();
00068         const const_itr_t lvv = localValuesView_.begin();
00069         const itr_t lv = localValues_.begin();
00070         for (int k = 0; k < numCols; ++k) {
00071           const int col_k = cols_[k];
00072           const const_itr_t lvv_k = lvv + localSubDim_*k;
00073           const itr_t lv_k = lv + leadingDim_*col_k;
00074           std::copy( lvv_k, lvv_k + localSubDim_, lv_k );
00075         }
00076       }
00077 #ifdef THYRA_DEBUG
00078       else {
00079         ++DefaultSpmdMultiVector<Scalar>::numSkipCopyBack;
00080       }
00081 #endif // THYRA_DEBUG
00082     }
00083 private:
00084   Array<int> cols_;
00085   ArrayRCP<const Scalar> localValuesView_;
00086   Ordinal localSubDim_;
00087   ArrayRCP<Scalar> localValues_;
00088   Ordinal leadingDim_;
00089   // Not defined and not to be called
00090   CopyBackSpmdMultiVectorEntries();
00091   CopyBackSpmdMultiVectorEntries(const CopyBackSpmdMultiVectorEntries&);
00092   CopyBackSpmdMultiVectorEntries& operator=(const CopyBackSpmdMultiVectorEntries&);
00093 };
00094 
00095 
00096 template<class Scalar>
00097 RCP<CopyBackSpmdMultiVectorEntries<Scalar> >
00098 copyBackSpmdMultiVectorEntries(
00099   const ArrayView<const int> &cols,
00100   const ArrayRCP<const Scalar> &localValuesView, const Ordinal localSubDim,
00101   const ArrayRCP<Scalar> &localValues, const Ordinal leadingDim
00102   )
00103 {
00104   return Teuchos::rcp(
00105     new CopyBackSpmdMultiVectorEntries<Scalar>(
00106       cols, localValuesView, localSubDim, localValues, leadingDim
00107       )
00108     );
00109 }
00110 
00111 
00112 //
00113 // DefaultSpmdMultiVector
00114 //
00115 
00116 
00117 #ifdef THYRA_DEBUG
00118 template<class Scalar>
00119 int DefaultSpmdMultiVector<Scalar>::numSkipCopyBack(0);
00120 #endif
00121 
00122 
00123 // Constructors/initializers/accessors
00124 
00125 
00126 template<class Scalar>
00127 DefaultSpmdMultiVector<Scalar>::DefaultSpmdMultiVector()
00128   :leadingDim_(0)
00129 {}
00130 
00131 
00132 template<class Scalar>
00133 DefaultSpmdMultiVector<Scalar>::DefaultSpmdMultiVector(
00134   const RCP<const SpmdVectorSpaceBase<Scalar> > &spmdRangeSpace
00135   ,const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace
00136   )
00137 {
00138   initialize(spmdRangeSpace,domainSpace);
00139 }
00140 
00141 
00142 template<class Scalar>
00143 DefaultSpmdMultiVector<Scalar>::DefaultSpmdMultiVector(
00144   const RCP<const SpmdVectorSpaceBase<Scalar> > &spmdRangeSpace
00145   ,const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace
00146   ,const ArrayRCP<Scalar> &localValues
00147   ,const Ordinal leadingDim
00148   )
00149 {
00150   initialize(spmdRangeSpace,domainSpace,localValues,leadingDim);
00151 }
00152 
00153 
00154 template<class Scalar>
00155 void DefaultSpmdMultiVector<Scalar>::initialize(
00156   const RCP<const SpmdVectorSpaceBase<Scalar> > &spmdRangeSpace
00157   ,const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace
00158   )
00159 {
00160   const Ordinal localSubDim = spmdRangeSpace->localSubDim();
00161   ArrayRCP<Scalar> values;
00162   if (localSubDim)
00163     values = Teuchos::arcp<Scalar>(localSubDim * domainSpace->dim());
00164   initialize(spmdRangeSpace, domainSpace, values, localSubDim);
00165 }
00166 
00167 
00168 template<class Scalar>
00169 void DefaultSpmdMultiVector<Scalar>::initialize(
00170   const RCP<const SpmdVectorSpaceBase<Scalar> > &spmdRangeSpace,
00171   const RCP<const ScalarProdVectorSpaceBase<Scalar> > &domainSpace,
00172   const ArrayRCP<Scalar> &localValues,
00173   const Ordinal leadingDim_in
00174   )
00175 {
00176   const Ordinal leadingDim =
00177     (leadingDim_in >= 0 ? leadingDim_in : spmdRangeSpace->localSubDim());
00178 #ifdef TEUCHOS_DEBUG
00179   TEUCHOS_ASSERT(!is_null(spmdRangeSpace));
00180   TEUCHOS_ASSERT(!is_null(domainSpace));
00181   if (spmdRangeSpace->dim()) {
00182     TEUCHOS_ASSERT(!is_null(localValues));
00183   }
00184   TEUCHOS_ASSERT_INEQUALITY(leadingDim, >=, spmdRangeSpace->localSubDim());
00185 #endif
00186   spmdRangeSpace_ = spmdRangeSpace;
00187   domainSpace_ = domainSpace;
00188   localValues_ = localValues;
00189   leadingDim_ = leadingDim;
00190   this->updateSpmdSpace();
00191 }
00192 
00193 
00194 template<class Scalar>
00195 void DefaultSpmdMultiVector<Scalar>::uninitialize(
00196   RCP<const SpmdVectorSpaceBase<Scalar> > *spmdRangeSpace
00197   ,RCP<const ScalarProdVectorSpaceBase<Scalar> > *domainSpace
00198   ,ArrayRCP<Scalar> *localValues
00199   ,Ordinal *leadingDim
00200   )
00201 {
00202   if(spmdRangeSpace) *spmdRangeSpace = spmdRangeSpace_;
00203   if(domainSpace) *domainSpace = domainSpace_;
00204   if(localValues) *localValues = localValues_;
00205   if(leadingDim) *leadingDim = leadingDim_;
00206 
00207   spmdRangeSpace_ = Teuchos::null;
00208   domainSpace_ = Teuchos::null;
00209   localValues_ = Teuchos::null;
00210   leadingDim_ = 0;
00211 
00212   this->updateSpmdSpace();
00213 }
00214 
00215 
00216 template<class Scalar>
00217 RCP< const ScalarProdVectorSpaceBase<Scalar> >
00218 DefaultSpmdMultiVector<Scalar>::domainScalarProdVecSpc() const
00219 {
00220 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00221   std::cerr << "\nSpmdMultiVectorStd<Scalar>::domainScalarProdVecSpc() const called!\n";
00222 #endif
00223   return domainSpace_;
00224 }
00225 
00226 
00227 // Overridden public functions from SpmdMultiVectorBase
00228 
00229 
00230 template<class Scalar>
00231 RCP<const SpmdVectorSpaceBase<Scalar> >
00232 DefaultSpmdMultiVector<Scalar>::spmdSpace() const
00233 {
00234 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00235   std::cerr << "\nSpmdMultiVectorStd<Scalar>::spmdSpace() const called!\n";
00236 #endif
00237   return spmdRangeSpace_;
00238 }
00239 
00240 
00241 // Overridden protected functions from MultiVectorBase
00242 
00243 
00244 template<class Scalar>
00245 RCP<VectorBase<Scalar> >
00246 DefaultSpmdMultiVector<Scalar>::nonconstColImpl(Ordinal j)
00247 {
00248 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00249   std::cerr << "\nSpmdMultiVectorStd<Scalar>::col() called!\n";
00250 #endif
00251 #ifdef TEUCHOS_DEBUG
00252   TEST_FOR_EXCEPT( !( 0 <= j && j < this->domain()->dim() ) );
00253 #endif
00254   return Teuchos::rcp(
00255     new DefaultSpmdVector<Scalar>(
00256       spmdRangeSpace_,
00257       localValues_.persistingView(j*leadingDim_,spmdRangeSpace_->localSubDim()),
00258       1
00259       )
00260     );
00261   //return Teuchos::rcp(new DefaultVectorMultiVector<Scalar>(subView(Range1D(j,j))));
00262 }
00263 
00264 
00265 template<class Scalar>
00266 RCP<const MultiVectorBase<Scalar> >
00267 DefaultSpmdMultiVector<Scalar>::contigSubViewImpl(
00268   const Range1D& col_rng_in
00269   ) const
00270 {
00271   const Range1D colRng = this->validateColRange(col_rng_in);
00272   return Teuchos::rcp(
00273     new DefaultSpmdMultiVector<Scalar>(
00274       spmdRangeSpace_,
00275       Teuchos::rcp_dynamic_cast<const ScalarProdVectorSpaceBase<Scalar> >(
00276         spmdRangeSpace_->smallVecSpcFcty()->createVecSpc(colRng.size())
00277         ,true
00278         ),
00279       localValues_.persistingView(colRng.lbound()*leadingDim_,colRng.size()*spmdRangeSpace_->localSubDim()),
00280       leadingDim_
00281       )
00282     );
00283 }
00284 
00285 
00286 template<class Scalar>
00287 RCP<MultiVectorBase<Scalar> >
00288 DefaultSpmdMultiVector<Scalar>::nonconstContigSubViewImpl(
00289   const Range1D& col_rng_in
00290   )
00291 {
00292   return Teuchos::rcp_const_cast<MultiVectorBase<Scalar> >(
00293     this->contigSubViewImpl(col_rng_in));
00294   // Have the nonconst version call the const version.  Note that in this case
00295   // we just need to take the const off of the returned MultiVectorBase object
00296   // because the localValues is already handled as nonconst.  This is the
00297   // perfect instance where the advice in Item 3 in "Effective C++ 3rd
00298   // edition" where Scott Meyers recommends having the nonconst version call
00299   // the const version.
00300 }
00301 
00302 
00303 template<class Scalar>
00304 RCP<const MultiVectorBase<Scalar> >
00305 DefaultSpmdMultiVector<Scalar>::nonContigSubViewImpl(
00306   const ArrayView<const int> &cols
00307   ) const
00308 {
00309   THYRA_DEBUG_ASSERT_MV_COLS("nonContigSubViewImpl(cols)", cols);
00310   const int numCols = cols.size();
00311   const ArrayRCP<Scalar> localValuesView = createContiguousCopy(cols);
00312   return defaultSpmdMultiVector<Scalar>(
00313     spmdRangeSpace_,
00314     createSmallScalarProdVectorSpaceBase<Scalar>(spmdRangeSpace_, numCols),
00315     localValuesView
00316     );
00317 }
00318 
00319 
00320 template<class Scalar>
00321 RCP<MultiVectorBase<Scalar> >
00322 DefaultSpmdMultiVector<Scalar>::nonconstNonContigSubViewImpl(
00323   const ArrayView<const int> &cols )
00324 {
00325   THYRA_DEBUG_ASSERT_MV_COLS("nonContigSubViewImpl(cols)", cols);
00326   const int numCols = cols.size();
00327   const ArrayRCP<Scalar> localValuesView = createContiguousCopy(cols);
00328   const Ordinal localSubDim = spmdRangeSpace_->localSubDim();
00329   RCP<CopyBackSpmdMultiVectorEntries<Scalar> > copyBackView =
00330     copyBackSpmdMultiVectorEntries<Scalar>(cols, localValuesView.getConst(),
00331       localSubDim, localValues_.create_weak(), leadingDim_);
00332   return Teuchos::rcpWithEmbeddedObjPreDestroy(
00333     new DefaultSpmdMultiVector<Scalar>(
00334       spmdRangeSpace_,
00335       createSmallScalarProdVectorSpaceBase<Scalar>(spmdRangeSpace_, numCols),
00336       localValuesView),
00337     copyBackView
00338     );
00339 }
00340 
00341 
00342 // Overridden protected members from SpmdMultiVectorBase
00343 
00344 
00345 template<class Scalar>
00346 void DefaultSpmdMultiVector<Scalar>::getNonconstLocalDataImpl(
00347   const Ptr<ArrayRCP<Scalar> > &localValues, const Ptr<Ordinal> &leadingDim
00348   )
00349 {
00350 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00351   std::cerr << "\nSpmdMultiVectorStd<Scalar>::getLocalDataImpl() called!\n";
00352 #endif
00353   *localValues = localValues_;
00354   *leadingDim = leadingDim_;
00355 }
00356 
00357 
00358 template<class Scalar>
00359 void DefaultSpmdMultiVector<Scalar>::getLocalDataImpl(
00360   const Ptr<ArrayRCP<const Scalar> > &localValues, const Ptr<Ordinal> &leadingDim
00361   ) const
00362 {
00363 #ifdef THYRA_DEFAULT_SPMD_MULTI_VECTOR_VERBOSE_TO_ERROR_OUT
00364   std::cerr << "\nSpmdMultiVectorStd<Scalar>::getLocalData() called!\n";
00365 #endif
00366   *localValues = localValues_;
00367   *leadingDim = leadingDim_;
00368 }
00369 
00370 
00371 // private
00372 
00373 
00374 template<class Scalar>
00375 ArrayRCP<Scalar>
00376 DefaultSpmdMultiVector<Scalar>::createContiguousCopy(
00377   const ArrayView<const int> &cols ) const
00378 {
00379   typedef typename ArrayRCP<Scalar>::const_iterator const_itr_t;
00380   typedef typename ArrayRCP<Scalar>::iterator itr_t;
00381   const int numCols = cols.size();
00382   const Ordinal localSubDim = spmdRangeSpace_->localSubDim();
00383   ArrayRCP<Scalar> localValuesView = Teuchos::arcp<Scalar>(numCols*localSubDim);
00384   // Copy to contiguous storage column by column
00385   const const_itr_t lv = localValues_.begin();
00386   const itr_t lvv = localValuesView.begin();
00387   for (int k = 0; k < numCols; ++k) {
00388     const int col_k = cols[k];
00389     const const_itr_t lv_k = lv + leadingDim_*col_k;
00390     const itr_t lvv_k = lvv + localSubDim*k;
00391     std::copy(lv_k, lv_k+localSubDim, lvv_k);
00392   }
00393   return localValuesView;
00394 }
00395 
00396 
00397 } // end namespace Thyra
00398 
00399 
00400 #endif // THYRA_DEFAULT_SPMD_MULTI_VECTOR_DEF_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines