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
158 assertBlockFillIsActive(
false);
159 numDiagBlocks_ = numRowBlocks;
160 diagonalBlocks_.resize(numDiagBlocks_);
161 productRange_ = null;
162 productDomain_ = null;
163 blockFillIsActive_ =
true;
167 template<
class Scalar>
178 assertBlockFillIsActive(
false);
179 productRange_ = productRange_in;
180 productDomain_ = productDomain_in;
181 numDiagBlocks_ = productRange_in->numBlocks();
182 diagonalBlocks_.resize(numDiagBlocks_);
183 blockFillIsActive_ =
true;
187 template<
class Scalar>
190 return blockFillIsActive_;
194 template<
class Scalar>
196 const int i,
const int j
199 assertBlockFillIsActive(
true);
200 assertBlockRowCol(i,j);
205 template<
class Scalar>
207 const int ,
const int ,
211 assertBlockFillIsActive(
true);
216 template<
class Scalar>
218 const int ,
const int ,
222 assertBlockFillIsActive(
true);
227 template<
class Scalar>
230 assertBlockFillIsActive(
true);
233 for (
int k = 0; k < numDiagBlocks_; ++k ) {
235 diagonalBlocks_[k].getConstObj();
237 "Error, the block diagonal k="<<k<<
" can not be null when ending block fill!"
241 domainSpaces.
push_back(lows_k->domain());
245 productRange_ = productVectorSpace<Scalar>(rangeSpaces());
246 productDomain_ = productVectorSpace<Scalar>(domainSpaces());
248 blockFillIsActive_ =
false;
252 template<
class Scalar>
255 assertBlockFillIsActive(
false);
256 productRange_ = Teuchos::null;
257 productDomain_ = Teuchos::null;
259 diagonalBlocks_.resize(0);
266 template<
class Scalar>
269 const int i,
const int j
272 assertBlockFillIsActive(
false);
273 assertBlockRowCol(i,j);
275 return Teuchos::null;
276 return diagonalBlocks_[i].getNonconstObj();
280 template<
class Scalar>
283 const int i,
const int j
286 assertBlockFillIsActive(
false);
287 assertBlockRowCol(i, j);
289 return Teuchos::null;
290 return diagonalBlocks_[i].getConstObj();
297 template<
class Scalar>
301 return productRange_;
305 template<
class Scalar>
309 return productDomain_;
313 template<
class Scalar>
315 const int i,
const int j
318 assertBlockFillIsActive(
false);
319 assertBlockRowCol(i,j);
322 return !
is_null(diagonalBlocks_[i].getConstObj());
326 template<
class Scalar>
328 const int i,
const int j
331 assertBlockFillIsActive(
true);
332 assertBlockRowCol(i,j);
333 return diagonalBlocks_[i].isConst();
337 template<
class Scalar>
340 const int i,
const int j
343 assertBlockFillIsActive(
true);
344 assertBlockRowCol(i,j);
346 return Teuchos::null;
347 return this->getNonconstLOWSBlock(i,j);
351 template<
class Scalar>
354 const int i,
const int j
357 assertBlockFillIsActive(
true);
358 assertBlockRowCol(i,j);
360 return Teuchos::null;
361 return this->getLOWSBlock(i,j);
368 template<
class Scalar>
372 return this->productRange();
376 template<
class Scalar>
380 return this->productDomain();
384 template<
class Scalar>
388 return Teuchos::null;
395 template<
class Scalar>
399 assertBlockFillIsActive(
false);
400 std::ostringstream oss;
403 <<
"numDiagBlocks="<<numDiagBlocks_
409 template<
class Scalar>
415 assertBlockFillIsActive(
false);
427 template<
class Scalar>
432 using Thyra::opSupported;
433 assertBlockFillIsActive(
false);
434 for (
int k = 0; k < numDiagBlocks_; ++k ) {
435 if ( !opSupported(*diagonalBlocks_[k].getConstObj(),M_trans) )
445 template<
class Scalar>
461 "DefaultBlockedTriangularLinearOpWithSolve<Scalar>::apply(...)",
462 *
this, M_trans, X_in, &*Y_inout
464 #endif // THYRA_DEBUG
481 for (
int i = 0; i < numDiagBlocks_; ++ i ) {
482 Thyra::apply( *diagonalBlocks_[i].getConstObj(), M_trans,
494 template<
class Scalar>
500 assertBlockFillIsActive(
false);
501 for (
int k = 0; k < numDiagBlocks_; ++k ) {
502 if ( !Thyra::solveSupports( *diagonalBlocks_[k].getConstObj(), M_trans ) )
512 template<
class Scalar>
518 using Thyra::solveSupportsSolveMeasureType;
519 assertBlockFillIsActive(
false);
520 for (
int k = 0; k < numDiagBlocks_; ++k ) {
522 !solveSupportsSolveMeasureType(
523 *diagonalBlocks_[k].getConstObj(),
524 M_trans, solveMeasureType
535 template<
class Scalar>
551 "DefaultBlockedTriangularLinearOpWithSolve<Scalar>::apply(...)",
552 *
this, M_trans, *X_inout, &B_in
562 #endif // THYRA_DEBUG
579 bool converged =
true;
580 for (
int i = 0; i < numDiagBlocks_; ++ i ) {
582 Op_k = diagonalBlocks_[i].getConstObj();
583 Op_k->setOStream(this->getOStream());
584 Op_k->setVerbLevel(this->getVerbLevel());
587 X.getNonconstMultiVectorBlock(i).ptr(), solveCriteria );
606 template<
class Scalar>
608 bool blockFillIsActive_in
614 (void)blockFillIsActive_in;
619 template<
class Scalar>
620 void DefaultBlockedTriangularLinearOpWithSolve<Scalar>::assertBlockRowCol(
621 const int i,
const int j
626 !( 0 <= i && i < numDiagBlocks_ ), std::logic_error,
627 "Error, i="<<i<<
" does not fall in the range [0,"<<numDiagBlocks_-1<<
"]!"
630 !( 0 <= j && j < numDiagBlocks_ ), std::logic_error,
631 "Error, j="<<j<<
" does not fall in the range [0,"<<numDiagBlocks_-1<<
"]!"
640 template<
class Scalar>
641 template<
class LinearOpWithSolveType>
642 void DefaultBlockedTriangularLinearOpWithSolve<Scalar>::setLOWSBlockImpl(
643 const int i,
const int j,
647 assertBlockFillIsActive(
true);
654 !this->acceptsLOWSBlock(i,j), std::logic_error,
655 "Error, this DefaultBlockedTriangularLinearOpWithSolve does not accept\n"
656 "LOWSB objects for the block i="<<i<<
", j="<<j<<
"!"
661 diagonalBlocks_[i] = block;
665 template<
class Scalar>
666 void DefaultBlockedTriangularLinearOpWithSolve<Scalar>::assertAndSetBlockStructure(
667 const PhysicallyBlockedLinearOpBase<Scalar>& blocks
672 "DefaultBlockedTriangularLinearOpWithSolve<Scalar>::assertAndSetBlockStructure(blocks)",
673 *blocks.range(), *this->range()
676 "DefaultBlockedTriangularLinearOpWithSolve<Scalar>::assertAndSetBlockStructure(blocks)",
677 *blocks.domain(), *this->domain()
691 #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)