00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef THYRA_DEFAULT_SPMD_MULTI_VECTOR_BASE_HPP
00030 #define THYRA_DEFAULT_SPMD_MULTI_VECTOR_BASE_HPP
00031
00032
00033
00034
00035 #include "Thyra_DefaultSpmdMultiVectorDecl.hpp"
00036 #include "Thyra_SpmdMultiVectorBase.hpp"
00037 #include "Thyra_DefaultSpmdVector.hpp"
00038
00039 namespace Thyra {
00040
00041
00042
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
00060
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
00069 std::copy( lvv_k, lvv_k + localSubDim_, lv_k );
00070
00071 }
00072
00073 }
00074 private:
00075 std::vector<int> cols_;
00076 const Scalar *localValuesView_;
00077 Index localSubDim_;
00078 Scalar *localValues_;
00079 Index leadingDim_;
00080
00081 CopyBackSpmdMultiVectorEntries();
00082 CopyBackSpmdMultiVectorEntries(const CopyBackSpmdMultiVectorEntries&);
00083 CopyBackSpmdMultiVectorEntries& operator=(const CopyBackSpmdMultiVectorEntries&);
00084 };
00085
00086
00087
00088
00089
00090
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
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
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
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
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
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
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
00355 }
00356
00357
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
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 }
00397
00398 #endif // THYRA_DEFAULT_SPMD_MULTI_VECTOR_BASE_HPP