8#include <dune/fem/solver/parameter.hh>
17 template <
class Operator,
class Precoditioner,
class DiscreteFunction>
18 inline int cg( Operator &op,
19 Precoditioner* preconditioner,
20 std::vector< DiscreteFunction >& tempMem,
22 const DiscreteFunction& b,
24 const int maxIterations,
25 const int toleranceCriteria,
26 std::ostream* os =
nullptr )
28 typedef typename DiscreteFunction::RangeFieldType RangeFieldType;
29 typedef typename Dune::FieldTraits< RangeFieldType >::real_type RealType;
31 assert( preconditioner ? tempMem.size() == 5 : tempMem.size() == 3 );
33 DiscreteFunction& h = tempMem[ 0 ];
39 DiscreteFunction& r = tempMem[ 1 ];
44 DiscreteFunction& p = tempMem[ 2 ];
48 DiscreteFunction& s = ( preconditioner ) ? tempMem[ 3 ] : p;
51 DiscreteFunction& q = ( preconditioner ) ? tempMem[ 4 ] : p;
54 (*preconditioner)( p, q );
58 RangeFieldType prevResiduum = 0;
59 RangeFieldType residuum = p.scalarProductDofs( q );
61 const RealType tolerance = epsilon * epsilon * (
62 toleranceCriteria == ToleranceCriteria::relative ? b.normSquaredDofs( ) :
63 toleranceCriteria == ToleranceCriteria::residualReduction ? std::real(residuum) :
69 for( iterations = 0; (std::real(residuum) > tolerance) && (iterations < maxIterations); ++iterations )
73 assert( residuum/prevResiduum == residuum/prevResiduum );
74 const RangeFieldType beta= residuum / prevResiduum;
88 RangeFieldType qdoth = q.scalarProductDofs( h );
89 const RangeFieldType alpha = residuum / qdoth;
90 assert( !std::isnan( alpha ) );
96 (*preconditioner)( p, s);
98 prevResiduum = residuum;
99 residuum = p.scalarProductDofs( s );
105 prevResiduum = residuum;
106 residuum = r.normSquaredDofs( );
111 (*os) <<
"Fem::CG it: " << iterations <<
" : sqr(residuum) " << residuum << std::endl;
115 return (iterations < maxIterations) ? iterations : -iterations;
Type traits to determine the type of reals (when working with complex numbers)
Dune namespace.
Definition: alignedallocator.hh:13