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
00021
00022
00023
00024
00025
00026 template <class T>
00027 class RelaxSolver : public LinearSolver<T>
00028 {
00029 public:
00030 RelaxSolver();
00031 virtual ~RelaxSolver();
00032
00033
00034
00035
00036
00037 virtual void setHomogeneous(bool a_homogeneous)
00038 {
00039 m_homogeneous = a_homogeneous;
00040 }
00041
00042
00043
00044
00045
00046 virtual void define(LinearOp<T>* a_op, bool a_homogeneous);
00047
00048
00049
00050
00051
00052 virtual void solve(T& a_phi, const T& a_rhs);
00053
00054
00055
00056
00057
00058 bool m_homogeneous;
00059
00060
00061
00062
00063
00064 LinearOp<T>* m_op;
00065
00066
00067
00068
00069
00070 int m_imax;
00071
00072
00073
00074
00075
00076 int m_normType;
00077
00078
00079
00080
00081
00082 int m_verbosity;
00083
00084
00085
00086
00087
00088 Real m_eps;
00089
00090
00091
00092
00093
00094 Real m_hang;
00095 private:
00096 Real m_minNorm;
00097 };
00098
00099
00100
00101
00102
00103 template <class T>
00104 RelaxSolver<T>::RelaxSolver()
00105 :m_homogeneous(false),
00106 m_op(NULL),
00107 m_imax(40),
00108 m_normType(2),
00109 m_verbosity(0),
00110 m_eps(1.0E-6),
00111 m_hang(0.0)
00112 {
00113 }
00114
00115 template <class T>
00116 RelaxSolver<T>::~RelaxSolver()
00117 {
00118 }
00119
00120 template <class T>
00121 void RelaxSolver<T>::define(LinearOp<T>* a_operator, bool a_homogeneous)
00122 {
00123 m_homogeneous = a_homogeneous;
00124 m_op = a_operator;
00125 }
00126
00127 template <class T>
00128 void RelaxSolver<T>::solve(T& a_phi, const T& a_rhs)
00129 {
00130 CH_assert(m_op != NULL);
00131 CH_TIME("RelaxSolver::solve");
00132 T r, e;
00133
00134 m_op->create(r, a_rhs);
00135 m_op->create(e, a_phi);
00136
00137 m_op->setToZero(r);
00138 m_op->residual(r, a_phi, a_rhs, m_homogeneous);
00139
00140 Real norm = m_op->norm(r, m_normType);
00141 m_minNorm = norm;
00142
00143 if (m_verbosity >= 3)
00144 {
00145 pout() << " RelaxSolver:: initial Residual norm = "
00146 << norm << "\n";
00147 }
00148
00149 if (norm > 0.)
00150 {
00151 Real initialNorm = norm;
00152 int iter =0;
00153 while (iter < m_imax)
00154 {
00155 m_op->setToZero(e);
00156 m_op->preCond(e, r);
00157 m_op->incr(a_phi, e, 1.0);
00158 m_op->residual(r, a_phi, a_rhs, m_homogeneous);
00159 Real oldNorm = norm;
00160 norm = m_op->norm(r, m_normType);
00161 iter++;
00162
00163 if (m_verbosity > 3)
00164 {
00165 pout() << " RelaxSolver:: iteration = " << iter
00166 << " residual norm = " << norm
00167 << ", rate = " << oldNorm/norm << endl;
00168 }
00169 if (norm < m_eps*initialNorm) break;
00170
00171 if (norm < m_minNorm)
00172 {
00173 m_minNorm = norm;
00174 }
00175 else if (norm * m_hang > m_minNorm)
00176 {
00177 if (m_verbosity > 3)
00178 {
00179 pout() << " RelaxSolver:: exit due to solver hang " << endl;
00180 }
00181 break;
00182 }
00183 }
00184 }
00185
00186 m_op->clear(r);
00187 m_op->clear(e);
00188 }
00189
00190 #include "NamespaceFooter.H"
00191 #endif