Reference documentation for deal.II version 8.4.2
solver_bicgstab.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 1998 - 2015 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii__solver_bicgstab_h
17 #define dealii__solver_bicgstab_h
18 
19 
20 #include <deal.II/base/config.h>
21 #include <deal.II/base/logstream.h>
22 #include <deal.II/lac/solver.h>
23 #include <deal.II/lac/solver_control.h>
24 #include <cmath>
25 #include <deal.II/base/subscriptor.h>
26 
27 DEAL_II_NAMESPACE_OPEN
28 
31 
71 template <typename VectorType = Vector<double> >
72 class SolverBicgstab : public Solver<VectorType>
73 {
74 public:
86  {
93  explicit
94  AdditionalData(const bool exact_residual = true,
95  const double breakdown = 1.e-10)
98  {}
106  double breakdown;
107  };
108 
114  const AdditionalData &data=AdditionalData());
115 
121  const AdditionalData &data=AdditionalData());
122 
126  virtual ~SolverBicgstab ();
127 
131  template<typename MatrixType, typename PreconditionerType>
132  void
133  solve (const MatrixType &A,
134  VectorType &x,
135  const VectorType &b,
136  const PreconditionerType &precondition);
137 
138 protected:
142  template <typename MatrixType>
143  double criterion (const MatrixType &A, const VectorType &x, const VectorType &b);
144 
150  virtual void print_vectors(const unsigned int step,
151  const VectorType &x,
152  const VectorType &r,
153  const VectorType &d) const;
154 
158  VectorType *Vx;
162  VectorType *Vr;
166  VectorType *Vrbar;
170  VectorType *Vp;
174  VectorType *Vy;
178  VectorType *Vz;
182  VectorType *Vt;
186  VectorType *Vv;
190  const VectorType *Vb;
191 
195  double alpha;
199  double beta;
203  double omega;
207  double rho;
211  double rhobar;
212 
216  unsigned int step;
217 
221  double res;
222 
227 
228 private:
232  template <typename MatrixType>
233  SolverControl::State start(const MatrixType &A);
234 
240  {
241  bool breakdown;
242  SolverControl::State state;
243  unsigned int last_step;
244  double last_residual;
245 
246  IterationResult (const bool breakdown,
247  const SolverControl::State state,
248  const unsigned int last_step,
249  const double last_residual);
250  };
251 
256  template<typename MatrixType, typename PreconditionerType>
258  iterate(const MatrixType &A,
259  const PreconditionerType &precondition);
260 };
261 
263 /*-------------------------Inline functions -------------------------------*/
264 
265 #ifndef DOXYGEN
266 
267 
268 template<typename VectorType>
270 (const bool breakdown,
271  const SolverControl::State state,
272  const unsigned int last_step,
273  const double last_residual)
274  :
275  breakdown (breakdown),
276  state (state),
277  last_step (last_step),
278  last_residual (last_residual)
279 {}
280 
281 
282 template<typename VectorType>
285  const AdditionalData &data)
286  :
287  Solver<VectorType>(cn,mem),
288  additional_data(data)
289 {}
290 
291 
292 
293 template<typename VectorType>
295  const AdditionalData &data)
296  :
297  Solver<VectorType>(cn),
298  additional_data(data)
299 {}
300 
301 
302 
303 template<typename VectorType>
305 {}
306 
307 
308 
309 template <typename VectorType>
310 template <typename MatrixType>
311 double
312 SolverBicgstab<VectorType>::criterion (const MatrixType &A,
313  const VectorType &x,
314  const VectorType &b)
315 {
316  A.vmult(*Vt, x);
317  Vt->add(-1.,b);
318  res = Vt->l2_norm();
319 
320  return res;
321 }
322 
323 
324 
325 template <typename VectorType >
326 template <typename MatrixType>
328 SolverBicgstab<VectorType>::start (const MatrixType &A)
329 {
330  A.vmult(*Vr, *Vx);
331  Vr->sadd(-1.,1.,*Vb);
332  res = Vr->l2_norm();
333 
334  return this->iteration_status(step, res, *Vx);
335 }
336 
337 
338 
339 template<typename VectorType>
340 void
342  const VectorType &,
343  const VectorType &,
344  const VectorType &) const
345 {}
346 
347 
348 
349 template<typename VectorType>
350 template<typename MatrixType, typename PreconditionerType>
352 SolverBicgstab<VectorType>::iterate(const MatrixType &A,
353  const PreconditionerType &precondition)
354 {
355 //TODO:[GK] Implement "use the length of the computed orthogonal residual" in the BiCGStab method.
357  alpha = omega = rho = 1.;
358 
359  VectorType &r = *Vr;
360  VectorType &rbar = *Vrbar;
361  VectorType &p = *Vp;
362  VectorType &y = *Vy;
363  VectorType &z = *Vz;
364  VectorType &t = *Vt;
365  VectorType &v = *Vv;
366 
367  rbar = r;
368  bool startup = true;
369 
370  do
371  {
372  ++step;
373 
374  rhobar = r*rbar;
375  beta = rhobar * alpha / (rho * omega);
376  rho = rhobar;
377  if (startup == true)
378  {
379  p = r;
380  startup = false;
381  }
382  else
383  {
384  p.sadd(beta, 1., r);
385  p.add(-beta*omega, v);
386  }
387 
388  precondition.vmult(y,p);
389  A.vmult(v,y);
390  rhobar = rbar * v;
391 
392  alpha = rho/rhobar;
393 
394 //TODO:[?] Find better breakdown criterion
395 
396  if (std::fabs(alpha) > 1.e10)
397  return IterationResult(true, state, step, res);
398 
399  res = std::sqrt(r.add_and_dot(-alpha, v, r));
400 
401  // check for early success, see the lac/bicgstab_early testcase as to
402  // why this is necessary
403  //
404  // note: the vector *Vx we pass to the iteration_status signal here is only
405  // the current approximation, not the one we will return with,
406  // which will be x=*Vx + alpha*y
408  {
409  Vx->add(alpha, y);
410  print_vectors(step, *Vx, r, y);
412  }
413 
414  precondition.vmult(z,r);
415  A.vmult(t,z);
416  rhobar = t*r;
417  omega = rhobar/(t*t);
418  Vx->add(alpha, y, omega, z);
419 
421  {
422  r.add(-omega, t);
423  res = criterion(A, *Vx, *Vb);
424  }
425  else
426  res = std::sqrt(r.add_and_dot(-omega, t, r));
427 
428  state = this->iteration_status(step, res, *Vx);
429  print_vectors(step, *Vx, r, y);
430  }
431  while (state == SolverControl::iterate);
432  return IterationResult(false, state, step, res);
433 }
434 
435 
436 template<typename VectorType>
437 template<typename MatrixType, typename PreconditionerType>
438 void
439 SolverBicgstab<VectorType>::solve(const MatrixType &A,
440  VectorType &x,
441  const VectorType &b,
442  const PreconditionerType &precondition)
443 {
444  deallog.push("Bicgstab");
445  Vr = this->memory.alloc();
446  Vr->reinit(x, true);
447  Vrbar = this->memory.alloc();
448  Vrbar->reinit(x, true);
449  Vp = this->memory.alloc();
450  Vp->reinit(x, true);
451  Vy = this->memory.alloc();
452  Vy->reinit(x, true);
453  Vz = this->memory.alloc();
454  Vz->reinit(x, true);
455  Vt = this->memory.alloc();
456  Vt->reinit(x, true);
457  Vv = this->memory.alloc();
458  Vv->reinit(x, true);
459 
460  Vx = &x;
461  Vb = &b;
462 
463  step = 0;
464 
465  IterationResult state(false,SolverControl::failure,0,0);
466 
467  // iterate while the inner iteration returns a breakdown
468  do
469  {
470  if (step != 0)
471  deallog << "Restart step " << step << std::endl;
472  if (start(A) == SolverControl::success)
473  {
474  state.state = SolverControl::success;
475  break;
476  }
477  state = iterate(A, precondition);
478  }
479  while (state.breakdown == true);
480 
481  this->memory.free(Vr);
482  this->memory.free(Vrbar);
483  this->memory.free(Vp);
484  this->memory.free(Vy);
485  this->memory.free(Vz);
486  this->memory.free(Vt);
487  this->memory.free(Vv);
488 
489  deallog.pop();
490 
491  // in case of failure: throw exception
492  AssertThrow(state.state == SolverControl::success,
493  SolverControl::NoConvergence (state.last_step,
494  state.last_residual));
495  // otherwise exit as normal
496 }
497 
498 #endif // DOXYGEN
499 
500 DEAL_II_NAMESPACE_CLOSE
501 
502 #endif
Stop iteration, goal not reached.
SolverBicgstab(SolverControl &cn, VectorMemory< VectorType > &mem, const AdditionalData &data=AdditionalData())
VectorType * Vp
void pop()
Definition: logstream.cc:300
IterationResult iterate(const MatrixType &A, const PreconditionerType &precondition)
Continue iteration.
#define AssertThrow(cond, exc)
Definition: exceptions.h:358
virtual ~SolverBicgstab()
void solve(const MatrixType &A, VectorType &x, const VectorType &b, const PreconditionerType &precondition)
unsigned int step
Stop iteration, goal reached.
AdditionalData additional_data
VectorType * Vv
VectorType * Vz
VectorMemory< VectorType > & memory
Definition: solver.h:402
boost::signals2::signal< SolverControl::State(const unsigned int iteration, const double check_value, const VectorType &current_iterate), StateCombiner > iteration_status
Definition: solver.h:448
AdditionalData(const bool exact_residual=true, const double breakdown=1.e-10)
Definition: solver.h:325
const VectorType * Vb
void push(const std::string &text)
Definition: logstream.cc:288
virtual void print_vectors(const unsigned int step, const VectorType &x, const VectorType &r, const VectorType &d) const
VectorType * Vr
SolverControl::State start(const MatrixType &A)
VectorType * Vx
VectorType * Vt
VectorType * Vrbar
VectorType * Vy
double criterion(const MatrixType &A, const VectorType &x, const VectorType &b)