Discontinuous Galerkin Library
#include "dg/algorithm.h"
pcg.h
Go to the documentation of this file.
1#ifndef _DG_PCG_
2#define _DG_PCG_
3
4#include <cmath>
5
6#include "blas.h"
7#include "functors.h"
8#include "extrapolation.h"
9#include "backend/typedefs.h"
10
11#include "backend/timer.h"
12
17namespace dg{
18
20
55template< class ContainerType>
56class PCG
57{
58 public:
59 using container_type = ContainerType;
62 PCG() = default;
69 PCG( const ContainerType& copyable, unsigned max_iterations):
70 r(copyable), p(r), ap(r), max_iter(max_iterations){}
73 void set_max( unsigned new_max) {max_iter = new_max;}
76 unsigned get_max() const {return max_iter;}
79 const ContainerType& copyable()const{ return r;}
80
83 void set_verbose( bool verbose){ m_verbose = verbose;}
87 void set_throw_on_fail( bool throw_on_fail){
88 m_throw_on_fail = throw_on_fail;
89 }
90
92 template<class ...Params>
93 void construct( Params&& ...ps)
94 {
95 //construct and swap
96 *this = PCG( std::forward<Params>( ps)...);
97 }
126 template< class MatrixType0, class ContainerType0, class ContainerType1, class MatrixType1, class ContainerType2 >
127 unsigned solve( MatrixType0&& A, ContainerType0& x, const ContainerType1& b, MatrixType1&& P, const ContainerType2& W, value_type eps = 1e-12, value_type nrmb_correction = 1, int test_frequency = 1);
128 private:
129 ContainerType r, p, ap;
130 unsigned max_iter;
131 bool m_verbose = false, m_throw_on_fail = true;
132};
133
135template< class ContainerType>
136template< class Matrix, class ContainerType0, class ContainerType1, class Preconditioner, class ContainerType2>
137unsigned PCG< ContainerType>::solve( Matrix&& A, ContainerType0& x, const ContainerType1& b, Preconditioner&& P, const ContainerType2& W, value_type eps, value_type nrmb_correction, int save_on_dots )
138{
139 // self-adjoint: apply PCG algorithm to (P 1/W) (W A) x = (P 1/W) (W b) : P' A' x = P' b'
140 // This effectively just replaces all scalar products with the weighted one
141 value_type nrmb = sqrt( blas2::dot( W, b));
142 value_type tol = eps*(nrmb + nrmb_correction);
143#ifdef MPI_VERSION
144 int rank;
145 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
146#endif //MPI
147 if( m_verbose)
148 {
149 DG_RANK0 std::cout << "# Norm of W b "<<nrmb <<"\n";
150 DG_RANK0 std::cout << "# Residual errors: \n";
151 }
152 if( nrmb == 0)
153 {
154 blas1::copy( 0., x);
155 return 0;
156 }
157 blas2::symv( std::forward<Matrix>(A),x,r);
158 blas1::axpby( 1., b, -1., r);
159 if( sqrt( blas2::dot(W,r) ) < tol) //if x happens to be the solution
160 return 0;
161 blas2::symv( std::forward<Preconditioner>(P), r, p );
162 value_type nrmzr_old = blas2::dot( p,W,r); //and store the scalar product
163 value_type alpha, nrmzr_new;
164 for( unsigned i=1; i<max_iter; i++)
165 {
166 blas2::symv( std::forward<Matrix>(A), p, ap);
167 alpha = nrmzr_old/blas2::dot( p, W, ap);
168 blas1::axpby( alpha, p, 1.,x);
169 blas1::axpby( -alpha, ap, 1., r);
170 if( 0 == i%save_on_dots )
171 {
172 if( m_verbose)
173 {
174 DG_RANK0 std::cout << "# Absolute r*W*r "<<sqrt( blas2::dot(W,r)) <<"\t ";
175 DG_RANK0 std::cout << "# < Critical "<<tol <<"\t ";
176 DG_RANK0 std::cout << "# (Relative "<<sqrt( blas2::dot(W,r) )/nrmb << ")\n";
177 }
178 if( sqrt( blas2::dot(W,r)) < tol)
179 return i;
180 }
181 blas2::symv(std::forward<Preconditioner>(P),r,ap);
182 nrmzr_new = blas2::dot( ap, W, r);
183 blas1::axpby(1.,ap, nrmzr_new/nrmzr_old, p );
184 nrmzr_old=nrmzr_new;
185 }
186 if( m_throw_on_fail)
187 {
188 throw dg::Fail( tol, Message(_ping_)
189 <<"After "<<max_iter<<" PCG iterations with rtol "<<eps<<" and atol "<<eps*nrmb_correction );
190 }
191 return max_iter;
192}
194
195} //namespace dg
196
197
198
199#endif //_DG_PCG_
Preconditioned conjugate gradient method to solve .
Definition: pcg.h:57
void set_throw_on_fail(bool throw_on_fail)
Set or unset a throw on failure-to-converge.
Definition: pcg.h:87
PCG()=default
Allocate nothing, Call construct method before usage.
PCG(const ContainerType &copyable, unsigned max_iterations)
Allocate memory for the pcg method.
Definition: pcg.h:69
get_value_type< ContainerType > value_type
Definition: pcg.h:60
void set_verbose(bool verbose)
Set or unset debugging output during iterations.
Definition: pcg.h:83
const ContainerType & copyable() const
Return an object of same size as the object used for construction.
Definition: pcg.h:79
void construct(Params &&...ps)
Perfect forward parameters to one of the constructors.
Definition: pcg.h:93
void set_max(unsigned new_max)
Set the maximum number of iterations.
Definition: pcg.h:73
ContainerType container_type
Definition: pcg.h:59
unsigned get_max() const
Get the current maximum number of iterations.
Definition: pcg.h:76
unsigned solve(MatrixType0 &&A, ContainerType0 &x, const ContainerType1 &b, MatrixType1 &&P, const ContainerType2 &W, value_type eps=1e-12, value_type nrmb_correction=1, int test_frequency=1)
Solve using a preconditioned conjugate gradient method.
#define _ping_
Definition: exceptions.h:12
void copy(const ContainerTypeIn &source, ContainerTypeOut &target)
Definition: blas1.h:164
void axpby(get_value_type< ContainerType > alpha, const ContainerType1 &x, get_value_type< ContainerType > beta, ContainerType &y)
Definition: blas1.h:231
void symv(MatrixType &&M, const ContainerType1 &x, ContainerType2 &y)
Definition: blas2.h:287
get_value_type< MatrixType > dot(const ContainerType1 &x, const MatrixType &m, const ContainerType2 &y)
; Binary reproducible general dot product
Definition: blas2.h:85
typename TensorTraits< std::decay_t< Vector > >::value_type get_value_type
Definition: tensor_traits.h:38
This is the namespace for all functions and classes defined and used by the discontinuous Galerkin li...
Indicate failure to converge.
Definition: exceptions.h:126
Useful typedefs of commonly used types.
#define DG_RANK0
Definition: typedefs.h:147