TSFBICGSTABSolverImpl.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 TSFBICGSTABSOLVER_IMPL_HPP
00030 #define TSFBICGSTABSOLVER_IMPL_HPP
00031 
00032 #include "TSFBICGSTABSolverDecl.hpp"
00033 #include "TSFLinearCombinationImpl.hpp"
00034 #include "TSFSimpleScaledOpDecl.hpp"
00035 #include "TSFSimpleComposedOpDecl.hpp"
00036 
00037 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00038 #include "TSFLinearOperatorImpl.hpp"
00039 #include "TSFLinearSolverBaseImpl.hpp"
00040 #include "TSFSimpleScaledOpImpl.hpp"
00041 #include "TSFSimpleComposedOpImpl.hpp"
00042 #endif
00043 
00044 
00045 
00046 namespace TSFExtended
00047 {
00048 using namespace Teuchos;
00049 using namespace Sundance;
00050 
00051 /* */
00052 template <class Scalar> inline
00053 BICGSTABSolver<Scalar>
00054 ::BICGSTABSolver(const ParameterList& params)
00055   : KrylovSolver<Scalar>(params) {;}
00056 
00057 /* */
00058 template <class Scalar> inline
00059 BICGSTABSolver<Scalar>::BICGSTABSolver(const ParameterList& params,
00060   const PreconditionerFactory<Scalar>& precond)
00061   : KrylovSolver<Scalar>(params, precond) {;}
00062 
00063 /* Write to a stream  */
00064 template <class Scalar> inline
00065 void BICGSTABSolver<Scalar>::print(std::ostream& os) const 
00066 {
00067   os << description() << "[" << std::endl;
00068   os << this->parameters() << std::endl;
00069   os << "]" << std::endl;
00070 }
00071 
00072     
00073 template <class Scalar> inline
00074 SolverState<Scalar> BICGSTABSolver<Scalar>
00075 ::solveUnprec(const LinearOperator<Scalar>& op,
00076   const Vector<Scalar>& b,
00077   Vector<Scalar>& soln) const
00078 {
00079   int maxiters = this->getMaxiters();
00080   Scalar tol = this->getTol();
00081   int verbosity = this->verb();
00082 
00083   Scalar normOfB = sqrt(b.dot(b));
00084 
00085   /* check for trivial case of zero rhs */
00086   if (normOfB < tol) 
00087   {
00088     soln = b.space().createMember();
00089     soln.zero();
00090     return SolverState<Scalar>(SolveConverged, "RHS was zero", 0, 0.0);
00091   }
00092 
00093   /* check for initial zero residual */
00094   Vector<Scalar> x0 = b.copy();
00095   Vector<Scalar> r0 = b.space().createMember();
00096   Vector<Scalar> tmp = b.space().createMember();
00097 
00098   // r0 =  b - op*x0;
00099   op.apply(x0, tmp);
00100   r0 = b - tmp;
00101   
00102   if (sqrt(r0.dot(r0)) < tol*normOfB) 
00103   {
00104     soln = x0;
00105     return SolverState<Scalar>(SolveConverged, "initial resid was zero", 
00106       0, 0.0);
00107   }
00108 
00109   Vector<Scalar> p0 = r0.copy();
00110   //    p0.randomize();
00111   Vector<Scalar> r0Hat = r0.copy();
00112   Vector<Scalar> xMid = b.space().createMember();
00113   Vector<Scalar> rMid = b.space().createMember();
00114   Vector<Scalar> ArMid = b.space().createMember();
00115   Vector<Scalar> x = b.space().createMember();
00116   Vector<Scalar> r = b.space().createMember();
00117   Vector<Scalar> s = b.space().createMember();
00118   Vector<Scalar> ap = b.space().createMember();
00119 
00120   int myRank = MPIComm::world().getRank();
00121 
00122   Scalar resid = -1.0;
00123 
00124   for (int k=1; k<=maxiters; k++)
00125   {
00126     // ap = A*p0
00127     op.apply(p0, ap);
00128 
00129     Scalar den = ap.dot(r0Hat);
00130     if (Utils::chop(sqrt(fabs(den))/normOfB)==0) 
00131     {
00132       SolverState<Scalar> rtn(SolveCrashed, 
00133         "BICGSTAB failure mode 1", k, resid);
00134       return rtn;
00135     }
00136       
00137     Scalar a0 = r0.dot(r0Hat)/den;
00138       
00139     xMid = x0 + a0*p0;
00140     //xMid.axpy(a0, p0, x0);
00141 
00142     rMid = r0 - a0*ap;
00143     //rMid.axpy(-a0, ap, r0);
00144 
00145     // check for convergence
00146     Scalar resid = rMid.norm2()/normOfB;
00147     if (resid < tol) 
00148     {
00149       soln = xMid; 
00150       SolverState<Scalar> rtn(SolveConverged, "yippee!!", k, resid);
00151       return rtn;
00152     }
00153 
00154     // ArMid = A*rMid
00155     op.apply(rMid, ArMid);
00156 
00157     den = ArMid.dot(ArMid);
00158     if (Utils::chop(sqrt(fabs(den))/normOfB)==0)  
00159     {
00160       SolverState<Scalar> rtn(SolveCrashed, 
00161         "BICGSTAB failure mode 2", k, resid);
00162       return rtn;
00163     }
00164 
00165     Scalar w = rMid.dot(ArMid)/den;
00166       
00167     x = xMid + w*rMid;
00168     //x.axpy(w, rMid, xMid);
00169       
00170     r = rMid - w*ArMid;
00171     //r.axpy(-w, ArMid, rMid);
00172 
00173     // check for convergence
00174     resid = sqrt(r.dot(r))/normOfB;
00175     if (resid < tol) 
00176     {
00177       soln = x;
00178       SolverState<Scalar> rtn(SolveConverged, "yippee!!", k, resid);
00179       return rtn;
00180     }
00181 
00182     den = w*(r0.dot(r0Hat));
00183     if (Utils::chop(sqrt(fabs(den))/normOfB)==0) 
00184     {
00185       SolverState<Scalar> rtn(SolveCrashed, 
00186         "BICGSTAB failure mode 3", k, resid);
00187       return rtn;
00188     }
00189     Scalar beta = a0*(r.dot(r0Hat))/den;
00190 
00191     p0 = r + beta*p0 - beta*w*ap;
00192     //s.axpy(-w, ap, p0);
00193     //p0.axpy(beta, s, r);
00194 
00195     r0 = r.copy();
00196     x0 = x.copy();
00197 
00198     if (myRank==0 && verbosity > 1 ) 
00199     {
00200       Out::os() << "BICGSTAB: iteration=";
00201       Out::os().width(8);
00202       Out::os() << k;
00203       Out::os().width(20);
00204       Out::os() << " resid=" << resid << std::endl;
00205     }
00206   }
00207     
00208   SolverState<Scalar> rtn(SolveFailedToConverge, 
00209     "BICGSTAB failed to converge", 
00210     maxiters, resid);
00211   return rtn;
00212 }
00213 
00214 
00215 }
00216 
00217 #endif

Site Contact