From a221cec7ff4c6071fd8ecbd44fb09d048416b15f Mon Sep 17 00:00:00 2001 From: Bernd Flemisch <bernd@iws.uni-stuttgart.de> Date: Wed, 11 Nov 2020 07:43:50 +0100 Subject: [PATCH] [nonlinear] fix norm calculation in the Newton solver Use the norm provided by the linear solver also for the initial residual. In subsequent steps, the linear solver calculated the norm of the solution instead of the residual. Fix this. --- dumux/nonlinear/newtonsolver.hh | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/dumux/nonlinear/newtonsolver.hh b/dumux/nonlinear/newtonsolver.hh index b33f113a46..647a0c6ba2 100644 --- a/dumux/nonlinear/newtonsolver.hh +++ b/dumux/nonlinear/newtonsolver.hh @@ -444,12 +444,18 @@ public: { if (numSteps_ == 0) { - Scalar norm2 = b.two_norm2(); - if (comm_.size() > 1) - norm2 = comm_.sum(norm2); + if constexpr (Detail::hasNorm<LinearSolver, SolutionVector>()) + initialResidual_ = this->linearSolver().norm(b); - using std::sqrt; - initialResidual_ = sqrt(norm2); + else + { + Scalar norm2 = b.two_norm2(); + if (comm_.size() > 1) + norm2 = comm_.sum(norm2); + + using std::sqrt; + initialResidual_ = sqrt(norm2); + } } // solve by calling the appropriate implementation depending on whether the linear solver @@ -789,7 +795,10 @@ protected: void computeResidualReduction_(const SolutionVector &uCurrentIter) { if constexpr (Detail::hasNorm<LinearSolver, SolutionVector>()) - residualNorm_ = this->linearSolver().norm(uCurrentIter); + { + this->assembler().assembleResidual(uCurrentIter); + residualNorm_ = this->linearSolver().norm(this->assembler().residual()); + } else residualNorm_ = this->assembler().residualNorm(uCurrentIter); -- GitLab