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 #ifndef __Teko_NeumannSeriesPreconditionerFactory_hpp__
00048 #define __Teko_NeumannSeriesPreconditionerFactory_hpp__
00049
00050 #include "Teko_NeumannSeriesPreconditionerFactoryDecl.hpp"
00051
00052 #include "Thyra_DefaultPreconditioner.hpp"
00053 #include "Thyra_DefaultPreconditioner.hpp"
00054 #include "Thyra_DefaultScaledAdjointLinearOp.hpp"
00055 #include "Thyra_DefaultAddedLinearOp.hpp"
00056 #include "Thyra_DefaultMultipliedLinearOp.hpp"
00057 #include "Thyra_DefaultIdentityLinearOp.hpp"
00058
00059 #include "Teuchos_Array.hpp"
00060 #include "Teuchos_StandardParameterEntryValidators.hpp"
00061
00062 namespace Teko {
00063
00064 using Teuchos::RCP;
00065 using Teuchos::rcp;
00066
00067 static RCP<Teuchos::StringToIntegralParameterEntryValidator<Teko::DiagonalType> > scalingTypeVdtor;
00068
00069 template <typename ScalarT>
00070 NeumannSeriesPreconditionerFactory<ScalarT>::NeumannSeriesPreconditionerFactory()
00071 : numberOfTerms_(1), scalingType_(Teko::NotDiag)
00072 {
00073 }
00074
00076 template <typename ScalarT>
00077 bool NeumannSeriesPreconditionerFactory<ScalarT>::isCompatible(const Thyra::LinearOpSourceBase<ScalarT> &fwdOpSrc) const
00078 {
00079 return true;
00080 }
00081
00083 template <typename ScalarT>
00084 RCP<Thyra::PreconditionerBase<ScalarT> > NeumannSeriesPreconditionerFactory<ScalarT>::createPrec() const
00085 {
00086 return rcp(new Thyra::DefaultPreconditioner<ScalarT>());
00087 }
00088
00097 template <typename ScalarT>
00098 void NeumannSeriesPreconditionerFactory<ScalarT>::initializePrec(const RCP<const Thyra::LinearOpSourceBase<ScalarT> > & fwdOpSrc,
00099 Thyra::PreconditionerBase<ScalarT> * prec,
00100 const Thyra::ESupportSolveUse supportSolveUse) const
00101 {
00102 using Thyra::scale;
00103 using Thyra::add;
00104 using Thyra::multiply;
00105
00106 RCP<const Thyra::LinearOpBase<ScalarT> > M;
00107 RCP<const Thyra::LinearOpBase<ScalarT> > A = fwdOpSrc->getOp();
00108 if(scalingType_!=Teko::NotDiag) {
00109 M = Teko::getInvDiagonalOp(A,scalingType_);
00110 A = Thyra::multiply(M,A);
00111 }
00112
00113 RCP<const Thyra::LinearOpBase<ScalarT> > id = Thyra::identity<ScalarT>(A->range());
00114 RCP<const Thyra::LinearOpBase<ScalarT> > idMA = add(id,scale(-1.0,A));
00115
00116
00117 RCP<const Thyra::LinearOpBase<ScalarT> > precOp;
00118 if(numberOfTerms_==1) {
00119
00120 precOp = id;
00121 }
00122 else {
00123 int iters = numberOfTerms_-1;
00124
00125 precOp = add(scale(2.0,id),scale(-1.0,A));
00126 for(int i=0;i<iters;i++)
00127 precOp = add(id,multiply(idMA,precOp));
00128 }
00129
00130
00131 if(M!=Teuchos::null)
00132 precOp = Thyra::multiply(precOp,M);
00133
00134
00135 Thyra::DefaultPreconditioner<ScalarT> & dPrec = Teuchos::dyn_cast<Thyra::DefaultPreconditioner<ScalarT> >(*prec);
00136
00137
00138 dPrec.initializeUnspecified(Teuchos::rcp_const_cast<Thyra::LinearOpBase<ScalarT> >(precOp));
00139 }
00140
00142 template <typename ScalarT>
00143 void NeumannSeriesPreconditionerFactory<ScalarT>::uninitializePrec(Thyra::PreconditionerBase<ScalarT> * prec,
00144 RCP<const Thyra::LinearOpSourceBase<ScalarT> > * fwdOpSrc,
00145 Thyra::ESupportSolveUse *supportSolveUse) const
00146 {
00147 Thyra::DefaultPreconditioner<ScalarT> & dPrec = Teuchos::dyn_cast<Thyra::DefaultPreconditioner<ScalarT> >(*prec);
00148
00149
00150 dPrec.uninitialize();
00151 }
00152
00153
00154
00156 template <typename ScalarT>
00157 void NeumannSeriesPreconditionerFactory<ScalarT>::setParameterList(const RCP<Teuchos::ParameterList> & paramList)
00158 {
00159 TEUCHOS_TEST_FOR_EXCEPT(paramList==Teuchos::null);
00160
00161
00162 paramList->validateParametersAndSetDefaults(*getValidParameters(),0);
00163
00164
00165 paramList_ = paramList;
00166
00167 numberOfTerms_ = paramList_->get<int>("Number of Terms");
00168
00169
00170 scalingType_ = Teko::NotDiag;
00171 const Teuchos::ParameterEntry * entry = paramList_->getEntryPtr("Scaling Type");
00172 if(entry!=NULL)
00173 scalingType_ = scalingTypeVdtor->getIntegralValue(*entry);
00174 }
00175
00177 template <typename ScalarT>
00178 RCP<const Teuchos::ParameterList> NeumannSeriesPreconditionerFactory<ScalarT>::getValidParameters() const
00179 {
00180 static RCP<Teuchos::ParameterList> validPL;
00181
00182
00183 if(validPL==Teuchos::null) {
00184 RCP<Teuchos::ParameterList> pl = rcp(new Teuchos::ParameterList());
00185
00186
00187 scalingTypeVdtor = Teuchos::stringToIntegralParameterEntryValidator<DiagonalType>(
00188 Teuchos::tuple<std::string>("Diagonal","Lumped","AbsRowSum","None"),
00189 Teuchos::tuple<Teko::DiagonalType>(Teko::Diagonal,Teko::Lumped,Teko::AbsRowSum,Teko::NotDiag),
00190 "Scaling Type");
00191
00192 pl->set<int>("Number of Terms",1,
00193 "The number of terms to use in the Neumann series expansion.");
00194 pl->set("Scaling Type","None","The number of terms to use in the Neumann series expansion.",
00195 scalingTypeVdtor);
00196
00197 validPL = pl;
00198 }
00199
00200 return validPL;
00201 }
00202
00204 template <typename ScalarT>
00205 RCP<Teuchos::ParameterList> NeumannSeriesPreconditionerFactory<ScalarT>::unsetParameterList()
00206 {
00207 Teuchos::RCP<Teuchos::ParameterList> oldList = paramList_;
00208 paramList_ = Teuchos::null;
00209 return oldList;
00210 }
00211
00213 template <typename ScalarT>
00214 RCP<const Teuchos::ParameterList> NeumannSeriesPreconditionerFactory<ScalarT>::getParameterList() const
00215 {
00216 return paramList_;
00217 }
00218
00220 template <typename ScalarT>
00221 RCP<Teuchos::ParameterList> NeumannSeriesPreconditionerFactory<ScalarT>::getNonconstParameterList()
00222 {
00223 return paramList_;
00224 }
00225
00226 template <typename ScalarT>
00227 std::string NeumannSeriesPreconditionerFactory<ScalarT>::description() const
00228 {
00229 std::ostringstream oss;
00230 oss << "Teko::NeumannSeriesPreconditionerFactory";
00231 return oss.str();
00232 }
00233
00234 }
00235
00236 #endif