00001 #ifdef CH_LANG_CC
00002
00003
00004
00005
00006
00007
00008
00009 #endif
00010
00011
00012
00013 #ifndef _RELAXSOLVER_H_
00014 #define _RELAXSOLVER_H_
00015
00016 #include "LinearSolver.H"
00017 #include "parstream.H"
00018 #include "CH_Timer.H"
00019 #include "NamespaceHeader.H"
00020
00022
00026 template <class T>
00027 class RelaxSolver : public LinearSolver<T>
00028 {
00029 public:
00030 RelaxSolver();
00031 virtual ~RelaxSolver();
00032
00034
00037 virtual void setHomogeneous(bool a_homogeneous)
00038 {m_homogeneous = a_homogeneous;}
00039
00041
00044 virtual void define(LinearOp<T>* a_op, bool a_homogeneous);
00045
00047
00050 virtual void solve(T& a_phi, const T& a_rhs);
00051
00053
00056 bool m_homogeneous;
00057
00059
00062 LinearOp<T>* m_op;
00063
00065
00068 int m_imax;
00069
00071
00074 int m_verbosity;
00075
00077
00080 Real m_eps;
00081
00082 };
00083
00084
00085
00086
00087
00088 template <class T>
00089 RelaxSolver<T>::RelaxSolver()
00090 :m_homogeneous(false), m_op(NULL), m_imax(40), m_verbosity(0), m_eps(1.0E-6) {;}
00091
00092 template <class T>
00093 RelaxSolver<T>::~RelaxSolver(){;}
00094
00095 template <class T>
00096 void RelaxSolver<T>::define(LinearOp<T>* a_operator, bool a_homogeneous)
00097 {
00098 m_homogeneous = a_homogeneous;
00099 m_op = a_operator;
00100 }
00101
00102 template <class T>
00103 void RelaxSolver<T>::solve(T& a_phi, const T& a_rhs)
00104 {
00105 CH_assert(m_op != NULL);
00106 CH_TIME("RelaxSolver::solve");
00107 T r, e;
00108
00109 m_op->create(r, a_rhs);
00110 m_op->create(e, a_phi);
00111
00112
00113
00114 m_op->residual(r, a_phi, a_rhs, m_homogeneous);
00115
00116 Real norm = m_op->norm(r, 2);
00117 Real initialNorm = norm;
00118 int iter =0;
00119 while(iter < m_imax){
00120 m_op->setToZero(e);
00121 m_op->preCond(e, r);
00122 m_op->incr(a_phi, e, 1.0);
00123 m_op->residual(r, a_phi, a_rhs, m_homogeneous);
00124 norm = m_op->norm(r, 2);
00125 if(m_verbosity > 3)
00126 {
00127 pout() << "iter# " << iter << " L2 Norm of resid: " << norm << endl;
00128 }
00129 iter++;
00130 if(norm < m_eps*initialNorm) break;
00131 }
00132
00133 m_op->clear(r);
00134 m_op->clear(e);
00135 }
00136
00137 #include "NamespaceFooter.H"
00138 #endif