42 #ifndef THYRA_DEFAULT_BLOCKED_TRIANGULAR_LINEAR_OP_WITH_SOLVE_DEF_HPP
43 #define THYRA_DEFAULT_BLOCKED_TRIANGULAR_LINEAR_OP_WITH_SOLVE_DEF_HPP
46 #include "Thyra_DefaultBlockedTriangularLinearOpWithSolve_decl.hpp"
47 #include "Thyra_ProductMultiVectorBase.hpp"
48 #include "Thyra_DefaultProductVectorSpace.hpp"
49 #include "Thyra_AssertOp.hpp"
61 template<
class Scalar>
63 : blockFillIsActive_(false), numDiagBlocks_(0)
67 template<
class Scalar>
72 assertAndSetBlockStructure(*blocks);
73 blocks_.initialize(blocks);
77 template<
class Scalar>
82 assertAndSetBlockStructure(*blocks);
83 blocks_.initialize(blocks);
87 template<
class Scalar>
91 return blocks_.getNonconstObj();
95 template<
class Scalar>
99 return blocks_.getConstObj();
106 template<
class Scalar>
108 const int i,
const int j
111 assertBlockFillIsActive(
true);
112 assertBlockRowCol(i,j);
116 template<
class Scalar>
118 const int i,
const int j,
122 setLOWSBlockImpl(i,j,block);
126 template<
class Scalar>
128 const int i,
const int j,
132 setLOWSBlockImpl(i,j,block);
139 template<
class Scalar>
142 assertBlockFillIsActive(
false);
147 template<
class Scalar>
149 const int numRowBlocks,
const int numColBlocks
156 assertBlockFillIsActive(
false);
157 numDiagBlocks_ = numRowBlocks;
158 diagonalBlocks_.resize(numDiagBlocks_);
159 productRange_ =
null;
160 productDomain_ =
null;
161 blockFillIsActive_ =
true;
165 template<
class Scalar>
176 assertBlockFillIsActive(
false);
177 productRange_ = productRange_in;
178 productDomain_ = productDomain_in;
179 numDiagBlocks_ = productRange_in->numBlocks();
180 diagonalBlocks_.resize(numDiagBlocks_);
181 blockFillIsActive_ =
true;
185 template<
class Scalar>
188 return blockFillIsActive_;
192 template<
class Scalar>
194 const int i,
const int j
197 assertBlockFillIsActive(
true);
198 assertBlockRowCol(i,j);
203 template<
class Scalar>
205 const int i,
const int j,
209 assertBlockFillIsActive(
true);
214 template<
class Scalar>
216 const int i,
const int j,
220 assertBlockFillIsActive(
true);
225 template<
class Scalar>
228 assertBlockFillIsActive(
true);
231 for (
int k = 0; k < numDiagBlocks_; ++k ) {
233 diagonalBlocks_[k].getConstObj();
235 "Error, the block diagonal k="<<k<<
" can not be null when ending block fill!"
239 domainSpaces.
push_back(lows_k->domain());
243 productRange_ = productVectorSpace<Scalar>(rangeSpaces());
244 productDomain_ = productVectorSpace<Scalar>(domainSpaces());
246 blockFillIsActive_ =
false;
250 template<
class Scalar>
253 assertBlockFillIsActive(
false);
254 productRange_ = Teuchos::null;
255 productDomain_ = Teuchos::null;
257 diagonalBlocks_.resize(0);
264 template<
class Scalar>
267 const int i,
const int j
270 assertBlockFillIsActive(
false);
271 assertBlockRowCol(i,j);
273 return Teuchos::null;
274 return diagonalBlocks_[i].getNonconstObj();
278 template<
class Scalar>
281 const int i,
const int j
284 assertBlockFillIsActive(
false);
285 assertBlockRowCol(i, j);
287 return Teuchos::null;
288 return diagonalBlocks_[i].getConstObj();
295 template<
class Scalar>
299 return productRange_;
303 template<
class Scalar>
307 return productDomain_;
311 template<
class Scalar>
313 const int i,
const int j
316 assertBlockFillIsActive(
false);
317 assertBlockRowCol(i,j);
320 return !
is_null(diagonalBlocks_[i].getConstObj());
324 template<
class Scalar>
326 const int i,
const int j
329 assertBlockFillIsActive(
true);
330 assertBlockRowCol(i,j);
331 return diagonalBlocks_[i].isConst();
335 template<
class Scalar>
338 const int i,
const int j
341 assertBlockFillIsActive(
true);
342 assertBlockRowCol(i,j);
344 return Teuchos::null;
345 return this->getNonconstLOWSBlock(i,j);
349 template<
class Scalar>
352 const int i,
const int j
355 assertBlockFillIsActive(
true);
356 assertBlockRowCol(i,j);
358 return Teuchos::null;
359 return this->getLOWSBlock(i,j);
366 template<
class Scalar>
370 return this->productRange();
374 template<
class Scalar>
378 return this->productDomain();
382 template<
class Scalar>
386 return Teuchos::null;
393 template<
class Scalar>
397 assertBlockFillIsActive(
false);
398 std::ostringstream oss;
401 <<
"numDiagBlocks="<<numDiagBlocks_
407 template<
class Scalar>
413 assertBlockFillIsActive(
false);
425 template<
class Scalar>
430 using Thyra::opSupported;
431 assertBlockFillIsActive(
false);
432 for (
int k = 0; k < numDiagBlocks_; ++k ) {
433 if ( !opSupported(*diagonalBlocks_[k].getConstObj(),M_trans) )
443 template<
class Scalar>
459 "DefaultBlockedTriangularLinearOpWithSolve<Scalar>::apply(...)",
460 *
this, M_trans, X_in, &*Y_inout
462 #endif // THYRA_DEBUG
479 for (
int i = 0; i < numDiagBlocks_; ++ i ) {
480 Thyra::apply( *diagonalBlocks_[i].getConstObj(), M_trans,
492 template<
class Scalar>
498 assertBlockFillIsActive(
false);
499 for (
int k = 0; k < numDiagBlocks_; ++k ) {
500 if ( !Thyra::solveSupports( *diagonalBlocks_[k].getConstObj(), M_trans ) )
510 template<
class Scalar>
516 using Thyra::solveSupportsSolveMeasureType;
517 assertBlockFillIsActive(
false);
518 for (
int k = 0; k < numDiagBlocks_; ++k ) {
520 !solveSupportsSolveMeasureType(
521 *diagonalBlocks_[k].getConstObj(),
522 M_trans, solveMeasureType
533 template<
class Scalar>
549 "DefaultBlockedTriangularLinearOpWithSolve<Scalar>::apply(...)",
550 *
this, M_trans, *X_inout, &B_in
560 #endif // THYRA_DEBUG
577 bool converged =
true;
578 for (
int i = 0; i < numDiagBlocks_; ++ i ) {
580 Op_k = diagonalBlocks_[i].getConstObj();
581 Op_k->setOStream(this->getOStream());
582 Op_k->setVerbLevel(this->getVerbLevel());
585 X.getNonconstMultiVectorBlock(i).ptr(), solveCriteria );
604 template<
class Scalar>
606 bool blockFillIsActive_in
615 template<
class Scalar>
616 void DefaultBlockedTriangularLinearOpWithSolve<Scalar>::assertBlockRowCol(
617 const int i,
const int j
622 !( 0 <= i && i < numDiagBlocks_ ), std::logic_error,
623 "Error, i="<<i<<
" does not fall in the range [0,"<<numDiagBlocks_-1<<
"]!"
626 !( 0 <= j && j < numDiagBlocks_ ), std::logic_error,
627 "Error, j="<<j<<
" does not fall in the range [0,"<<numDiagBlocks_-1<<
"]!"
633 template<
class Scalar>
634 template<
class LinearOpWithSolveType>
635 void DefaultBlockedTriangularLinearOpWithSolve<Scalar>::setLOWSBlockImpl(
636 const int i,
const int j,
640 assertBlockFillIsActive(
true);
647 !this->acceptsLOWSBlock(i,j), std::logic_error,
648 "Error, this DefaultBlockedTriangularLinearOpWithSolve does not accept\n"
649 "LOWSB objects for the block i="<<i<<
", j="<<j<<
"!"
652 diagonalBlocks_[i] = block;
656 template<
class Scalar>
657 void DefaultBlockedTriangularLinearOpWithSolve<Scalar>::assertAndSetBlockStructure(
658 const PhysicallyBlockedLinearOpBase<Scalar>& blocks
663 "DefaultBlockedTriangularLinearOpWithSolve<Scalar>::assertAndSetBlockStructure(blocks)",
664 *blocks.range(), *this->range()
667 "DefaultBlockedTriangularLinearOpWithSolve<Scalar>::assertAndSetBlockStructure(blocks)",
668 *blocks.domain(), *this->domain()
680 #endif // THYRA_DEFAULT_BLOCKED_TRIANGULAR_LINEAR_OP_WITH_SOLVE_DEF_HPP