Go to the documentation of this file.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 #ifndef TSFKRYLOVSOLVER_HPP
00030 #define TSFKRYLOVSOLVER_HPP
00031
00032 #include "SundanceDefs.hpp"
00033 #include "TSFIterativeSolver.hpp"
00034 #include "TSFPreconditionerFactory.hpp"
00035 #include "TSFILUKPreconditionerFactory.hpp"
00036
00037 namespace TSFExtended
00038 {
00039 using namespace Teuchos;
00040
00041
00042
00043
00044 template <class Scalar>
00045 class KrylovSolver : public IterativeSolver<Scalar>
00046 {
00047 public:
00048
00049 KrylovSolver(const ParameterList& params);
00050
00051 KrylovSolver(const ParameterList& params,
00052 const PreconditionerFactory<Scalar>& precond);
00053
00054
00055 virtual ~KrylovSolver(){;}
00056
00057
00058 virtual SolverState<Scalar> solve(const LinearOperator<Scalar>& op,
00059 const Vector<Scalar>& rhs,
00060 Vector<Scalar>& soln) const ;
00061 protected:
00062 virtual SolverState<Scalar> solveUnprec(const LinearOperator<Scalar>& op,
00063 const Vector<Scalar>& rhs,
00064 Vector<Scalar>& soln) const = 0 ;
00065
00066 const PreconditionerFactory<Scalar>& precond() const {return precond_;}
00067
00068 private:
00069 PreconditionerFactory<Scalar> precond_;
00070 };
00071
00072
00073 template <class Scalar> inline
00074 KrylovSolver<Scalar>::KrylovSolver(const ParameterList& params)
00075 : IterativeSolver<Scalar>(params), precond_()
00076 {
00077 if (!params.isParameter("Precond")) return;
00078
00079 const std::string& precondType = params.template get<string>("Precond");
00080
00081 if (precondType=="ILUK")
00082 {
00083 precond_ = new ILUKPreconditionerFactory<Scalar>(params);
00084 }
00085 }
00086
00087 template <class Scalar> inline
00088 KrylovSolver<Scalar>::KrylovSolver(const ParameterList& params,
00089 const PreconditionerFactory<Scalar>& precond)
00090 : IterativeSolver<Scalar>(params), precond_(precond)
00091 {
00092 TEST_FOR_EXCEPTION(params.isParameter("Precond"), std::runtime_error,
00093 "ambiguous preconditioner specification in "
00094 "KrylovSolver ctor: parameters specify "
00095 << params.template get<string>("Precond")
00096 << " but preconditioner argument is "
00097 << precond);
00098 }
00099
00100 template <class Scalar> inline
00101 SolverState<Scalar> KrylovSolver<Scalar>
00102 ::solve(const LinearOperator<Scalar>& op,
00103 const Vector<Scalar>& rhs,
00104 Vector<Scalar>& soln) const
00105 {
00106 if (precond_.ptr().get()==0)
00107 {
00108 return solveUnprec(op, rhs, soln);
00109 }
00110
00111
00112 Preconditioner<Scalar> p = precond_.createPreconditioner(op);
00113
00114 if (!p.hasRight())
00115 {
00116 LinearOperator<Scalar> A = p.left()*op;
00117 Vector<Scalar> newRHS = rhs.space().createMember();
00118 p.left().apply(rhs, newRHS);
00119 return solveUnprec(A, newRHS, soln);
00120 }
00121 else if (!p.hasLeft())
00122 {
00123 LinearOperator<Scalar> A = op * p.right();
00124 Vector<Scalar> intermediateSoln;
00125 SolverState<Scalar> rtn
00126 = solveUnprec(A, rhs, intermediateSoln);
00127 if (rtn.finalState()==SolveConverged)
00128 {
00129 p.right().apply(intermediateSoln, soln);
00130 }
00131 return rtn;
00132 }
00133 else
00134 {
00135 LinearOperator<Scalar> A = p.left() * op * p.right();
00136 Vector<Scalar> newRHS;
00137 p.left().apply(rhs, newRHS);
00138 Vector<Scalar> intermediateSoln;
00139 SolverState<Scalar> rtn
00140 = solveUnprec(A, newRHS, intermediateSoln);
00141 if (rtn.finalState()==SolveConverged)
00142 {
00143 p.right().apply(intermediateSoln, soln);
00144 }
00145 return rtn;
00146 }
00147 }
00148
00149 }
00150
00151 #endif
00152