10#include "Thyra_EpetraLinearOp.hpp" 
   12#include "Thyra_SpmdMultiVectorBase.hpp" 
   13#include "Thyra_MultiVectorStdOps.hpp" 
   14#include "Thyra_AssertOp.hpp" 
   15#include "Teuchos_dyn_cast.hpp" 
   16#include "Teuchos_Assert.hpp" 
   17#include "Teuchos_getConst.hpp" 
   18#include "Teuchos_as.hpp" 
   19#include "Teuchos_TimeMonitor.hpp" 
   21#include "Epetra_Map.h" 
   22#include "Epetra_Vector.h" 
   23#include "Epetra_Operator.h" 
   24#include "Epetra_CrsMatrix.h"  
   34  :isFullyInitialized_(false),
 
 
   51  using Teuchos::rcp_dynamic_cast;
 
   57    "Thyra::EpetraLinearOp::initialize(...): Error!" );
 
   62  if(!is_null(range_in))
 
   63    l_spmdRange = rcp_dynamic_cast<const SPMDVSB>(range_in,
true);
 
   69  if(!is_null(domain_in))
 
   70    l_spmdDomain = rcp_dynamic_cast<const SPMDVSB>(domain_in,
true);
 
   76  isFullyInitialized_ = 
true;
 
   81  adjointSupport_ = adjointSupport;
 
   83  domain_ = l_spmdDomain;
 
 
   98  using Teuchos::rcp_dynamic_cast;
 
  104    "Thyra::EpetraLinearOp::partiallyInitialize(...): Error!" );
 
  106    "Thyra::EpetraLinearOp::partiallyInitialize(...): Error!" );
 
  108    "Thyra::EpetraLinearOp::partiallyInitialize(...): Error!" );
 
  112    l_spmdRange = rcp_dynamic_cast<const SPMDVSB>(range_in,
true);
 
  114    l_spmdDomain = rcp_dynamic_cast<const SPMDVSB>(domain_in,
true);
 
  117  isFullyInitialized_ = 
false;
 
  122  adjointSupport_ = adjointSupport;
 
  123  range_ = l_spmdRange;
 
  124  domain_ = l_spmdDomain;
 
 
  132  isFullyInitialized_ = 
true;
 
 
  147  if(opTrans) *opTrans = opTrans_;
 
  148  if(applyAs) *applyAs = applyAs_;
 
  149  if(adjointSupport) *adjointSupport = adjointSupport_;
 
  150  if(range_out) *range_out = range_;
 
  151  if(domain_out) *domain_out = domain_;
 
  153  isFullyInitialized_ = 
false;
 
 
  204  *epetraOpTransp = opTrans_;
 
  205  *epetraOpApplyAs = applyAs_;
 
  206  *epetraOpAdjointSupport = adjointSupport_;
 
 
  218  *epetraOpTransp = opTrans_;
 
  219  *epetraOpApplyAs = applyAs_;
 
  220  *epetraOpAdjointSupport = adjointSupport_;
 
 
  254  std::ostringstream oss;
 
  257    oss << 
"op=\'"<<typeName(*op_)<<
"\'";
 
  258    oss << 
",rangeDim="<<this->
range()->dim();
 
  259    oss << 
",domainDim="<<this->
domain()->dim();
 
 
  276  using Teuchos::rcp_dynamic_cast;
 
  278  using Teuchos::describe;
 
  287      << 
"rangeDim=" << this->
range()->dim()
 
  288      << 
",domainDim=" << this->
domain()->dim()
 
  293        out << 
"opTrans="<<
toString(opTrans_)<<
"\n";
 
  294        out << 
"applyAs="<<
toString(applyAs_)<<
"\n";
 
  295        out << 
"adjointSupport="<<
toString(adjointSupport_)<<
"\n";
 
  296        out << 
