From 24a802f153e2c86f1c2f5fbf82f8372afcdac6fc Mon Sep 17 00:00:00 2001 From: Nils-Arne Dreier <n.dreier@uni-muenster.de> Date: Mon, 20 May 2019 13:51:48 +0200 Subject: [PATCH] call Preconditioner::pre before computing the residuum, since pre might change the vectors --- dune/istl/solvers.hh | 57 ++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/dune/istl/solvers.hh b/dune/istl/solvers.hh index fac537736..daaa8b45e 100644 --- a/dune/istl/solvers.hh +++ b/dune/istl/solvers.hh @@ -76,16 +76,18 @@ namespace Dune { virtual void apply (X& x, X& b, InverseOperatorResult& res) { Iteration iteration(*this, res); + _prec->pre(x,b); // overwrite b with defect _op->applyscaleadd(-1,x,b); // compute norm, \todo parallelization real_type def = _sp->norm(b); - if(iteration.step(0, def)) + if(iteration.step(0, def)){ + _prec->post(x); return; + } // prepare preconditioner - _prec->pre(x,b); // allocate correction vector X v(x); @@ -147,15 +149,18 @@ namespace Dune { virtual void apply (X& x, X& b, InverseOperatorResult& res) { Iteration iteration(*this, res); - _op->applyscaleadd(-1,x,b); // overwrite b with defect + _prec->pre(x,b); // prepare preconditioner - X p(x); // create local vectors - X q(b); + _op->applyscaleadd(-1,x,b); // overwrite b with defec real_type def = _sp->norm(b); // compute norm - if(iteration.step(0, def)) + if(iteration.step(0, def)){ + _prec->post(x); return; - _prec->pre(x,b); // prepare preconditioner + } + + X p(x); // create local vectors + X q(b); int i=1; // loop variables field_type lambda; @@ -265,15 +270,18 @@ namespace Dune { virtual void apply (X& x, X& b, InverseOperatorResult& res) { Iteration iteration(*this,res); - _op->applyscaleadd(-1,x,b); // overwrite b with defect + _prec->pre(x,b); // prepare preconditioner - X p(x); // the search direction - X q(x); // a temporary vector + _op->applyscaleadd(-1,x,b); // overwrite b with defect real_type def = _sp->norm(b); // compute norm - if(iteration.step(0, def)) + if(iteration.step(0, def)){ + _prec->post(x); return; - _prec->pre(x,b); // prepare preconditioner + } + + X p(x); // the search direction + X q(x); // a temporary vector // Remember lambda and beta values for condition estimate std::vector<real_type> lambdas(0); @@ -451,14 +459,17 @@ namespace Dune { // r = r - Ax; rt = r Iteration iteration(*this,res); + _prec->pre(x,r); // prepare preconditioner + _op->applyscaleadd(-1,x,r); // overwrite b with defect rt=r; norm = _sp->norm(r); - if(iteration.step(0, norm)) + if(iteration.step(0, norm)){ + _prec->post(x); return; - _prec->pre(x,r); // prepare preconditioner + } p=0; v=0; @@ -612,15 +623,18 @@ namespace Dune { using std::sqrt; using std::abs; Iteration iteration(*this, res); + // prepare preconditioner + _prec->pre(x,b); + // overwrite rhs with defect _op->applyscaleadd(-1,x,b); // compute residual norm real_type def = _sp->norm(b); - if(iteration.step(0, def)) + if(iteration.step(0, def)){ + _prec->post(x); return; - // prepare preconditioner - _prec->pre(x,b); + } // recurrence coefficients as computed in Lanczos algorithm field_type alpha, beta; @@ -1125,14 +1139,15 @@ namespace Dune { // setup preconditioner if it does something in pre // calculate residual and overwrite a copy of the rhs with it + _prec->pre(x, b); v[0] = b; _op->applyscaleadd(-1.0, x, v[0]); // b -= Ax norm = _sp->norm(v[0]); // the residual norm if(iteration.step(0, norm)){ + _prec->post(x); return; } - _prec->pre(x, b); // start iterations res.converged = false;; @@ -1297,6 +1312,7 @@ private: virtual void apply (X& x, X& b, InverseOperatorResult& res) { Iteration iteration(*this, res); + _prec->pre(x,b); // prepare preconditioner _op->applyscaleadd(-1,x,b); // overwrite b with defect std::vector<std::shared_ptr<X> > p(_restart); @@ -1308,9 +1324,9 @@ private: real_type def = _sp->norm(b); // compute norm if(iteration.step(0, def)){ + _prec->post(x); return; } - _prec->pre(x,b); // prepare preconditioner // some local variables field_type rho, lambda; @@ -1458,6 +1474,7 @@ private: using rAlloc = ReboundAllocatorType<X,real_type>; res.clear(); Iteration iteration(*this,res); + _prec->pre(x,b); // prepare preconditioner _op->applyscaleadd(-1,x,b); // overwrite b with defect //arrays for interim values: @@ -1468,9 +1485,9 @@ private: real_type def = _sp->norm(b); // compute norm if(iteration.step(0, def)){ + _prec->post(x); return; } - _prec->pre(x,b); // prepare preconditioner // some local variables real_type alpha; -- GitLab