From 6547ce08dc9f629636e31f869476c8544b1303ee Mon Sep 17 00:00:00 2001
From: Kilian Weishaupt <kilian.weishaupt@iws.uni-stuttgart.de>
Date: Thu, 16 Feb 2017 19:43:09 +0100
Subject: [PATCH] [staggeredGrid][localJacobian] Use function to determine
 numerical eps

* Do not use fixed values anymore
---
 dumux/implicit/staggered/localjacobian.hh | 30 ++++++++++++++++-------
 1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/dumux/implicit/staggered/localjacobian.hh b/dumux/implicit/staggered/localjacobian.hh
index 0d6dca42ae..027747031f 100644
--- a/dumux/implicit/staggered/localjacobian.hh
+++ b/dumux/implicit/staggered/localjacobian.hh
@@ -266,11 +266,10 @@ private:
 
             for(auto pvIdx : PriVarIndices(cellCenterIdx))
             {
-                const Scalar eps = 1e-4; // TODO: do properly
-
                 PrimaryVariables priVars(CellCenterPrimaryVariables(this->model_().curSol()[cellCenterIdx][globalJ]),
                                          FacePrimaryVariables(0.0));
 
+                const Scalar eps = numericEpsilon(priVars[pvIdx]);
                 priVars[pvIdx] += eps;
                 ElementSolutionVector elemSol{std::move(priVars)};
                 curVolVars.update(elemSol, this->problem_(), elementJ, scvJ);
@@ -318,9 +317,8 @@ private:
             for(auto pvIdx : PriVarIndices(faceIdx))
             {
                 PrimaryVariables priVars(CellCenterPrimaryVariables(0.0), FacePrimaryVariables(this->model_().curSol()[faceIdx][globalJ]));
-                const Scalar eps = 1e-4; // TODO: do properly
+                const Scalar eps = numericEpsilon(priVars[pvIdx]);
                 priVars[pvIdx] += eps;
-
                 curFaceVars.update(priVars[faceIdx]);
 
                 this->localResidual().evalCellCenter(element, fvGeometry, scvI,
@@ -370,11 +368,10 @@ private:
 
                 for(auto pvIdx : PriVarIndices(cellCenterIdx))
                 {
-                    const Scalar eps = 1e-4; // TODO: do properly
-
                     PrimaryVariables priVars(CellCenterPrimaryVariables(this->model_().curSol()[cellCenterIdx][globalJ]),
                                              FacePrimaryVariables(0.0));
 
+                    const Scalar eps = numericEpsilon(priVars[pvIdx]);
                     priVars[pvIdx] += eps;
                     ElementSolutionVector elemSol{std::move(priVars)};
                     curVolVars.update(elemSol, this->problem_(), elementJ, scvJ);
@@ -424,11 +421,10 @@ private:
 
                 for(auto pvIdx : PriVarIndices(faceIdx))
                 {
-                    const Scalar eps = 1e-10; // TODO: do properly
-
                     PrimaryVariables priVars(CellCenterPrimaryVariables(0.0), FacePrimaryVariables(this->model_().curSol()[faceIdx][globalJ]));
-                    priVars[pvIdx] += eps;
 
+                    const Scalar eps = numericEpsilon(priVars[pvIdx]);
+                    priVars[pvIdx] += eps;
                     curFaceVars.update(priVars[faceIdx]);
 
                     this->localResidual().evalFace(element, fvGeometry, scvf,
@@ -491,6 +487,22 @@ private:
     const JacobianAssembler &jacAsm_() const
     { return model_().jacobianAssembler(); }
 
+    Scalar numericEpsilon(const Scalar priVar) const
+    {
+        // define the base epsilon as the geometric mean of 1 and the
+        // resolution of the scalar type. E.g. for standard 64 bit
+        // floating point values, the resolution is about 10^-16 and
+        // the base epsilon is thus approximately 10^-8.
+        /*
+        static const Scalar baseEps
+            = Dumux::geometricMean<Scalar>(std::numeric_limits<Scalar>::epsilon(), 1.0);
+        */
+        static const Scalar baseEps = 1e-10;
+        assert(std::numeric_limits<Scalar>::epsilon()*1e4 < baseEps);
+        // the epsilon value used for the numeric differentiation is
+        // now scaled by the absolute value of the primary variable...
+        return baseEps*(std::abs(priVar) + 1.0);
+    }
     /*!
      * \brief Updates the current global Jacobian matrix with the
      *        partial derivatives of all equations in regard to the
-- 
GitLab