"op="<<typeName(*op_)<<
"\n";
 
  301          csr_op = rcp_dynamic_cast<const Epetra_CrsMatrix>(op_);
 
  302        if (!is_null(csr_op)) {
 
  308      out << 
"op=NULL"<<
"\n";
 
 
  322  if (!isFullyInitialized_)
 
 
  338  THYRA_FUNC_TIME_MONITOR(
"Thyra::EpetraLinearOp::euclideanApply");
 
  345    "EpetraLinearOp::euclideanApply(...)", *
this, M_trans, X_in, Y_inout
 
  350    "EpetraLinearOp::apply(...): *this was informed that adjoints " 
  351    "are not supported when initialized."  
  356  const int numCols = XY_domain->dim();
 
  369    THYRA_FUNC_TIME_MONITOR_DIFF(
 
  370      "Thyra::EpetraLinearOp::euclideanApply: Convert MultiVectors", MultiVectors);
 
  373      real_M_trans==
NOTRANS ? getDomainMap() : getRangeMap(), X_in );
 
  377        real_M_trans==
NOTRANS ? getRangeMap() : getDomainMap(), *Y_inout );
 
  389  bool oldState = op_->UseTranspose();
 
  390  op_->SetUseTranspose(
 
  397    THYRA_FUNC_TIME_MONITOR_DIFF(
 
  398      "Thyra::EpetraLinearOp::euclideanApply: Apply", Apply);
 
  402        THYRA_FUNC_TIME_MONITOR_DIFF(
 
  403          "Thyra::EpetraLinearOp::euclideanApply: Apply(beta==0): Apply",
 
  405        op_->Apply( *X, *Y );
 
  408        THYRA_FUNC_TIME_MONITOR_DIFF(
 
  409          "Thyra::EpetraLinearOp::euclideanApply: Apply(beta==0): ApplyInverse",
 
  411        op_->ApplyInverse( *X, *Y );
 
  420        THYRA_FUNC_TIME_MONITOR_DIFF(
 
  421          "Thyra::EpetraLinearOp::euclideanApply: Apply(beta==0): Scale Y",
 
  429        THYRA_FUNC_TIME_MONITOR_DIFF(
 
  430          "Thyra::EpetraLinearOp::euclideanApply: Apply(beta!=0): Scale Y",
 
  432        scale( beta, Y_inout );
 
  435        THYRA_FUNC_TIME_MONITOR_DIFF(
 
  436          "Thyra::EpetraLinearOp::euclideanApply: Apply(beta!=0): Y=0",
 
  438        assign( Y_inout, 0.0 );
 
  446        THYRA_FUNC_TIME_MONITOR_DIFF(
 
  447          "Thyra::EpetraLinearOp::euclideanApply: Apply(beta!=0): Apply",
 
  452        THYRA_FUNC_TIME_MONITOR_DIFF(
 
  453          "Thyra::EpetraLinearOp::euclideanApply: Apply(beta!=0): ApplyInverse",
 
  455        op_->ApplyInverse( *X, T );
 
  464        THYRA_FUNC_TIME_MONITOR_DIFF(
 
  465          "Thyra::EpetraLinearOp::euclideanApply: Apply(beta!=0): Update Y",
 
  481  op_->SetUseTranspose(oldState);
 
 
  494  return nonnull(rowMatrix_);
 
 
  500  return nonnull(rowMatrix_);
 
 
  506  using Teuchos::rcpFromRef;
 
  509  rowMatrix_->LeftScale(*row_scaling);
 
 
  515  using Teuchos::rcpFromRef;
 
  518  rowMatrix_->RightScale(*col_scaling);
 
 
  526  const RowStatLinearOpBaseUtils::ERowStat rowStat)
 const 
  528  if (is_null(rowMatrix_)) {
 
  532    case RowStatLinearOpBaseUtils::ROW_STAT_INV_ROW_SUM:
 
  533    case RowStatLinearOpBaseUtils::ROW_STAT_ROW_SUM:
 
 
  543  const RowStatLinearOpBaseUtils::ERowStat rowStat,
 
  547  using Teuchos::rcpFromPtr;
 
  551    case RowStatLinearOpBaseUtils::ROW_STAT_INV_ROW_SUM:
 
  552      rowMatrix_->InvRowSums(*rowStatVec);
 
  554    case RowStatLinearOpBaseUtils::ROW_STAT_ROW_SUM:
 
  556      computeAbsRowSum(*rowStatVec);
 
 
  595const Epetra_Map& EpetraLinearOp::getRangeMap()
 const 
  598    ? op_->OperatorRangeMap() : op_->OperatorDomainMap() );
 
  603const Epetra_Map& EpetraLinearOp::getDomainMap()
 const 
  606    ? op_->OperatorDomainMap() : op_->OperatorRangeMap() );
 
  610void EpetraLinearOp::computeAbsRowSum(
Epetra_Vector & x)
 const 
  614  RCP<Epetra_CrsMatrix> crsMatrix 
 
  618    Exceptions::OpNotSupported,
 
  619    "EpetraLinearOp::computeAbsRowSum(...): wrapped matrix must be of type " 
  620    "Epetra_CrsMatrix for this method. Other operator types are not supported." 
  628  if (crsMatrix->Filled()) {
 
  630      std::invalid_argument,
 
  631      "EpetraLinearOp::computeAbsRowSum(...): Epetra_CrsMatrix must be filled" 
  636  double * xp = (
double*)x.
Values();
 
  637  if (crsMatrix->Graph().RangeMap().SameAs(x.
Map()) && crsMatrix->Exporter() != 0) {
 
  639    x_tmp.PutScalar(0.0);
 
  640    double * x_tmp_p = (
double*)x_tmp.Values();
 
  641    for (i=0; i < crsMatrix->NumMyRows(); i++) {
 
  643      double * RowValues  = 0;
 
  644      crsMatrix->ExtractMyRowView(i,NumEntries,RowValues);
 
  645      for (j=0; j < NumEntries; j++)  x_tmp_p[i] += std::abs(RowValues[j]);
 
  649  else if (crsMatrix->Graph().RowMap().SameAs(x.
Map())) {
 
  650    for (i=0; i < crsMatrix->NumMyRows(); i++) {
 
  652      double * RowValues  = 0;
 
  653      crsMatrix->ExtractMyRowView(i,NumEntries,RowValues);
 
  655      for (j=0; j < NumEntries; j++) scale += std::abs(RowValues[j]);
 
  671Thyra::nonconstEpetraLinearOp()
 
  678Thyra::partialNonconstEpetraLinearOp(
 
  679  const RCP<
const VectorSpaceBase<double> > &range,
 
  680  const RCP<
const VectorSpaceBase<double> > &domain,
 
  681  const RCP<Epetra_Operator> &op,
 
  683  EApplyEpetraOpAs applyAs,
 
  684  EAdjointEpetraOp adjointSupport
 
  687  RCP<EpetraLinearOp> thyraEpetraOp = 
Teuchos::rcp(
new EpetraLinearOp());
 
  688  thyraEpetraOp->partiallyInitialize(
 
  689    range, domain,op,opTrans, applyAs, adjointSupport
 
  691  return thyraEpetraOp;
 
  696Thyra::nonconstEpetraLinearOp(
 
  697  const RCP<Epetra_Operator> &op,
 
  699  EApplyEpetraOpAs applyAs,
 
  700  EAdjointEpetraOp adjointSupport,
 
  701  const RCP< 
const VectorSpaceBase<double> > &range,
 
  702  const RCP< 
const VectorSpaceBase<double> > &domain
 
  705  RCP<EpetraLinearOp> thyraEpetraOp = 
Teuchos::rcp(
new EpetraLinearOp());
 
  706  thyraEpetraOp->initialize(
 
  707    op,opTrans, applyAs, adjointSupport, range, domain
 
  709  return thyraEpetraOp;
 
  714Thyra::epetraLinearOp(
 
  715  const RCP<const Epetra_Operator> &op,
 
  717  EApplyEpetraOpAs applyAs,
 
  718  EAdjointEpetraOp adjointSupport,
 
  719  const RCP<
const VectorSpaceBase<double> > &range,
 
  720  const RCP<
const VectorSpaceBase<double> > &domain
 
  723  RCP<EpetraLinearOp> thyraEpetraOp = 
Teuchos::rcp(
new EpetraLinearOp());
 
  724  thyraEpetraOp->initialize(
 
  726    opTrans, applyAs, adjointSupport, range, domain
 
  728  return thyraEpetraOp;
 
  733Thyra::nonconstEpetraLinearOp(
 
  734  const RCP<Epetra_Operator> &op,
 
  735  const std::string &label,
 
  737  EApplyEpetraOpAs applyAs,
 
  738  EAdjointEpetraOp adjointSupport,
 
  739  const RCP<
const VectorSpaceBase<double> > &range,
 
  740  const RCP<
const VectorSpaceBase<double> > &domain
 
  743  RCP<EpetraLinearOp> thyraEpetraOp = 
Teuchos::rcp(
new EpetraLinearOp());
 
  744  thyraEpetraOp->initialize(
 
  745    op,opTrans, applyAs, adjointSupport, range, domain
 
  747  thyraEpetraOp->setObjectLabel(label);
 
  748  return thyraEpetraOp;
 
  753Thyra::epetraLinearOp(
 
  754  const RCP<const Epetra_Operator> &op,
 
  755  const std::string &label,
 
  757  EApplyEpetraOpAs applyAs,
 
  758  EAdjointEpetraOp adjointSupport,
 
  759  const RCP< 
const SpmdVectorSpaceBase<double> > &range,
 
  760  const RCP< 
const SpmdVectorSpaceBase<double> > &domain
 
  763  RCP<EpetraLinearOp> thyraEpetraOp = 
Teuchos::rcp(
new EpetraLinearOp());
 
  764  thyraEpetraOp->initialize(
 
  766    opTrans, applyAs, adjointSupport, range, domain
 
  768  thyraEpetraOp->setObjectLabel(label);
 
  769  return thyraEpetraOp;
 
const Epetra_BlockMap & Map() const
 
int Export(const Epetra_SrcDistObject &A, const Epetra_Import &Importer, Epetra_CombineMode CombineMode, const Epetra_OffsetIndex *Indexor=0)
 
int PutScalar(double ScalarConstant)
 
virtual std::string description() const
 
RCP< const SpmdVectorSpaceBase< double > > spmdDomain() const
Return a smart pointer to the SpmdVectorSpaceBase object for the domain.
 
std::string description() const
 
virtual void scaleLeftImpl(const VectorBase< double > &row_scaling)
 
void applyImpl(const EOpTransp M_trans, const MultiVectorBase< double > &X, const Ptr< MultiVectorBase< double > > &Y, const double alpha, const double beta) const
 
virtual void scaleRightImpl(const VectorBase< double > &col_scaling)
 
void getNonconstEpetraOpView(const Ptr< RCP< Epetra_Operator > > &epetraOp, const Ptr< EOpTransp > &epetraOpTransp, const Ptr< EApplyEpetraOpAs > &epetraOpApplyAs, const Ptr< EAdjointEpetraOp > &epetraOpAdjointSupport)
 
void getEpetraOpView(const Ptr< RCP< const Epetra_Operator > > &epetraOp, const Ptr< EOpTransp > &epetraOpTransp, const Ptr< EApplyEpetraOpAs > &epetraOpApplyAs, const Ptr< EAdjointEpetraOp > &epetraOpAdjointSupport) const
 
void uninitialize(RCP< Epetra_Operator > *op=NULL, EOpTransp *opTrans=NULL, EApplyEpetraOpAs *applyAs=NULL, EAdjointEpetraOp *adjointSupport=NULL, RCP< const VectorSpaceBase< double > > *range=NULL, RCP< const VectorSpaceBase< double > > *domain=NULL)
Set to uninitialized and optionally return the current state.
 
EpetraLinearOp()
Construct to uninitialized.
 
virtual bool supportsScaleRightImpl() const
 
void setFullyInitialized(bool isFullyInitialized=true)
Set to fully initialized.
 
virtual void getRowStatImpl(const RowStatLinearOpBaseUtils::ERowStat rowStat, const Ptr< VectorBase< double > > &rowStatVec) const
 
void describe(FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel) const
 
virtual RCP< const SpmdVectorSpaceBase< double > > allocateRange(const RCP< Epetra_Operator > &op, EOpTransp op_trans) const
Allocate the range space of the operator.
 
void initialize(const RCP< Epetra_Operator > &op, EOpTransp opTrans=NOTRANS, EApplyEpetraOpAs applyAs=EPETRA_OP_APPLY_APPLY, EAdjointEpetraOp adjointSupport=EPETRA_OP_ADJOINT_SUPPORTED, const RCP< const VectorSpaceBase< double > > &range=Teuchos::null, const RCP< const VectorSpaceBase< double > > &domain=Teuchos::null)
Fully initialize.
 
RCP< const LinearOpBase< double > > clone() const
 
void partiallyInitialize(const RCP< const VectorSpaceBase< double > > &range, const RCP< const VectorSpaceBase< double > > &domain, const RCP< Epetra_Operator > &op, EOpTransp opTrans=NOTRANS, EApplyEpetraOpAs applyAs=EPETRA_OP_APPLY_APPLY, EAdjointEpetraOp adjointSupport=EPETRA_OP_ADJOINT_SUPPORTED)
Partially initialize.
 
RCP< const SpmdVectorSpaceBase< double > > spmdRange() const
Return a smart pointer to the SpmdVectorSpaceBase object for the range.
 
virtual bool rowStatIsSupportedImpl(const RowStatLinearOpBaseUtils::ERowStat rowStat) const
 
RCP< Epetra_Operator > epetra_op()
 
virtual RCP< const SpmdVectorSpaceBase< double > > allocateDomain(const RCP< Epetra_Operator > &op, EOpTransp op_trans) const
Allocate the domain space of the operator.
 
bool opSupportedImpl(EOpTransp M_trans) const
 
RCP< const VectorSpaceBase< double > > range() const
 
virtual bool supportsScaleLeftImpl() const
 
RCP< const VectorSpaceBase< double > > domain() const
 
virtual RCP< const VectorSpaceBase< Scalar > > domain() const =0
Return a smart pointer for the domain space for this operator.
 
Interface for a collection of column vectors called a multi-vector.
 
Base abstract VectorSpaceBase class for all SPMD-based vector spaces.
 
Abstract interface for finite-dimensional dense vectors.
 
Abstract interface for objects that represent a space for vectors.
 
EApplyEpetraOpAs
Determine how the apply an Epetra_Operator as a linear operator.
 
RCP< MultiVectorBase< double > > create_MultiVector(const RCP< Epetra_MultiVector > &epetra_mv, const RCP< const VectorSpaceBase< double > > &range=Teuchos::null, const RCP< const VectorSpaceBase< double > > &domain=Teuchos::null)
Create a non-const MultiVectorBase object from a non-const Epetra_MultiVector object.
 
RCP< const VectorSpaceBase< double > > create_VectorSpace(const RCP< const Epetra_Map > &epetra_map)
Create an VectorSpaceBase object given an Epetra_Map object.
 
RCP< Epetra_Vector > get_Epetra_Vector(const Epetra_Map &map, const RCP< VectorBase< double > > &v)
Get a non-const Epetra_Vector view from a non-const VectorBase object if possible.
 
RCP< Epetra_MultiVector > get_Epetra_MultiVector(const Epetra_Map &map, const RCP< MultiVectorBase< double > > &mv)
Get a non-const Epetra_MultiVector view from a non-const MultiVectorBase object if possible.
 
EAdjointEpetraOp
Determine if adjoints are supported on Epetra_Opeator or not.
 
@ EPETRA_OP_APPLY_APPLY
Apply using Epetra_Operator::Apply(...)
 
@ EPETRA_OP_APPLY_APPLY_INVERSE
Apply using Epetra_Operator::ApplyInverse(...)
 
@ EPETRA_OP_ADJOINT_UNSUPPORTED
Adjoint not supported.
 
@ EPETRA_OP_ADJOINT_SUPPORTED
Adjoint supported.
 
#define TEUCHOS_ASSERT(assertion_test)
 
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)
 
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
 
bool is_null(const std::shared_ptr< T > &p)
 
#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. `*.
 
const char * toString(EConj conj)
Return a string name for a EOpTransp value. `*.
 
EOpTransp real_trans(EOpTransp transp)
Return NOTRANS or TRANS for real scalar valued operators and this also is used for determining struct...
 
EOpTransp trans_trans(EOpTransp trans1, EOpTransp trans2)
Combine two transpose arguments.
 
@ TRANS
Use the transposed operator.
 
@ NOTRANS
Use the non-transposed operator.
 
TypeTo as(const TypeFrom &t)
 
#define TEUCHOS_UNREACHABLE_RETURN(dummyReturnVal)
 
T_To & dyn_cast(T_From &from)
 
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
 
TEUCHOSCORE_LIB_DLL_EXPORT bool includesVerbLevel(const EVerbosityLevel verbLevel, const EVerbosityLevel requestedVerbLevel, const bool isDefaultLevel=false)