From 45d34aad6ffaf085939689ab26ea9e5abc7a2cac Mon Sep 17 00:00:00 2001
From: Kilian Weishaupt <kilian.weishaupt@iws.uni-stuttgart.de>
Date: Tue, 8 Sep 2020 10:02:39 +0200
Subject: [PATCH] [newtonsolver] Use linearSolver.norm() if available

* fall back to assembler.residualNorm() otherwise
---
 dumux/nonlinear/newtonsolver.hh | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/dumux/nonlinear/newtonsolver.hh b/dumux/nonlinear/newtonsolver.hh
index 4ff3f1b2f2..0d2d242d6b 100644
--- a/dumux/nonlinear/newtonsolver.hh
+++ b/dumux/nonlinear/newtonsolver.hh
@@ -74,6 +74,14 @@ using DetectPVSwitch = typename Assembler::GridVariables::VolumeVariables::Prima
 template<class Assembler>
 using GetPVSwitch = Dune::Std::detected_or<int, DetectPVSwitch, Assembler>;
 
+// helper struct and function detecting if the linear solver features a norm() function
+template <class LinearSolver, class Residual>
+using NormDetector = decltype(std::declval<LinearSolver>().norm(std::declval<Residual>()));
+
+template<class LinearSolver, class Residual>
+static constexpr bool hasNorm()
+{ return Dune::Std::is_detected<NormDetector, LinearSolver, Residual>::value; }
+
 // helpers to implement max relative shift
 template<class C> using dynamicIndexAccess = decltype(std::declval<C>()[0]);
 template<class C> using staticIndexAccess = decltype(std::declval<C>()[Dune::Indices::_0]);
@@ -785,7 +793,11 @@ protected:
 
     void computeResidualReduction_(const SolutionVector &uCurrentIter)
     {
-        residualNorm_ = this->assembler().residualNorm(uCurrentIter);
+        if constexpr (Detail::hasNorm<LinearSolver, SolutionVector>())
+            residualNorm_ = this->linearSolver().norm(uCurrentIter);
+        else
+            residualNorm_ = this->assembler().residualNorm(uCurrentIter);
+
         reduction_ = residualNorm_;
         reduction_ /= initialResidual_;
     }
-- 
GitLab