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_InverseFactoryOperator.hpp"
00048
00049
00050 #include "Teko_BasicMappingStrategy.hpp"
00051
00052
00053 #include "Thyra_EpetraLinearOp.hpp"
00054
00055 using Teuchos::RCP;
00056 using Teuchos::rcp;
00057 using Teuchos::rcpFromRef;
00058 using Teuchos::rcp_dynamic_cast;
00059
00060 namespace Teko {
00061 namespace Epetra {
00062
00069 InverseFactoryOperator::InverseFactoryOperator(const Teuchos::RCP<const InverseFactory> & ifp)
00070 : inverseFactory_(ifp), firstBuildComplete_(false), setConstFwdOp_(true)
00071 {
00072 }
00073
00086 void InverseFactoryOperator::initInverse(bool clearOld)
00087 {
00088 if(not clearOld)
00089 return;
00090 invOperator_ = Teuchos::null;
00091 }
00092
00105 void InverseFactoryOperator::buildInverseOperator(const Teuchos::RCP<const Epetra_Operator> & A,bool clear)
00106 {
00107 Teko_DEBUG_SCOPE("InverseFactoryOperator::buildInverseOperator",10);
00108
00109
00110 RCP<const Thyra::LinearOpBase<double> > thyraA = extractLinearOp(A);
00111
00112
00113 SetMapStrategy(rcp(new InverseMappingStrategy(extractMappingStrategy(A))));
00114
00115 initInverse(clear);
00116
00117
00118 invOperator_ = Teko::buildInverse(*inverseFactory_,thyraA);
00119
00120 SetOperator(invOperator_,false);
00121
00122 firstBuildComplete_ = true;
00123
00124 if(setConstFwdOp_)
00125 fwdOp_ = A;
00126
00127 setConstFwdOp_ = true;
00128
00129 TEUCHOS_ASSERT(invOperator_!=Teuchos::null);
00130 TEUCHOS_ASSERT(getForwardOp()!=Teuchos::null);
00131 TEUCHOS_ASSERT(getThyraOp()!=Teuchos::null);
00132 TEUCHOS_ASSERT(getMapStrategy()!=Teuchos::null);
00133 TEUCHOS_ASSERT(firstBuildComplete_==true);
00134 }
00135
00136 void InverseFactoryOperator::buildInverseOperator(const Teuchos::RCP<Epetra_Operator> & A,bool clear)
00137 {
00138 setConstFwdOp_ = false;
00139
00140 fwdOp_.initialize(A);
00141
00142 buildInverseOperator(A.getConst());
00143
00144 TEUCHOS_ASSERT(setConstFwdOp_==true);
00145 }
00146
00159 void InverseFactoryOperator::rebuildInverseOperator(const Teuchos::RCP<const Epetra_Operator> & A)
00160 {
00161 Teko_DEBUG_SCOPE("InverseFactoryOperator::rebuildPreconditioner",10);
00162
00163
00164 if(not firstBuildComplete_) {
00165 buildInverseOperator(A,false);
00166 return;
00167 }
00168
00169 RCP<const Thyra::LinearOpBase<double> > thyraA = extractLinearOp(A);
00170 Teko::rebuildInverse(*inverseFactory_,thyraA,invOperator_);
00171
00172 if(setConstFwdOp_)
00173 fwdOp_.initialize(A);
00174
00175 SetOperator(invOperator_,false);
00176
00177 setConstFwdOp_ = true;
00178
00179 TEUCHOS_ASSERT(getForwardOp()!=Teuchos::null);
00180 TEUCHOS_ASSERT(invOperator_!=Teuchos::null);
00181 TEUCHOS_ASSERT(getThyraOp()!=Teuchos::null);
00182 TEUCHOS_ASSERT(firstBuildComplete_==true);
00183 }
00184
00185 void InverseFactoryOperator::rebuildInverseOperator(const Teuchos::RCP<Epetra_Operator> & A)
00186 {
00187 setConstFwdOp_ = false;
00188
00189 fwdOp_.initialize(A);
00190
00191
00192 rebuildInverseOperator(A.getConst());
00193
00194 TEUCHOS_ASSERT(setConstFwdOp_==true);
00195 }
00196
00197 Teuchos::RCP<const Thyra::LinearOpBase<double> > InverseFactoryOperator::extractLinearOp(const Teuchos::RCP<const Epetra_Operator> & A) const
00198 {
00199
00200 const RCP<const EpetraOperatorWrapper> & eow = rcp_dynamic_cast<const EpetraOperatorWrapper>(A);
00201
00202
00203 if(eow!=Teuchos::null)
00204 return eow->getThyraOp();
00205
00206
00207 return Thyra::epetraLinearOp(A);
00208 }
00209
00210 Teuchos::RCP<const MappingStrategy> InverseFactoryOperator::extractMappingStrategy(const Teuchos::RCP<const Epetra_Operator> & A) const
00211 {
00212
00213 const RCP<const EpetraOperatorWrapper> & eow = rcp_dynamic_cast<const EpetraOperatorWrapper>(A);
00214
00215
00216 if(eow!=Teuchos::null)
00217 return eow->getMapStrategy();
00218
00219
00220 RCP<const Epetra_Map> range = rcpFromRef(A->OperatorRangeMap());
00221 RCP<const Epetra_Map> domain = rcpFromRef(A->OperatorDomainMap());
00222 return rcp(new BasicMappingStrategy(range,domain,A->Comm()));
00223 }
00224
00225 }
00226 }