BISICLES AMR ice sheet model  0.9
CGSolver.H
Go to the documentation of this file.
1 #ifdef CH_LANG_CC
2 /*
3 * _______ __
4 * / ___/ / ___ __ _ / / ___
5 * / /__/ _ \/ _ \/ V \/ _ \/ _ \
6 * \___/_//_/\___/_/_/_/_.__/\___/
7 * Please refer to Copyright.txt, in Chombo's root directory.
8 */
9 #endif
10 
11 // SLC, Oct 12, 2011
12 
13 #ifndef _CGSOLVER_H_
14 #define _CGSOLVER_H_
15 
16 #include "LinearSolver.H"
17 #include "parstream.H"
18 #include "CH_Timer.H"
19 #include "NamespaceHeader.H"
20 
22 
25 template <class T>
26 class CGSolver : public LinearSolver<T>
27 {
28 public:
29 
30  CGSolver();
31 
32  virtual ~CGSolver();
33 
34  virtual void setHomogeneous(bool a_homogeneous)
35  {m_homogeneous = a_homogeneous;}
36 
38 
43  virtual void define(LinearOp<T>* a_op, bool a_homogeneous);
44 
46  virtual void solve(T& a_phi, const T& a_rhs);
47 
49  virtual void setConvergenceMetrics(Real a_metric,
50  Real a_tolerance);
51 
53 
58 
60 
63  LinearOp<T>* m_op;
64 
66 
69  int m_imax;
70 
72 
77 
79 
82  Real m_eps;
83 
85 
88  Real m_reps;
89 
91 
96 
98 
101  Real m_hang;
102 
104 
112 
114 
117  Real m_small;
118 
120 
124 
126 
131 
132 };
133 
134 // *******************************************************
135 // CGSolver Implementation
136 // *******************************************************
137 
138 template <class T>
140  :m_homogeneous(false), m_op(NULL), m_imax(80), m_verbosity(3), m_eps(1.0E-6),
141  m_reps(1.0E-12), m_convergenceMetric(-1.0), m_hang(1E-8), m_exitStatus(-1),
142  m_small(1.0E-30), m_numRestarts(5), m_normType(2){;}
143 
144 template <class T>
146 {
147  m_op = NULL;
148 }
149 
150 template <class T>
151 void CGSolver<T>::define(LinearOp<T>* a_operator, bool a_homogeneous)
152 {
153  m_homogeneous = a_homogeneous;
154  m_op = a_operator;
155 }
156 
157 template <class T>
158 void CGSolver<T>::solve(T& a_phi, const T& a_rhs)
159 {
160  CH_TIMERS("CGSolver::solve");
161 
162  CH_TIMER("CGSolver::solve::Initialize",timeInitialize);
163  CH_TIMER("CGSolver::solve::MainLoop",timeMainLoop);
164  CH_TIMER("CGSolver::solve::Cleanup",timeCleanup);
165 
166  CH_START(timeInitialize);
167 
168  T r,z,p,Lp;
169 
170  m_op->create(r,a_rhs);
171  m_op->create(z,a_phi);
172  m_op->create(p,a_phi);
173  m_op->create(Lp,a_rhs);
174 
175  CH_assert(m_op != NULL);
176 
177  m_op->residual(r, a_phi, a_rhs, m_homogeneous);
178 
179 
180  Real initial_norm = m_op->norm(r, m_normType);
181  Real norm = initial_norm;
182  if (m_verbosity >= 3)
183  {
184  pout() << " CG:: initial Residual norm = "
185  << initial_norm << "\n";
186  }
187  m_op->setToZero(z);
188  m_op->preCond(z, r);
189  m_op->assign(p,z);
190 
191  // if a convergence metric has been supplied, replace initial residual
192  // with the supplied convergence metric...
193  if (m_convergenceMetric > 0)
194  {
195  initial_norm = m_convergenceMetric;
196  }
197 
198  CH_STOP(timeInitialize);
199 
200  CH_START(timeMainLoop);
201  int iter = 0;
202  while (iter < m_imax )
203  {
204 
205  m_op->applyOp(Lp, p, true);
206  Real rdotz = m_op->dotProduct(r, z);
207  Real alpha = rdotz / m_op->dotProduct(p , Lp);
208  m_op->incr(a_phi, p , alpha);
209  m_op->incr(r, Lp , -alpha);
210  Real norm_old = norm;
211  norm = m_op->norm(r, m_normType);
212  if (m_verbosity >= 3)
213  {
214  pout() << " CG:: iteration = " << iter
215  << ", error norm = " << norm
216  << ", rate = " << norm_old/norm << "\n";
217  }
218 
219 
220  if(norm < m_eps*initial_norm)
221  {
222  break;
223  }
224  if (norm_old < m_hang * norm)
225  {
226  break;
227  }
228 
229  m_op->preCond(z, r);
230  Real beta = m_op->dotProduct(r, z) / rdotz;
231  m_op->scale(p,beta);
232  m_op->incr(p, z , 1.0);
233  iter++;
234  }
235  CH_STOP(timeMainLoop);
236 
237  CH_START(timeCleanup);
238 
239  if (m_verbosity >= 3)
240  {
241  pout() << " CG:: " << iter
242  << " iterations, final Residual norm = "
243  << norm << "\n";
244  }
245 
246 
247 
248  m_op->clear(r);
249  m_op->clear(z);
250  m_op->clear(p);
251  m_op->clear(Lp);
252  CH_STOP(timeCleanup);
253 }
254 
255 template <class T>
257  Real a_tolerance)
258 {
259  m_convergenceMetric = a_metric;
260  m_eps = a_tolerance;
261 }
262 
263 #include "NamespaceFooter.H"
264 #endif /*_CGSOLVER_H_*/
Real m_reps
Definition: CGSolver.H:88
Definition: CGSolver.H:26
Real m_convergenceMetric
Definition: CGSolver.H:95
virtual void solve(T &a_phi, const T &a_rhs)
solve the equation.
Definition: CGSolver.H:158
virtual void setConvergenceMetrics(Real a_metric, Real a_tolerance)
Definition: CGSolver.H:256
bool m_homogeneous
Definition: CGSolver.H:57
int m_normType
Definition: CGSolver.H:130
int m_numRestarts
Definition: CGSolver.H:123
LinearOp< T > * m_op
Definition: CGSolver.H:63
CGSolver()
Definition: CGSolver.H:139
Real m_small
Definition: CGSolver.H:117
Real m_eps
Definition: CGSolver.H:82
int m_verbosity
Definition: CGSolver.H:76
int m_exitStatus
Definition: CGSolver.H:111
virtual ~CGSolver()
Definition: CGSolver.H:145
int m_imax
Definition: CGSolver.H:69
Real m_hang
Definition: CGSolver.H:101
virtual void setHomogeneous(bool a_homogeneous)
Definition: CGSolver.H:34
virtual void define(LinearOp< T > *a_op, bool a_homogeneous)
Definition: CGSolver.H:151