TSFKrylovSolver.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 /* ***********************************************************************
00003 // 
00004 //           TSFExtended: Trilinos Solver Framework Extended
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 #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 

Site Contact