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_HPP
00030 #define THYRA_DEFAULT_PRODUCT_MULTI_VECTOR_HPP
00031
00032 #include "Thyra_DefaultProductMultiVectorDecl.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 const Teuchos::RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
00047 const int numMembers
00048 )
00049 :numBlocks_(0)
00050 {
00051 initialize(productSpace,numMembers);
00052 }
00053
00054
00055 template<class Scalar>
00056 DefaultProductMultiVector<Scalar>::DefaultProductMultiVector(
00057 const Teuchos::RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
00058 const Teuchos::RCP<MultiVectorBase<Scalar> > multiVecs[]
00059 )
00060 :numBlocks_(0)
00061 {
00062 initialize(productSpace,multiVecs);
00063 }
00064
00065
00066 template<class Scalar>
00067 DefaultProductMultiVector<Scalar>::DefaultProductMultiVector(
00068 const Teuchos::RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
00069 const Teuchos::RCP<const MultiVectorBase<Scalar> > multiVecs[]
00070 )
00071 :numBlocks_(0)
00072 {
00073 initialize(productSpace,multiVecs);
00074 }
00075
00076
00077 template<class Scalar>
00078 void DefaultProductMultiVector<Scalar>::initialize(
00079 const Teuchos::RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
00080 const int numMembers
00081 )
00082 {
00083 #ifdef TEUCHOS_DEBUG
00084 TEST_FOR_EXCEPT( is_null(productSpace) );
00085 TEST_FOR_EXCEPT( numMembers <= 0 );
00086 #endif
00087 Teuchos::Array<Teuchos::RCP<MultiVectorBase<Scalar> > >
00088 multiVecs;
00089 const int numBlocks = productSpace->numBlocks();
00090 for ( int k = 0; k < numBlocks; ++k )
00091 multiVecs.push_back(createMembers(productSpace->getBlock(k),numMembers));
00092 initialize(productSpace,&multiVecs[0]);
00093 }
00094
00095
00096 template<class Scalar>
00097 void DefaultProductMultiVector<Scalar>::initialize(
00098 const Teuchos::RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
00099 const Teuchos::RCP<MultiVectorBase<Scalar> > multiVecs[]
00100 )
00101 {
00102 initializeImpl(productSpace,multiVecs);
00103 }
00104
00105
00106 template<class Scalar>
00107 void DefaultProductMultiVector<Scalar>::initialize(
00108 const Teuchos::RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
00109 const Teuchos::RCP<const MultiVectorBase<Scalar> > multiVecs[]
00110 )
00111 {
00112 initializeImpl(productSpace,multiVecs);
00113 }
00114
00115
00116 template<class Scalar>
00117 void DefaultProductMultiVector<Scalar>::uninitialize()
00118 {
00119 productSpace_ = Teuchos::null;
00120 multiVecs_.resize(0);
00121 numBlocks_ = 0;
00122 }
00123
00124
00125
00126
00127
00128 template<class Scalar>
00129 std::string DefaultProductMultiVector<Scalar>::description() const
00130 {
00131 std::ostringstream oss;
00132 oss
00133 << Teuchos::Describable::description()
00134 << "{"
00135 << "rangeDim="<<this->range()->dim()
00136 << ",domainDim="<<this->domain()->dim()
00137 << ",numBlocks = "<<numBlocks_
00138 << "}";
00139 return oss.str();
00140 }
00141
00142
00143 template<class Scalar>
00144 void DefaultProductMultiVector<Scalar>::describe(
00145 Teuchos::FancyOStream &out_arg,
00146 const Teuchos::EVerbosityLevel verbLevel
00147 ) const
00148 {
00149 typedef Teuchos::ScalarTraits<Scalar> ST;
00150 using Teuchos::RCP;
00151 using Teuchos::FancyOStream;
00152 using Teuchos::OSTab;
00153 using Teuchos::describe;
00154 if (verbLevel == Teuchos::VERB_NONE)
00155 return;
00156 RCP<FancyOStream> out = rcp(&out_arg,false);
00157 OSTab tab(out);
00158 switch(verbLevel) {
00159 case Teuchos::VERB_DEFAULT:
00160 case Teuchos::VERB_LOW:
00161 *out << this->description() << std::endl;
00162 break;
00163 case Teuchos::VERB_MEDIUM:
00164 case Teuchos::VERB_HIGH:
00165 case Teuchos::VERB_EXTREME:
00166 {
00167 *out
00168 << Teuchos::Describable::description() << "{"
00169 << "rangeDim="<<this->range()->dim()
00170 << ",domainDim="<<this->domain()->dim()
00171 << "}\n";
00172 OSTab tab(out);
00173 *out
00174 << "numBlocks="<< numBlocks_ << std::endl
00175 << "Constituent multi-vector objects V[0], V[1], ... V[numBlocks-1]:\n";
00176 tab.incrTab();
00177 for( int k = 0; k < numBlocks_; ++k ) {
00178 *out << "V["<<k<<"] = "
00179 << Teuchos::describe(*multiVecs_[k].getConstObj(),verbLevel);
00180 }
00181 break;
00182 }
00183 default:
00184 TEST_FOR_EXCEPT(true);
00185 }
00186 }
00187
00188
00189
00190
00191
00192 template<class Scalar>
00193 Teuchos::RCP<const ProductVectorSpaceBase<Scalar> >
00194 DefaultProductMultiVector<Scalar>::productSpace() const
00195 {
00196 return productSpace_;
00197 }
00198
00199
00200 template<class Scalar>
00201 bool DefaultProductMultiVector<Scalar>::blockIsConst(const int k) const
00202 {
00203 return multiVecs_[k].isConst();
00204 }
00205
00206
00207 template<class Scalar>
00208 Teuchos::RCP<MultiVectorBase<Scalar> >
00209 DefaultProductMultiVector<Scalar>::getNonconstMultiVectorBlock(const int k)
00210 {
00211 return multiVecs_[k].getNonconstObj();
00212 }
00213
00214
00215 template<class Scalar>
00216 Teuchos::RCP<const MultiVectorBase<Scalar> >
00217 DefaultProductMultiVector<Scalar>::getMultiVectorBlock(const int k) const
00218 {
00219 return multiVecs_[k].getConstObj();
00220 }
00221
00222
00223
00224
00225
00226 template<class Scalar>
00227 Teuchos::RCP<const VectorBase<Scalar> >
00228 DefaultProductMultiVector<Scalar>::col(Index j) const
00229 {
00230 validateColIndex(j);
00231 Teuchos::Array<Teuchos::RCP<const VectorBase<Scalar> > > cols_;
00232 for ( int k = 0; k < numBlocks_; ++k )
00233 cols_.push_back(multiVecs_[k].getConstObj()->col(j));
00234 return defaultProductVector<Scalar>(productSpace_,&cols_[0]);
00235 }
00236
00237
00238 template<class Scalar>
00239 Teuchos::RCP<VectorBase<Scalar> >
00240 DefaultProductMultiVector<Scalar>::col(Index j)
00241 {
00242 validateColIndex(j);
00243 Teuchos::Array<Teuchos::RCP<VectorBase<Scalar> > > cols_;
00244 for ( int k = 0; k < numBlocks_; ++k )
00245 cols_.push_back(multiVecs_[k].getNonconstObj()->col(j));
00246 return defaultProductVector<Scalar>(productSpace_,&cols_[0]);
00247 }
00248
00249
00250 template<class Scalar>
00251 Teuchos::RCP<const MultiVectorBase<Scalar> >
00252 DefaultProductMultiVector<Scalar>::subView( const Range1D& colRng ) const
00253 {
00254 assertInitialized();
00255 Teuchos::Array<Teuchos::RCP<const MultiVectorBase<Scalar> > > blocks_;
00256 for ( int k = 0; k < numBlocks_; ++k )
00257 blocks_.push_back(multiVecs_[k].getConstObj()->subView(colRng));
00258 return defaultProductMultiVector<Scalar>(productSpace_,&blocks_[0]);
00259 }
00260
00261
00262 template<class Scalar>
00263 Teuchos::RCP<MultiVectorBase<Scalar> >
00264 DefaultProductMultiVector<Scalar>::subView( const Range1D& colRng )
00265 {
00266 assertInitialized();
00267 Teuchos::Array<Teuchos::RCP<MultiVectorBase<Scalar> > > blocks_;
00268 for ( int k = 0; k < numBlocks_; ++k )
00269 blocks_.push_back(multiVecs_[k].getNonconstObj()->subView(colRng));
00270 return defaultProductMultiVector<Scalar>(productSpace_,&blocks_[0]);
00271 }
00272
00273
00274 template<class Scalar>
00275 Teuchos::RCP<const MultiVectorBase<Scalar> >
00276 DefaultProductMultiVector<Scalar>::subView(
00277 const int numCols, const int cols[]
00278 ) const
00279 {
00280 assertInitialized();
00281 Teuchos::Array<Teuchos::RCP<const MultiVectorBase<Scalar> > > blocks_;
00282 for ( int k = 0; k < numBlocks_; ++k )
00283 blocks_.push_back(multiVecs_[k].getConstObj()->subView(numCols,cols));
00284 return defaultProductMultiVector<Scalar>(productSpace_,&blocks_[0]);
00285 }
00286
00287
00288 template<class Scalar>
00289 Teuchos::RCP<MultiVectorBase<Scalar> >
00290 DefaultProductMultiVector<Scalar>::subView(
00291 const int numCols, const int cols[]
00292 )
00293 {
00294 assertInitialized();
00295 Teuchos::Array<Teuchos::RCP<MultiVectorBase<Scalar> > > blocks_;
00296 for ( int k = 0; k < numBlocks_; ++k )
00297 blocks_.push_back(multiVecs_[k].getNonconstObj()->subView(numCols,cols));
00298 return defaultProductMultiVector<Scalar>(productSpace_,&blocks_[0]);
00299 }
00300
00301
00302 template<class Scalar>
00303 void DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(
00304 const RTOpPack::RTOpT<Scalar> &primary_op,
00305 const int num_multi_vecs,
00306 const MultiVectorBase<Scalar>*const multi_vecs_in[],
00307 const int num_targ_multi_vecs,
00308 MultiVectorBase<Scalar>*const targ_multi_vecs_inout[],
00309 RTOpPack::ReductTarget*const reduct_objs[],
00310 const Index primary_first_ele_offset_in,
00311 const Index primary_sub_dim_in,
00312 const Index primary_global_offset_in,
00313 const Index secondary_first_ele_offset_in,
00314 const Index secondary_sub_dim_in
00315 ) const
00316 {
00317
00318 using Teuchos::Array;
00319 using Teuchos::RCP;
00320 using Thyra::applyOp;
00321
00322 assertInitialized();
00323
00324 const Index domainDim = this->domain()->dim();
00325 const Index rangeDim = this->range()->dim();
00326
00327 #ifdef TEUCHOS_DEBUG
00328 TEST_FOR_EXCEPT( num_multi_vecs < 0 );
00329 TEST_FOR_EXCEPT( num_multi_vecs > 0 && multi_vecs_in == 0 );
00330 for ( int j = 0; j < num_multi_vecs; ++j ) {
00331 THYRA_ASSERT_VEC_SPACES(
00332 "DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(...)",
00333 *this->range(), *multi_vecs_in[j]->range()
00334 );
00335 THYRA_ASSERT_VEC_SPACES(
00336 "DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(...)",
00337 *this->domain(), *multi_vecs_in[j]->domain()
00338 );
00339 }
00340 TEST_FOR_EXCEPT( num_targ_multi_vecs < 0 );
00341 TEST_FOR_EXCEPT( num_targ_multi_vecs > 0 && targ_multi_vecs_inout == 0 );
00342 for ( int j = 0; j < num_targ_multi_vecs; ++j ) {
00343 THYRA_ASSERT_VEC_SPACES(
00344 "DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(...)",
00345 *this->range(), *targ_multi_vecs_inout[j]->range()
00346 );
00347 THYRA_ASSERT_VEC_SPACES(
00348 "DefaultProductMultiVector<Scalar>::mvMultiReductApplyOpImpl(...)",
00349 *this->domain(), *targ_multi_vecs_inout[j]->domain()
00350 );
00351 }
00352 TEST_FOR_EXCEPT(
00353 !(
00354 0 <= primary_first_ele_offset_in
00355 &&
00356 primary_first_ele_offset_in < rangeDim
00357 )
00358 );
00359 TEST_FOR_EXCEPT(
00360 primary_sub_dim_in > 0
00361 &&
00362 primary_first_ele_offset_in + primary_sub_dim_in > rangeDim
00363 );
00364 TEST_FOR_EXCEPT(
00365 !(
00366 0 <= secondary_first_ele_offset_in
00367 &&
00368 secondary_first_ele_offset_in < domainDim
00369 )
00370 );
00371 TEST_FOR_EXCEPT(
00372 secondary_sub_dim_in > 0
00373 &&
00374 secondary_first_ele_offset_in + secondary_sub_dim_in > domainDim
00375 );
00376 #endif // TEUCHOS_DEBUG
00377
00378 const Index primary_sub_dim
00379 = (
00380 primary_sub_dim_in < 0
00381 ? rangeDim - primary_first_ele_offset_in
00382 : primary_sub_dim_in
00383 );
00384 const Index secondary_sub_dim
00385 = (
00386 secondary_sub_dim_in < 0
00387 ? domainDim - secondary_first_ele_offset_in
00388 : secondary_sub_dim_in
00389 );
00390
00391
00392
00393
00394
00395
00396 bool allProductMultiVectors = true;
00397
00398 Array<const ProductMultiVectorBase<Scalar>*> multi_vecs;
00399 for ( int j = 0; j < num_multi_vecs && allProductMultiVectors; ++j ) {
00400 #ifdef TEUCHOS_DEBUG
00401 TEST_FOR_EXCEPT( multi_vecs_in[j] == 0 );
00402 #endif
00403 const ProductMultiVectorBase<Scalar>
00404 *multi_vecs_k = dynamic_cast<const ProductMultiVectorBase<Scalar>*>(
00405 multi_vecs_in[j]
00406 );
00407 if ( multi_vecs_k ) {
00408 multi_vecs.push_back(multi_vecs_k);
00409 }
00410 else {
00411 allProductMultiVectors = false;
00412 }
00413 }
00414
00415 Array<ProductMultiVectorBase<Scalar>*> targ_multi_vecs;
00416 for ( int j = 0; j < num_targ_multi_vecs && allProductMultiVectors; ++j )
00417 {
00418 #ifdef TEUCHOS_DEBUG
00419 TEST_FOR_EXCEPT( targ_multi_vecs_inout[j] == 0 );
00420 #endif
00421 ProductMultiVectorBase<Scalar>
00422 *targ_multi_vecs_k = dynamic_cast<ProductMultiVectorBase<Scalar>*>(
00423 targ_multi_vecs_inout[j]
00424 );
00425 if ( targ_multi_vecs_k ) {
00426 targ_multi_vecs.push_back(targ_multi_vecs_k);
00427 }
00428 else {
00429 allProductMultiVectors = false;
00430 }
00431 }
00432
00433
00434
00435
00436
00437 if ( allProductMultiVectors ) {
00438
00439
00440
00441
00442
00443
00444
00445
00446 Array<RCP<const MultiVectorBase<Scalar> > >
00447 multi_vecs_rcp_block_k(num_multi_vecs);
00448 Array<const MultiVectorBase<Scalar>*>
00449 multi_vecs_block_k(num_multi_vecs);
00450 Array<RCP<MultiVectorBase<Scalar> > >
00451 targ_multi_vecs_rcp_block_k(num_targ_multi_vecs);
00452 Array<MultiVectorBase<Scalar>*>
00453 targ_multi_vecs_block_k(num_targ_multi_vecs);
00454
00455 Index num_rows_remaining = primary_sub_dim;
00456 Index g_off = -primary_first_ele_offset_in;
00457
00458 for ( int k = 0; k < numBlocks_; ++k ) {
00459
00460
00461
00462 const Index local_dim = productSpace_->getBlock(k)->dim();
00463 if( g_off < 0 && -g_off+1 > local_dim ) {
00464 g_off += local_dim;
00465 continue;
00466 }
00467 const Index local_sub_dim
00468 = (
00469 g_off >= 0
00470 ? std::min( local_dim, num_rows_remaining )
00471 : std::min( local_dim + g_off, num_rows_remaining )
00472 );
00473 if( local_sub_dim <= 0 )
00474 break;
00475
00476
00477
00478 for ( int j = 0; j < num_multi_vecs; ++j ) {
00479 RCP<const MultiVectorBase<Scalar> >
00480 multi_vecs_rcp_block_k_j = multi_vecs[j]->getMultiVectorBlock(k);
00481 multi_vecs_rcp_block_k[j] = multi_vecs_rcp_block_k_j;
00482 multi_vecs_block_k[j] = &*multi_vecs_rcp_block_k_j;
00483 }
00484
00485 for ( int j = 0; j < num_targ_multi_vecs; ++j ) {
00486 RCP<MultiVectorBase<Scalar> >
00487 targ_multi_vecs_rcp_block_k_j = targ_multi_vecs[j]->getNonconstMultiVectorBlock(k);
00488 targ_multi_vecs_rcp_block_k[j] = targ_multi_vecs_rcp_block_k_j;
00489 targ_multi_vecs_block_k[j] = &*targ_multi_vecs_rcp_block_k_j;
00490 }
00491
00492
00493
00494 Thyra::applyOp<Scalar>(
00495 primary_op,
00496 num_multi_vecs, num_multi_vecs ? &multi_vecs_block_k[0] : 0,
00497 num_targ_multi_vecs, num_targ_multi_vecs ? &targ_multi_vecs_block_k[0] : 0,
00498 reduct_objs,
00499 g_off < 0 ? -g_off : 0,
00500 local_sub_dim,
00501 g_off < 0 ? primary_global_offset_in : primary_global_offset_in + g_off,
00502 secondary_first_ele_offset_in, secondary_sub_dim
00503 );
00504 }
00505
00506 }
00507 else {
00508
00509
00510
00511
00512
00513
00514 MultiVectorDefaultBase<Scalar>::mvMultiReductApplyOpImpl(
00515 primary_op,
00516 num_multi_vecs, multi_vecs_in,
00517 num_targ_multi_vecs, 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 template<class Scalar>
00576 Teuchos::RCP<MultiVectorBase<Scalar> >
00577 DefaultProductMultiVector<Scalar>::clone_mv() const
00578 {
00579 assertInitialized();
00580 Teuchos::Array<Teuchos::RCP<MultiVectorBase<Scalar> > > blocks_;
00581 for ( int k = 0; k < numBlocks_; ++k )
00582 blocks_.push_back(multiVecs_[k].getConstObj()->clone_mv());
00583 return defaultProductMultiVector<Scalar>(productSpace_,&blocks_[0]);
00584
00585
00586 return Teuchos::null;
00587
00588 TEST_FOR_EXCEPT(true);
00589 }
00590
00591
00592
00593
00594
00595 template<class Scalar>
00596 Teuchos::RCP< const VectorSpaceBase<Scalar> >
00597 DefaultProductMultiVector<Scalar>::range() const
00598 {
00599 return productSpace_;
00600 }
00601
00602
00603 template<class Scalar>
00604 Teuchos::RCP< const VectorSpaceBase<Scalar> >
00605 DefaultProductMultiVector<Scalar>::domain() const
00606 {
00607 if (is_null(productSpace_))
00608 return Teuchos::null;
00609 return multiVecs_[0].getConstObj()->domain();
00610 }
00611
00612
00613
00614
00615
00616 template<class Scalar>
00617 bool DefaultProductMultiVector<Scalar>::opSupported(ETransp M_trans) const
00618 {
00619 return true;
00620 }
00621
00622
00623 template<class Scalar>
00624 void DefaultProductMultiVector<Scalar>::apply(
00625 const ETransp M_trans,
00626 const MultiVectorBase<Scalar> &X_in,
00627 MultiVectorBase<Scalar> *Y_inout,
00628 const Scalar alpha,
00629 const Scalar beta
00630 ) const
00631 {
00632
00633 typedef Teuchos::ScalarTraits<Scalar> ST;
00634 using Teuchos::dyn_cast;
00635 using Thyra::apply;
00636
00637 #ifdef TEUCHOS_DEBUG
00638 THYRA_ASSERT_LINEAR_OP_MULTIVEC_APPLY_SPACES(
00639 "DefaultProductMultiVector<Scalar>::apply(...)",
00640 *this, M_trans, X_in, Y_inout );
00641 #endif
00642
00643 if ( real_trans(M_trans) == NOTRANS ) {
00644
00645
00646
00647
00648
00649
00650
00651 ProductMultiVectorBase<Scalar>
00652 &Y = dyn_cast<ProductMultiVectorBase<Scalar> >(*Y_inout);
00653 for ( int k = 0; k < numBlocks_; ++k ) {
00654 Thyra::apply(
00655 *multiVecs_[k].getConstObj(), M_trans,
00656 X_in, &*Y.getNonconstMultiVectorBlock(k),
00657 alpha, beta
00658 );
00659 }
00660 }
00661 else {
00662
00663
00664
00665
00666
00667
00668
00669 const ProductMultiVectorBase<Scalar>
00670 &X = dyn_cast<const ProductMultiVectorBase<Scalar> >(X_in);
00671 for ( int k = 0; k < numBlocks_; ++k ) {
00672 Teuchos::RCP<const MultiVectorBase<Scalar> >
00673 M_k = multiVecs_[k].getConstObj(),
00674 X_k = X.getMultiVectorBlock(k);
00675 if ( 0 == k ) {
00676 Thyra::apply( *M_k, M_trans, *X_k, &*Y_inout, alpha, beta );
00677 }
00678 else {
00679 Thyra::apply( *M_k, M_trans, *X_k, &*Y_inout, alpha, ST::one() );
00680 }
00681 }
00682 }
00683 }
00684
00685
00686
00687
00688
00689 template<class Scalar>
00690 template<class MultiVectorType>
00691 void DefaultProductMultiVector<Scalar>::initializeImpl(
00692 const Teuchos::RCP<const DefaultProductVectorSpace<Scalar> > &productSpace,
00693 const Teuchos::RCP<MultiVectorType> multiVecs[]
00694 )
00695 {
00696
00697
00698
00699 #ifdef TEUCHOS_DEBUG
00700 TEST_FOR_EXCEPT( is_null(productSpace) );
00701 TEST_FOR_EXCEPT( 0==multiVecs );
00702 #endif // TEUCHOS_DEBUG
00703 const Teuchos::RCP<const VectorSpaceBase<Scalar> >
00704 theDomain = multiVecs[0]->domain();
00705 const int numBlocks = productSpace->numBlocks();
00706 #ifdef TEUCHOS_DEBUG
00707 for ( int k = 0; k < numBlocks; ++k ) {
00708 THYRA_ASSERT_VEC_SPACES(
00709 Teuchos::TypeNameTraits<DefaultProductMultiVector<Scalar> >::name(),
00710 *theDomain, *multiVecs[k]->domain()
00711 );
00712 }
00713 #endif
00714 productSpace_ = productSpace;
00715 numBlocks_ = numBlocks;
00716 multiVecs_.resize(0);
00717 for ( int k = 0; k < numBlocks; ++k ) {
00718 multiVecs_.push_back(multiVecs[k]);
00719 }
00720 }
00721
00722
00723 #ifdef TEUCHOS_DEBUG
00724
00725
00726 template<class Scalar>
00727 void DefaultProductMultiVector<Scalar>::assertInitialized() const
00728 {
00729 TEST_FOR_EXCEPTION(
00730 is_null(productSpace_), std::logic_error,
00731 "Error, this DefaultProductMultiVector object is not intialized!"
00732 );
00733 }
00734
00735
00736 template<class Scalar>
00737 void DefaultProductMultiVector<Scalar>::validateColIndex(const int j) const
00738 {
00739 assertInitialized();
00740 const int domainDim = multiVecs_[0].getConstObj()->domain()->dim();
00741 TEST_FOR_EXCEPTION(
00742 ! ( 0 <= j && j < domainDim ), std::logic_error,
00743 "Error, the column index j = " << j << " does not fall in the range [0,"<<domainDim<<"]!"
00744 );
00745 }
00746
00747
00748 #endif // TEUCHOS_DEBUG
00749
00750 }
00751
00752
00753 #endif // THYRA_DEFAULT_PRODUCT_MULTI_VECTOR_HPP