Thyra Package Browser (Single Doxygen Collection) Version of the Day
Thyra_EpetraLinearOp.cpp
Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //               Thyra: Trilinos Solver Framework Core
00005 //                 Copyright (2004) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // ***********************************************************************
00027 // @HEADER
00028 
00029 #include "Thyra_EpetraLinearOp.hpp"
00030 #include "Thyra_EpetraThyraWrappers.hpp"
00031 #include "Thyra_SpmdMultiVectorBase.hpp"
00032 #include "Thyra_MultiVectorStdOps.hpp"
00033 #include "Thyra_AssertOp.hpp"
00034 #include "Teuchos_dyn_cast.hpp"
00035 #include "Teuchos_TestForException.hpp"
00036 #include "Teuchos_getConst.hpp"
00037 #include "Teuchos_Assert.hpp"
00038 #include "Teuchos_as.hpp"
00039 
00040 #include "Epetra_Map.h"
00041 #include "Epetra_Vector.h"
00042 #include "Epetra_Operator.h"
00043 #include "Epetra_CrsMatrix.h" // Printing only!
00044 
00045 #ifndef TEUCHOS_DISABLE_ALL_TIMERS
00046 // Define this to see selected timers
00047 #define EPETRA_THYRA_TEUCHOS_TIMERS
00048 #endif // TEUCHOS_DISABLE_ALL_TIMERS
00049 
00050 #ifdef EPETRA_THYRA_TEUCHOS_TIMERS
00051 #include "Teuchos_TimeMonitor.hpp"
00052 #endif
00053 
00054 
00055 namespace Thyra {
00056 
00057 
00058 // Constructors / initializers / accessors
00059 
00060 
00061 EpetraLinearOp::EpetraLinearOp()
00062   :isFullyInitialized_(false),
00063    opTrans_(NOTRANS),
00064    applyAs_(EPETRA_OP_APPLY_APPLY),
00065    adjointSupport_(EPETRA_OP_ADJOINT_UNSUPPORTED)
00066 {}
00067 
00068 
00069 void EpetraLinearOp::initialize(
00070   const RCP<Epetra_Operator> &op,
00071   EOpTransp opTrans,
00072   EApplyEpetraOpAs applyAs,
00073   EAdjointEpetraOp adjointSupport,
00074   const RCP< const VectorSpaceBase<double> > &range_in,
00075   const RCP< const VectorSpaceBase<double> > &domain_in
00076   )
00077 {
00078   
00079   using Teuchos::rcp_dynamic_cast;
00080   typedef SpmdVectorSpaceBase<double> SPMDVSB;
00081   typedef ScalarProdVectorSpaceBase<double> SPVSB;
00082 
00083   // Validate input, allocate spaces, validate ...
00084 #ifdef TEUCHOS_DEBUG
00085   TEST_FOR_EXCEPTION( is_null(op), std::invalid_argument,
00086     "Thyra::EpetraLinearOp::initialize(...): Error!" );
00087   // ToDo: Validate spmdRange, spmdDomain against op maps!
00088 #endif
00089 
00090   RCP<const SPMDVSB> l_spmdRange;
00091   if(!is_null(range_in))
00092     l_spmdRange = rcp_dynamic_cast<const SPMDVSB>(range_in,true);
00093   else
00094     l_spmdRange = ( applyAs==EPETRA_OP_APPLY_APPLY
00095       ? allocateRange(op,opTrans) : allocateDomain(op,opTrans) );
00096 
00097   RCP<const SPMDVSB> l_spmdDomain;
00098   if(!is_null(domain_in))
00099     l_spmdDomain = rcp_dynamic_cast<const SPMDVSB>(domain_in,true);
00100   else
00101     l_spmdDomain = ( applyAs==EPETRA_OP_APPLY_APPLY
00102       ? allocateDomain(op,opTrans) : allocateRange(op,opTrans) );
00103   
00104   // Set data (no exceptions should be thrown now)
00105   isFullyInitialized_ = true;
00106   op_ = op;
00107   opTrans_ = opTrans;
00108   applyAs_ = applyAs;
00109   adjointSupport_ = adjointSupport;
00110   range_ = l_spmdRange;
00111   domain_ = l_spmdDomain;
00112 
00113 }
00114 
00115 
00116 void EpetraLinearOp::partiallyInitialize(
00117   const RCP<const VectorSpaceBase<double> > &range_in,
00118   const RCP<const VectorSpaceBase<double> > &domain_in,
00119   const RCP<Epetra_Operator> &op,
00120   EOpTransp opTrans,
00121   EApplyEpetraOpAs applyAs,
00122   EAdjointEpetraOp adjointSupport
00123   )
00124 {
00125   
00126   using Teuchos::rcp_dynamic_cast;
00127   typedef SpmdVectorSpaceBase<double> SPMDVSB;
00128   typedef ScalarProdVectorSpaceBase<double> SPVSB;
00129 
00130   // Validate input, allocate spaces, validate ...
00131 #ifdef TEUCHOS_DEBUG
00132   TEST_FOR_EXCEPTION( is_null(range_in), std::invalid_argument,
00133     "Thyra::EpetraLinearOp::partiallyInitialize(...): Error!" );
00134   TEST_FOR_EXCEPTION( is_null(domain_in), std::invalid_argument,
00135     "Thyra::EpetraLinearOp::partiallyInitialize(...): Error!" );
00136   TEST_FOR_EXCEPTION( is_null(op), std::invalid_argument,
00137     "Thyra::EpetraLinearOp::partiallyInitialize(...): Error!" );
00138 #endif
00139 
00140   RCP<const SPMDVSB>
00141     l_spmdRange = rcp_dynamic_cast<const SPMDVSB>(range_in,true);
00142   RCP<const SPMDVSB>
00143     l_spmdDomain = rcp_dynamic_cast<const SPMDVSB>(domain_in,true);
00144   
00145   // Set data (no exceptions should be thrown now)
00146   isFullyInitialized_ = false;
00147   op_ = op;
00148   opTrans_ = opTrans;
00149   applyAs_ = applyAs;
00150   adjointSupport_ = adjointSupport;
00151   range_ = l_spmdRange;
00152   domain_ = l_spmdDomain;
00153   
00154 }
00155 
00156 
00157 void EpetraLinearOp::setFullyInitialized(bool isFullyInitialized)
00158 {
00159   // ToDo: Validate that everything matches up!
00160   isFullyInitialized_ = true;
00161 }
00162 
00163 
00164 void EpetraLinearOp::uninitialize(
00165   RCP<Epetra_Operator> *op,
00166   EOpTransp *opTrans,
00167   EApplyEpetraOpAs *applyAs,
00168   EAdjointEpetraOp *adjointSupport,
00169   RCP<const VectorSpaceBase<double> > *range_out,
00170   RCP<const VectorSpaceBase<double> > *domain_out
00171   )
00172 {
00173 
00174   if(op) *op = op_;
00175   if(opTrans) *opTrans = opTrans_;
00176   if(applyAs) *applyAs = applyAs_;
00177   if(adjointSupport) *adjointSupport = adjointSupport_;
00178   if(range_out) *range_out = range_;
00179   if(domain_out) *domain_out = domain_;
00180 
00181   isFullyInitialized_ = false;
00182   op_ = Teuchos::null;
00183   opTrans_ = NOTRANS;
00184   applyAs_ = EPETRA_OP_APPLY_APPLY;
00185   adjointSupport_ = EPETRA_OP_ADJOINT_SUPPORTED;
00186   range_ = Teuchos::null;
00187   domain_ = Teuchos::null;
00188 
00189 }
00190 
00191 
00192 RCP< const SpmdVectorSpaceBase<double> >
00193 EpetraLinearOp::spmdRange() const
00194 {
00195   return range_;
00196 }
00197 
00198 
00199 RCP< const SpmdVectorSpaceBase<double> >
00200 EpetraLinearOp::spmdDomain() const
00201 {
00202   return domain_;
00203 }
00204 
00205 
00206 RCP<Epetra_Operator>
00207 EpetraLinearOp::epetra_op() 
00208 {
00209   return op_;
00210 }
00211 
00212 
00213 RCP<const Epetra_Operator>
00214 EpetraLinearOp::epetra_op() const 
00215 {
00216   return op_;
00217 }
00218 
00219 
00220 // Overridden from EpetraLinearOpBase
00221 
00222 
00223 void EpetraLinearOp::getNonconstEpetraOpView(
00224   const Ptr<RCP<Epetra_Operator> > &epetraOp,
00225   const Ptr<EOpTransp> &epetraOpTransp,
00226   const Ptr<EApplyEpetraOpAs> &epetraOpApplyAs,
00227   const Ptr<EAdjointEpetraOp> &epetraOpAdjointSupport
00228   )
00229 {
00230   *epetraOp = op_;
00231   *epetraOpTransp = opTrans_;
00232   *epetraOpApplyAs = applyAs_;
00233   *epetraOpAdjointSupport = adjointSupport_;
00234 }
00235 
00236 
00237 void EpetraLinearOp::getEpetraOpView(
00238   const Ptr<RCP<const Epetra_Operator> > &epetraOp,
00239   const Ptr<EOpTransp> &epetraOpTransp,
00240   const Ptr<EApplyEpetraOpAs> &epetraOpApplyAs,
00241   const Ptr<EAdjointEpetraOp> &epetraOpAdjointSupport
00242   ) const
00243 {
00244   *epetraOp = op_;
00245   *epetraOpTransp = opTrans_;
00246   *epetraOpApplyAs = applyAs_;
00247   *epetraOpAdjointSupport = adjointSupport_;
00248 }
00249 
00250 
00251 // Overridden from LinearOpBase
00252 
00253 
00254 RCP<const VectorSpaceBase<double> >
00255 EpetraLinearOp::range() const
00256 {
00257   return range_;
00258 }
00259 
00260 
00261 RCP<const VectorSpaceBase<double> >
00262 EpetraLinearOp::domain() const
00263 {
00264   return domain_;
00265 }
00266 
00267 
00268 RCP<const LinearOpBase<double> >
00269 EpetraLinearOp::clone() const
00270 {
00271   assert(0); // ToDo: Implement when needed
00272   return Teuchos::null;
00273 }
00274 
00275 
00276 // Overridden from Teuchos::Describable
00277 
00278 
00279 std::string EpetraLinearOp::description() const
00280 {
00281   std::ostringstream oss;
00282   oss << Teuchos::Describable::description() << "{";
00283   if(op_.get()) {
00284     oss << "op=\'"<<typeName(*op_)<<"\'";
00285     oss << ",rangeDim="<<this->range()->dim();
00286     oss << ",domainDim="<<this->domain()->dim();
00287   }
00288   else {
00289     oss << "op=NULL";
00290   }
00291   oss << "}";
00292   return oss.str();
00293 }
00294 
00295 
00296 void EpetraLinearOp::describe(
00297   FancyOStream &out,
00298   const Teuchos::EVerbosityLevel verbLevel
00299   ) const
00300 {
00301   typedef Teuchos::ScalarTraits<double> ST;
00302   using Teuchos::includesVerbLevel;
00303   using Teuchos::as;
00304   using Teuchos::rcp_dynamic_cast;
00305   using Teuchos::OSTab;
00306   using Teuchos::describe;
00307   OSTab tab(out);
00308   if ( as<int>(verbLevel) == as<int>(Teuchos::VERB_LOW) || is_null(op_)) {
00309     out << this->description() << std::endl;
00310   }
00311   else if (includesVerbLevel(verbLevel,Teuchos::VERB_MEDIUM)) {
00312     out
00313       << Teuchos::Describable::description()
00314       << "{"
00315       << "rangeDim=" << this->range()->dim()
00316       << ",domainDim=" << this->domain()->dim()
00317       << "}\n";
00318     OSTab tab2(out);
00319     if (op_.get()) {
00320       if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
00321         out << "opTrans="<<toString(opTrans_)<<"\n";
00322         out << "applyAs="<<toString(applyAs_)<<"\n";
00323         out << "adjointSupport="<<toString(adjointSupport_)<<"\n";
00324         out << "op="<<typeName(*op_)<<"\n";
00325       }
00326       if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_EXTREME) ) {
00327         OSTab tab3(out);
00328         RCP<const Epetra_CrsMatrix>
00329           csr_op = rcp_dynamic_cast<const Epetra_CrsMatrix>(op_);
00330         if (!is_null(csr_op)) {
00331           csr_op->Print(out);
00332         }
00333       }
00334     }
00335     else {
00336       out << "op=NULL"<<"\n";
00337     }
00338   }
00339 }
00340 
00341 
00342 // protected
00343 
00344 
00345 // Protected member functions overridden from LinearOpBase
00346 
00347 
00348 bool EpetraLinearOp::opSupportedImpl(EOpTransp M_trans) const
00349 {
00350   if (!isFullyInitialized_)
00351     return false;
00352   return ( M_trans == NOTRANS
00353     ? true : adjointSupport_==EPETRA_OP_ADJOINT_SUPPORTED );
00354 }
00355 
00356 
00357 void EpetraLinearOp::applyImpl(
00358   const EOpTransp M_trans,
00359   const MultiVectorBase<double> &X_in,
00360   const Ptr<MultiVectorBase<double> > &Y_inout,
00361   const double alpha,
00362   const double beta
00363   ) const
00364 {
00365 
00366 #ifdef EPETRA_THYRA_TEUCHOS_TIMERS
00367   TEUCHOS_FUNC_TIME_MONITOR("Thyra::EpetraLinearOp::euclideanApply");
00368 #endif
00369 
00370   const EOpTransp real_M_trans = real_trans(M_trans);
00371 
00372 #ifdef TEUCHOS_DEBUG
00373   TEST_FOR_EXCEPT(!isFullyInitialized_);
00374   THYRA_ASSERT_LINEAR_OP_MULTIVEC_APPLY_SPACES(
00375     "EpetraLinearOp::euclideanApply(...)", *this, M_trans, X_in, &*Y_inout
00376     );
00377   TEST_FOR_EXCEPTION(
00378     real_M_trans==TRANS && adjointSupport_==EPETRA_OP_ADJOINT_UNSUPPORTED,
00379     Exceptions::OpNotSupported,
00380     "EpetraLinearOp::apply(...): *this was informed that adjoints "
00381     "are not supported when initialized." 
00382     );
00383 #endif
00384 
00385   const RCP<const VectorSpaceBase<double> > XY_domain = X_in.domain();
00386   const int numCols = XY_domain->dim();
00387  
00388   //
00389   // Get Epetra_MultiVector objects for the arguments
00390   //
00391   // 2007/08/18: rabartl: Note: After profiling, I found that calling the more
00392   // general functions get_Epetra_MultiVector(...) was too slow. These
00393   // functions must ensure that memory is being remembered efficiently and the
00394   // use of extra data with the RCP and other things is slow.
00395   //
00396   RCP<const Epetra_MultiVector> X;
00397   RCP<Epetra_MultiVector> Y;
00398   {
00399 #ifdef EPETRA_THYRA_TEUCHOS_TIMERS
00400     TEUCHOS_FUNC_TIME_MONITOR_DIFF(
00401       "Thyra::EpetraLinearOp::euclideanApply: Convert MultiVectors", MultiVectors);
00402 #endif
00403     // X
00404     X = get_Epetra_MultiVector(
00405       real_M_trans==NOTRANS ? getDomainMap() : getRangeMap(), X_in );
00406     // Y
00407     if( beta == 0 ) {
00408       Y = get_Epetra_MultiVector(
00409         real_M_trans==NOTRANS ? getRangeMap() : getDomainMap(), *Y_inout );
00410     }
00411   }
00412 
00413   //
00414   // Set the operator mode
00415   //
00416 
00417   /* We need to save the transpose state here, and then reset it after 
00418    * application. The reason for this is that if we later apply the 
00419    * operator outside Thyra (in Aztec, for instance), it will remember
00420    * the transpose flag set here. */
00421   bool oldState = op_->UseTranspose();
00422   op_->SetUseTranspose(
00423     real_trans(trans_trans(opTrans_,M_trans)) == NOTRANS ? false : true );
00424 
00425   //
00426   // Perform the apply operation
00427   //
00428   {
00429 #ifdef EPETRA_THYRA_TEUCHOS_TIMERS
00430     TEUCHOS_FUNC_TIME_MONITOR_DIFF(
00431       "Thyra::EpetraLinearOp::euclideanApply: Apply", Apply);
00432 #endif
00433     if( beta == 0.0 ) {
00434       // Y = M * X
00435       if( applyAs_ == EPETRA_OP_APPLY_APPLY ) {
00436 #ifdef EPETRA_THYRA_TEUCHOS_TIMERS
00437         TEUCHOS_FUNC_TIME_MONITOR_DIFF(
00438           "Thyra::EpetraLinearOp::euclideanApply: Apply(beta==0): Apply",
00439           ApplyApply);
00440 #endif
00441         op_->Apply( *X, *Y );
00442       }
00443       else if( applyAs_ == EPETRA_OP_APPLY_APPLY_INVERSE ) {
00444 #ifdef EPETRA_THYRA_TEUCHOS_TIMERS
00445         TEUCHOS_FUNC_TIME_MONITOR_DIFF(
00446           "Thyra::EpetraLinearOp::euclideanApply: Apply(beta==0): ApplyInverse",
00447           ApplyApplyInverse);
00448 #endif
00449         op_->ApplyInverse( *X, *Y );
00450       }
00451       else {
00452 #ifdef TEUCHOS_DEBUG
00453         TEST_FOR_EXCEPT(true);
00454 #endif
00455       }
00456       // Y = alpha * Y
00457       if( alpha != 1.0 ) {
00458 #ifdef EPETRA_THYRA_TEUCHOS_TIMERS
00459         TEUCHOS_FUNC_TIME_MONITOR_DIFF(
00460           "Thyra::EpetraLinearOp::euclideanApply: Apply(beta==0): Scale Y",
00461           Scale);
00462 #endif
00463         Y->Scale(alpha);
00464       }
00465     }
00466     else {  // beta != 0.0
00467       // Y_inout = beta * Y_inout
00468       if(beta != 0.0) {
00469 #ifdef EPETRA_THYRA_TEUCHOS_TIMERS
00470         TEUCHOS_FUNC_TIME_MONITOR_DIFF(
00471           "Thyra::EpetraLinearOp::euclideanApply: Apply(beta!=0): Scale Y",
00472           Scale);
00473 #endif
00474         scale( beta, Y_inout );
00475       }
00476       else {
00477 #ifdef EPETRA_THYRA_TEUCHOS_TIMERS
00478         TEUCHOS_FUNC_TIME_MONITOR_DIFF(
00479           "Thyra::EpetraLinearOp::euclideanApply: Apply(beta!=0): Y=0",
00480           Apply2);
00481 #endif
00482         assign( Y_inout, 0.0 );
00483       }
00484       // T = M * X
00485       Epetra_MultiVector T(op_->OperatorRangeMap(), numCols, false);
00486       // NOTE: Above, op_->OperatorRange() will be right for either
00487       // non-transpose or transpose because we have already set the
00488       // UseTranspose flag correctly.
00489       if( applyAs_ == EPETRA_OP_APPLY_APPLY ) {
00490 #ifdef EPETRA_THYRA_TEUCHOS_TIMERS
00491         TEUCHOS_FUNC_TIME_MONITOR_DIFF(
00492           "Thyra::EpetraLinearOp::euclideanApply: Apply(beta!=0): Apply",
00493           Apply2);
00494 #endif
00495         op_->Apply( *X, T );
00496       }
00497       else if( applyAs_ == EPETRA_OP_APPLY_APPLY_INVERSE ) {
00498 #ifdef EPETRA_THYRA_TEUCHOS_TIMERS
00499         TEUCHOS_FUNC_TIME_MONITOR_DIFF(
00500           "Thyra::EpetraLinearOp::euclideanApply: Apply(beta!=0): ApplyInverse",
00501           ApplyInverse);
00502 #endif
00503         op_->ApplyInverse( *X, T );
00504       }
00505       else {
00506 #ifdef TEUCHOS_DEBUG
00507         TEST_FOR_EXCEPT(true);
00508 #endif
00509       }
00510       // Y_inout += alpha * T
00511       {
00512 #ifdef EPETRA_THYRA_TEUCHOS_TIMERS
00513         TEUCHOS_FUNC_TIME_MONITOR_DIFF(
00514           "Thyra::EpetraLinearOp::euclideanApply: Apply(beta!=0): Update Y",
00515           Update);
00516 #endif
00517         update(
00518           alpha,
00519           *create_MultiVector(
00520             Teuchos::rcp(&Teuchos::getConst(T),false),
00521             Y_inout->range(),
00522             XY_domain
00523             ),
00524           Y_inout
00525           );
00526       }
00527     }
00528   }
00529 
00530   // Reset the transpose state
00531   op_->SetUseTranspose(oldState);
00532 
00533   // 2009/04/14: ToDo: This will not reset the transpose flag correctly if an
00534   // exception is thrown!
00535 
00536 }
00537 
00538 
00539 // Allocators for domain and range spaces
00540 
00541 
00542 RCP< const SpmdVectorSpaceBase<double> > 
00543 EpetraLinearOp::allocateDomain(
00544   const RCP<Epetra_Operator> &op,
00545   EOpTransp op_trans
00546   ) const
00547 {
00548   return Teuchos::rcp_dynamic_cast<const SpmdVectorSpaceBase<double> >(
00549     create_VectorSpace(Teuchos::rcp(&op->OperatorDomainMap(),false))
00550     );
00551   // ToDo: What about the transpose argument???, test this!!!
00552 }
00553 
00554 
00555 RCP<const SpmdVectorSpaceBase<double> > 
00556 EpetraLinearOp::allocateRange(
00557   const RCP<Epetra_Operator> &op,
00558   EOpTransp op_trans
00559   ) const
00560 {
00561   return Teuchos::rcp_dynamic_cast<const SpmdVectorSpaceBase<double> >(
00562     create_VectorSpace(Teuchos::rcp(&op->OperatorRangeMap(),false))
00563     );
00564   // ToDo: What about the transpose argument???, test this!!!
00565 }
00566 
00567 
00568 // private
00569 
00570 
00571 const Epetra_Map& EpetraLinearOp::getRangeMap() const
00572 {
00573   return ( applyAs_ == EPETRA_OP_APPLY_APPLY
00574     ? op_->OperatorRangeMap() : op_->OperatorDomainMap() );
00575   // ToDo: What about the transpose argument???, test this!!!
00576 }
00577 
00578 
00579 const Epetra_Map& EpetraLinearOp::getDomainMap() const
00580 {
00581   return ( applyAs_ == EPETRA_OP_APPLY_APPLY
00582     ? op_->OperatorDomainMap() : op_->OperatorRangeMap() );
00583   // ToDo: What about the transpose argument???, test this!!!
00584 }
00585 
00586 
00587 } // end namespace Thyra
00588 
00589 
00590 // Nonmembers
00591 
00592 
00593 Teuchos::RCP<Thyra::EpetraLinearOp>
00594 Thyra::nonconstEpetraLinearOp()
00595 {
00596   return Teuchos::rcp(new EpetraLinearOp());
00597 }
00598 
00599 
00600 Teuchos::RCP<Thyra::EpetraLinearOp>
00601 Thyra::partialNonconstEpetraLinearOp(
00602   const RCP<const VectorSpaceBase<double> > &range,
00603   const RCP<const VectorSpaceBase<double> > &domain,
00604   const RCP<Epetra_Operator> &op,
00605   EOpTransp opTrans,
00606   EApplyEpetraOpAs applyAs,
00607   EAdjointEpetraOp adjointSupport
00608   )
00609 {
00610   RCP<EpetraLinearOp> thyraEpetraOp = Teuchos::rcp(new EpetraLinearOp());
00611   thyraEpetraOp->partiallyInitialize(
00612     range, domain,op,opTrans, applyAs, adjointSupport
00613     );
00614   return thyraEpetraOp;
00615 }
00616 
00617 
00618 Teuchos::RCP<Thyra::EpetraLinearOp>
00619 Thyra::nonconstEpetraLinearOp(
00620   const RCP<Epetra_Operator> &op,
00621   EOpTransp opTrans,
00622   EApplyEpetraOpAs applyAs,
00623   EAdjointEpetraOp adjointSupport,
00624   const RCP< const VectorSpaceBase<double> > &range,
00625   const RCP< const VectorSpaceBase<double> > &domain
00626   )
00627 {
00628   RCP<EpetraLinearOp> thyraEpetraOp = Teuchos::rcp(new EpetraLinearOp());
00629   thyraEpetraOp->initialize(
00630     op,opTrans, applyAs, adjointSupport, range, domain
00631     );
00632   return thyraEpetraOp;
00633 }
00634 
00635 
00636 Teuchos::RCP<const Thyra::EpetraLinearOp>
00637 Thyra::epetraLinearOp(
00638   const RCP<const Epetra_Operator> &op,
00639   EOpTransp opTrans,
00640   EApplyEpetraOpAs applyAs,
00641   EAdjointEpetraOp adjointSupport,
00642   const RCP<const VectorSpaceBase<double> > &range,
00643   const RCP<const VectorSpaceBase<double> > &domain
00644   )
00645 {
00646   RCP<EpetraLinearOp> thyraEpetraOp = Teuchos::rcp(new EpetraLinearOp());
00647   thyraEpetraOp->initialize(
00648     Teuchos::rcp_const_cast<Epetra_Operator>(op), // Safe cast due to return type!
00649     opTrans, applyAs, adjointSupport, range, domain
00650     );
00651   return thyraEpetraOp;
00652 }
00653 
00654 
00655 Teuchos::RCP<Thyra::EpetraLinearOp>
00656 Thyra::nonconstEpetraLinearOp(
00657   const RCP<Epetra_Operator> &op,
00658   const std::string &label,
00659   EOpTransp opTrans,
00660   EApplyEpetraOpAs applyAs,
00661   EAdjointEpetraOp adjointSupport,
00662   const RCP<const VectorSpaceBase<double> > &range,
00663   const RCP<const VectorSpaceBase<double> > &domain
00664   )
00665 {
00666   RCP<EpetraLinearOp> thyraEpetraOp = Teuchos::rcp(new EpetraLinearOp());
00667   thyraEpetraOp->initialize(
00668     op,opTrans, applyAs, adjointSupport, range, domain
00669     );
00670   thyraEpetraOp->setObjectLabel(label);
00671   return thyraEpetraOp;
00672 }
00673 
00674 
00675 Teuchos::RCP<const Thyra::EpetraLinearOp>
00676 Thyra::epetraLinearOp(
00677   const RCP<const Epetra_Operator> &op,
00678   const std::string &label,
00679   EOpTransp opTrans,
00680   EApplyEpetraOpAs applyAs,
00681   EAdjointEpetraOp adjointSupport,
00682   const RCP< const SpmdVectorSpaceBase<double> > &range,
00683   const RCP< const SpmdVectorSpaceBase<double> > &domain
00684   )
00685 {
00686   RCP<EpetraLinearOp> thyraEpetraOp = Teuchos::rcp(new EpetraLinearOp());
00687   thyraEpetraOp->initialize(
00688     Teuchos::rcp_const_cast<Epetra_Operator>(op), // Safe cast due to return type!
00689     opTrans, applyAs, adjointSupport, range, domain
00690     );
00691   thyraEpetraOp->setObjectLabel(label);
00692   return thyraEpetraOp;
00693 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines