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.