00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include "Teko_EpetraBlockPreconditioner.hpp"
00048 #include "Teko_Preconditioner.hpp"
00049
00050
00051 #include "Thyra_DefaultLinearOpSource.hpp"
00052 #include "Thyra_EpetraLinearOp.hpp"
00053
00054
00055 #include "Teuchos_Time.hpp"
00056
00057
00058 #include "Teko_BasicMappingStrategy.hpp"
00059
00060 namespace Teko {
00061 namespace Epetra {
00062
00063 using Teuchos::RCP;
00064 using Teuchos::rcp;
00065 using Teuchos::rcpFromRef;
00066 using Teuchos::rcp_dynamic_cast;
00067
00074 EpetraBlockPreconditioner::EpetraBlockPreconditioner(const Teuchos::RCP<const PreconditionerFactory> & bfp)
00075 : preconFactory_(bfp), firstBuildComplete_(false)
00076 {
00077 }
00078
00079 void EpetraBlockPreconditioner::initPreconditioner(bool clearOld)
00080 {
00081 if((not clearOld) && preconObj_!=Teuchos::null)
00082 return;
00083 preconObj_ = preconFactory_->createPrec();
00084 }
00085
00098 void EpetraBlockPreconditioner::buildPreconditioner(const Teuchos::RCP<const Epetra_Operator> & A,bool clear)
00099 {
00100 Teko_DEBUG_SCOPE("EBP::buildPreconditioner",10);
00101
00102
00103 RCP<const Thyra::LinearOpBase<double> > thyraA = extractLinearOp(A);
00104
00105
00106
00107 SetMapStrategy(rcp(new InverseMappingStrategy(extractMappingStrategy(A))));
00108
00109
00110 initPreconditioner(clear);
00111
00112
00113 RCP<const Thyra::LinearOpSourceBase<double> > lOpSrc = Thyra::defaultLinearOpSource(thyraA);
00114 preconFactory_->initializePrec(lOpSrc,&*preconObj_,Thyra::SUPPORT_SOLVE_UNSPECIFIED);
00115
00116
00117 RCP<const Thyra::LinearOpBase<double> > preconditioner = preconObj_->getUnspecifiedPrecOp();
00118
00119 SetOperator(preconditioner,false);
00120
00121 firstBuildComplete_ = true;
00122
00123 TEUCHOS_ASSERT(preconObj_!=Teuchos::null);
00124 TEUCHOS_ASSERT(getThyraOp()!=Teuchos::null);
00125 TEUCHOS_ASSERT(getMapStrategy()!=Teuchos::null);
00126 TEUCHOS_ASSERT(firstBuildComplete_==true);
00127 }
00128
00142 void EpetraBlockPreconditioner::buildPreconditioner(const Teuchos::RCP<const Epetra_Operator> & A,const Epetra_MultiVector & epetra_mv,bool clear)
00143 {
00144 Teko_DEBUG_SCOPE("EBP::buildPreconditioner - with solution",10);
00145
00146
00147 RCP<const Thyra::LinearOpBase<double> > thyraA = extractLinearOp(A);
00148
00149
00150 SetMapStrategy(rcp(new InverseMappingStrategy(extractMappingStrategy(A))));
00151
00152 TEUCHOS_ASSERT(getMapStrategy()!=Teuchos::null);
00153
00154
00155 RCP<Thyra::MultiVectorBase<double> > thyra_mv = Thyra::createMembers(thyraA->range(),epetra_mv.NumVectors());
00156 getMapStrategy()->copyEpetraIntoThyra(epetra_mv,thyra_mv.ptr());
00157
00158
00159 initPreconditioner(clear);
00160
00161
00162 preconFactory_->initializePrec(Thyra::defaultLinearOpSource(thyraA),thyra_mv,&*preconObj_,Thyra::SUPPORT_SOLVE_UNSPECIFIED);
00163 RCP<const Thyra::LinearOpBase<double> > preconditioner = preconObj_->getUnspecifiedPrecOp();
00164
00165 SetOperator(preconditioner,false);
00166
00167 firstBuildComplete_ = true;
00168
00169 TEUCHOS_ASSERT(preconObj_!=Teuchos::null);
00170 TEUCHOS_ASSERT(getThyraOp()!=Teuchos::null);
00171 TEUCHOS_ASSERT(getMapStrategy()!=Teuchos::null);
00172 TEUCHOS_ASSERT(firstBuildComplete_==true);
00173 }
00174
00188 void EpetraBlockPreconditioner::rebuildPreconditioner(const Teuchos::RCP<const Epetra_Operator> & A)
00189 {
00190 Teko_DEBUG_SCOPE("EBP::rebuildPreconditioner",10);
00191
00192
00193 if(not firstBuildComplete_) {
00194 buildPreconditioner(A,false);
00195 return;
00196 }
00197 Teko_DEBUG_EXPR(Teuchos::Time timer(""));
00198
00199
00200 Teko_DEBUG_EXPR(timer.start(true));
00201 RCP<const Thyra::LinearOpBase<double> > thyraA = extractLinearOp(A);
00202 Teko_DEBUG_EXPR(timer.stop());
00203 Teko_DEBUG_MSG("EBP::rebuild get thyraop time = " << timer.totalElapsedTime(),2);
00204
00205
00206 Teko_DEBUG_EXPR(timer.start(true));
00207 preconFactory_->initializePrec(Thyra::defaultLinearOpSource(thyraA),&*preconObj_,Thyra::SUPPORT_SOLVE_UNSPECIFIED);
00208 RCP<const Thyra::LinearOpBase<double> > preconditioner = preconObj_->getUnspecifiedPrecOp();
00209 Teko_DEBUG_EXPR(timer.stop());
00210 Teko_DEBUG_MSG("EBP::rebuild initialize prec time = " << timer.totalElapsedTime(),2);
00211
00212 Teko_DEBUG_EXPR(timer.start(true));
00213 SetOperator(preconditioner,false);
00214 Teko_DEBUG_EXPR(timer.stop());
00215 Teko_DEBUG_MSG("EBP::rebuild set operator time = " << timer.totalElapsedTime(),2);
00216
00217 TEUCHOS_ASSERT(preconObj_!=Teuchos::null);
00218 TEUCHOS_ASSERT(getThyraOp()!=Teuchos::null);
00219 TEUCHOS_ASSERT(firstBuildComplete_==true);
00220 }
00221
00235 void EpetraBlockPreconditioner::rebuildPreconditioner(const Teuchos::RCP<const Epetra_Operator> & A,const Epetra_MultiVector & epetra_mv)
00236 {
00237 Teko_DEBUG_SCOPE("EBP::rebuildPreconditioner - with solution",10);
00238
00239
00240 if(not firstBuildComplete_) {
00241 buildPreconditioner(A,epetra_mv,false);
00242 return;
00243 }
00244 Teko_DEBUG_EXPR(Teuchos::Time timer(""));
00245
00246
00247 Teko_DEBUG_EXPR(timer.start(true));
00248 RCP<const Thyra::LinearOpBase<double> > thyraA = extractLinearOp(A);
00249 Teko_DEBUG_EXPR(timer.stop());
00250 Teko_DEBUG_MSG("EBP::rebuild get thyraop time = " << timer.totalElapsedTime(),2);
00251
00252
00253 Teko_DEBUG_EXPR(timer.start(true));
00254 RCP<Thyra::MultiVectorBase<double> > thyra_mv = Thyra::createMembers(thyraA->range(),epetra_mv.NumVectors());
00255 getMapStrategy()->copyEpetraIntoThyra(epetra_mv,thyra_mv.ptr());
00256 Teko_DEBUG_EXPR(timer.stop());
00257 Teko_DEBUG_MSG("EBP::rebuild vector copy time = " << timer.totalElapsedTime(),2);
00258
00259
00260 Teko_DEBUG_EXPR(timer.start(true));
00261 preconFactory_->initializePrec(Thyra::defaultLinearOpSource(thyraA),thyra_mv,&*preconObj_,Thyra::SUPPORT_SOLVE_UNSPECIFIED);
00262 RCP<const Thyra::LinearOpBase<double> > preconditioner = preconObj_->getUnspecifiedPrecOp();
00263 Teko_DEBUG_EXPR(timer.stop());
00264 Teko_DEBUG_MSG("EBP::rebuild initialize prec time = " << timer.totalElapsedTime(),2);
00265
00266 Teko_DEBUG_EXPR(timer.start(true));
00267 SetOperator(preconditioner,false);
00268 Teko_DEBUG_EXPR(timer.stop());
00269 Teko_DEBUG_MSG("EBP::rebuild set operator time = " << timer.totalElapsedTime(),2);
00270
00271 TEUCHOS_ASSERT(preconObj_!=Teuchos::null);
00272 TEUCHOS_ASSERT(getThyraOp()!=Teuchos::null);
00273 TEUCHOS_ASSERT(firstBuildComplete_==true);
00274 }
00275
00285 Teuchos::RCP<PreconditionerState> EpetraBlockPreconditioner::getPreconditionerState()
00286 {
00287 Teuchos::RCP<Preconditioner> bp = rcp_dynamic_cast<Preconditioner>(preconObj_);
00288
00289 if(bp!=Teuchos::null)
00290 return bp->getStateObject();
00291
00292 return Teuchos::null;
00293 }
00294
00304 Teuchos::RCP<const PreconditionerState> EpetraBlockPreconditioner::getPreconditionerState() const
00305 {
00306 Teuchos::RCP<const Preconditioner> bp = rcp_dynamic_cast<const Preconditioner>(preconObj_);
00307
00308 if(bp!=Teuchos::null)
00309 return bp->getStateObject();
00310
00311 return Teuchos::null;
00312 }
00313
00314 Teuchos::RCP<const Thyra::LinearOpBase<double> > EpetraBlockPreconditioner::extractLinearOp(const Teuchos::RCP<const Epetra_Operator> & A) const
00315 {
00316
00317 const RCP<const EpetraOperatorWrapper> & eow = rcp_dynamic_cast<const EpetraOperatorWrapper>(A);
00318
00319
00320 if(eow!=Teuchos::null)
00321 return eow->getThyraOp();
00322
00323
00324 return Thyra::epetraLinearOp(A);
00325 }
00326
00327 Teuchos::RCP<const MappingStrategy> EpetraBlockPreconditioner::extractMappingStrategy(const Teuchos::RCP<const Epetra_Operator> & A) const
00328 {
00329
00330 const RCP<const EpetraOperatorWrapper> & eow = rcp_dynamic_cast<const EpetraOperatorWrapper>(A);
00331
00332
00333 if(eow!=Teuchos::null)
00334 return eow->getMapStrategy();
00335
00336
00337 RCP<const Epetra_Map> range = rcpFromRef(A->OperatorRangeMap());
00338 RCP<const Epetra_Map> domain = rcpFromRef(A->OperatorDomainMap());
00339 return rcp(new BasicMappingStrategy(range,domain,A->Comm()));
00340 }
00341
00342 }
00343 }