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)