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
00030 #ifndef THYRA_DEFAULT_BLOCKED_LINEAR_OP_DEF_HPP
00031 #define THYRA_DEFAULT_BLOCKED_LINEAR_OP_DEF_HPP
00032
00033
00034 #include "Thyra_DefaultBlockedLinearOp_decl.hpp"
00035 #include "Thyra_DefaultProductVectorSpace.hpp"
00036 #include "Thyra_DefaultProductVector.hpp"
00037 #include "Thyra_DefaultProductMultiVector.hpp"
00038 #include "Thyra_MultiVectorStdOps.hpp"
00039 #include "Thyra_AssertOp.hpp"
00040 #include "Teuchos_Utils.hpp"
00041
00042
00043 namespace Thyra {
00044
00045
00046
00047
00048
00049 template<class Scalar>
00050 DefaultBlockedLinearOp<Scalar>::DefaultBlockedLinearOp()
00051 :numRowBlocks_(0), numColBlocks_(0), blockFillIsActive_(false)
00052 {}
00053
00054
00055
00056
00057
00058 template<class Scalar>
00059 void DefaultBlockedLinearOp<Scalar>::beginBlockFill()
00060 {
00061 assertBlockFillIsActive(false);
00062 uninitialize();
00063 resetStorage(0,0);
00064 }
00065
00066
00067 template<class Scalar>
00068 void DefaultBlockedLinearOp<Scalar>::beginBlockFill(
00069 const int numRowBlocks, const int numColBlocks
00070 )
00071 {
00072 assertBlockFillIsActive(false);
00073 uninitialize();
00074 resetStorage(numRowBlocks,numColBlocks);
00075 }
00076
00077
00078 template<class Scalar>
00079 void DefaultBlockedLinearOp<Scalar>::beginBlockFill(
00080 const RCP<const ProductVectorSpaceBase<Scalar> > &productRange
00081 ,const RCP<const ProductVectorSpaceBase<Scalar> > &productDomain
00082 )
00083 {
00084 using Teuchos::rcp_dynamic_cast;
00085 assertBlockFillIsActive(false);
00086 uninitialize();
00087 productRange_ = productRange.assert_not_null();
00088 productDomain_ = productDomain.assert_not_null();
00089 defaultProductRange_ =
00090 rcp_dynamic_cast<const DefaultProductVectorSpace<Scalar> >(productRange_);
00091 defaultProductDomain_ =
00092 rcp_dynamic_cast<const DefaultProductVectorSpace<Scalar> >(productDomain_);
00093
00094 resetStorage(productRange_->numBlocks(), productDomain_->numBlocks());
00095 }
00096
00097
00098 template<class Scalar>
00099 bool DefaultBlockedLinearOp<Scalar>::blockFillIsActive() const
00100 {
00101 return blockFillIsActive_;
00102 }
00103
00104
00105 template<class Scalar>
00106 bool DefaultBlockedLinearOp<Scalar>::acceptsBlock(
00107 const int i, const int j
00108 ) const
00109 {
00110 assertBlockFillIsActive(true);
00111 assertBlockRowCol(i,j);
00112 return true;
00113 }
00114
00115
00116 template<class Scalar>
00117 void DefaultBlockedLinearOp<Scalar>::setNonconstBlock(
00118 const int i, const int j
00119 ,const RCP<LinearOpBase<Scalar> > &block
00120 )
00121 {
00122 setBlockImpl(i, j, block);
00123 }
00124
00125
00126 template<class Scalar>
00127 void DefaultBlockedLinearOp<Scalar>::setBlock(
00128 const int i, const int j
00129 ,const RCP<const LinearOpBase<Scalar> > &block
00130 )
00131 {
00132 setBlockImpl(i, j, block);
00133 }
00134
00135
00136 template<class Scalar>
00137 void DefaultBlockedLinearOp<Scalar>::endBlockFill()
00138 {
00139
00140 using Teuchos::as;
00141
00142 assertBlockFillIsActive(true);
00143
00144
00145
00146
00147
00148
00149 if (nonnull(productRange_)) {
00150 numRowBlocks_ = productRange_->numBlocks();
00151 numColBlocks_ = productDomain_->numBlocks();
00152 }
00153 else {
00154 numRowBlocks_ = rangeBlocks_.size();
00155 numColBlocks_ = domainBlocks_.size();
00156
00157
00158
00159 }
00160
00161
00162
00163 #ifdef TEUCHOS_DEBUG
00164 if (is_null(productRange_)) {
00165 for (int i = 0; i < numRowBlocks_; ++i) {
00166 TEST_FOR_EXCEPTION(
00167 !rangeBlocks_[i].get(), std::logic_error
00168 ,"DefaultBlockedLinearOp<Scalar>::endBlockFill():"
00169 " Error, no linear operator block for the i="<<i<<" block row was added"
00170 " and we can not complete the block fill!"
00171 );
00172 }
00173 for(int j = 0; j < numColBlocks_; ++j) {
00174 TEST_FOR_EXCEPTION(
00175 !domainBlocks_[j].get(), std::logic_error
00176 ,"DefaultBlockedLinearOp<Scalar>::endBlockFill():"
00177 " Error, no linear operator block for the j="
00178 <<j<<" block column was added"
00179 " and we can not complete the block fill!"
00180 );
00181 }
00182 }
00183 #endif
00184
00185
00186 if (Ops_stack_.size()) {
00187 Ops_.resize(numRowBlocks_*numColBlocks_);
00188 for ( int k = 0; k < as<int>(Ops_stack_.size()); ++k ) {
00189 const BlockEntry<Scalar> &block_i_j = Ops_stack_[k];
00190 Ops_[numRowBlocks_*block_i_j.j + block_i_j.i] = block_i_j.block;
00191 }
00192 Ops_stack_.resize(0);
00193 }
00194
00195
00196 if (is_null(productRange_)) {
00197 adjustBlockSpaces();
00198 defaultProductRange_ = productVectorSpace<Scalar>(rangeBlocks_());
00199 defaultProductDomain_ = productVectorSpace<Scalar>(domainBlocks_());
00200 productRange_ = defaultProductRange_;
00201 productDomain_ = defaultProductDomain_;
00202 }
00203
00204 rangeBlocks_.resize(0);
00205 domainBlocks_.resize(0);
00206
00207 blockFillIsActive_ = false;
00208
00209 }
00210
00211
00212 template<class Scalar>
00213 void DefaultBlockedLinearOp<Scalar>::uninitialize()
00214 {
00215 productRange_ = Teuchos::null;
00216 productDomain_ = Teuchos::null;
00217 numRowBlocks_ = 0;
00218 numColBlocks_ = 0;
00219 Ops_.resize(0);
00220 Ops_stack_.resize(0);
00221 rangeBlocks_.resize(0);
00222 domainBlocks_.resize(0);
00223 blockFillIsActive_ = false;
00224 }
00225
00226
00227
00228
00229
00230 template<class Scalar>
00231 RCP<const ProductVectorSpaceBase<Scalar> >
00232 DefaultBlockedLinearOp<Scalar>::productRange() const
00233 {
00234 return productRange_;
00235 }
00236
00237
00238 template<class Scalar>
00239 RCP<const ProductVectorSpaceBase<Scalar> >
00240 DefaultBlockedLinearOp<Scalar>::productDomain() const
00241 {
00242 return productDomain_;
00243 }
00244
00245
00246 template<class Scalar>
00247 bool DefaultBlockedLinearOp<Scalar>::blockExists(
00248 const int i, const int j
00249 ) const
00250 {
00251 assertBlockFillIsActive(false);
00252 assertBlockRowCol(i,j);
00253 return true;
00254 }
00255
00256
00257 template<class Scalar>
00258 bool DefaultBlockedLinearOp<Scalar>::blockIsConst(
00259 const int i, const int j
00260 ) const
00261 {
00262 #ifdef TEUCHOS_DEBUG
00263 TEST_FOR_EXCEPT(!blockExists(i,j));
00264 #endif
00265 assertBlockFillIsActive(false);
00266 assertBlockRowCol(i,j);
00267 return Ops_[numRowBlocks_*j+i].isConst();
00268 }
00269
00270
00271 template<class Scalar>
00272 RCP<LinearOpBase<Scalar> >
00273 DefaultBlockedLinearOp<Scalar>::getNonconstBlock(const int i, const int j)
00274 {
00275 #ifdef TEUCHOS_DEBUG
00276 TEST_FOR_EXCEPT(!blockExists(i,j));
00277 #endif
00278 assertBlockFillIsActive(false);
00279 assertBlockRowCol(i,j);
00280 return Ops_[numRowBlocks_*j+i].getNonconstObj();
00281 }
00282
00283
00284 template<class Scalar>
00285 RCP<const LinearOpBase<Scalar> >
00286 DefaultBlockedLinearOp<Scalar>::getBlock(const int i, const int j) const
00287 {
00288 #ifdef TEUCHOS_DEBUG
00289 TEST_FOR_EXCEPT(!blockExists(i,j));
00290 #endif
00291 assertBlockFillIsActive(false);
00292 assertBlockRowCol(i,j);
00293 return Ops_[numRowBlocks_*j+i];
00294 }
00295
00296
00297
00298
00299
00300 template<class Scalar>
00301 RCP< const VectorSpaceBase<Scalar> >
00302 DefaultBlockedLinearOp<Scalar>::range() const
00303 {
00304 return productRange_;
00305 }
00306
00307
00308 template<class Scalar>
00309 RCP< const VectorSpaceBase<Scalar> >
00310 DefaultBlockedLinearOp<Scalar>::domain() const
00311 {
00312 return productDomain_;
00313 }
00314
00315
00316 template<class Scalar>
00317 RCP<const LinearOpBase<Scalar> >
00318 DefaultBlockedLinearOp<Scalar>::clone() const
00319 {
00320 return Teuchos::null;
00321 }
00322
00323
00324
00325
00326
00327 template<class Scalar>
00328 std::string DefaultBlockedLinearOp<Scalar>::description() const
00329 {
00330 assertBlockFillIsActive(false);
00331 std::ostringstream oss;
00332 oss
00333 << Teuchos::Describable::description() << "{"
00334 << "numRowBlocks="<<numRowBlocks_
00335 << ",numColBlocks="<<numColBlocks_
00336 << "}";
00337 return oss.str();
00338 }
00339
00340
00341 template<class Scalar>
00342 void DefaultBlockedLinearOp<Scalar>::describe(
00343 Teuchos::FancyOStream &out_arg
00344 ,const Teuchos::EVerbosityLevel verbLevel
00345 ) const
00346 {
00347 typedef Teuchos::ScalarTraits<Scalar> ST;
00348 using Teuchos::rcpFromRef;
00349 using Teuchos::FancyOStream;
00350 using Teuchos::OSTab;
00351 assertBlockFillIsActive(false);
00352 RCP<FancyOStream> out = rcpFromRef(out_arg);
00353 OSTab tab(out);
00354 switch(verbLevel) {
00355 case Teuchos::VERB_DEFAULT:
00356 case Teuchos::VERB_LOW:
00357 *out << this->description() << std::endl;
00358 break;
00359 case Teuchos::VERB_MEDIUM:
00360 case Teuchos::VERB_HIGH:
00361 case Teuchos::VERB_EXTREME:
00362 {
00363 *out
00364 << Teuchos::Describable::description() << "{"
00365 << "rangeDim=" << this->range()->dim()
00366 << ",domainDim=" << this->domain()->dim()
00367 << ",numRowBlocks=" << numRowBlocks_
00368 << ",numColBlocks=" << numColBlocks_
00369 << "}\n";
00370 OSTab tab(out);
00371 *out
00372 << "Constituent LinearOpBase objects for M = [ Op[0,0] ..."
00373 << " ; ... ; ... Op[numRowBlocks-1,numColBlocks-1] ]:\n";
00374 tab.incrTab();
00375 for( int i = 0; i < numRowBlocks_; ++i ) {
00376 for( int j = 0; j < numColBlocks_; ++j ) {
00377 *out << "Op["<<i<<","<<j<<"] = ";
00378 RCP<const LinearOpBase<Scalar> >
00379 block_i_j = getBlock(i,j);
00380 if(block_i_j.get())
00381 *out << Teuchos::describe(*getBlock(i,j),verbLevel);
00382 else
00383 *out << "NULL\n";
00384 }
00385 }
00386 break;
00387 }
00388 default:
00389 TEST_FOR_EXCEPT(true);
00390 }
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400 template<class Scalar>
00401 bool DefaultBlockedLinearOp<Scalar>::opSupported(
00402 EOpTransp M_trans
00403 ) const
00404 {
00405 bool opSupported = true;
00406 for( int i = 0; i < numRowBlocks_; ++i ) {
00407 for( int j = 0; j < numColBlocks_; ++j ) {
00408 RCP<const LinearOpBase<Scalar> >
00409 block_i_j = getBlock(i,j);
00410 if( block_i_j.get() && !Thyra::opSupported(*block_i_j,M_trans) )
00411 opSupported = false;
00412 }
00413 }
00414 return opSupported;
00415 }
00416
00417
00418 template<class Scalar>
00419 void DefaultBlockedLinearOp<Scalar>::apply(
00420 const EOpTransp M_trans
00421 ,const MultiVectorBase<Scalar> &X_in
00422 ,MultiVectorBase<Scalar> *Y_inout
00423 ,const Scalar alpha
00424 ,const Scalar beta
00425 ) const
00426 {
00427
00428 using Teuchos::rcpFromRef;
00429 typedef Teuchos::ScalarTraits<Scalar> ST;
00430 typedef RCP<MultiVectorBase<Scalar> > MultiVectorPtr;
00431 typedef RCP<const MultiVectorBase<Scalar> > ConstMultiVectorPtr;
00432 typedef RCP<const LinearOpBase<Scalar> > ConstLinearOpPtr;
00433
00434 #ifdef TEUCHOS_DEBUG
00435 THYRA_ASSERT_LINEAR_OP_MULTIVEC_APPLY_SPACES(
00436 "DefaultBlockedLinearOp<Scalar>::apply(...)",*this,M_trans,X_in,Y_inout
00437 );
00438 #endif // TEUCHOS_DEBUG
00439
00440 const bool
00441 struct_transp = (real_trans(M_trans)!=NOTRANS);
00442 const int
00443 opNumRowBlocks = ( !struct_transp ? numRowBlocks_ : numColBlocks_ ),
00444 opNumColBlocks = ( !struct_transp ? numColBlocks_ : numRowBlocks_ );
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456 const RCP<const DefaultProductVectorSpace<Scalar> >
00457 defaultProductRange_op = ( real_trans(M_trans)==NOTRANS
00458 ? defaultProductRange_ : defaultProductDomain_ ),
00459 defaultProductDomain_op = ( real_trans(M_trans)==NOTRANS
00460 ? defaultProductDomain_ : defaultProductRange_ );
00461
00462 const RCP<const ProductMultiVectorBase<Scalar> >
00463 X = castOrCreateSingleBlockProductMultiVector<Scalar>(
00464 defaultProductDomain_op, rcpFromRef(X_in));
00465 const RCP<ProductMultiVectorBase<Scalar> >
00466 Y = nonconstCastOrCreateSingleBlockProductMultiVector<Scalar>(
00467 defaultProductRange_op, rcpFromRef(*Y_inout));
00468
00469 for( int i = 0; i < opNumRowBlocks; ++i ) {
00470 MultiVectorPtr Y_i = Y->getNonconstMultiVectorBlock(i);
00471 for( int j = 0; j < opNumColBlocks; ++j ) {
00472 ConstLinearOpPtr
00473 Op_i_j = ( !struct_transp ? getBlock(i,j) : getBlock(j,i) );
00474 ConstMultiVectorPtr
00475 X_j = X->getMultiVectorBlock(j);
00476 if(j==0) {
00477 if (nonnull(Op_i_j))
00478 Thyra::apply(*Op_i_j, M_trans,* X_j, Y_i.ptr(), alpha, beta);
00479 else
00480 scale(beta, Y_i.ptr());
00481 }
00482 else {
00483 if (nonnull(Op_i_j))
00484 Thyra::apply(*Op_i_j, M_trans, *X_j, Y_i.ptr(), alpha, ST::one());
00485 }
00486 }
00487 }
00488 }
00489
00490
00491
00492
00493
00494 template<class Scalar>
00495 void DefaultBlockedLinearOp<Scalar>::resetStorage(
00496 const int numRowBlocks, const int numColBlocks
00497 )
00498 {
00499 numRowBlocks_ = numRowBlocks;
00500 numColBlocks_ = numColBlocks;
00501 Ops_.resize(numRowBlocks_*numColBlocks_);
00502 if (is_null(productRange_)) {
00503 rangeBlocks_.resize(numRowBlocks);
00504 domainBlocks_.resize(numColBlocks);
00505 }
00506 blockFillIsActive_ = true;
00507 }
00508
00509
00510 template<class Scalar>
00511 void DefaultBlockedLinearOp<Scalar>::assertBlockFillIsActive(
00512 bool blockFillIsActive
00513 ) const
00514 {
00515 #ifdef TEUCHOS_DEBUG
00516 TEST_FOR_EXCEPT(!(blockFillIsActive_==blockFillIsActive));
00517 #endif
00518 }
00519
00520
00521 template<class Scalar>
00522 void DefaultBlockedLinearOp<Scalar>::assertBlockRowCol(
00523 const int i, const int j
00524 ) const
00525 {
00526 #ifdef TEUCHOS_DEBUG
00527 TEST_FOR_EXCEPTION(
00528 !( 0 <= i ), std::logic_error
00529 ,"Error, i="<<i<<" is invalid!"
00530 );
00531 TEST_FOR_EXCEPTION(
00532 !( 0 <= j ), std::logic_error
00533 ,"Error, j="<<j<<" is invalid!"
00534 );
00535
00536
00537 if(Ops_.size()) {
00538 TEST_FOR_EXCEPTION(
00539 !( 0 <= i && i < numRowBlocks_ ), std::logic_error
00540 ,"Error, i="<<i<<" does not fall in the range [0,"<<numRowBlocks_-1<<"]!"
00541 );
00542 TEST_FOR_EXCEPTION(
00543 !( 0 <= j && j < numColBlocks_ ), std::logic_error
00544 ,"Error, j="<<j<<" does not fall in the range [0,"<<numColBlocks_-1<<"]!"
00545 );
00546 }
00547 #endif
00548 }
00549
00550
00551 template<class Scalar>
00552 void DefaultBlockedLinearOp<Scalar>::setBlockSpaces(
00553 const int i, const int j, const LinearOpBase<Scalar> &block
00554 )
00555 {
00556
00557 typedef std::string s;
00558 using Teuchos::toString;
00559 assertBlockFillIsActive(true);
00560 assertBlockRowCol(i,j);
00561
00562
00563
00564 if( i < numRowBlocks_ && j < numColBlocks_ ) {
00565 #ifdef TEUCHOS_DEBUG
00566 RCP<const VectorSpaceBase<Scalar> >
00567 rangeBlock = (
00568 productRange_.get()
00569 ? productRange_->getBlock(i)
00570 : rangeBlocks_[i]
00571 ),
00572 domainBlock = (
00573 productDomain_.get()
00574 ? productDomain_->getBlock(j)
00575 : domainBlocks_[j]
00576 );
00577 if(rangeBlock.get()) {
00578 THYRA_ASSERT_VEC_SPACES_NAMES(
00579 "DefaultBlockedLinearOp<Scalar>::setBlockSpaces(i,j,block):\n\n"
00580 "Adding block: " + block.description(),
00581 *rangeBlock,("(*productRange->getBlock("+toString(i)+"))"),
00582 *block.range(),("(*block["+toString(i)+","+toString(j)+"].range())")
00583 );
00584 }
00585 if(domainBlock.get()) {
00586 THYRA_ASSERT_VEC_SPACES_NAMES(
00587 "DefaultBlockedLinearOp<Scalar>::setBlockSpaces(i,j,block):\n\n"
00588 "Adding block: " + block.description(),
00589 *domainBlock,("(*productDomain->getBlock("+toString(j)+"))"),
00590 *block.domain(),("(*block["+toString(i)+","+toString(j)+"].domain())")
00591 );
00592 }
00593 #endif // TEUCHOS_DEBUG
00594 }
00595
00596
00597
00598 for( int k = numRowBlocks_; k <= i; ++k )
00599 rangeBlocks_.push_back(Teuchos::null);
00600 for( int k = numColBlocks_; k <= j; ++k )
00601 domainBlocks_.push_back(Teuchos::null);
00602
00603
00604 if(!productRange_.get()) {
00605 if(!rangeBlocks_[i].get())
00606 rangeBlocks_[i] = block.range().assert_not_null();
00607 if(!domainBlocks_[j].get()) {
00608 domainBlocks_[j] = block.domain().assert_not_null();
00609 }
00610 }
00611
00612
00613
00614 if(!Ops_.size()) {
00615 numRowBlocks_ = rangeBlocks_.size();
00616 numColBlocks_ = domainBlocks_.size();
00617 }
00618
00619 }
00620
00621
00622 template<class Scalar>
00623 template<class LinearOpType>
00624 void DefaultBlockedLinearOp<Scalar>::setBlockImpl(
00625 const int i, const int j,
00626 const RCP<LinearOpType> &block
00627 )
00628 {
00629 setBlockSpaces(i, j, *block);
00630 if (Ops_.size()) {
00631
00632
00633 Ops_[numRowBlocks_*j+i] = block;
00634 }
00635 else {
00636
00637
00638 bool foundBlock = false;
00639 for( unsigned int k = 0; k < Ops_stack_.size(); ++k ) {
00640 BlockEntry<Scalar> &block_i_j = Ops_stack_[k];
00641 if( block_i_j.i == i && block_i_j.j == j ) {
00642 block_i_j.block = block;
00643 foundBlock = true;
00644 break;
00645 }
00646 }
00647 if(!foundBlock)
00648 Ops_stack_.push_back(BlockEntry<Scalar>(i,j,block));
00649 }
00650 }
00651
00652
00653 template<class Scalar>
00654 void DefaultBlockedLinearOp<Scalar>::adjustBlockSpaces()
00655 {
00656
00657 #ifdef TEUCHOS_DEBUG
00658 TEUCHOS_ASSERT_INEQUALITY(Ops_.size(), !=, 0);
00659 #endif
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673 for (int i = 0; i < numRowBlocks_; ++i) {
00674 for (int j = 0; j < numColBlocks_; ++j) {
00675 const RCP<const LinearOpBase<Scalar> >
00676 op_i_j = Ops_[numRowBlocks_*j+i];
00677 if (is_null(op_i_j))
00678 continue;
00679 const RCP<const VectorSpaceBase<Scalar> > range_i_j = op_i_j->range();
00680 if (is_null(productVectorSpaceBase<Scalar>(range_i_j, false))) {
00681 rangeBlocks_[i] = range_i_j;
00682 break;
00683 }
00684 }
00685 }
00686
00687
00688 for (int j = 0; j < numColBlocks_; ++j) {
00689 for (int i = 0; i < numRowBlocks_; ++i) {
00690 const RCP<const LinearOpBase<Scalar> >
00691 op_i_j = Ops_[numRowBlocks_*j+i];
00692 if (is_null(op_i_j))
00693 continue;
00694 const RCP<const VectorSpaceBase<Scalar> >
00695 domain_i_j = op_i_j->domain();
00696 if (is_null(productVectorSpaceBase<Scalar>(domain_i_j, false))) {
00697 domainBlocks_[j] = domain_i_j;
00698 break;
00699 }
00700 }
00701 }
00702
00703 }
00704
00705
00706 }
00707
00708
00709 template<class Scalar>
00710 Teuchos::RCP<Thyra::DefaultBlockedLinearOp<Scalar> >
00711 Thyra::defaultBlockedLinearOp()
00712 {
00713 return Teuchos::rcp(new DefaultBlockedLinearOp<Scalar>());
00714 }
00715
00716
00717 template<class Scalar>
00718 Teuchos::RCP<const Thyra::LinearOpBase<Scalar> >
00719 Thyra::block1x1(
00720 const RCP<const LinearOpBase<Scalar> > &A00,
00721 const std::string &label
00722 )
00723 {
00724 RCP<PhysicallyBlockedLinearOpBase<Scalar> >
00725 M = defaultBlockedLinearOp<Scalar>();
00726 M->beginBlockFill(1,1);
00727 M->setBlock(0, 0, A00);
00728 M->endBlockFill();
00729 if (label.length())
00730 M->setObjectLabel(label);
00731 return M;
00732 }
00733
00734
00735 template<class Scalar>
00736 Teuchos::RCP<const Thyra::LinearOpBase<Scalar> >
00737 Thyra::block1x2(
00738 const RCP<const LinearOpBase<Scalar> > &A00,
00739 const RCP<const LinearOpBase<Scalar> > &A01,
00740 const std::string &label
00741 )
00742 {
00743 RCP<PhysicallyBlockedLinearOpBase<Scalar> >
00744 M = defaultBlockedLinearOp<Scalar>();
00745 M->beginBlockFill(1,2);
00746 if(A00.get()) M->setBlock(0,0,A00);
00747 if(A01.get()) M->setBlock(0,1,A01);
00748 M->endBlockFill();
00749 if (label.length())
00750 M->setObjectLabel(label);
00751 return M;
00752 }
00753
00754
00755 template<class Scalar>
00756 Teuchos::RCP<const Thyra::LinearOpBase<Scalar> >
00757 Thyra::block2x1(
00758 const RCP<const LinearOpBase<Scalar> > &A00,
00759 const RCP<const LinearOpBase<Scalar> > &A10,
00760 const std::string &label
00761 )
00762 {
00763 RCP<PhysicallyBlockedLinearOpBase<Scalar> >
00764 M = defaultBlockedLinearOp<Scalar>();
00765 M->beginBlockFill(2,1);
00766 if(A00.get()) M->setBlock(0,0,A00);
00767 if(A10.get()) M->setBlock(1,0,A10);
00768 M->endBlockFill();
00769 if (label.length())
00770 M->setObjectLabel(label);
00771 return M;
00772 }
00773
00774
00775 template<class Scalar>
00776 Teuchos::RCP<const Thyra::LinearOpBase<Scalar> >
00777 Thyra::block2x2(
00778 const RCP<const LinearOpBase<Scalar> > &A00,
00779 const RCP<const LinearOpBase<Scalar> > &A01,
00780 const RCP<const LinearOpBase<Scalar> > &A10,
00781 const RCP<const LinearOpBase<Scalar> > &A11,
00782 const std::string &label
00783 )
00784 {
00785 RCP<PhysicallyBlockedLinearOpBase<Scalar> >
00786 M = defaultBlockedLinearOp<Scalar>();
00787 M->beginBlockFill(2,2);
00788 if(A00.get()) M->setBlock(0,0,A00);
00789 if(A01.get()) M->setBlock(0,1,A01);
00790 if(A10.get()) M->setBlock(1,0,A10);
00791 if(A11.get()) M->setBlock(1,1,A11);
00792 M->endBlockFill();
00793 if (label.length())
00794 M->setObjectLabel(label);
00795 return M;
00796 }
00797
00798
00799 template<class Scalar>
00800 Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
00801 Thyra::nonconstBlock1x1(
00802 const RCP<LinearOpBase<Scalar> > &A00,
00803 const std::string &label
00804 )
00805 {
00806 RCP<PhysicallyBlockedLinearOpBase<Scalar> >
00807 M = defaultBlockedLinearOp<Scalar>();
00808 M->beginBlockFill(1, 1);
00809 M->setNonconstBlock(0, 0, A00);
00810 M->endBlockFill();
00811 if (label.length())
00812 M->setObjectLabel(label);
00813 return M;
00814 }
00815
00816
00817 template<class Scalar>
00818 Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
00819 Thyra::nonconstBlock1x2(
00820 const RCP<LinearOpBase<Scalar> > &A00,
00821 const RCP<LinearOpBase<Scalar> > &A01,
00822 const std::string &label
00823 )
00824 {
00825 RCP<PhysicallyBlockedLinearOpBase<Scalar> >
00826 M = defaultBlockedLinearOp<Scalar>();
00827 M->beginBlockFill(1,2);
00828 if(A00.get()) M->setNonconstBlock(0,0,A00);
00829 if(A01.get()) M->setNonconstBlock(0,1,A01);
00830 M->endBlockFill();
00831 if (label.length())
00832 M->setObjectLabel(label);
00833 return M;
00834 }
00835
00836
00837 template<class Scalar>
00838 Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
00839 Thyra::nonconstBlock2x1(
00840 const RCP<LinearOpBase<Scalar> > &A00,
00841 const RCP<LinearOpBase<Scalar> > &A10,
00842 const std::string &label
00843 )
00844 {
00845 RCP<PhysicallyBlockedLinearOpBase<Scalar> >
00846 M = defaultBlockedLinearOp<Scalar>();
00847 M->beginBlockFill(2,1);
00848 if(A00.get()) M->setNonconstBlock(0,0,A00);
00849 if(A10.get()) M->setNonconstBlock(1,0,A10);
00850 M->endBlockFill();
00851 if (label.length())
00852 M->setObjectLabel(label);
00853 return M;
00854 }
00855
00856
00857 template<class Scalar>
00858 Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
00859 Thyra::nonconstBlock2x2(
00860 const RCP<LinearOpBase<Scalar> > &A00,
00861 const RCP<LinearOpBase<Scalar> > &A01,
00862 const RCP<LinearOpBase<Scalar> > &A10,
00863 const RCP<LinearOpBase<Scalar> > &A11,
00864 const std::string &label
00865 )
00866 {
00867 RCP<PhysicallyBlockedLinearOpBase<Scalar> >
00868 M = defaultBlockedLinearOp<Scalar>();
00869 M->beginBlockFill(2,2);
00870 if(A00.get()) M->setNonconstBlock(0,0,A00);
00871 if(A01.get()) M->setNonconstBlock(0,1,A01);
00872 if(A10.get()) M->setNonconstBlock(1,0,A10);
00873 if(A11.get()) M->setNonconstBlock(1,1,A11);
00874 M->endBlockFill();
00875 if (label.length())
00876 M->setObjectLabel(label);
00877 return M;
00878 }
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888 #define THYRA_DEFAULT_BLOCKED_LINEAR_OP_INSTANT(SCALAR) \
00889 \
00890 template class DefaultBlockedLinearOp<SCALAR >; \
00891 \
00892 template RCP<DefaultBlockedLinearOp<SCALAR > > \
00893 defaultBlockedLinearOp(); \
00894 \
00895 template RCP<const LinearOpBase<SCALAR > > \
00896 block1x1( \
00897 const RCP<const LinearOpBase<SCALAR > > &A00, \
00898 const std::string &label \
00899 ); \
00900 \
00901 template RCP<const LinearOpBase<SCALAR > > \
00902 block1x2( \
00903 const RCP<const LinearOpBase<SCALAR > > &A00, \
00904 const RCP<const LinearOpBase<SCALAR > > &A01, \
00905 const std::string &label \
00906 ); \
00907 \
00908 template RCP<const LinearOpBase<SCALAR > > \
00909 block2x1( \
00910 const RCP<const LinearOpBase<SCALAR > > &A00, \
00911 const RCP<const LinearOpBase<SCALAR > > &A10, \
00912 const std::string &label \
00913 ); \
00914 \
00915 template RCP<const LinearOpBase<SCALAR > > \
00916 block2x2( \
00917 const RCP<const LinearOpBase<SCALAR > > &A00, \
00918 const RCP<const LinearOpBase<SCALAR > > &A01, \
00919 const RCP<const LinearOpBase<SCALAR > > &A10, \
00920 const RCP<const LinearOpBase<SCALAR > > &A11, \
00921 const std::string &label \
00922 ); \
00923 \
00924 template RCP<LinearOpBase<SCALAR > > \
00925 nonconstBlock1x1( \
00926 const RCP<LinearOpBase<SCALAR > > &A00, \
00927 const std::string &label \
00928 ); \
00929 \
00930 template RCP<LinearOpBase<SCALAR > > \
00931 nonconstBlock1x2( \
00932 const RCP<LinearOpBase<SCALAR > > &A00, \
00933 const RCP<LinearOpBase<SCALAR > > &A01, \
00934 const std::string &label \
00935 ); \
00936 \
00937 template RCP<LinearOpBase<SCALAR > > \
00938 nonconstBlock2x1( \
00939 const RCP<LinearOpBase<SCALAR > > &A00, \
00940 const RCP<LinearOpBase<SCALAR > > &A10, \
00941 const std::string &label \
00942 ); \
00943 \
00944 template RCP<LinearOpBase<SCALAR > > \
00945 nonconstBlock2x2( \
00946 const RCP<LinearOpBase<SCALAR > > &A00, \
00947 const RCP<LinearOpBase<SCALAR > > &A01, \
00948 const RCP<LinearOpBase<SCALAR > > &A10, \
00949 const RCP<LinearOpBase<SCALAR > > &A11, \
00950 const std::string &label \
00951 );
00952
00953
00954 #endif // THYRA_DEFAULT_BLOCKED_LINEAR_OP_DEF_HPP