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_MULTI_VECTOR_DEF_HPP
00030 #define THYRA_DEFAULT_PRODUCT_MULTI_VECTOR_DEF_HPP
00031
00032 #include "Thyra_DefaultProductMultiVector_decl.hpp"
00033 #include "Thyra_DefaultProductVectorSpace.hpp"
00034 #include "Thyra_DefaultProductVector.hpp"
00035 #include "Thyra_AssertOp.hpp"
00036
00037
00038 namespace Thyra {
00039
00040
00041
00042
00043
00044 template<class Scalar>
00045 DefaultProductMultiVector<Scalar>::DefaultProductMultiVector()
00046 :numBlocks_(0)
00047 {}
00048
00049
00050 template<class Scalar>
00051 void DefaultProductMultiVector<Scalar>::initialize(
00052 const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace_in,
00053 const int numMembers
00054 )
00055 {
00056 #ifdef TEUCHOS_DEBUG
00057 TEST_FOR_EXCEPT( is_null(productSpace_in) );
00058 TEST_FOR_EXCEPT( numMembers <= 0 );
00059 #endif
00060 Array<RCP<MultiVectorBase<Scalar> > > multiVecs;
00061 const int numBlocks = productSpace_in->numBlocks();
00062 for ( int k = 0; k < numBlocks; ++k )
00063 multiVecs.push_back(createMembers(productSpace_in->getBlock(k),numMembers));
00064 initialize(productSpace_in,multiVecs);
00065 }
00066
00067
00068 template<class Scalar>
00069 void DefaultProductMultiVector<Scalar>::initialize(
00070 const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace_in,
00071 const ArrayView<const RCP<MultiVectorBase<Scalar> > > &multiVecs
00072 )
00073 {
00074 initializeImpl(productSpace_in,multiVecs);
00075 }
00076
00077
00078 template<class Scalar>
00079 void DefaultProductMultiVector<Scalar>::initialize(
00080 const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace_in,
00081 const ArrayView<const RCP<const MultiVectorBase<Scalar> > > &multiVecs
00082 )
00083 {
00084 initializeImpl(productSpace_in,multiVecs);
00085 }
00086
00087
00088 template<class Scalar>
00089 void DefaultProductMultiVector<Scalar>::uninitialize()
00090 {
00091 productSpace_ = Teuchos::null;
00092 multiVecs_.resize(0);
00093 numBlocks_ = 0;
00094 }
00095
00096
00097
00098
00099
00100 template<class Scalar>
00101 std::string DefaultProductMultiVector<Scalar>::description() const
00102 {
00103 std::ostringstream oss;
00104 oss
00105 << Teuchos::Describable::description()
00106 << "{"
00107 << "rangeDim="<<this->range()->dim()
00108 << ",domainDim="<<this->domain()->dim()
00109 << ",numBlocks = "<<numBlocks_
00110 << "}";
00111 return oss.str();
00112 }
00113
00114
00115 template<class Scalar>
00116 void DefaultProductMultiVector<Scalar>::describe(
00117 FancyOStream &out_arg,
00118 const Teuchos::EVerbosityLevel verbLevel
00119 ) const
00120 {
00121 typedef Teuchos::ScalarTraits<Scalar> ST;
00122 using Teuchos::OSTab;
00123 using Teuchos::describe;
00124 if (verbLevel == Teuchos::VERB_NONE)
00125 return;
00126 RCP<FancyOStream> out = rcp(&out_arg,false);
00127 OSTab tab(out);
00128 switch(verbLevel) {
00129 case Teuchos::VERB_NONE:
00130 break;
00131 case Teuchos::VERB_DEFAULT:
00132 case Teuchos::VERB_LOW:
00133 *out << this->description() << std::endl;
00134 break;
00135 case Teuchos::VERB_MEDIUM:
00136 case Teuchos::VERB_HIGH:
00137 case Teuchos::VERB_EXTREME:
00138 {
00139 *out
00140 << Teuchos::Describable::description() << "{"
00141 << "rangeDim="<<this->range()->dim()
00142 << ",domainDim="<<this->domain()->dim()
00143 << "}\n";
00144 OSTab tab2(out);
00145 *out
00146 << "numBlocks="<< numBlocks_ << std::endl
00147 << "Constituent multi-vector objects V[0], V[1], ... V[numBlocks-1]:\n";
00148 OSTab tab3(out);
00149 for( int k = 0; k < numBlocks_; ++k ) {
00150 *out << "V["<<k<<"] = "
00151 << Teuchos::describe(*multiVecs_[k].getConstObj(),verbLevel);
00152 }
00153 break;
00154 }
00155 default:
00156 TEST_FOR_EXCEPT(true);
00157 }
00158 }
00159
00160
00161
00162
00163
00164 template<class Scalar>
00165 RCP<const ProductVectorSpaceBase<Scalar> >
00166 DefaultProductMultiVector<Scalar>::productSpace() const
00167 {
00168 return productSpace_;
00169 }
00170
00171
00172 template<class Scalar>
00173 bool DefaultProductMultiVector<Scalar>::blockIsConst(const int k) const
00174 {
00175 return multiVecs_[k].isConst();
00176 }
00177
00178
00179 template<class Scalar>
00180 RCP<MultiVectorBase<Scalar> >
00181 DefaultProductMultiVector<Scalar>::getNonconstMultiVectorBlock(const int k)
00182 {
00183 return multiVecs_[k].getNonconstObj();
00184 }
00185
00186
00187 template<class Scalar>
00188 RCP<const MultiVectorBase<Scalar> >
00189 DefaultProductMultiVector<Scalar>::getMultiVectorBlock(const int k) const
00190 {
00191 return multiVecs_[k].getConstObj();
00192 }
00193
00194
00195
00196
00197
00198 template<class Scalar>
00199 RCP<MultiVectorBase<Scalar> >
00200 DefaultProductMultiVector<Scalar>::clone_mv() const
00201 {
00202 assertInitialized();
00203 Array<RCP<MultiVectorBase<Scalar> > > blocks;
00204 for ( int k = 0; k < numBlocks_; ++k )
00205 blocks.push_back(multiVecs_[k].getConstObj()->clone_mv());
00206 return defaultProductMultiVector<Scalar>(productSpace_, blocks());
00207 }
00208
00209
00210
00211
00212
00213 template<class Scalar>
00214 RCP< const VectorSpaceBase<Scalar> >
00215 DefaultProductMultiVector<Scalar>::range() const
00216 {
00217 return productSpace_;
00218 }
00219
00220
00221 template<class Scalar>
00222 RCP< const VectorSpaceBase<Scalar> >
00223 DefaultProductMultiVector<Scalar>::domain() const
00224 {
00225 if (is_null(productSpace_))
00226 return Teuchos::null;
00227 return multiVecs_[0].getConstObj()->domain();
00228 }
00229
00230
00231
00232
00233
00234
00235
00236
00237 template<class Scalar>
00238 RCP<const VectorBase<Scalar> >
00239 DefaultProductMultiVector<Scalar>::colImpl(Index j) const
00240 {
00241 validateColIndex(j);
00242 Array<RCP<const VectorBase<Scalar> > > cols_;
00243 for ( int k = 0; k < numBlocks_; ++k )
00244 cols_.push_back(multiVecs_[k].getConstObj()->col(j));
00245 return defaultProductVector<Scalar>(productSpace_,&cols_[0]);
00246 }
00247
00248
00249 template<class Scalar>
00250 RCP<VectorBase<Scalar> >
00251 DefaultProductMultiVector<Scalar>::nonconstColImpl(Index j)
00252 {
00253 validateColIndex(j);
00254 Array<RCP<VectorBase<Scalar> > > cols_;
00255 for ( int k = 0; k < numBlocks_; ++k )
00256 cols_.push_back(multiVecs_[k].getNonconstObj()->col(j));
00257 return defaultProductVector<Scalar>(productSpace_,&cols_[0]);
00258 }
00259
00260
00261 template<class Scalar>
00262 RCP<const MultiVectorBase<Scalar> >
00263 DefaultProductMultiVector<Scalar>::contigSubViewImpl( const Range1D& colRng ) const
00264 {
00265 assertInitialized();
00266 Array<RCP<const MultiVectorBase<Scalar> > > blocks;
00267 for ( int k = 0; k < numBlocks_; ++k )
00268 blocks.push_back(multiVecs_[k].getConstObj()->subView(colRng));
00269 return defaultProductMultiVector<Scalar>(productSpace_, blocks());
00270 }
00271
00272
00273 template<class Scalar>
00274 RCP<MultiVectorBase<Scalar> >
00275 DefaultProductMultiVector<Scalar>::nonconstContigSubViewImpl( const Range1D& colRng )
00276 {
00277 assertInitialized();
00278 Array<RCP<MultiVectorBase<Scalar> > > blocks;
00279 for ( int k = 0; k < numBlocks_; ++k )
00280 blocks.push_back(multiVecs_[k].getNonconstObj()->subView(colRng));
00281 return defaultProductMultiVector<Scalar>(productSpace_, blocks());
00282 }
00283
00284
00285 template<class Scalar>
00286 RCP<const MultiVectorBase<Scalar> >
00287 DefaultProductMultiVector<Scalar>::nonContigSubViewImpl(
00288 const ArrayView<const int> &cols
00289 ) const
00290 {
00291 assertInitialized();
00292 Array<RCP<const MultiVectorBase<Scalar> > > blocks;
00293 for ( int k = 0; k < numBlocks_; ++k )
00294 blocks.push_back(multiVecs_[k].getConstObj()->subView(cols));
00295 return defaultProductMultiVector<Scalar>(productSpace_, blocks());
00296 }
00297
00298
00299 template<class Scalar>
00300 RCP<MultiVectorBase<Scalar> >
00301 DefaultProductMultiVector<Scalar>::nonconstNonContigSubViewImpl(
00302 const ArrayView<const int> &cols
00303 )
00304 {
00305 assertInitialized();
00306 Array<RCP<MultiVectorBase<Scalar> > > blocks;
00307 for ( int k = 0; k < numBlocks_; ++k )
00308 blocks.push_back(multiVecs_[k].getNonconstObj()->subView(cols));
00309 return defaultProductMultiVector<Scalar>(productSpace_, blocks());
00310 }
00311
00312
00313 template<class Scalar>
00314 void DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(
00315 const RTOpPack::RTOpT<Scalar> &primary_op,
00316 const ArrayView<const Ptr<const MultiVectorBase<Scalar> > > &multi_vecs_in,
00317 const ArrayView<const Ptr<MultiVectorBase<Scalar> > > &targ_multi_vecs_inout,
00318 const ArrayView<const Ptr<RTOpPack::ReductTarget> > &reduct_objs,
00319 const Index primary_first_ele_offset_in,
00320 const Index primary_sub_dim_in,
00321 const Index primary_global_offset_in,
00322 const Index secondary_first_ele_offset_in,
00323 const Index secondary_sub_dim_in
00324 ) const
00325 {
00326
00327 using Teuchos::ptr_dynamic_cast;
00328 using Thyra::applyOp;
00329
00330 assertInitialized();
00331
00332 const Index domainDim = this->domain()->dim();
00333 const Index rangeDim = this->range()->dim();
00334
00335 #ifdef TEUCHOS_DEBUG
00336 for ( int j = 0; j < multi_vecs_in.size(); ++j ) {
00337 THYRA_ASSERT_VEC_SPACES(
00338 "DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(...)",
00339 *this->range(), *multi_vecs_in[j]->range()
00340 );
00341 THYRA_ASSERT_VEC_SPACES(
00342 "DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(...)",
00343 *this->domain(), *multi_vecs_in[j]->domain()
00344 );
00345 }
00346 for ( int j = 0; j < targ_multi_vecs_inout.size(); ++j ) {
00347 THYRA_ASSERT_VEC_SPACES(
00348 "DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(...)",
00349 *this->range(), *targ_multi_vecs_inout[j]->range()
00350 );
00351 THYRA_ASSERT_VEC_SPACES(
00352 "DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(...)",
00353 *this->domain(), *targ_multi_vecs_inout[j]->domain()
00354 );
00355 }
00356 TEST_FOR_EXCEPT(
00357 !(
00358 0 <= primary_first_ele_offset_in
00359 &&
00360 primary_first_ele_offset_in < rangeDim
00361 )
00362 );
00363 TEST_FOR_EXCEPT(
00364 primary_sub_dim_in > 0
00365 &&
00366 primary_first_ele_offset_in + primary_sub_dim_in > rangeDim
00367 );
00368 TEST_FOR_EXCEPT(
00369 !(
00370 0 <= secondary_first_ele_offset_in
00371 &&
00372 secondary_first_ele_offset_in < domainDim
00373 )
00374 );
00375 TEST_FOR_EXCEPT(
00376 secondary_sub_dim_in > 0
00377 &&
00378 secondary_first_ele_offset_in + secondary_sub_dim_in > domainDim
00379 );
00380 #endif // TEUCHOS_DEBUG
00381
00382 const Index primary_sub_dim
00383 = (
00384 primary_sub_dim_in < 0
00385 ? rangeDim - primary_first_ele_offset_in
00386 : primary_sub_dim_in
00387 );
00388 const Index secondary_sub_dim
00389 = (
00390 secondary_sub_dim_in < 0
00391 ? domainDim - secondary_first_ele_offset_in
00392 : secondary_sub_dim_in
00393 );
00394
00395
00396
00397
00398
00399
00400 bool allProductMultiVectors = true;
00401
00402 Array<Ptr<const ProductMultiVectorBase<Scalar> > > multi_vecs;
00403 for ( int j = 0; j < multi_vecs_in.size() && allProductMultiVectors; ++j ) {
00404 #ifdef TEUCHOS_DEBUG
00405 TEST_FOR_EXCEPT( is_null(multi_vecs_in[j]) );
00406 #endif
00407 const Ptr<const ProductMultiVectorBase<Scalar> >
00408 multi_vecs_j = ptr_dynamic_cast<const ProductMultiVectorBase<Scalar> >(
00409 multi_vecs_in[j]
00410 );
00411 if ( !is_null(multi_vecs_j) ) {
00412 multi_vecs.push_back(multi_vecs_j);
00413 }
00414 else {
00415 allProductMultiVectors = false;
00416 }
00417 }
00418
00419 Array<Ptr<ProductMultiVectorBase<Scalar> > > targ_multi_vecs;
00420 for ( int j = 0; j < targ_multi_vecs_inout.size() && allProductMultiVectors; ++j )
00421 {
00422 #ifdef TEUCHOS_DEBUG
00423 TEST_FOR_EXCEPT( is_null(targ_multi_vecs_inout[j]) );
00424 #endif
00425 Ptr<ProductMultiVectorBase<Scalar> >
00426 targ_multi_vecs_j = ptr_dynamic_cast<ProductMultiVectorBase<Scalar> >(
00427 targ_multi_vecs_inout[j]
00428 );
00429 if (!is_null(targ_multi_vecs_j)) {
00430 targ_multi_vecs.push_back(targ_multi_vecs_j);
00431 }
00432 else {
00433 allProductMultiVectors = false;
00434 }
00435 }
00436
00437
00438
00439
00440
00441 if ( allProductMultiVectors ) {
00442
00443
00444
00445
00446
00447
00448
00449
00450 Array<RCP<const MultiVectorBase<Scalar> > >
00451 multi_vecs_rcp_block_k(multi_vecs_in.size());
00452 Array<Ptr<const MultiVectorBase<Scalar> > >
00453 multi_vecs_block_k(multi_vecs_in.size());
00454 Array<RCP<MultiVectorBase<Scalar> > >
00455 targ_multi_vecs_rcp_block_k(targ_multi_vecs_inout.size());
00456 Array<Ptr<MultiVectorBase<Scalar> > >
00457 targ_multi_vecs_block_k(targ_multi_vecs_inout.size());
00458
00459 Index num_rows_remaining = primary_sub_dim;
00460 Index g_off = -primary_first_ele_offset_in;
00461
00462 for ( int k = 0; k < numBlocks_; ++k ) {
00463
00464
00465
00466 const Index local_dim = productSpace_->getBlock(k)->dim();
00467 if( g_off < 0 && -g_off+1 > local_dim ) {
00468 g_off += local_dim;
00469 continue;
00470 }
00471 const Index local_sub_dim
00472 = (
00473 g_off >= 0
00474 ? std::min( local_dim, num_rows_remaining )
00475 : std::min( local_dim + g_off, num_rows_remaining )
00476 );
00477 if( local_sub_dim <= 0 )
00478 break;
00479
00480
00481
00482 for ( int j = 0; j < multi_vecs_in.size(); ++j ) {
00483 RCP<const MultiVectorBase<Scalar> > multi_vecs_rcp_block_k_j =
00484 multi_vecs[j]->getMultiVectorBlock(k);
00485 multi_vecs_rcp_block_k[j] = multi_vecs_rcp_block_k_j;
00486 multi_vecs_block_k[j] = multi_vecs_rcp_block_k_j.ptr();
00487 }
00488
00489 for ( int j = 0; j < targ_multi_vecs_inout.size(); ++j ) {
00490 RCP<MultiVectorBase<Scalar> > targ_multi_vecs_rcp_block_k_j =
00491 targ_multi_vecs[j]->getNonconstMultiVectorBlock(k);
00492 targ_multi_vecs_rcp_block_k[j] = targ_multi_vecs_rcp_block_k_j;
00493 targ_multi_vecs_block_k[j] = targ_multi_vecs_rcp_block_k_j.ptr();
00494 }
00495
00496
00497
00498 Thyra::applyOp<Scalar>(
00499 primary_op, multi_vecs_block_k(), targ_multi_vecs_block_k(),
00500 reduct_objs,
00501 g_off < 0 ? -g_off : 0,
00502 local_sub_dim,
00503 g_off < 0 ? primary_global_offset_in : primary_global_offset_in + g_off,
00504 secondary_first_ele_offset_in, secondary_sub_dim
00505 );
00506 }
00507
00508 }
00509 else {
00510
00511
00512
00513
00514
00515
00516 MultiVectorDefaultBase<Scalar>::mvMultiReductApplyOpImpl(
00517 primary_op, multi_vecs_in(), targ_multi_vecs_inout(),
00518 reduct_objs,
00519 primary_first_ele_offset_in, primary_sub_dim_in, primary_global_offset_in,
00520 secondary_first_ele_offset_in, secondary_sub_dim_in
00521 );
00522
00523 }
00524
00525 }
00526
00527
00528 template<class Scalar>
00529 void DefaultProductMultiVector<Scalar>::acquireDetachedMultiVectorViewImpl(
00530 const Range1D &rowRng,
00531 const Range1D &colRng,
00532 RTOpPack::ConstSubMultiVectorView<Scalar> *sub_mv
00533 ) const
00534 {
00535 return MultiVectorDefaultBase<Scalar>::acquireDetachedMultiVectorViewImpl(
00536 rowRng, colRng, sub_mv );
00537
00538 }
00539
00540
00541 template<class Scalar>
00542 void DefaultProductMultiVector<Scalar>::releaseDetachedMultiVectorViewImpl(
00543 RTOpPack::ConstSubMultiVectorView<Scalar>* sub_mv
00544 ) const
00545 {
00546 return MultiVectorDefaultBase<Scalar>::releaseDetachedMultiVectorViewImpl(
00547 sub_mv );
00548
00549 }
00550
00551
00552 template<class Scalar>
00553 void DefaultProductMultiVector<Scalar>::acquireNonconstDetachedMultiVectorViewImpl(
00554 const Range1D &rowRng,
00555 const Range1D &colRng,
00556 RTOpPack::SubMultiVectorView<Scalar> *sub_mv
00557 )
00558 {
00559 return MultiVectorDefaultBase<Scalar>::acquireNonconstDetachedMultiVectorViewImpl(
00560 rowRng,colRng,sub_mv );
00561
00562 }
00563
00564
00565 template<class Scalar>
00566 void DefaultProductMultiVector<Scalar>::commitNonconstDetachedMultiVectorViewImpl(
00567 RTOpPack::SubMultiVectorView<Scalar>* sub_mv
00568 )
00569 {
00570 return MultiVectorDefaultBase<Scalar>::commitNonconstDetachedMultiVectorViewImpl(sub_mv);
00571
00572 }
00573
00574
00575
00576
00577
00578 template<class Scalar>
00579 bool DefaultProductMultiVector<Scalar>::opSupported(EOpTransp M_trans) const
00580 {
00581 return true;
00582 }
00583
00584
00585 template<class Scalar>
00586 void DefaultProductMultiVector<Scalar>::apply(
00587 const EOpTransp M_trans,
00588 const MultiVectorBase<Scalar> &X_in,
00589 MultiVectorBase<Scalar> *Y_inout,
00590 const Scalar alpha,
00591 const Scalar beta
00592 ) const
00593 {
00594
00595 typedef Teuchos::ScalarTraits<Scalar> ST;
00596 using Teuchos::dyn_cast;
00597 using Thyra::apply;
00598
00599 #ifdef TEUCHOS_DEBUG
00600 THYRA_ASSERT_LINEAR_OP_MULTIVEC_APPLY_SPACES(
00601 "DefaultProductMultiVector<Scalar>::apply(...)",
00602 *this, M_trans, X_in, Y_inout );
00603 #endif
00604
00605 if ( real_trans(M_trans) == NOTRANS ) {
00606
00607
00608
00609
00610
00611
00612
00613 ProductMultiVectorBase<Scalar>
00614 &Y = dyn_cast<ProductMultiVectorBase<Scalar> >(*Y_inout);
00615 for ( int k = 0; k < numBlocks_; ++k ) {
00616 Thyra::apply(
00617 *multiVecs_[k].getConstObj(), M_trans,
00618 X_in, &*Y.getNonconstMultiVectorBlock(k),
00619 alpha, beta
00620 );
00621 }
00622 }
00623 else {
00624
00625
00626
00627
00628
00629
00630
00631 const ProductMultiVectorBase<Scalar>
00632 &X = dyn_cast<const ProductMultiVectorBase<Scalar> >(X_in);
00633 for ( int k = 0; k < numBlocks_; ++k ) {
00634 RCP<const MultiVectorBase<Scalar> >
00635 M_k = multiVecs_[k].getConstObj(),
00636 X_k = X.getMultiVectorBlock(k);
00637 if ( 0 == k ) {
00638 Thyra::apply( *M_k, M_trans, *X_k, &*Y_inout, alpha, beta );
00639 }
00640 else {
00641 Thyra::apply( *M_k, M_trans, *X_k, &*Y_inout, alpha, ST::one() );
00642 }
00643 }
00644 }
00645 }
00646
00647
00648
00649
00650
00651 template<class Scalar>
00652 template<class MultiVectorType>
00653 void DefaultProductMultiVector<Scalar>::initializeImpl(
00654 const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace_in,
00655 const ArrayView<const RCP<MultiVectorType> > &multiVecs
00656 )
00657 {
00658
00659
00660
00661 #ifdef TEUCHOS_DEBUG
00662 TEUCHOS_ASSERT(nonnull(productSpace_in));
00663 TEUCHOS_ASSERT_EQUALITY(multiVecs.size(), productSpace_in->numBlocks());
00664 #endif // TEUCHOS_DEBUG
00665 const RCP<const VectorSpaceBase<Scalar> >
00666 theDomain = multiVecs[0]->domain();
00667 const int numBlocks = productSpace_in->numBlocks();
00668 #ifdef TEUCHOS_DEBUG
00669 for ( int k = 0; k < numBlocks; ++k ) {
00670 THYRA_ASSERT_VEC_SPACES(
00671 Teuchos::TypeNameTraits<DefaultProductMultiVector<Scalar> >::name(),
00672 *theDomain, *multiVecs[k]->domain()
00673 );
00674 }
00675 #endif
00676 productSpace_ = productSpace_in;
00677 numBlocks_ = numBlocks;
00678 multiVecs_.assign(multiVecs.begin(),multiVecs.end());
00679 }
00680
00681
00682 #ifdef TEUCHOS_DEBUG
00683
00684
00685 template<class Scalar>
00686 void DefaultProductMultiVector<Scalar>::assertInitialized() const
00687 {
00688 TEST_FOR_EXCEPTION(
00689 is_null(productSpace_), std::logic_error,
00690 "Error, this DefaultProductMultiVector object is not intialized!"
00691 );
00692 }
00693
00694
00695 template<class Scalar>
00696 void DefaultProductMultiVector<Scalar>::validateColIndex(const int j) const
00697 {
00698 assertInitialized();
00699 const int domainDim = multiVecs_[0].getConstObj()->domain()->dim();
00700 TEST_FOR_EXCEPTION(
00701 ! ( 0 <= j && j < domainDim ), std::logic_error,
00702 "Error, the column index j = " << j << " does not fall in the range [0,"<<domainDim<<"]!"
00703 );
00704 }
00705
00706
00707 #endif // TEUCHOS_DEBUG
00708
00709
00710 }
00711
00712
00713 template<class Scalar>
00714 Teuchos::RCP<Thyra::DefaultProductMultiVector<Scalar> >
00715 Thyra::defaultProductMultiVector()
00716 {
00717 return Teuchos::rcp(new DefaultProductMultiVector<Scalar>);
00718 }
00719
00720
00721 template<class Scalar>
00722 Teuchos::RCP<Thyra::DefaultProductMultiVector<Scalar> >
00723 Thyra::defaultProductMultiVector(
00724 const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
00725 const int numMembers
00726 )
00727 {
00728 RCP<DefaultProductMultiVector<Scalar> > pmv = defaultProductMultiVector<Scalar>();
00729 pmv->initialize(productSpace, numMembers);
00730 return pmv;
00731 }
00732
00733
00734 template<class Scalar>
00735 Teuchos::RCP<Thyra::DefaultProductMultiVector<Scalar> >
00736 Thyra::defaultProductMultiVector(
00737 const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
00738 const ArrayView<const RCP<MultiVectorBase<Scalar> > > &multiVecs
00739 )
00740 {
00741 const RCP<DefaultProductMultiVector<Scalar> > pmv =
00742 defaultProductMultiVector<Scalar>();
00743 pmv->initialize(productSpace, multiVecs);
00744 return pmv;
00745 }
00746
00747
00748 template<class Scalar>
00749 Teuchos::RCP<Thyra::DefaultProductMultiVector<Scalar> >
00750 Thyra::defaultProductMultiVector(
00751 const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
00752 const ArrayView<const RCP<const MultiVectorBase<Scalar> > > &multiVecs
00753 )
00754 {
00755 const RCP<DefaultProductMultiVector<Scalar> > pmv =
00756 defaultProductMultiVector<Scalar>();
00757 pmv->initialize(productSpace, multiVecs);
00758 return pmv;
00759 }
00760
00761
00762 template<class Scalar>
00763 Teuchos::RCP<const Thyra::ProductMultiVectorBase<Scalar> >
00764 Thyra::castOrCreateSingleBlockProductMultiVector(
00765 const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
00766 const RCP<const MultiVectorBase<Scalar> > &mv
00767 )
00768 {
00769 const RCP<const ProductMultiVectorBase<Scalar> > pmv =
00770 Teuchos::rcp_dynamic_cast<const ProductMultiVectorBase<Scalar> >(mv);
00771 if (nonnull(pmv))
00772 return pmv;
00773 return defaultProductMultiVector<Scalar>(productSpace, Teuchos::tuple(mv)());
00774 }
00775
00776
00777 template<class Scalar>
00778 Teuchos::RCP<Thyra::ProductMultiVectorBase<Scalar> >
00779 Thyra::nonconstCastOrCreateSingleBlockProductMultiVector(
00780 const RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
00781 const RCP<MultiVectorBase<Scalar> > &mv
00782 )
00783 {
00784 const RCP<ProductMultiVectorBase<Scalar> > pmv =
00785 Teuchos::rcp_dynamic_cast<ProductMultiVectorBase<Scalar> >(mv);
00786 if (nonnull(pmv))
00787 return pmv;
00788 return defaultProductMultiVector<Scalar>(productSpace, Teuchos::tuple(mv)());
00789 }
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799 #define THYRA_DEFAULT_PRODUCT_MULTI_VECTOR_INSTANT(SCALAR) \
00800 \
00801 template class DefaultProductMultiVector<SCALAR >; \
00802 \
00803 template RCP<DefaultProductMultiVector<SCALAR > > \
00804 defaultProductMultiVector(); \
00805 \
00806 \
00807 template RCP<DefaultProductMultiVector<SCALAR > > \
00808 defaultProductMultiVector( \
00809 const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
00810 const int numMembers \
00811 ); \
00812 \
00813 \
00814 template RCP<DefaultProductMultiVector<SCALAR > > \
00815 defaultProductMultiVector( \
00816 const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
00817 const ArrayView<const RCP<MultiVectorBase<SCALAR > > > &multiVecs \
00818 ); \
00819 \
00820 \
00821 template RCP<DefaultProductMultiVector<SCALAR > > \
00822 defaultProductMultiVector( \
00823 const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
00824 const ArrayView<const RCP<const MultiVectorBase<SCALAR > > > &multiVecs \
00825 ); \
00826 \
00827 \
00828 template RCP<const ProductMultiVectorBase<SCALAR > > \
00829 castOrCreateSingleBlockProductMultiVector( \
00830 const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
00831 const RCP<const MultiVectorBase<SCALAR > > &mv \
00832 ); \
00833 \
00834 \
00835 template RCP<ProductMultiVectorBase<SCALAR > > \
00836 nonconstCastOrCreateSingleBlockProductMultiVector( \
00837 const RCP<const DefaultProductVectorSpace<SCALAR > > &productSpace, \
00838 const RCP<MultiVectorBase<SCALAR > > &mv \
00839 );
00840
00841
00842 #endif // THYRA_DEFAULT_PRODUCT_MULTI_VECTOR_DEF_HPP