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_PRODUCT_VECTOR_SPACE_HPP
00030 #define THYRA_DEFAULT_PRODUCT_VECTOR_SPACE_HPP
00031
00032
00033 #include "Thyra_DefaultProductVectorSpace_decl.hpp"
00034 #include "Thyra_DefaultProductVector.hpp"
00035 #include "Thyra_DefaultProductMultiVector.hpp"
00036 #include "Thyra_ProductMultiVectorBase.hpp"
00037 #include "Teuchos_dyn_cast.hpp"
00038
00039
00040 namespace Thyra {
00041
00042
00043
00044
00045
00046 template<class Scalar>
00047 DefaultProductVectorSpace<Scalar>::DefaultProductVectorSpace()
00048 : numBlocks_(-1), dim_(-1)
00049 {}
00050
00051
00052 template<class Scalar>
00053 DefaultProductVectorSpace<Scalar>::DefaultProductVectorSpace(
00054 const ArrayView<const RCP<const VectorSpaceBase<Scalar> > > &vecSpaces_in
00055 )
00056 : numBlocks_(-1), dim_(-1)
00057 {
00058 initialize(vecSpaces_in);
00059 }
00060
00061
00062 template<class Scalar>
00063 void DefaultProductVectorSpace<Scalar>::initialize(
00064 const ArrayView<const RCP<const VectorSpaceBase<Scalar> > > &vecSpaces_in
00065 )
00066 {
00067
00068
00069
00070
00071 const int nBlocks = vecSpaces_in.size();
00072 #ifdef TEUCHOS_DEBUG
00073 TEST_FOR_EXCEPT( nBlocks == 0 );
00074 #endif
00075 bool overallHasInCoreView = true;
00076 for (int k = 0; k < nBlocks; ++k) {
00077 #ifdef TEUCHOS_DEBUG
00078 TEST_FOR_EXCEPTION(
00079 vecSpaces_in[k].get() == NULL, std::invalid_argument
00080 ,"Error, the smart pointer vecSpaces["<<k<<"] can not be NULL!"
00081 );
00082 #endif
00083 if (!vecSpaces_in[k]->hasInCoreView()) overallHasInCoreView = false;
00084 }
00085
00086
00087
00088
00089 numBlocks_ = nBlocks;
00090 vecSpaces_ = Teuchos::rcp(new vecSpaces_t);
00091 *vecSpaces_ = vecSpaces_in;
00092 vecSpacesOffsets_ = Teuchos::rcp(new vecSpacesOffsets_t(nBlocks+1));
00093 (*vecSpacesOffsets_)[0] = 0;
00094 dim_ = 0;
00095 for( int k = 1; k <= nBlocks; ++k ) {
00096 const Index dim_km1 = vecSpaces_in[k-1]->dim();
00097 (*vecSpacesOffsets_)[k] = (*vecSpacesOffsets_)[k-1] + dim_km1;
00098 dim_ += dim_km1;
00099 }
00100 isInCore_ = overallHasInCoreView;
00101
00102 }
00103
00104
00105 template<class Scalar>
00106 void DefaultProductVectorSpace<Scalar>::uninitialize(
00107 const ArrayView<RCP<const VectorSpaceBase<Scalar> > > &vecSpaces_in
00108 )
00109 {
00110 TEST_FOR_EXCEPT(!is_null(vecSpaces_in));
00111 vecSpaces_ = Teuchos::null;
00112 vecSpacesOffsets_ = Teuchos::null;
00113 numBlocks_ = -1;
00114 dim_ = -1;
00115 isInCore_ = false;
00116 }
00117
00118
00119 template<class Scalar>
00120 void DefaultProductVectorSpace<Scalar>::getVecSpcPoss(
00121 Index i, int* kth_vector_space, Index* kth_global_offset
00122 ) const
00123 {
00124
00125 #ifdef TEUCHOS_DEBUG
00126 TEST_FOR_EXCEPTION(
00127 !(0 <= i && i < this->dim()), std::out_of_range
00128 ,"VectorSpaceBlocked::get_vector_space_position(...): Error, i = "
00129 << i << " is not in range [0,"<<(this->dim()-1)<<"]"
00130 );
00131 #endif
00132 *kth_vector_space = 0;
00133 *kth_global_offset = 0;
00134 while( *kth_vector_space < numBlocks_ ) {
00135 const Index off_kp1 = (*vecSpacesOffsets_)[*kth_vector_space+1];
00136 if( off_kp1 > i ) {
00137 *kth_global_offset = (*vecSpacesOffsets_)[*kth_vector_space];
00138 break;
00139 }
00140 ++(*kth_vector_space);
00141 }
00142 TEST_FOR_EXCEPT( !(*kth_vector_space < numBlocks_) );
00143 }
00144
00145
00146
00147
00148
00149 template<class Scalar>
00150 int DefaultProductVectorSpace<Scalar>::numBlocks() const
00151 {
00152 return numBlocks_;
00153 }
00154
00155
00156 template<class Scalar>
00157 Teuchos::RCP<const VectorSpaceBase<Scalar> >
00158 DefaultProductVectorSpace<Scalar>::getBlock(const int k) const
00159 {
00160 TEST_FOR_EXCEPT( k < 0 || numBlocks_ < k );
00161 return (*vecSpaces_)[k];
00162 }
00163
00164
00165
00166
00167
00168 template<class Scalar>
00169 Index DefaultProductVectorSpace<Scalar>::dim() const
00170 {
00171 return dim_;
00172 }
00173
00174
00175 template<class Scalar>
00176 bool DefaultProductVectorSpace<Scalar>::isCompatible(
00177 const VectorSpaceBase<Scalar>& vecSpc ) const
00178 {
00179
00180 using Teuchos::ptrFromRef;
00181 using Teuchos::ptr_dynamic_cast;
00182
00183 const int nBlocks = this->numBlocks();
00184
00185
00186 const Ptr<const ProductVectorSpaceBase<Scalar> > pvsb =
00187 ptr_dynamic_cast<const ProductVectorSpaceBase<Scalar> >(ptrFromRef(vecSpc));
00188
00189 if (nonnull(pvsb)) {
00190
00191 if( nBlocks != pvsb->numBlocks() )
00192 return false;
00193 for( int i = 0; i < nBlocks; ++i ) {
00194 if( !this->getBlock(i)->isCompatible(*pvsb->getBlock(i)) )
00195 return false;
00196 }
00197 return true;
00198 }
00199
00200
00201 if (nBlocks == 1) {
00202 return this->getBlock(0)->isCompatible(vecSpc);
00203 }
00204
00205
00206 if (this->hasInCoreView(Range1D(), VIEW_TYPE_DETACHED, STRIDE_TYPE_NONUNIT)
00207 && vecSpc.hasInCoreView() && ( this->dim() == vecSpc.dim() ) )
00208 {
00209 return true;
00210 }
00211
00212
00213
00214
00215
00216
00217 return false;
00218
00219 }
00220
00221
00222 template<class Scalar>
00223 Teuchos::RCP< VectorBase<Scalar> >
00224 DefaultProductVectorSpace<Scalar>::createMember() const
00225 {
00226 return defaultProductVector<Scalar>(Teuchos::rcpFromRef(*this));
00227 }
00228
00229
00230 template<class Scalar>
00231 Scalar DefaultProductVectorSpace<Scalar>::scalarProd(
00232 const VectorBase<Scalar> &x_in,
00233 const VectorBase<Scalar> &y_in
00234 ) const
00235 {
00236 const int nBlocks = this->numBlocks();
00237 const ProductVectorBase<Scalar>
00238 &x = Teuchos::dyn_cast<const ProductVectorBase<Scalar> >(x_in),
00239 &y = Teuchos::dyn_cast<const ProductVectorBase<Scalar> >(y_in);
00240 #ifdef TEUCHOS_DEBUG
00241 TEST_FOR_EXCEPT(
00242 nBlocks!=x.productSpace()->numBlocks()
00243 || nBlocks!=y.productSpace()->numBlocks()
00244 );
00245 #endif
00246 Scalar scalarProd_rtn = Teuchos::ScalarTraits<Scalar>::zero();
00247 for( int k = 0; k < nBlocks; ++k )
00248 scalarProd_rtn += (*vecSpaces_)[k]->scalarProd(
00249 *x.getVectorBlock(k),*y.getVectorBlock(k)
00250 );
00251 return scalarProd_rtn;
00252 }
00253
00254
00255 template<class Scalar>
00256 void DefaultProductVectorSpace<Scalar>::scalarProdsImpl(
00257 const MultiVectorBase<Scalar> &X_in,
00258 const MultiVectorBase<Scalar> &Y_in,
00259 const ArrayView<Scalar> &scalarProds_out
00260 ) const
00261 {
00262 using Teuchos::as;
00263 using Teuchos::Workspace;
00264 const VectorSpaceBase<Scalar> &domain = *X_in.domain();
00265 const Index m = domain.dim();
00266 #ifdef TEUCHOS_DEBUG
00267 TEST_FOR_EXCEPT(is_null(scalarProds_out));
00268 TEST_FOR_EXCEPT( !domain.isCompatible(*Y_in.domain()) );
00269 TEUCHOS_ASSERT_EQUALITY( as<Ordinal>(scalarProds_out.size()),
00270 as<Ordinal>(m) )
00271 #endif
00272 if(m==1) {
00273 scalarProds_out[0] = this->scalarProd(*X_in.col(0),*Y_in.col(0));
00274 return;
00275
00276 }
00277 Teuchos::WorkspaceStore* wss = Teuchos::get_default_workspace_store().get();
00278 const int nBlocks = this->numBlocks();
00279 const ProductMultiVectorBase<Scalar>
00280 &X = Teuchos::dyn_cast<const ProductMultiVectorBase<Scalar> >(X_in),
00281 &Y = Teuchos::dyn_cast<const ProductMultiVectorBase<Scalar> >(Y_in);
00282 #ifdef TEUCHOS_DEBUG
00283 TEST_FOR_EXCEPT( nBlocks!=X.productSpace()->numBlocks() || nBlocks!=Y.productSpace()->numBlocks() );
00284 #endif
00285 Workspace<Scalar> _scalarProds_out(wss, m, false);
00286 std::fill( scalarProds_out.begin(), scalarProds_out.end(),
00287 ScalarTraits<Scalar>::zero() );
00288 for( int k = 0; k < nBlocks; ++k ) {
00289 (*vecSpaces_)[k]->scalarProds(
00290 *X.getMultiVectorBlock(k), *Y.getMultiVectorBlock(k), _scalarProds_out());
00291 for( int j = 0; j < m; ++j )
00292 scalarProds_out[j] += _scalarProds_out[j];
00293 }
00294 }
00295
00296
00297 template<class Scalar>
00298 bool DefaultProductVectorSpace<Scalar>::hasInCoreView(const Range1D& rng_in, const EViewType viewType, const EStrideType strideType) const
00299 {
00300 const Range1D rng = full_range(rng_in,0,dim_-1);
00301
00302 int kth_vector_space = -1;
00303 Index kth_global_offset = 0;
00304 this->getVecSpcPoss(rng.lbound(),&kth_vector_space,&kth_global_offset);
00305 #ifdef TEUCHOS_DEBUG
00306 TEST_FOR_EXCEPT( !( 0 <= kth_vector_space && kth_vector_space <= numBlocks_ ) );
00307 #endif
00308 if( rng.lbound() + rng.size() <= kth_global_offset + (*vecSpaces_)[kth_vector_space]->dim() ) {
00309 return (*vecSpaces_)[kth_vector_space]->hasInCoreView(rng_in-kth_global_offset,viewType,strideType);
00310 }
00311
00312
00313
00314
00315
00316 if( viewType == VIEW_TYPE_DIRECT )
00317 return false;
00318
00319
00320
00321 if(isInCore_)
00322 return true;
00323
00324
00325
00326
00327
00328
00329 return false;
00330 }
00331
00332
00333 template<class Scalar>
00334 Teuchos::RCP< const VectorSpaceFactoryBase<Scalar> >
00335 DefaultProductVectorSpace<Scalar>::smallVecSpcFcty() const
00336 {
00337 if (dim_)
00338 return (*vecSpaces_)[0]->smallVecSpcFcty();
00339 return Teuchos::null;
00340 }
00341
00342
00343 template<class Scalar>
00344 Teuchos::RCP< MultiVectorBase<Scalar> >
00345 DefaultProductVectorSpace<Scalar>::createMembers(int numMembers) const
00346 {
00347 return defaultProductMultiVector<Scalar>(Teuchos::rcpFromRef(*this),
00348 numMembers);
00349 }
00350
00351
00352 template<class Scalar>
00353 Teuchos::RCP< const VectorSpaceBase<Scalar> >
00354 DefaultProductVectorSpace<Scalar>::clone() const
00355 {
00356
00357
00358
00359 Teuchos::RCP<DefaultProductVectorSpace<Scalar> >
00360 pvs = productVectorSpace<Scalar>();
00361 pvs->numBlocks_ = numBlocks_;
00362 pvs->vecSpaces_ = vecSpaces_;
00363 pvs->vecSpacesOffsets_ = vecSpacesOffsets_;
00364 pvs->dim_ = dim_;
00365 pvs->isInCore_ = isInCore_;
00366 return pvs;
00367 }
00368
00369
00370
00371
00372
00373 template<class Scalar>
00374 std::string DefaultProductVectorSpace<Scalar>::description() const
00375 {
00376 std::ostringstream oss;
00377 oss
00378 << Teuchos::Describable::description() << "{"
00379 << "dim="<<dim_
00380 << ",numBlocks="<<numBlocks_
00381 << "}";
00382 return oss.str();
00383 }
00384
00385
00386 template<class Scalar>
00387 void DefaultProductVectorSpace<Scalar>::describe(
00388 Teuchos::FancyOStream &out_arg
00389 ,const Teuchos::EVerbosityLevel verbLevel
00390 ) const
00391 {
00392 typedef Teuchos::ScalarTraits<Scalar> ST;
00393 using Teuchos::RCP;
00394 using Teuchos::FancyOStream;
00395 using Teuchos::OSTab;
00396 RCP<FancyOStream> out = rcpFromRef(out_arg);
00397 OSTab tab(out);
00398 switch(verbLevel) {
00399 case Teuchos::VERB_NONE:
00400 break;
00401 case Teuchos::VERB_DEFAULT:
00402 case Teuchos::VERB_LOW:
00403 *out << this->description() << std::endl;
00404 break;
00405 case Teuchos::VERB_MEDIUM:
00406 case Teuchos::VERB_HIGH:
00407 case Teuchos::VERB_EXTREME:
00408 {
00409 *out << this->description() << std::endl;
00410 if (numBlocks_ <= 0)
00411 break;
00412 OSTab tab2(out);
00413 *out
00414 << "Constituent vector spaces V[0], V[1], ... V[numBlocks-1]:\n";
00415 OSTab tab3(out);
00416 for( int k = 0; k < numBlocks_; ++k ) {
00417 *out << "V["<<k<<"] = " << Teuchos::describe(*(*vecSpaces_)[k],verbLevel);
00418 }
00419 break;
00420 }
00421 default:
00422 TEST_FOR_EXCEPT(true);
00423 }
00424 }
00425
00426
00427 }
00428
00429
00430 #endif // THYRA_DEFAULT_PRODUCT_VECTOR_SPACE_HPP