|
Thyra Package Browser (Single Doxygen Collection) Version of the Day
|
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 }
1.7.4