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::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
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
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
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
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
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
00345 }
00346
00347
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
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 }
00387
00388 #endif // THYRA_DEFAULT_SPMD_MULTI_VECTOR_BASE_HPP