version 3.8
numericdifferentiation.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3//
4// SPDX-FileCopyrightInfo: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
13#ifndef DUMUX_NUMERIC_DIFFERENTIATION_HH
14#define DUMUX_NUMERIC_DIFFERENTIATION_HH
15
16#include <cmath>
17#include <limits>
18
19namespace Dumux {
20
26{
27public:
28
34 template<class Scalar>
35 static Scalar epsilon(const Scalar value, const Scalar baseEps = 1e-10)
36 {
37 assert(std::numeric_limits<Scalar>::epsilon()*1e4 < baseEps);
38 // the epsilon value used for the numeric differentiation is
39 // now scaled by the absolute value of the primary variable...
40 using std::abs;
41 return baseEps*(abs(value) + 1.0);
42 }
43
48 template<class Function, class Scalar, class FunctionEvalType>
49 static void partialDerivative(const Function& function, Scalar x0,
50 FunctionEvalType& derivative,
51 const FunctionEvalType& fx0,
52 const int numericDifferenceMethod = 1)
53 { partialDerivative(function, x0, derivative, fx0, epsilon(x0), numericDifferenceMethod); }
54
65 template<class Function, class Scalar, class FunctionEvalType>
66 static void partialDerivative(const Function& function, Scalar x0,
67 FunctionEvalType& derivative,
68 const FunctionEvalType& fx0,
69 const Scalar eps,
70 const int numericDifferenceMethod = 1)
71 {
72 Scalar delta = 0.0;
73 // we are using forward or central differences, i.e. we need to calculate f(x + \epsilon)
74 if (numericDifferenceMethod >= 0)
75 {
76 delta += eps;
77 // calculate the function evaluated with the deflected variable
78 derivative = function(x0 + eps);
79 }
80
81 // we are using backward differences,
82 // i.e. we don't need to calculate f(x + \epsilon)
83 // we can recycle the (possibly cached) f(x)
84 else derivative = fx0;
85
86 // we are using backward or central differences,
87 // i.e. we need to calculate f(x - \epsilon)
88 if (numericDifferenceMethod <= 0)
89 {
90 delta += eps;
91 // subtract the function evaluated with the deflected variable
92 derivative -= function(x0 - eps);
93 }
94
95 // we are using forward differences,
96 // i.e. we don't need to calculate f(x - \epsilon)
97 // we can recycle the (possibly cached) f(x)
98 else derivative -= fx0;
99
100 // divide difference in residuals by the magnitude of the
101 // deflections between the two function evaluation
102 derivative /= delta;
103 }
104};
105
106} // end namespace Dumux
107
108#endif
A class for numeric differentiation with respect to a scalar parameter.
Definition: numericdifferentiation.hh:26
static Scalar epsilon(const Scalar value, const Scalar baseEps=1e-10)
Computes the epsilon used for numeric differentiation.
Definition: numericdifferentiation.hh:35
static void partialDerivative(const Function &function, Scalar x0, FunctionEvalType &derivative, const FunctionEvalType &fx0, const int numericDifferenceMethod=1)
Computes the derivative of a function with respect to a function parameter.
Definition: numericdifferentiation.hh:49
static void partialDerivative(const Function &function, Scalar x0, FunctionEvalType &derivative, const FunctionEvalType &fx0, const Scalar eps, const int numericDifferenceMethod=1)
Computes the derivative of a function with respect to a function parameter.
Definition: numericdifferentiation.hh:66
Definition: adapt.hh:17