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 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
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
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
00094 Vector<Scalar> x0 = b.copy();
00095 Vector<Scalar> r0 = b.space().createMember();
00096 Vector<Scalar> tmp = b.space().createMember();
00097
00098
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
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
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
00141
00142 rMid = r0 - a0*ap;
00143
00144
00145
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
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
00169
00170 r = rMid - w*ArMid;
00171
00172
00173
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
00193
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