18#include <boost/circular_buffer.hpp>
20#include "dune/common/timer.hh"
21#include "dune/istl/istlexception.hh"
22#include "dune/istl/operators.hh"
23#include "dune/istl/preconditioners.hh"
24#include "dune/istl/scalarproducts.hh"
25#include "dune/istl/solvers.hh"
37 template <
class X,
class Xstar>
41 template <
class Linearization,
class VariableSet>
47 template <
class X,
class Xstar>
53 lin.ddxpy(y,z,0,2,2,3);
57 boost::fusion::at_c<0>(v.
data) += boost::fusion::at_c<0>(y.get().data);
58 boost::fusion::at_c<1>(v.
data) += boost::fusion::at_c<1>(y.get().data);
64 Linearization
const& lin;
78 template<
class X,
class Xstar,
class Regularization=NoRegularization>
79 class TCG :
public Dune::InverseOperator<X,Xstar> {
92 template <class Int=int, class enable = typename std::enable_if<!std::is_same<Regularization,NoRegularization>::value && std::is_same<Int,int>::value>::type>
94 Regularization& regularization_,
double relTol_=1e-3,
size_t maxSteps_=100, Int verbose_=0) :
95 op(op_), prec(prec_), dp(dp_), regularization(regularization_), relTol(relTol_), absTol(1e-9), maxSteps(maxSteps_), verbose(verbose_)
109 template <class Int=int, class enable = typename std::enable_if<std::is_same<Regularization,NoRegularization>::value && std::is_same<Int,int>::value>::type>
111 double relTol_=1e-3,
size_t maxSteps_=100, Int verbose_=0) :
112 op(op_), prec(prec_), dp(dp_), relTol(relTol_), absTol(1e-9), maxSteps(maxSteps_), verbose(verbose_)
127 virtual int apply (
X& u,
X& q, Xstar& b, Dune::InverseOperatorResult& res)
129 result = Result::Failed;
130 int numberOfResults = 1;
138 op.applyscaleadd(-1.0,u,r);
141 X rq(u), du(u); rq = 0;
151 Real alpha,beta,sigma,gamma;
155 double const sigma0 = std::abs(sigma);
158 std::cout <<
"=== Kaskade7 TCG" << std::endl;
160 this->printHeader(std::cout);
161 this->printOutput(std::cout,0,sigma0);
176 result = Result::EncounteredNonConvexity;
177 if(verbose > 0) std::cout <<
"Nonconvexity at iteration " << i <<
", qAq=" << qAq <<
", ||q||=" << sqrt(q*q) << std::endl;
191 if(dp(du,du) < absTol)
193 result = Result::Converged;
199 resDebug.push_back(std::sqrt(sigma));
211 double sigmaNew = dp(rq,r);
214 this->printOutput(std::cout,i,std::abs(sigmaNew),std::abs(sigma));
218 if (std::abs(sigmaNew) < relTol*sigma0)
220 result = Result::Converged;
223 beta = sigmaNew/sigma;
224 if(verbose > 0) std::cout <<
"step reduction: " << (sigmaNew/sigma) <<
", overall reduction: " << (sigmaNew/sigma0) << std::endl;
229 if(i > maxSteps)
break;
233 res.reduction = std::sqrt(std::abs(sigma)/sigma0);
234 res.conv_rate = pow(res.reduction,1.0/i);
235 res.elapsed = watch.elapsed();
239 std::cout <<
"=== rate=" << res.conv_rate
240 <<
", time=" << res.elapsed
241 <<
", iterations=" << i << std::endl;
246 return numberOfResults;
252 virtual void apply (
X& u, Xstar& b, Dune::InverseOperatorResult& res) {
259 Dune::InverseOperatorResult res;
266 virtual void apply (
X& x,
X& b,
double relTol, Dune::InverseOperatorResult& res) {
268 (*this).apply(x,b,res);
280 Dune::LinearOperator<X,Xstar>& op;
281 Dune::Preconditioner<X,Xstar>& prec;
283 typename std::conditional<std::is_same<Regularization,NoRegularization>::value,
NoRegularization,Regularization&>::type regularization;
284 double relTol, absTol;
287 std::vector<double> resDebug;
Mathematical Vector that supports copy-on-write, implements AbstractFunctionSpaceElement.
Abstract base class for dual pairing of and its dual space .
Helper class for working with (real or complex) scalar field types.
preconditioned conjugate gradient method
TCG(Dune::LinearOperator< X, Xstar > &op_, Dune::Preconditioner< X, Xstar > &prec_, DualPairing< X, Xstar > const &dp_, Regularization ®ularization_, double relTol_=1e-3, size_t maxSteps_=100, Int verbose_=0)
Set up conjugate gradient solver with absolute energy error termination criterion.
bool encounteredNonConvexity() const
void setRelativeAccuracy(double relTol_)
virtual void apply(X &u, Xstar &b, Dune::InverseOperatorResult &res)
Apply tcg and possibly forget second descent direction.
TCG(Dune::LinearOperator< X, Xstar > &op_, Dune::Preconditioner< X, Xstar > &prec_, DualPairing< X, Xstar > const &dp_, double relTol_=1e-3, size_t maxSteps_=100, Int verbose_=0)
Set up conjugate gradient solver with absolute energy error termination criterion.
virtual int apply(X &u, X &q, Xstar &b, Dune::InverseOperatorResult &res)
Apply inverse operator.
ScalarTraits< typenameGetScalar< X >::type >::Real Real
the real field type corresponding to X::field_type
void setMaxSteps(size_t maxSteps_)
bool localConvergenceLikely() const
void apply(X &u, Xstar &b)
virtual void apply(X &x, X &b, double relTol, Dune::InverseOperatorResult &res)
Apply inverse operator with given absolute tolerance.
A class for storing a heterogeneous collection of FunctionSpaceElement s.
VSDescriptions Descriptions
Type of the VariableSetDescription.
DoRegularization(Linearization const &lin_, typename VariableSet::Descriptions const &description)
void operator()(const X &x, Xstar &r)
void operator()(const X &, Xstar &)