10 #ifndef THYRA_DEFAULT_BLOCKED_TRIANGULAR_LINEAR_OP_WITH_SOLVE_DEF_HPP
11 #define THYRA_DEFAULT_BLOCKED_TRIANGULAR_LINEAR_OP_WITH_SOLVE_DEF_HPP
14 #include "Thyra_DefaultBlockedTriangularLinearOpWithSolve_decl.hpp"
15 #include "Thyra_ProductMultiVectorBase.hpp"
16 #include "Thyra_DefaultProductVectorSpace.hpp"
17 #include "Thyra_AssertOp.hpp"
29 template<
class Scalar>
31 : blockFillIsActive_(false), numDiagBlocks_(0)
35 template<
class Scalar>
40 assertAndSetBlockStructure(*blocks);
41 blocks_.initialize(blocks);
45 template<
class Scalar>
50 assertAndSetBlockStructure(*blocks);
51 blocks_.initialize(blocks);
55 template<
class Scalar>
59 return blocks_.getNonconstObj();
63 template<
class Scalar>
67 return blocks_.getConstObj();
74 template<
class Scalar>
76 const int i,
const int j
79 assertBlockFillIsActive(
true);
80 assertBlockRowCol(i,j);
84 template<
class Scalar>
86 const int i,
const int j,
90 setLOWSBlockImpl(i,j,block);
94 template<
class Scalar>
96 const int i,
const int j,
100 setLOWSBlockImpl(i,j,block);
107 template<
class Scalar>
110 assertBlockFillIsActive(
false);
115 template<
class Scalar>
117 const int numRowBlocks,
const int numColBlocks
126 assertBlockFillIsActive(
false);
127 numDiagBlocks_ = numRowBlocks;
128 diagonalBlocks_.resize(numDiagBlocks_);
129 productRange_ = null;
130 productDomain_ = null;
131 blockFillIsActive_ =
true;
135 template<
class Scalar>
146 assertBlockFillIsActive(
false);
147 productRange_ = productRange_in;
148 productDomain_ = productDomain_in;
149 numDiagBlocks_ = productRange_in->numBlocks();
150 diagonalBlocks_.resize(numDiagBlocks_);
151 blockFillIsActive_ =
true;
155 template<
class Scalar>
158 return blockFillIsActive_;
162 template<
class Scalar>
164 const int i,
const int j
167 assertBlockFillIsActive(
true);
168 assertBlockRowCol(i,j);
173 template<
class Scalar>
175 const int ,
const int ,
179 assertBlockFillIsActive(
true);
184 template<
class Scalar>
186 const int ,
const int ,
190 assertBlockFillIsActive(
true);
195 template<
class Scalar>
198 assertBlockFillIsActive(
true);
201 for (
int k = 0; k < numDiagBlocks_; ++k ) {
203 diagonalBlocks_[k].getConstObj();
205 "Error, the block diagonal k="<<k<<
" can not be null when ending block fill!"
209 domainSpaces.
push_back(lows_k->domain());
213 productRange_ = productVectorSpace<Scalar>(rangeSpaces());
214 productDomain_ = productVectorSpace<Scalar>(domainSpaces());
216 blockFillIsActive_ =
false;
220 template<
class Scalar>
223 assertBlockFillIsActive(
false);
224 productRange_ = Teuchos::null;
225 productDomain_ = Teuchos::null;
227 diagonalBlocks_.resize(0);
234 template<
class Scalar>
237 const int i,
const int j
240 assertBlockFillIsActive(
false);
241 assertBlockRowCol(i,j);
243 return Teuchos::null;
244 return diagonalBlocks_[i].getNonconstObj();
248 template<
class Scalar>
251 const int i,
const int j
254 assertBlockFillIsActive(
false);
255 assertBlockRowCol(i, j);
257 return Teuchos::null;
258 return diagonalBlocks_[i].getConstObj();
265 template<
class Scalar>
269 return productRange_;
273 template<
class Scalar>
277 return productDomain_;
281 template<
class Scalar>
283 const int i,
const int j
286 assertBlockFillIsActive(
false);
287 assertBlockRowCol(i,j);
290 return !
is_null(diagonalBlocks_[i].getConstObj());
294 template<
class Scalar>
296 const int i,
const int j
299 assertBlockFillIsActive(
true);
300 assertBlockRowCol(i,j);
301 return diagonalBlocks_[i].isConst();
305 template<
class Scalar>
308 const int i,
const int j
311 assertBlockFillIsActive(
true);
312 assertBlockRowCol(i,j);
314 return Teuchos::null;
315 return this->getNonconstLOWSBlock(i,j);
319 template<
class Scalar>
322 const int i,
const int j
325 assertBlockFillIsActive(
true);
326 assertBlockRowCol(i,j);
328 return Teuchos::null;
329 return this->getLOWSBlock(i,j);
336 template<
class Scalar>
340 return this->productRange();
344 template<
class Scalar>
348 return this->productDomain();
352 template<
class Scalar>
356 return Teuchos::null;
363 template<
class Scalar>
367 assertBlockFillIsActive(
false);
368 std::ostringstream oss;
371 <<
"numDiagBlocks="<<numDiagBlocks_
377 template<
class Scalar>
383 assertBlockFillIsActive(
false);
395 template<
class Scalar>
400 using Thyra::opSupported;
401 assertBlockFillIsActive(
false);
402 for (
int k = 0; k < numDiagBlocks_; ++k ) {
403 if ( !opSupported(*diagonalBlocks_[k].getConstObj(),M_trans) )
413 template<
class Scalar>
429 "DefaultBlockedTriangularLinearOpWithSolve<Scalar>::apply(...)",
430 *
this, M_trans, X_in, &*Y_inout
432 #endif // THYRA_DEBUG
449 for (
int i = 0; i < numDiagBlocks_; ++ i ) {
450 Thyra::apply( *diagonalBlocks_[i].getConstObj(), M_trans,
462 template<
class Scalar>
468 assertBlockFillIsActive(
false);
469 for (
int k = 0; k < numDiagBlocks_; ++k ) {
470 if ( !Thyra::solveSupports( *diagonalBlocks_[k].getConstObj(), M_trans ) )
480 template<
class Scalar>
486 using Thyra::solveSupportsSolveMeasureType;
487 assertBlockFillIsActive(
false);
488 for (
int k = 0; k < numDiagBlocks_; ++k ) {
490 !solveSupportsSolveMeasureType(
491 *diagonalBlocks_[k].getConstObj(),
492 M_trans, solveMeasureType
503 template<
class Scalar>
519 "DefaultBlockedTriangularLinearOpWithSolve<Scalar>::apply(...)",
520 *
this, M_trans, *X_inout, &B_in
530 #endif // THYRA_DEBUG
547 bool converged =
true;
548 for (
int i = 0; i < numDiagBlocks_; ++ i ) {
550 Op_k = diagonalBlocks_[i].getConstObj();
551 Op_k->setOStream(this->getOStream());
552 Op_k->setVerbLevel(this->getVerbLevel());
555 X.getNonconstMultiVectorBlock(i).ptr(), solveCriteria );
574 template<
class Scalar>
576 bool blockFillIsActive_in
582 (void)blockFillIsActive_in;
587 template<
class Scalar>
588 void DefaultBlockedTriangularLinearOpWithSolve<Scalar>::assertBlockRowCol(
589 const int i,
const int j
594 !( 0 <= i && i < numDiagBlocks_ ), std::logic_error,
595 "Error, i="<<i<<
" does not fall in the range [0,"<<numDiagBlocks_-1<<
"]!"
598 !( 0 <= j && j < numDiagBlocks_ ), std::logic_error,
599 "Error, j="<<j<<
" does not fall in the range [0,"<<numDiagBlocks_-1<<
"]!"
608 template<
class Scalar>
609 template<
class LinearOpWithSolveType>
610 void DefaultBlockedTriangularLinearOpWithSolve<Scalar>::setLOWSBlockImpl(
611 const int i,
const int j,
615 assertBlockFillIsActive(
true);
622 !this->acceptsLOWSBlock(i,j), std::logic_error,
623 "Error, this DefaultBlockedTriangularLinearOpWithSolve does not accept\n"
624 "LOWSB objects for the block i="<<i<<
", j="<<j<<
"!"
629 diagonalBlocks_[i] = block;
633 template<
class Scalar>
634 void DefaultBlockedTriangularLinearOpWithSolve<Scalar>::assertAndSetBlockStructure(
635 const PhysicallyBlockedLinearOpBase<Scalar>& blocks
640 "DefaultBlockedTriangularLinearOpWithSolve<Scalar>::assertAndSetBlockStructure(blocks)",
641 *blocks.range(), *this->range()
644 "DefaultBlockedTriangularLinearOpWithSolve<Scalar>::assertAndSetBlockStructure(blocks)",
645 *blocks.domain(), *this->domain()
659 #endif // THYRA_DEFAULT_BLOCKED_TRIANGULAR_LINEAR_OP_WITH_SOLVE_DEF_HPP
bool solveSupportsSolveMeasureTypeImpl(EOpTransp M_trans, const SolveMeasureType &solveMeasureType) const
Base interface for product multi-vectors.
RCP< LinearOpWithSolveBase< Scalar > > getNonconstLOWSBlock(const int i, const int j)
#define THYRA_ASSERT_VEC_SPACES(FUNC_NAME, VS1, VS2)
This is a very useful macro that should be used to validate that two vector spaces are compatible...
SolveStatus< Scalar > solveImpl(const EOpTransp transp, const MultiVectorBase< Scalar > &B, const Ptr< MultiVectorBase< Scalar > > &X, const Ptr< const SolveCriteria< Scalar > > solveCriteria) const
void setBlocks(const RCP< const PhysicallyBlockedLinearOpBase< Scalar > > &blocks)
Base class for all linear operators that can support a high-level solve operation.
bool is_null(const boost::shared_ptr< T > &p)
EOpTransp
Enumeration for determining how a linear operator is applied. `*.
void setNonconstBlock(const int i, const int j, const RCP< LinearOpBase< Scalar > > &block)
RCP< const LinearOpBase< Scalar > > getBlock(const int i, const int j) const
bool solveSupportsImpl(EOpTransp M_trans) const
bool acceptsLOWSBlock(const int i, const int j) const
Concrete composite LinearOpWithSolveBase subclass that creates single upper or lower block triangular...
#define THYRA_ASSERT_LINEAR_OP_MULTIVEC_APPLY_SPACES(FUNC_NAME, M, M_T, X, Y)
This is a very useful macro that should be used to validate that the spaces for the multi-vector vers...
bool blockFillIsActive() const
RCP< const ProductVectorSpaceBase< Scalar > > productDomain() const
void applyImpl(const EOpTransp M_trans, const MultiVectorBase< Scalar > &X, const Ptr< MultiVectorBase< Scalar > > &Y, const Scalar alpha, const Scalar beta) const
RCP< const VectorSpaceBase< Scalar > > range() const
void setBlock(const int i, const int j, const RCP< const LinearOpBase< Scalar > > &block)
#define TEUCHOS_ASSERT_INEQUALITY(val1, comp, val2)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
RCP< const PhysicallyBlockedLinearOpBase< Scalar > > getBlocks()
T_To & dyn_cast(T_From &from)
bool blockExists(const int i, const int j) const
virtual Teuchos::RCP< const MultiVectorBase< Scalar > > getMultiVectorBlock(const int k) const =0
Returns a non-persisting const view of the (zero-based) kth block multi-vector.
RCP< LinearOpBase< Scalar > > getNonconstBlock(const int i, const int j)
Interface for a collection of column vectors called a multi-vector.
void setLOWSBlock(const int i, const int j, const RCP< const LinearOpWithSolveBase< Scalar > > &block)
RCP< PhysicallyBlockedLinearOpBase< Scalar > > getNonconstBlocks()
Base interface for physically blocked linear operators.
RCP< const VectorSpaceBase< Scalar > > domain() const
virtual std::string description() const
RCP< const LinearOpBase< Scalar > > clone() const
Simple struct for the return status from a solve.
std::string description() const
Prints just the name DefaultBlockedTriangularLinearOpWithSolve along with the overall dimensions and ...
Base class for all linear operators.
bool acceptsBlock(const int i, const int j) const
ESolveStatus solveStatus
The return status of the solve.
RCP< const ProductVectorSpaceBase< Scalar > > productRange() const
RCP< const LinearOpWithSolveBase< Scalar > > getLOWSBlock(const int i, const int j) const
void push_back(const value_type &x)
bool opSupportedImpl(EOpTransp M_trans) const
void setNonconstLOWSBlock(const int i, const int j, const RCP< LinearOpWithSolveBase< Scalar > > &block)
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
Prints the details about the constituent linear operators.
bool blockIsConst(const int i, const int j) const
The requested solution criteria has likely been achieved.
#define TEUCHOS_ASSERT_EQUALITY(val1, val2)
The requested solution criteria has likely not been achieved.
Simple struct that defines the requested solution criteria for a solve.
DefaultBlockedTriangularLinearOpWithSolve()
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
virtual void describe(FancyOStream &out, const EVerbosityLevel verbLevel=verbLevel_default) const
void setNonconstBlocks(const RCP< PhysicallyBlockedLinearOpBase< Scalar > > &blocks)