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_BLOCKED_TRIANGULAR_LINEAR_OP_WITH_SOLVE_HPP
00030 #define THYRA_DEFAULT_BLOCKED_TRIANGULAR_LINEAR_OP_WITH_SOLVE_HPP
00031
00032
00033 #include "Thyra_DefaultBlockedTriangularLinearOpWithSolveDecl.hpp"
00034
00035
00036 namespace Thyra {
00037
00038
00039
00040
00041
00042
00043
00044
00045 template<class Scalar>
00046 DefaultBlockedTriangularLinearOpWithSolve<Scalar>::DefaultBlockedTriangularLinearOpWithSolve()
00047 : blockFillIsActive_(false), numDiagBlocks_(0)
00048 {}
00049
00050
00051
00052
00053
00054 template<class Scalar>
00055 bool DefaultBlockedTriangularLinearOpWithSolve<Scalar>::acceptsLOWSBlock(
00056 const int i, const int j
00057 ) const
00058 {
00059 assertBlockFillIsActive(true);
00060 assertBlockRowCol(i,j);
00061 return i==j;
00062 }
00063
00064 template<class Scalar>
00065 void DefaultBlockedTriangularLinearOpWithSolve<Scalar>::setNonconstLOWSBlock(
00066 const int i, const int j,
00067 const Teuchos::RCP<LinearOpWithSolveBase<Scalar> > &block
00068 )
00069 {
00070 setLOWSBlockImpl(i,j,block);
00071 }
00072
00073
00074 template<class Scalar>
00075 void DefaultBlockedTriangularLinearOpWithSolve<Scalar>::setLOWSBlock(
00076 const int i, const int j,
00077 const Teuchos::RCP<const LinearOpWithSolveBase<Scalar> > &block
00078 )
00079 {
00080 setLOWSBlockImpl(i,j,block);
00081 }
00082
00083
00084
00085
00086
00087 template<class Scalar>
00088 void DefaultBlockedTriangularLinearOpWithSolve<Scalar>::beginBlockFill()
00089 {
00090 assertBlockFillIsActive(false);
00091 TEST_FOR_EXCEPT("ToDo: Have not implemented flexible block fill yet!");
00092 }
00093
00094
00095 template<class Scalar>
00096 void DefaultBlockedTriangularLinearOpWithSolve<Scalar>::beginBlockFill(
00097 const int numRowBlocks, const int numColBlocks
00098 )
00099 {
00100 assertBlockFillIsActive(false);
00101 TEST_FOR_EXCEPT("ToDo: Have not implemented block fill with just numBlocks yet!!");
00102 }
00103
00104
00105 template<class Scalar>
00106 void DefaultBlockedTriangularLinearOpWithSolve<Scalar>::beginBlockFill(
00107 const Teuchos::RCP<const ProductVectorSpaceBase<Scalar> > &productRange,
00108 const Teuchos::RCP<const ProductVectorSpaceBase<Scalar> > &productDomain
00109 )
00110 {
00111 assertBlockFillIsActive(false);
00112 TEST_FOR_EXCEPT( is_null(productRange) );
00113 TEST_FOR_EXCEPT( is_null(productDomain) );
00114 TEST_FOR_EXCEPT( productRange->numBlocks() != productDomain->numBlocks() );
00115 productRange_ = productRange.assert_not_null();
00116 productDomain_ = productDomain.assert_not_null();
00117 numDiagBlocks_ = productRange->numBlocks();
00118 diagonalBlocks_.resize(numDiagBlocks_);
00119 blockFillIsActive_ = true;
00120 }
00121
00122
00123 template<class Scalar>
00124 bool DefaultBlockedTriangularLinearOpWithSolve<Scalar>::blockFillIsActive() const
00125 {
00126 return blockFillIsActive_;
00127 }
00128
00129
00130 template<class Scalar>
00131 bool DefaultBlockedTriangularLinearOpWithSolve<Scalar>::acceptsBlock(
00132 const int i, const int j
00133 ) const
00134 {
00135 assertBlockFillIsActive(true);
00136 assertBlockRowCol(i,j);
00137 return false;
00138 }
00139
00140
00141 template<class Scalar>
00142 void DefaultBlockedTriangularLinearOpWithSolve<Scalar>::setNonconstBlock(
00143 const int i, const int j,
00144 const Teuchos::RCP<LinearOpBase<Scalar> > &block
00145 )
00146 {
00147 assertBlockFillIsActive(true);
00148 TEST_FOR_EXCEPT("Error, we don't support off-diagonal LOB objects yet!");
00149 }
00150
00151
00152 template<class Scalar>
00153 void DefaultBlockedTriangularLinearOpWithSolve<Scalar>::setBlock(
00154 const int i, const int j,
00155 const Teuchos::RCP<const LinearOpBase<Scalar> > &block
00156 )
00157 {
00158 assertBlockFillIsActive(true);
00159 TEST_FOR_EXCEPT("Error, we don't support off-diagonal LOB objects yet!");
00160 }
00161
00162
00163 template<class Scalar>
00164 void DefaultBlockedTriangularLinearOpWithSolve<Scalar>::endBlockFill()
00165 {
00166 assertBlockFillIsActive(true);
00167 for ( int k = 0; k < numDiagBlocks_; ++k ) {
00168 TEST_FOR_EXCEPTION(
00169 is_null(diagonalBlocks_[k].getConstObj()), std::logic_error,
00170 "Error, the block diagonal k="<<k<<" can not be null when ending block fill!"
00171 );
00172 }
00173 blockFillIsActive_ = false;
00174 }
00175
00176
00177 template<class Scalar>
00178 void DefaultBlockedTriangularLinearOpWithSolve<Scalar>::uninitialize()
00179 {
00180 assertBlockFillIsActive(false);
00181 productRange_ = Teuchos::null;
00182 productDomain_ = Teuchos::null;
00183 numDiagBlocks_ = 0;
00184 diagonalBlocks_.resize(0);
00185 }
00186
00187
00188
00189
00190
00191 template<class Scalar>
00192 Teuchos::RCP<LinearOpWithSolveBase<Scalar> >
00193 DefaultBlockedTriangularLinearOpWithSolve<Scalar>::getNonconstLOWSBlock(
00194 const int i, const int j
00195 )
00196 {
00197 assertBlockFillIsActive(false);
00198 assertBlockRowCol(i,j);
00199 if (i!=j)
00200 return Teuchos::null;
00201 return diagonalBlocks_[i].getNonconstObj();
00202 }
00203
00204
00205 template<class Scalar>
00206 Teuchos::RCP<const LinearOpWithSolveBase<Scalar> >
00207 DefaultBlockedTriangularLinearOpWithSolve<Scalar>::getLOWSBlock(
00208 const int i, const int j
00209 ) const
00210 {
00211 assertBlockFillIsActive(false);
00212 assertBlockRowCol(i,j);
00213 if (i!=j)
00214 return Teuchos::null;
00215 return diagonalBlocks_[i].getConstObj();
00216 }
00217
00218
00219
00220
00221
00222 template<class Scalar>
00223 Teuchos::RCP<const ProductVectorSpaceBase<Scalar> >
00224 DefaultBlockedTriangularLinearOpWithSolve<Scalar>::productRange() const
00225 {
00226 return productRange_;
00227 }
00228
00229
00230 template<class Scalar>
00231 Teuchos::RCP<const ProductVectorSpaceBase<Scalar> >
00232 DefaultBlockedTriangularLinearOpWithSolve<Scalar>::productDomain() const
00233 {
00234 return productDomain_;
00235 }
00236
00237
00238 template<class Scalar>
00239 bool DefaultBlockedTriangularLinearOpWithSolve<Scalar>::blockExists(
00240 const int i, const int j
00241 ) const
00242 {
00243 assertBlockFillIsActive(false);
00244 assertBlockRowCol(i,j);
00245 if (i!=j)
00246 return false;
00247 return !is_null(diagonalBlocks_[i].getConstObj());
00248 }
00249
00250
00251 template<class Scalar>
00252 bool DefaultBlockedTriangularLinearOpWithSolve<Scalar>::blockIsConst(
00253 const int i, const int j
00254 ) const
00255 {
00256 assertBlockFillIsActive(true);
00257 assertBlockRowCol(i,j);
00258 return diagonalBlocks_[i].isConst();
00259 }
00260
00261
00262 template<class Scalar>
00263 Teuchos::RCP<LinearOpBase<Scalar> >
00264 DefaultBlockedTriangularLinearOpWithSolve<Scalar>::getNonconstBlock(
00265 const int i, const int j
00266 )
00267 {
00268 assertBlockFillIsActive(true);
00269 assertBlockRowCol(i,j);
00270 if (i!=j)
00271 return Teuchos::null;
00272 return this->getNonconstLOWSBlock(i,j);
00273 }
00274
00275
00276 template<class Scalar>
00277 Teuchos::RCP<const LinearOpBase<Scalar> >
00278 DefaultBlockedTriangularLinearOpWithSolve<Scalar>::getBlock(
00279 const int i, const int j
00280 ) const
00281 {
00282 assertBlockFillIsActive(true);
00283 assertBlockRowCol(i,j);
00284 if (i!=j)
00285 return Teuchos::null;
00286 return this->getLOWSBlock(i,j);
00287 }
00288
00289
00290
00291
00292
00293 template<class Scalar>
00294 Teuchos::RCP< const VectorSpaceBase<Scalar> >
00295 DefaultBlockedTriangularLinearOpWithSolve<Scalar>::range() const
00296 {
00297 return this->productRange();
00298 }
00299
00300
00301 template<class Scalar>
00302 Teuchos::RCP< const VectorSpaceBase<Scalar> >
00303 DefaultBlockedTriangularLinearOpWithSolve<Scalar>::domain() const
00304 {
00305 return this->productDomain();
00306 }
00307
00308
00309 template<class Scalar>
00310 Teuchos::RCP<const LinearOpBase<Scalar> >
00311 DefaultBlockedTriangularLinearOpWithSolve<Scalar>::clone() const
00312 {
00313 return Teuchos::null;
00314 }
00315
00316
00317
00318
00319
00320 template<class Scalar>
00321 std::string
00322 DefaultBlockedTriangularLinearOpWithSolve<Scalar>::description() const
00323 {
00324 typedef Teuchos::ScalarTraits<Scalar> ST;
00325 assertBlockFillIsActive(false);
00326 std::ostringstream oss;
00327 oss
00328 << Teuchos::Describable::description() << "{"
00329 << "numDiagBlocks="<<numDiagBlocks_
00330 << "}";
00331 return oss.str();
00332 }
00333
00334
00335 template<class Scalar>
00336 void DefaultBlockedTriangularLinearOpWithSolve<Scalar>::describe(
00337 Teuchos::FancyOStream &out,
00338 const Teuchos::EVerbosityLevel verbLevel
00339 ) const
00340 {
00341 assertBlockFillIsActive(false);
00342 Teuchos::Describable::describe(out,verbLevel);
00343
00344 }
00345
00346
00347
00348
00349
00350
00351
00352
00353 template<class Scalar>
00354 bool DefaultBlockedTriangularLinearOpWithSolve<Scalar>::solveSupportsTrans(
00355 ETransp M_trans
00356 ) const
00357 {
00358 assertBlockFillIsActive(false);
00359 for ( int k = 0; k < numDiagBlocks_; ++k ) {
00360 if ( !solveSupports( *diagonalBlocks_[k].getConstObj(), M_trans ) )
00361 return false;
00362 }
00363 return true;
00364
00365
00366
00367 }
00368
00369
00370 template<class Scalar>
00371 bool
00372 DefaultBlockedTriangularLinearOpWithSolve<Scalar>::solveSupportsSolveMeasureType(
00373 ETransp M_trans, const SolveMeasureType& solveMeasureType
00374 ) const
00375 {
00376 using Thyra::solveSupportsSolveMeasureType;
00377 assertBlockFillIsActive(false);
00378 for ( int k = 0; k < numDiagBlocks_; ++k ) {
00379 if (
00380 !solveSupportsSolveMeasureType(
00381 *diagonalBlocks_[k].getConstObj(),
00382 M_trans, solveMeasureType
00383 )
00384 )
00385 {
00386 return false;
00387 }
00388 }
00389 return true;
00390
00391
00392
00393 }
00394
00395
00396 template<class Scalar>
00397 void DefaultBlockedTriangularLinearOpWithSolve<Scalar>::solve(
00398 const ETransp M_trans,
00399 const MultiVectorBase<Scalar> &B_in,
00400 MultiVectorBase<Scalar> *X_inout,
00401 const int numBlocks,
00402 const BlockSolveCriteria<Scalar> blockSolveCriteria[],
00403 SolveStatus<Scalar> blockSolveStatus[]
00404 ) const
00405 {
00406
00407 using Teuchos::RCP;
00408 using Teuchos::dyn_cast;
00409 typedef Teuchos::ScalarTraits<Scalar> ST;
00410 using Thyra::solve;
00411
00412 #ifdef TEUCHOS_DEBUG
00413 TEST_FOR_EXCEPT(0==X_inout);
00414 THYRA_ASSERT_LINEAR_OP_MULTIVEC_APPLY_SPACES(
00415 "DefaultBlockedTriangularLinearOpWithSolve<Scalar>::apply(...)",*this,M_trans,*X_inout,&B_in
00416 );
00417 TEST_FOR_EXCEPT(!this->solveSupportsTrans(M_trans));
00418 TEST_FOR_EXCEPT( numBlocks > 1 );
00419 TEST_FOR_EXCEPTION(
00420 blockSolveCriteria && !blockSolveCriteria[0].solveCriteria.solveMeasureType.useDefault(),
00421 std::logic_error,
00422 "Error, we can't handle any non-default solve criteria yet!"
00423 );
00424
00425
00426 #endif // TEUCHOS_DEBUG
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438 const ProductMultiVectorBase<Scalar>
00439 &B = dyn_cast<const ProductMultiVectorBase<Scalar> >(B_in);
00440 ProductMultiVectorBase<Scalar>
00441 &X = dyn_cast<ProductMultiVectorBase<Scalar> >(*X_inout);
00442
00443 for ( int i = 0; i < numDiagBlocks_; ++ i ) {
00444 Thyra::solve( *diagonalBlocks_[i].getConstObj(), M_trans,
00445 *B.getMultiVectorBlock(i),
00446 &*X.getNonconstMultiVectorBlock(i)
00447 );
00448
00449 }
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460 }
00461
00462
00463
00464
00465
00466 template<class Scalar>
00467 bool DefaultBlockedTriangularLinearOpWithSolve<Scalar>::opSupported(
00468 ETransp M_trans
00469 ) const
00470 {
00471 using Thyra::opSupported;
00472 assertBlockFillIsActive(false);
00473 for ( int k = 0; k < numDiagBlocks_; ++k ) {
00474 if ( !opSupported(*diagonalBlocks_[k].getConstObj(),M_trans) )
00475 return false;
00476 }
00477 return true;
00478
00479
00480
00481 }
00482
00483
00484 template<class Scalar>
00485 void DefaultBlockedTriangularLinearOpWithSolve<Scalar>::apply(
00486 const ETransp M_trans,
00487 const MultiVectorBase<Scalar> &X_in,
00488 MultiVectorBase<Scalar> *Y_inout,
00489 const Scalar alpha,
00490 const Scalar beta
00491 ) const
00492 {
00493
00494 using Teuchos::RCP;
00495 using Teuchos::dyn_cast;
00496 typedef Teuchos::ScalarTraits<Scalar> ST;
00497 using Thyra::apply;
00498
00499 #ifdef TEUCHOS_DEBUG
00500 THYRA_ASSERT_LINEAR_OP_MULTIVEC_APPLY_SPACES(
00501 "DefaultBlockedTriangularLinearOpWithSolve<Scalar>::apply(...)",*this,M_trans,X_in,Y_inout
00502 );
00503 #endif // TEUCHOS_DEBUG
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515 const ProductMultiVectorBase<Scalar>
00516 &X = dyn_cast<const ProductMultiVectorBase<Scalar> >(X_in);
00517 ProductMultiVectorBase<Scalar>
00518 &Y = dyn_cast<ProductMultiVectorBase<Scalar> >(*Y_inout);
00519
00520 for ( int i = 0; i < numDiagBlocks_; ++ i ) {
00521 Thyra::apply( *diagonalBlocks_[i].getConstObj(), M_trans,
00522 *X.getMultiVectorBlock(i),
00523 &*Y.getNonconstMultiVectorBlock(i)
00524 );
00525 }
00526
00527 }
00528
00529
00530
00531
00532
00533 template<class Scalar>
00534 void DefaultBlockedTriangularLinearOpWithSolve<Scalar>::assertBlockFillIsActive(
00535 bool blockFillIsActive
00536 ) const
00537 {
00538 #ifdef TEUCHOS_DEBUG
00539 TEST_FOR_EXCEPT(!(blockFillIsActive_==blockFillIsActive));
00540 #endif
00541 }
00542
00543
00544 template<class Scalar>
00545 void DefaultBlockedTriangularLinearOpWithSolve<Scalar>::assertBlockRowCol(
00546 const int i, const int j
00547 ) const
00548 {
00549 #ifdef TEUCHOS_DEBUG
00550 TEST_FOR_EXCEPTION(
00551 !( 0 <= i && i < numDiagBlocks_ ), std::logic_error,
00552 "Error, i="<<i<<" does not fall in the range [0,"<<numDiagBlocks_-1<<"]!"
00553 );
00554 TEST_FOR_EXCEPTION(
00555 !( 0 <= j && j < numDiagBlocks_ ), std::logic_error,
00556 "Error, j="<<j<<" does not fall in the range [0,"<<numDiagBlocks_-1<<"]!"
00557 );
00558 #endif
00559 }
00560
00561
00562 template<class Scalar>
00563 template<class LinearOpWithSolveType>
00564 void DefaultBlockedTriangularLinearOpWithSolve<Scalar>::setLOWSBlockImpl(
00565 const int i, const int j,
00566 const Teuchos::RCP<LinearOpWithSolveType> &block
00567 )
00568 {
00569 assertBlockFillIsActive(true);
00570 TEST_FOR_EXCEPTION(
00571 !this->acceptsLOWSBlock(i,j), std::logic_error,
00572 "Error, this DefaultBlockedTriangularLinearOpWithSolve does not accept\n"
00573 "LOWSB objects for the block i="<<i<<", j="<<j<<"!"
00574 );
00575 diagonalBlocks_[i] = block;
00576 }
00577
00578
00579
00580 }
00581
00582
00583 #endif // THYRA_DEFAULT_BLOCKED_TRIANGULAR_LINEAR_OP_WITH_SOLVE_HPP