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"
31 : blockFillIsActive_(false), numDiagBlocks_(0)
40 assertAndSetBlockStructure(*blocks);
41 blocks_.initialize(blocks);
50 assertAndSetBlockStructure(*blocks);
51 blocks_.initialize(blocks);
59 return blocks_.getNonconstObj();
67 return blocks_.getConstObj();
76 const int i,
const int j
79 assertBlockFillIsActive(
true);
80 assertBlockRowCol(i,j);
86 const int i,
const int j,
90 setLOWSBlockImpl(i,j,block);
96 const int i,
const int j,
100 setLOWSBlockImpl(i,j,block);
107template<
class Scalar>
110 assertBlockFillIsActive(
false);
115template<
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;
135template<
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;
155template<
class Scalar>
158 return blockFillIsActive_;
162template<
class Scalar>
164 const int i,
const int j
167 assertBlockFillIsActive(
true);
168 assertBlockRowCol(i,j);
173template<
class Scalar>
175 const int ,
const int ,
179 assertBlockFillIsActive(
true);
184template<
class Scalar>
186 const int ,
const int ,
190 assertBlockFillIsActive(
true);
195template<
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!"
207 if (is_null(productRange_)) {
209 domainSpaces.
push_back(lows_k->domain());
212 if (is_null(productRange_)) {
213 productRange_ = productVectorSpace<Scalar>(rangeSpaces());
214 productDomain_ = productVectorSpace<Scalar>(domainSpaces());
216 blockFillIsActive_ =
false;
220template<
class Scalar>
223 assertBlockFillIsActive(
false);
227 diagonalBlocks_.resize(0);
234template<
class Scalar>
237 const int i,
const int j
240 assertBlockFillIsActive(
false);
241 assertBlockRowCol(i,j);
244 return diagonalBlocks_[i].getNonconstObj();
248template<
class Scalar>
251 const int i,
const int j
254 assertBlockFillIsActive(
false);
255 assertBlockRowCol(i, j);
258 return diagonalBlocks_[i].getConstObj();
265template<
class Scalar>
269 return productRange_;
273template<
class Scalar>
277 return productDomain_;
281template<
class Scalar>
283 const int i,
const int j
286 assertBlockFillIsActive(
false);
287 assertBlockRowCol(i,j);
290 return !is_null(diagonalBlocks_[i].getConstObj());
294template<
class Scalar>
296 const int i,
const int j
299 assertBlockFillIsActive(
true);
300 assertBlockRowCol(i,j);
301 return diagonalBlocks_[i].isConst();
305template<
class Scalar>
308 const int i,
const int j
311 assertBlockFillIsActive(
true);
312 assertBlockRowCol(i,j);
315 return this->getNonconstLOWSBlock(i,j);
319template<
class Scalar>
322 const int i,
const int j
325 assertBlockFillIsActive(
true);
326 assertBlockRowCol(i,j);
329 return this->getLOWSBlock(i,j);
336template<
class Scalar>
340 return this->productRange();
344template<
class Scalar>
348 return this->productDomain();
352template<
class Scalar>
363template<
class Scalar>
367 assertBlockFillIsActive(
false);
368 std::ostringstream oss;
371 <<
"numDiagBlocks="<<numDiagBlocks_
377template<
class Scalar>
383 assertBlockFillIsActive(
false);
395template<
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) )
413template<
class Scalar>
429 "DefaultBlockedTriangularLinearOpWithSolve<Scalar>::apply(...)",
430 *
this, M_trans, X_in, &*Y_inout
445 &X = dyn_cast<const ProductMultiVectorBase<Scalar> >(X_in);
447 &Y = dyn_cast<ProductMultiVectorBase<Scalar> >(*Y_inout);
449 for (
int i = 0; i < numDiagBlocks_; ++ i ) {
450 Thyra::apply( *diagonalBlocks_[i].getConstObj(), M_trans,
462template<
class Scalar>
468 assertBlockFillIsActive(
false);
469 for (
int k = 0; k < numDiagBlocks_; ++k ) {
470 if ( !Thyra::solveSupports( *diagonalBlocks_[k].getConstObj(), M_trans ) )
480template<
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
503template<
class Scalar>
519 "DefaultBlockedTriangularLinearOpWithSolve<Scalar>::apply(...)",
520 *
this, M_trans, *X_inout, &B_in
543 &B = dyn_cast<const ProductMultiVectorBase<Scalar> >(B_in);
545 &X = dyn_cast<ProductMultiVectorBase<Scalar> >(*X_inout);
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 );
574template<
class Scalar>
576 bool blockFillIsActive_in
582 (void)blockFillIsActive_in;
587template<
class Scalar>
588void 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<<
"]!"
608template<
class Scalar>
609template<
class LinearOpWithSolveType>
610void 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;
633template<
class Scalar>
634void 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()
void push_back(const value_type &x)
virtual void describe(FancyOStream &out, const EVerbosityLevel verbLevel=verbLevel_default) const
virtual std::string description() const
Concrete composite LinearOpWithSolveBase subclass that creates single upper or lower block triangular...
bool acceptsLOWSBlock(const int i, const int j) const
RCP< const PhysicallyBlockedLinearOpBase< Scalar > > getBlocks()
RCP< const ProductVectorSpaceBase< Scalar > > productDomain() const
void setNonconstBlocks(const RCP< PhysicallyBlockedLinearOpBase< Scalar > > &blocks)
SolveStatus< Scalar > solveImpl(const EOpTransp transp, const MultiVectorBase< Scalar > &B, const Ptr< MultiVectorBase< Scalar > > &X, const Ptr< const SolveCriteria< Scalar > > solveCriteria) const
void setLOWSBlock(const int i, const int j, const RCP< const LinearOpWithSolveBase< Scalar > > &block)
RCP< const LinearOpWithSolveBase< Scalar > > getLOWSBlock(const int i, const int j) const
RCP< const LinearOpBase< Scalar > > getBlock(const int i, const int j) const
bool opSupportedImpl(EOpTransp M_trans) const
void setNonconstBlock(const int i, const int j, const RCP< LinearOpBase< Scalar > > &block)
bool solveSupportsImpl(EOpTransp M_trans) const
void setBlocks(const RCP< const PhysicallyBlockedLinearOpBase< Scalar > > &blocks)
bool solveSupportsSolveMeasureTypeImpl(EOpTransp M_trans, const SolveMeasureType &solveMeasureType) const
RCP< PhysicallyBlockedLinearOpBase< Scalar > > getNonconstBlocks()
RCP< const VectorSpaceBase< Scalar > > domain() const
std::string description() const
Prints just the name DefaultBlockedTriangularLinearOpWithSolve along with the overall dimensions and ...
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.
void setBlock(const int i, const int j, const RCP< const LinearOpBase< Scalar > > &block)
DefaultBlockedTriangularLinearOpWithSolve()
bool blockIsConst(const int i, const int j) const
RCP< const VectorSpaceBase< Scalar > > range() 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 LinearOpBase< Scalar > > clone() const
bool acceptsBlock(const int i, const int j) const
RCP< LinearOpWithSolveBase< Scalar > > getNonconstLOWSBlock(const int i, const int j)
RCP< LinearOpBase< Scalar > > getNonconstBlock(const int i, const int j)
bool blockFillIsActive() const
RCP< const ProductVectorSpaceBase< Scalar > > productRange() const
bool blockExists(const int i, const int j) const
Base class for all linear operators.
Base class for all linear operators that can support a high-level solve operation.
Interface for a collection of column vectors called a multi-vector.
Base interface for physically blocked linear operators.
Base interface for product multi-vectors.
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.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
#define TEUCHOS_ASSERT_INEQUALITY(val1, comp, val2)
#define TEUCHOS_ASSERT_EQUALITY(val1, val2)
@ SOLVE_STATUS_UNCONVERGED
The requested solution criteria has likely not been achieved.
@ SOLVE_STATUS_CONVERGED
The requested solution criteria has likely been achieved.
#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.
#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...
EOpTransp
Enumeration for determining how a linear operator is applied. `*.
T_To & dyn_cast(T_From &from)
Simple struct that defines the requested solution criteria for a solve.
Simple struct for the return status from a solve.
ESolveStatus solveStatus
The return status of the solve.